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-2002.
10 * Copyright (C) Jean François Micouleau 1998-2001.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 * This is the implementation of the SAMR code.
33 extern fstring global_myworkgroup
;
34 extern pstring global_myname
;
35 extern DOM_SID global_sam_sid
;
36 extern DOM_SID global_sid_Builtin
;
38 extern rid_name domain_group_rids
[];
39 extern rid_name domain_alias_rids
[];
40 extern rid_name builtin_alias_rids
[];
42 typedef struct _disp_info
{
44 uint32 num_user_account
;
45 DISP_USER_INFO
*disp_user_info
;
47 uint32 num_group_account
;
48 DISP_GROUP_INFO
*disp_group_info
;
52 /* for use by the \PIPE\samr policy */
54 uint32 status
; /* some sort of flag. best to record it. comes from opnum 0x39 */
58 /*******************************************************************
59 Create a samr_info struct.
60 ********************************************************************/
62 static struct samr_info
*get_samr_info_by_sid(DOM_SID
*psid
)
64 struct samr_info
*info
;
67 if ((info
= (struct samr_info
*)malloc(sizeof(struct samr_info
))) == NULL
)
72 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_to_string(sid_str
, psid
) ));
73 sid_copy( &info
->sid
, psid
);
75 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
80 /*******************************************************************
81 Function to free the per handle data.
82 ********************************************************************/
84 static void free_samr_db(struct samr_info
*info
)
88 if (info
->disp_info
.group_dbloaded
) {
89 for (i
=0; i
<info
->disp_info
.num_group_account
; i
++)
90 SAFE_FREE(info
->disp_info
.disp_group_info
[i
].grp
);
92 SAFE_FREE(info
->disp_info
.disp_group_info
);
95 if (info
->disp_info
.user_dbloaded
){
96 for (i
=0; i
<info
->disp_info
.num_user_account
; i
++)
97 pdb_free_sam(info
->disp_info
.disp_user_info
[i
].sam
);
99 SAFE_FREE(info
->disp_info
.disp_user_info
);
102 info
->disp_info
.user_dbloaded
=False
;
103 info
->disp_info
.group_dbloaded
=False
;
104 info
->disp_info
.num_group_account
=0;
105 info
->disp_info
.num_user_account
=0;
108 /*******************************************************************
109 Function to free the per handle data.
110 ********************************************************************/
112 static void free_samr_info(void *ptr
)
114 struct samr_info
*info
=(struct samr_info
*) ptr
;
120 /*******************************************************************
121 Ensure password info is never given out. Paranioa... JRA.
122 ********************************************************************/
124 static void samr_clear_passwd_fields( SAM_USER_INFO_21
*pass
, int num_entries
)
131 for (i
= 0; i
< num_entries
; i
++) {
132 memset(&pass
[i
].lm_pwd
, '\0', sizeof(pass
[i
].lm_pwd
));
133 memset(&pass
[i
].nt_pwd
, '\0', sizeof(pass
[i
].nt_pwd
));
137 static void samr_clear_sam_passwd(SAM_ACCOUNT
*sam_pass
)
143 memset(sam_pass
->lm_pw
, '\0', 16);
145 memset(sam_pass
->nt_pw
, '\0', 16);
148 static NTSTATUS
load_sampwd_entries(struct samr_info
*info
, uint16 acb_mask
)
150 SAM_ACCOUNT
*pwd
= NULL
;
151 DISP_USER_INFO
*pwd_array
= NULL
;
153 DEBUG(10,("load_sampwd_entries\n"));
155 /* if the snapshoot is already loaded, return */
156 if (info
->disp_info
.user_dbloaded
==True
) {
157 DEBUG(10,("load_sampwd_entries: already in memory\n"));
161 if (!pdb_setsampwent(False
)) {
162 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
163 return NT_STATUS_ACCESS_DENIED
;
166 for (pdb_init_sam(&pwd
); pdb_getsampwent(pwd
) == True
; pwd
=NULL
, pdb_init_sam(&pwd
) ) {
168 if (acb_mask
!= 0 && !(pwd
->acct_ctrl
& acb_mask
)) {
170 DEBUG(5,(" acb_mask %x reject\n", acb_mask
));
174 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
175 if (info
->disp_info
.num_user_account
% MAX_SAM_ENTRIES
== 0) {
177 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
178 pwd_array
=(DISP_USER_INFO
*)Realloc(info
->disp_info
.disp_user_info
,
179 (info
->disp_info
.num_user_account
+MAX_SAM_ENTRIES
)*sizeof(DISP_USER_INFO
));
182 return NT_STATUS_NO_MEMORY
;
184 info
->disp_info
.disp_user_info
=pwd_array
;
187 /* link the SAM_ACCOUNT to the array */
188 info
->disp_info
.disp_user_info
[info
->disp_info
.num_user_account
].sam
=pwd
;
190 DEBUG(10,("load_sampwd_entries: entry: %d\n", info
->disp_info
.num_user_account
));
192 info
->disp_info
.num_user_account
++;
197 /* the snapshoot is in memory, we're ready to enumerate fast */
199 info
->disp_info
.user_dbloaded
=True
;
201 DEBUG(12,("load_sampwd_entries: done\n"));
207 * This is a really ugly hack to make this interface work in the 2.2.x code. JRA.
208 * Return a malloced map so we can free it.
211 static int setup_fake_group_map(GROUP_MAP
**ret_map
)
213 static GROUP_MAP static_map
[2];
214 static BOOL group_map_init
;
215 extern DOM_SID global_sam_sid
;
217 *ret_map
= (GROUP_MAP
*)malloc(sizeof(GROUP_MAP
)*2);
221 if (group_map_init
) {
222 memcpy( *ret_map
, &static_map
[0], sizeof(GROUP_MAP
)*2);
223 return sizeof(static_map
)/sizeof(GROUP_MAP
);
226 group_map_init
= True
;
228 static_map
[0].gid
= (gid_t
)-1;
229 sid_copy(&static_map
[0].sid
, &global_sam_sid
);
230 sid_append_rid(&static_map
[0].sid
, DOMAIN_GROUP_RID_ADMINS
);
231 static_map
[0].sid_name_use
= SID_NAME_DOM_GRP
;
232 fstrcpy(static_map
[0].nt_name
, "Domain Admins");
233 fstrcpy(static_map
[0].comment
, "Administrators for the domain");
234 static_map
[0].privilege
= 0;
236 static_map
[1].gid
= (gid_t
)-1;
237 sid_copy(&static_map
[1].sid
, &global_sam_sid
);
238 sid_append_rid(&static_map
[1].sid
, DOMAIN_GROUP_RID_USERS
);
239 static_map
[1].sid_name_use
= SID_NAME_DOM_GRP
;
240 fstrcpy(static_map
[1].nt_name
, "Domain Users");
241 fstrcpy(static_map
[1].comment
, "Users in the domain");
242 static_map
[1].privilege
= 0;
244 memcpy( *ret_map
, &static_map
[0], sizeof(GROUP_MAP
)*2);
245 return sizeof(static_map
)/sizeof(GROUP_MAP
);
248 static NTSTATUS
load_group_domain_entries(struct samr_info
*info
, DOM_SID
*sid
)
251 DISP_GROUP_INFO
*grp_array
= NULL
;
252 uint32 group_entries
= 0;
255 DEBUG(10,("load_group_domain_entries\n"));
257 /* if the snapshoot is already loaded, return */
258 if (info
->disp_info
.group_dbloaded
==True
) {
259 DEBUG(10,("load_group_domain_entries: already in memory\n"));
264 * This is a really ugly hack to make this interface work in the 2.2.x code. JRA.
267 group_entries
= setup_fake_group_map(&map
);
269 info
->disp_info
.num_group_account
=group_entries
;
271 grp_array
=(DISP_GROUP_INFO
*)malloc(info
->disp_info
.num_group_account
*sizeof(DISP_GROUP_INFO
));
273 if (group_entries
!=0 && grp_array
==NULL
) {
274 return NT_STATUS_NO_MEMORY
;
277 info
->disp_info
.disp_group_info
=grp_array
;
279 for (i
=0; i
<group_entries
; i
++) {
281 grp_array
[i
].grp
=(DOMAIN_GRP
*)malloc(sizeof(DOMAIN_GRP
));
283 fstrcpy(grp_array
[i
].grp
->name
, map
[i
].nt_name
);
284 fstrcpy(grp_array
[i
].grp
->comment
, map
[i
].comment
);
285 sid_split_rid(&map
[i
].sid
, &grp_array
[i
].grp
->rid
);
286 grp_array
[i
].grp
->attr
=SID_NAME_DOM_GRP
;
291 /* the snapshoot is in memory, we're ready to enumerate fast */
293 info
->disp_info
.group_dbloaded
=True
;
295 DEBUG(12,("load_group_domain_entries: done\n"));
300 /*******************************************************************
301 This next function should be replaced with something that
302 dynamically returns the correct user info..... JRA.
303 ********************************************************************/
305 static NTSTATUS
get_sampwd_entries(SAM_USER_INFO_21
*pw_buf
, int start_idx
,
306 int *total_entries
, int *num_entries
,
307 int max_num_entries
, uint16 acb_mask
)
309 SAM_ACCOUNT
*pwd
= NULL
;
310 BOOL not_finished
= True
;
313 (*total_entries
) = 0;
316 return NT_STATUS_NO_MEMORY
;
320 if (!pdb_setsampwent(False
)) {
321 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
323 return NT_STATUS_ACCESS_DENIED
;
326 while (((not_finished
= pdb_getsampwent(pwd
)) != False
)
327 && (*num_entries
) < max_num_entries
)
335 /* skip the requested number of entries.
336 not very efficient, but hey... */
341 user_name_len
= strlen(pdb_get_username(pwd
))+1;
342 init_unistr2(&pw_buf
[(*num_entries
)].uni_user_name
, pdb_get_username(pwd
), user_name_len
);
343 init_uni_hdr(&pw_buf
[(*num_entries
)].hdr_user_name
, user_name_len
);
344 pw_buf
[(*num_entries
)].user_rid
= pwd
->user_rid
;
345 memset((char *)pw_buf
[(*num_entries
)].nt_pwd
, '\0', 16);
347 /* Now check if the NT compatible password is available. */
348 if (pdb_get_nt_passwd(pwd
))
349 memcpy( pw_buf
[(*num_entries
)].nt_pwd
, pdb_get_nt_passwd(pwd
), 16);
351 pw_buf
[(*num_entries
)].acb_info
= pdb_get_acct_ctrl(pwd
);
353 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
354 (*num_entries
), pdb_get_username(pwd
), pdb_get_user_rid(pwd
), pdb_get_acct_ctrl(pwd
) ));
356 if (acb_mask
== 0 || (pwd
->acct_ctrl
& acb_mask
)) {
357 DEBUG(5,(" acb_mask %x accepts\n", acb_mask
));
360 DEBUG(5,(" acb_mask %x rejects\n", acb_mask
));
373 return STATUS_MORE_ENTRIES
;
378 /*******************************************************************
380 ********************************************************************/
382 NTSTATUS
_samr_close_hnd(pipes_struct
*p
, SAMR_Q_CLOSE_HND
*q_u
, SAMR_R_CLOSE_HND
*r_u
)
384 r_u
->status
= NT_STATUS_OK
;
386 /* close the policy handle */
387 if (!close_policy_hnd(p
, &q_u
->pol
))
388 return NT_STATUS_OBJECT_NAME_INVALID
;
390 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__
));
395 /*******************************************************************
396 samr_reply_open_domain
397 ********************************************************************/
399 NTSTATUS
_samr_open_domain(pipes_struct
*p
, SAMR_Q_OPEN_DOMAIN
*q_u
, SAMR_R_OPEN_DOMAIN
*r_u
)
401 struct samr_info
*info
;
403 r_u
->status
= NT_STATUS_OK
;
405 /* find the connection policy handle. */
406 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
407 return NT_STATUS_INVALID_HANDLE
;
409 /* associate the domain SID with the (unique) handle. */
410 if ((info
= get_samr_info_by_sid(&q_u
->dom_sid
.sid
))==NULL
)
411 return NT_STATUS_NO_MEMORY
;
413 /* get a (unique) handle. open a policy on it. */
414 if (!create_policy_hnd(p
, &r_u
->domain_pol
, free_samr_info
, (void *)info
))
415 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
417 DEBUG(5,("samr_open_domain: %d\n", __LINE__
));
422 static uint32
get_lsa_policy_samr_rid(struct samr_info
*info
)
425 DEBUG(3,("Error getting policy\n"));
429 return info
->sid
.sub_auths
[info
->sid
.num_auths
-1];
432 /*******************************************************************
433 _samr_get_usrdom_pwinfo
434 ********************************************************************/
436 NTSTATUS
_samr_get_usrdom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_USRDOM_PWINFO
*q_u
, SAMR_R_GET_USRDOM_PWINFO
*r_u
)
438 struct samr_info
*info
= NULL
;
440 r_u
->status
= NT_STATUS_OK
;
442 /* find the policy handle. open a policy on it. */
443 if (!find_policy_by_hnd(p
, &q_u
->user_pol
, (void **)&info
)) {
444 return NT_STATUS_INVALID_HANDLE
;
447 /* find the user's rid */
448 if (get_lsa_policy_samr_rid(info
) == 0xffffffff) {
449 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
452 init_samr_r_get_usrdom_pwinfo(r_u
, NT_STATUS_OK
);
454 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__
));
459 /*******************************************************************
461 ********************************************************************/
463 static NTSTATUS
samr_make_usr_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC_BUF
**buf
, DOM_SID
*usr_sid
)
465 extern DOM_SID global_sid_Builtin
;
466 extern DOM_SID global_sid_World
;
474 SEC_DESC
*psd
= NULL
;
477 sid_copy(&adm_sid
, &global_sid_Builtin
);
478 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
480 sid_copy(&act_sid
, &global_sid_Builtin
);
481 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
483 init_sec_access(&mask
, 0x2035b);
484 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
486 init_sec_access(&mask
, 0xf07ff);
487 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
488 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
490 init_sec_access(&mask
,0x20044);
491 init_sec_ace(&ace
[3], usr_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
493 if((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 4, ace
)) == NULL
)
494 return NT_STATUS_NO_MEMORY
;
496 if((psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, &sd_size
)) == NULL
)
497 return NT_STATUS_NO_MEMORY
;
499 if((*buf
= make_sec_desc_buf(ctx
, sd_size
, psd
)) == NULL
)
500 return NT_STATUS_NO_MEMORY
;
505 static BOOL
get_lsa_policy_samr_sid(pipes_struct
*p
, POLICY_HND
*pol
, DOM_SID
*sid
)
507 struct samr_info
*info
= NULL
;
509 /* find the policy handle. open a policy on it. */
510 if (!find_policy_by_hnd(p
, pol
, (void **)&info
))
520 /*******************************************************************
522 ********************************************************************/
524 NTSTATUS
_samr_query_sec_obj(pipes_struct
*p
, SAMR_Q_QUERY_SEC_OBJ
*q_u
, SAMR_R_QUERY_SEC_OBJ
*r_u
)
528 r_u
->status
= NT_STATUS_OK
;
532 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &pol_sid
))
533 return NT_STATUS_INVALID_HANDLE
;
535 r_u
->status
= samr_make_usr_obj_sd(p
->mem_ctx
, &r_u
->buf
, &pol_sid
);
537 if (NT_STATUS_IS_OK(r_u
->status
))
543 /*******************************************************************
544 makes a SAM_ENTRY / UNISTR2* structure from a user list.
545 ********************************************************************/
547 static void make_user_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
548 uint32 num_sam_entries
, SAM_USER_INFO_21
*pass
)
557 if (num_sam_entries
== 0)
560 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
562 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
564 if (sam
== NULL
|| uni_name
== NULL
) {
565 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
569 for (i
= 0; i
< num_sam_entries
; i
++) {
570 int len
= pass
[i
].uni_user_name
.uni_str_len
;
572 init_sam_entry(&sam
[i
], len
, pass
[i
].user_rid
);
573 copy_unistr2(&uni_name
[i
], &pass
[i
].uni_user_name
);
577 *uni_name_pp
= uni_name
;
580 /*******************************************************************
581 samr_reply_enum_dom_users
582 ********************************************************************/
584 NTSTATUS
_samr_enum_dom_users(pipes_struct
*p
, SAMR_Q_ENUM_DOM_USERS
*q_u
, SAMR_R_ENUM_DOM_USERS
*r_u
)
586 SAM_USER_INFO_21 pass
[MAX_SAM_ENTRIES
];
588 int total_entries
= 0;
590 r_u
->status
= NT_STATUS_OK
;
592 /* find the policy handle. open a policy on it. */
593 if (!find_policy_by_hnd(p
, &q_u
->pol
, NULL
))
594 return NT_STATUS_INVALID_HANDLE
;
596 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
599 r_u
->status
= get_sampwd_entries(pass
, q_u
->start_idx
, &total_entries
, &num_entries
,
600 MAX_SAM_ENTRIES
, q_u
->acb_mask
);
603 if (NT_STATUS_IS_ERR(r_u
->status
))
606 samr_clear_passwd_fields(pass
, num_entries
);
609 * Note from JRA. total_entries is not being used here. Currently if there is a
610 * large user base then it looks like NT will enumerate until get_sampwd_entries
611 * returns False due to num_entries being zero. This will cause an access denied
612 * return. I don't think this is right and needs further investigation. Note that
613 * this is also the same in the TNG code (I don't think that has been tested with
614 * a very large user list as MAX_SAM_ENTRIES is set to 600).
616 * I also think that one of the 'num_entries' return parameters is probably
617 * the "max entries" parameter - but in the TNG code they're all currently set to the same
618 * value (again I think this is wrong).
621 make_user_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_acct_name
, num_entries
, pass
);
623 init_samr_r_enum_dom_users(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
625 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
630 /*******************************************************************
631 makes a SAM_ENTRY / UNISTR2* structure from a group list.
632 ********************************************************************/
634 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
635 uint32 num_sam_entries
, DOMAIN_GRP
*grp
)
644 if (num_sam_entries
== 0)
647 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
649 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
651 if (sam
== NULL
|| uni_name
== NULL
) {
652 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
656 for (i
= 0; i
< num_sam_entries
; i
++) {
658 * JRA. I think this should include the null. TNG does not.
660 int len
= strlen(unix_to_dos_static(grp
[i
].name
))+1;
662 init_sam_entry(&sam
[i
], len
, grp
[i
].rid
);
663 init_unistr2(&uni_name
[i
], unix_to_dos_static(grp
[i
].name
), len
);
667 *uni_name_pp
= uni_name
;
670 /*******************************************************************
671 Get the group entries - similar to get_sampwd_entries().
672 ********************************************************************/
674 static NTSTATUS
get_group_alias_entries(DOMAIN_GRP
*d_grp
, DOM_SID
*sid
, uint32 start_idx
,
675 uint32
*p_num_entries
, uint32 max_entries
)
679 uint32 num_entries
= 0;
681 sid_to_string(sid_str
, sid
);
682 sid_to_string(sam_sid_str
, &global_sam_sid
);
686 /* well-known aliases */
687 if (strequal(sid_str
, "S-1-5-32")) {
688 const char *alias_name
;
689 while (!lp_hide_local_users() &&
690 num_entries
< max_entries
&&
691 ((alias_name
= builtin_alias_rids
[num_entries
].name
) != NULL
)) {
693 fstrcpy(d_grp
[num_entries
].name
, alias_name
);
694 d_grp
[num_entries
].rid
= builtin_alias_rids
[num_entries
].rid
;
698 } else if (strequal(sid_str
, sam_sid_str
) && !lp_hide_local_users()) {
701 struct sys_grent
*glist
;
702 struct sys_grent
*grp
;
704 sep
= lp_winbind_separator();
707 /* we return the UNIX groups here. This seems to be the right */
708 /* thing to do, since NT member servers return their local */
709 /* groups in the same situation. */
711 /* use getgrent_list() to retrieve the list of groups to avoid
712 * problems with getgrent possible infinite loop by internal
713 * libc grent structures overwrites by called functions */
714 grp
= glist
= getgrent_list();
716 return NT_STATUS_NO_MEMORY
;
718 for (;(num_entries
< max_entries
) && (grp
!= NULL
); grp
= grp
->next
) {
722 fstrcpy(name
,grp
->gr_name
);
723 DEBUG(10,("get_group_alias_entries: got group %s\n", name
));
725 /* Don't return winbind groups as they are not local! */
727 if (strchr(name
, *sep
) != NULL
) {
728 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", name
));
732 /* Don't return user private groups... */
733 if (Get_Pwnam(name
, False
) != 0) {
734 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", name
));
738 trid
= pdb_gid_to_group_rid(grp
->gr_gid
);
739 for( i
= 0; i
< num_entries
; i
++)
740 if ( d_grp
[i
].rid
== trid
)
743 if ( i
< num_entries
)
744 continue; /* rid was there, dup! */
746 /* JRA - added this for large group db enumeration... */
749 /* skip the requested number of entries.
750 not very efficient, but hey...
756 fstrcpy(d_grp
[num_entries
].name
, name
);
757 d_grp
[num_entries
].rid
= trid
;
764 *p_num_entries
= num_entries
;
766 if (num_entries
>= max_entries
)
767 return STATUS_MORE_ENTRIES
;
771 /*******************************************************************
772 Get the group entries - similar to get_sampwd_entries().
773 ********************************************************************/
775 static NTSTATUS
get_group_domain_entries(DOMAIN_GRP
*d_grp
, DOM_SID
*sid
, uint32 start_idx
,
776 uint32
*p_num_entries
, uint32 max_entries
)
780 uint32 num_entries
= 0;
781 fstring name
="Domain Admins";
782 fstring comment
="Just to make it work !";
784 sid_to_string(sid_str
, sid
);
785 sid_to_string(sam_sid_str
, &global_sam_sid
);
789 fstrcpy(d_grp
[0].name
, name
);
790 fstrcpy(d_grp
[0].comment
, comment
);
791 d_grp
[0].rid
= DOMAIN_GROUP_RID_ADMINS
;
792 d_grp
[0].attr
=SID_NAME_DOM_GRP
;
794 fstrcpy(d_grp
[1].name
, "Domain Users");
795 fstrcpy(d_grp
[1].comment
, "Just to make it work !");
796 d_grp
[1].rid
= DOMAIN_GROUP_RID_USERS
;
797 d_grp
[1].attr
=SID_NAME_DOM_GRP
;
801 *p_num_entries
= num_entries
;
806 /*******************************************************************
807 samr_reply_enum_dom_groups
808 Only reply with one group - domain admins. This must be fixed for
810 ********************************************************************/
812 NTSTATUS
_samr_enum_dom_groups(pipes_struct
*p
, SAMR_Q_ENUM_DOM_GROUPS
*q_u
, SAMR_R_ENUM_DOM_GROUPS
*r_u
)
818 r_u
->status
= NT_STATUS_OK
;
820 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
))
821 return NT_STATUS_INVALID_HANDLE
;
823 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__
));
825 get_group_domain_entries(grp
, &sid
, q_u
->start_idx
, &num_entries
, MAX_SAM_ENTRIES
);
827 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
829 init_samr_r_enum_dom_groups(r_u
, q_u
->start_idx
, num_entries
);
831 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__
));
837 /*******************************************************************
838 samr_reply_enum_dom_aliases
839 ********************************************************************/
841 NTSTATUS
_samr_enum_dom_aliases(pipes_struct
*p
, SAMR_Q_ENUM_DOM_ALIASES
*q_u
, SAMR_R_ENUM_DOM_ALIASES
*r_u
)
843 DOMAIN_GRP grp
[MAX_SAM_ENTRIES
];
844 uint32 num_entries
= 0;
848 r_u
->status
= NT_STATUS_OK
;
850 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
))
851 return NT_STATUS_INVALID_HANDLE
;
853 sid_to_string(sid_str
, &sid
);
854 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str
));
856 r_u
->status
= get_group_alias_entries(grp
, &sid
, q_u
->start_idx
,
857 &num_entries
, MAX_SAM_ENTRIES
);
858 if (NT_STATUS_IS_ERR(r_u
->status
))
861 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
863 init_samr_r_enum_dom_aliases(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
865 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__
));
870 /*******************************************************************
871 samr_reply_query_dispinfo
872 ********************************************************************/
873 NTSTATUS
_samr_query_dispinfo(pipes_struct
*p
, SAMR_Q_QUERY_DISPINFO
*q_u
, SAMR_R_QUERY_DISPINFO
*r_u
)
875 struct samr_info
*info
= NULL
;
876 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
879 uint32 max_entries
=q_u
->max_entries
;
880 uint32 enum_context
=q_u
->start_idx
;
881 uint32 max_size
=q_u
->max_size
;
883 SAM_DISPINFO_CTR
*ctr
;
884 uint32 temp_size
=0, total_data_size
=0;
886 uint32 num_account
= 0;
887 enum remote_arch_types ra_type
= get_remote_arch();
890 max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
892 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__
));
893 r_u
->status
= NT_STATUS_OK
;
895 /* find the policy handle. open a policy on it. */
896 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
897 return NT_STATUS_INVALID_HANDLE
;
900 * calculate how many entries we will return.
902 * - the number of entries the client asked
903 * - our limit on that
904 * - the starting point (enumeration context)
905 * - the buffer size the client will accept
909 * We are a lot more like W2K. Instead of reading the SAM
910 * each time to find the records we need to send back,
911 * we read it once and link that copy to the sam handle.
912 * For large user list (over the MAX_SAM_ENTRIES)
913 * it's a definitive win.
914 * second point to notice: between enumerations
915 * our sam is now the same as it's a snapshoot.
916 * third point: got rid of the static SAM_USER_21 struct
917 * no more intermediate.
918 * con: it uses much more memory, as a full copy is stored
921 * If you want to change it, think twice and think
922 * of the second point , that's really important.
927 /* Get what we need from the password database */
929 if (q_u
->switch_level
==2)
930 acb_mask
= ACB_WSTRUST
;
932 acb_mask
= ACB_NORMAL
;
934 /* Get what we need from the password database */
935 switch (q_u
->switch_level
) {
940 r_u
->status
=load_sampwd_entries(info
, acb_mask
);
942 if (NT_STATUS_IS_ERR(r_u
->status
)) {
943 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
946 num_account
= info
->disp_info
.num_user_account
;
950 r_u
->status
= load_group_domain_entries(info
, &info
->sid
);
951 if (NT_STATUS_IS_ERR(r_u
->status
))
953 num_account
= info
->disp_info
.num_group_account
;
956 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u
->switch_level
));
957 return NT_STATUS_INVALID_INFO_CLASS
;
960 /* first limit the number of entries we will return */
961 if(max_entries
> max_sam_entries
) {
962 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries
, max_sam_entries
));
963 max_entries
= max_sam_entries
;
966 if (enum_context
> num_account
) {
967 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
971 /* verify we won't overflow */
972 if (max_entries
> num_account
-enum_context
) {
973 max_entries
= num_account
-enum_context
;
974 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries
));
977 /* calculate the size and limit on the number of entries we will return */
978 temp_size
=max_entries
*struct_size
;
980 if (temp_size
>max_size
) {
981 max_entries
=MIN((max_size
/struct_size
),max_entries
);
982 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries
));
985 if (!(ctr
= (SAM_DISPINFO_CTR
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_DISPINFO_CTR
))))
986 return NT_STATUS_NO_MEMORY
;
990 /* Now create reply structure */
991 switch (q_u
->switch_level
) {
994 if (!(ctr
->sam
.info1
= (SAM_DISPINFO_1
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_1
))))
995 return NT_STATUS_NO_MEMORY
;
997 disp_ret
= init_sam_dispinfo_1(p
->mem_ctx
, ctr
->sam
.info1
, max_entries
, enum_context
, info
->disp_info
.disp_user_info
);
998 if (NT_STATUS_IS_ERR(disp_ret
))
1003 if (!(ctr
->sam
.info2
= (SAM_DISPINFO_2
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_2
))))
1004 return NT_STATUS_NO_MEMORY
;
1006 disp_ret
= init_sam_dispinfo_2(p
->mem_ctx
, ctr
->sam
.info2
, max_entries
, enum_context
, info
->disp_info
.disp_user_info
);
1007 if (NT_STATUS_IS_ERR(disp_ret
))
1012 if (!(ctr
->sam
.info3
= (SAM_DISPINFO_3
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_3
))))
1013 return NT_STATUS_NO_MEMORY
;
1015 disp_ret
= init_sam_dispinfo_3(p
->mem_ctx
, ctr
->sam
.info3
, max_entries
, enum_context
, info
->disp_info
.disp_group_info
);
1016 if (NT_STATUS_IS_ERR(disp_ret
))
1021 if (!(ctr
->sam
.info4
= (SAM_DISPINFO_4
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_4
))))
1022 return NT_STATUS_NO_MEMORY
;
1024 disp_ret
= init_sam_dispinfo_4(p
->mem_ctx
, ctr
->sam
.info4
, max_entries
, enum_context
, info
->disp_info
.disp_user_info
);
1025 if (NT_STATUS_IS_ERR(disp_ret
))
1030 if (!(ctr
->sam
.info5
= (SAM_DISPINFO_5
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_5
))))
1031 return NT_STATUS_NO_MEMORY
;
1033 disp_ret
= init_sam_dispinfo_5(p
->mem_ctx
, ctr
->sam
.info5
, max_entries
, enum_context
, info
->disp_info
.disp_group_info
);
1034 if (NT_STATUS_IS_ERR(disp_ret
))
1039 ctr
->sam
.info
= NULL
;
1040 return NT_STATUS_INVALID_INFO_CLASS
;
1043 /* calculate the total size */
1044 total_data_size
=num_account
*struct_size
;
1046 if (enum_context
+max_entries
< num_account
)
1047 r_u
->status
= STATUS_MORE_ENTRIES
;
1049 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__
));
1051 init_samr_r_query_dispinfo(r_u
, max_entries
, total_data_size
, temp_size
, q_u
->switch_level
, ctr
, r_u
->status
);
1057 /*******************************************************************
1058 samr_reply_query_aliasinfo
1059 ********************************************************************/
1061 NTSTATUS
_samr_query_aliasinfo(pipes_struct
*p
, SAMR_Q_QUERY_ALIASINFO
*q_u
, SAMR_R_QUERY_ALIASINFO
*r_u
)
1063 fstring alias_desc
= "Local Unix group";
1065 enum SID_NAME_USE type
;
1067 struct samr_info
*info
= NULL
;
1069 r_u
->status
= NT_STATUS_OK
;
1071 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1073 /* find the policy handle. open a policy on it. */
1074 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1075 return NT_STATUS_INVALID_HANDLE
;
1077 alias_rid
= get_lsa_policy_samr_rid(info
);
1078 if(alias_rid
== 0xffffffff)
1079 return NT_STATUS_NO_SUCH_ALIAS
;
1081 if(!local_lookup_rid(alias_rid
, alias
, &type
))
1082 return NT_STATUS_NO_SUCH_ALIAS
;
1084 switch (q_u
->switch_level
) {
1087 r_u
->ctr
.switch_value1
= 3;
1088 init_samr_alias_info3(&r_u
->ctr
.alias
.info3
, alias_desc
);
1091 return NT_STATUS_INVALID_INFO_CLASS
;
1094 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1100 /*******************************************************************
1101 samr_reply_lookup_ids
1102 ********************************************************************/
1104 uint32
_samr_lookup_ids(pipes_struct
*p
, SAMR_Q_LOOKUP_IDS
*q_u
, SAMR_R_LOOKUP_IDS
*r_u
)
1106 uint32 rid
[MAX_SAM_ENTRIES
];
1107 int num_rids
= q_u
->num_sids1
;
1109 r_u
->status
= NT_STATUS_OK
;
1111 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1113 if (num_rids
> MAX_SAM_ENTRIES
) {
1114 num_rids
= MAX_SAM_ENTRIES
;
1115 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids
));
1120 SMB_ASSERT_ARRAY(q_u
->uni_user_name
, num_rids
);
1122 for (i
= 0; i
< num_rids
&& status
== 0; i
++)
1124 struct sam_passwd
*sam_pass
;
1128 fstrcpy(user_name
, unistrn2(q_u
->uni_user_name
[i
].buffer
,
1129 q_u
->uni_user_name
[i
].uni_str_len
));
1131 /* find the user account */
1133 sam_pass
= get_smb21pwd_entry(user_name
, 0);
1136 if (sam_pass
== NULL
)
1138 status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1143 rid
[i
] = sam_pass
->user_rid
;
1149 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
1151 init_samr_r_lookup_ids(&r_u
, num_rids
, rid
, NT_STATUS_OK
);
1153 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1159 /*******************************************************************
1161 ********************************************************************/
1163 NTSTATUS
_samr_lookup_names(pipes_struct
*p
, SAMR_Q_LOOKUP_NAMES
*q_u
, SAMR_R_LOOKUP_NAMES
*r_u
)
1165 uint32 rid
[MAX_SAM_ENTRIES
];
1167 enum SID_NAME_USE type
[MAX_SAM_ENTRIES
];
1168 enum SID_NAME_USE local_type
;
1170 int num_rids
= q_u
->num_names2
;
1174 r_u
->status
= NT_STATUS_OK
;
1176 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1181 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
)) {
1182 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, 0, NULL
, NULL
, NT_STATUS_OBJECT_TYPE_MISMATCH
);
1186 if (num_rids
> MAX_SAM_ENTRIES
) {
1187 num_rids
= MAX_SAM_ENTRIES
;
1188 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids
));
1191 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str
, &pol_sid
)));
1193 for (i
= 0; i
< num_rids
; i
++) {
1197 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1199 rid
[i
] = 0xffffffff;
1200 type
[i
] = SID_NAME_UNKNOWN
;
1202 fstrcpy(name
, dos_unistrn2(q_u
->uni_name
[i
].buffer
, q_u
->uni_name
[i
].uni_str_len
));
1205 * we are only looking for a name
1206 * the SID we get back can be outside
1207 * the scope of the pol_sid
1209 * in clear: it prevents to reply to domain\group: yes
1210 * when only builtin\group exists.
1212 * a cleaner code is to add the sid of the domain we're looking in
1213 * to the local_lookup_name function.
1216 if(local_lookup_name(global_myname
, name
, &sid
, &local_type
)) {
1217 sid_split_rid(&sid
, &local_rid
);
1219 if (sid_equal(&sid
, &pol_sid
)) {
1222 r_u
->status
= NT_STATUS_OK
;
1227 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, num_rids
, rid
, (uint32
*)type
, r_u
->status
);
1229 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1234 /*******************************************************************
1235 _samr_chgpasswd_user
1236 ********************************************************************/
1238 NTSTATUS
_samr_chgpasswd_user(pipes_struct
*p
, SAMR_Q_CHGPASSWD_USER
*q_u
, SAMR_R_CHGPASSWD_USER
*r_u
)
1243 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1245 r_u
->status
= NT_STATUS_OK
;
1247 fstrcpy(user_name
, dos_unistrn2(q_u
->uni_user_name
.buffer
, q_u
->uni_user_name
.uni_str_len
));
1248 fstrcpy(wks
, dos_unistrn2(q_u
->uni_dest_host
.buffer
, q_u
->uni_dest_host
.uni_str_len
));
1250 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name
, wks
));
1253 * Pass the user through the NT -> unix user mapping
1257 (void)map_username(user_name
);
1260 * Do any UNIX username case mangling.
1262 (void)Get_Pwnam( user_name
, True
);
1264 if (!pass_oem_change(user_name
, q_u
->lm_newpass
.pass
, q_u
->lm_oldhash
.hash
,
1265 q_u
->nt_newpass
.pass
, q_u
->nt_oldhash
.hash
))
1266 r_u
->status
= NT_STATUS_WRONG_PASSWORD
;
1268 init_samr_r_chgpasswd_user(r_u
, r_u
->status
);
1270 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1275 /*******************************************************************
1276 makes a SAMR_R_LOOKUP_RIDS structure.
1277 ********************************************************************/
1279 static BOOL
make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
, fstring names
[],
1280 UNIHDR
**pp_hdr_name
, UNISTR2
**pp_uni_name
)
1283 UNIHDR
*hdr_name
= NULL
;
1284 UNISTR2
*uni_name
= NULL
;
1286 *pp_uni_name
= NULL
;
1287 *pp_hdr_name
= NULL
;
1289 if (num_names
!= 0) {
1290 hdr_name
= (UNIHDR
*)talloc_zero(ctx
, sizeof(UNIHDR
)*num_names
);
1291 if (hdr_name
== NULL
)
1294 uni_name
= (UNISTR2
*)talloc_zero(ctx
,sizeof(UNISTR2
)*num_names
);
1295 if (uni_name
== NULL
)
1299 for (i
= 0; i
< num_names
; i
++) {
1300 int len
= names
[i
] != NULL
? strlen(names
[i
]) : 0;
1301 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
]));
1302 init_uni_hdr(&hdr_name
[i
], len
);
1303 init_unistr2(&uni_name
[i
], names
[i
], len
);
1306 *pp_uni_name
= uni_name
;
1307 *pp_hdr_name
= hdr_name
;
1312 /*******************************************************************
1314 ********************************************************************/
1316 NTSTATUS
_samr_lookup_rids(pipes_struct
*p
, SAMR_Q_LOOKUP_RIDS
*q_u
, SAMR_R_LOOKUP_RIDS
*r_u
)
1318 fstring group_names
[MAX_SAM_ENTRIES
];
1319 uint32
*group_attrs
= NULL
;
1320 UNIHDR
*hdr_name
= NULL
;
1321 UNISTR2
*uni_name
= NULL
;
1323 int num_rids
= q_u
->num_rids1
;
1326 r_u
->status
= NT_STATUS_OK
;
1328 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1330 /* find the policy handle. open a policy on it. */
1331 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
))
1332 return NT_STATUS_INVALID_HANDLE
;
1334 if (num_rids
> MAX_SAM_ENTRIES
) {
1335 num_rids
= MAX_SAM_ENTRIES
;
1336 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids
));
1340 if ((group_attrs
= (uint32
*)talloc_zero(p
->mem_ctx
, num_rids
* sizeof(uint32
))) == NULL
)
1341 return NT_STATUS_NO_MEMORY
;
1344 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1346 for (i
= 0; i
< num_rids
; i
++) {
1350 enum SID_NAME_USE type
;
1352 group_attrs
[i
] = SID_NAME_UNKNOWN
;
1353 *group_names
[i
] = '\0';
1355 if (sid_equal(&pol_sid
, &global_sam_sid
)) {
1356 sid_copy(&sid
, &pol_sid
);
1357 sid_append_rid(&sid
, q_u
->rid
[i
]);
1359 if (lookup_sid(&sid
, domname
, tmpname
, &type
)) {
1360 r_u
->status
= NT_STATUS_OK
;
1361 group_attrs
[i
] = (uint32
)type
;
1362 fstrcpy(group_names
[i
],tmpname
);
1367 if(!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, group_names
, &hdr_name
, &uni_name
))
1368 return NT_STATUS_NO_MEMORY
;
1370 init_samr_r_lookup_rids(r_u
, num_rids
, hdr_name
, uni_name
, group_attrs
);
1372 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1377 /*******************************************************************
1378 _api_samr_open_user. Safe - gives out no passwd info.
1379 ********************************************************************/
1381 NTSTATUS
_api_samr_open_user(pipes_struct
*p
, SAMR_Q_OPEN_USER
*q_u
, SAMR_R_OPEN_USER
*r_u
)
1383 SAM_ACCOUNT
*sampass
=NULL
;
1385 POLICY_HND domain_pol
= q_u
->domain_pol
;
1386 uint32 user_rid
= q_u
->user_rid
;
1387 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1388 struct samr_info
*info
= NULL
;
1391 r_u
->status
= NT_STATUS_OK
;
1393 /* find the domain policy handle. */
1394 if (!find_policy_by_hnd(p
, &domain_pol
, NULL
))
1395 return NT_STATUS_INVALID_HANDLE
;
1397 pdb_init_sam(&sampass
);
1400 ret
=pdb_getsampwrid(sampass
, user_rid
);
1403 /* check that the RID exists in our domain. */
1405 pdb_free_sam(sampass
);
1406 return NT_STATUS_NO_SUCH_USER
;
1409 samr_clear_sam_passwd(sampass
);
1410 pdb_free_sam(sampass
);
1412 /* Get the domain SID stored in the domain policy */
1413 if(!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
))
1414 return NT_STATUS_INVALID_HANDLE
;
1416 /* append the user's RID to it */
1417 if(!sid_append_rid(&sid
, user_rid
))
1418 return NT_STATUS_NO_SUCH_USER
;
1420 /* associate the user's SID with the new handle. */
1421 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
)
1422 return NT_STATUS_NO_MEMORY
;
1424 /* get a (unique) handle. open a policy on it. */
1425 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
))
1426 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1431 /*************************************************************************
1432 get_user_info_10. Safe. Only gives out acb bits.
1433 *************************************************************************/
1435 static BOOL
get_user_info_10(SAM_USER_INFO_10
*id10
, uint32 user_rid
)
1437 SAM_ACCOUNT
*smbpass
=NULL
;
1440 if (!pdb_rid_is_user(user_rid
)) {
1441 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1445 pdb_init_sam(&smbpass
);
1448 ret
= pdb_getsampwrid(smbpass
, user_rid
);
1452 DEBUG(4,("User 0x%x not found\n", user_rid
));
1453 pdb_free_sam(smbpass
);
1457 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass
) ));
1460 init_sam_user_info10(id10
, pdb_get_acct_ctrl(smbpass
) );
1462 samr_clear_sam_passwd(smbpass
);
1463 pdb_free_sam(smbpass
);
1468 /*************************************************************************
1469 get_user_info_12. OK - this is the killer as it gives out password info.
1470 Ensure that this is only allowed on an encrypted connection with a root
1472 *************************************************************************/
1474 static NTSTATUS
get_user_info_12(pipes_struct
*p
, SAM_USER_INFO_12
* id12
, uint32 user_rid
)
1476 SAM_ACCOUNT
*smbpass
=NULL
;
1479 if (!p
->ntlmssp_auth_validated
)
1480 return NT_STATUS_ACCESS_DENIED
;
1482 if (!(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SIGN
) || !(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SEAL
))
1483 return NT_STATUS_ACCESS_DENIED
;
1486 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1488 pdb_init_sam(&smbpass
);
1490 ret
= pdb_getsampwrid(smbpass
, user_rid
);
1493 DEBUG(4, ("User 0x%x not found\n", user_rid
));
1494 pdb_free_sam(smbpass
);
1495 return (geteuid() == (uid_t
)0) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
1498 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
1500 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
1501 pdb_free_sam(smbpass
);
1502 return NT_STATUS_ACCOUNT_DISABLED
;
1506 init_sam_user_info12(id12
, pdb_get_lanman_passwd(smbpass
), pdb_get_nt_passwd(smbpass
));
1508 pdb_free_sam(smbpass
);
1510 return NT_STATUS_OK
;
1513 #if 1 /* JRA - re-enabled... JERRY - why was this removed ? */
1514 /*************************************************************************
1516 *************************************************************************/
1518 static BOOL
get_user_info_20(SAM_USER_INFO_20
*id20
, uint32 user_rid
)
1520 SAM_ACCOUNT
*sampass
=NULL
;
1523 if (!pdb_rid_is_user(user_rid
)) {
1524 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1528 pdb_init_sam(&sampass
);
1531 ret
= pdb_getsampwrid(sampass
, user_rid
);
1535 DEBUG(4,("User 0x%x not found\n", user_rid
));
1536 pdb_free_sam(sampass
);
1540 samr_clear_sam_passwd(sampass
);
1542 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1545 init_sam_user_info20A(id20
, sampass
);
1547 pdb_free_sam(sampass
);
1553 /*************************************************************************
1555 *************************************************************************/
1557 static BOOL
get_user_info_21(SAM_USER_INFO_21
*id21
, uint32 user_rid
)
1559 SAM_ACCOUNT
*sampass
=NULL
;
1562 if (!pdb_rid_is_user(user_rid
)) {
1563 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid
));
1567 pdb_init_sam(&sampass
);
1570 ret
= pdb_getsampwrid(sampass
, user_rid
);
1574 DEBUG(4,("User 0x%x not found\n", user_rid
));
1575 pdb_free_sam(sampass
);
1579 samr_clear_sam_passwd(sampass
);
1581 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1584 init_sam_user_info21A(id21
, sampass
);
1586 pdb_free_sam(sampass
);
1591 /*******************************************************************
1592 _samr_query_userinfo
1593 ********************************************************************/
1595 NTSTATUS
_samr_query_userinfo(pipes_struct
*p
, SAMR_Q_QUERY_USERINFO
*q_u
, SAMR_R_QUERY_USERINFO
*r_u
)
1597 SAM_USERINFO_CTR
*ctr
;
1599 struct samr_info
*info
= NULL
;
1601 r_u
->status
=NT_STATUS_OK
;
1603 /* search for the handle */
1604 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1605 return NT_STATUS_INVALID_HANDLE
;
1607 /* find the user's rid */
1608 if ((rid
= get_lsa_policy_samr_rid(info
)) == 0xffffffff)
1609 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1611 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid
));
1613 ctr
= (SAM_USERINFO_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USERINFO_CTR
));
1615 return NT_STATUS_NO_MEMORY
;
1619 /* ok! user info levels (lots: see MSDEV help), off we go... */
1620 ctr
->switch_value
= q_u
->switch_value
;
1622 switch (q_u
->switch_value
) {
1624 ctr
->info
.id10
= (SAM_USER_INFO_10
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USER_INFO_10
));
1625 if (ctr
->info
.id10
== NULL
)
1626 return NT_STATUS_NO_MEMORY
;
1628 if (!get_user_info_10(ctr
->info
.id10
, rid
))
1629 return NT_STATUS_NO_SUCH_USER
;
1633 /* whoops - got this wrong. i think. or don't understand what's happening. */
1637 info
= (void *)&id11
;
1639 expire
.low
= 0xffffffff;
1640 expire
.high
= 0x7fffffff;
1642 ctr
->info
.id
= (SAM_USER_INFO_11
*)talloc_zero(p
->mem_ctx
,
1647 init_sam_user_info11(ctr
->info
.id11
, &expire
,
1648 "BROOKFIELDS$", /* name */
1649 0x03ef, /* user rid */
1650 0x201, /* group rid */
1651 0x0080); /* acb info */
1658 ctr
->info
.id12
= (SAM_USER_INFO_12
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USER_INFO_12
));
1659 if (ctr
->info
.id12
== NULL
)
1660 return NT_STATUS_NO_MEMORY
;
1662 if (NT_STATUS_IS_ERR(r_u
->status
= get_user_info_12(p
, ctr
->info
.id12
, rid
)))
1667 ctr
->info
.id20
= (SAM_USER_INFO_20
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_USER_INFO_20
));
1668 if (ctr
->info
.id20
== NULL
)
1669 return NT_STATUS_NO_MEMORY
;
1670 if (!get_user_info_20(ctr
->info
.id20
, rid
))
1671 return NT_STATUS_NO_SUCH_USER
;
1675 ctr
->info
.id21
= (SAM_USER_INFO_21
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_USER_INFO_21
));
1676 if (ctr
->info
.id21
== NULL
)
1677 return NT_STATUS_NO_MEMORY
;
1678 if (!get_user_info_21(ctr
->info
.id21
, rid
))
1679 return NT_STATUS_NO_SUCH_USER
;
1683 return NT_STATUS_INVALID_INFO_CLASS
;
1686 init_samr_r_query_userinfo(r_u
, ctr
, r_u
->status
);
1688 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__
));
1693 /*******************************************************************
1694 samr_reply_query_usergroups
1695 ********************************************************************/
1697 NTSTATUS
_samr_query_usergroups(pipes_struct
*p
, SAMR_Q_QUERY_USERGROUPS
*q_u
, SAMR_R_QUERY_USERGROUPS
*r_u
)
1699 SAM_ACCOUNT
*sam_pass
=NULL
;
1700 DOM_GID
*gids
= NULL
;
1704 struct samr_info
*info
= NULL
;
1707 r_u
->status
= NT_STATUS_OK
;
1709 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
1711 /* find the policy handle. open a policy on it. */
1712 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1713 return NT_STATUS_INVALID_HANDLE
;
1715 /* find the user's rid */
1716 if ((rid
= get_lsa_policy_samr_rid(info
)) == 0xffffffff)
1717 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1719 pdb_init_sam(&sam_pass
);
1722 ret
= pdb_getsampwrid(sam_pass
, rid
);
1726 samr_clear_sam_passwd(sam_pass
);
1727 pdb_free_sam(sam_pass
);
1728 return NT_STATUS_NO_SUCH_USER
;
1731 get_domain_user_groups(groups
, pdb_get_username(sam_pass
));
1733 num_groups
= make_dom_gids(p
->mem_ctx
, groups
, &gids
);
1735 /* construct the response. lkclXXXX: gids are not copied! */
1736 init_samr_r_query_usergroups(r_u
, num_groups
, gids
, r_u
->status
);
1738 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
1740 samr_clear_sam_passwd(sam_pass
);
1741 pdb_free_sam(sam_pass
);
1746 /*******************************************************************
1747 _samr_query_dom_info
1748 ********************************************************************/
1750 NTSTATUS
_samr_query_dom_info(pipes_struct
*p
, SAMR_Q_QUERY_DOMAIN_INFO
*q_u
, SAMR_R_QUERY_DOMAIN_INFO
*r_u
)
1752 struct samr_info
*info
= NULL
;
1754 uint32 min_pass_len
,pass_hist
,flag
;
1755 time_t u_expire
, u_min_age
;
1756 NTTIME nt_expire
, nt_min_age
;
1758 time_t u_lock_duration
, u_reset_time
;
1759 NTTIME nt_lock_duration
, nt_reset_time
;
1765 uint32 num_users
=0, num_groups
=0, num_aliases
=0;
1767 if ((ctr
= (SAM_UNK_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_UNK_CTR
))) == NULL
)
1768 return NT_STATUS_NO_MEMORY
;
1772 r_u
->status
= NT_STATUS_OK
;
1774 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
1776 /* find the policy handle. open a policy on it. */
1777 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
1778 return NT_STATUS_INVALID_HANDLE
;
1780 switch (q_u
->switch_value
) {
1782 /* Use defaults until we merge with HEAD db. JRA */
1783 min_pass_len
= MINPASSWDLENGTH
; /* 5 chars minimum */
1784 pass_hist
= 0; /* don't keep any old password */
1785 flag
= 0; /* don't force user to logon */
1786 u_expire
= MAX_PASSWORD_AGE
; /* 21 days */
1787 u_min_age
= 0; /* 0 days */
1789 unix_to_nt_time_abs(&nt_expire
, u_expire
);
1790 unix_to_nt_time_abs(&nt_min_age
, u_min_age
);
1792 init_unk_info1(&ctr
->info
.inf1
, (uint16
)min_pass_len
, (uint16
)pass_hist
,
1793 flag
, nt_expire
, nt_min_age
);
1797 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
);
1799 if (NT_STATUS_IS_ERR(r_u
->status
)) {
1800 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1803 num_users
=info
->disp_info
.num_user_account
;
1806 r_u
->status
=load_group_domain_entries(info
, &global_sam_sid
);
1807 if (NT_STATUS_IS_ERR(r_u
->status
)) {
1808 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
1811 num_groups
=info
->disp_info
.num_group_account
;
1814 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1815 init_unk_info2(&ctr
->info
.inf2
, global_myworkgroup
, global_myname
, (uint32
) time(NULL
),
1816 num_users
, num_groups
, num_aliases
);
1819 /* Use defaults until we merge with HEAD db. JRA */
1820 u_logout
= -1; /* don't force logout */
1821 unix_to_nt_time_abs(&nt_logout
, u_logout
);
1822 init_unk_info3(&ctr
->info
.inf3
, nt_logout
);
1825 init_unk_info5(&ctr
->info
.inf5
, global_myname
);
1828 init_unk_info6(&ctr
->info
.inf6
);
1831 init_unk_info7(&ctr
->info
.inf7
);
1834 /* Use defaults until we merge with HEAD db. JRA */
1835 u_lock_duration
= 0; /* lockout for 0 minutes */
1836 u_reset_time
= 0; /* reset immediatly */
1837 lockout
= 0; /* don't lockout */
1839 unix_to_nt_time_abs(&nt_lock_duration
, u_lock_duration
);
1840 unix_to_nt_time_abs(&nt_reset_time
, u_reset_time
);
1842 init_unk_info12(&ctr
->info
.inf12
, nt_lock_duration
, nt_reset_time
, (uint16
)lockout
);
1845 return NT_STATUS_INVALID_INFO_CLASS
;
1848 init_samr_r_query_dom_info(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_OK
);
1850 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
1855 /*******************************************************************
1856 _api_samr_create_user
1857 Create an account, can be either a normal user or a machine.
1858 This funcion will need to be updated for bdc/domain trusts.
1859 ********************************************************************/
1861 NTSTATUS
_api_samr_create_user(pipes_struct
*p
, SAMR_Q_CREATE_USER
*q_u
, SAMR_R_CREATE_USER
*r_u
)
1863 SAM_ACCOUNT
*sam_pass
=NULL
;
1870 POLICY_HND dom_pol
= q_u
->domain_pol
;
1871 UNISTR2 user_account
= q_u
->uni_name
;
1872 uint16 acb_info
= q_u
->acb_info
;
1873 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1874 struct samr_info
*info
= NULL
;
1877 /* find the policy handle. open a policy on it. */
1878 if (!find_policy_by_hnd(p
, &dom_pol
, NULL
))
1879 return NT_STATUS_INVALID_HANDLE
;
1881 /* find the machine account: tell the caller if it exists.
1882 lkclXXXX i have *no* idea if this is a problem or not
1883 or even if you are supposed to construct a different
1884 reply if the account already exists...
1887 fstrcpy(mach_acct
, dos_unistrn2(user_account
.buffer
, user_account
.uni_str_len
));
1888 strlower(mach_acct
);
1890 pdb_init_sam(&sam_pass
);
1893 ret
= pdb_getsampwnam(sam_pass
, mach_acct
);
1896 /* machine account exists: say so */
1897 pdb_free_sam(sam_pass
);
1898 return NT_STATUS_USER_EXISTS
;
1901 local_flags
=LOCAL_ADD_USER
|LOCAL_DISABLE_USER
|LOCAL_SET_NO_PASSWORD
;
1902 local_flags
|= (acb_info
& ACB_WSTRUST
) ? LOCAL_TRUST_ACCOUNT
:0;
1905 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1906 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1907 * that only people with write access to the smbpasswd file will be able
1908 * to create a user. JRA.
1912 * add the user in the /etc/passwd file or the unix authority system.
1913 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1914 * a) local_password_change() checks for us if the /etc/passwd account really exists
1915 * b) smb_create_user() would return an error if the account already exists
1916 * and as it could return an error also if it can't create the account, it would be tricky.
1918 * So we go the easy way, only check after if the account exists.
1919 * JFM (2/3/2001), to clear any possible bad understanding (-:
1922 pstrcpy(add_script
, lp_adduser_script());
1925 smb_create_user(mach_acct
, NULL
);
1927 /* add the user in the smbpasswd file or the Samba authority database */
1928 if (!local_password_change(mach_acct
, local_flags
, NULL
, err_str
, sizeof(err_str
), msg_str
, sizeof(msg_str
))) {
1929 DEBUG(0, ("%s\n", err_str
));
1930 pdb_free_sam(sam_pass
);
1931 return NT_STATUS_ACCESS_DENIED
;
1935 ret
= pdb_getsampwnam(sam_pass
, mach_acct
);
1938 /* account doesn't exist: say so */
1939 pdb_free_sam(sam_pass
);
1940 return NT_STATUS_ACCESS_DENIED
;
1943 /* Get the domain SID stored in the domain policy */
1944 if(!get_lsa_policy_samr_sid(p
, &dom_pol
, &sid
)) {
1945 pdb_free_sam(sam_pass
);
1946 return NT_STATUS_INVALID_HANDLE
;
1949 /* append the user's RID to it */
1950 if(!sid_append_rid(&sid
, pdb_get_user_rid(sam_pass
) )) {
1951 pdb_free_sam(sam_pass
);
1952 return NT_STATUS_NO_SUCH_USER
;
1955 /* associate the user's SID with the new handle. */
1957 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
) {
1958 pdb_free_sam(sam_pass
);
1959 return NT_STATUS_NO_MEMORY
;
1962 /* get a (unique) handle. open a policy on it. */
1963 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
)) {
1964 pdb_free_sam(sam_pass
);
1965 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1968 r_u
->user_rid
=sam_pass
->user_rid
;
1969 r_u
->unknown_0
= 0x000703ff;
1971 pdb_free_sam(sam_pass
);
1973 return NT_STATUS_OK
;
1976 /*******************************************************************
1977 samr_reply_connect_anon
1978 ********************************************************************/
1980 NTSTATUS
_samr_connect_anon(pipes_struct
*p
, SAMR_Q_CONNECT_ANON
*q_u
, SAMR_R_CONNECT_ANON
*r_u
)
1982 struct samr_info
*info
= NULL
;
1984 /* set up the SAMR connect_anon response */
1986 r_u
->status
= NT_STATUS_OK
;
1988 /* associate the user's SID with the new handle. */
1989 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
1990 return NT_STATUS_NO_MEMORY
;
1992 info
->status
= q_u
->unknown_0
;
1994 /* get a (unique) handle. open a policy on it. */
1995 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
1996 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2001 /*******************************************************************
2003 ********************************************************************/
2005 NTSTATUS
_samr_connect(pipes_struct
*p
, SAMR_Q_CONNECT
*q_u
, SAMR_R_CONNECT
*r_u
)
2007 struct samr_info
*info
= NULL
;
2009 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2011 r_u
->status
= NT_STATUS_OK
;
2013 /* associate the user's SID with the new handle. */
2014 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2015 return NT_STATUS_NO_MEMORY
;
2017 info
->status
= q_u
->access_mask
;
2019 /* get a (unique) handle. open a policy on it. */
2020 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2021 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2023 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2028 /**********************************************************************
2029 api_samr_lookup_domain
2030 **********************************************************************/
2032 NTSTATUS
_samr_lookup_domain(pipes_struct
*p
, SAMR_Q_LOOKUP_DOMAIN
*q_u
, SAMR_R_LOOKUP_DOMAIN
*r_u
)
2034 fstring domain_name
;
2037 r_u
->status
= NT_STATUS_OK
;
2039 if (!find_policy_by_hnd(p
, &q_u
->connect_pol
, NULL
))
2040 return NT_STATUS_INVALID_HANDLE
;
2042 fstrcpy(domain_name
, dos_unistrn2( q_u
->uni_domain
.buffer
, q_u
->uni_domain
.uni_str_len
));
2046 if (!secrets_fetch_domain_sid(domain_name
, &sid
)) {
2047 r_u
->status
= NT_STATUS_NO_SUCH_DOMAIN
;
2050 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
, sid_string_static(&sid
)));
2052 init_samr_r_lookup_domain(r_u
, &sid
, r_u
->status
);
2057 /******************************************************************
2058 makes a SAMR_R_ENUM_DOMAINS structure.
2059 ********************************************************************/
2061 static BOOL
make_enum_domains(TALLOC_CTX
*ctx
, SAM_ENTRY
**pp_sam
,
2062 UNISTR2
**pp_uni_name
, uint32 num_sam_entries
, fstring doms
[])
2068 DEBUG(5, ("make_enum_domains\n"));
2071 *pp_uni_name
= NULL
;
2073 if (num_sam_entries
== 0)
2076 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
2077 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
2079 if (sam
== NULL
|| uni_name
== NULL
)
2082 for (i
= 0; i
< num_sam_entries
; i
++) {
2083 int len
= doms
[i
] != NULL
? strlen(doms
[i
]) : 0;
2085 init_sam_entry(&sam
[i
], len
, 0);
2086 init_unistr2(&uni_name
[i
], doms
[i
], len
);
2090 *pp_uni_name
= uni_name
;
2095 /**********************************************************************
2096 api_samr_enum_domains
2097 **********************************************************************/
2099 NTSTATUS
_samr_enum_domains(pipes_struct
*p
, SAMR_Q_ENUM_DOMAINS
*q_u
, SAMR_R_ENUM_DOMAINS
*r_u
)
2101 uint32 num_entries
= 2;
2105 r_u
->status
= NT_STATUS_OK
;
2107 switch (lp_server_role()) {
2108 case ROLE_DOMAIN_PDC
:
2109 case ROLE_DOMAIN_BDC
:
2110 name
= global_myworkgroup
;
2113 name
= global_myname
;
2116 fstrcpy(dom
[0],name
);
2118 fstrcpy(dom
[1],"Builtin");
2120 if (!make_enum_domains(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_dom_name
, num_entries
, dom
))
2121 return NT_STATUS_NO_MEMORY
;
2123 init_samr_r_enum_domains(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
2128 /*******************************************************************
2130 ********************************************************************/
2132 NTSTATUS
_api_samr_open_alias(pipes_struct
*p
, SAMR_Q_OPEN_ALIAS
*q_u
, SAMR_R_OPEN_ALIAS
*r_u
)
2135 POLICY_HND domain_pol
= q_u
->dom_pol
;
2136 uint32 alias_rid
= q_u
->rid_alias
;
2137 POLICY_HND
*alias_pol
= &r_u
->pol
;
2138 struct samr_info
*info
= NULL
;
2140 r_u
->status
= NT_STATUS_OK
;
2142 /* get the domain policy. */
2143 if (!find_policy_by_hnd(p
, &domain_pol
, NULL
))
2144 return NT_STATUS_INVALID_HANDLE
;
2146 /* Get the domain SID stored in the domain policy */
2147 if(!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
))
2148 return NT_STATUS_INVALID_HANDLE
;
2150 /* append the alias' RID to it */
2151 if(!sid_append_rid(&sid
, alias_rid
))
2152 return NT_STATUS_NO_SUCH_USER
;
2155 * we should check if the rid really exist !!!
2159 /* associate the user's SID with the new handle. */
2160 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
)
2161 return NT_STATUS_NO_MEMORY
;
2163 /* get a (unique) handle. open a policy on it. */
2164 if (!create_policy_hnd(p
, alias_pol
, free_samr_info
, (void *)info
))
2165 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2170 /*******************************************************************
2172 ********************************************************************/
2174 static BOOL
set_user_info_10(const SAM_USER_INFO_10
*id10
, uint32 rid
)
2176 SAM_ACCOUNT
*pwd
=NULL
;
2181 ret
= pdb_getsampwrid(pwd
, rid
);
2189 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2194 if (!pdb_set_acct_ctrl(pwd
, id10
->acb_info
)) {
2199 if(!pdb_update_sam_account(pwd
, True
)) {
2209 /*******************************************************************
2211 ********************************************************************/
2213 static BOOL
set_user_info_12(SAM_USER_INFO_12
*id12
, uint32 rid
)
2215 SAM_ACCOUNT
*pwd
= NULL
;
2219 if(!pdb_getsampwrid(pwd
, rid
)) {
2225 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2230 if (!pdb_set_lanman_passwd (pwd
, id12
->lm_pwd
)) {
2234 if (!pdb_set_nt_passwd(pwd
, id12
->nt_pwd
)) {
2239 if(!pdb_update_sam_account(pwd
, True
)) {
2248 /*******************************************************************
2250 ********************************************************************/
2252 static BOOL
set_user_info_21(SAM_USER_INFO_21
*id21
, uint32 rid
)
2254 SAM_ACCOUNT
*pwd
= NULL
;
2258 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2264 if (!pdb_getsampwrid(pwd
, rid
)) {
2269 /* we make a copy so that we can modify stuff */
2270 copy_id21_to_sam_passwd(pwd
, id21
);
2273 * The funny part about the previous two calls is
2274 * that pwd still has the password hashes from the
2275 * passdb entry. These have not been updated from
2276 * id21. I don't know if they need to be set. --jerry
2279 /* write the change out */
2280 if(!pdb_update_sam_account(pwd
, True
)) {
2290 /*******************************************************************
2292 ********************************************************************/
2294 static BOOL
set_user_info_23(SAM_USER_INFO_23
*id23
, uint32 rid
)
2296 SAM_ACCOUNT
*pwd
= NULL
;
2305 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2311 if (!pdb_getsampwrid(pwd
, rid
)) {
2316 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2318 copy_id23_to_sam_passwd(pwd
, id23
);
2320 if (!decode_pw_buffer((char*)id23
->pass
, buf
, 256, &len
, nt_hash
, lm_hash
)) {
2325 if (!pdb_set_lanman_passwd (pwd
, lm_hash
)) {
2329 if (!pdb_set_nt_passwd(pwd
, nt_hash
)) {
2334 /* if it's a trust account, don't update /etc/passwd */
2335 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2336 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2337 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2338 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2340 /* update the UNIX password */
2341 if (lp_unix_password_sync() )
2342 if(!chgpasswd(pdb_get_username(pwd
), "", buf
, True
)) {
2348 memset(buf
, 0, sizeof(buf
));
2350 if(!pdb_update_sam_account(pwd
, True
)) {
2360 /*******************************************************************
2362 ********************************************************************/
2364 static BOOL
set_user_info_pw(char *pass
, uint32 rid
)
2366 SAM_ACCOUNT
*pwd
= NULL
;
2375 if (!pdb_getsampwrid(pwd
, rid
)) {
2380 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2382 memset(buf
, 0, sizeof(buf
));
2384 if (!decode_pw_buffer(pass
, buf
, 256, &len
, nt_hash
, lm_hash
)) {
2389 if (!pdb_set_lanman_passwd (pwd
, lm_hash
)) {
2393 if (!pdb_set_nt_passwd(pwd
, nt_hash
)) {
2398 /* if it's a trust account, don't update /etc/passwd */
2399 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2400 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2401 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2402 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2404 /* update the UNIX password */
2405 if (lp_unix_password_sync())
2406 if(!chgpasswd(pdb_get_username(pwd
), "", buf
, True
)) {
2412 memset(buf
, 0, sizeof(buf
));
2414 DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
2416 /* update the SAMBA password */
2417 if(!pdb_update_sam_account(pwd
, True
)) {
2427 /*******************************************************************
2428 samr_reply_set_userinfo
2429 ********************************************************************/
2431 NTSTATUS
_samr_set_userinfo(pipes_struct
*p
, SAMR_Q_SET_USERINFO
*q_u
, SAMR_R_SET_USERINFO
*r_u
)
2435 struct current_user user
;
2436 SAM_ACCOUNT
*sam_pass
=NULL
;
2437 unsigned char sess_key
[16];
2438 POLICY_HND
*pol
= &q_u
->pol
;
2439 uint16 switch_value
= q_u
->switch_value
;
2440 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
2443 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__
));
2445 r_u
->status
= NT_STATUS_OK
;
2447 if (p
->ntlmssp_auth_validated
) {
2448 memcpy(&user
, &p
->pipe_user
, sizeof(user
));
2450 extern struct current_user current_user
;
2451 memcpy(&user
, ¤t_user
, sizeof(user
));
2454 /* find the policy handle. open a policy on it. */
2455 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
))
2456 return NT_STATUS_INVALID_HANDLE
;
2458 sid_split_rid(&sid
, &rid
);
2460 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid
, switch_value
));
2463 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2464 return NT_STATUS_INVALID_INFO_CLASS
;
2468 pdb_init_sam(&sam_pass
);
2471 * We need the NT hash of the user who is changing the user's password.
2472 * This NT hash is used to generate a "user session key"
2473 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2477 ret
= pdb_getsampwuid(sam_pass
, user
.uid
);
2480 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user
.uid
));
2481 pdb_free_sam(sam_pass
);
2482 return NT_STATUS_ACCESS_DENIED
;
2485 memset(sess_key
, '\0', 16);
2486 mdfour(sess_key
, pdb_get_nt_passwd(sam_pass
), 16);
2488 pdb_free_sam(sam_pass
);
2491 /* ok! user info levels (lots: see MSDEV help), off we go... */
2492 switch (switch_value
) {
2494 if (!set_user_info_12(ctr
->info
.id12
, rid
))
2495 return NT_STATUS_ACCESS_DENIED
;
2499 SamOEMhash(ctr
->info
.id24
->pass
, sess_key
, 516);
2501 dump_data(100, (char *)ctr
->info
.id24
->pass
, 516);
2503 if (!set_user_info_pw((char *)ctr
->info
.id24
->pass
, rid
))
2504 return NT_STATUS_ACCESS_DENIED
;
2510 * Currently we don't really know how to unmarshall
2511 * the level 25 struct, and the password encryption
2512 * is different. This is a placeholder for when we
2513 * do understand it. In the meantime just return INVALID
2514 * info level and W2K SP2 drops down to level 23... JRA.
2517 SamOEMhash(ctr
->info
.id25
->pass
, sess_key
, 532);
2519 dump_data(100, (char *)ctr
->info
.id25
->pass
, 532);
2521 if (!set_user_info_pw(ctr
->info
.id25
->pass
, rid
))
2522 return NT_STATUS_ACCESS_DENIED
;
2525 return NT_STATUS_INVALID_INFO_CLASS
;
2528 SamOEMhash(ctr
->info
.id23
->pass
, sess_key
, 516);
2530 dump_data(100, (char *)ctr
->info
.id23
->pass
, 516);
2532 if (!set_user_info_23(ctr
->info
.id23
, rid
))
2533 return NT_STATUS_ACCESS_DENIED
;
2537 return NT_STATUS_INVALID_INFO_CLASS
;
2543 /*******************************************************************
2544 samr_reply_set_userinfo2
2545 ********************************************************************/
2547 NTSTATUS
_samr_set_userinfo2(pipes_struct
*p
, SAMR_Q_SET_USERINFO2
*q_u
, SAMR_R_SET_USERINFO2
*r_u
)
2551 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
2552 POLICY_HND
*pol
= &q_u
->pol
;
2553 uint16 switch_value
= q_u
->switch_value
;
2555 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__
));
2557 r_u
->status
= NT_STATUS_OK
;
2559 /* find the policy handle. open a policy on it. */
2560 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
))
2561 return NT_STATUS_INVALID_HANDLE
;
2563 sid_split_rid(&sid
, &rid
);
2565 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid
));
2568 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2569 return NT_STATUS_INVALID_INFO_CLASS
;
2572 switch_value
=ctr
->switch_value
;
2574 /* ok! user info levels (lots: see MSDEV help), off we go... */
2575 switch (switch_value
) {
2577 if (!set_user_info_21(ctr
->info
.id21
, rid
))
2578 return NT_STATUS_ACCESS_DENIED
;
2581 if (!set_user_info_10(ctr
->info
.id10
, rid
))
2582 return NT_STATUS_ACCESS_DENIED
;
2585 /* Used by AS/U JRA. */
2586 if (!set_user_info_12(ctr
->info
.id12
, rid
))
2587 return NT_STATUS_ACCESS_DENIED
;
2590 return NT_STATUS_INVALID_INFO_CLASS
;
2596 /*********************************************************************
2597 _samr_query_aliasmem
2598 *********************************************************************/
2600 NTSTATUS
_samr_query_useraliases(pipes_struct
*p
, SAMR_Q_QUERY_USERALIASES
*q_u
, SAMR_R_QUERY_USERALIASES
*r_u
)
2606 rid
=(uint32
*)talloc_zero(p
->mem_ctx
, num_rids
*sizeof(uint32
));
2608 return NT_STATUS_NO_MEMORY
;
2610 /* until i see a real useraliases query, we fack one up */
2612 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
2614 init_samr_r_query_useraliases(r_u
, num_rids
, rid
, NT_STATUS_OK
);
2616 return NT_STATUS_OK
;
2620 /*********************************************************************
2621 _samr_query_aliasmem
2622 *********************************************************************/
2624 NTSTATUS
_samr_query_aliasmem(pipes_struct
*p
, SAMR_Q_QUERY_ALIASMEM
*q_u
, SAMR_R_QUERY_ALIASMEM
*r_u
)
2626 DEBUG(0,("_samr_query_aliasmem: Not yet implemented.\n"));
2627 return NT_STATUS_NOT_IMPLEMENTED
;
2630 /*********************************************************************
2631 _samr_query_groupmem
2632 *********************************************************************/
2634 NTSTATUS
_samr_query_groupmem(pipes_struct
*p
, SAMR_Q_QUERY_GROUPMEM
*q_u
, SAMR_R_QUERY_GROUPMEM
*r_u
)
2636 DEBUG(0,("_samr_query_groupmem: Not yet implemented.\n"));
2637 return NT_STATUS_NOT_IMPLEMENTED
;
2640 /*********************************************************************
2642 *********************************************************************/
2644 NTSTATUS
_samr_add_aliasmem(pipes_struct
*p
, SAMR_Q_ADD_ALIASMEM
*q_u
, SAMR_R_ADD_ALIASMEM
*r_u
)
2646 DEBUG(0,("_samr_add_aliasmem: Not yet implemented.\n"));
2647 return NT_STATUS_NOT_IMPLEMENTED
;
2650 /*********************************************************************
2652 *********************************************************************/
2654 NTSTATUS
_samr_del_aliasmem(pipes_struct
*p
, SAMR_Q_DEL_ALIASMEM
*q_u
, SAMR_R_DEL_ALIASMEM
*r_u
)
2656 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2657 return NT_STATUS_NOT_IMPLEMENTED
;
2660 /*********************************************************************
2662 *********************************************************************/
2664 NTSTATUS
_samr_add_groupmem(pipes_struct
*p
, SAMR_Q_ADD_GROUPMEM
*q_u
, SAMR_R_ADD_GROUPMEM
*r_u
)
2666 DEBUG(0,("_samr_add_groupmem: Not yet implemented.\n"));
2667 return NT_STATUS_NOT_IMPLEMENTED
;
2670 /*********************************************************************
2672 *********************************************************************/
2674 NTSTATUS
_samr_del_groupmem(pipes_struct
*p
, SAMR_Q_DEL_GROUPMEM
*q_u
, SAMR_R_DEL_GROUPMEM
*r_u
)
2676 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2677 return NT_STATUS_NOT_IMPLEMENTED
;
2680 /*********************************************************************
2681 _samr_delete_dom_user
2682 *********************************************************************/
2684 NTSTATUS
_samr_delete_dom_user(pipes_struct
*p
, SAMR_Q_DELETE_DOM_USER
*q_u
, SAMR_R_DELETE_DOM_USER
*r_u
)
2686 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2687 return NT_STATUS_NOT_IMPLEMENTED
;
2690 /*********************************************************************
2691 _samr_delete_dom_group
2692 *********************************************************************/
2694 NTSTATUS
_samr_delete_dom_group(pipes_struct
*p
, SAMR_Q_DELETE_DOM_GROUP
*q_u
, SAMR_R_DELETE_DOM_GROUP
*r_u
)
2696 DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
2697 return NT_STATUS_NOT_IMPLEMENTED
;
2700 /*********************************************************************
2701 _samr_delete_dom_alias
2702 *********************************************************************/
2704 NTSTATUS
_samr_delete_dom_alias(pipes_struct
*p
, SAMR_Q_DELETE_DOM_ALIAS
*q_u
, SAMR_R_DELETE_DOM_ALIAS
*r_u
)
2706 DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
2707 return NT_STATUS_NOT_IMPLEMENTED
;
2710 /*********************************************************************
2711 _samr_create_dom_group
2712 *********************************************************************/
2714 NTSTATUS
_samr_create_dom_group(pipes_struct
*p
, SAMR_Q_CREATE_DOM_GROUP
*q_u
, SAMR_R_CREATE_DOM_GROUP
*r_u
)
2716 DEBUG(0,("_samr_create_dom_group: Not yet implemented.\n"));
2717 return NT_STATUS_NOT_IMPLEMENTED
;
2720 /*********************************************************************
2721 _samr_create_dom_alias
2722 *********************************************************************/
2724 NTSTATUS
_samr_create_dom_alias(pipes_struct
*p
, SAMR_Q_CREATE_DOM_ALIAS
*q_u
, SAMR_R_CREATE_DOM_ALIAS
*r_u
)
2726 DEBUG(0,("_samr_create_dom_alias: Not yet implemented.\n"));
2727 return NT_STATUS_NOT_IMPLEMENTED
;
2730 /*********************************************************************
2731 _samr_query_groupinfo
2732 *********************************************************************/
2734 NTSTATUS
_samr_query_groupinfo(pipes_struct
*p
, SAMR_Q_QUERY_GROUPINFO
*q_u
, SAMR_R_QUERY_GROUPINFO
*r_u
)
2736 DEBUG(0,("_samr_query_groupinfo: Not yet implemented.\n"));
2737 return NT_STATUS_NOT_IMPLEMENTED
;
2740 /*********************************************************************
2742 *********************************************************************/
2744 NTSTATUS
_samr_set_groupinfo(pipes_struct
*p
, SAMR_Q_SET_GROUPINFO
*q_u
, SAMR_R_SET_GROUPINFO
*r_u
)
2746 DEBUG(0,("_samr_set_groupinfo: Not yet implemented.\n"));
2747 return NT_STATUS_NOT_IMPLEMENTED
;
2750 /*********************************************************************
2751 _samr_get_dom_pwinfo
2752 *********************************************************************/
2754 NTSTATUS
_samr_get_dom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_DOM_PWINFO
*q_u
, SAMR_R_GET_DOM_PWINFO
*r_u
)
2756 /* Actually, returning zeros here works quite well :-). */
2757 return NT_STATUS_OK
;
2760 /*********************************************************************
2762 *********************************************************************/
2764 NTSTATUS
_samr_open_group(pipes_struct
*p
, SAMR_Q_OPEN_GROUP
*q_u
, SAMR_R_OPEN_GROUP
*r_u
)
2766 DEBUG(0,("_samr_open_group: Not yet implemented.\n"));
2767 return NT_STATUS_NOT_IMPLEMENTED
;
2770 /*********************************************************************
2772 *********************************************************************/
2774 NTSTATUS
_samr_unknown_2d(pipes_struct
*p
, SAMR_Q_UNKNOWN_2D
*q_u
, SAMR_R_UNKNOWN_2D
*r_u
)
2776 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
2777 return NT_STATUS_NOT_IMPLEMENTED
;