2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Anthony Liguori 2002,
11 * Copyright (C) Jim McDonough 2002.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern fstring global_myworkgroup
;
38 extern pstring global_myname
;
39 extern DOM_SID global_sid_Builtin
;
41 extern rid_name domain_group_rids
[];
42 extern rid_name domain_alias_rids
[];
43 extern rid_name builtin_alias_rids
[];
46 typedef struct _disp_info
{
48 uint32 num_user_account
;
49 DISP_USER_INFO
*disp_user_info
;
51 uint32 num_group_account
;
52 DISP_GROUP_INFO
*disp_group_info
;
56 /* for use by the \PIPE\samr policy */
58 uint32 status
; /* some sort of flag. best to record it. comes from opnum 0x39 */
67 struct generic_mapping sam_generic_mapping
= {SAMR_READ
, SAMR_WRITE
, SAMR_EXECUTE
, SAMR_ALL_ACCESS
};
68 struct generic_mapping dom_generic_mapping
= {DOMAIN_READ
, DOMAIN_WRITE
, DOMAIN_EXECUTE
, DOMAIN_ALL_ACCESS
};
69 struct generic_mapping usr_generic_mapping
= {USER_READ
, USER_WRITE
, USER_EXECUTE
, USER_ALL_ACCESS
};
70 struct generic_mapping grp_generic_mapping
= {GROUP_READ
, GROUP_WRITE
, GROUP_EXECUTE
, GROUP_ALL_ACCESS
};
71 struct generic_mapping ali_generic_mapping
= {ALIAS_READ
, ALIAS_WRITE
, ALIAS_EXECUTE
, ALIAS_ALL_ACCESS
};
73 static NTSTATUS
samr_make_dom_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
);
75 /*******************************************************************
76 Checks if access to an object should be granted, and returns that
77 level of access for further checks.
78 ********************************************************************/
80 NTSTATUS
access_check_samr_object(SEC_DESC
*psd
, NT_USER_TOKEN
*nt_user_token
, uint32 des_access
,
81 uint32
*acc_granted
, const char *debug
)
83 NTSTATUS status
= NT_STATUS_ACCESS_DENIED
;
85 if (!se_access_check(psd
, nt_user_token
, des_access
, acc_granted
, &status
)) {
86 if (geteuid() == sec_initial_uid()) {
87 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
89 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
90 status
= NT_STATUS_OK
;
93 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
100 /*******************************************************************
101 Checks if access to a function can be granted
102 ********************************************************************/
104 NTSTATUS
access_check_samr_function(uint32 acc_granted
, uint32 acc_required
, const char *debug
)
106 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
107 debug
, acc_granted
, acc_required
));
108 if ((acc_granted
& acc_required
) != acc_required
) {
109 if (geteuid() == sec_initial_uid()) {
110 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
111 debug
, acc_granted
, acc_required
));
112 DEBUGADD(4,("but overwritten by euid == 0\n"));
115 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
116 debug
, acc_granted
, acc_required
));
117 return NT_STATUS_ACCESS_DENIED
;
123 /*******************************************************************
124 Create a samr_info struct.
125 ********************************************************************/
127 static struct samr_info
*get_samr_info_by_sid(DOM_SID
*psid
)
129 struct samr_info
*info
;
134 sid_to_string(sid_str
, psid
);
136 fstrcpy(sid_str
,"(NULL)");
139 mem_ctx
= talloc_init_named("samr_info for domain sid %s", sid_str
);
141 if ((info
= (struct samr_info
*)talloc(mem_ctx
, sizeof(struct samr_info
))) == NULL
)
145 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str
));
147 sid_copy( &info
->sid
, psid
);
149 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
151 info
->mem_ctx
= mem_ctx
;
156 /*******************************************************************
157 Function to free the per handle data.
158 ********************************************************************/
159 static void free_samr_users(struct samr_info
*info
)
163 if (info
->disp_info
.user_dbloaded
){
164 for (i
=0; i
<info
->disp_info
.num_user_account
; i
++) {
165 /* Not really a free, actually a 'clear' */
166 pdb_free_sam(&info
->disp_info
.disp_user_info
[i
].sam
);
169 info
->disp_info
.user_dbloaded
=False
;
170 info
->disp_info
.num_user_account
=0;
174 /*******************************************************************
175 Function to free the per handle data.
176 ********************************************************************/
177 static void free_samr_db(struct samr_info
*info
)
179 /* Groups are talloced */
181 free_samr_users(info
);
183 info
->disp_info
.group_dbloaded
=False
;
184 info
->disp_info
.num_group_account
=0;
188 static void free_samr_info(void *ptr
)
190 struct samr_info
*info
=(struct samr_info
*) ptr
;
193 talloc_destroy(info
->mem_ctx
);
196 /*******************************************************************
197 Ensure password info is never given out. Paranioa... JRA.
198 ********************************************************************/
200 static void samr_clear_sam_passwd(SAM_ACCOUNT
*sam_pass
)
206 /* These now zero out the old password */
208 pdb_set_lanman_passwd(sam_pass
, NULL
);
209 pdb_set_nt_passwd(sam_pass
, NULL
);
213 static NTSTATUS
load_sampwd_entries(struct samr_info
*info
, uint16 acb_mask
, BOOL all_machines
)
215 SAM_ACCOUNT
*pwd
= NULL
;
216 DISP_USER_INFO
*pwd_array
= NULL
;
217 NTSTATUS nt_status
= NT_STATUS_OK
;
218 TALLOC_CTX
*mem_ctx
= info
->mem_ctx
;
220 DEBUG(10,("load_sampwd_entries\n"));
222 /* if the snapshoot is already loaded, return */
223 if ((info
->disp_info
.user_dbloaded
==True
)
224 && (info
->acb_mask
== acb_mask
)
225 && (info
->all_machines
== all_machines
)) {
226 DEBUG(10,("load_sampwd_entries: already in memory\n"));
230 free_samr_users(info
);
232 if (!pdb_setsampwent(False
)) {
233 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
234 return NT_STATUS_ACCESS_DENIED
;
237 for (; (NT_STATUS_IS_OK(nt_status
= pdb_init_sam_talloc(mem_ctx
, &pwd
)))
238 && pdb_getsampwent(pwd
) == True
; pwd
=NULL
) {
241 if (!((pdb_get_acct_ctrl(pwd
) & ACB_WSTRUST
)
242 || (pdb_get_acct_ctrl(pwd
) & ACB_SVRTRUST
))) {
243 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd
), acb_mask
));
248 if (acb_mask
!= 0 && !(pdb_get_acct_ctrl(pwd
) & acb_mask
)) {
250 DEBUG(5,(" acb_mask %x reject\n", acb_mask
));
255 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
256 if (info
->disp_info
.num_user_account
% MAX_SAM_ENTRIES
== 0) {
258 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
259 pwd_array
=(DISP_USER_INFO
*)talloc_realloc(mem_ctx
, info
->disp_info
.disp_user_info
,
260 (info
->disp_info
.num_user_account
+MAX_SAM_ENTRIES
)*sizeof(DISP_USER_INFO
));
263 return NT_STATUS_NO_MEMORY
;
265 info
->disp_info
.disp_user_info
=pwd_array
;
268 /* link the SAM_ACCOUNT to the array */
269 info
->disp_info
.disp_user_info
[info
->disp_info
.num_user_account
].sam
=pwd
;
271 DEBUG(10,("load_sampwd_entries: entry: %d\n", info
->disp_info
.num_user_account
));
273 info
->disp_info
.num_user_account
++;
278 /* the snapshoot is in memory, we're ready to enumerate fast */
280 info
->acb_mask
= acb_mask
;
281 info
->all_machines
= all_machines
;
282 info
->disp_info
.user_dbloaded
=True
;
284 DEBUG(12,("load_sampwd_entries: done\n"));
289 static NTSTATUS
load_group_domain_entries(struct samr_info
*info
, DOM_SID
*sid
)
292 DISP_GROUP_INFO
*grp_array
= NULL
;
293 uint32 group_entries
= 0;
295 TALLOC_CTX
*mem_ctx
= info
->mem_ctx
;
297 DEBUG(10,("load_group_domain_entries\n"));
299 /* if the snapshoot is already loaded, return */
300 if (info
->disp_info
.group_dbloaded
==True
) {
301 DEBUG(10,("load_group_domain_entries: already in memory\n"));
305 if (!enum_group_mapping(SID_NAME_DOM_GRP
, &map
, (int *)&group_entries
, ENUM_ONLY_MAPPED
, MAPPING_WITHOUT_PRIV
)) {
306 return NT_STATUS_NO_MEMORY
;
309 info
->disp_info
.num_group_account
=group_entries
;
311 grp_array
=(DISP_GROUP_INFO
*)talloc(mem_ctx
, info
->disp_info
.num_group_account
*sizeof(DISP_GROUP_INFO
));
313 if (group_entries
!=0 && grp_array
==NULL
) {
315 return NT_STATUS_NO_MEMORY
;
318 info
->disp_info
.disp_group_info
=grp_array
;
320 for (i
=0; i
<group_entries
; i
++) {
322 grp_array
[i
].grp
=(DOMAIN_GRP
*)talloc(mem_ctx
, sizeof(DOMAIN_GRP
));
324 fstrcpy(grp_array
[i
].grp
->name
, map
[i
].nt_name
);
325 fstrcpy(grp_array
[i
].grp
->comment
, map
[i
].comment
);
326 sid_split_rid(&map
[i
].sid
, &grp_array
[i
].grp
->rid
);
327 grp_array
[i
].grp
->attr
=SID_NAME_DOM_GRP
;
332 /* the snapshoot is in memory, we're ready to enumerate fast */
334 info
->disp_info
.group_dbloaded
=True
;
336 DEBUG(12,("load_group_domain_entries: done\n"));
342 /*******************************************************************
344 ********************************************************************/
346 NTSTATUS
_samr_close_hnd(pipes_struct
*p
, SAMR_Q_CLOSE_HND
*q_u
, SAMR_R_CLOSE_HND
*r_u
)
348 r_u
->status
= NT_STATUS_OK
;
350 /* close the policy handle */
351 if (!close_policy_hnd(p
, &q_u
->pol
))
352 return NT_STATUS_OBJECT_NAME_INVALID
;
354 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__
));
359 /*******************************************************************
360 samr_reply_open_domain
361 ********************************************************************/
363 NTSTATUS
_samr_open_domain(pipes_struct
*p
, SAMR_Q_OPEN_DOMAIN
*q_u
, SAMR_R_OPEN_DOMAIN
*r_u
)
365 struct samr_info
*info
;
366 SEC_DESC
*psd
= NULL
;
368 uint32 des_access
= q_u
->flags
;
372 r_u
->status
= NT_STATUS_OK
;
374 /* find the connection policy handle. */
375 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void**)&info
))
376 return NT_STATUS_INVALID_HANDLE
;
378 if (!NT_STATUS_IS_OK(status
= access_check_samr_function(info
->acc_granted
, SAMR_ACCESS_OPEN_DOMAIN
,"_samr_open_domain"))) {
382 /*check if access can be granted as requested by client. */
383 samr_make_dom_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
384 se_map_generic(&des_access
,&dom_generic_mapping
);
386 if (!NT_STATUS_IS_OK(status
=
387 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
388 des_access
, &acc_granted
, "_samr_open_domain"))) {
392 /* associate the domain SID with the (unique) handle. */
393 if ((info
= get_samr_info_by_sid(&q_u
->dom_sid
.sid
))==NULL
)
394 return NT_STATUS_NO_MEMORY
;
395 info
->acc_granted
= acc_granted
;
397 /* get a (unique) handle. open a policy on it. */
398 if (!create_policy_hnd(p
, &r_u
->domain_pol
, free_samr_info
, (void *)info
))
399 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
401 DEBUG(5,("samr_open_domain: %d\n", __LINE__
));
406 /*******************************************************************
407 _samr_get_usrdom_pwinfo
408 ********************************************************************/
410 NTSTATUS
_samr_get_usrdom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_USRDOM_PWINFO
*q_u
, SAMR_R_GET_USRDOM_PWINFO
*r_u
)
412 struct samr_info
*info
= NULL
;
414 r_u
->status
= NT_STATUS_OK
;
416 /* find the policy handle. open a policy on it. */
417 if (!find_policy_by_hnd(p
, &q_u
->user_pol
, (void **)&info
))
418 return NT_STATUS_INVALID_HANDLE
;
420 if (!sid_check_is_in_our_domain(&info
->sid
))
421 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
423 init_samr_r_get_usrdom_pwinfo(r_u
, NT_STATUS_OK
);
425 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__
));
428 * NT sometimes return NT_STATUS_ACCESS_DENIED
429 * I don't know yet why.
435 /*******************************************************************
437 ********************************************************************/
439 static NTSTATUS
samr_make_dom_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
)
441 extern DOM_SID global_sid_World
;
450 sid_copy(&adm_sid
, &global_sid_Builtin
);
451 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
453 sid_copy(&act_sid
, &global_sid_Builtin
);
454 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
456 /*basic access for every one*/
457 init_sec_access(&mask
, DOMAIN_EXECUTE
| DOMAIN_READ
);
458 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
460 /*full access for builtin aliases Administrators and Account Operators*/
461 init_sec_access(&mask
, DOMAIN_ALL_ACCESS
);
462 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
463 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
465 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
466 return NT_STATUS_NO_MEMORY
;
468 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
469 return NT_STATUS_NO_MEMORY
;
474 /*******************************************************************
476 ********************************************************************/
478 static NTSTATUS
samr_make_usr_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
, DOM_SID
*usr_sid
)
480 extern DOM_SID global_sid_World
;
489 sid_copy(&adm_sid
, &global_sid_Builtin
);
490 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
492 sid_copy(&act_sid
, &global_sid_Builtin
);
493 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
495 /*basic access for every one*/
496 init_sec_access(&mask
, USER_EXECUTE
| USER_READ
);
497 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
499 /*full access for builtin aliases Administrators and Account Operators*/
500 init_sec_access(&mask
, USER_ALL_ACCESS
);
501 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
502 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
504 /*extended access for the user*/
505 init_sec_access(&mask
,READ_CONTROL_ACCESS
| USER_ACCESS_CHANGE_PASSWORD
| USER_ACCESS_SET_LOC_COM
);
506 init_sec_ace(&ace
[3], usr_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
508 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 4, ace
)) == NULL
)
509 return NT_STATUS_NO_MEMORY
;
511 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
512 return NT_STATUS_NO_MEMORY
;
517 /*******************************************************************
519 ********************************************************************/
521 static NTSTATUS
samr_make_grp_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
)
523 extern DOM_SID global_sid_World
;
532 sid_copy(&adm_sid
, &global_sid_Builtin
);
533 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
535 sid_copy(&act_sid
, &global_sid_Builtin
);
536 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
538 /*basic access for every one*/
539 init_sec_access(&mask
, GROUP_EXECUTE
| GROUP_READ
);
540 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
542 /*full access for builtin aliases Administrators and Account Operators*/
543 init_sec_access(&mask
, GROUP_ALL_ACCESS
);
544 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
545 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
547 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
548 return NT_STATUS_NO_MEMORY
;
550 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
551 return NT_STATUS_NO_MEMORY
;
556 /*******************************************************************
558 ********************************************************************/
560 static NTSTATUS
samr_make_ali_obj_sd(TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
)
562 extern DOM_SID global_sid_World
;
571 sid_copy(&adm_sid
, &global_sid_Builtin
);
572 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
574 sid_copy(&act_sid
, &global_sid_Builtin
);
575 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
577 /*basic access for every one*/
578 init_sec_access(&mask
, ALIAS_EXECUTE
| ALIAS_READ
);
579 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
581 /*full access for builtin aliases Administrators and Account Operators*/
582 init_sec_access(&mask
, ALIAS_ALL_ACCESS
);
583 init_sec_ace(&ace
[1], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
584 init_sec_ace(&ace
[2], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
586 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) == NULL
)
587 return NT_STATUS_NO_MEMORY
;
589 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
590 return NT_STATUS_NO_MEMORY
;
595 static BOOL
get_lsa_policy_samr_sid(pipes_struct
*p
, POLICY_HND
*pol
, DOM_SID
*sid
, uint32
*acc_granted
)
597 struct samr_info
*info
= NULL
;
599 /* find the policy handle. open a policy on it. */
600 if (!find_policy_by_hnd(p
, pol
, (void **)&info
))
607 *acc_granted
= info
->acc_granted
;
611 /*******************************************************************
613 ********************************************************************/
615 NTSTATUS
_samr_set_sec_obj(pipes_struct
*p
, SAMR_Q_SET_SEC_OBJ
*q_u
, SAMR_R_SET_SEC_OBJ
*r_u
)
617 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
618 return NT_STATUS_NOT_IMPLEMENTED
;
622 /*******************************************************************
624 ********************************************************************/
626 NTSTATUS
_samr_query_sec_obj(pipes_struct
*p
, SAMR_Q_QUERY_SEC_OBJ
*q_u
, SAMR_R_QUERY_SEC_OBJ
*r_u
)
630 SEC_DESC
* psd
= NULL
;
634 r_u
->status
= NT_STATUS_OK
;
637 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &pol_sid
, &acc_granted
))
638 return NT_STATUS_INVALID_HANDLE
;
642 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
644 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
646 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
647 if (pol_sid
.sid_rev_num
== 0)
649 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
650 r_u
->status
= samr_make_sam_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
652 else if (sid_equal(&pol_sid
,get_global_sam_sid())) /* check if it is our domain SID */
655 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
656 r_u
->status
= samr_make_dom_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
658 else if (sid_equal(&pol_sid
,&global_sid_Builtin
)) /* check if it is the Builtin Domain */
660 /* TODO: Builtin probably needs a different SD with restricted write access*/
661 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
662 r_u
->status
= samr_make_dom_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
664 else if (sid_check_is_in_our_domain(&pol_sid
) ||
665 sid_check_is_in_builtin(&pol_sid
))
667 /* TODO: different SDs have to be generated for aliases groups and users.
668 Currently all three get a default user SD */
669 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
670 r_u
->status
= samr_make_usr_obj_sd(p
->mem_ctx
, &psd
,&sd_size
, &pol_sid
);
672 else return NT_STATUS_OBJECT_TYPE_MISMATCH
;
674 if ((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
675 return NT_STATUS_NO_MEMORY
;
677 if (NT_STATUS_IS_OK(r_u
->status
))
683 /*******************************************************************
684 makes a SAM_ENTRY / UNISTR2* structure from a user list.
685 ********************************************************************/
687 static NTSTATUS
make_user_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
688 uint32 num_entries
, uint32 start_idx
, DISP_USER_INFO
*disp_user_info
,
694 SAM_ACCOUNT
*pwd
= NULL
;
695 UNISTR2 uni_temp_name
;
696 const char *temp_name
;
697 const DOM_SID
*user_sid
;
699 fstring user_sid_string
;
700 fstring domain_sid_string
;
705 if (num_entries
== 0)
708 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_entries
);
710 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_entries
);
712 if (sam
== NULL
|| uni_name
== NULL
) {
713 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
714 return NT_STATUS_NO_MEMORY
;
717 for (i
= 0; i
< num_entries
; i
++) {
718 pwd
= disp_user_info
[i
+start_idx
].sam
;
719 temp_name
= pdb_get_username(pwd
);
720 init_unistr2(&uni_temp_name
, temp_name
, strlen(temp_name
)+1);
721 user_sid
= pdb_get_user_sid(pwd
);
723 if (!sid_peek_check_rid(domain_sid
, user_sid
, &user_rid
)) {
724 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
725 "the domain sid %s. Failing operation.\n",
727 sid_to_string(user_sid_string
, user_sid
),
728 sid_to_string(domain_sid_string
, domain_sid
)));
729 return NT_STATUS_UNSUCCESSFUL
;
732 init_sam_entry(&sam
[i
], uni_temp_name
.uni_str_len
, user_rid
);
733 copy_unistr2(&uni_name
[i
], &uni_temp_name
);
737 *uni_name_pp
= uni_name
;
741 /*******************************************************************
742 samr_reply_enum_dom_users
743 ********************************************************************/
745 NTSTATUS
_samr_enum_dom_users(pipes_struct
*p
, SAMR_Q_ENUM_DOM_USERS
*q_u
,
746 SAMR_R_ENUM_DOM_USERS
*r_u
)
748 struct samr_info
*info
= NULL
;
749 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
751 uint32 enum_context
=q_u
->start_idx
;
752 uint32 max_size
=q_u
->max_size
;
754 enum remote_arch_types ra_type
= get_remote_arch();
755 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
756 uint32 max_entries
= max_sam_entries
;
759 r_u
->status
= NT_STATUS_OK
;
761 /* find the policy handle. open a policy on it. */
762 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
763 return NT_STATUS_INVALID_HANDLE
;
765 domain_sid
= info
->sid
;
767 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
,
768 DOMAIN_ACCESS_ENUM_ACCOUNTS
,
769 "_samr_enum_dom_users"))) {
773 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
776 r_u
->status
=load_sampwd_entries(info
, q_u
->acb_mask
, False
);
779 if (!NT_STATUS_IS_OK(r_u
->status
))
782 num_account
= info
->disp_info
.num_user_account
;
784 if (enum_context
> num_account
) {
785 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
789 /* verify we won't overflow */
790 if (max_entries
> num_account
-enum_context
) {
791 max_entries
= num_account
-enum_context
;
792 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries
));
795 /* calculate the size and limit on the number of entries we will return */
796 temp_size
=max_entries
*struct_size
;
798 if (temp_size
>max_size
) {
799 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
800 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries
));
804 * Note from JRA. total_entries is not being used here. Currently if there is a
805 * large user base then it looks like NT will enumerate until get_sampwd_entries
806 * returns False due to num_entries being zero. This will cause an access denied
807 * return. I don't think this is right and needs further investigation. Note that
808 * this is also the same in the TNG code (I don't think that has been tested with
809 * a very large user list as MAX_SAM_ENTRIES is set to 600).
811 * I also think that one of the 'num_entries' return parameters is probably
812 * the "max entries" parameter - but in the TNG code they're all currently set to the same
813 * value (again I think this is wrong).
816 r_u
->status
= make_user_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_acct_name
,
817 max_entries
, enum_context
,
818 info
->disp_info
.disp_user_info
,
821 if (!NT_STATUS_IS_OK(r_u
->status
))
824 if (enum_context
+max_entries
< num_account
)
825 r_u
->status
= STATUS_MORE_ENTRIES
;
827 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__
));
829 init_samr_r_enum_dom_users(r_u
, q_u
->start_idx
+ max_entries
, max_entries
);
831 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
836 /*******************************************************************
837 makes a SAM_ENTRY / UNISTR2* structure from a group list.
838 ********************************************************************/
840 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
841 uint32 num_sam_entries
, DOMAIN_GRP
*grp
)
850 if (num_sam_entries
== 0)
853 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
855 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
857 if (sam
== NULL
|| uni_name
== NULL
) {
858 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
862 for (i
= 0; i
< num_sam_entries
; i
++) {
864 * JRA. I think this should include the null. TNG does not.
866 int len
= strlen(grp
[i
].name
)+1;
868 init_sam_entry(&sam
[i
], len
, grp
[i
].rid
);
869 init_unistr2(&uni_name
[i
], grp
[i
].name
, len
);
873 *uni_name_pp
= uni_name
;
876 /*******************************************************************
877 Get the group entries - similar to get_sampwd_entries().
878 ********************************************************************/
880 static NTSTATUS
get_group_alias_entries(TALLOC_CTX
*ctx
, DOMAIN_GRP
**d_grp
, DOM_SID
*sid
, uint32 start_idx
,
881 uint32
*p_num_entries
, uint32 max_entries
)
884 uint32 num_entries
= 0;
889 sid_to_string(sid_str
, sid
);
890 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str
));
894 /* well-known aliases */
895 if (sid_equal(sid
, &global_sid_Builtin
) && !lp_hide_local_users()) {
897 enum_group_mapping(SID_NAME_ALIAS
, &map
, (int *)&num_entries
, ENUM_ONLY_MAPPED
, MAPPING_WITHOUT_PRIV
);
899 if (num_entries
!= 0) {
900 *d_grp
=(DOMAIN_GRP
*)talloc_zero(ctx
, num_entries
*sizeof(DOMAIN_GRP
));
902 return NT_STATUS_NO_MEMORY
;
904 for(i
=0; i
<num_entries
&& i
<max_entries
; i
++) {
905 fstrcpy((*d_grp
)[i
].name
, map
[i
+start_idx
].nt_name
);
906 sid_split_rid(&map
[i
+start_idx
].sid
, &(*d_grp
)[i
].rid
);
912 } else if (sid_equal(sid
, get_global_sam_sid()) && !lp_hide_local_users()) {
913 struct sys_grent
*glist
;
914 struct sys_grent
*grp
;
916 gid_t winbind_gid_low
, winbind_gid_high
;
917 BOOL winbind_groups_exist
= lp_winbind_gid(&winbind_gid_low
, &winbind_gid_high
);
920 /* we return the UNIX groups here. This seems to be the right */
921 /* thing to do, since NT member servers return their local */
922 /* groups in the same situation. */
924 /* use getgrent_list() to retrieve the list of groups to avoid
925 * problems with getgrent possible infinite loop by internal
926 * libc grent structures overwrites by called functions */
927 grp
= glist
= getgrent_list();
929 return NT_STATUS_NO_MEMORY
;
931 for (; (num_entries
< max_entries
) && (grp
!= NULL
); grp
= grp
->next
) {
934 if(!get_group_from_gid(grp
->gr_gid
, &smap
, MAPPING_WITHOUT_PRIV
))
937 if (smap
.sid_name_use
!=SID_NAME_ALIAS
) {
941 sid_split_rid(&smap
.sid
, &trid
);
943 if (!sid_equal(sid
, &smap
.sid
))
946 /* Don't return winbind groups as they are not local! */
947 if (winbind_groups_exist
&& (grp
->gr_gid
>= winbind_gid_low
)&&(grp
->gr_gid
<= winbind_gid_high
)) {
948 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap
.nt_name
));
952 /* Don't return user private groups... */
954 if ((pw
= Get_Pwnam(smap
.nt_name
)) != 0) {
955 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap
.nt_name
));
959 for( i
= 0; i
< num_entries
; i
++)
960 if ( (*d_grp
)[i
].rid
== trid
)
963 if ( i
< num_entries
) {
964 continue; /* rid was there, dup! */
967 /* JRA - added this for large group db enumeration... */
970 /* skip the requested number of entries.
971 not very efficient, but hey...
977 *d_grp
=talloc_realloc(ctx
,*d_grp
, (num_entries
+1)*sizeof(DOMAIN_GRP
));
980 return NT_STATUS_NO_MEMORY
;
983 fstrcpy((*d_grp
)[num_entries
].name
, smap
.nt_name
);
984 (*d_grp
)[num_entries
].rid
= trid
;
986 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries
, trid
));
992 *p_num_entries
= num_entries
;
994 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries
));
996 if (num_entries
>= max_entries
)
997 return STATUS_MORE_ENTRIES
;
1001 /*******************************************************************
1002 Get the group entries - similar to get_sampwd_entries().
1003 ********************************************************************/
1005 static NTSTATUS
get_group_domain_entries(TALLOC_CTX
*ctx
, DOMAIN_GRP
**d_grp
, DOM_SID
*sid
, uint32 start_idx
,
1006 uint32
*p_num_entries
, uint32 max_entries
)
1008 GROUP_MAP
*map
=NULL
;
1010 uint32 group_entries
= 0;
1011 uint32 num_entries
= 0;
1015 enum_group_mapping(SID_NAME_DOM_GRP
, &map
, (int *)&group_entries
, ENUM_ONLY_MAPPED
, MAPPING_WITHOUT_PRIV
);
1017 num_entries
=group_entries
-start_idx
;
1019 /* limit the number of entries */
1020 if (num_entries
>max_entries
) {
1021 DEBUG(5,("Limiting to %d entries\n", max_entries
));
1022 num_entries
=max_entries
;
1025 *d_grp
=(DOMAIN_GRP
*)talloc_zero(ctx
, num_entries
*sizeof(DOMAIN_GRP
));
1026 if (num_entries
!=0 && *d_grp
==NULL
){
1028 return NT_STATUS_NO_MEMORY
;
1031 for (i
=0; i
<num_entries
; i
++) {
1032 fstrcpy((*d_grp
)[i
].name
, map
[i
+start_idx
].nt_name
);
1033 fstrcpy((*d_grp
)[i
].comment
, map
[i
+start_idx
].comment
);
1034 sid_split_rid(&map
[i
+start_idx
].sid
, &(*d_grp
)[i
].rid
);
1035 (*d_grp
)[i
].attr
=SID_NAME_DOM_GRP
;
1040 *p_num_entries
= num_entries
;
1042 return NT_STATUS_OK
;
1045 /*******************************************************************
1046 samr_reply_enum_dom_groups
1047 ********************************************************************/
1049 NTSTATUS
_samr_enum_dom_groups(pipes_struct
*p
, SAMR_Q_ENUM_DOM_GROUPS
*q_u
, SAMR_R_ENUM_DOM_GROUPS
*r_u
)
1051 DOMAIN_GRP
*grp
=NULL
;
1056 r_u
->status
= NT_STATUS_OK
;
1058 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
1059 return NT_STATUS_INVALID_HANDLE
;
1061 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, DOMAIN_ACCESS_ENUM_ACCOUNTS
, "_samr_enum_dom_groups"))) {
1065 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__
));
1067 /* the domain group array is being allocated in the function below */
1068 if (!NT_STATUS_IS_OK(r_u
->status
= get_group_domain_entries(p
->mem_ctx
, &grp
, &sid
, q_u
->start_idx
, &num_entries
, MAX_SAM_ENTRIES
))) {
1072 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
1074 init_samr_r_enum_dom_groups(r_u
, q_u
->start_idx
, num_entries
);
1076 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__
));
1082 /*******************************************************************
1083 samr_reply_enum_dom_aliases
1084 ********************************************************************/
1086 NTSTATUS
_samr_enum_dom_aliases(pipes_struct
*p
, SAMR_Q_ENUM_DOM_ALIASES
*q_u
, SAMR_R_ENUM_DOM_ALIASES
*r_u
)
1088 DOMAIN_GRP
*grp
=NULL
;
1089 uint32 num_entries
= 0;
1095 r_u
->status
= NT_STATUS_OK
;
1097 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
1098 return NT_STATUS_INVALID_HANDLE
;
1100 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, DOMAIN_ACCESS_ENUM_ACCOUNTS
, "_samr_enum_dom_aliases"))) {
1104 sid_to_string(sid_str
, &sid
);
1105 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str
));
1107 status
= get_group_alias_entries(p
->mem_ctx
, &grp
, &sid
, q_u
->start_idx
,
1108 &num_entries
, MAX_SAM_ENTRIES
);
1109 if (NT_STATUS_IS_ERR(status
)) return status
;
1111 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
1115 init_samr_r_enum_dom_aliases(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
1117 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__
));
1122 /*******************************************************************
1123 samr_reply_query_dispinfo
1124 ********************************************************************/
1125 NTSTATUS
_samr_query_dispinfo(pipes_struct
*p
, SAMR_Q_QUERY_DISPINFO
*q_u
,
1126 SAMR_R_QUERY_DISPINFO
*r_u
)
1128 struct samr_info
*info
= NULL
;
1129 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
1131 uint32 max_entries
=q_u
->max_entries
;
1132 uint32 enum_context
=q_u
->start_idx
;
1133 uint32 max_size
=q_u
->max_size
;
1135 SAM_DISPINFO_CTR
*ctr
;
1136 uint32 temp_size
=0, total_data_size
=0;
1138 uint32 num_account
= 0;
1139 enum remote_arch_types ra_type
= get_remote_arch();
1140 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
1143 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__
));
1144 r_u
->status
= NT_STATUS_OK
;
1146 /* find the policy handle. open a policy on it. */
1147 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
1148 return NT_STATUS_INVALID_HANDLE
;
1150 domain_sid
= info
->sid
;
1153 * calculate how many entries we will return.
1155 * - the number of entries the client asked
1156 * - our limit on that
1157 * - the starting point (enumeration context)
1158 * - the buffer size the client will accept
1162 * We are a lot more like W2K. Instead of reading the SAM
1163 * each time to find the records we need to send back,
1164 * we read it once and link that copy to the sam handle.
1165 * For large user list (over the MAX_SAM_ENTRIES)
1166 * it's a definitive win.
1167 * second point to notice: between enumerations
1168 * our sam is now the same as it's a snapshoot.
1169 * third point: got rid of the static SAM_USER_21 struct
1170 * no more intermediate.
1171 * con: it uses much more memory, as a full copy is stored
1174 * If you want to change it, think twice and think
1175 * of the second point , that's really important.
1180 /* Get what we need from the password database */
1181 switch (q_u
->switch_level
) {
1186 /* Level 2 is for all machines, otherwise only 'normal' users */
1187 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
, q_u
->switch_level
==2);
1189 if (!NT_STATUS_IS_OK(r_u
->status
)) {
1190 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1193 num_account
= info
->disp_info
.num_user_account
;
1197 r_u
->status
= load_group_domain_entries(info
, &info
->sid
);
1198 if (!NT_STATUS_IS_OK(r_u
->status
))
1200 num_account
= info
->disp_info
.num_group_account
;
1203 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u
->switch_level
));
1204 return NT_STATUS_INVALID_INFO_CLASS
;
1207 /* first limit the number of entries we will return */
1208 if(max_entries
> max_sam_entries
) {
1209 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries
, max_sam_entries
));
1210 max_entries
= max_sam_entries
;
1213 if (enum_context
> num_account
) {
1214 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1215 return NT_STATUS_NO_MORE_ENTRIES
;
1218 /* verify we won't overflow */
1219 if (max_entries
> num_account
-enum_context
) {
1220 max_entries
= num_account
-enum_context
;
1221 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries
));
1224 /* calculate the size and limit on the number of entries we will return */
1225 temp_size
=max_entries
*struct_size
;
1227 if (temp_size
>max_size
) {
1228 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
1229 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries
));
1232 if (!(ctr
= (SAM_DISPINFO_CTR
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_DISPINFO_CTR
))))
1233 return NT_STATUS_NO_MEMORY
;
1237 /* Now create reply structure */
1238 switch (q_u
->switch_level
) {
1241 if (!(ctr
->sam
.info1
= (SAM_DISPINFO_1
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_1
))))
1242 return NT_STATUS_NO_MEMORY
;
1244 disp_ret
= init_sam_dispinfo_1(p
->mem_ctx
, ctr
->sam
.info1
, max_entries
, enum_context
,
1245 info
->disp_info
.disp_user_info
, &domain_sid
);
1246 if (!NT_STATUS_IS_OK(disp_ret
))
1251 if (!(ctr
->sam
.info2
= (SAM_DISPINFO_2
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_2
))))
1252 return NT_STATUS_NO_MEMORY
;
1254 disp_ret
= init_sam_dispinfo_2(p
->mem_ctx
, ctr
->sam
.info2
, max_entries
, enum_context
,
1255 info
->disp_info
.disp_user_info
, &domain_sid
);
1256 if (!NT_STATUS_IS_OK(disp_ret
))
1261 if (!(ctr
->sam
.info3
= (SAM_DISPINFO_3
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_3
))))
1262 return NT_STATUS_NO_MEMORY
;
1264 disp_ret
= init_sam_dispinfo_3(p
->mem_ctx
, ctr
->sam
.info3
, max_entries
, enum_context
, info
->disp_info
.disp_group_info
);
1265 if (!NT_STATUS_IS_OK(disp_ret
))
1270 if (!(ctr
->sam
.info4
= (SAM_DISPINFO_4
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_4
))))
1271 return NT_STATUS_NO_MEMORY
;
1273 disp_ret
= init_sam_dispinfo_4(p
->mem_ctx
, ctr
->sam
.info4
, max_entries
, enum_context
, info
->disp_info
.disp_user_info
);
1274 if (!NT_STATUS_IS_OK(disp_ret
))
1279 if (!(ctr
->sam
.info5
= (SAM_DISPINFO_5
*)talloc_zero(p
->mem_ctx
,max_entries
*sizeof(SAM_DISPINFO_5
))))
1280 return NT_STATUS_NO_MEMORY
;
1282 disp_ret
= init_sam_dispinfo_5(p
->mem_ctx
, ctr
->sam
.info5
, max_entries
, enum_context
, info
->disp_info
.disp_group_info
);
1283 if (!NT_STATUS_IS_OK(disp_ret
))
1288 ctr
->sam
.info
= NULL
;
1289 return NT_STATUS_INVALID_INFO_CLASS
;
1292 /* calculate the total size */
1293 total_data_size
=num_account
*struct_size
;
1295 if (enum_context
+max_entries
< num_account
)
1296 r_u
->status
= STATUS_MORE_ENTRIES
;
1298 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__
));
1300 init_samr_r_query_dispinfo(r_u
, max_entries
, total_data_size
, temp_size
, q_u
->switch_level
, ctr
, r_u
->status
);
1306 /*******************************************************************
1307 samr_reply_query_aliasinfo
1308 ********************************************************************/
1310 NTSTATUS
_samr_query_aliasinfo(pipes_struct
*p
, SAMR_Q_QUERY_ALIASINFO
*q_u
, SAMR_R_QUERY_ALIASINFO
*r_u
)
1316 r_u
->status
= NT_STATUS_OK
;
1318 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1320 /* find the policy handle. open a policy on it. */
1321 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
1322 return NT_STATUS_INVALID_HANDLE
;
1323 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, ALIAS_ACCESS_LOOKUP_INFO
, "_samr_query_aliasinfo"))) {
1327 if (!sid_check_is_in_our_domain(&sid
) &&
1328 !sid_check_is_in_builtin(&sid
))
1329 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1331 if (!get_local_group_from_sid(sid
, &map
, MAPPING_WITHOUT_PRIV
))
1332 return NT_STATUS_NO_SUCH_ALIAS
;
1334 switch (q_u
->switch_level
) {
1337 r_u
->ctr
.switch_value1
= 1;
1338 init_samr_alias_info1(&r_u
->ctr
.alias
.info1
, map
.nt_name
, 1, map
.comment
);
1342 r_u
->ctr
.switch_value1
= 3;
1343 init_samr_alias_info3(&r_u
->ctr
.alias
.info3
, map
.comment
);
1346 return NT_STATUS_INVALID_INFO_CLASS
;
1349 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1355 /*******************************************************************
1356 samr_reply_lookup_ids
1357 ********************************************************************/
1359 uint32
_samr_lookup_ids(pipes_struct
*p
, SAMR_Q_LOOKUP_IDS
*q_u
, SAMR_R_LOOKUP_IDS
*r_u
)
1361 uint32 rid
[MAX_SAM_ENTRIES
];
1362 int num_rids
= q_u
->num_sids1
;
1364 r_u
->status
= NT_STATUS_OK
;
1366 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1368 if (num_rids
> MAX_SAM_ENTRIES
) {
1369 num_rids
= MAX_SAM_ENTRIES
;
1370 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids
));
1375 SMB_ASSERT_ARRAY(q_u
->uni_user_name
, num_rids
);
1377 for (i
= 0; i
< num_rids
&& status
== 0; i
++)
1379 struct sam_passwd
*sam_pass
;
1383 fstrcpy(user_name
, unistrn2(q_u
->uni_user_name
[i
].buffer
,
1384 q_u
->uni_user_name
[i
].uni_str_len
));
1386 /* find the user account */
1388 sam_pass
= get_smb21pwd_entry(user_name
, 0);
1391 if (sam_pass
== NULL
)
1393 status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1398 rid
[i
] = sam_pass
->user_rid
;
1404 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
1406 init_samr_r_lookup_ids(&r_u
, num_rids
, rid
, NT_STATUS_OK
);
1408 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1414 /*******************************************************************
1416 ********************************************************************/
1418 NTSTATUS
_samr_lookup_names(pipes_struct
*p
, SAMR_Q_LOOKUP_NAMES
*q_u
, SAMR_R_LOOKUP_NAMES
*r_u
)
1420 uint32 rid
[MAX_SAM_ENTRIES
];
1422 enum SID_NAME_USE type
[MAX_SAM_ENTRIES
];
1423 enum SID_NAME_USE local_type
;
1425 int num_rids
= q_u
->num_names2
;
1430 r_u
->status
= NT_STATUS_OK
;
1432 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1437 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
, &acc_granted
)) {
1438 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, 0, NULL
, NULL
, NT_STATUS_OBJECT_TYPE_MISMATCH
);
1442 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1446 if (num_rids
> MAX_SAM_ENTRIES
) {
1447 num_rids
= MAX_SAM_ENTRIES
;
1448 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids
));
1451 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str
, &pol_sid
)));
1453 become_root(); /* local_lookup_name can require root privs */
1455 for (i
= 0; i
< num_rids
; i
++) {
1459 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1461 rid
[i
] = 0xffffffff;
1462 type
[i
] = SID_NAME_UNKNOWN
;
1464 rpcstr_pull(name
, q_u
->uni_name
[i
].buffer
, sizeof(name
), q_u
->uni_name
[i
].uni_str_len
*2, 0);
1467 * we are only looking for a name
1468 * the SID we get back can be outside
1469 * the scope of the pol_sid
1471 * in clear: it prevents to reply to domain\group: yes
1472 * when only builtin\group exists.
1474 * a cleaner code is to add the sid of the domain we're looking in
1475 * to the local_lookup_name function.
1477 if(local_lookup_name(name
, &sid
, &local_type
)) {
1478 sid_split_rid(&sid
, &local_rid
);
1480 if (sid_equal(&sid
, &pol_sid
)) {
1483 r_u
->status
= NT_STATUS_OK
;
1490 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, num_rids
, rid
, (uint32
*)type
, r_u
->status
);
1492 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1497 /*******************************************************************
1498 _samr_chgpasswd_user
1499 ********************************************************************/
1501 NTSTATUS
_samr_chgpasswd_user(pipes_struct
*p
, SAMR_Q_CHGPASSWD_USER
*q_u
, SAMR_R_CHGPASSWD_USER
*r_u
)
1506 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1508 r_u
->status
= NT_STATUS_OK
;
1510 rpcstr_pull(user_name
, q_u
->uni_user_name
.buffer
, sizeof(user_name
), q_u
->uni_user_name
.uni_str_len
*2, 0);
1511 rpcstr_pull(wks
, q_u
->uni_dest_host
.buffer
, sizeof(wks
), q_u
->uni_dest_host
.uni_str_len
*2,0);
1513 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name
, wks
));
1516 * Pass the user through the NT -> unix user mapping
1520 (void)map_username(user_name
);
1523 * UNIX username case mangling not required, pass_oem_change
1524 * is case insensitive.
1527 if (!pass_oem_change(user_name
, q_u
->lm_newpass
.pass
, q_u
->lm_oldhash
.hash
,
1528 q_u
->nt_newpass
.pass
, q_u
->nt_oldhash
.hash
))
1529 r_u
->status
= NT_STATUS_WRONG_PASSWORD
;
1531 init_samr_r_chgpasswd_user(r_u
, r_u
->status
);
1533 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1538 /*******************************************************************
1539 makes a SAMR_R_LOOKUP_RIDS structure.
1540 ********************************************************************/
1542 static BOOL
make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
, fstring names
[],
1543 UNIHDR
**pp_hdr_name
, UNISTR2
**pp_uni_name
)
1546 UNIHDR
*hdr_name
=NULL
;
1547 UNISTR2
*uni_name
=NULL
;
1549 *pp_uni_name
= NULL
;
1550 *pp_hdr_name
= NULL
;
1552 if (num_names
!= 0) {
1553 hdr_name
= (UNIHDR
*)talloc_zero(ctx
, sizeof(UNIHDR
)*num_names
);
1554 if (hdr_name
== NULL
)
1557 uni_name
= (UNISTR2
*)talloc_zero(ctx
,sizeof(UNISTR2
)*num_names
);
1558 if (uni_name
== NULL
)
1562 for (i
= 0; i
< num_names
; i
++) {
1563 int len
= names
[i
] != NULL
? strlen(names
[i
]) : 0;
1564 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
]));
1565 init_uni_hdr(&hdr_name
[i
], len
);
1566 init_unistr2(&uni_name
[i
], names
[i
], len
);
1569 *pp_uni_name
= uni_name
;
1570 *pp_hdr_name
= hdr_name
;
1575 /*******************************************************************
1577 ********************************************************************/
1579 NTSTATUS
_samr_lookup_rids(pipes_struct
*p
, SAMR_Q_LOOKUP_RIDS
*q_u
, SAMR_R_LOOKUP_RIDS
*r_u
)
1581 fstring group_names
[MAX_SAM_ENTRIES
];
1582 uint32
*group_attrs
= NULL
;
1583 UNIHDR
*hdr_name
= NULL
;
1584 UNISTR2
*uni_name
= NULL
;
1586 int num_rids
= q_u
->num_rids1
;
1590 r_u
->status
= NT_STATUS_OK
;
1592 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1594 /* find the policy handle. open a policy on it. */
1595 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
, &acc_granted
))
1596 return NT_STATUS_INVALID_HANDLE
;
1598 if (num_rids
> MAX_SAM_ENTRIES
) {
1599 num_rids
= MAX_SAM_ENTRIES
;
1600 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids
));
1604 if ((group_attrs
= (uint32
*)talloc_zero(p
->mem_ctx
, num_rids
* sizeof(uint32
))) == NULL
)
1605 return NT_STATUS_NO_MEMORY
;
1608 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1610 become_root(); /* lookup_sid can require root privs */
1612 for (i
= 0; i
< num_rids
; i
++) {
1616 enum SID_NAME_USE type
;
1618 group_attrs
[i
] = SID_NAME_UNKNOWN
;
1619 *group_names
[i
] = '\0';
1621 if (sid_equal(&pol_sid
, get_global_sam_sid())) {
1622 sid_copy(&sid
, &pol_sid
);
1623 sid_append_rid(&sid
, q_u
->rid
[i
]);
1625 if (lookup_sid(&sid
, domname
, tmpname
, &type
)) {
1626 r_u
->status
= NT_STATUS_OK
;
1627 group_attrs
[i
] = (uint32
)type
;
1628 fstrcpy(group_names
[i
],tmpname
);
1629 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names
[i
], group_attrs
[i
]));
1636 if(!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, group_names
, &hdr_name
, &uni_name
))
1637 return NT_STATUS_NO_MEMORY
;
1639 init_samr_r_lookup_rids(r_u
, num_rids
, hdr_name
, uni_name
, group_attrs
);
1641 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1646 /*******************************************************************
1647 _api_samr_open_user. Safe - gives out no passwd info.
1648 ********************************************************************/
1650 NTSTATUS
_api_samr_open_user(pipes_struct
*p
, SAMR_Q_OPEN_USER
*q_u
, SAMR_R_OPEN_USER
*r_u
)
1652 SAM_ACCOUNT
*sampass
=NULL
;
1654 POLICY_HND domain_pol
= q_u
->domain_pol
;
1655 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1656 struct samr_info
*info
= NULL
;
1657 SEC_DESC
*psd
= NULL
;
1659 uint32 des_access
= q_u
->access_mask
;
1664 r_u
->status
= NT_STATUS_OK
;
1666 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1667 if (!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
, &acc_granted
))
1668 return NT_STATUS_INVALID_HANDLE
;
1670 if (!NT_STATUS_IS_OK(nt_status
= access_check_samr_function(acc_granted
, DOMAIN_ACCESS_OPEN_ACCOUNT
, "_samr_open_user"))) {
1674 nt_status
= pdb_init_sam_talloc(p
->mem_ctx
, &sampass
);
1675 if (!NT_STATUS_IS_OK(nt_status
)) {
1679 /* append the user's RID to it */
1680 if (!sid_append_rid(&sid
, q_u
->user_rid
))
1681 return NT_STATUS_NO_SUCH_USER
;
1683 /* check if access can be granted as requested by client. */
1684 samr_make_usr_obj_sd(p
->mem_ctx
, &psd
, &sd_size
, &sid
);
1685 se_map_generic(&des_access
, &usr_generic_mapping
);
1686 if (!NT_STATUS_IS_OK(nt_status
=
1687 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
1688 des_access
, &acc_granted
, "_samr_open_user"))) {
1693 ret
=pdb_getsampwsid(sampass
, &sid
);
1696 /* check that the SID exists in our domain. */
1698 return NT_STATUS_NO_SUCH_USER
;
1701 pdb_free_sam(&sampass
);
1703 /* associate the user's SID and access bits with the new handle. */
1704 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
)
1705 return NT_STATUS_NO_MEMORY
;
1706 info
->acc_granted
= acc_granted
;
1708 /* get a (unique) handle. open a policy on it. */
1709 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
))
1710 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1715 /*************************************************************************
1716 get_user_info_10. Safe. Only gives out acb bits.
1717 *************************************************************************/
1719 static NTSTATUS
get_user_info_10(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_10
*id10
, DOM_SID
*user_sid
)
1721 SAM_ACCOUNT
*smbpass
=NULL
;
1725 nt_status
= pdb_init_sam_talloc(mem_ctx
, &smbpass
);
1727 if (!NT_STATUS_IS_OK(nt_status
)) {
1732 ret
= pdb_getsampwsid(smbpass
, user_sid
);
1736 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1737 return NT_STATUS_NO_SUCH_USER
;
1740 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass
) ));
1743 init_sam_user_info10(id10
, pdb_get_acct_ctrl(smbpass
) );
1745 pdb_free_sam(&smbpass
);
1747 return NT_STATUS_OK
;
1750 /*************************************************************************
1751 get_user_info_12. OK - this is the killer as it gives out password info.
1752 Ensure that this is only allowed on an encrypted connection with a root
1754 *************************************************************************/
1756 static NTSTATUS
get_user_info_12(pipes_struct
*p
, TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_12
* id12
, DOM_SID
*user_sid
)
1758 SAM_ACCOUNT
*smbpass
=NULL
;
1762 if (!p
->ntlmssp_auth_validated
)
1763 return NT_STATUS_ACCESS_DENIED
;
1765 if (!(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SIGN
) || !(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SEAL
))
1766 return NT_STATUS_ACCESS_DENIED
;
1769 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1772 nt_status
= pdb_init_sam_talloc(mem_ctx
, &smbpass
);
1774 if (!NT_STATUS_IS_OK(nt_status
)) {
1778 ret
= pdb_getsampwsid(smbpass
, user_sid
);
1781 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid
)));
1782 pdb_free_sam(&smbpass
);
1783 return (geteuid() == (uid_t
)0) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
1786 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
1788 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
1789 pdb_free_sam(&smbpass
);
1790 return NT_STATUS_ACCOUNT_DISABLED
;
1794 init_sam_user_info12(id12
, pdb_get_lanman_passwd(smbpass
), pdb_get_nt_passwd(smbpass
));
1796 pdb_free_sam(&smbpass
);
1798 return NT_STATUS_OK
;
1801 /*************************************************************************
1803 *************************************************************************/
1805 static NTSTATUS
get_user_info_20(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_20
*id20
, DOM_SID
*user_sid
)
1807 SAM_ACCOUNT
*sampass
=NULL
;
1810 pdb_init_sam_talloc(mem_ctx
, &sampass
);
1813 ret
= pdb_getsampwsid(sampass
, user_sid
);
1817 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1818 return NT_STATUS_NO_SUCH_USER
;
1821 samr_clear_sam_passwd(sampass
);
1823 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1826 init_sam_user_info20A(id20
, sampass
);
1828 pdb_free_sam(&sampass
);
1830 return NT_STATUS_OK
;
1833 /*************************************************************************
1835 *************************************************************************/
1837 static NTSTATUS
get_user_info_21(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_21
*id21
,
1838 DOM_SID
*user_sid
, DOM_SID
*domain_sid
)
1840 SAM_ACCOUNT
*sampass
=NULL
;
1844 nt_status
= pdb_init_sam_talloc(mem_ctx
, &sampass
);
1845 if (!NT_STATUS_IS_OK(nt_status
)) {
1850 ret
= pdb_getsampwsid(sampass
, user_sid
);
1854 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1855 return NT_STATUS_NO_SUCH_USER
;
1858 samr_clear_sam_passwd(sampass
);
1860 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1863 nt_status
= init_sam_user_info21A(id21
, sampass
, domain_sid
);
1865 pdb_free_sam(&sampass
);
1867 return NT_STATUS_OK
;
1870 /*******************************************************************
1871 _samr_query_userinfo
1872 ********************************************************************/
1874 NTSTATUS
_samr_query_userinfo(pipes_struct
*p
, SAMR_Q_QUERY_USERINFO
*q_u
, SAMR_R_QUERY_USERINFO
*r_u
)
1876 SAM_USERINFO_CTR
*ctr
;
1877 struct samr_info
*info
= NULL
;
1881 r_u
->status
=NT_STATUS_OK
;
1883 /* search for the handle */
1884 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1885 return NT_STATUS_INVALID_HANDLE
;
1887 domain_sid
= info
->sid
;
1889 sid_split_rid(&domain_sid
, &rid
);
1891 if (!sid_check_is_in_our_domain(&info
->sid
))
1892 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1894 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info
->sid
)));
1896 ctr
= (SAM_USERINFO_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USERINFO_CTR
));
1898 return NT_STATUS_NO_MEMORY
;
1902 /* ok! user info levels (lots: see MSDEV help), off we go... */
1903 ctr
->switch_value
= q_u
->switch_value
;
1905 switch (q_u
->switch_value
) {
1907 ctr
->info
.id10
= (SAM_USER_INFO_10
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USER_INFO_10
));
1908 if (ctr
->info
.id10
== NULL
)
1909 return NT_STATUS_NO_MEMORY
;
1911 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_10(p
->mem_ctx
, ctr
->info
.id10
, &info
->sid
)))
1916 /* whoops - got this wrong. i think. or don't understand what's happening. */
1920 info
= (void *)&id11
;
1922 expire
.low
= 0xffffffff;
1923 expire
.high
= 0x7fffffff;
1925 ctr
->info
.id
= (SAM_USER_INFO_11
*)talloc_zero(p
->mem_ctx
,
1930 ZERO_STRUCTP(ctr
->info
.id11
);
1931 init_sam_user_info11(ctr
->info
.id11
, &expire
,
1932 "BROOKFIELDS$", /* name */
1933 0x03ef, /* user rid */
1934 0x201, /* group rid */
1935 0x0080); /* acb info */
1942 ctr
->info
.id12
= (SAM_USER_INFO_12
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_USER_INFO_12
));
1943 if (ctr
->info
.id12
== NULL
)
1944 return NT_STATUS_NO_MEMORY
;
1946 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_12(p
, p
->mem_ctx
, ctr
->info
.id12
, &info
->sid
)))
1951 ctr
->info
.id20
= (SAM_USER_INFO_20
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_USER_INFO_20
));
1952 if (ctr
->info
.id20
== NULL
)
1953 return NT_STATUS_NO_MEMORY
;
1954 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_20(p
->mem_ctx
, ctr
->info
.id20
, &info
->sid
)))
1959 ctr
->info
.id21
= (SAM_USER_INFO_21
*)talloc_zero(p
->mem_ctx
,sizeof(SAM_USER_INFO_21
));
1960 if (ctr
->info
.id21
== NULL
)
1961 return NT_STATUS_NO_MEMORY
;
1962 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_21(p
->mem_ctx
, ctr
->info
.id21
,
1963 &info
->sid
, &domain_sid
)))
1968 return NT_STATUS_INVALID_INFO_CLASS
;
1971 init_samr_r_query_userinfo(r_u
, ctr
, r_u
->status
);
1973 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__
));
1978 /*******************************************************************
1979 samr_reply_query_usergroups
1980 ********************************************************************/
1982 NTSTATUS
_samr_query_usergroups(pipes_struct
*p
, SAMR_Q_QUERY_USERGROUPS
*q_u
, SAMR_R_QUERY_USERGROUPS
*r_u
)
1984 SAM_ACCOUNT
*sam_pass
=NULL
;
1986 DOM_GID
*gids
= NULL
;
1992 * from the SID in the request:
1993 * we should send back the list of DOMAIN GROUPS
1994 * the user is a member of
1996 * and only the DOMAIN GROUPS
1997 * no ALIASES !!! neither aliases of the domain
1998 * nor aliases of the builtin SID
2003 r_u
->status
= NT_STATUS_OK
;
2005 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
2007 /* find the policy handle. open a policy on it. */
2008 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
2009 return NT_STATUS_INVALID_HANDLE
;
2011 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, USER_ACCESS_GET_GROUPS
, "_samr_query_usergroups"))) {
2015 if (!sid_check_is_in_our_domain(&sid
))
2016 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
2018 pdb_init_sam(&sam_pass
);
2021 ret
= pdb_getsampwsid(sam_pass
, &sid
);
2025 pdb_free_sam(&sam_pass
);
2026 return NT_STATUS_NO_SUCH_USER
;
2029 if(!get_domain_user_groups(p
->mem_ctx
, &num_groups
, &gids
, sam_pass
)) {
2030 pdb_free_sam(&sam_pass
);
2031 return NT_STATUS_NO_SUCH_GROUP
;
2034 /* construct the response. lkclXXXX: gids are not copied! */
2035 init_samr_r_query_usergroups(r_u
, num_groups
, gids
, r_u
->status
);
2037 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
2039 pdb_free_sam(&sam_pass
);
2044 /*******************************************************************
2045 _samr_query_dom_info
2046 ********************************************************************/
2048 NTSTATUS
_samr_query_dom_info(pipes_struct
*p
, SAMR_Q_QUERY_DOMAIN_INFO
*q_u
, SAMR_R_QUERY_DOMAIN_INFO
*r_u
)
2050 struct samr_info
*info
= NULL
;
2052 uint32 min_pass_len
,pass_hist
,flag
;
2053 time_t u_expire
, u_min_age
;
2054 NTTIME nt_expire
, nt_min_age
;
2056 time_t u_lock_duration
, u_reset_time
;
2057 NTTIME nt_lock_duration
, nt_reset_time
;
2063 uint32 account_policy_temp
;
2065 uint32 num_users
=0, num_groups
=0, num_aliases
=0;
2067 if ((ctr
= (SAM_UNK_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_UNK_CTR
))) == NULL
)
2068 return NT_STATUS_NO_MEMORY
;
2072 r_u
->status
= NT_STATUS_OK
;
2074 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
2076 /* find the policy handle. open a policy on it. */
2077 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
2078 return NT_STATUS_INVALID_HANDLE
;
2080 switch (q_u
->switch_value
) {
2083 account_policy_get(AP_MIN_PASSWORD_LEN
, &account_policy_temp
);
2084 min_pass_len
= account_policy_temp
;
2086 account_policy_get(AP_PASSWORD_HISTORY
, &account_policy_temp
);
2087 pass_hist
= account_policy_temp
;
2089 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS
, &account_policy_temp
);
2090 flag
= account_policy_temp
;
2092 account_policy_get(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
2093 u_expire
= account_policy_temp
;
2095 account_policy_get(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
2096 u_min_age
= account_policy_temp
;
2098 unix_to_nt_time_abs(&nt_expire
, u_expire
);
2099 unix_to_nt_time_abs(&nt_min_age
, u_min_age
);
2101 init_unk_info1(&ctr
->info
.inf1
, (uint16
)min_pass_len
, (uint16
)pass_hist
,
2102 flag
, nt_expire
, nt_min_age
);
2106 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
, False
);
2108 if (!NT_STATUS_IS_OK(r_u
->status
)) {
2109 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2112 num_users
=info
->disp_info
.num_user_account
;
2115 r_u
->status
=load_group_domain_entries(info
, get_global_sam_sid());
2116 if (!NT_STATUS_IS_OK(r_u
->status
)) {
2117 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2120 num_groups
=info
->disp_info
.num_group_account
;
2123 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2124 init_unk_info2(&ctr
->info
.inf2
, global_myworkgroup
, global_myname
, (uint32
) time(NULL
),
2125 num_users
, num_groups
, num_aliases
);
2128 account_policy_get(AP_TIME_TO_LOGOUT
, (int *)&u_logout
);
2129 unix_to_nt_time_abs(&nt_logout
, u_logout
);
2131 init_unk_info3(&ctr
->info
.inf3
, nt_logout
);
2134 init_unk_info5(&ctr
->info
.inf5
, global_myname
);
2137 init_unk_info6(&ctr
->info
.inf6
);
2140 init_unk_info7(&ctr
->info
.inf7
);
2143 account_policy_get(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
2144 u_lock_duration
= account_policy_temp
;
2146 account_policy_get(AP_RESET_COUNT_TIME
, &account_policy_temp
);
2147 u_reset_time
= account_policy_temp
;
2149 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
2150 lockout
= account_policy_temp
;
2152 unix_to_nt_time_abs(&nt_lock_duration
, u_lock_duration
);
2153 unix_to_nt_time_abs(&nt_reset_time
, u_reset_time
);
2155 init_unk_info12(&ctr
->info
.inf12
, nt_lock_duration
, nt_reset_time
, (uint16
)lockout
);
2158 return NT_STATUS_INVALID_INFO_CLASS
;
2161 init_samr_r_query_dom_info(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_OK
);
2163 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
2168 /*******************************************************************
2169 _api_samr_create_user
2170 Create an account, can be either a normal user or a machine.
2171 This funcion will need to be updated for bdc/domain trusts.
2172 ********************************************************************/
2174 NTSTATUS
_api_samr_create_user(pipes_struct
*p
, SAMR_Q_CREATE_USER
*q_u
, SAMR_R_CREATE_USER
*r_u
)
2176 SAM_ACCOUNT
*sam_pass
=NULL
;
2180 POLICY_HND dom_pol
= q_u
->domain_pol
;
2181 UNISTR2 user_account
= q_u
->uni_name
;
2182 uint16 acb_info
= q_u
->acb_info
;
2183 POLICY_HND
*user_pol
= &r_u
->user_pol
;
2184 struct samr_info
*info
= NULL
;
2193 /* Get the domain SID stored in the domain policy */
2194 if (!get_lsa_policy_samr_sid(p
, &dom_pol
, &sid
, &acc_granted
))
2195 return NT_STATUS_INVALID_HANDLE
;
2197 if (!NT_STATUS_IS_OK(nt_status
= access_check_samr_function(acc_granted
, DOMAIN_ACCESS_CREATE_USER
, "_samr_create_user"))) {
2201 /* find the account: tell the caller if it exists.
2202 lkclXXXX i have *no* idea if this is a problem or not
2203 or even if you are supposed to construct a different
2204 reply if the account already exists...
2207 rpcstr_pull(account
, user_account
.buffer
, sizeof(account
), user_account
.uni_str_len
*2, 0);
2210 pdb_init_sam(&sam_pass
);
2213 ret
= pdb_getsampwnam(sam_pass
, account
);
2216 /* this account exists: say so */
2217 pdb_free_sam(&sam_pass
);
2218 return NT_STATUS_USER_EXISTS
;
2221 pdb_free_sam(&sam_pass
);
2224 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2225 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2226 * that only people with write access to the smbpasswd file will be able
2227 * to create a user. JRA.
2231 * add the user in the /etc/passwd file or the unix authority system.
2232 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2233 * a) local_password_change() checks for us if the /etc/passwd account really exists
2234 * b) smb_create_user() would return an error if the account already exists
2235 * and as it could return an error also if it can't create the account, it would be tricky.
2237 * So we go the easy way, only check after if the account exists.
2238 * JFM (2/3/2001), to clear any possible bad understanding (-:
2240 * We now have seperate script paramaters for adding users/machines so we
2241 * now have some sainity-checking to match.
2244 DEBUG(10,("checking account %s at pos %d for $ termination\n",account
, strlen(account
)-1));
2246 if ((acb_info
& ACB_WSTRUST
) && (account
[strlen(account
)-1] == '$')) {
2247 pstrcpy(add_script
, lp_addmachine_script());
2248 } else if ((!(acb_info
& ACB_WSTRUST
)) && (account
[strlen(account
)-1] != '$')) {
2249 pstrcpy(add_script
, lp_adduser_script());
2251 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2252 pdb_free_sam(&sam_pass
);
2253 return NT_STATUS_UNSUCCESSFUL
;
2258 * we can't check both the ending $ and the acb_info.
2260 * UserManager creates trust accounts (ending in $,
2261 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2264 if (account
[strlen(account
)-1] == '$')
2265 pstrcpy(add_script
, lp_addmachine_script());
2267 pstrcpy(add_script
, lp_adduser_script());
2271 all_string_sub(add_script
, "%u", account
, sizeof(account
));
2272 add_ret
= smbrun(add_script
,NULL
);
2273 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script
, add_ret
));
2276 pw
= getpwnam_alloc(account
);
2279 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_sam_pw(&sam_pass
, pw
))) {
2283 passwd_free(&pw
); /* done with this now */
2285 DEBUG(3,("attempting to create non-unix account %s\n", account
));
2287 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_sam(&sam_pass
))) {
2291 if (!pdb_set_username(sam_pass
, account
)) {
2292 pdb_free_sam(&sam_pass
);
2293 return NT_STATUS_NO_MEMORY
;
2297 pdb_set_acct_ctrl(sam_pass
, acb_info
);
2299 if (!pdb_add_sam_account(sam_pass
)) {
2300 pdb_free_sam(&sam_pass
);
2301 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2303 return NT_STATUS_ACCESS_DENIED
;
2306 pdb_reset_sam(sam_pass
);
2308 if (!pdb_getsampwnam(sam_pass
, account
)) {
2309 pdb_free_sam(&sam_pass
);
2310 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n",
2312 return NT_STATUS_ACCESS_DENIED
;
2315 /* Get the user's SID */
2316 sid_copy(&sid
, pdb_get_user_sid(sam_pass
));
2318 samr_make_usr_obj_sd(p
->mem_ctx
, &psd
, &sd_size
, &sid
);
2319 se_map_generic(&des_access
, &usr_generic_mapping
);
2320 if (!NT_STATUS_IS_OK(nt_status
=
2321 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2322 des_access
, &acc_granted
, "_samr_create_user"))) {
2326 /* associate the user's SID with the new handle. */
2327 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
) {
2328 pdb_free_sam(&sam_pass
);
2329 return NT_STATUS_NO_MEMORY
;
2334 info
->acc_granted
= acc_granted
;
2336 /* get a (unique) handle. open a policy on it. */
2337 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
)) {
2338 pdb_free_sam(&sam_pass
);
2339 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2342 r_u
->user_rid
=pdb_get_user_rid(sam_pass
);
2344 r_u
->access_granted
= acc_granted
;
2346 pdb_free_sam(&sam_pass
);
2348 return NT_STATUS_OK
;
2351 /*******************************************************************
2352 samr_reply_connect_anon
2353 ********************************************************************/
2355 NTSTATUS
_samr_connect_anon(pipes_struct
*p
, SAMR_Q_CONNECT_ANON
*q_u
, SAMR_R_CONNECT_ANON
*r_u
)
2357 struct samr_info
*info
= NULL
;
2361 if (!pipe_access_check(p
)) {
2362 DEBUG(3, ("access denied to samr_connect_anon\n"));
2363 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2367 /* set up the SAMR connect_anon response */
2369 r_u
->status
= NT_STATUS_OK
;
2371 /* associate the user's SID with the new handle. */
2372 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2373 return NT_STATUS_NO_MEMORY
;
2375 info
->status
= q_u
->unknown_0
;
2377 /* get a (unique) handle. open a policy on it. */
2378 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2379 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2384 /*******************************************************************
2386 ********************************************************************/
2388 NTSTATUS
_samr_connect(pipes_struct
*p
, SAMR_Q_CONNECT
*q_u
, SAMR_R_CONNECT
*r_u
)
2390 struct samr_info
*info
= NULL
;
2391 SEC_DESC
*psd
= NULL
;
2393 uint32 des_access
= q_u
->access_mask
;
2398 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2402 if (!pipe_access_check(p
)) {
2403 DEBUG(3, ("access denied to samr_connect\n"));
2404 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2408 samr_make_sam_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
2409 se_map_generic(&des_access
, &sam_generic_mapping
);
2410 if (!NT_STATUS_IS_OK(nt_status
=
2411 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2412 des_access
, &acc_granted
, "_samr_connect"))) {
2416 r_u
->status
= NT_STATUS_OK
;
2418 /* associate the user's SID and access granted with the new handle. */
2419 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2420 return NT_STATUS_NO_MEMORY
;
2422 info
->acc_granted
= acc_granted
;
2423 info
->status
= q_u
->access_mask
;
2425 /* get a (unique) handle. open a policy on it. */
2426 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2427 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2429 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2434 /*******************************************************************
2436 ********************************************************************/
2438 NTSTATUS
_samr_connect4(pipes_struct
*p
, SAMR_Q_CONNECT4
*q_u
, SAMR_R_CONNECT4
*r_u
)
2440 struct samr_info
*info
= NULL
;
2441 SEC_DESC
*psd
= NULL
;
2443 uint32 des_access
= q_u
->access_mask
;
2448 DEBUG(5,("_samr_connect4: %d\n", __LINE__
));
2452 if (!pipe_access_check(p
)) {
2453 DEBUG(3, ("access denied to samr_connect4\n"));
2454 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2458 samr_make_sam_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
2459 se_map_generic(&des_access
, &sam_generic_mapping
);
2460 if (!NT_STATUS_IS_OK(nt_status
=
2461 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2462 des_access
, &acc_granted
, "_samr_connect"))) {
2466 r_u
->status
= NT_STATUS_OK
;
2468 /* associate the user's SID and access granted with the new handle. */
2469 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2470 return NT_STATUS_NO_MEMORY
;
2472 info
->acc_granted
= acc_granted
;
2473 info
->status
= q_u
->access_mask
;
2475 /* get a (unique) handle. open a policy on it. */
2476 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2477 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2479 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2484 /**********************************************************************
2485 api_samr_lookup_domain
2486 **********************************************************************/
2488 NTSTATUS
_samr_lookup_domain(pipes_struct
*p
, SAMR_Q_LOOKUP_DOMAIN
*q_u
, SAMR_R_LOOKUP_DOMAIN
*r_u
)
2490 struct samr_info
*info
;
2491 fstring domain_name
;
2494 r_u
->status
= NT_STATUS_OK
;
2496 if (!find_policy_by_hnd(p
, &q_u
->connect_pol
, (void**)&info
))
2497 return NT_STATUS_INVALID_HANDLE
;
2499 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
, SAMR_ACCESS_OPEN_DOMAIN
, "_samr_lookup_domain"))) {
2503 rpcstr_pull(domain_name
, q_u
->uni_domain
.buffer
, sizeof(domain_name
), q_u
->uni_domain
.uni_str_len
*2, 0);
2507 if (!secrets_fetch_domain_sid(domain_name
, &sid
)) {
2508 r_u
->status
= NT_STATUS_NO_SUCH_DOMAIN
;
2511 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
, sid_string_static(&sid
)));
2513 init_samr_r_lookup_domain(r_u
, &sid
, r_u
->status
);
2518 /******************************************************************
2519 makes a SAMR_R_ENUM_DOMAINS structure.
2520 ********************************************************************/
2522 static BOOL
make_enum_domains(TALLOC_CTX
*ctx
, SAM_ENTRY
**pp_sam
,
2523 UNISTR2
**pp_uni_name
, uint32 num_sam_entries
, fstring doms
[])
2529 DEBUG(5, ("make_enum_domains\n"));
2532 *pp_uni_name
= NULL
;
2534 if (num_sam_entries
== 0)
2537 sam
= (SAM_ENTRY
*)talloc_zero(ctx
, sizeof(SAM_ENTRY
)*num_sam_entries
);
2538 uni_name
= (UNISTR2
*)talloc_zero(ctx
, sizeof(UNISTR2
)*num_sam_entries
);
2540 if (sam
== NULL
|| uni_name
== NULL
)
2543 for (i
= 0; i
< num_sam_entries
; i
++) {
2544 int len
= doms
[i
] != NULL
? strlen(doms
[i
]) : 0;
2546 init_sam_entry(&sam
[i
], len
, 0);
2547 init_unistr2(&uni_name
[i
], doms
[i
], len
);
2551 *pp_uni_name
= uni_name
;
2556 /**********************************************************************
2557 api_samr_enum_domains
2558 **********************************************************************/
2560 NTSTATUS
_samr_enum_domains(pipes_struct
*p
, SAMR_Q_ENUM_DOMAINS
*q_u
, SAMR_R_ENUM_DOMAINS
*r_u
)
2562 struct samr_info
*info
;
2563 uint32 num_entries
= 2;
2567 r_u
->status
= NT_STATUS_OK
;
2569 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void**)&info
))
2570 return NT_STATUS_INVALID_HANDLE
;
2572 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
, SAMR_ACCESS_ENUM_DOMAINS
, "_samr_enum_domains"))) {
2576 switch (lp_server_role()) {
2577 case ROLE_DOMAIN_PDC
:
2578 case ROLE_DOMAIN_BDC
:
2579 name
= global_myworkgroup
;
2582 name
= global_myname
;
2585 fstrcpy(dom
[0],name
);
2587 fstrcpy(dom
[1],"Builtin");
2589 if (!make_enum_domains(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_dom_name
, num_entries
, dom
))
2590 return NT_STATUS_NO_MEMORY
;
2592 init_samr_r_enum_domains(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
2597 /*******************************************************************
2599 ********************************************************************/
2601 NTSTATUS
_api_samr_open_alias(pipes_struct
*p
, SAMR_Q_OPEN_ALIAS
*q_u
, SAMR_R_OPEN_ALIAS
*r_u
)
2604 POLICY_HND domain_pol
= q_u
->dom_pol
;
2605 uint32 alias_rid
= q_u
->rid_alias
;
2606 POLICY_HND
*alias_pol
= &r_u
->pol
;
2607 struct samr_info
*info
= NULL
;
2608 SEC_DESC
*psd
= NULL
;
2610 uint32 des_access
= q_u
->access_mask
;
2614 r_u
->status
= NT_STATUS_OK
;
2616 /* find the domain policy and get the SID / access bits stored in the domain policy */
2617 if (!get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
, &acc_granted
))
2618 return NT_STATUS_INVALID_HANDLE
;
2620 if (!NT_STATUS_IS_OK(status
= access_check_samr_function(acc_granted
, DOMAIN_ACCESS_OPEN_ACCOUNT
, "_samr_open_alias"))) {
2624 /* append the alias' RID to it */
2625 if (!sid_append_rid(&sid
, alias_rid
))
2626 return NT_STATUS_NO_SUCH_USER
;
2628 /*check if access can be granted as requested by client. */
2629 samr_make_ali_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
2630 se_map_generic(&des_access
,&ali_generic_mapping
);
2631 if (!NT_STATUS_IS_OK(status
=
2632 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2633 des_access
, &acc_granted
, "_samr_open_alias"))) {
2638 * we should check if the rid really exist !!!
2642 /* associate the user's SID with the new handle. */
2643 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
)
2644 return NT_STATUS_NO_MEMORY
;
2646 info
->acc_granted
= acc_granted
;
2648 /* get a (unique) handle. open a policy on it. */
2649 if (!create_policy_hnd(p
, alias_pol
, free_samr_info
, (void *)info
))
2650 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2655 /*******************************************************************
2657 ********************************************************************/
2659 static BOOL
set_user_info_10(const SAM_USER_INFO_10
*id10
, DOM_SID
*sid
)
2661 SAM_ACCOUNT
*pwd
=NULL
;
2666 ret
= pdb_getsampwsid(pwd
, sid
);
2674 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2679 if (!pdb_set_acct_ctrl(pwd
, id10
->acb_info
)) {
2684 if(!pdb_update_sam_account(pwd
)) {
2694 /*******************************************************************
2696 ********************************************************************/
2698 static BOOL
set_user_info_12(SAM_USER_INFO_12
*id12
, DOM_SID
*sid
)
2700 SAM_ACCOUNT
*pwd
= NULL
;
2704 if(!pdb_getsampwsid(pwd
, sid
)) {
2710 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2715 if (!pdb_set_lanman_passwd (pwd
, id12
->lm_pwd
)) {
2719 if (!pdb_set_nt_passwd (pwd
, id12
->nt_pwd
)) {
2723 if (!pdb_set_pass_changed_now (pwd
)) {
2728 if(!pdb_update_sam_account(pwd
)) {
2737 /*******************************************************************
2739 ********************************************************************/
2741 static BOOL
set_user_info_21(SAM_USER_INFO_21
*id21
, DOM_SID
*sid
)
2743 SAM_ACCOUNT
*pwd
= NULL
;
2746 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2752 if (!pdb_getsampwsid(pwd
, sid
)) {
2757 copy_id21_to_sam_passwd(pwd
, id21
);
2760 * The funny part about the previous two calls is
2761 * that pwd still has the password hashes from the
2762 * passdb entry. These have not been updated from
2763 * id21. I don't know if they need to be set. --jerry
2766 /* write the change out */
2767 if(!pdb_update_sam_account(pwd
)) {
2777 /*******************************************************************
2779 ********************************************************************/
2781 static BOOL
set_user_info_23(SAM_USER_INFO_23
*id23
, DOM_SID
*sid
)
2783 SAM_ACCOUNT
*pwd
= NULL
;
2784 pstring plaintext_buf
;
2789 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2795 if (!pdb_getsampwsid(pwd
, sid
)) {
2800 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2801 pdb_get_username(pwd
)));
2803 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2805 copy_id23_to_sam_passwd(pwd
, id23
);
2807 if (!decode_pw_buffer((char*)id23
->pass
, plaintext_buf
, 256, &len
)) {
2812 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
2817 /* if it's a trust account, don't update /etc/passwd */
2818 if ( (!IS_SAM_UNIX_USER(pwd
)) ||
2819 ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2820 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2821 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2822 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2824 /* update the UNIX password */
2825 if (lp_unix_password_sync() )
2826 if(!chgpasswd(pdb_get_username(pwd
), "", plaintext_buf
, True
)) {
2832 ZERO_STRUCT(plaintext_buf
);
2834 if(!pdb_update_sam_account(pwd
)) {
2844 /*******************************************************************
2846 ********************************************************************/
2848 static BOOL
set_user_info_pw(char *pass
, DOM_SID
*sid
)
2850 SAM_ACCOUNT
*pwd
= NULL
;
2852 pstring plaintext_buf
;
2857 if (!pdb_getsampwsid(pwd
, sid
)) {
2862 DEBUG(5, ("Attempting administrator password change for user %s\n",
2863 pdb_get_username(pwd
)));
2865 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2867 ZERO_STRUCT(plaintext_buf
);
2869 if (!decode_pw_buffer(pass
, plaintext_buf
, 256, &len
)) {
2874 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
2879 /* if it's a trust account, don't update /etc/passwd */
2880 if ( (!IS_SAM_UNIX_USER(pwd
)) ||
2881 ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2882 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2883 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2884 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2886 /* update the UNIX password */
2887 if (lp_unix_password_sync()) {
2888 if(!chgpasswd(pdb_get_username(pwd
), "", plaintext_buf
, True
)) {
2895 ZERO_STRUCT(plaintext_buf
);
2897 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2899 /* update the SAMBA password */
2900 if(!pdb_update_sam_account(pwd
)) {
2910 /*******************************************************************
2911 samr_reply_set_userinfo
2912 ********************************************************************/
2914 NTSTATUS
_samr_set_userinfo(pipes_struct
*p
, SAMR_Q_SET_USERINFO
*q_u
, SAMR_R_SET_USERINFO
*r_u
)
2917 POLICY_HND
*pol
= &q_u
->pol
;
2918 uint16 switch_value
= q_u
->switch_value
;
2919 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
2921 uint32 acc_required
;
2923 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__
));
2925 r_u
->status
= NT_STATUS_OK
;
2927 /* find the policy handle. open a policy on it. */
2928 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
, &acc_granted
))
2929 return NT_STATUS_INVALID_HANDLE
;
2931 acc_required
= USER_ACCESS_SET_LOC_COM
| USER_ACCESS_SET_ATTRIBUTES
; /* This is probably wrong */
2932 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, acc_required
, "_samr_set_userinfo"))) {
2936 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid
), switch_value
));
2939 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2940 return NT_STATUS_INVALID_INFO_CLASS
;
2943 /* ok! user info levels (lots: see MSDEV help), off we go... */
2944 switch (switch_value
) {
2946 if (!set_user_info_12(ctr
->info
.id12
, &sid
))
2947 return NT_STATUS_ACCESS_DENIED
;
2951 SamOEMhash(ctr
->info
.id24
->pass
, p
->session_key
, 516);
2953 dump_data(100, (char *)ctr
->info
.id24
->pass
, 516);
2955 if (!set_user_info_pw((char *)ctr
->info
.id24
->pass
, &sid
))
2956 return NT_STATUS_ACCESS_DENIED
;
2962 * Currently we don't really know how to unmarshall
2963 * the level 25 struct, and the password encryption
2964 * is different. This is a placeholder for when we
2965 * do understand it. In the meantime just return INVALID
2966 * info level and W2K SP2 drops down to level 23... JRA.
2969 SamOEMhash(ctr
->info
.id25
->pass
, p
->session_key
, 532);
2971 dump_data(100, (char *)ctr
->info
.id25
->pass
, 532);
2973 if (!set_user_info_pw(ctr
->info
.id25
->pass
, &sid
))
2974 return NT_STATUS_ACCESS_DENIED
;
2977 return NT_STATUS_INVALID_INFO_CLASS
;
2980 SamOEMhash(ctr
->info
.id23
->pass
, p
->session_key
, 516);
2982 dump_data(100, (char *)ctr
->info
.id23
->pass
, 516);
2984 if (!set_user_info_23(ctr
->info
.id23
, &sid
))
2985 return NT_STATUS_ACCESS_DENIED
;
2989 return NT_STATUS_INVALID_INFO_CLASS
;
2995 /*******************************************************************
2996 samr_reply_set_userinfo2
2997 ********************************************************************/
2999 NTSTATUS
_samr_set_userinfo2(pipes_struct
*p
, SAMR_Q_SET_USERINFO2
*q_u
, SAMR_R_SET_USERINFO2
*r_u
)
3002 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
3003 POLICY_HND
*pol
= &q_u
->pol
;
3004 uint16 switch_value
= q_u
->switch_value
;
3006 uint32 acc_required
;
3008 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__
));
3010 r_u
->status
= NT_STATUS_OK
;
3012 /* find the policy handle. open a policy on it. */
3013 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
, &acc_granted
))
3014 return NT_STATUS_INVALID_HANDLE
;
3016 acc_required
= USER_ACCESS_SET_LOC_COM
| USER_ACCESS_SET_ATTRIBUTES
; /* This is probably wrong */
3017 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, acc_required
, "_samr_set_userinfo2"))) {
3021 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid
)));
3024 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3025 return NT_STATUS_INVALID_INFO_CLASS
;
3028 switch_value
=ctr
->switch_value
;
3030 /* ok! user info levels (lots: see MSDEV help), off we go... */
3031 switch (switch_value
) {
3033 if (!set_user_info_21(ctr
->info
.id21
, &sid
))
3034 return NT_STATUS_ACCESS_DENIED
;
3037 if (!set_user_info_10(ctr
->info
.id10
, &sid
))
3038 return NT_STATUS_ACCESS_DENIED
;
3041 /* Used by AS/U JRA. */
3042 if (!set_user_info_12(ctr
->info
.id12
, &sid
))
3043 return NT_STATUS_ACCESS_DENIED
;
3046 return NT_STATUS_INVALID_INFO_CLASS
;
3052 /*********************************************************************
3053 _samr_query_aliasmem
3054 *********************************************************************/
3056 NTSTATUS
_samr_query_useraliases(pipes_struct
*p
, SAMR_Q_QUERY_USERALIASES
*q_u
, SAMR_R_QUERY_USERALIASES
*r_u
)
3058 int num_groups
= 0, tmp_num_groups
=0;
3059 uint32
*rids
=NULL
, *new_rids
=NULL
, *tmp_rids
=NULL
;
3060 struct samr_info
*info
= NULL
;
3062 /* until i see a real useraliases query, we fack one up */
3064 /* I have seen one, JFM 2/12/2001 */
3066 * Explanation of what this call does:
3067 * for all the SID given in the request:
3068 * return a list of alias (local groups)
3069 * that have those SID as members.
3071 * and that's the alias in the domain specified
3072 * in the policy_handle
3074 * if the policy handle is on an incorrect sid
3075 * for example a user's sid
3076 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3079 r_u
->status
= NT_STATUS_OK
;
3081 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__
));
3083 /* find the policy handle. open a policy on it. */
3084 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
3085 return NT_STATUS_INVALID_HANDLE
;
3087 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
, USER_ACCESS_GET_GROUPS
, "_samr_query_useraliases"))) {
3091 if (!sid_check_is_domain(&info
->sid
) &&
3092 !sid_check_is_builtin(&info
->sid
))
3093 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3096 for (i
=0; i
<q_u
->num_sids1
; i
++) {
3098 r_u
->status
=get_alias_user_groups(p
->mem_ctx
, &info
->sid
, &tmp_num_groups
, &tmp_rids
, &(q_u
->sid
[i
].sid
));
3101 * if there is an error, we just continue as
3102 * it can be an unfound user or group
3104 if (!NT_STATUS_IS_OK(r_u
->status
)) {
3105 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3109 if (tmp_num_groups
==0) {
3110 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3114 new_rids
=(uint32
*)talloc_realloc(p
->mem_ctx
, rids
, (num_groups
+tmp_num_groups
)*sizeof(uint32
));
3115 if (new_rids
==NULL
) {
3116 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3117 return NT_STATUS_NO_MEMORY
;
3121 for (j
=0; j
<tmp_num_groups
; j
++)
3122 rids
[j
+num_groups
]=tmp_rids
[j
];
3124 safe_free(tmp_rids
);
3126 num_groups
+=tmp_num_groups
;
3129 init_samr_r_query_useraliases(r_u
, num_groups
, rids
, NT_STATUS_OK
);
3130 return NT_STATUS_OK
;
3133 /*********************************************************************
3134 _samr_query_aliasmem
3135 *********************************************************************/
3137 NTSTATUS
_samr_query_aliasmem(pipes_struct
*p
, SAMR_Q_QUERY_ALIASMEM
*q_u
, SAMR_R_QUERY_ALIASMEM
*r_u
)
3149 fstring alias_sid_str
;
3152 SAM_ACCOUNT
*sam_user
= NULL
;
3156 /* find the policy handle. open a policy on it. */
3157 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3158 return NT_STATUS_INVALID_HANDLE
;
3160 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, ALIAS_ACCESS_GET_MEMBERS
, "_samr_query_aliasmem"))) {
3164 sid_copy(&als_sid
, &alias_sid
);
3165 sid_to_string(alias_sid_str
, &alias_sid
);
3166 sid_split_rid(&alias_sid
, &alias_rid
);
3168 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3170 if (sid_equal(&alias_sid
, &global_sid_Builtin
)) {
3171 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3172 if(!get_local_group_from_sid(als_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3173 return NT_STATUS_NO_SUCH_ALIAS
;
3175 if (sid_equal(&alias_sid
, get_global_sam_sid())) {
3176 DEBUG(10, ("lookup on Server SID\n"));
3177 if(!get_local_group_from_sid(als_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3178 return NT_STATUS_NO_SUCH_ALIAS
;
3182 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
3183 return NT_STATUS_NO_SUCH_ALIAS
;
3185 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3186 sid
= (DOM_SID2
*)talloc_zero(p
->mem_ctx
, sizeof(DOM_SID2
) * num_uids
);
3187 if (num_uids
!=0 && sid
== NULL
)
3188 return NT_STATUS_NO_MEMORY
;
3190 for (i
= 0; i
< num_uids
; i
++) {
3191 struct passwd
*pass
;
3194 sid_copy(&temp_sid
, get_global_sam_sid());
3196 pass
= getpwuid_alloc(uid
[i
]);
3197 if (!pass
) continue;
3199 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user
))) {
3205 check
= pdb_getsampwnam(sam_user
, pass
->pw_name
);
3208 if (check
!= True
) {
3209 pdb_free_sam(&sam_user
);
3214 rid
= pdb_get_user_rid(sam_user
);
3216 pdb_free_sam(&sam_user
);
3221 pdb_free_sam(&sam_user
);
3224 sid_append_rid(&temp_sid
, rid
);
3226 init_dom_sid2(&sid
[i
], &temp_sid
);
3229 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3230 init_samr_r_query_aliasmem(r_u
, num_uids
, sid
, NT_STATUS_OK
);
3232 return NT_STATUS_OK
;
3235 /*********************************************************************
3236 _samr_query_groupmem
3237 *********************************************************************/
3239 NTSTATUS
_samr_query_groupmem(pipes_struct
*p
, SAMR_Q_QUERY_GROUPMEM
*q_u
, SAMR_R_QUERY_GROUPMEM
*r_u
)
3245 fstring group_sid_str
;
3253 SAM_ACCOUNT
*sam_user
= NULL
;
3257 /* find the policy handle. open a policy on it. */
3258 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
, &acc_granted
))
3259 return NT_STATUS_INVALID_HANDLE
;
3261 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, GROUP_ACCESS_GET_MEMBERS
, "_samr_query_groupmem"))) {
3265 /* todo: change to use sid_compare_front */
3267 sid_split_rid(&group_sid
, &group_rid
);
3268 sid_to_string(group_sid_str
, &group_sid
);
3269 DEBUG(10, ("sid is %s\n", group_sid_str
));
3271 /* can we get a query for an SID outside our domain ? */
3272 if (!sid_equal(&group_sid
, get_global_sam_sid()))
3273 return NT_STATUS_NO_SUCH_GROUP
;
3275 sid_append_rid(&group_sid
, group_rid
);
3276 DEBUG(10, ("lookup on Domain SID\n"));
3278 if(!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3279 return NT_STATUS_NO_SUCH_GROUP
;
3281 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
3282 return NT_STATUS_NO_SUCH_GROUP
;
3284 rid
=talloc_zero(p
->mem_ctx
, sizeof(uint32
)*num_uids
);
3285 attr
=talloc_zero(p
->mem_ctx
, sizeof(uint32
)*num_uids
);
3287 if (num_uids
!=0 && (rid
==NULL
|| attr
==NULL
))
3288 return NT_STATUS_NO_MEMORY
;
3290 for (i
=0; i
<num_uids
; i
++) {
3291 struct passwd
*pass
;
3294 pass
= getpwuid_alloc(uid
[i
]);
3295 if (!pass
) continue;
3297 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user
))) {
3303 check
= pdb_getsampwnam(sam_user
, pass
->pw_name
);
3306 if (check
!= True
) {
3307 pdb_free_sam(&sam_user
);
3312 urid
= pdb_get_user_rid(sam_user
);
3314 pdb_free_sam(&sam_user
);
3319 pdb_free_sam(&sam_user
);
3323 attr
[i
] = SID_NAME_USER
;
3326 init_samr_r_query_groupmem(r_u
, num_uids
, rid
, attr
, NT_STATUS_OK
);
3328 return NT_STATUS_OK
;
3331 /*********************************************************************
3333 *********************************************************************/
3335 NTSTATUS
_samr_add_aliasmem(pipes_struct
*p
, SAMR_Q_ADD_ALIASMEM
*q_u
, SAMR_R_ADD_ALIASMEM
*r_u
)
3338 fstring alias_sid_str
;
3345 SAM_ACCOUNT
*sam_user
= NULL
;
3349 /* Find the policy handle. Open a policy on it. */
3350 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3351 return NT_STATUS_INVALID_HANDLE
;
3353 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, ALIAS_ACCESS_ADD_MEMBER
, "_samr_add_aliasmem"))) {
3357 sid_to_string(alias_sid_str
, &alias_sid
);
3358 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3360 if (sid_compare(&alias_sid
, get_global_sam_sid())>0) {
3361 DEBUG(10, ("adding member on Server SID\n"));
3362 if(!get_local_group_from_sid(alias_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3363 return NT_STATUS_NO_SUCH_ALIAS
;
3366 if (sid_compare(&alias_sid
, &global_sid_Builtin
)>0) {
3367 DEBUG(10, ("adding member on BUILTIN SID\n"));
3368 if( !get_local_group_from_sid(alias_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3369 return NT_STATUS_NO_SUCH_ALIAS
;
3372 return NT_STATUS_NO_SUCH_ALIAS
;
3375 ret
= pdb_init_sam(&sam_user
);
3376 if (!NT_STATUS_IS_OK(ret
))
3379 check
= pdb_getsampwsid(sam_user
, &q_u
->sid
.sid
);
3381 if (check
!= True
) {
3382 pdb_free_sam(&sam_user
);
3383 return NT_STATUS_NO_SUCH_USER
;
3386 uid
= pdb_get_uid(sam_user
);
3388 pdb_free_sam(&sam_user
);
3389 return NT_STATUS_NO_SUCH_USER
;
3392 pdb_free_sam(&sam_user
);
3394 if ((pwd
=getpwuid_alloc(uid
)) == NULL
) {
3395 return NT_STATUS_NO_SUCH_USER
;
3400 if ((grp
=getgrgid(map
.gid
)) == NULL
)
3401 return NT_STATUS_NO_SUCH_ALIAS
;
3403 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3404 fstrcpy(grp_name
, grp
->gr_name
);
3406 /* if the user is already in the group */
3407 if(user_in_group_list(pwd
->pw_name
, grp_name
))
3408 return NT_STATUS_MEMBER_IN_ALIAS
;
3411 * ok, the group exist, the user exist, the user is not in the group,
3412 * we can (finally) add it to the group !
3414 smb_add_user_group(grp_name
, pwd
->pw_name
);
3416 /* check if the user has been added then ... */
3417 if(!user_in_group_list(pwd
->pw_name
, grp_name
))
3418 return NT_STATUS_MEMBER_NOT_IN_ALIAS
; /* don't know what to reply else */
3420 return NT_STATUS_OK
;
3423 /*********************************************************************
3425 *********************************************************************/
3427 NTSTATUS
_samr_del_aliasmem(pipes_struct
*p
, SAMR_Q_DEL_ALIASMEM
*q_u
, SAMR_R_DEL_ALIASMEM
*r_u
)
3430 fstring alias_sid_str
;
3434 SAM_ACCOUNT
*sam_pass
=NULL
;
3437 /* Find the policy handle. Open a policy on it. */
3438 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3439 return NT_STATUS_INVALID_HANDLE
;
3441 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, ALIAS_ACCESS_REMOVE_MEMBER
, "_samr_del_aliasmem"))) {
3445 sid_to_string(alias_sid_str
, &alias_sid
);
3446 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str
));
3448 if (!sid_check_is_in_our_domain(&alias_sid
) &&
3449 !sid_check_is_in_builtin(&alias_sid
)) {
3450 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3451 return NT_STATUS_NO_SUCH_ALIAS
;
3454 if( !get_local_group_from_sid(alias_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3455 return NT_STATUS_NO_SUCH_ALIAS
;
3457 if ((grp
=getgrgid(map
.gid
)) == NULL
)
3458 return NT_STATUS_NO_SUCH_ALIAS
;
3460 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3461 fstrcpy(grp_name
, grp
->gr_name
);
3463 /* check if the user exists before trying to remove it from the group */
3464 pdb_init_sam(&sam_pass
);
3465 if(!pdb_getsampwsid(sam_pass
, &q_u
->sid
.sid
)) {
3466 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass
)));
3467 pdb_free_sam(&sam_pass
);
3468 return NT_STATUS_NO_SUCH_USER
;
3471 /* if the user is not in the group */
3472 if(!user_in_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3473 pdb_free_sam(&sam_pass
);
3474 return NT_STATUS_MEMBER_IN_ALIAS
;
3477 smb_delete_user_group(grp_name
, pdb_get_username(sam_pass
));
3479 /* check if the user has been removed then ... */
3480 if(user_in_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3481 pdb_free_sam(&sam_pass
);
3482 return NT_STATUS_MEMBER_NOT_IN_ALIAS
; /* don't know what to reply else */
3485 pdb_free_sam(&sam_pass
);
3486 return NT_STATUS_OK
;
3489 /*********************************************************************
3491 *********************************************************************/
3493 NTSTATUS
_samr_add_groupmem(pipes_struct
*p
, SAMR_Q_ADD_GROUPMEM
*q_u
, SAMR_R_ADD_GROUPMEM
*r_u
)
3497 fstring group_sid_str
;
3504 SAM_ACCOUNT
*sam_user
;
3508 /* Find the policy handle. Open a policy on it. */
3509 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
3510 return NT_STATUS_INVALID_HANDLE
;
3512 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, GROUP_ACCESS_ADD_MEMBER
, "_samr_add_groupmem"))) {
3516 sid_to_string(group_sid_str
, &group_sid
);
3517 DEBUG(10, ("sid is %s\n", group_sid_str
));
3519 if (sid_compare(&group_sid
, get_global_sam_sid())<=0)
3520 return NT_STATUS_NO_SUCH_GROUP
;
3522 DEBUG(10, ("lookup on Domain SID\n"));
3524 if(!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3525 return NT_STATUS_NO_SUCH_GROUP
;
3527 sid_copy(&user_sid
, get_global_sam_sid());
3528 sid_append_rid(&user_sid
, q_u
->rid
);
3530 ret
= pdb_init_sam(&sam_user
);
3531 if (!NT_STATUS_IS_OK(ret
))
3534 check
= pdb_getsampwsid(sam_user
, &user_sid
);
3536 if (check
!= True
) {
3537 pdb_free_sam(&sam_user
);
3538 return NT_STATUS_NO_SUCH_USER
;
3541 uid
= pdb_get_uid(sam_user
);
3543 pdb_free_sam(&sam_user
);
3544 return NT_STATUS_NO_SUCH_USER
;
3547 pdb_free_sam(&sam_user
);
3549 if ((pwd
=getpwuid_alloc(uid
)) == NULL
) {
3550 return NT_STATUS_NO_SUCH_USER
;
3555 if ((grp
=getgrgid(map
.gid
)) == NULL
)
3556 return NT_STATUS_NO_SUCH_GROUP
;
3558 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3559 fstrcpy(grp_name
, grp
->gr_name
);
3561 /* if the user is already in the group */
3562 if(user_in_group_list(pwd
->pw_name
, grp_name
))
3563 return NT_STATUS_MEMBER_IN_GROUP
;
3566 * ok, the group exist, the user exist, the user is not in the group,
3568 * we can (finally) add it to the group !
3571 smb_add_user_group(grp_name
, pwd
->pw_name
);
3573 /* check if the user has been added then ... */
3574 if(!user_in_group_list(pwd
->pw_name
, grp_name
))
3575 return NT_STATUS_MEMBER_NOT_IN_GROUP
; /* don't know what to reply else */
3577 return NT_STATUS_OK
;
3580 /*********************************************************************
3582 *********************************************************************/
3584 NTSTATUS
_samr_del_groupmem(pipes_struct
*p
, SAMR_Q_DEL_GROUPMEM
*q_u
, SAMR_R_DEL_GROUPMEM
*r_u
)
3588 SAM_ACCOUNT
*sam_pass
=NULL
;
3595 * delete the group member named q_u->rid
3596 * who is a member of the sid associated with the handle
3597 * the rid is a user's rid as the group is a domain group.
3600 /* Find the policy handle. Open a policy on it. */
3601 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
3602 return NT_STATUS_INVALID_HANDLE
;
3604 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, GROUP_ACCESS_REMOVE_MEMBER
, "_samr_del_groupmem"))) {
3608 if (!sid_check_is_in_our_domain(&group_sid
))
3609 return NT_STATUS_NO_SUCH_GROUP
;
3611 sid_copy(&user_sid
, get_global_sam_sid());
3612 sid_append_rid(&user_sid
, q_u
->rid
);
3614 if (!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3615 return NT_STATUS_NO_SUCH_GROUP
;
3617 if ((grp
=getgrgid(map
.gid
)) == NULL
)
3618 return NT_STATUS_NO_SUCH_GROUP
;
3620 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3621 fstrcpy(grp_name
, grp
->gr_name
);
3623 /* check if the user exists before trying to remove it from the group */
3624 pdb_init_sam(&sam_pass
);
3625 if (!pdb_getsampwsid(sam_pass
, &user_sid
)) {
3626 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass
)));
3627 pdb_free_sam(&sam_pass
);
3628 return NT_STATUS_NO_SUCH_USER
;
3631 /* if the user is not in the group */
3632 if (!user_in_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3633 pdb_free_sam(&sam_pass
);
3634 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
3637 smb_delete_user_group(grp_name
, pdb_get_username(sam_pass
));
3639 /* check if the user has been removed then ... */
3640 if (user_in_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3641 pdb_free_sam(&sam_pass
);
3642 return NT_STATUS_ACCESS_DENIED
; /* don't know what to reply else */
3645 pdb_free_sam(&sam_pass
);
3646 return NT_STATUS_OK
;
3650 /****************************************************************************
3651 Delete a UNIX user on demand.
3652 ****************************************************************************/
3654 static int smb_delete_user(const char *unix_user
)
3659 pstrcpy(del_script
, lp_deluser_script());
3662 all_string_sub(del_script
, "%u", unix_user
, sizeof(pstring
));
3663 ret
= smbrun(del_script
,NULL
);
3664 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script
,ret
));
3668 /*********************************************************************
3669 _samr_delete_dom_user
3670 *********************************************************************/
3672 NTSTATUS
_samr_delete_dom_user(pipes_struct
*p
, SAMR_Q_DELETE_DOM_USER
*q_u
, SAMR_R_DELETE_DOM_USER
*r_u
)
3675 SAM_ACCOUNT
*sam_pass
=NULL
;
3678 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__
));
3680 /* Find the policy handle. Open a policy on it. */
3681 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &user_sid
, &acc_granted
))
3682 return NT_STATUS_INVALID_HANDLE
;
3684 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, DELETE_ACCESS
, "_samr_delete_dom_user"))) {
3688 if (!sid_check_is_in_our_domain(&user_sid
))
3689 return NT_STATUS_CANNOT_DELETE
;
3691 /* check if the user exists before trying to delete */
3692 pdb_init_sam(&sam_pass
);
3693 if(!pdb_getsampwsid(sam_pass
, &user_sid
)) {
3694 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass
)));
3695 pdb_free_sam(&sam_pass
);
3696 return NT_STATUS_NO_SUCH_USER
;
3699 /* delete the unix side */
3701 * note: we don't check if the delete really happened
3702 * as the script is not necessary present
3703 * and maybe the sysadmin doesn't want to delete the unix side
3705 smb_delete_user(pdb_get_username(sam_pass
));
3707 /* and delete the samba side */
3708 if (!pdb_delete_sam_account(sam_pass
)) {
3709 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass
)));
3710 pdb_free_sam(&sam_pass
);
3711 return NT_STATUS_CANNOT_DELETE
;
3714 pdb_free_sam(&sam_pass
);
3716 if (!close_policy_hnd(p
, &q_u
->user_pol
))
3717 return NT_STATUS_OBJECT_NAME_INVALID
;
3719 return NT_STATUS_OK
;
3722 /*********************************************************************
3723 _samr_delete_dom_group
3724 *********************************************************************/
3726 NTSTATUS
_samr_delete_dom_group(pipes_struct
*p
, SAMR_Q_DELETE_DOM_GROUP
*q_u
, SAMR_R_DELETE_DOM_GROUP
*r_u
)
3731 fstring group_sid_str
;
3737 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__
));
3739 /* Find the policy handle. Open a policy on it. */
3740 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
, &acc_granted
))
3741 return NT_STATUS_INVALID_HANDLE
;
3743 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, DELETE_ACCESS
, "_samr_delete_dom_group"))) {
3747 sid_copy(&dom_sid
, &group_sid
);
3748 sid_to_string(group_sid_str
, &dom_sid
);
3749 sid_split_rid(&dom_sid
, &group_rid
);
3751 DEBUG(10, ("sid is %s\n", group_sid_str
));
3753 /* we check if it's our SID before deleting */
3754 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
3755 return NT_STATUS_NO_SUCH_GROUP
;
3757 DEBUG(10, ("lookup on Domain SID\n"));
3759 if(!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3760 return NT_STATUS_NO_SUCH_GROUP
;
3764 /* check if group really exists */
3765 if ( (grp
=getgrgid(gid
)) == NULL
)
3766 return NT_STATUS_NO_SUCH_GROUP
;
3768 /* we can delete the UNIX group */
3769 smb_delete_group(grp
->gr_name
);
3771 /* check if the group has been successfully deleted */
3772 if ( (grp
=getgrgid(gid
)) != NULL
)
3773 return NT_STATUS_ACCESS_DENIED
;
3775 if(!group_map_remove(group_sid
))
3776 return NT_STATUS_ACCESS_DENIED
;
3778 if (!close_policy_hnd(p
, &q_u
->group_pol
))
3779 return NT_STATUS_OBJECT_NAME_INVALID
;
3781 return NT_STATUS_OK
;
3784 /*********************************************************************
3785 _samr_delete_dom_alias
3786 *********************************************************************/
3788 NTSTATUS
_samr_delete_dom_alias(pipes_struct
*p
, SAMR_Q_DELETE_DOM_ALIAS
*q_u
, SAMR_R_DELETE_DOM_ALIAS
*r_u
)
3793 fstring alias_sid_str
;
3799 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__
));
3801 /* Find the policy handle. Open a policy on it. */
3802 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3803 return NT_STATUS_INVALID_HANDLE
;
3805 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, DELETE_ACCESS
, "_samr_delete_dom_alias"))) {
3809 sid_copy(&dom_sid
, &alias_sid
);
3810 sid_to_string(alias_sid_str
, &dom_sid
);
3811 sid_split_rid(&dom_sid
, &alias_rid
);
3813 DEBUG(10, ("sid is %s\n", alias_sid_str
));
3815 /* we check if it's our SID before deleting */
3816 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
3817 return NT_STATUS_NO_SUCH_ALIAS
;
3819 DEBUG(10, ("lookup on Local SID\n"));
3821 if(!get_local_group_from_sid(alias_sid
, &map
, MAPPING_WITHOUT_PRIV
))
3822 return NT_STATUS_NO_SUCH_ALIAS
;
3826 /* check if group really exists */
3827 if ( (grp
=getgrgid(gid
)) == NULL
)
3828 return NT_STATUS_NO_SUCH_ALIAS
;
3830 /* we can delete the UNIX group */
3831 smb_delete_group(grp
->gr_name
);
3833 /* check if the group has been successfully deleted */
3834 if ( (grp
=getgrgid(gid
)) != NULL
)
3835 return NT_STATUS_ACCESS_DENIED
;
3837 /* don't check if we removed it as it could be an un-mapped group */
3838 group_map_remove(alias_sid
);
3840 if (!close_policy_hnd(p
, &q_u
->alias_pol
))
3841 return NT_STATUS_OBJECT_NAME_INVALID
;
3843 return NT_STATUS_OK
;
3846 /*********************************************************************
3847 _samr_create_dom_group
3848 *********************************************************************/
3850 NTSTATUS
_samr_create_dom_group(pipes_struct
*p
, SAMR_Q_CREATE_DOM_GROUP
*q_u
, SAMR_R_CREATE_DOM_GROUP
*r_u
)
3857 struct samr_info
*info
;
3858 PRIVILEGE_SET priv_set
;
3862 init_privilege(&priv_set
);
3864 /* Find the policy handle. Open a policy on it. */
3865 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &dom_sid
, &acc_granted
))
3866 return NT_STATUS_INVALID_HANDLE
;
3868 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, DOMAIN_ACCESS_CREATE_GROUP
, "_samr_create_dom_group"))) {
3872 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
3873 return NT_STATUS_ACCESS_DENIED
;
3875 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3877 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
3879 /* check if group already exist */
3880 if ((grp
=getgrnam(name
)) != NULL
)
3881 return NT_STATUS_GROUP_EXISTS
;
3883 /* we can create the UNIX group */
3884 if (smb_create_group(name
, &gid
) != 0)
3885 return NT_STATUS_ACCESS_DENIED
;
3887 /* check if the group has been successfully created */
3888 if ((grp
=getgrgid(gid
)) == NULL
)
3889 return NT_STATUS_ACCESS_DENIED
;
3891 r_u
->rid
=pdb_gid_to_group_rid(grp
->gr_gid
);
3893 /* add the group to the mapping table */
3894 sid_copy(&info_sid
, get_global_sam_sid());
3895 sid_append_rid(&info_sid
, r_u
->rid
);
3896 sid_to_string(sid_string
, &info_sid
);
3898 if(!add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_DOM_GRP
, name
, NULL
, priv_set
, PR_ACCESS_FROM_NETWORK
))
3899 return NT_STATUS_ACCESS_DENIED
;
3901 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
3902 return NT_STATUS_NO_MEMORY
;
3904 /* get a (unique) handle. open a policy on it. */
3905 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
3906 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3908 return NT_STATUS_OK
;
3911 /*********************************************************************
3912 _samr_create_dom_alias
3913 *********************************************************************/
3915 NTSTATUS
_samr_create_dom_alias(pipes_struct
*p
, SAMR_Q_CREATE_DOM_ALIAS
*q_u
, SAMR_R_CREATE_DOM_ALIAS
*r_u
)
3922 struct samr_info
*info
;
3923 PRIVILEGE_SET priv_set
;
3927 init_privilege(&priv_set
);
3929 /* Find the policy handle. Open a policy on it. */
3930 if (!get_lsa_policy_samr_sid(p
, &q_u
->dom_pol
, &dom_sid
, &acc_granted
))
3931 return NT_STATUS_INVALID_HANDLE
;
3933 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, DOMAIN_ACCESS_CREATE_ALIAS
, "_samr_create_alias"))) {
3937 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
3938 return NT_STATUS_ACCESS_DENIED
;
3940 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3942 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
3944 /* check if group already exists */
3945 if ( (grp
=getgrnam(name
)) != NULL
)
3946 return NT_STATUS_GROUP_EXISTS
;
3948 /* we can create the UNIX group */
3949 if (smb_create_group(name
, &gid
) != 0)
3950 return NT_STATUS_ACCESS_DENIED
;
3952 /* check if the group has been successfully created */
3953 if ((grp
=getgrgid(gid
)) == NULL
)
3954 return NT_STATUS_ACCESS_DENIED
;
3956 r_u
->rid
=pdb_gid_to_group_rid(grp
->gr_gid
);
3958 sid_copy(&info_sid
, get_global_sam_sid());
3959 sid_append_rid(&info_sid
, r_u
->rid
);
3960 sid_to_string(sid_string
, &info_sid
);
3962 /* add the group to the mapping table */
3963 if(!add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_ALIAS
, name
, NULL
, priv_set
, PR_ACCESS_FROM_NETWORK
))
3964 return NT_STATUS_ACCESS_DENIED
;
3966 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
3967 return NT_STATUS_NO_MEMORY
;
3969 /* get a (unique) handle. open a policy on it. */
3970 if (!create_policy_hnd(p
, &r_u
->alias_pol
, free_samr_info
, (void *)info
))
3971 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3973 return NT_STATUS_OK
;
3976 /*********************************************************************
3977 _samr_query_groupinfo
3979 sends the name/comment pair of a domain group
3980 level 1 send also the number of users of that group
3981 *********************************************************************/
3983 NTSTATUS
_samr_query_groupinfo(pipes_struct
*p
, SAMR_Q_QUERY_GROUPINFO
*q_u
, SAMR_R_QUERY_GROUPINFO
*r_u
)
3989 GROUP_INFO_CTR
*ctr
;
3992 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
3993 return NT_STATUS_INVALID_HANDLE
;
3995 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, GROUP_ACCESS_LOOKUP_INFO
, "_samr_query_groupinfo"))) {
3999 if (!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITHOUT_PRIV
))
4000 return NT_STATUS_INVALID_HANDLE
;
4002 ctr
=(GROUP_INFO_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(GROUP_INFO_CTR
));
4004 return NT_STATUS_NO_MEMORY
;
4006 switch (q_u
->switch_level
) {
4008 ctr
->switch_value1
= 1;
4009 if(!get_uid_list_of_group(map
.gid
, &uid
, &num_uids
))
4010 return NT_STATUS_NO_SUCH_GROUP
;
4011 init_samr_group_info1(&ctr
->group
.info1
, map
.nt_name
, map
.comment
, num_uids
);
4015 ctr
->switch_value1
= 3;
4016 init_samr_group_info3(&ctr
->group
.info3
);
4019 ctr
->switch_value1
= 4;
4020 init_samr_group_info4(&ctr
->group
.info4
, map
.comment
);
4023 return NT_STATUS_INVALID_INFO_CLASS
;
4026 init_samr_r_query_groupinfo(r_u
, ctr
, NT_STATUS_OK
);
4028 return NT_STATUS_OK
;
4031 /*********************************************************************
4034 update a domain group's comment.
4035 *********************************************************************/
4037 NTSTATUS
_samr_set_groupinfo(pipes_struct
*p
, SAMR_Q_SET_GROUPINFO
*q_u
, SAMR_R_SET_GROUPINFO
*r_u
)
4041 GROUP_INFO_CTR
*ctr
;
4044 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
4045 return NT_STATUS_INVALID_HANDLE
;
4047 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, GROUP_ACCESS_SET_INFO
, "_samr_set_groupinfo"))) {
4051 if (!get_domain_group_from_sid(group_sid
, &map
, MAPPING_WITH_PRIV
))
4052 return NT_STATUS_NO_SUCH_GROUP
;
4056 switch (ctr
->switch_value1
) {
4058 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info1
.uni_acct_desc
), sizeof(map
.comment
)-1);
4061 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info4
.uni_acct_desc
), sizeof(map
.comment
)-1);
4064 free_privilege(&map
.priv_set
);
4065 return NT_STATUS_INVALID_INFO_CLASS
;
4068 if(!add_mapping_entry(&map
, TDB_REPLACE
)) {
4069 free_privilege(&map
.priv_set
);
4070 return NT_STATUS_NO_SUCH_GROUP
;
4073 free_privilege(&map
.priv_set
);
4075 return NT_STATUS_OK
;
4078 /*********************************************************************
4081 update an alias's comment.
4082 *********************************************************************/
4084 NTSTATUS
_samr_set_aliasinfo(pipes_struct
*p
, SAMR_Q_SET_ALIASINFO
*q_u
, SAMR_R_SET_ALIASINFO
*r_u
)
4088 ALIAS_INFO_CTR
*ctr
;
4091 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &group_sid
, &acc_granted
))
4092 return NT_STATUS_INVALID_HANDLE
;
4094 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, ALIAS_ACCESS_SET_INFO
, "_samr_set_aliasinfo"))) {
4098 if (!get_local_group_from_sid(group_sid
, &map
, MAPPING_WITH_PRIV
))
4099 return NT_STATUS_NO_SUCH_GROUP
;
4103 switch (ctr
->switch_value1
) {
4105 unistr2_to_ascii(map
.comment
, &(ctr
->alias
.info3
.uni_acct_desc
), sizeof(map
.comment
)-1);
4108 free_privilege(&map
.priv_set
);
4109 return NT_STATUS_INVALID_INFO_CLASS
;
4112 if(!add_mapping_entry(&map
, TDB_REPLACE
)) {
4113 free_privilege(&map
.priv_set
);
4114 return NT_STATUS_NO_SUCH_GROUP
;
4117 free_privilege(&map
.priv_set
);
4119 return NT_STATUS_OK
;
4122 /*********************************************************************
4123 _samr_get_dom_pwinfo
4124 *********************************************************************/
4126 NTSTATUS
_samr_get_dom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_DOM_PWINFO
*q_u
, SAMR_R_GET_DOM_PWINFO
*r_u
)
4128 /* Perform access check. Since this rpc does not require a
4129 policy handle it will not be caught by the access checks on
4130 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4132 if (!pipe_access_check(p
)) {
4133 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4134 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
4138 /* Actually, returning zeros here works quite well :-). */
4140 return NT_STATUS_OK
;
4143 /*********************************************************************
4145 *********************************************************************/
4147 NTSTATUS
_samr_open_group(pipes_struct
*p
, SAMR_Q_OPEN_GROUP
*q_u
, SAMR_R_OPEN_GROUP
*r_u
)
4152 struct samr_info
*info
;
4153 SEC_DESC
*psd
= NULL
;
4160 if (!get_lsa_policy_samr_sid(p
, &q_u
->domain_pol
, &sid
, &acc_granted
))
4161 return NT_STATUS_INVALID_HANDLE
;
4163 if (!NT_STATUS_IS_OK(status
= access_check_samr_function(acc_granted
, DOMAIN_ACCESS_OPEN_ACCOUNT
, "_samr_open_group"))) {
4167 /*check if access can be granted as requested by client. */
4168 samr_make_grp_obj_sd(p
->mem_ctx
, &psd
, &sd_size
);
4169 se_map_generic(&des_access
,&grp_generic_mapping
);
4170 if (!NT_STATUS_IS_OK(status
=
4171 access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
4172 des_access
, &acc_granted
, "_samr_open_group"))) {
4177 /* this should not be hard-coded like this */
4178 if (!sid_equal(&sid
, get_global_sam_sid()))
4179 return NT_STATUS_ACCESS_DENIED
;
4181 sid_copy(&info_sid
, get_global_sam_sid());
4182 sid_append_rid(&info_sid
, q_u
->rid_group
);
4183 sid_to_string(sid_string
, &info_sid
);
4185 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4186 return NT_STATUS_NO_MEMORY
;
4188 info
->acc_granted
= acc_granted
;
4190 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string
));
4192 /* check if that group really exists */
4193 if (!get_domain_group_from_sid(info
->sid
, &map
, MAPPING_WITHOUT_PRIV
))
4194 return NT_STATUS_NO_SUCH_GROUP
;
4196 /* get a (unique) handle. open a policy on it. */
4197 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
4198 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4200 return NT_STATUS_OK
;
4203 /*********************************************************************
4205 *********************************************************************/
4207 NTSTATUS
_samr_unknown_2d(pipes_struct
*p
, SAMR_Q_UNKNOWN_2D
*q_u
, SAMR_R_UNKNOWN_2D
*r_u
)
4209 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4210 return NT_STATUS_NOT_IMPLEMENTED
;
4213 /*******************************************************************
4215 ********************************************************************/
4217 NTSTATUS
_samr_unknown_2e(pipes_struct
*p
, SAMR_Q_UNKNOWN_2E
*q_u
, SAMR_R_UNKNOWN_2E
*r_u
)
4219 struct samr_info
*info
= NULL
;
4221 uint32 min_pass_len
,pass_hist
,flag
;
4222 time_t u_expire
, u_min_age
;
4223 NTTIME nt_expire
, nt_min_age
;
4225 time_t u_lock_duration
, u_reset_time
;
4226 NTTIME nt_lock_duration
, nt_reset_time
;
4232 uint32 num_users
=0, num_groups
=0, num_aliases
=0;
4234 uint32 account_policy_temp
;
4236 if ((ctr
= (SAM_UNK_CTR
*)talloc_zero(p
->mem_ctx
, sizeof(SAM_UNK_CTR
))) == NULL
)
4237 return NT_STATUS_NO_MEMORY
;
4241 r_u
->status
= NT_STATUS_OK
;
4243 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__
));
4245 /* find the policy handle. open a policy on it. */
4246 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
4247 return NT_STATUS_INVALID_HANDLE
;
4249 switch (q_u
->switch_value
) {
4251 account_policy_get(AP_MIN_PASSWORD_LEN
, &account_policy_temp
);
4252 min_pass_len
= account_policy_temp
;
4254 account_policy_get(AP_PASSWORD_HISTORY
, &account_policy_temp
);
4255 pass_hist
= account_policy_temp
;
4257 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS
, &account_policy_temp
);
4258 flag
= account_policy_temp
;
4260 account_policy_get(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
4261 u_expire
= account_policy_temp
;
4263 account_policy_get(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
4264 u_min_age
= account_policy_temp
;
4266 unix_to_nt_time_abs(&nt_expire
, u_expire
);
4267 unix_to_nt_time_abs(&nt_min_age
, u_min_age
);
4269 init_unk_info1(&ctr
->info
.inf1
, (uint16
)min_pass_len
, (uint16
)pass_hist
,
4270 flag
, nt_expire
, nt_min_age
);
4274 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
, False
);
4276 if (!NT_STATUS_IS_OK(r_u
->status
)) {
4277 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4280 num_users
=info
->disp_info
.num_user_account
;
4283 r_u
->status
=load_group_domain_entries(info
, get_global_sam_sid());
4284 if (NT_STATUS_IS_ERR(r_u
->status
)) {
4285 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4288 num_groups
=info
->disp_info
.num_group_account
;
4291 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4292 init_unk_info2(&ctr
->info
.inf2
, global_myworkgroup
, global_myname
, (uint32
) time(NULL
),
4293 num_users
, num_groups
, num_aliases
);
4296 account_policy_get(AP_TIME_TO_LOGOUT
, &account_policy_temp
);
4297 u_logout
= account_policy_temp
;
4299 unix_to_nt_time_abs(&nt_logout
, u_logout
);
4301 init_unk_info3(&ctr
->info
.inf3
, nt_logout
);
4304 init_unk_info5(&ctr
->info
.inf5
, global_myname
);
4307 init_unk_info6(&ctr
->info
.inf6
);
4310 init_unk_info7(&ctr
->info
.inf7
);
4313 account_policy_get(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
4314 u_lock_duration
= account_policy_temp
;
4316 account_policy_get(AP_RESET_COUNT_TIME
, &account_policy_temp
);
4317 u_reset_time
= account_policy_temp
;
4319 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
4320 lockout
= account_policy_temp
;
4322 unix_to_nt_time_abs(&nt_lock_duration
, u_lock_duration
);
4323 unix_to_nt_time_abs(&nt_reset_time
, u_reset_time
);
4325 init_unk_info12(&ctr
->info
.inf12
, nt_lock_duration
, nt_reset_time
, (uint16
)lockout
);
4328 return NT_STATUS_INVALID_INFO_CLASS
;
4331 init_samr_r_samr_unknown_2e(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_OK
);
4333 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__
));
4338 /*******************************************************************
4340 ********************************************************************/
4342 NTSTATUS
_samr_set_dom_info(pipes_struct
*p
, SAMR_Q_SET_DOMAIN_INFO
*q_u
, SAMR_R_SET_DOMAIN_INFO
*r_u
)
4344 time_t u_expire
, u_min_age
;
4346 time_t u_lock_duration
, u_reset_time
;
4348 r_u
->status
= NT_STATUS_OK
;
4350 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__
));
4352 /* find the policy handle. open a policy on it. */
4353 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, NULL
))
4354 return NT_STATUS_INVALID_HANDLE
;
4356 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u
->switch_value
));
4358 switch (q_u
->switch_value
) {
4360 u_expire
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf1
.expire
);
4361 u_min_age
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf1
.min_passwordage
);
4363 account_policy_set(AP_MIN_PASSWORD_LEN
, (uint32
)q_u
->ctr
->info
.inf1
.min_length_password
);
4364 account_policy_set(AP_PASSWORD_HISTORY
, (uint32
)q_u
->ctr
->info
.inf1
.password_history
);
4365 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS
, (uint32
)q_u
->ctr
->info
.inf1
.flag
);
4366 account_policy_set(AP_MAX_PASSWORD_AGE
, (int)u_expire
);
4367 account_policy_set(AP_MIN_PASSWORD_AGE
, (int)u_min_age
);
4372 u_logout
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf3
.logout
);
4373 account_policy_set(AP_TIME_TO_LOGOUT
, (int)u_logout
);
4382 u_lock_duration
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf12
.duration
);
4383 u_reset_time
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf12
.reset_count
);
4385 account_policy_set(AP_LOCK_ACCOUNT_DURATION
, (int)u_lock_duration
);
4386 account_policy_set(AP_RESET_COUNT_TIME
, (int)u_reset_time
);
4387 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT
, (uint32
)q_u
->ctr
->info
.inf12
.bad_attempt_lockout
);
4390 return NT_STATUS_INVALID_INFO_CLASS
;
4393 init_samr_r_set_domain_info(r_u
, NT_STATUS_OK
);
4395 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__
));