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)
83 memset(sam_pass->lm_pw, '\0', 16);
85 memset(sam_pass->nt_pw, '\0', 16);
88 /*******************************************************************
89 This next function should be replaced with something that
90 dynamically returns the correct user info..... JRA.
91 ********************************************************************/
93 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
94 int *total_entries, int *num_entries,
95 int max_num_entries, uint16 acb_mask)
97 SAM_ACCOUNT *pwd = NULL;
100 (*total_entries) = 0;
105 if (!pdb_setsampwent(False)) {
106 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
110 while (((pwd = pdb_getsampwent()) != NULL) && (*num_entries) < max_num_entries) {
114 /* skip the requested number of entries.
115 not very efficient, but hey...
121 user_name_len = strlen(pdb_get_username(pwd))+1;
122 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
123 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
124 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
125 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
127 /* Now check if the NT compatible password is available. */
128 if (pdb_get_nt_passwd(pwd))
129 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
131 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
133 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
134 (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
136 if (acb_mask == 0 || (pwd->acct_ctrl & acb_mask)) {
137 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
141 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
148 return (*num_entries) > 0;
151 static BOOL jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
152 int *total_entries, uint32 *num_entries,
153 int max_num_entries, uint16 acb_mask)
155 SAM_ACCOUNT *pwd = NULL;
163 if (!pdb_setsampwent(False)) {
164 DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
168 while (((pwd = pdb_getsampwent()) != NULL) && (*num_entries) < max_num_entries) {
172 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask))
176 /* skip the requested number of entries.
177 not very efficient, but hey...
183 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
185 user_name_len = strlen(pdb_get_username(pwd));
186 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
187 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
189 full_name_len = strlen(pdb_get_fullname(pwd));
190 init_unistr2(&pw_buf[(*num_entries)].uni_full_name, pdb_get_fullname(pwd), full_name_len);
191 init_uni_hdr(&pw_buf[(*num_entries)].hdr_full_name, full_name_len);
193 pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
194 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
196 /* Now check if the NT compatible password is available. */
197 if (pdb_get_nt_passwd(pwd))
198 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
200 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
202 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries),
203 pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
209 *total_entries = *num_entries;
213 /*******************************************************************
214 This function uses the username map file and tries to map a UNIX
215 user name to an DOS name. (Sort of the reverse of the
216 map_username() function.) Since more than one DOS name can map
217 to the UNIX name, to reverse the mapping you have to specify
218 which corresponding DOS name you want; that's where the name_idx
219 parameter comes in. Returns the string requested or NULL if it
220 fails or can't complete the request for any reason. This doesn't
221 handle group names (starting with '@') or names starting with
222 '+' or '&'. If they are encountered, they are skipped.
223 ********************************************************************/
225 static char *unmap_unixname(char *unix_user_name, int name_idx)
227 char *mapfile = lp_username_map();
232 if (!*unix_user_name) return NULL;
233 if (!*mapfile) return NULL;
235 lines = file_lines_load(mapfile, NULL,False);
237 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
241 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
243 for (i=0; lines[i]; i++) {
244 char *unixname = lines[i];
245 char *dosname = strchr(unixname,'=');
252 while (isspace(*unixname))
254 if ('!' == *unixname) {
256 while (*unixname && isspace(*unixname))
260 if (!*unixname || strchr("#;",*unixname))
263 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
266 /* We have matched the UNIX user name */
268 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
269 if (!strchr("@&+", *tok)) {
278 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
279 file_lines_free(lines);
282 file_lines_free(lines);
287 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
288 file_lines_free(lines);
292 /*******************************************************************
293 This function sets up a list of users taken from the list of
294 users that UNIX knows about, as well as all the user names that
295 Samba maps to a valid UNIX user name. (This should work with
297 ********************************************************************/
299 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
301 int *total_entries, int *num_entries,
305 static struct passwd *pwd = NULL;
306 static uint32 pw_rid;
307 static BOOL orig_done = False;
308 static int current_idx = 0;
309 static int mapped_idx = 0;
312 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
315 (*total_entries) = 0;
317 /* Skip all this stuff if we're in appliance mode */
319 if (lp_hide_local_users()) goto done;
321 if (pw_buf == NULL) return False;
323 if (current_idx == 0) {
327 /* These two cases are inefficient, but should be called very rarely */
328 /* they are the cases where the starting index isn't picking up */
329 /* where we left off last time. It is efficient when it starts over */
330 /* at zero though. */
331 if (start_idx > current_idx) {
332 /* We aren't far enough; advance to start_idx */
333 while (current_idx <= start_idx) {
337 if ((pwd = sys_getpwent()) == NULL) break;
342 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
343 (current_idx < start_idx)) {
348 if (unmap_name == NULL) {
353 } else if (start_idx < current_idx) {
354 /* We are already too far; start over and advance to start_idx */
360 while (current_idx < start_idx) {
364 if ((pwd = sys_getpwent()) == NULL) break;
369 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
370 (current_idx < start_idx)) {
375 if (unmap_name == NULL) {
382 sep = lp_winbind_separator();
384 /* now current_idx == start_idx */
385 while ((*num_entries) < max_num_entries) {
389 /* This does the original UNIX user itself */
391 if ((pwd = sys_getpwent()) == NULL) break;
393 /* Don't enumerate winbind users as they are not local */
395 if (strchr(pwd->pw_name, *sep) != NULL) {
399 user_name_len = strlen(pwd->pw_name);
401 /* skip the trust account stored in the /etc/passwd file */
402 if (pwd->pw_name[user_name_len-1]=='$')
405 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
406 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
407 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pwd->pw_name, user_name_len);
408 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
409 pw_buf[(*num_entries)].user_rid = pw_rid;
410 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
412 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
414 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
422 /* This does all the user names that map to the UNIX user */
423 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
424 (*num_entries < max_num_entries)) {
425 user_name_len = strlen(unmap_name);
426 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
427 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, unmap_name, user_name_len);
428 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
429 pw_buf[(*num_entries)].user_rid = pw_rid;
430 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
432 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
434 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
442 if (unmap_name == NULL) {
443 /* done with 'aliases', go on to next UNIX user */
450 /* totally done, reset everything */
457 return (*num_entries) > 0;
460 /*******************************************************************
462 ********************************************************************/
464 uint32 _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
466 r_u->status = NT_STATUS_NOPROBLEMO;
468 /* close the policy handle */
469 if (!close_policy_hnd(p, &q_u->pol))
470 return NT_STATUS_OBJECT_NAME_INVALID;
472 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
477 /*******************************************************************
478 samr_reply_open_domain
479 ********************************************************************/
481 uint32 _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
483 struct samr_info *info;
485 r_u->status = NT_STATUS_NOPROBLEMO;
487 /* find the connection policy handle. */
488 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
489 return NT_STATUS_INVALID_HANDLE;
491 /* associate the domain SID with the (unique) handle. */
492 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
493 return NT_STATUS_NO_MEMORY;
496 info->sid = q_u->dom_sid.sid;
498 /* get a (unique) handle. open a policy on it. */
499 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
500 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
502 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
507 static uint32 get_lsa_policy_samr_rid(struct samr_info *info)
510 DEBUG(3,("Error getting policy\n"));
514 return info->sid.sub_auths[info->sid.num_auths-1];
517 /*******************************************************************
518 _samr_get_usrdom_pwinfo
519 ********************************************************************/
521 uint32 _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
523 struct samr_info *info = NULL;
525 r_u->status = NT_STATUS_NOPROBLEMO;
527 /* find the policy handle. open a policy on it. */
528 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info)) {
529 return NT_STATUS_INVALID_HANDLE;
532 /* find the user's rid */
533 if (get_lsa_policy_samr_rid(info) == 0xffffffff) {
534 return NT_STATUS_OBJECT_TYPE_MISMATCH;
537 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_NOPROBLEMO);
539 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
544 /*******************************************************************
546 ********************************************************************/
548 static uint32 samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
550 extern DOM_SID global_sid_World;
558 SEC_DESC *psd = NULL;
561 sid_copy(&adm_sid, &global_sid_Builtin);
562 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
564 sid_copy(&act_sid, &global_sid_Builtin);
565 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
567 init_sec_access(&mask, 0x2035b);
568 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
570 init_sec_access(&mask, 0xf07ff);
571 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
572 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
574 init_sec_access(&mask,0x20044);
575 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
577 if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
578 return NT_STATUS_NO_MEMORY;
580 if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
581 return NT_STATUS_NO_MEMORY;
583 if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
584 return NT_STATUS_NO_MEMORY;
586 return NT_STATUS_NOPROBLEMO;
589 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
591 struct samr_info *info = NULL;
593 /* find the policy handle. open a policy on it. */
594 if (!find_policy_by_hnd(p, pol, (void **)&info))
604 /*******************************************************************
606 ********************************************************************/
608 uint32 _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
612 r_u->status = NT_STATUS_NOPROBLEMO;
616 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
617 return NT_STATUS_INVALID_HANDLE;
619 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
621 if (r_u->status == NT_STATUS_NOPROBLEMO)
627 /*******************************************************************
628 makes a SAM_ENTRY / UNISTR2* structure from a user list.
629 ********************************************************************/
631 static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
632 uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
641 if (num_sam_entries == 0)
644 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
646 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
648 if (sam == NULL || uni_name == NULL) {
649 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
653 for (i = 0; i < num_sam_entries; i++) {
654 int len = pass[i].uni_user_name.uni_str_len;
656 init_sam_entry(&sam[i], len, pass[i].user_rid);
657 copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
661 *uni_name_pp = uni_name;
664 /*******************************************************************
665 samr_reply_enum_dom_users
666 ********************************************************************/
668 uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
670 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
672 int total_entries = 0;
675 r_u->status = NT_STATUS_NOPROBLEMO;
677 /* find the policy handle. open a policy on it. */
678 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
679 return NT_STATUS_INVALID_HANDLE;
681 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
684 ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
685 MAX_SAM_ENTRIES, q_u->acb_mask);
689 return NT_STATUS_ACCESS_DENIED;
691 samr_clear_passwd_fields(pass, num_entries);
694 * Note from JRA. total_entries is not being used here. Currently if there is a
695 * large user base then it looks like NT will enumerate until get_sampwd_entries
696 * returns False due to num_entries being zero. This will cause an access denied
697 * return. I don't think this is right and needs further investigation. Note that
698 * this is also the same in the TNG code (I don't think that has been tested with
699 * a very large user list as MAX_SAM_ENTRIES is set to 600).
701 * I also think that one of the 'num_entries' return parameters is probably
702 * the "max entries" parameter - but in the TNG code they're all currently set to the same
703 * value (again I think this is wrong).
706 make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
708 init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
710 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
715 /*******************************************************************
716 makes a SAM_ENTRY / UNISTR2* structure from a group list.
717 ********************************************************************/
719 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
720 uint32 num_sam_entries, DOMAIN_GRP *grp)
729 if (num_sam_entries == 0)
732 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
734 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
736 if (sam == NULL || uni_name == NULL) {
737 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
741 for (i = 0; i < num_sam_entries; i++) {
743 * JRA. I think this should include the null. TNG does not.
745 int len = strlen(grp[i].name)+1;
747 init_sam_entry(&sam[i], len, grp[i].rid);
748 init_unistr2(&uni_name[i], grp[i].name, len);
752 *uni_name_pp = uni_name;
755 /*******************************************************************
756 Get the group entries - similar to get_sampwd_entries().
757 ********************************************************************/
759 static BOOL get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
760 uint32 *p_num_entries, uint32 max_entries)
764 uint32 num_entries = 0;
766 sid_to_string(sid_str, sid);
767 sid_to_string(sam_sid_str, &global_sam_sid);
771 /* well-known aliases */
772 if (strequal(sid_str, "S-1-5-32")) {
774 while (!lp_hide_local_users() &&
775 num_entries < max_entries &&
776 ((name = builtin_alias_rids[num_entries].name) != NULL)) {
778 fstrcpy(d_grp[num_entries].name, name);
779 d_grp[num_entries].rid = builtin_alias_rids[num_entries].rid;
783 } else if (strequal(sid_str, sam_sid_str) && !lp_hide_local_users()) {
788 sep = lp_winbind_separator();
791 /* we return the UNIX groups here. This seems to be the right */
792 /* thing to do, since NT member servers return their local */
793 /* groups in the same situation. */
796 while (num_entries < max_entries && ((grp = getgrent()) != NULL)) {
801 DEBUG(10,("get_group_alias_entries: got group %s\n", name ));
803 /* Don't return winbind groups as they are not local! */
805 if (strchr(name, *sep) != NULL) {
806 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", name ));
810 /* Don't return user private groups... */
811 if (Get_Pwnam(name, False) != 0) {
812 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", name ));
816 trid = pdb_gid_to_group_rid(grp->gr_gid);
817 for( i = 0; i < num_entries; i++)
818 if ( d_grp[i].rid == trid ) break;
820 if ( i < num_entries )
821 continue; /* rid was there, dup! */
823 /* JRA - added this for large group db enumeration... */
826 /* skip the requested number of entries.
827 not very efficient, but hey...
833 fstrcpy(d_grp[num_entries].name, name);
834 d_grp[num_entries].rid = trid;
841 *p_num_entries = num_entries;
846 /*******************************************************************
847 Get the group entries - similar to get_sampwd_entries().
848 ********************************************************************/
850 static BOOL get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
851 uint32 *p_num_entries, uint32 max_entries)
855 uint32 num_entries = 0;
856 fstring name="Domain Admins";
857 fstring comment="Just to make it work !";
859 sid_to_string(sid_str, sid);
860 sid_to_string(sam_sid_str, &global_sam_sid);
864 fstrcpy(d_grp[0].name, name);
865 fstrcpy(d_grp[0].comment, comment);
866 d_grp[0].rid = DOMAIN_GROUP_RID_ADMINS;
867 d_grp[0].attr=SID_NAME_DOM_GRP;
869 fstrcpy(d_grp[1].name, "Domain Users");
870 fstrcpy(d_grp[1].comment, "Just to make it work !");
871 d_grp[1].rid = DOMAIN_GROUP_RID_USERS;
872 d_grp[1].attr=SID_NAME_DOM_GRP;
876 *p_num_entries = num_entries;
881 /*******************************************************************
882 samr_reply_enum_dom_groups
883 Only reply with one group - domain admins. This must be fixed for
885 ********************************************************************/
887 uint32 _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
893 r_u->status = NT_STATUS_NOPROBLEMO;
895 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
896 return NT_STATUS_INVALID_HANDLE;
898 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
900 get_group_domain_entries(grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
902 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
904 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
906 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
912 /*******************************************************************
913 samr_reply_enum_dom_aliases
914 ********************************************************************/
916 uint32 _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
918 DOMAIN_GRP grp[MAX_SAM_ENTRIES];
919 uint32 num_entries = 0;
923 r_u->status = NT_STATUS_NOPROBLEMO;
925 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
926 return NT_STATUS_INVALID_HANDLE;
928 sid_to_string(sid_str, &sid);
929 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
931 if (!get_group_alias_entries(grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))
932 return NT_STATUS_ACCESS_DENIED;
934 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
936 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx, num_entries);
938 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
943 /*******************************************************************
944 samr_reply_query_dispinfo
945 ********************************************************************/
947 uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
949 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
950 DOMAIN_GRP grps[MAX_SAM_ENTRIES];
951 uint16 acb_mask = ACB_NORMAL;
952 uint32 num_entries = 0;
953 int orig_num_entries = 0;
954 int total_entries = 0;
955 uint32 data_size = 0;
958 SAM_DISPINFO_CTR *ctr;
960 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
962 r_u->status = NT_STATUS_NOPROBLEMO;
964 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
965 return NT_STATUS_INVALID_HANDLE;
967 /* decide how many entries to get depending on the max_entries
968 and max_size passed by client */
970 if(q_u->max_entries > MAX_SAM_ENTRIES)
971 q_u->max_entries = MAX_SAM_ENTRIES;
973 /* Get what we need from the password database */
974 switch (q_u->switch_level) {
976 acb_mask = ACB_WSTRUST;
982 ret = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
983 MAX_SAM_ENTRIES, acb_mask);
987 * Which should we use here ? JRA.
989 ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
990 MAX_SAM_ENTRIES, acb_mask);
993 ret = jf_get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
994 MAX_SAM_ENTRIES, acb_mask);
998 DEBUG(5, ("get_sampwd_entries: failed\n"));
999 return NT_STATUS_ACCESS_DENIED;
1004 ret = get_group_domain_entries(grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
1006 return NT_STATUS_ACCESS_DENIED;
1009 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1010 return NT_STATUS_INVALID_INFO_CLASS;
1014 if (num_entries > q_u->max_entries)
1015 num_entries = q_u->max_entries;
1017 if (num_entries > MAX_SAM_ENTRIES) {
1018 num_entries = MAX_SAM_ENTRIES;
1019 DEBUG(5, ("limiting number of entries to %d\n", num_entries));
1022 /* Ensure password info is never given out here. PARANOIA... JRA */
1023 samr_clear_passwd_fields(pass, num_entries);
1025 data_size = q_u->max_size;
1026 orig_num_entries = num_entries;
1028 ctr = (SAM_DISPINFO_CTR *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_CTR));
1030 /* Now create reply structure */
1031 switch (q_u->switch_level) {
1033 ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_1));
1034 init_sam_dispinfo_1(ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass);
1037 ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_2));
1038 init_sam_dispinfo_2(ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass);
1041 ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_3));
1042 init_sam_dispinfo_3(ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps);
1045 ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_4));
1046 init_sam_dispinfo_4(ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass);
1049 ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_5));
1050 init_sam_dispinfo_5(ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps);
1053 ctr->sam.info = NULL;
1054 return NT_STATUS_INVALID_INFO_CLASS;
1057 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1059 init_samr_r_query_dispinfo(r_u, num_entries, data_size, q_u->switch_level, ctr, r_u->status);
1061 if (num_entries < orig_num_entries) {
1062 return STATUS_MORE_ENTRIES;
1068 /*******************************************************************
1069 samr_reply_query_aliasinfo
1070 ********************************************************************/
1072 uint32 _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1074 fstring alias_desc = "Local Unix group";
1076 enum SID_NAME_USE type;
1078 struct samr_info *info = NULL;
1080 r_u->status = NT_STATUS_NOPROBLEMO;
1082 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1084 /* find the policy handle. open a policy on it. */
1085 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1086 return NT_STATUS_INVALID_HANDLE;
1088 alias_rid = get_lsa_policy_samr_rid(info);
1089 if(alias_rid == 0xffffffff)
1090 return NT_STATUS_NO_SUCH_ALIAS;
1092 if(!local_lookup_rid(alias_rid, alias, &type))
1093 return NT_STATUS_NO_SUCH_ALIAS;
1095 switch (q_u->switch_level) {
1098 r_u->ctr.switch_value1 = 3;
1099 init_samr_alias_info3(&r_u->ctr.alias.info3, alias_desc);
1102 return NT_STATUS_INVALID_INFO_CLASS;
1105 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1111 /*******************************************************************
1112 samr_reply_lookup_ids
1113 ********************************************************************/
1115 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1117 uint32 rid[MAX_SAM_ENTRIES];
1118 int num_rids = q_u->num_sids1;
1120 r_u->status = NT_STATUS_NOPROBLEMO;
1122 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1124 if (num_rids > MAX_SAM_ENTRIES) {
1125 num_rids = MAX_SAM_ENTRIES;
1126 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1131 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1133 for (i = 0; i < num_rids && status == 0; i++)
1135 struct sam_passwd *sam_pass;
1139 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1140 q_u->uni_user_name[i].uni_str_len));
1142 /* find the user account */
1144 sam_pass = get_smb21pwd_entry(user_name, 0);
1147 if (sam_pass == NULL)
1149 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1154 rid[i] = sam_pass->user_rid;
1160 rid[0] = BUILTIN_ALIAS_RID_USERS;
1162 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_NOPROBLEMO);
1164 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1170 /*******************************************************************
1172 ********************************************************************/
1174 uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1176 uint32 rid[MAX_SAM_ENTRIES];
1177 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1179 int num_rids = q_u->num_names1;
1182 r_u->status = NT_STATUS_NOPROBLEMO;
1184 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1189 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
1190 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1194 if (num_rids > MAX_SAM_ENTRIES) {
1195 num_rids = MAX_SAM_ENTRIES;
1196 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1199 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1201 for (i = 0; i < num_rids; i++) {
1204 r_u->status = NT_STATUS_NONE_MAPPED;
1206 rid [i] = 0xffffffff;
1207 type[i] = SID_NAME_UNKNOWN;
1209 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer, q_u->uni_name[i].uni_str_len));
1211 if(sid_equal(&pol_sid, &global_sam_sid)) {
1213 if(local_lookup_name(global_myname, name, &sid, &type[i])) {
1214 sid_split_rid( &sid, &rid[i]);
1215 r_u->status = NT_STATUS_NOPROBLEMO;
1220 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1222 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1227 /*******************************************************************
1228 _samr_chgpasswd_user
1229 ********************************************************************/
1231 uint32 _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1236 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1238 r_u->status = NT_STATUS_NOPROBLEMO;
1240 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1241 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1243 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1245 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1246 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1247 r_u->status = NT_STATUS_WRONG_PASSWORD;
1249 init_samr_r_chgpasswd_user(r_u, r_u->status);
1251 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1256 /*******************************************************************
1257 makes a SAMR_R_LOOKUP_RIDS structure.
1258 ********************************************************************/
1260 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1261 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1264 UNIHDR *hdr_name=NULL;
1265 UNISTR2 *uni_name=NULL;
1267 *pp_uni_name = NULL;
1268 *pp_hdr_name = NULL;
1270 if (num_names != 0) {
1271 hdr_name = (UNIHDR *)talloc(ctx, sizeof(UNIHDR)*num_names);
1272 if (hdr_name == NULL)
1275 uni_name = (UNISTR2 *)talloc(ctx,sizeof(UNISTR2)*num_names);
1276 if (uni_name == NULL)
1280 for (i = 0; i < num_names; i++) {
1281 int len = names[i] != NULL ? strlen(names[i]) : 0;
1282 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1283 init_uni_hdr(&hdr_name[i], len);
1284 init_unistr2(&uni_name[i], names[i], len);
1287 *pp_uni_name = uni_name;
1288 *pp_hdr_name = hdr_name;
1293 /*******************************************************************
1295 ********************************************************************/
1297 uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1299 fstring group_names[MAX_SAM_ENTRIES];
1300 uint32 group_attrs[MAX_SAM_ENTRIES];
1301 UNIHDR *hdr_name = NULL;
1302 UNISTR2 *uni_name = NULL;
1304 int num_rids = q_u->num_rids1;
1307 r_u->status = NT_STATUS_NOPROBLEMO;
1309 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1311 /* find the policy handle. open a policy on it. */
1312 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
1313 return NT_STATUS_INVALID_HANDLE;
1315 if (num_rids > MAX_SAM_ENTRIES) {
1316 num_rids = MAX_SAM_ENTRIES;
1317 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1320 r_u->status = NT_STATUS_NONE_MAPPED;
1322 for (i = 0; i < num_rids; i++) {
1326 enum SID_NAME_USE type;
1328 group_attrs[i] = SID_NAME_UNKNOWN;
1329 *group_names[i] = '\0';
1331 if (sid_equal(&pol_sid, &global_sam_sid)) {
1332 sid_copy(&sid, &pol_sid);
1333 sid_append_rid(&sid, q_u->rid[i]);
1335 if (lookup_sid(&sid, domname, tmpname, &type)) {
1336 r_u->status = NT_STATUS_NOPROBLEMO;
1337 group_attrs[i] = (uint32)type;
1338 fstrcpy(group_names[i],tmpname);
1343 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1344 return NT_STATUS_NO_MEMORY;
1346 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1348 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1353 /*******************************************************************
1354 _api_samr_open_user. Safe - gives out no passwd info.
1355 ********************************************************************/
1357 uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1359 SAM_ACCOUNT *sampass;
1361 POLICY_HND domain_pol = q_u->domain_pol;
1362 uint32 user_rid = q_u->user_rid;
1363 POLICY_HND *user_pol = &r_u->user_pol;
1364 struct samr_info *info = NULL;
1366 r_u->status = NT_STATUS_NO_PROBLEMO;
1368 /* find the domain policy handle. */
1369 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1370 return NT_STATUS_INVALID_HANDLE;
1373 sampass = pdb_getsampwrid(user_rid);
1376 /* check that the RID exists in our domain. */
1377 if (sampass == NULL)
1378 return NT_STATUS_NO_SUCH_USER;
1380 samr_clear_sam_passwd(sampass);
1382 /* Get the domain SID stored in the domain policy */
1383 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1384 return NT_STATUS_INVALID_HANDLE;
1386 /* append the user's RID to it */
1387 if(!sid_append_rid(&sid, user_rid))
1388 return NT_STATUS_NO_SUCH_USER;
1390 /* associate the user's SID with the new handle. */
1391 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1392 return NT_STATUS_NO_MEMORY;
1397 /* get a (unique) handle. open a policy on it. */
1398 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1399 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1404 /*************************************************************************
1405 get_user_info_10. Safe. Only gives out acb bits.
1406 *************************************************************************/
1408 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1410 SAM_ACCOUNT *smbpass;
1412 if (!pdb_rid_is_user(user_rid)) {
1413 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1418 smbpass = pdb_getsampwrid(user_rid);
1421 if (smbpass == NULL) {
1422 DEBUG(4,("User 0x%x not found\n", user_rid));
1426 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1428 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1433 /*************************************************************************
1434 get_user_info_12. OK - this is the killer as it gives out password info.
1435 Ensure that this is only allowed on an encrypted connection with a root
1437 *************************************************************************/
1439 static uint32 get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
1441 SAM_ACCOUNT *smbpass;
1443 if (!p->ntlmssp_auth_validated)
1444 return NT_STATUS_ACCESS_DENIED;
1446 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1447 return NT_STATUS_ACCESS_DENIED;
1450 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1453 smbpass = pdb_getsampwrid(user_rid);
1455 if (smbpass == NULL) {
1456 DEBUG(4, ("User 0x%x not found\n", user_rid));
1457 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1460 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1462 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED)
1463 return NT_STATUS_ACCOUNT_DISABLED;
1465 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1467 return NT_STATUS_NOPROBLEMO;
1470 /*************************************************************************
1472 *************************************************************************/
1474 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1476 SAM_ACCOUNT *sampass;
1478 if (!pdb_rid_is_user(user_rid)) {
1479 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1484 sampass = pdb_getsampwrid(user_rid);
1487 if (sampass == NULL) {
1488 DEBUG(4,("User 0x%x not found\n", user_rid));
1492 samr_clear_sam_passwd(sampass);
1494 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1496 init_sam_user_info21A(id21, sampass);
1501 /*******************************************************************
1502 _samr_query_userinfo
1503 ********************************************************************/
1505 uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1507 SAM_USERINFO_CTR *ctr;
1509 struct samr_info *info = NULL;
1511 r_u->status=NT_STATUS_NO_PROBLEMO;
1513 /* search for the handle */
1514 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1515 return NT_STATUS_INVALID_HANDLE;
1517 /* find the user's rid */
1518 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1519 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1521 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
1523 ctr = (SAM_USERINFO_CTR *)talloc(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1525 return NT_STATUS_NO_MEMORY;
1529 /* ok! user info levels (lots: see MSDEV help), off we go... */
1530 ctr->switch_value = q_u->switch_value;
1532 switch (q_u->switch_value) {
1534 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1535 if (ctr->info.id10 == NULL)
1536 return NT_STATUS_NO_MEMORY;
1538 if (!get_user_info_10(ctr->info.id10, rid))
1539 return NT_STATUS_NO_SUCH_USER;
1543 /* whoops - got this wrong. i think. or don't understand what's happening. */
1547 info = (void *)&id11;
1549 expire.low = 0xffffffff;
1550 expire.high = 0x7fffffff;
1552 ctr->info.id = (SAM_USER_INFO_11 *)talloc(p->mem_ctx,
1557 init_sam_user_info11(ctr->info.id11, &expire,
1558 "BROOKFIELDS$", /* name */
1559 0x03ef, /* user rid */
1560 0x201, /* group rid */
1561 0x0080); /* acb info */
1568 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1569 if (ctr->info.id12 == NULL)
1570 return NT_STATUS_NO_MEMORY;
1572 if ((r_u->status = get_user_info_12(p, ctr->info.id12, rid)) != NT_STATUS_NOPROBLEMO)
1577 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1578 if (ctr->info.id21 == NULL)
1579 return NT_STATUS_NO_MEMORY;
1580 if (!get_user_info_21(ctr->info.id21, rid))
1581 return NT_STATUS_NO_SUCH_USER;
1585 return NT_STATUS_INVALID_INFO_CLASS;
1588 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1590 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1595 /*******************************************************************
1596 samr_reply_query_usergroups
1597 ********************************************************************/
1599 uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1601 struct sam_passwd *sam_pass;
1602 DOM_GID *gids = NULL;
1606 struct samr_info *info = NULL;
1608 r_u->status = NT_STATUS_NO_PROBLEMO;
1610 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1612 /* find the policy handle. open a policy on it. */
1613 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1614 return NT_STATUS_INVALID_HANDLE;
1616 /* find the user's rid */
1617 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1618 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1621 sam_pass = pdb_getsampwrid(rid);
1624 if (sam_pass == NULL)
1625 return NT_STATUS_NO_SUCH_USER;
1627 samr_clear_sam_passwd(sam_pass);
1629 get_domain_user_groups(groups, pdb_get_username(sam_pass));
1631 num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
1633 /* construct the response. lkclXXXX: gids are not copied! */
1634 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1636 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1641 /*******************************************************************
1642 _samr_query_dom_info
1643 ********************************************************************/
1645 uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1649 if ((ctr = (SAM_UNK_CTR *)talloc(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
1650 return NT_STATUS_NO_MEMORY;
1654 r_u->status = NT_STATUS_NO_PROBLEMO;
1656 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1658 /* find the policy handle. open a policy on it. */
1659 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
1660 return NT_STATUS_INVALID_HANDLE;
1662 switch (q_u->switch_value) {
1664 init_unk_info1(&ctr->info.inf1);
1667 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1668 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL));
1671 init_unk_info3(&ctr->info.inf3);
1674 init_unk_info6(&ctr->info.inf6);
1677 init_unk_info7(&ctr->info.inf7);
1680 init_unk_info12(&ctr->info.inf12);
1683 return NT_STATUS_INVALID_INFO_CLASS;
1686 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_NOPROBLEMO);
1688 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1693 /*******************************************************************
1694 _api_samr_create_user
1695 ********************************************************************/
1697 uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
1699 SAM_ACCOUNT *sam_pass;
1706 POLICY_HND dom_pol = q_u->domain_pol;
1707 UNISTR2 user_account = q_u->uni_name;
1708 uint16 acb_info = q_u->acb_info;
1709 POLICY_HND *user_pol = &r_u->user_pol;
1710 struct samr_info *info = NULL;
1712 /* find the policy handle. open a policy on it. */
1713 if (!find_policy_by_hnd(p, &dom_pol, NULL))
1714 return NT_STATUS_INVALID_HANDLE;
1716 /* find the machine account: tell the caller if it exists.
1717 lkclXXXX i have *no* idea if this is a problem or not
1718 or even if you are supposed to construct a different
1719 reply if the account already exists...
1722 fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
1723 strlower(mach_acct);
1726 sam_pass = pdb_getsampwnam(mach_acct);
1728 if (sam_pass != NULL) {
1729 /* machine account exists: say so */
1730 return NT_STATUS_USER_EXISTS;
1733 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1734 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1737 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1738 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1739 * that only people with write access to the smbpasswd file will be able
1740 * to create a user. JRA.
1744 * add the user in the /etc/passwd file or the unix authority system.
1745 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1746 * a) local_password_change() checks for us if the /etc/passwd account really exists
1747 * b) smb_create_user() would return an error if the account already exists
1748 * and as it could return an error also if it can't create the account, it would be tricky.
1750 * So we go the easy way, only check after if the account exists.
1751 * JFM (2/3/2001), to clear any possible bad understanding (-:
1754 pstrcpy(add_script, lp_adduser_script());
1757 smb_create_user(mach_acct, NULL);
1759 /* add the user in the smbpasswd file or the Samba authority database */
1760 if (!local_password_change(mach_acct, local_flags, NULL, err_str,
1761 sizeof(err_str), msg_str, sizeof(msg_str)))
1763 DEBUG(0, ("%s\n", err_str));
1764 close_policy_hnd(p, user_pol);
1765 return NT_STATUS_ACCESS_DENIED;
1769 sam_pass = pdb_getsampwnam(mach_acct);
1771 if (sam_pass == NULL) {
1772 /* account doesn't exist: say so */
1773 close_policy_hnd(p, user_pol);
1774 return NT_STATUS_ACCESS_DENIED;
1777 /* Get the domain SID stored in the domain policy */
1778 if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
1779 close_policy_hnd(p, user_pol);
1780 return NT_STATUS_INVALID_HANDLE;
1783 /* append the user's RID to it */
1784 if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
1785 close_policy_hnd(p, user_pol);
1786 return NT_STATUS_NO_SUCH_USER;
1789 /* associate the user's SID with the new handle. */
1790 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1791 return NT_STATUS_NO_MEMORY;
1796 /* get a (unique) handle. open a policy on it. */
1797 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1798 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1800 r_u->user_rid=sam_pass->user_rid;
1801 r_u->unknown_0 = 0x000703ff;
1803 return NT_STATUS_NO_PROBLEMO;
1806 /*******************************************************************
1807 samr_reply_connect_anon
1808 ********************************************************************/
1810 uint32 _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
1812 struct samr_info *info = NULL;
1814 /* set up the SAMR connect_anon response */
1816 r_u->status = NT_STATUS_NO_PROBLEMO;
1818 /* associate the user's SID with the new handle. */
1819 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1820 return NT_STATUS_NO_MEMORY;
1823 info->status = q_u->unknown_0;
1825 /* get a (unique) handle. open a policy on it. */
1826 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
1827 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1832 /*******************************************************************
1834 ********************************************************************/
1836 uint32 _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
1838 struct samr_info *info = NULL;
1840 DEBUG(5,("_samr_connect: %d\n", __LINE__));
1842 r_u->status = NT_STATUS_NO_PROBLEMO;
1844 /* associate the user's SID with the new handle. */
1845 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1846 return NT_STATUS_NO_MEMORY;
1849 info->status = q_u->access_mask;
1851 /* get a (unique) handle. open a policy on it. */
1852 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
1853 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1855 DEBUG(5,("_samr_connect: %d\n", __LINE__));
1860 /**********************************************************************
1861 api_samr_lookup_domain
1862 **********************************************************************/
1864 uint32 _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
1866 r_u->status = NT_STATUS_NO_PROBLEMO;
1868 if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
1869 return NT_STATUS_INVALID_HANDLE;
1871 /* assume the domain name sent is our global_myname and
1872 send global_sam_sid */
1873 init_samr_r_lookup_domain(r_u, &global_sam_sid, r_u->status);
1878 /******************************************************************
1879 makes a SAMR_R_ENUM_DOMAINS structure.
1880 ********************************************************************/
1882 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
1883 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
1889 DEBUG(5, ("make_enum_domains\n"));
1892 *pp_uni_name = NULL;
1894 if (num_sam_entries == 0)
1897 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
1898 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
1900 if (sam == NULL || uni_name == NULL)
1903 for (i = 0; i < num_sam_entries; i++) {
1904 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
1906 init_sam_entry(&sam[i], len, 0);
1907 init_unistr2(&uni_name[i], doms[i], len);
1911 *pp_uni_name = uni_name;
1916 /**********************************************************************
1917 api_samr_enum_domains
1918 **********************************************************************/
1920 uint32 _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
1922 uint32 num_entries = 2;
1925 r_u->status = NT_STATUS_NO_PROBLEMO;
1927 fstrcpy(dom[0],global_myworkgroup);
1928 fstrcpy(dom[1],"Builtin");
1930 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
1931 return NT_STATUS_NO_MEMORY;
1933 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
1938 /*******************************************************************
1940 ********************************************************************/
1942 uint32 _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
1945 POLICY_HND domain_pol = q_u->dom_pol;
1946 uint32 alias_rid = q_u->rid_alias;
1947 POLICY_HND *alias_pol = &r_u->pol;
1948 struct samr_info *info = NULL;
1950 r_u->status = NT_STATUS_NO_PROBLEMO;
1952 /* get the domain policy. */
1953 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1954 return NT_STATUS_INVALID_HANDLE;
1956 /* Get the domain SID stored in the domain policy */
1957 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1958 return NT_STATUS_INVALID_HANDLE;
1960 /* append the alias' RID to it */
1961 if(!sid_append_rid(&sid, alias_rid))
1962 return NT_STATUS_NO_SUCH_USER;
1965 * we should check if the rid really exist !!!
1969 /* associate the user's SID with the new handle. */
1970 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1971 return NT_STATUS_NO_MEMORY;
1976 /* get a (unique) handle. open a policy on it. */
1977 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
1978 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1983 /*******************************************************************
1985 ********************************************************************/
1987 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
1989 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
1992 DEBUG(5, ("set_user_info_10: NULL id10\n"));
1996 pwd = pdb_getsampwrid(rid);
2000 pdb_set_acct_ctrl(pwd, id10->acb_info);
2002 if(!pdb_update_sam_account(pwd, True))
2008 /*******************************************************************
2010 ********************************************************************/
2012 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2014 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2020 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2024 pdb_set_lanman_passwd (pwd, id12->lm_pwd);
2025 pdb_set_nt_passwd (pwd, id12->nt_pwd);
2027 if(!pdb_update_sam_account(pwd, True))
2033 /*******************************************************************
2035 ********************************************************************/
2037 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
2039 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2040 SAM_ACCOUNT new_pwd;
2043 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2050 /* we make a copy so that we can modify stuff */
2051 copy_sam_passwd(&new_pwd, pwd);
2052 copy_id21_to_sam_passwd(&new_pwd, id21);
2055 * The funny part about the previous two calls is
2056 * that pwd still has the password hashes from the
2057 * passdb entry. These have not been updated from
2058 * id21. I don't know if they need to be set. --jerry
2061 /* write the change out */
2062 if(!pdb_update_sam_account(&new_pwd, True))
2068 /*******************************************************************
2070 ********************************************************************/
2072 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2074 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2075 SAM_ACCOUNT new_pwd;
2083 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2090 acct_ctrl = pdb_get_acct_ctrl(pwd);
2092 copy_sam_passwd(&new_pwd, pwd);
2093 copy_id23_to_sam_passwd(&new_pwd, id23);
2095 if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len))
2098 nt_lm_owf_gen(buf, nt_hash, lm_hash);
2100 pdb_set_lanman_passwd (&new_pwd, lm_hash);
2101 pdb_set_nt_passwd (&new_pwd, nt_hash);
2103 /* if it's a trust account, don't update /etc/passwd */
2104 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2105 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2106 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2107 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2109 /* update the UNIX password */
2110 /* update the UNIX password */
2111 if (lp_unix_password_sync() )
2112 if(!chgpasswd(pdb_get_username(&new_pwd), "", buf, True))
2116 memset(buf, 0, sizeof(buf));
2118 if(!pdb_update_sam_account(&new_pwd, True))
2124 /*******************************************************************
2126 ********************************************************************/
2128 static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid)
2130 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2140 acct_ctrl = pdb_get_acct_ctrl(pwd);
2142 memset(buf, 0, sizeof(buf));
2144 if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len))
2147 DEBUG(5,("set_user_info_24:nt_lm_owf_gen\n"));
2149 nt_lm_owf_gen(buf, nt_hash, lm_hash);
2151 pdb_set_lanman_passwd (pwd, lm_hash);
2152 pdb_set_nt_passwd (pwd, nt_hash);
2154 /* if it's a trust account, don't update /etc/passwd */
2155 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2156 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2157 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2158 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2160 /* update the UNIX password */
2161 if (lp_unix_password_sync())
2162 if(!chgpasswd(pdb_get_username(pwd), "", buf, True))
2166 memset(buf, 0, sizeof(buf));
2168 DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
2170 /* update the SAMBA password */
2171 if(!pdb_update_sam_account(pwd, True))
2177 /*******************************************************************
2178 samr_reply_set_userinfo
2179 ********************************************************************/
2181 uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2185 struct current_user user;
2186 SAM_ACCOUNT *sam_pass;
2187 unsigned char sess_key[16];
2188 POLICY_HND *pol = &q_u->pol;
2189 uint16 switch_value = q_u->switch_value;
2190 SAM_USERINFO_CTR *ctr = q_u->ctr;
2192 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2194 r_u->status = NT_STATUS_NOPROBLEMO;
2196 if (p->ntlmssp_auth_validated) {
2197 memcpy(&user, &p->pipe_user, sizeof(user));
2199 extern struct current_user current_user;
2200 memcpy(&user, ¤t_user, sizeof(user));
2203 /* find the policy handle. open a policy on it. */
2204 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2205 return NT_STATUS_INVALID_HANDLE;
2207 sid_split_rid(&sid, &rid);
2209 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2212 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2213 return NT_STATUS_INVALID_INFO_CLASS;
2218 * We need the NT hash of the user who is changing the user's password.
2219 * This NT hash is used to generate a "user session key"
2220 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2224 sam_pass = pdb_getsampwuid(user.uid);
2226 if(sam_pass == NULL) {
2227 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
2228 return NT_STATUS_ACCESS_DENIED;
2231 memset(sess_key, '\0', 16);
2232 mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2234 /* ok! user info levels (lots: see MSDEV help), off we go... */
2235 switch (switch_value) {
2237 if (!set_user_info_12(ctr->info.id12, rid))
2238 return NT_STATUS_ACCESS_DENIED;
2242 SamOEMhash(ctr->info.id24->pass, sess_key, 1);
2243 if (!set_user_info_24(ctr->info.id24, rid))
2244 return NT_STATUS_ACCESS_DENIED;
2248 SamOEMhash(ctr->info.id23->pass, sess_key, 1);
2249 if (!set_user_info_23(ctr->info.id23, rid))
2250 return NT_STATUS_ACCESS_DENIED;
2254 return NT_STATUS_INVALID_INFO_CLASS;
2260 /*******************************************************************
2261 samr_reply_set_userinfo2
2262 ********************************************************************/
2264 uint32 _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2268 SAM_USERINFO_CTR *ctr = q_u->ctr;
2269 POLICY_HND *pol = &q_u->pol;
2270 uint16 switch_value = q_u->switch_value;
2272 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2274 r_u->status = NT_STATUS_NOPROBLEMO;
2276 /* find the policy handle. open a policy on it. */
2277 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2278 return NT_STATUS_INVALID_HANDLE;
2280 sid_split_rid(&sid, &rid);
2282 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2285 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2286 return NT_STATUS_INVALID_INFO_CLASS;
2289 switch_value=ctr->switch_value;
2291 /* ok! user info levels (lots: see MSDEV help), off we go... */
2292 switch (switch_value) {
2294 if (!set_user_info_21(ctr->info.id21, rid))
2295 return NT_STATUS_ACCESS_DENIED;
2298 if (!set_user_info_10(ctr->info.id10, rid))
2299 return NT_STATUS_ACCESS_DENIED;
2302 /* Used by AS/U JRA. */
2303 if (!set_user_info_12(ctr->info.id12, rid))
2304 return NT_STATUS_ACCESS_DENIED;
2307 return NT_STATUS_INVALID_INFO_CLASS;
2313 /*********************************************************************
2314 _samr_query_aliasmem
2315 *********************************************************************/
2317 uint32 _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
2323 rid=(uint32 *)talloc(p->mem_ctx, num_rids*sizeof(uint32));
2325 return NT_STATUS_NO_MEMORY;
2327 /* until i see a real useraliases query, we fack one up */
2329 rid[0] = BUILTIN_ALIAS_RID_USERS;
2331 init_samr_r_query_useraliases(r_u, num_rids, rid, NT_STATUS_NO_PROBLEMO);
2333 return NT_STATUS_NO_PROBLEMO;
2337 /*********************************************************************
2338 _samr_query_aliasmem
2339 *********************************************************************/
2341 uint32 _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
2353 fstring alias_sid_str;
2357 /* find the policy handle. open a policy on it. */
2358 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2359 return NT_STATUS_INVALID_HANDLE;
2361 sid_copy(&als_sid, &alias_sid);
2362 sid_to_string(alias_sid_str, &alias_sid);
2363 sid_split_rid(&alias_sid, &alias_rid);
2365 DEBUG(10, ("sid is %s\n", alias_sid_str));
2367 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
2368 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
2369 if(!get_builtin_group_from_sid(als_sid, &map))
2370 return NT_STATUS_NO_SUCH_ALIAS;
2372 if (sid_equal(&alias_sid, &global_sam_sid)) {
2373 DEBUG(10, ("lookup on Server SID\n"));
2374 if(!get_local_group_from_sid(als_sid, &map))
2375 return NT_STATUS_NO_SUCH_ALIAS;
2379 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2380 return NT_STATUS_NO_SUCH_ALIAS;
2382 DEBUG(10, ("sid is %s\n", alias_sid_str));
2383 sid = (DOM_SID2 *)talloc(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
2385 return NT_STATUS_NO_SUCH_ALIAS;
2387 for (i = 0; i < num_uids; i++) {
2388 sid_copy(&temp_sid, &global_sam_sid);
2389 sid_append_rid(&temp_sid, pdb_uid_to_user_rid(uid[i]));
2391 init_dom_sid2(&sid[i], &temp_sid);
2394 DEBUG(10, ("sid is %s\n", alias_sid_str));
2395 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_NO_PROBLEMO);
2397 return NT_STATUS_NOPROBLEMO;
2400 /*********************************************************************
2401 _samr_query_groupmem
2402 *********************************************************************/
2404 uint32 _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
2410 fstring group_sid_str;
2419 /* find the policy handle. open a policy on it. */
2420 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid))
2421 return NT_STATUS_INVALID_HANDLE;
2423 /* todo: change to use sid_compare_front */
2425 sid_split_rid(&group_sid, &group_rid);
2426 sid_to_string(group_sid_str, &group_sid);
2427 DEBUG(10, ("sid is %s\n", group_sid_str));
2429 /* can we get a query for an SID outside our domain ? */
2430 if (!sid_equal(&group_sid, &global_sam_sid))
2431 return NT_STATUS_NO_SUCH_GROUP;
2433 sid_append_rid(&group_sid, group_rid);
2434 DEBUG(10, ("lookup on Domain SID\n"));
2436 if(!get_domain_group_from_sid(group_sid, &map))
2437 return NT_STATUS_NO_SUCH_GROUP;
2439 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2440 return NT_STATUS_NO_SUCH_GROUP;
2442 rid=talloc(p->mem_ctx, sizeof(uint32)*num_uids);
2443 attr=talloc(p->mem_ctx, sizeof(uint32)*num_uids);
2445 if (rid==NULL || attr==NULL)
2446 return NT_STATUS_NO_MEMORY;
2448 for (i=0; i<num_uids; i++) {
2449 rid[i]=pdb_uid_to_user_rid(uid[i]);
2450 attr[i] = SID_NAME_USER;
2453 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_NOPROBLEMO);
2455 return NT_STATUS_NOPROBLEMO;
2458 /*********************************************************************
2460 *********************************************************************/
2462 uint32 _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
2465 fstring alias_sid_str;
2473 /* Find the policy handle. Open a policy on it. */
2474 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2475 return NT_STATUS_INVALID_HANDLE;
2477 sid_to_string(alias_sid_str, &alias_sid);
2478 DEBUG(10, ("sid is %s\n", alias_sid_str));
2480 if (sid_compare(&alias_sid, &global_sam_sid)>0) {
2481 DEBUG(10, ("adding member on Server SID\n"));
2482 if(!get_local_group_from_sid(alias_sid, &map))
2483 return NT_STATUS_NO_SUCH_ALIAS;
2486 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
2487 DEBUG(10, ("adding member on BUILTIN SID\n"));
2488 if( !get_builtin_group_from_sid(alias_sid, &map))
2489 return NT_STATUS_NO_SUCH_ALIAS;
2492 return NT_STATUS_NO_SUCH_ALIAS;
2495 sid_split_rid(&q_u->sid.sid, &rid);
2496 uid=pdb_user_rid_to_uid(rid);
2498 if ((pwd=getpwuid(uid)) == NULL)
2499 return NT_STATUS_NO_SUCH_USER;
2501 if ((grp=getgrgid(map.gid)) == NULL)
2502 return NT_STATUS_NO_SUCH_ALIAS;
2504 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2505 fstrcpy(grp_name, grp->gr_name);
2507 /* if the user is already in the group */
2508 if(user_in_group_list(pwd->pw_name, grp_name))
2509 return NT_STATUS_MEMBER_IN_ALIAS;
2512 * ok, the group exist, the user exist, the user is not in the group,
2513 * we can (finally) add it to the group !
2515 smb_add_user_group(grp_name, pwd->pw_name);
2517 /* check if the user has been added then ... */
2518 if(!user_in_group_list(pwd->pw_name, grp_name))
2519 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
2521 return NT_STATUS_NOPROBLEMO;
2524 /*********************************************************************
2526 *********************************************************************/
2528 uint32 _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
2530 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2534 /*********************************************************************
2536 *********************************************************************/
2538 uint32 _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
2541 fstring group_sid_str;
2547 /* Find the policy handle. Open a policy on it. */
2548 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2549 return NT_STATUS_INVALID_HANDLE;
2551 sid_to_string(group_sid_str, &group_sid);
2552 DEBUG(10, ("sid is %s\n", group_sid_str));
2554 if (sid_compare(&group_sid, &global_sam_sid)<=0)
2555 return NT_STATUS_NO_SUCH_GROUP;
2557 DEBUG(10, ("lookup on Domain SID\n"));
2559 if(!get_domain_group_from_sid(group_sid, &map))
2560 return NT_STATUS_NO_SUCH_GROUP;
2562 if ((pwd=getpwuid(pdb_user_rid_to_uid(q_u->rid))) ==NULL)
2563 return NT_STATUS_NO_SUCH_USER;
2565 if ((grp=getgrgid(map.gid)) == NULL)
2566 return NT_STATUS_NO_SUCH_GROUP;
2568 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2569 fstrcpy(grp_name, grp->gr_name);
2571 /* if the user is already in the group */
2572 if(user_in_group_list(pwd->pw_name, grp_name))
2573 return NT_STATUS_MEMBER_IN_GROUP;
2576 * ok, the group exist, the user exist, the user is not in the group,
2578 * we can (finally) add it to the group !
2581 smb_add_user_group(grp_name, pwd->pw_name);
2583 /* check if the user has been added then ... */
2584 if(!user_in_group_list(pwd->pw_name, grp_name))
2585 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
2587 return NT_STATUS_NOPROBLEMO;
2590 /*********************************************************************
2592 *********************************************************************/
2594 uint32 _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
2596 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2600 /*********************************************************************
2601 _samr_delete_dom_user
2602 *********************************************************************/
2604 uint32 _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
2606 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2610 /*********************************************************************
2611 _samr_delete_dom_group
2612 *********************************************************************/
2614 uint32 _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
2616 DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
2620 /*********************************************************************
2621 _samr_delete_dom_alias
2622 *********************************************************************/
2624 uint32 _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
2626 DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
2630 /*********************************************************************
2631 _samr_create_dom_group
2632 *********************************************************************/
2634 uint32 _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
2641 struct samr_info *info;
2643 /* Find the policy handle. Open a policy on it. */
2644 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid))
2645 return NT_STATUS_INVALID_HANDLE;
2647 if (!sid_equal(&dom_sid, &global_sam_sid))
2648 return NT_STATUS_ACCESS_DENIED;
2650 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2652 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
2654 /* check if group already exist */
2655 if ((grp=getgrnam(name)) != NULL)
2656 return NT_STATUS_GROUP_EXISTS;
2658 /* we can create the UNIX group */
2659 smb_create_group(name);
2661 /* check if the group has been successfully created */
2662 if ((grp=getgrnam(name)) == NULL)
2663 return NT_STATUS_ACCESS_DENIED;
2665 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
2667 /* add the group to the mapping table */
2668 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, SE_PRIV_NONE))
2669 return NT_STATUS_ACCESS_DENIED;
2671 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2672 return NT_STATUS_NO_MEMORY;
2676 sid_copy(&info_sid, &global_sam_sid);
2677 sid_append_rid(&info->sid, r_u->rid);
2678 sid_to_string(sid_string, &info->sid);
2680 /* get a (unique) handle. open a policy on it. */
2681 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
2682 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2684 return NT_STATUS_NOPROBLEMO;
2687 /*********************************************************************
2688 _samr_create_dom_alias
2689 *********************************************************************/
2691 uint32 _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
2697 struct samr_info *info;
2699 /* Find the policy handle. Open a policy on it. */
2700 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid))
2701 return NT_STATUS_INVALID_HANDLE;
2703 if (!sid_equal(&dom_sid, &global_sam_sid))
2704 return NT_STATUS_ACCESS_DENIED;
2706 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2708 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
2710 /* check if group already exists */
2711 if ( (grp=getgrnam(name)) != NULL)
2712 return NT_STATUS_GROUP_EXISTS;
2714 /* we can create the UNIX group */
2715 smb_create_group(name);
2717 /* check if the group has been successfully created */
2718 if ((grp=getgrnam(name)) == NULL)
2719 return NT_STATUS_ACCESS_DENIED;
2721 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
2723 /* add the group to the mapping table */
2724 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, NULL, NULL, SE_PRIV_NONE))
2725 return NT_STATUS_ACCESS_DENIED;
2727 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2728 return NT_STATUS_NO_MEMORY;
2732 sid_copy(&info->sid, &global_sam_sid);
2733 sid_append_rid(&info->sid, r_u->rid);
2734 sid_to_string(sid_string, &info->sid);
2736 /* get a (unique) handle. open a policy on it. */
2737 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
2738 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2740 return NT_STATUS_NOPROBLEMO;
2743 /*********************************************************************
2744 _samr_query_groupinfo
2746 sends the name/comment pair of a domain group
2747 level 1 send also the number of users of that group
2748 *********************************************************************/
2750 uint32 _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
2756 GROUP_INFO_CTR *ctr;
2758 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2759 return NT_STATUS_INVALID_HANDLE;
2761 if (!get_domain_group_from_sid(group_sid, &map))
2762 return NT_STATUS_INVALID_HANDLE;
2764 ctr=(GROUP_INFO_CTR *)talloc(p->mem_ctx, sizeof(GROUP_INFO_CTR));
2766 return NT_STATUS_NO_MEMORY;
2768 switch (q_u->switch_level) {
2770 ctr->switch_value1 = 1;
2771 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2772 return NT_STATUS_NO_SUCH_GROUP;
2773 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
2777 ctr->switch_value1 = 4;
2778 init_samr_group_info4(&ctr->group.info4, map.comment);
2781 return NT_STATUS_INVALID_INFO_CLASS;
2784 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_NO_PROBLEMO);
2786 return NT_STATUS_NO_PROBLEMO;
2789 /*********************************************************************
2792 update a domain group's comment.
2793 *********************************************************************/
2795 uint32 _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
2799 GROUP_INFO_CTR *ctr;
2801 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2802 return NT_STATUS_INVALID_HANDLE;
2804 if (!get_domain_group_from_sid(group_sid, &map))
2805 return NT_STATUS_NO_SUCH_GROUP;
2809 switch (ctr->switch_value1) {
2811 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
2814 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
2817 return NT_STATUS_INVALID_INFO_CLASS;
2820 if(!add_mapping_entry(&map, TDB_REPLACE))
2821 return NT_STATUS_NO_SUCH_GROUP;
2823 return NT_STATUS_NO_PROBLEMO;
2826 /*********************************************************************
2827 _samr_get_dom_pwinfo
2828 *********************************************************************/
2830 uint32 _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
2832 /* Actually, returning zeros here works quite well :-). */
2833 return NT_STATUS_NOPROBLEMO;
2836 /*********************************************************************
2838 *********************************************************************/
2840 uint32 _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
2844 struct samr_info *info;
2847 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
2848 return NT_STATUS_INVALID_HANDLE;
2850 /* this should not be hard-coded like this */
2851 if (!sid_equal(&sid, &global_sam_sid))
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, q_u->rid_group);
2861 sid_to_string(sid_string, &info->sid);
2863 DEBUG(10, ("Opening SID: %s\n", sid_string));
2865 /* check if that group really exists */
2866 if (!get_domain_group_from_sid(info->sid, &map))
2867 return NT_STATUS_NO_SUCH_USER;
2869 /* get a (unique) handle. open a policy on it. */
2870 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
2871 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2873 return NT_STATUS_NO_PROBLEMO;
2876 /*********************************************************************
2878 *********************************************************************/
2880 uint32 _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
2882 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));