2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1997,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7 * Copyright (C) Paul Ashton 1997.
8 * Copyright (C) Marc Jacobsen 1999.
9 * Copyright (C) Jeremy Allison 2001.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * This is the implementation of the SAMR code.
32 extern fstring global_myworkgroup
;
33 extern pstring global_myname
;
34 extern DOM_SID global_sam_sid
;
35 extern DOM_SID global_sid_Builtin
;
37 extern rid_name domain_group_rids
[];
38 extern rid_name domain_alias_rids
[];
39 extern rid_name builtin_alias_rids
[];
42 /* for use by the \PIPE\samr policy */
44 uint32 status
; /* some sort of flag. best to record it. comes from opnum 0x39 */
47 /*******************************************************************
48 Function to free the per handle data.
49 ********************************************************************/
51 static void free_samr_info(void *ptr
)
56 /*******************************************************************
57 Ensure password info is never given out. Paranioa... JRA.
58 ********************************************************************/
60 static void samr_clear_passwd_fields( SAM_USER_INFO_21
*pass
, int num_entries
)
67 for (i
= 0; i
< num_entries
; i
++) {
68 memset(&pass
[i
].lm_pwd
, '\0', sizeof(pass
[i
].lm_pwd
));
69 memset(&pass
[i
].nt_pwd
, '\0', sizeof(pass
[i
].nt_pwd
));
73 static void samr_clear_sam_passwd(SAM_ACCOUNT
*sam_pass
)
78 if (sam_pass
->lm_pw
) memset(sam_pass
->lm_pw
, '\0', 16);
79 if (sam_pass
->nt_pw
) memset(sam_pass
->nt_pw
, '\0', 16);
82 /*******************************************************************
83 This next function should be replaced with something that
84 dynamically returns the correct user info..... JRA.
85 ********************************************************************/
87 static NTSTATUS
get_sampwd_entries(SAM_USER_INFO_21
*pw_buf
, int start_idx
,
88 int *total_entries
, int *num_entries
,
89 int max_num_entries
, uint16 acb_mask
)
91 SAM_ACCOUNT
*pwd
= NULL
;
92 BOOL not_finished
= True
;
98 return NT_STATUS_NO_MEMORY
;
102 if (!pdb_setsampwent(False
)) {
103 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
105 return NT_STATUS_ACCESS_DENIED
;
108 while (((not_finished
= pdb_getsampwent(pwd
)) != False
)
109 && (*num_entries
) < max_num_entries
)
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
));
140 DEBUG(5,(" acb_mask %x rejects\n", acb_mask
));
150 return STATUS_MORE_ENTRIES
;
155 static NTSTATUS
jf_get_sampwd_entries(SAM_USER_INFO_21
*pw_buf
, int start_idx
,
156 int *total_entries
, uint32
*num_entries
,
157 int max_num_entries
, uint16 acb_mask
)
159 SAM_ACCOUNT
*pwd
= NULL
;
160 BOOL not_finished
= True
;
166 return NT_STATUS_NO_MEMORY
;
168 DEBUG(10,("jf_get_sampwd_entries: start index:%d, max entries:%d, mask:%d\n",
169 start_idx
, max_num_entries
, acb_mask
));
171 if (!pdb_setsampwent(False
)) {
172 DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
173 return NT_STATUS_ACCESS_DENIED
;
178 while (((not_finished
= pdb_getsampwent(pwd
)) != False
) && (*num_entries
) < max_num_entries
) {
182 if (acb_mask
!= 0 && !(pdb_get_acct_ctrl(pwd
) & acb_mask
)) {
188 /* skip the requested number of entries.
189 not very efficient, but hey...
196 ZERO_STRUCTP(&pw_buf
[(*num_entries
)]);
198 user_name_len
= strlen(pdb_get_username(pwd
));
199 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, pdb_get_username(pwd
), user_name_len
);
200 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
202 full_name_len
= strlen(pdb_get_fullname(pwd
));
203 init_unistr2(&pw_buf
[(*num_entries
)].uni_full_name
, pdb_get_fullname(pwd
), full_name_len
);
204 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_full_name
, full_name_len
);
206 pw_buf
[(*num_entries
)].user_rid
= pdb_get_user_rid(pwd
);
207 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
209 /* Now check if the NT compatible password is available. */
210 if (pdb_get_nt_passwd(pwd
))
211 memcpy( pw_buf
[(*num_entries
)].nt_pwd
, pdb_get_nt_passwd(pwd
), 16);
213 pw_buf
[(*num_entries
)].acb_info
= pdb_get_acct_ctrl(pwd
);
215 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries
),
216 pdb_get_username(pwd
), pdb_get_user_rid(pwd
), pdb_get_acct_ctrl(pwd
) ));
225 *total_entries
= *num_entries
;
230 return STATUS_MORE_ENTRIES
;
236 * These next two functions are not used. Tagged
241 /*******************************************************************
242 This function uses the username map file and tries to map a UNIX
243 user name to an DOS name. (Sort of the reverse of the
244 map_username() function.) Since more than one DOS name can map
245 to the UNIX name, to reverse the mapping you have to specify
246 which corresponding DOS name you want; that's where the name_idx
247 parameter comes in. Returns the string requested or NULL if it
248 fails or can't complete the request for any reason. This doesn't
249 handle group names (starting with '@') or names starting with
250 '+' or '&'. If they are encountered, they are skipped.
251 ********************************************************************/
253 static char *unmap_unixname(char *unix_user_name
, int name_idx
)
255 char *mapfile
= lp_username_map();
260 if (!*unix_user_name
) return NULL
;
261 if (!*mapfile
) return NULL
;
263 lines
= file_lines_load(mapfile
, NULL
,False
);
265 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile
));
269 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile
, name_idx
));
271 for (i
=0; lines
[i
]; i
++) {
272 char *unixname
= lines
[i
];
273 char *dosname
= strchr(unixname
,'=');
280 while (isspace(*unixname
))
282 if ('!' == *unixname
) {
284 while (*unixname
&& isspace(*unixname
))
288 if (!*unixname
|| strchr("#;",*unixname
))
291 if (strncmp(unixname
, unix_user_name
, strlen(unix_user_name
)))
294 /* We have matched the UNIX user name */
296 while(next_token(&dosname
, tok
, LIST_SEP
, sizeof(tok
))) {
297 if (!strchr("@&+", *tok
)) {
306 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
307 file_lines_free(lines
);
310 file_lines_free(lines
);
315 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
316 file_lines_free(lines
);
320 /*******************************************************************
321 This function sets up a list of users taken from the list of
322 users that UNIX knows about, as well as all the user names that
323 Samba maps to a valid UNIX user name. (This should work with
325 ********************************************************************/
327 static BOOL
get_passwd_entries(SAM_USER_INFO_21
*pw_buf
,
329 int *total_entries
, int *num_entries
,
333 static struct passwd
*pwd
= NULL
;
334 static uint32 pw_rid
;
335 static BOOL orig_done
= False
;
336 static int current_idx
= 0;
337 static int mapped_idx
= 0;
340 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
343 (*total_entries
) = 0;
345 /* Skip all this stuff if we're in appliance mode */
347 if (lp_hide_local_users()) goto done
;
349 if (pw_buf
== NULL
) return False
;
351 if (current_idx
== 0) {
355 /* These two cases are inefficient, but should be called very rarely */
356 /* they are the cases where the starting index isn't picking up */
357 /* where we left off last time. It is efficient when it starts over */
358 /* at zero though. */
359 if (start_idx
> current_idx
) {
360 /* We aren't far enough; advance to start_idx */
361 while (current_idx
<= start_idx
) {
365 if ((pwd
= sys_getpwent()) == NULL
) break;
370 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
371 (current_idx
< start_idx
)) {
376 if (unmap_name
== NULL
) {
381 } else if (start_idx
< current_idx
) {
382 /* We are already too far; start over and advance to start_idx */
388 while (current_idx
< start_idx
) {
392 if ((pwd
= sys_getpwent()) == NULL
) break;
397 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
398 (current_idx
< start_idx
)) {
403 if (unmap_name
== NULL
) {
410 sep
= lp_winbind_separator();
412 /* now current_idx == start_idx */
413 while ((*num_entries
) < max_num_entries
) {
417 /* This does the original UNIX user itself */
419 if ((pwd
= sys_getpwent()) == NULL
) break;
421 /* Don't enumerate winbind users as they are not local */
423 if (strchr(pwd
->pw_name
, *sep
) != NULL
) {
427 user_name_len
= strlen(pwd
->pw_name
);
429 /* skip the trust account stored in the /etc/passwd file */
430 if (pwd
->pw_name
[user_name_len
-1]=='$')
433 pw_rid
= pdb_uid_to_user_rid(pwd
->pw_uid
);
434 ZERO_STRUCTP(&pw_buf
[(*num_entries
)]);
435 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, pwd
->pw_name
, user_name_len
);
436 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
437 pw_buf
[(*num_entries
)].user_rid
= pw_rid
;
438 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
440 pw_buf
[(*num_entries
)].acb_info
= ACB_NORMAL
;
442 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries
), pwd
->pw_name
, pw_rid
));
450 /* This does all the user names that map to the UNIX user */
451 while (((unmap_name
= unmap_unixname(pwd
->pw_name
, mapped_idx
)) != NULL
) &&
452 (*num_entries
< max_num_entries
)) {
453 user_name_len
= strlen(unmap_name
);
454 ZERO_STRUCTP(&pw_buf
[(*num_entries
)]);
455 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, unmap_name
, user_name_len
);
456 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
457 pw_buf
[(*num_entries
)].user_rid
= pw_rid
;
458 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
460 pw_buf
[(*num_entries
)].acb_info
= ACB_NORMAL
;
462 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries
), pwd
->pw_name
, pw_rid
));
470 if (unmap_name
== NULL
) {
471 /* done with 'aliases', go on to next UNIX user */
478 /* totally done, reset everything */
485 return (*num_entries
) > 0;
489 /*******************************************************************
491 ********************************************************************/
493 NTSTATUS
_samr_close_hnd(pipes_struct
*p
, SAMR_Q_CLOSE_HND
*q_u
, SAMR_R_CLOSE_HND
*r_u
)
495 r_u
->status
= NT_STATUS_OK
;
497 /* close the policy handle */
498 if (!close_policy_hnd(p
, &q_u
->pol
))
499 return NT_STATUS_OBJECT_NAME_INVALID
;
501 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__
));
506 /*******************************************************************
507 samr_reply_open_domain
508 ********************************************************************/
510 NTSTATUS
_samr_open_domain(pipes_struct
*p
, SAMR_Q_OPEN_DOMAIN
*q_u
, SAMR_R_OPEN_DOMAIN
*r_u
)
512 struct samr_info
*info
;
514 r_u
->status
= NT_STATUS_OK
;
516 /* find the connection policy handle. */
517 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
518 return NT_STATUS_INVALID_HANDLE
;
520 /* associate the domain SID with the (unique) handle. */
521 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
522 return NT_STATUS_NO_MEMORY
;
525 info
->sid
= q_u
->dom_sid
.sid
;
527 /* get a (unique) handle. open a policy on it. */
528 if (!create_policy_hnd(p
, &r_u
->domain_pol
, free_samr_info
, (void *)info
))
529 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
531 DEBUG(5,("samr_open_domain: %d\n", __LINE__
));
536 static uint32
get_lsa_policy_samr_rid(struct samr_info
*info
)
539 DEBUG(3,("Error getting policy\n"));
543 return info
->sid
.sub_auths
[info
->sid
.num_auths
-1];
546 /*******************************************************************
547 _samr_get_usrdom_pwinfo
548 ********************************************************************/
550 NTSTATUS
_samr_get_usrdom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_USRDOM_PWINFO
*q_u
, SAMR_R_GET_USRDOM_PWINFO
*r_u
)
552 struct samr_info
*info
= NULL
;
554 r_u
->status
= NT_STATUS_OK
;
556 /* find the policy handle. open a policy on it. */
557 if (!find_policy_by_hnd(p
, &q_u
->user_pol
, (void **)&info
)) {
558 return NT_STATUS_INVALID_HANDLE
;
561 /* find the user's rid */
562 if (get_lsa_policy_samr_rid(info
) == 0xffffffff) {
563 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
566 init_samr_r_get_usrdom_pwinfo(r_u
, NT_STATUS_OK
);
568 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__
));
573 /*******************************************************************
575 ********************************************************************/
577 static NTSTATUS
samr_make_usr_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC_BUF
**buf
, DOM_SID
*usr_sid
)
579 extern DOM_SID global_sid_Builtin
;
580 extern DOM_SID global_sid_World
;
588 SEC_DESC
*psd
= NULL
;
591 sid_copy(&adm_sid
, &global_sid_Builtin
);
592 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
594 sid_copy(&act_sid
, &global_sid_Builtin
);
595 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
597 init_sec_access(&mask
, 0x2035b);
598 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
600 init_sec_access(&mask
, 0xf07ff);
601 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
602 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
604 init_sec_access(&mask
,0x20044);
605 init_sec_ace(&ace
[3], usr_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
607 if((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 4, ace
)) == NULL
)
608 return NT_STATUS_NO_MEMORY
;
610 if((psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, &sd_size
)) == NULL
)
611 return NT_STATUS_NO_MEMORY
;
613 if((*buf
= make_sec_desc_buf(ctx
, sd_size
, psd
)) == NULL
)
614 return NT_STATUS_NO_MEMORY
;
619 static BOOL
get_lsa_policy_samr_sid(pipes_struct
*p
, POLICY_HND
*pol
, DOM_SID
*sid
)
621 struct samr_info
*info
= NULL
;
623 /* find the policy handle. open a policy on it. */
624 if (!find_policy_by_hnd(p
, pol
, (void **)&info
))
634 /*******************************************************************
636 ********************************************************************/
638 NTSTATUS
_samr_query_sec_obj(pipes_struct
*p
, SAMR_Q_QUERY_SEC_OBJ
*q_u
, SAMR_R_QUERY_SEC_OBJ
*r_u
)
642 r_u
->status
= NT_STATUS_OK
;
646 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &pol_sid
))
647 return NT_STATUS_INVALID_HANDLE
;
649 r_u
->status
= samr_make_usr_obj_sd(p
->mem_ctx
, &r_u
->buf
, &pol_sid
);
651 if (NT_STATUS_IS_OK(r_u
->status
))
657 /*******************************************************************
658 makes a SAM_ENTRY / UNISTR2* structure from a user list.
659 ********************************************************************/
661 static void make_user_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
662 uint32 num_sam_entries
, SAM_USER_INFO_21
*pass
)
671 if (num_sam_entries
== 0)
674 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
676 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
678 if (sam
== NULL
|| uni_name
== NULL
) {
679 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
683 for (i
= 0; i
< num_sam_entries
; i
++) {
684 int len
= pass
[i
].uni_user_name
.uni_str_len
;
686 init_sam_entry(&sam
[i
], len
, pass
[i
].user_rid
);
687 copy_unistr2(&uni_name
[i
], &pass
[i
].uni_user_name
);
691 *uni_name_pp
= uni_name
;
694 /*******************************************************************
695 samr_reply_enum_dom_users
696 ********************************************************************/
698 NTSTATUS
_samr_enum_dom_users(pipes_struct
*p
, SAMR_Q_ENUM_DOM_USERS
*q_u
, SAMR_R_ENUM_DOM_USERS
*r_u
)
700 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
702 int total_entries
= 0;
704 r_u
->status
= NT_STATUS_OK
;
706 /* find the policy handle. open a policy on it. */
707 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
708 return NT_STATUS_INVALID_HANDLE
;
710 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
713 r_u
->status
= get_sampwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
714 MAX_SAM_ENTRIES
, q_u
->acb_mask
);
717 if (NT_STATUS_IS_ERR(r_u
->status
))
720 samr_clear_passwd_fields(pass
, num_entries
);
723 * Note from JRA. total_entries is not being used here. Currently if there is a
724 * large user base then it looks like NT will enumerate until get_sampwd_entries
725 * returns False due to num_entries being zero. This will cause an access denied
726 * return. I don't think this is right and needs further investigation. Note that
727 * this is also the same in the TNG code (I don't think that has been tested with
728 * a very large user list as MAX_SAM_ENTRIES is set to 600).
730 * I also think that one of the 'num_entries' return parameters is probably
731 * the "max entries" parameter - but in the TNG code they're all currently set to the same
732 * value (again I think this is wrong).
735 make_user_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_acct_name
, num_entries
, pass
);
737 init_samr_r_enum_dom_users(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
739 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
744 /*******************************************************************
745 makes a SAM_ENTRY / UNISTR2* structure from a group list.
746 ********************************************************************/
748 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
749 uint32 num_sam_entries
, DOMAIN_GRP
*grp
)
758 if (num_sam_entries
== 0)
761 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
763 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
765 if (sam
== NULL
|| uni_name
== NULL
) {
766 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
770 for (i
= 0; i
< num_sam_entries
; i
++) {
772 * JRA. I think this should include the null. TNG does not.
774 int len
= strlen(grp
[i
].name
)+1;
776 init_sam_entry(&sam
[i
], len
, grp
[i
].rid
);
777 init_unistr2(&uni_name
[i
], grp
[i
].name
, len
);
781 *uni_name_pp
= uni_name
;
784 /*******************************************************************
785 Get the group entries - similar to get_sampwd_entries().
786 ********************************************************************/
788 static NTSTATUS
get_group_alias_entries(DOMAIN_GRP
*d_grp
, DOM_SID
*sid
, uint32 start_idx
,
789 uint32
*p_num_entries
, uint32 max_entries
)
793 uint32 num_entries
= 0;
795 sid_to_string(sid_str
, sid
);
796 sid_to_string(sam_sid_str
, &global_sam_sid
);
800 /* well-known aliases */
801 if (strequal(sid_str
, "S-1-5-32")) {
803 while (!lp_hide_local_users() &&
804 num_entries
< max_entries
&&
805 ((alias_name
= builtin_alias_rids
[num_entries
].name
) != NULL
)) {
807 fstrcpy(d_grp
[num_entries
].name
, alias_name
);
808 d_grp
[num_entries
].rid
= builtin_alias_rids
[num_entries
].rid
;
812 } else if (strequal(sid_str
, sam_sid_str
) && !lp_hide_local_users()) {
815 struct sys_grent
*glist
;
816 struct sys_grent
*grp
;
818 sep
= lp_winbind_separator();
821 /* we return the UNIX groups here. This seems to be the right */
822 /* thing to do, since NT member servers return their local */
823 /* groups in the same situation. */
825 /* use getgrent_list() to retrieve the list of groups to avoid
826 * problems with getgrent possible infinite loop by internal
827 * libc grent structures overwrites by called functions */
828 grp
= glist
= getgrent_list();
830 return NT_STATUS_NO_MEMORY
;
832 for (;(num_entries
< max_entries
) && (grp
!= NULL
); grp
= grp
->next
) {
836 fstrcpy(name
,grp
->gr_name
);
837 DEBUG(10,("get_group_alias_entries: got group %s\n", name
));
839 /* Don't return winbind groups as they are not local! */
841 if (strchr(name
, *sep
) != NULL
) {
842 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", name
));
846 /* Don't return user private groups... */
847 if (Get_Pwnam(name
, False
) != 0) {
848 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", name
));
852 trid
= pdb_gid_to_group_rid(grp
->gr_gid
);
853 for( i
= 0; i
< num_entries
; i
++)
854 if ( d_grp
[i
].rid
== trid
)
857 if ( i
< num_entries
)
858 continue; /* rid was there, dup! */
860 /* JRA - added this for large group db enumeration... */
863 /* skip the requested number of entries.
864 not very efficient, but hey...
870 fstrcpy(d_grp
[num_entries
].name
, name
);
871 d_grp
[num_entries
].rid
= trid
;
878 *p_num_entries
= num_entries
;
880 if (num_entries
>= max_entries
)
881 return STATUS_MORE_ENTRIES
;
885 /*******************************************************************
886 Get the group entries - similar to get_sampwd_entries().
887 ********************************************************************/
889 static NTSTATUS
get_group_domain_entries(DOMAIN_GRP
*d_grp
, DOM_SID
*sid
, uint32 start_idx
,
890 uint32
*p_num_entries
, uint32 max_entries
)
894 uint32 num_entries
= 0;
895 fstring name
="Domain Admins";
896 fstring comment
="Just to make it work !";
898 sid_to_string(sid_str
, sid
);
899 sid_to_string(sam_sid_str
, &global_sam_sid
);
903 fstrcpy(d_grp
[0].name
, name
);
904 fstrcpy(d_grp
[0].comment
, comment
);
905 d_grp
[0].rid
= DOMAIN_GROUP_RID_ADMINS
;
906 d_grp
[0].attr
=SID_NAME_DOM_GRP
;
908 fstrcpy(d_grp
[1].name
, "Domain Users");
909 fstrcpy(d_grp
[1].comment
, "Just to make it work !");
910 d_grp
[1].rid
= DOMAIN_GROUP_RID_USERS
;
911 d_grp
[1].attr
=SID_NAME_DOM_GRP
;
915 *p_num_entries
= num_entries
;
920 /*******************************************************************
921 samr_reply_enum_dom_groups
922 Only reply with one group - domain admins. This must be fixed for
924 ********************************************************************/
926 NTSTATUS
_samr_enum_dom_groups(pipes_struct
*p
, SAMR_Q_ENUM_DOM_GROUPS
*q_u
, SAMR_R_ENUM_DOM_GROUPS
*r_u
)
932 r_u
->status
= NT_STATUS_OK
;
934 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
))
935 return NT_STATUS_INVALID_HANDLE
;
937 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__
));
939 get_group_domain_entries(grp
, &sid
, q_u
->start_idx
, &num_entries
, MAX_SAM_ENTRIES
);
941 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 NTSTATUS
_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
[MAX_SAM_ENTRIES
];
958 uint32 num_entries
= 0;
962 r_u
->status
= NT_STATUS_OK
;
964 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
))
965 return NT_STATUS_INVALID_HANDLE
;
967 sid_to_string(sid_str
, &sid
);
968 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str
));
970 r_u
->status
= get_group_alias_entries(grp
, &sid
, q_u
->start_idx
,
971 &num_entries
, MAX_SAM_ENTRIES
);
972 if (NT_STATUS_IS_ERR(r_u
->status
))
975 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
, num_entries
);
979 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__
));
984 /*******************************************************************
985 samr_reply_query_dispinfo
986 ********************************************************************/
988 NTSTATUS
_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
[MAX_SAM_ENTRIES
];
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_OK
;
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 r_u
->status
= 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 r_u
->status
= get_sampwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
1031 MAX_SAM_ENTRIES
, acb_mask
);
1034 r_u
->status
= jf_get_sampwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
1035 MAX_SAM_ENTRIES
, acb_mask
);
1038 if (NT_STATUS_IS_ERR(r_u
->status
)) {
1039 DEBUG(5, ("get_sampwd_entries: failed\n"));
1045 r_u
->status
= get_group_domain_entries(grps
, &sid
, q_u
->start_idx
, &num_entries
, MAX_SAM_ENTRIES
);
1048 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u
->switch_level
));
1049 return NT_STATUS_INVALID_INFO_CLASS
;
1052 orig_num_entries
= num_entries
;
1054 if (num_entries
> q_u
->max_entries
)
1055 num_entries
= q_u
->max_entries
;
1057 if (num_entries
> MAX_SAM_ENTRIES
) {
1058 num_entries
= MAX_SAM_ENTRIES
;
1059 DEBUG(5, ("limiting number of entries to %d\n", num_entries
));
1062 /* Ensure password info is never given out here. PARANOIA... JRA */
1063 samr_clear_passwd_fields(pass
, num_entries
);
1065 data_size
= q_u
->max_size
;
1067 if (!(ctr
= (SAM_DISPINFO_CTR
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_DISPINFO_CTR
))))
1068 return NT_STATUS_NO_MEMORY
;
1072 /* Now create reply structure */
1073 switch (q_u
->switch_level
) {
1076 if (!(ctr
->sam
.info1
= (SAM_DISPINFO_1
*)talloc_zero(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_1
))))
1077 return NT_STATUS_NO_MEMORY
;
1079 disp_ret
= init_sam_dispinfo_1(p
->mem_ctx
,ctr
->sam
.info1
, &num_entries
, &data_size
, q_u
->start_idx
, pass
);
1080 if (NT_STATUS_IS_ERR(disp_ret
))
1085 if (!(ctr
->sam
.info2
= (SAM_DISPINFO_2
*)talloc_zero(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_2
))))
1086 return NT_STATUS_NO_MEMORY
;
1088 disp_ret
= init_sam_dispinfo_2(p
->mem_ctx
,ctr
->sam
.info2
, &num_entries
, &data_size
, q_u
->start_idx
, pass
);
1089 if (NT_STATUS_IS_ERR(disp_ret
))
1094 if (!(ctr
->sam
.info3
= (SAM_DISPINFO_3
*)talloc_zero(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_3
))))
1095 return NT_STATUS_NO_MEMORY
;
1097 disp_ret
= init_sam_dispinfo_3(p
->mem_ctx
,ctr
->sam
.info3
, &num_entries
, &data_size
, q_u
->start_idx
, grps
);
1098 if (NT_STATUS_IS_ERR(disp_ret
))
1103 if (!(ctr
->sam
.info4
= (SAM_DISPINFO_4
*)talloc_zero(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_4
))))
1104 return NT_STATUS_NO_MEMORY
;
1106 disp_ret
= init_sam_dispinfo_4(p
->mem_ctx
,ctr
->sam
.info4
, &num_entries
, &data_size
, q_u
->start_idx
, pass
);
1107 if (NT_STATUS_IS_ERR(disp_ret
))
1112 if (!(ctr
->sam
.info5
= (SAM_DISPINFO_5
*)talloc_zero(p
->mem_ctx
,num_entries
*sizeof(SAM_DISPINFO_5
))))
1113 return NT_STATUS_NO_MEMORY
;
1115 disp_ret
= init_sam_dispinfo_5(p
->mem_ctx
,ctr
->sam
.info5
, &num_entries
, &data_size
, q_u
->start_idx
, grps
);
1116 if (NT_STATUS_IS_ERR(disp_ret
))
1120 ctr
->sam
.info
= NULL
;
1121 return NT_STATUS_INVALID_INFO_CLASS
;
1124 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__
));
1126 if (num_entries
< orig_num_entries
)
1127 return STATUS_MORE_ENTRIES
;
1129 init_samr_r_query_dispinfo(r_u
, num_entries
, data_size
, q_u
->switch_level
, ctr
, r_u
->status
);
1134 /*******************************************************************
1135 samr_reply_query_aliasinfo
1136 ********************************************************************/
1138 NTSTATUS
_samr_query_aliasinfo(pipes_struct
*p
, SAMR_Q_QUERY_ALIASINFO
*q_u
, SAMR_R_QUERY_ALIASINFO
*r_u
)
1140 fstring alias_desc
= "Local Unix group";
1142 enum SID_NAME_USE type
;
1144 struct samr_info
*info
= NULL
;
1146 r_u
->status
= NT_STATUS_OK
;
1148 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1150 /* find the policy handle. open a policy on it. */
1151 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1152 return NT_STATUS_INVALID_HANDLE
;
1154 alias_rid
= get_lsa_policy_samr_rid(info
);
1155 if(alias_rid
== 0xffffffff)
1156 return NT_STATUS_NO_SUCH_ALIAS
;
1158 if(!local_lookup_rid(alias_rid
, alias
, &type
))
1159 return NT_STATUS_NO_SUCH_ALIAS
;
1161 switch (q_u
->switch_level
) {
1164 r_u
->ctr
.switch_value1
= 3;
1165 init_samr_alias_info3(&r_u
->ctr
.alias
.info3
, alias_desc
);
1168 return NT_STATUS_INVALID_INFO_CLASS
;
1171 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1177 /*******************************************************************
1178 samr_reply_lookup_ids
1179 ********************************************************************/
1181 uint32
_samr_lookup_ids(pipes_struct
*p
, SAMR_Q_LOOKUP_IDS
*q_u
, SAMR_R_LOOKUP_IDS
*r_u
)
1183 uint32 rid
[MAX_SAM_ENTRIES
];
1184 int num_rids
= q_u
->num_sids1
;
1186 r_u
->status
= NT_STATUS_OK
;
1188 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1190 if (num_rids
> MAX_SAM_ENTRIES
) {
1191 num_rids
= MAX_SAM_ENTRIES
;
1192 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids
));
1197 SMB_ASSERT_ARRAY(q_u
->uni_user_name
, num_rids
);
1199 for (i
= 0; i
< num_rids
&& status
== 0; i
++)
1201 struct sam_passwd
*sam_pass
;
1205 fstrcpy(user_name
, unistrn2(q_u
->uni_user_name
[i
].buffer
,
1206 q_u
->uni_user_name
[i
].uni_str_len
));
1208 /* find the user account */
1210 sam_pass
= get_smb21pwd_entry(user_name
, 0);
1213 if (sam_pass
== NULL
)
1215 status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1220 rid
[i
] = sam_pass
->user_rid
;
1226 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
1228 init_samr_r_lookup_ids(&r_u
, num_rids
, rid
, NT_STATUS_OK
);
1230 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1236 /*******************************************************************
1238 ********************************************************************/
1240 NTSTATUS
_samr_lookup_names(pipes_struct
*p
, SAMR_Q_LOOKUP_NAMES
*q_u
, SAMR_R_LOOKUP_NAMES
*r_u
)
1242 uint32 rid
[MAX_SAM_ENTRIES
];
1244 enum SID_NAME_USE type
[MAX_SAM_ENTRIES
];
1245 enum SID_NAME_USE local_type
;
1247 int num_rids
= q_u
->num_names2
;
1251 r_u
->status
= NT_STATUS_OK
;
1253 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1258 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
)) {
1259 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, 0, NULL
, NULL
, NT_STATUS_OBJECT_TYPE_MISMATCH
);
1263 if (num_rids
> MAX_SAM_ENTRIES
) {
1264 num_rids
= MAX_SAM_ENTRIES
;
1265 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids
));
1268 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str
, &pol_sid
)));
1270 for (i
= 0; i
< num_rids
; i
++) {
1274 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1276 rid
[i
] = 0xffffffff;
1277 type
[i
] = SID_NAME_UNKNOWN
;
1279 fstrcpy(name
, dos_unistrn2(q_u
->uni_name
[i
].buffer
, q_u
->uni_name
[i
].uni_str_len
));
1282 * we are only looking for a name
1283 * the SID we get back can be outside
1284 * the scope of the pol_sid
1286 * in clear: it prevents to reply to domain\group: yes
1287 * when only builtin\group exists.
1289 * a cleaner code is to add the sid of the domain we're looking in
1290 * to the local_lookup_name function.
1293 if(local_lookup_name(global_myname
, name
, &sid
, &local_type
)) {
1294 sid_split_rid(&sid
, &local_rid
);
1296 if (sid_equal(&sid
, &pol_sid
)) {
1299 r_u
->status
= NT_STATUS_OK
;
1304 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, num_rids
, rid
, (uint32
*)type
, r_u
->status
);
1306 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1311 /*******************************************************************
1312 _samr_chgpasswd_user
1313 ********************************************************************/
1315 NTSTATUS
_samr_chgpasswd_user(pipes_struct
*p
, SAMR_Q_CHGPASSWD_USER
*q_u
, SAMR_R_CHGPASSWD_USER
*r_u
)
1320 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1322 r_u
->status
= NT_STATUS_OK
;
1324 fstrcpy(user_name
, dos_unistrn2(q_u
->uni_user_name
.buffer
, q_u
->uni_user_name
.uni_str_len
));
1325 fstrcpy(wks
, dos_unistrn2(q_u
->uni_dest_host
.buffer
, q_u
->uni_dest_host
.uni_str_len
));
1327 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name
, wks
));
1330 * Pass the user through the NT -> unix user mapping
1334 (void)map_username(user_name
);
1337 * Do any UNIX username case mangling.
1339 (void)Get_Pwnam( user_name
, True
);
1341 if (!pass_oem_change(user_name
, q_u
->lm_newpass
.pass
, q_u
->lm_oldhash
.hash
,
1342 q_u
->nt_newpass
.pass
, q_u
->nt_oldhash
.hash
))
1343 r_u
->status
= NT_STATUS_WRONG_PASSWORD
;
1345 init_samr_r_chgpasswd_user(r_u
, r_u
->status
);
1347 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1352 /*******************************************************************
1353 makes a SAMR_R_LOOKUP_RIDS structure.
1354 ********************************************************************/
1356 static BOOL
make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
, fstring names
[],
1357 UNIHDR
**pp_hdr_name
, UNISTR2
**pp_uni_name
)
1360 UNIHDR
*hdr_name
= NULL
;
1361 UNISTR2
*uni_name
= NULL
;
1363 *pp_uni_name
= NULL
;
1364 *pp_hdr_name
= NULL
;
1366 if (num_names
!= 0) {
1367 hdr_name
= (UNIHDR
*)talloc_zero(ctx
, sizeof(UNIHDR
)*num_names
);
1368 if (hdr_name
== NULL
)
1371 uni_name
= (UNISTR2
*)talloc_zero(ctx
,sizeof(UNISTR2
)*num_names
);
1372 if (uni_name
== NULL
)
1376 for (i
= 0; i
< num_names
; i
++) {
1377 int len
= names
[i
] != NULL
? strlen(names
[i
]) : 0;
1378 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
]));
1379 init_uni_hdr(&hdr_name
[i
], len
);
1380 init_unistr2(&uni_name
[i
], names
[i
], len
);
1383 *pp_uni_name
= uni_name
;
1384 *pp_hdr_name
= hdr_name
;
1389 /*******************************************************************
1391 ********************************************************************/
1393 NTSTATUS
_samr_lookup_rids(pipes_struct
*p
, SAMR_Q_LOOKUP_RIDS
*q_u
, SAMR_R_LOOKUP_RIDS
*r_u
)
1395 fstring group_names
[MAX_SAM_ENTRIES
];
1396 uint32
*group_attrs
= NULL
;
1397 UNIHDR
*hdr_name
= NULL
;
1398 UNISTR2
*uni_name
= NULL
;
1400 int num_rids
= q_u
->num_rids1
;
1403 r_u
->status
= NT_STATUS_OK
;
1405 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1407 /* find the policy handle. open a policy on it. */
1408 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
))
1409 return NT_STATUS_INVALID_HANDLE
;
1411 if (num_rids
> MAX_SAM_ENTRIES
) {
1412 num_rids
= MAX_SAM_ENTRIES
;
1413 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids
));
1417 if ((group_attrs
= (uint32
*)talloc_zero(p
->mem_ctx
, num_rids
* sizeof(uint32
))) == NULL
)
1418 return NT_STATUS_NO_MEMORY
;
1421 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1423 for (i
= 0; i
< num_rids
; i
++) {
1427 enum SID_NAME_USE type
;
1429 group_attrs
[i
] = SID_NAME_UNKNOWN
;
1430 *group_names
[i
] = '\0';
1432 if (sid_equal(&pol_sid
, &global_sam_sid
)) {
1433 sid_copy(&sid
, &pol_sid
);
1434 sid_append_rid(&sid
, q_u
->rid
[i
]);
1436 if (lookup_sid(&sid
, domname
, tmpname
, &type
)) {
1437 r_u
->status
= NT_STATUS_OK
;
1438 group_attrs
[i
] = (uint32
)type
;
1439 fstrcpy(group_names
[i
],tmpname
);
1444 if(!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, group_names
, &hdr_name
, &uni_name
))
1445 return NT_STATUS_NO_MEMORY
;
1447 init_samr_r_lookup_rids(r_u
, num_rids
, hdr_name
, uni_name
, group_attrs
);
1449 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1454 /*******************************************************************
1455 _api_samr_open_user. Safe - gives out no passwd info.
1456 ********************************************************************/
1458 NTSTATUS
_api_samr_open_user(pipes_struct
*p
, SAMR_Q_OPEN_USER
*q_u
, SAMR_R_OPEN_USER
*r_u
)
1460 SAM_ACCOUNT
*sampass
=NULL
;
1462 POLICY_HND domain_pol
= q_u
->domain_pol
;
1463 uint32 user_rid
= q_u
->user_rid
;
1464 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1465 struct samr_info
*info
= NULL
;
1468 r_u
->status
= NT_STATUS_OK
;
1470 /* find the domain policy handle. */
1471 if (!find_policy_by_hnd(p
, &domain_pol
, NULL
))
1472 return NT_STATUS_INVALID_HANDLE
;
1474 pdb_init_sam(&sampass
);
1477 ret
=pdb_getsampwrid(sampass
, user_rid
);
1480 /* check that the RID exists in our domain. */
1482 pdb_free_sam(sampass
);
1483 return NT_STATUS_NO_SUCH_USER
;
1486 samr_clear_sam_passwd(sampass
);
1487 pdb_free_sam(sampass
);
1489 /* Get the domain SID stored in the domain policy */
1490 if(!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
))
1491 return NT_STATUS_INVALID_HANDLE
;
1493 /* append the user's RID to it */
1494 if(!sid_append_rid(&sid
, user_rid
))
1495 return NT_STATUS_NO_SUCH_USER
;
1497 /* associate the user's SID with the new handle. */
1498 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
1499 return NT_STATUS_NO_MEMORY
;
1504 /* get a (unique) handle. open a policy on it. */
1505 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
))
1506 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1511 /*************************************************************************
1512 get_user_info_10. Safe. Only gives out acb bits.
1513 *************************************************************************/
1515 static BOOL
get_user_info_10(SAM_USER_INFO_10
*id10
, uint32 user_rid
)
1517 SAM_ACCOUNT
*smbpass
=NULL
;
1520 if (!pdb_rid_is_user(user_rid
)) {
1521 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1525 pdb_init_sam(&smbpass
);
1528 ret
= pdb_getsampwrid(smbpass
, user_rid
);
1532 DEBUG(4,("User 0x%x not found\n", user_rid
));
1533 pdb_free_sam(smbpass
);
1537 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass
) ));
1540 init_sam_user_info10(id10
, pdb_get_acct_ctrl(smbpass
) );
1542 samr_clear_sam_passwd(smbpass
);
1543 pdb_free_sam(smbpass
);
1548 /*************************************************************************
1549 get_user_info_12. OK - this is the killer as it gives out password info.
1550 Ensure that this is only allowed on an encrypted connection with a root
1552 *************************************************************************/
1554 static NTSTATUS
get_user_info_12(pipes_struct
*p
, SAM_USER_INFO_12
* id12
, uint32 user_rid
)
1556 SAM_ACCOUNT
*smbpass
=NULL
;
1559 if (!p
->ntlmssp_auth_validated
)
1560 return NT_STATUS_ACCESS_DENIED
;
1562 if (!(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SIGN
) || !(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SEAL
))
1563 return NT_STATUS_ACCESS_DENIED
;
1566 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1568 pdb_init_sam(&smbpass
);
1570 ret
= pdb_getsampwrid(smbpass
, user_rid
);
1573 DEBUG(4, ("User 0x%x not found\n", user_rid
));
1574 pdb_free_sam(smbpass
);
1575 return (geteuid() == (uid_t
)0) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
1578 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
1580 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
1581 pdb_free_sam(smbpass
);
1582 return NT_STATUS_ACCOUNT_DISABLED
;
1586 init_sam_user_info12(id12
, pdb_get_lanman_passwd(smbpass
), pdb_get_nt_passwd(smbpass
));
1588 pdb_free_sam(smbpass
);
1590 return NT_STATUS_OK
;
1593 #if 1 /* JRA - re-enabled... JERRY - why was this removed ? */
1594 /*************************************************************************
1596 *************************************************************************/
1598 static BOOL
get_user_info_20(SAM_USER_INFO_20
*id20
, uint32 user_rid
)
1600 SAM_ACCOUNT
*sampass
=NULL
;
1603 if (!pdb_rid_is_user(user_rid
)) {
1604 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1608 pdb_init_sam(&sampass
);
1611 ret
= pdb_getsampwrid(sampass
, user_rid
);
1615 DEBUG(4,("User 0x%x not found\n", user_rid
));
1616 pdb_free_sam(sampass
);
1620 samr_clear_sam_passwd(sampass
);
1622 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1625 init_sam_user_info20A(id20
, sampass
);
1627 pdb_free_sam(sampass
);
1633 /*************************************************************************
1635 *************************************************************************/
1637 static BOOL
get_user_info_21(SAM_USER_INFO_21
*id21
, uint32 user_rid
)
1639 SAM_ACCOUNT
*sampass
=NULL
;
1642 if (!pdb_rid_is_user(user_rid
)) {
1643 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1647 pdb_init_sam(&sampass
);
1650 ret
= pdb_getsampwrid(sampass
, user_rid
);
1654 DEBUG(4,("User 0x%x not found\n", user_rid
));
1655 pdb_free_sam(sampass
);
1659 samr_clear_sam_passwd(sampass
);
1661 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1664 init_sam_user_info21A(id21
, sampass
);
1666 pdb_free_sam(sampass
);
1671 /*******************************************************************
1672 _samr_query_userinfo
1673 ********************************************************************/
1675 NTSTATUS
_samr_query_userinfo(pipes_struct
*p
, SAMR_Q_QUERY_USERINFO
*q_u
, SAMR_R_QUERY_USERINFO
*r_u
)
1677 SAM_USERINFO_CTR
*ctr
;
1679 struct samr_info
*info
= NULL
;
1681 r_u
->status
=NT_STATUS_OK
;
1683 /* search for the handle */
1684 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1685 return NT_STATUS_INVALID_HANDLE
;
1687 /* find the user's rid */
1688 if ((rid
= get_lsa_policy_samr_rid(info
)) == 0xffffffff)
1689 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1691 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid
));
1693 ctr
= (SAM_USERINFO_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USERINFO_CTR
));
1695 return NT_STATUS_NO_MEMORY
;
1699 /* ok! user info levels (lots: see MSDEV help), off we go... */
1700 ctr
->switch_value
= q_u
->switch_value
;
1702 switch (q_u
->switch_value
) {
1704 ctr
->info
.id10
= (SAM_USER_INFO_10
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USER_INFO_10
));
1705 if (ctr
->info
.id10
== NULL
)
1706 return NT_STATUS_NO_MEMORY
;
1708 if (!get_user_info_10(ctr
->info
.id10
, rid
))
1709 return NT_STATUS_NO_SUCH_USER
;
1713 /* whoops - got this wrong. i think. or don't understand what's happening. */
1717 info
= (void *)&id11
;
1719 expire
.low
= 0xffffffff;
1720 expire
.high
= 0x7fffffff;
1722 ctr
->info
.id
= (SAM_USER_INFO_11
*)talloc_zero(p
->mem_ctx
,
1727 init_sam_user_info11(ctr
->info
.id11
, &expire
,
1728 "BROOKFIELDS$", /* name */
1729 0x03ef, /* user rid */
1730 0x201, /* group rid */
1731 0x0080); /* acb info */
1738 ctr
->info
.id12
= (SAM_USER_INFO_12
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USER_INFO_12
));
1739 if (ctr
->info
.id12
== NULL
)
1740 return NT_STATUS_NO_MEMORY
;
1742 if (NT_STATUS_IS_ERR(r_u
->status
= get_user_info_12(p
, ctr
->info
.id12
, rid
)))
1747 ctr
->info
.id20
= (SAM_USER_INFO_20
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_USER_INFO_20
));
1748 if (ctr
->info
.id20
== NULL
)
1749 return NT_STATUS_NO_MEMORY
;
1750 if (!get_user_info_20(ctr
->info
.id20
, rid
))
1751 return NT_STATUS_NO_SUCH_USER
;
1755 ctr
->info
.id21
= (SAM_USER_INFO_21
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_USER_INFO_21
));
1756 if (ctr
->info
.id21
== NULL
)
1757 return NT_STATUS_NO_MEMORY
;
1758 if (!get_user_info_21(ctr
->info
.id21
, rid
))
1759 return NT_STATUS_NO_SUCH_USER
;
1763 return NT_STATUS_INVALID_INFO_CLASS
;
1766 init_samr_r_query_userinfo(r_u
, ctr
, r_u
->status
);
1768 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__
));
1773 /*******************************************************************
1774 samr_reply_query_usergroups
1775 ********************************************************************/
1777 NTSTATUS
_samr_query_usergroups(pipes_struct
*p
, SAMR_Q_QUERY_USERGROUPS
*q_u
, SAMR_R_QUERY_USERGROUPS
*r_u
)
1779 SAM_ACCOUNT
*sam_pass
=NULL
;
1780 DOM_GID
*gids
= NULL
;
1784 struct samr_info
*info
= NULL
;
1787 r_u
->status
= NT_STATUS_OK
;
1789 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
1791 /* find the policy handle. open a policy on it. */
1792 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1793 return NT_STATUS_INVALID_HANDLE
;
1795 /* find the user's rid */
1796 if ((rid
= get_lsa_policy_samr_rid(info
)) == 0xffffffff)
1797 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1799 pdb_init_sam(&sam_pass
);
1802 ret
= pdb_getsampwrid(sam_pass
, rid
);
1806 samr_clear_sam_passwd(sam_pass
);
1807 return NT_STATUS_NO_SUCH_USER
;
1810 get_domain_user_groups(groups
, pdb_get_username(sam_pass
));
1812 num_groups
= make_dom_gids(p
->mem_ctx
, groups
, &gids
);
1814 /* construct the response. lkclXXXX: gids are not copied! */
1815 init_samr_r_query_usergroups(r_u
, num_groups
, gids
, r_u
->status
);
1817 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
1819 samr_clear_sam_passwd(sam_pass
);
1824 /*******************************************************************
1825 _samr_query_dom_info
1826 ********************************************************************/
1828 NTSTATUS
_samr_query_dom_info(pipes_struct
*p
, SAMR_Q_QUERY_DOMAIN_INFO
*q_u
, SAMR_R_QUERY_DOMAIN_INFO
*r_u
)
1832 if ((ctr
= (SAM_UNK_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_UNK_CTR
))) == NULL
)
1833 return NT_STATUS_NO_MEMORY
;
1837 r_u
->status
= NT_STATUS_OK
;
1839 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
1841 /* find the policy handle. open a policy on it. */
1842 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, NULL
))
1843 return NT_STATUS_INVALID_HANDLE
;
1845 switch (q_u
->switch_value
) {
1847 init_unk_info1(&ctr
->info
.inf1
);
1850 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1851 init_unk_info2(&ctr
->info
.inf2
, global_myworkgroup
, global_myname
, (uint32
) time(NULL
));
1854 init_unk_info3(&ctr
->info
.inf3
);
1857 init_unk_info5(&ctr
->info
.inf5
, global_myname
);
1860 init_unk_info6(&ctr
->info
.inf6
);
1863 init_unk_info7(&ctr
->info
.inf7
);
1866 init_unk_info12(&ctr
->info
.inf12
);
1869 return NT_STATUS_INVALID_INFO_CLASS
;
1872 init_samr_r_query_dom_info(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_OK
);
1874 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
1879 /*******************************************************************
1880 _api_samr_create_user
1881 Create an account, can be either a normal user or a machine.
1882 This funcion will need to be updated for bdc/domain trusts.
1883 ********************************************************************/
1885 NTSTATUS
_api_samr_create_user(pipes_struct
*p
, SAMR_Q_CREATE_USER
*q_u
, SAMR_R_CREATE_USER
*r_u
)
1887 SAM_ACCOUNT
*sam_pass
=NULL
;
1894 POLICY_HND dom_pol
= q_u
->domain_pol
;
1895 UNISTR2 user_account
= q_u
->uni_name
;
1896 uint16 acb_info
= q_u
->acb_info
;
1897 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1898 struct samr_info
*info
= NULL
;
1901 /* find the policy handle. open a policy on it. */
1902 if (!find_policy_by_hnd(p
, &dom_pol
, NULL
))
1903 return NT_STATUS_INVALID_HANDLE
;
1905 /* find the machine account: tell the caller if it exists.
1906 lkclXXXX i have *no* idea if this is a problem or not
1907 or even if you are supposed to construct a different
1908 reply if the account already exists...
1911 fstrcpy(mach_acct
, dos_unistrn2(user_account
.buffer
, user_account
.uni_str_len
));
1912 strlower(mach_acct
);
1914 pdb_init_sam(&sam_pass
);
1917 ret
= pdb_getsampwnam(sam_pass
, mach_acct
);
1920 /* machine account exists: say so */
1921 pdb_free_sam(sam_pass
);
1922 return NT_STATUS_USER_EXISTS
;
1925 local_flags
=LOCAL_ADD_USER
|LOCAL_DISABLE_USER
|LOCAL_SET_NO_PASSWORD
;
1926 local_flags
|= (acb_info
& ACB_WSTRUST
) ? LOCAL_TRUST_ACCOUNT
:0;
1929 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1930 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1931 * that only people with write access to the smbpasswd file will be able
1932 * to create a user. JRA.
1936 * add the user in the /etc/passwd file or the unix authority system.
1937 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1938 * a) local_password_change() checks for us if the /etc/passwd account really exists
1939 * b) smb_create_user() would return an error if the account already exists
1940 * and as it could return an error also if it can't create the account, it would be tricky.
1942 * So we go the easy way, only check after if the account exists.
1943 * JFM (2/3/2001), to clear any possible bad understanding (-:
1946 pstrcpy(add_script
, lp_adduser_script());
1949 smb_create_user(mach_acct
, NULL
);
1951 /* add the user in the smbpasswd file or the Samba authority database */
1952 if (!local_password_change(mach_acct
, local_flags
, NULL
, err_str
, sizeof(err_str
), msg_str
, sizeof(msg_str
))) {
1953 DEBUG(0, ("%s\n", err_str
));
1954 pdb_free_sam(sam_pass
);
1955 return NT_STATUS_ACCESS_DENIED
;
1959 ret
= pdb_getsampwnam(sam_pass
, mach_acct
);
1962 /* account doesn't exist: say so */
1963 pdb_free_sam(sam_pass
);
1964 return NT_STATUS_ACCESS_DENIED
;
1967 /* Get the domain SID stored in the domain policy */
1968 if(!get_lsa_policy_samr_sid(p
, &dom_pol
, &sid
)) {
1969 pdb_free_sam(sam_pass
);
1970 return NT_STATUS_INVALID_HANDLE
;
1973 /* append the user's RID to it */
1974 if(!sid_append_rid(&sid
, pdb_get_user_rid(sam_pass
) )) {
1975 pdb_free_sam(sam_pass
);
1976 return NT_STATUS_NO_SUCH_USER
;
1979 /* associate the user's SID with the new handle. */
1980 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
) {
1981 pdb_free_sam(sam_pass
);
1982 return NT_STATUS_NO_MEMORY
;
1988 /* get a (unique) handle. open a policy on it. */
1989 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
)) {
1990 pdb_free_sam(sam_pass
);
1991 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1994 r_u
->user_rid
=sam_pass
->user_rid
;
1995 r_u
->unknown_0
= 0x000703ff;
1997 pdb_free_sam(sam_pass
);
1999 return NT_STATUS_OK
;
2002 /*******************************************************************
2003 samr_reply_connect_anon
2004 ********************************************************************/
2006 NTSTATUS
_samr_connect_anon(pipes_struct
*p
, SAMR_Q_CONNECT_ANON
*q_u
, SAMR_R_CONNECT_ANON
*r_u
)
2008 struct samr_info
*info
= NULL
;
2010 /* set up the SAMR connect_anon response */
2012 r_u
->status
= NT_STATUS_OK
;
2014 /* associate the user's SID with the new handle. */
2015 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
2016 return NT_STATUS_NO_MEMORY
;
2019 info
->status
= q_u
->unknown_0
;
2021 /* get a (unique) handle. open a policy on it. */
2022 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2023 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2028 /*******************************************************************
2030 ********************************************************************/
2032 NTSTATUS
_samr_connect(pipes_struct
*p
, SAMR_Q_CONNECT
*q_u
, SAMR_R_CONNECT
*r_u
)
2034 struct samr_info
*info
= NULL
;
2036 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2038 r_u
->status
= NT_STATUS_OK
;
2040 /* associate the user's SID with the new handle. */
2041 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
2042 return NT_STATUS_NO_MEMORY
;
2045 info
->status
= q_u
->access_mask
;
2047 /* get a (unique) handle. open a policy on it. */
2048 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2049 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2051 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2056 /**********************************************************************
2057 api_samr_lookup_domain
2058 **********************************************************************/
2060 NTSTATUS
_samr_lookup_domain(pipes_struct
*p
, SAMR_Q_LOOKUP_DOMAIN
*q_u
, SAMR_R_LOOKUP_DOMAIN
*r_u
)
2062 r_u
->status
= NT_STATUS_OK
;
2064 if (!find_policy_by_hnd(p
, &q_u
->connect_pol
, NULL
))
2065 return NT_STATUS_INVALID_HANDLE
;
2067 /* assume the domain name sent is our global_myname and
2068 send global_sam_sid */
2069 init_samr_r_lookup_domain(r_u
, &global_sam_sid
, r_u
->status
);
2074 /******************************************************************
2075 makes a SAMR_R_ENUM_DOMAINS structure.
2076 ********************************************************************/
2078 static BOOL
make_enum_domains(TALLOC_CTX
*ctx
, SAM_ENTRY
**pp_sam
,
2079 UNISTR2
**pp_uni_name
, uint32 num_sam_entries
, fstring doms
[])
2085 DEBUG(5, ("make_enum_domains\n"));
2088 *pp_uni_name
= NULL
;
2090 if (num_sam_entries
== 0)
2093 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
2094 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
2096 if (sam
== NULL
|| uni_name
== NULL
)
2099 for (i
= 0; i
< num_sam_entries
; i
++) {
2100 int len
= doms
[i
] != NULL
? strlen(doms
[i
]) : 0;
2102 init_sam_entry(&sam
[i
], len
, 0);
2103 init_unistr2(&uni_name
[i
], doms
[i
], len
);
2107 *pp_uni_name
= uni_name
;
2112 /**********************************************************************
2113 api_samr_enum_domains
2114 **********************************************************************/
2116 NTSTATUS
_samr_enum_domains(pipes_struct
*p
, SAMR_Q_ENUM_DOMAINS
*q_u
, SAMR_R_ENUM_DOMAINS
*r_u
)
2118 uint32 num_entries
= 2;
2121 r_u
->status
= NT_STATUS_OK
;
2123 fstrcpy(dom
[0],global_myworkgroup
);
2124 fstrcpy(dom
[1],"Builtin");
2126 if (!make_enum_domains(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_dom_name
, num_entries
, dom
))
2127 return NT_STATUS_NO_MEMORY
;
2129 init_samr_r_enum_domains(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
2134 /*******************************************************************
2136 ********************************************************************/
2138 NTSTATUS
_api_samr_open_alias(pipes_struct
*p
, SAMR_Q_OPEN_ALIAS
*q_u
, SAMR_R_OPEN_ALIAS
*r_u
)
2141 POLICY_HND domain_pol
= q_u
->dom_pol
;
2142 uint32 alias_rid
= q_u
->rid_alias
;
2143 POLICY_HND
*alias_pol
= &r_u
->pol
;
2144 struct samr_info
*info
= NULL
;
2146 r_u
->status
= NT_STATUS_OK
;
2148 /* get the domain policy. */
2149 if (!find_policy_by_hnd(p
, &domain_pol
, NULL
))
2150 return NT_STATUS_INVALID_HANDLE
;
2152 /* Get the domain SID stored in the domain policy */
2153 if(!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
))
2154 return NT_STATUS_INVALID_HANDLE
;
2156 /* append the alias' RID to it */
2157 if(!sid_append_rid(&sid
, alias_rid
))
2158 return NT_STATUS_NO_SUCH_USER
;
2161 * we should check if the rid really exist !!!
2165 /* associate the user's SID with the new handle. */
2166 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
2167 return NT_STATUS_NO_MEMORY
;
2172 /* get a (unique) handle. open a policy on it. */
2173 if (!create_policy_hnd(p
, alias_pol
, free_samr_info
, (void *)info
))
2174 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2179 /*******************************************************************
2181 ********************************************************************/
2183 static BOOL
set_user_info_10(const SAM_USER_INFO_10
*id10
, uint32 rid
)
2185 SAM_ACCOUNT
*pwd
=NULL
;
2190 ret
= pdb_getsampwrid(pwd
, rid
);
2198 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2203 if (!pdb_set_acct_ctrl(pwd
, id10
->acb_info
)) {
2208 if(!pdb_update_sam_account(pwd
, True
)) {
2218 /*******************************************************************
2220 ********************************************************************/
2222 static BOOL
set_user_info_12(SAM_USER_INFO_12
*id12
, uint32 rid
)
2224 SAM_ACCOUNT
*pwd
= NULL
;
2228 if(!pdb_getsampwrid(pwd
, rid
)) {
2234 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2239 if (!pdb_set_lanman_passwd (pwd
, id12
->lm_pwd
)) {
2243 if (!pdb_set_nt_passwd(pwd
, id12
->nt_pwd
)) {
2248 if(!pdb_update_sam_account(pwd
, True
)) {
2257 /*******************************************************************
2259 ********************************************************************/
2261 static BOOL
set_user_info_21(SAM_USER_INFO_21
*id21
, uint32 rid
)
2263 SAM_ACCOUNT
*pwd
= NULL
;
2264 SAM_ACCOUNT
*new_pwd
= NULL
;
2267 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2272 pdb_init_sam(&new_pwd
);
2274 if (!pdb_getsampwrid(pwd
, rid
)) {
2276 pdb_free_sam(new_pwd
);
2280 /* we make a copy so that we can modify stuff */
2281 copy_sam_passwd(new_pwd
, pwd
);
2282 copy_id21_to_sam_passwd(new_pwd
, id21
);
2285 * The funny part about the previous two calls is
2286 * that pwd still has the password hashes from the
2287 * passdb entry. These have not been updated from
2288 * id21. I don't know if they need to be set. --jerry
2291 /* write the change out */
2292 if(!pdb_update_sam_account(new_pwd
, True
)) {
2294 pdb_free_sam(new_pwd
);
2299 pdb_free_sam(new_pwd
);
2304 /*******************************************************************
2306 ********************************************************************/
2308 static BOOL
set_user_info_23(SAM_USER_INFO_23
*id23
, uint32 rid
)
2310 SAM_ACCOUNT
*pwd
= NULL
;
2311 SAM_ACCOUNT
*new_pwd
= NULL
;
2319 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2324 pdb_init_sam(&new_pwd
);
2326 if (!pdb_getsampwrid(pwd
, rid
)) {
2328 pdb_free_sam(new_pwd
);
2332 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2334 copy_sam_passwd(new_pwd
, pwd
);
2337 copy_id23_to_sam_passwd(new_pwd
, id23
);
2339 if (!decode_pw_buffer((char*)id23
->pass
, buf
, 256, &len
, nt_hash
, lm_hash
)) {
2340 pdb_free_sam(new_pwd
);
2344 if (!pdb_set_lanman_passwd (new_pwd
, lm_hash
)) {
2345 pdb_free_sam(new_pwd
);
2348 if (!pdb_set_nt_passwd(new_pwd
, nt_hash
)) {
2349 pdb_free_sam(new_pwd
);
2353 /* if it's a trust account, don't update /etc/passwd */
2354 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2355 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2356 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2357 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2359 /* update the UNIX password */
2360 if (lp_unix_password_sync() )
2361 if(!chgpasswd(pdb_get_username(new_pwd
), "", buf
, True
)) {
2362 pdb_free_sam(new_pwd
);
2367 memset(buf
, 0, sizeof(buf
));
2369 if(!pdb_update_sam_account(new_pwd
, True
)) {
2370 pdb_free_sam(new_pwd
);
2374 pdb_free_sam(new_pwd
);
2379 /*******************************************************************
2381 ********************************************************************/
2383 static BOOL
set_user_info_pw(char *pass
, uint32 rid
)
2385 SAM_ACCOUNT
*pwd
= NULL
;
2394 if (!pdb_getsampwrid(pwd
, rid
)) {
2399 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2401 memset(buf
, 0, sizeof(buf
));
2403 if (!decode_pw_buffer(pass
, buf
, 256, &len
, nt_hash
, lm_hash
)) {
2408 if (!pdb_set_lanman_passwd (pwd
, lm_hash
)) {
2412 if (!pdb_set_nt_passwd(pwd
, nt_hash
)) {
2417 /* if it's a trust account, don't update /etc/passwd */
2418 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2419 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2420 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2421 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2423 /* update the UNIX password */
2424 if (lp_unix_password_sync())
2425 if(!chgpasswd(pdb_get_username(pwd
), "", buf
, True
)) {
2431 memset(buf
, 0, sizeof(buf
));
2433 DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
2435 /* update the SAMBA password */
2436 if(!pdb_update_sam_account(pwd
, True
)) {
2446 /*******************************************************************
2447 samr_reply_set_userinfo
2448 ********************************************************************/
2450 NTSTATUS
_samr_set_userinfo(pipes_struct
*p
, SAMR_Q_SET_USERINFO
*q_u
, SAMR_R_SET_USERINFO
*r_u
)
2454 struct current_user user
;
2455 SAM_ACCOUNT
*sam_pass
=NULL
;
2456 unsigned char sess_key
[16];
2457 POLICY_HND
*pol
= &q_u
->pol
;
2458 uint16 switch_value
= q_u
->switch_value
;
2459 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
2462 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__
));
2464 r_u
->status
= NT_STATUS_OK
;
2466 if (p
->ntlmssp_auth_validated
) {
2467 memcpy(&user
, &p
->pipe_user
, sizeof(user
));
2469 extern struct current_user current_user
;
2470 memcpy(&user
, ¤t_user
, sizeof(user
));
2473 /* find the policy handle. open a policy on it. */
2474 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
))
2475 return NT_STATUS_INVALID_HANDLE
;
2477 sid_split_rid(&sid
, &rid
);
2479 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid
, switch_value
));
2482 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2483 return NT_STATUS_INVALID_INFO_CLASS
;
2487 pdb_init_sam(&sam_pass
);
2490 * We need the NT hash of the user who is changing the user's password.
2491 * This NT hash is used to generate a "user session key"
2492 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2496 ret
= pdb_getsampwuid(sam_pass
, user
.uid
);
2499 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user
.uid
));
2500 pdb_free_sam(sam_pass
);
2501 return NT_STATUS_ACCESS_DENIED
;
2504 memset(sess_key
, '\0', 16);
2505 mdfour(sess_key
, pdb_get_nt_passwd(sam_pass
), 16);
2507 pdb_free_sam(sam_pass
);
2509 /* ok! user info levels (lots: see MSDEV help), off we go... */
2510 switch (switch_value
) {
2512 if (!set_user_info_12(ctr
->info
.id12
, rid
))
2513 return NT_STATUS_ACCESS_DENIED
;
2517 SamOEMhash(ctr
->info
.id24
->pass
, sess_key
, 516);
2519 dump_data(100, (char *)ctr
->info
.id24
->pass
, 516);
2521 if (!set_user_info_pw((char *)ctr
->info
.id24
->pass
, rid
))
2522 return NT_STATUS_ACCESS_DENIED
;
2528 * Currently we don't really know how to unmarshall
2529 * the level 25 struct, and the password encryption
2530 * is different. This is a placeholder for when we
2531 * do understand it. In the meantime just return INVALID
2532 * info level and W2K SP2 drops down to level 23... JRA.
2535 SamOEMhash(ctr
->info
.id25
->pass
, sess_key
, 532);
2537 dump_data(100, (char *)ctr
->info
.id25
->pass
, 532);
2539 if (!set_user_info_pw(ctr
->info
.id25
->pass
, rid
))
2540 return NT_STATUS_ACCESS_DENIED
;
2543 return NT_STATUS_INVALID_INFO_CLASS
;
2546 SamOEMhash(ctr
->info
.id23
->pass
, sess_key
, 516);
2548 dump_data(100, (char *)ctr
->info
.id23
->pass
, 516);
2550 if (!set_user_info_23(ctr
->info
.id23
, rid
))
2551 return NT_STATUS_ACCESS_DENIED
;
2555 return NT_STATUS_INVALID_INFO_CLASS
;
2561 /*******************************************************************
2562 samr_reply_set_userinfo2
2563 ********************************************************************/
2565 NTSTATUS
_samr_set_userinfo2(pipes_struct
*p
, SAMR_Q_SET_USERINFO2
*q_u
, SAMR_R_SET_USERINFO2
*r_u
)
2569 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
2570 POLICY_HND
*pol
= &q_u
->pol
;
2571 uint16 switch_value
= q_u
->switch_value
;
2573 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__
));
2575 r_u
->status
= NT_STATUS_OK
;
2577 /* find the policy handle. open a policy on it. */
2578 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
))
2579 return NT_STATUS_INVALID_HANDLE
;
2581 sid_split_rid(&sid
, &rid
);
2583 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid
));
2586 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2587 return NT_STATUS_INVALID_INFO_CLASS
;
2590 switch_value
=ctr
->switch_value
;
2592 /* ok! user info levels (lots: see MSDEV help), off we go... */
2593 switch (switch_value
) {
2595 if (!set_user_info_21(ctr
->info
.id21
, rid
))
2596 return NT_STATUS_ACCESS_DENIED
;
2599 if (!set_user_info_10(ctr
->info
.id10
, rid
))
2600 return NT_STATUS_ACCESS_DENIED
;
2603 /* Used by AS/U JRA. */
2604 if (!set_user_info_12(ctr
->info
.id12
, rid
))
2605 return NT_STATUS_ACCESS_DENIED
;
2608 return NT_STATUS_INVALID_INFO_CLASS
;
2614 /*********************************************************************
2615 _samr_query_aliasmem
2616 *********************************************************************/
2618 NTSTATUS
_samr_query_useraliases(pipes_struct
*p
, SAMR_Q_QUERY_USERALIASES
*q_u
, SAMR_R_QUERY_USERALIASES
*r_u
)
2624 rid
=(uint32
*)talloc_zero(p
->mem_ctx
, num_rids
*sizeof(uint32
));
2626 return NT_STATUS_NO_MEMORY
;
2628 /* until i see a real useraliases query, we fack one up */
2630 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
2632 init_samr_r_query_useraliases(r_u
, num_rids
, rid
, NT_STATUS_OK
);
2634 return NT_STATUS_OK
;
2638 /*********************************************************************
2639 _samr_query_aliasmem
2640 *********************************************************************/
2642 NTSTATUS
_samr_query_aliasmem(pipes_struct
*p
, SAMR_Q_QUERY_ALIASMEM
*q_u
, SAMR_R_QUERY_ALIASMEM
*r_u
)
2644 DEBUG(0,("_samr_query_aliasmem: Not yet implemented.\n"));
2645 return NT_STATUS_NOT_IMPLEMENTED
;
2648 /*********************************************************************
2649 _samr_query_groupmem
2650 *********************************************************************/
2652 NTSTATUS
_samr_query_groupmem(pipes_struct
*p
, SAMR_Q_QUERY_GROUPMEM
*q_u
, SAMR_R_QUERY_GROUPMEM
*r_u
)
2654 DEBUG(0,("_samr_query_groupmem: Not yet implemented.\n"));
2655 return NT_STATUS_NOT_IMPLEMENTED
;
2658 /*********************************************************************
2660 *********************************************************************/
2662 NTSTATUS
_samr_add_aliasmem(pipes_struct
*p
, SAMR_Q_ADD_ALIASMEM
*q_u
, SAMR_R_ADD_ALIASMEM
*r_u
)
2664 DEBUG(0,("_samr_add_aliasmem: Not yet implemented.\n"));
2665 return NT_STATUS_NOT_IMPLEMENTED
;
2668 /*********************************************************************
2670 *********************************************************************/
2672 NTSTATUS
_samr_del_aliasmem(pipes_struct
*p
, SAMR_Q_DEL_ALIASMEM
*q_u
, SAMR_R_DEL_ALIASMEM
*r_u
)
2674 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2675 return NT_STATUS_NOT_IMPLEMENTED
;
2678 /*********************************************************************
2680 *********************************************************************/
2682 NTSTATUS
_samr_add_groupmem(pipes_struct
*p
, SAMR_Q_ADD_GROUPMEM
*q_u
, SAMR_R_ADD_GROUPMEM
*r_u
)
2684 DEBUG(0,("_samr_add_groupmem: Not yet implemented.\n"));
2685 return NT_STATUS_NOT_IMPLEMENTED
;
2688 /*********************************************************************
2690 *********************************************************************/
2692 NTSTATUS
_samr_del_groupmem(pipes_struct
*p
, SAMR_Q_DEL_GROUPMEM
*q_u
, SAMR_R_DEL_GROUPMEM
*r_u
)
2694 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2695 return NT_STATUS_NOT_IMPLEMENTED
;
2698 /*********************************************************************
2699 _samr_delete_dom_user
2700 *********************************************************************/
2702 NTSTATUS
_samr_delete_dom_user(pipes_struct
*p
, SAMR_Q_DELETE_DOM_USER
*q_u
, SAMR_R_DELETE_DOM_USER
*r_u
)
2704 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2705 return NT_STATUS_NOT_IMPLEMENTED
;
2708 /*********************************************************************
2709 _samr_delete_dom_group
2710 *********************************************************************/
2712 NTSTATUS
_samr_delete_dom_group(pipes_struct
*p
, SAMR_Q_DELETE_DOM_GROUP
*q_u
, SAMR_R_DELETE_DOM_GROUP
*r_u
)
2714 DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
2715 return NT_STATUS_NOT_IMPLEMENTED
;
2718 /*********************************************************************
2719 _samr_delete_dom_alias
2720 *********************************************************************/
2722 NTSTATUS
_samr_delete_dom_alias(pipes_struct
*p
, SAMR_Q_DELETE_DOM_ALIAS
*q_u
, SAMR_R_DELETE_DOM_ALIAS
*r_u
)
2724 DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
2725 return NT_STATUS_NOT_IMPLEMENTED
;
2728 /*********************************************************************
2729 _samr_create_dom_group
2730 *********************************************************************/
2732 NTSTATUS
_samr_create_dom_group(pipes_struct
*p
, SAMR_Q_CREATE_DOM_GROUP
*q_u
, SAMR_R_CREATE_DOM_GROUP
*r_u
)
2734 DEBUG(0,("_samr_create_dom_group: Not yet implemented.\n"));
2735 return NT_STATUS_NOT_IMPLEMENTED
;
2738 /*********************************************************************
2739 _samr_create_dom_alias
2740 *********************************************************************/
2742 NTSTATUS
_samr_create_dom_alias(pipes_struct
*p
, SAMR_Q_CREATE_DOM_ALIAS
*q_u
, SAMR_R_CREATE_DOM_ALIAS
*r_u
)
2744 DEBUG(0,("_samr_create_dom_alias: Not yet implemented.\n"));
2745 return NT_STATUS_NOT_IMPLEMENTED
;
2748 /*********************************************************************
2749 _samr_query_groupinfo
2750 *********************************************************************/
2752 NTSTATUS
_samr_query_groupinfo(pipes_struct
*p
, SAMR_Q_QUERY_GROUPINFO
*q_u
, SAMR_R_QUERY_GROUPINFO
*r_u
)
2754 DEBUG(0,("_samr_query_groupinfo: Not yet implemented.\n"));
2755 return NT_STATUS_NOT_IMPLEMENTED
;
2758 /*********************************************************************
2760 *********************************************************************/
2762 NTSTATUS
_samr_set_groupinfo(pipes_struct
*p
, SAMR_Q_SET_GROUPINFO
*q_u
, SAMR_R_SET_GROUPINFO
*r_u
)
2764 DEBUG(0,("_samr_set_groupinfo: Not yet implemented.\n"));
2765 return NT_STATUS_NOT_IMPLEMENTED
;
2768 /*********************************************************************
2769 _samr_get_dom_pwinfo
2770 *********************************************************************/
2772 NTSTATUS
_samr_get_dom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_DOM_PWINFO
*q_u
, SAMR_R_GET_DOM_PWINFO
*r_u
)
2774 /* Actually, returning zeros here works quite well :-). */
2775 return NT_STATUS_OK
;
2778 /*********************************************************************
2780 *********************************************************************/
2782 NTSTATUS
_samr_open_group(pipes_struct
*p
, SAMR_Q_OPEN_GROUP
*q_u
, SAMR_R_OPEN_GROUP
*r_u
)
2784 DEBUG(0,("_samr_open_group: Not yet implemented.\n"));
2785 return NT_STATUS_NOT_IMPLEMENTED
;
2788 /*********************************************************************
2790 *********************************************************************/
2792 NTSTATUS
_samr_unknown_2d(pipes_struct
*p
, SAMR_Q_UNKNOWN_2D
*q_u
, SAMR_R_UNKNOWN_2D
*r_u
)
2794 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
2795 return NT_STATUS_NOT_IMPLEMENTED
;