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) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
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 #define SAMR_USR_RIGHTS_WRITE_PW \
38 ( READ_CONTROL_ACCESS | \
39 SA_RIGHT_USER_CHANGE_PASSWORD | \
40 SA_RIGHT_USER_SET_LOC_COM )
42 extern DOM_SID global_sid_Builtin
;
44 extern rid_name domain_group_rids
[];
45 extern rid_name domain_alias_rids
[];
46 extern rid_name builtin_alias_rids
[];
49 typedef struct _disp_info
{
51 uint32 num_user_account
;
52 SAM_ACCOUNT
*disp_user_info
;
54 uint32 num_group_account
;
55 DOMAIN_GRP
*disp_group_info
;
59 /* for use by the \PIPE\samr policy */
61 uint32 status
; /* some sort of flag. best to record it. comes from opnum 0x39 */
70 struct generic_mapping sam_generic_mapping
= {GENERIC_RIGHTS_SAM_READ
, GENERIC_RIGHTS_SAM_WRITE
, GENERIC_RIGHTS_SAM_EXECUTE
, GENERIC_RIGHTS_SAM_ALL_ACCESS
};
71 struct generic_mapping dom_generic_mapping
= {GENERIC_RIGHTS_DOMAIN_READ
, GENERIC_RIGHTS_DOMAIN_WRITE
, GENERIC_RIGHTS_DOMAIN_EXECUTE
, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS
};
72 struct generic_mapping usr_generic_mapping
= {GENERIC_RIGHTS_USER_READ
, GENERIC_RIGHTS_USER_WRITE
, GENERIC_RIGHTS_USER_EXECUTE
, GENERIC_RIGHTS_USER_ALL_ACCESS
};
73 struct generic_mapping grp_generic_mapping
= {GENERIC_RIGHTS_GROUP_READ
, GENERIC_RIGHTS_GROUP_WRITE
, GENERIC_RIGHTS_GROUP_EXECUTE
, GENERIC_RIGHTS_GROUP_ALL_ACCESS
};
74 struct generic_mapping ali_generic_mapping
= {GENERIC_RIGHTS_ALIAS_READ
, GENERIC_RIGHTS_ALIAS_WRITE
, GENERIC_RIGHTS_ALIAS_EXECUTE
, GENERIC_RIGHTS_ALIAS_ALL_ACCESS
};
76 /*******************************************************************
77 *******************************************************************/
79 static NTSTATUS
make_samr_object_sd( TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
,
80 struct generic_mapping
*map
,
81 DOM_SID
*sid
, uint32 sid_access
)
83 extern DOM_SID global_sid_World
;
84 DOM_SID adm_sid
, act_sid
, domadmin_sid
;
85 SEC_ACE ace
[5]; /* at most 5 entries */
91 /* basic access for Everyone */
93 init_sec_access(&mask
, map
->generic_execute
| map
->generic_read
);
94 init_sec_ace(&ace
[i
++], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
96 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
98 sid_copy(&adm_sid
, &global_sid_Builtin
);
99 sid_append_rid(&adm_sid
, BUILTIN_ALIAS_RID_ADMINS
);
101 sid_copy(&act_sid
, &global_sid_Builtin
);
102 sid_append_rid(&act_sid
, BUILTIN_ALIAS_RID_ACCOUNT_OPS
);
104 init_sec_access(&mask
, map
->generic_all
);
106 init_sec_ace(&ace
[i
++], &adm_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
107 init_sec_ace(&ace
[i
++], &act_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
109 /* Add Full Access for Domain Admins if we are a DC */
112 sid_copy( &domadmin_sid
, get_global_sam_sid() );
113 sid_append_rid( &domadmin_sid
, DOMAIN_GROUP_RID_ADMINS
);
114 init_sec_ace(&ace
[i
++], &domadmin_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
117 /* if we have a sid, give it some special access */
120 init_sec_access( &mask
, sid_access
);
121 init_sec_ace(&ace
[i
++], sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, mask
, 0);
124 /* create the security descriptor */
126 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, i
, ace
)) == NULL
)
127 return NT_STATUS_NO_MEMORY
;
129 if ((*psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
, SEC_DESC_SELF_RELATIVE
, NULL
, NULL
, NULL
, psa
, sd_size
)) == NULL
)
130 return NT_STATUS_NO_MEMORY
;
135 /*******************************************************************
136 Checks if access to an object should be granted, and returns that
137 level of access for further checks.
138 ********************************************************************/
140 static NTSTATUS
access_check_samr_object( SEC_DESC
*psd
, NT_USER_TOKEN
*token
,
141 SE_PRIV
*rights
, uint32 rights_mask
,
142 uint32 des_access
, uint32
*acc_granted
,
145 NTSTATUS status
= NT_STATUS_ACCESS_DENIED
;
146 uint32 saved_mask
= 0;
148 /* check privileges; certain SAM access bits should be overridden
149 by privileges (mostly having to do with creating/modifying/deleting
152 if ( rights
&& user_has_any_privilege( token
, rights
) ) {
154 saved_mask
= (des_access
& rights_mask
);
155 des_access
&= ~saved_mask
;
157 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
162 /* check the security descriptor first */
164 if ( se_access_check(psd
, token
, des_access
, acc_granted
, &status
) )
167 /* give root a free pass */
169 if ( geteuid() == sec_initial_uid() ) {
171 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug
, des_access
));
172 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
174 *acc_granted
= des_access
;
176 status
= NT_STATUS_OK
;
182 /* add in any bits saved during the privilege check (only
183 matters is status is ok) */
185 *acc_granted
|= rights_mask
;
187 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
188 debug
, NT_STATUS_IS_OK(status
) ? "GRANTED" : "DENIED",
189 des_access
, *acc_granted
));
194 /*******************************************************************
195 Checks if access to a function can be granted
196 ********************************************************************/
198 static NTSTATUS
access_check_samr_function(uint32 acc_granted
, uint32 acc_required
, const char *debug
)
200 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
201 debug
, acc_granted
, acc_required
));
203 /* check the security descriptor first */
205 if ( (acc_granted
&acc_required
) == acc_required
)
208 /* give root a free pass */
210 if (geteuid() == sec_initial_uid()) {
212 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
213 debug
, acc_granted
, acc_required
));
214 DEBUGADD(4,("but overwritten by euid == 0\n"));
219 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
220 debug
, acc_granted
, acc_required
));
222 return NT_STATUS_ACCESS_DENIED
;
226 /*******************************************************************
227 Create a samr_info struct.
228 ********************************************************************/
230 static struct samr_info
*get_samr_info_by_sid(DOM_SID
*psid
)
232 struct samr_info
*info
;
237 sid_to_string(sid_str
, psid
);
239 fstrcpy(sid_str
,"(NULL)");
242 mem_ctx
= talloc_init("samr_info for domain sid %s", sid_str
);
244 if ((info
= TALLOC_P(mem_ctx
, struct samr_info
)) == NULL
)
248 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str
));
250 sid_copy( &info
->sid
, psid
);
252 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
254 info
->mem_ctx
= mem_ctx
;
258 /*******************************************************************
259 Function to free the per handle data.
260 ********************************************************************/
262 static void free_samr_users(struct samr_info
*info
)
266 if (info
->disp_info
.user_dbloaded
){
267 for (i
=0; i
<info
->disp_info
.num_user_account
; i
++) {
268 SAM_ACCOUNT
*sam
= &info
->disp_info
.disp_user_info
[i
];
269 /* Not really a free, actually a 'clear' */
273 info
->disp_info
.user_dbloaded
=False
;
274 info
->disp_info
.num_user_account
=0;
277 /*******************************************************************
278 Function to free the per handle data.
279 ********************************************************************/
281 static void free_samr_db(struct samr_info
*info
)
283 /* Groups are talloced */
285 free_samr_users(info
);
287 info
->disp_info
.group_dbloaded
=False
;
288 info
->disp_info
.num_group_account
=0;
291 static void free_samr_info(void *ptr
)
293 struct samr_info
*info
=(struct samr_info
*) ptr
;
296 talloc_destroy(info
->mem_ctx
);
299 /*******************************************************************
300 Ensure password info is never given out. Paranioa... JRA.
301 ********************************************************************/
303 static void samr_clear_sam_passwd(SAM_ACCOUNT
*sam_pass
)
309 /* These now zero out the old password */
311 pdb_set_lanman_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
312 pdb_set_nt_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
316 static NTSTATUS
load_sampwd_entries(struct samr_info
*info
, uint16 acb_mask
, BOOL only_machines
)
318 SAM_ACCOUNT
*pwd
= NULL
;
319 SAM_ACCOUNT
*pwd_array
= NULL
;
320 NTSTATUS nt_status
= NT_STATUS_OK
;
321 TALLOC_CTX
*mem_ctx
= info
->mem_ctx
;
322 uint16 query_acb_mask
= acb_mask
;
324 DEBUG(10,("load_sampwd_entries\n"));
326 /* if the snapshoot is already loaded, return */
327 if ((info
->disp_info
.user_dbloaded
==True
)
328 && (info
->acb_mask
== acb_mask
)
329 && (info
->only_machines
== only_machines
)) {
330 DEBUG(10,("load_sampwd_entries: already in memory\n"));
334 free_samr_users(info
);
337 query_acb_mask
|= ACB_WSTRUST
;
338 query_acb_mask
|= ACB_SVRTRUST
;
341 if (!pdb_setsampwent(False
, query_acb_mask
)) {
342 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
343 return NT_STATUS_ACCESS_DENIED
;
346 for (; (NT_STATUS_IS_OK(nt_status
= pdb_init_sam_talloc(mem_ctx
, &pwd
)))
347 && pdb_getsampwent(pwd
) == True
; pwd
=NULL
) {
350 if (!((pdb_get_acct_ctrl(pwd
) & ACB_WSTRUST
)
351 || (pdb_get_acct_ctrl(pwd
) & ACB_SVRTRUST
))) {
352 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd
), acb_mask
));
357 if (acb_mask
!= 0 && !(pdb_get_acct_ctrl(pwd
) & acb_mask
)) {
359 DEBUG(5,(" acb_mask %x reject\n", acb_mask
));
364 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
365 if (info
->disp_info
.num_user_account
% MAX_SAM_ENTRIES
== 0) {
367 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
368 pwd_array
=TALLOC_REALLOC_ARRAY(mem_ctx
, info
->disp_info
.disp_user_info
, SAM_ACCOUNT
,
369 info
->disp_info
.num_user_account
+MAX_SAM_ENTRIES
);
372 return NT_STATUS_NO_MEMORY
;
374 info
->disp_info
.disp_user_info
=pwd_array
;
377 /* Copy the SAM_ACCOUNT into the array */
378 info
->disp_info
.disp_user_info
[info
->disp_info
.num_user_account
]=*pwd
;
380 DEBUG(10,("load_sampwd_entries: entry: %d\n", info
->disp_info
.num_user_account
));
382 info
->disp_info
.num_user_account
++;
387 /* the snapshoot is in memory, we're ready to enumerate fast */
389 info
->acb_mask
= acb_mask
;
390 info
->only_machines
= only_machines
;
391 info
->disp_info
.user_dbloaded
=True
;
393 DEBUG(10,("load_sampwd_entries: done\n"));
398 static NTSTATUS
load_group_domain_entries(struct samr_info
*info
, DOM_SID
*sid
)
401 DOMAIN_GRP
*grp_array
= NULL
;
402 uint32 group_entries
= 0;
404 TALLOC_CTX
*mem_ctx
= info
->mem_ctx
;
407 DEBUG(10,("load_group_domain_entries\n"));
409 /* if the snapshoot is already loaded, return */
410 if (info
->disp_info
.group_dbloaded
==True
) {
411 DEBUG(10,("load_group_domain_entries: already in memory\n"));
415 if (sid_equal(sid
, &global_sid_Builtin
)) {
416 /* No domain groups for now in the BUILTIN domain */
417 info
->disp_info
.num_group_account
=0;
418 info
->disp_info
.disp_group_info
=NULL
;
419 info
->disp_info
.group_dbloaded
=True
;
424 ret
= pdb_enum_group_mapping(SID_NAME_DOM_GRP
, &map
, (int *)&group_entries
, ENUM_ONLY_MAPPED
);
428 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
429 return NT_STATUS_NO_MEMORY
;
433 info
->disp_info
.num_group_account
=group_entries
;
435 grp_array
=TALLOC_ARRAY(mem_ctx
, DOMAIN_GRP
, info
->disp_info
.num_group_account
);
436 if (group_entries
!=0 && grp_array
==NULL
) {
437 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
439 return NT_STATUS_NO_MEMORY
;
442 info
->disp_info
.disp_group_info
=grp_array
;
444 for (i
=0; i
<group_entries
; i
++) {
445 fstrcpy(grp_array
[i
].name
, map
[i
].nt_name
);
446 fstrcpy(grp_array
[i
].comment
, map
[i
].comment
);
447 sid_split_rid(&map
[i
].sid
, &grp_array
[i
].rid
);
448 grp_array
[i
].attr
=SID_NAME_DOM_GRP
;
453 /* the snapshoot is in memory, we're ready to enumerate fast */
455 info
->disp_info
.group_dbloaded
=True
;
457 DEBUG(10,("load_group_domain_entries: done\n"));
463 /*******************************************************************
465 ********************************************************************/
467 NTSTATUS
_samr_close_hnd(pipes_struct
*p
, SAMR_Q_CLOSE_HND
*q_u
, SAMR_R_CLOSE_HND
*r_u
)
469 r_u
->status
= NT_STATUS_OK
;
471 /* close the policy handle */
472 if (!close_policy_hnd(p
, &q_u
->pol
))
473 return NT_STATUS_OBJECT_NAME_INVALID
;
475 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__
));
480 /*******************************************************************
481 samr_reply_open_domain
482 ********************************************************************/
484 NTSTATUS
_samr_open_domain(pipes_struct
*p
, SAMR_Q_OPEN_DOMAIN
*q_u
, SAMR_R_OPEN_DOMAIN
*r_u
)
486 struct samr_info
*info
;
487 SEC_DESC
*psd
= NULL
;
489 uint32 des_access
= q_u
->flags
;
494 r_u
->status
= NT_STATUS_OK
;
496 /* find the connection policy handle. */
498 if ( !find_policy_by_hnd(p
, &q_u
->pol
, (void**)&info
) )
499 return NT_STATUS_INVALID_HANDLE
;
501 status
= access_check_samr_function( info
->acc_granted
,
502 SA_RIGHT_SAM_OPEN_DOMAIN
, "_samr_open_domain" );
504 if ( !NT_STATUS_IS_OK(status
) )
507 /*check if access can be granted as requested by client. */
509 make_samr_object_sd( p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0 );
510 se_map_generic( &des_access
, &dom_generic_mapping
);
512 se_priv_copy( &se_rights
, &se_machine_account
);
513 se_priv_add( &se_rights
, &se_add_users
);
515 status
= access_check_samr_object( psd
, p
->pipe_user
.nt_user_token
,
516 &se_rights
, GENERIC_RIGHTS_DOMAIN_WRITE
, des_access
,
517 &acc_granted
, "_samr_open_domain" );
519 if ( !NT_STATUS_IS_OK(status
) )
522 /* associate the domain SID with the (unique) handle. */
523 if ((info
= get_samr_info_by_sid(&q_u
->dom_sid
.sid
))==NULL
)
524 return NT_STATUS_NO_MEMORY
;
525 info
->acc_granted
= acc_granted
;
527 /* get a (unique) handle. open a policy on it. */
528 if (!create_policy_hnd(p
, &r_u
->domain_pol
, free_samr_info
, (void *)info
))
529 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
531 DEBUG(5,("samr_open_domain: %d\n", __LINE__
));
536 /*******************************************************************
537 _samr_get_usrdom_pwinfo
538 ********************************************************************/
540 NTSTATUS
_samr_get_usrdom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_USRDOM_PWINFO
*q_u
, SAMR_R_GET_USRDOM_PWINFO
*r_u
)
542 struct samr_info
*info
= NULL
;
544 r_u
->status
= NT_STATUS_OK
;
546 /* find the policy handle. open a policy on it. */
547 if (!find_policy_by_hnd(p
, &q_u
->user_pol
, (void **)&info
))
548 return NT_STATUS_INVALID_HANDLE
;
550 if (!sid_check_is_in_our_domain(&info
->sid
))
551 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
553 init_samr_r_get_usrdom_pwinfo(r_u
, NT_STATUS_OK
);
555 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__
));
558 * NT sometimes return NT_STATUS_ACCESS_DENIED
559 * I don't know yet why.
566 /*******************************************************************
568 ********************************************************************/
570 NTSTATUS
_samr_set_sec_obj(pipes_struct
*p
, SAMR_Q_SET_SEC_OBJ
*q_u
, SAMR_R_SET_SEC_OBJ
*r_u
)
572 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
573 return NT_STATUS_NOT_IMPLEMENTED
;
577 /*******************************************************************
578 ********************************************************************/
580 static BOOL
get_lsa_policy_samr_sid( pipes_struct
*p
, POLICY_HND
*pol
,
581 DOM_SID
*sid
, uint32
*acc_granted
)
583 struct samr_info
*info
= NULL
;
585 /* find the policy handle. open a policy on it. */
586 if (!find_policy_by_hnd(p
, pol
, (void **)&info
))
593 *acc_granted
= info
->acc_granted
;
597 /*******************************************************************
599 ********************************************************************/
601 NTSTATUS
_samr_query_sec_obj(pipes_struct
*p
, SAMR_Q_QUERY_SEC_OBJ
*q_u
, SAMR_R_QUERY_SEC_OBJ
*r_u
)
605 SEC_DESC
* psd
= NULL
;
609 r_u
->status
= NT_STATUS_OK
;
612 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &pol_sid
, &acc_granted
))
613 return NT_STATUS_INVALID_HANDLE
;
617 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
619 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
621 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
622 if (pol_sid
.sid_rev_num
== 0)
624 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
625 r_u
->status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
627 else if (sid_equal(&pol_sid
,get_global_sam_sid())) /* check if it is our domain SID */
630 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
631 r_u
->status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0);
633 else if (sid_equal(&pol_sid
,&global_sid_Builtin
)) /* check if it is the Builtin Domain */
635 /* TODO: Builtin probably needs a different SD with restricted write access*/
636 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
637 r_u
->status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0);
639 else if (sid_check_is_in_our_domain(&pol_sid
) ||
640 sid_check_is_in_builtin(&pol_sid
))
642 /* TODO: different SDs have to be generated for aliases groups and users.
643 Currently all three get a default user SD */
644 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid
, &pol_sid
)));
645 r_u
->status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
, &pol_sid
, SAMR_USR_RIGHTS_WRITE_PW
);
647 else return NT_STATUS_OBJECT_TYPE_MISMATCH
;
649 if ((r_u
->buf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
650 return NT_STATUS_NO_MEMORY
;
652 if (NT_STATUS_IS_OK(r_u
->status
))
658 /*******************************************************************
659 makes a SAM_ENTRY / UNISTR2* structure from a user list.
660 ********************************************************************/
662 static NTSTATUS
make_user_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
663 uint32 num_entries
, uint32 start_idx
, SAM_ACCOUNT
*disp_user_info
,
669 SAM_ACCOUNT
*pwd
= NULL
;
670 UNISTR2 uni_temp_name
;
671 const char *temp_name
;
672 const DOM_SID
*user_sid
;
674 fstring user_sid_string
;
675 fstring domain_sid_string
;
680 if (num_entries
== 0)
683 sam
= TALLOC_ZERO_ARRAY(ctx
, SAM_ENTRY
, num_entries
);
685 uni_name
= TALLOC_ZERO_ARRAY(ctx
, UNISTR2
, num_entries
);
687 if (sam
== NULL
|| uni_name
== NULL
) {
688 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
689 return NT_STATUS_NO_MEMORY
;
692 for (i
= 0; i
< num_entries
; i
++) {
693 pwd
= &disp_user_info
[i
+start_idx
];
694 temp_name
= pdb_get_username(pwd
);
697 * usrmgr expects a non-NULL terminated string with
698 * trust relationships
700 if (pdb_get_acct_ctrl(pwd
) & ACB_DOMTRUST
) {
701 init_unistr2(&uni_temp_name
, temp_name
, UNI_FLAGS_NONE
);
703 init_unistr2(&uni_temp_name
, temp_name
, UNI_STR_TERMINATE
);
706 user_sid
= pdb_get_user_sid(pwd
);
708 if (!sid_peek_check_rid(domain_sid
, user_sid
, &user_rid
)) {
709 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
710 "the domain sid %s. Failing operation.\n",
712 sid_to_string(user_sid_string
, user_sid
),
713 sid_to_string(domain_sid_string
, domain_sid
)));
714 return NT_STATUS_UNSUCCESSFUL
;
717 init_sam_entry(&sam
[i
], &uni_temp_name
, user_rid
);
718 copy_unistr2(&uni_name
[i
], &uni_temp_name
);
722 *uni_name_pp
= uni_name
;
726 /*******************************************************************
727 samr_reply_enum_dom_users
728 ********************************************************************/
730 NTSTATUS
_samr_enum_dom_users(pipes_struct
*p
, SAMR_Q_ENUM_DOM_USERS
*q_u
,
731 SAMR_R_ENUM_DOM_USERS
*r_u
)
733 struct samr_info
*info
= NULL
;
734 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
736 uint32 enum_context
=q_u
->start_idx
;
737 uint32 max_size
=q_u
->max_size
;
739 enum remote_arch_types ra_type
= get_remote_arch();
740 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
741 uint32 max_entries
= max_sam_entries
;
744 r_u
->status
= NT_STATUS_OK
;
746 /* find the policy handle. open a policy on it. */
747 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
748 return NT_STATUS_INVALID_HANDLE
;
750 domain_sid
= info
->sid
;
752 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
,
753 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
,
754 "_samr_enum_dom_users"))) {
758 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
761 r_u
->status
=load_sampwd_entries(info
, q_u
->acb_mask
, False
);
764 if (!NT_STATUS_IS_OK(r_u
->status
))
767 num_account
= info
->disp_info
.num_user_account
;
769 if (enum_context
> num_account
) {
770 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
774 /* verify we won't overflow */
775 if (max_entries
> num_account
-enum_context
) {
776 max_entries
= num_account
-enum_context
;
777 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries
));
780 /* calculate the size and limit on the number of entries we will return */
781 temp_size
=max_entries
*struct_size
;
783 if (temp_size
>max_size
) {
784 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
785 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries
));
789 * Note from JRA. total_entries is not being used here. Currently if there is a
790 * large user base then it looks like NT will enumerate until get_sampwd_entries
791 * returns False due to num_entries being zero. This will cause an access denied
792 * return. I don't think this is right and needs further investigation. Note that
793 * this is also the same in the TNG code (I don't think that has been tested with
794 * a very large user list as MAX_SAM_ENTRIES is set to 600).
796 * I also think that one of the 'num_entries' return parameters is probably
797 * the "max entries" parameter - but in the TNG code they're all currently set to the same
798 * value (again I think this is wrong).
801 r_u
->status
= make_user_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_acct_name
,
802 max_entries
, enum_context
,
803 info
->disp_info
.disp_user_info
,
806 if (!NT_STATUS_IS_OK(r_u
->status
))
809 if (enum_context
+max_entries
< num_account
)
810 r_u
->status
= STATUS_MORE_ENTRIES
;
812 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__
));
814 init_samr_r_enum_dom_users(r_u
, q_u
->start_idx
+ max_entries
, max_entries
);
816 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__
));
821 /*******************************************************************
822 makes a SAM_ENTRY / UNISTR2* structure from a group list.
823 ********************************************************************/
825 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
, SAM_ENTRY
**sam_pp
, UNISTR2
**uni_name_pp
,
826 uint32 num_sam_entries
, DOMAIN_GRP
*grp
)
835 if (num_sam_entries
== 0)
838 sam
= TALLOC_ZERO_ARRAY(ctx
, SAM_ENTRY
, num_sam_entries
);
839 uni_name
= TALLOC_ZERO_ARRAY(ctx
, UNISTR2
, num_sam_entries
);
841 if (sam
== NULL
|| uni_name
== NULL
) {
842 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
846 for (i
= 0; i
< num_sam_entries
; i
++) {
848 * JRA. I think this should include the null. TNG does not.
850 init_unistr2(&uni_name
[i
], grp
[i
].name
, UNI_STR_TERMINATE
);
851 init_sam_entry(&sam
[i
], &uni_name
[i
], grp
[i
].rid
);
855 *uni_name_pp
= uni_name
;
858 /*******************************************************************
859 Get the group entries - similar to get_sampwd_entries().
860 ******************************************************************/
862 static NTSTATUS
get_group_domain_entries( TALLOC_CTX
*ctx
,
863 DOMAIN_GRP
**d_grp
, DOM_SID
*sid
, uint32 start_idx
,
864 uint32
*p_num_entries
, uint32 max_entries
)
868 uint32 group_entries
= 0;
869 uint32 num_entries
= 0;
873 /* access checks for the users were performed higher up. become/unbecome_root()
874 needed for some passdb backends to enumerate groups */
877 pdb_enum_group_mapping(SID_NAME_DOM_GRP
, &map
, (int *)&group_entries
,
881 num_entries
=group_entries
-start_idx
;
883 /* limit the number of entries */
884 if (num_entries
>max_entries
) {
885 DEBUG(5,("Limiting to %d entries\n", max_entries
));
886 num_entries
=max_entries
;
889 *d_grp
=TALLOC_ZERO_ARRAY(ctx
, DOMAIN_GRP
, num_entries
);
890 if (num_entries
!=0 && *d_grp
==NULL
){
892 return NT_STATUS_NO_MEMORY
;
895 for (i
=0; i
<num_entries
; i
++) {
896 fstrcpy((*d_grp
)[i
].name
, map
[i
+start_idx
].nt_name
);
897 fstrcpy((*d_grp
)[i
].comment
, map
[i
+start_idx
].comment
);
898 sid_split_rid(&map
[i
+start_idx
].sid
, &(*d_grp
)[i
].rid
);
899 (*d_grp
)[i
].attr
=SID_NAME_DOM_GRP
;
904 *p_num_entries
= num_entries
;
906 DEBUG(10,("get_group_domain_entries: returning %d entries\n",
912 /*******************************************************************
913 Wrapper for enumerating local groups
914 ******************************************************************/
916 static NTSTATUS
get_alias_entries( TALLOC_CTX
*ctx
, DOMAIN_GRP
**d_grp
,
917 const DOM_SID
*sid
, uint32 start_idx
,
918 uint32
*p_num_entries
, uint32 max_entries
)
920 struct acct_info
*info
;
925 res
= pdb_enum_aliases(sid
, start_idx
, max_entries
,
926 p_num_entries
, &info
);
930 return NT_STATUS_ACCESS_DENIED
;
932 if (*p_num_entries
== 0)
935 *d_grp
= TALLOC_ARRAY(ctx
, DOMAIN_GRP
, *p_num_entries
);
937 if (*d_grp
== NULL
) {
939 return NT_STATUS_NO_MEMORY
;
942 for (i
=0; i
<*p_num_entries
; i
++) {
943 fstrcpy((*d_grp
)[i
].name
, info
[i
].acct_name
);
944 fstrcpy((*d_grp
)[i
].comment
, info
[i
].acct_desc
);
945 (*d_grp
)[i
].rid
= info
[i
].rid
;
946 (*d_grp
)[i
].attr
= SID_NAME_ALIAS
;
953 /*******************************************************************
954 samr_reply_enum_dom_groups
955 ********************************************************************/
957 NTSTATUS
_samr_enum_dom_groups(pipes_struct
*p
, SAMR_Q_ENUM_DOM_GROUPS
*q_u
, SAMR_R_ENUM_DOM_GROUPS
*r_u
)
959 DOMAIN_GRP
*grp
=NULL
;
964 r_u
->status
= NT_STATUS_OK
;
966 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
967 return NT_STATUS_INVALID_HANDLE
;
969 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
, "_samr_enum_dom_groups"))) {
973 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__
));
975 /* the domain group array is being allocated in the function below */
976 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
))) {
980 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
982 init_samr_r_enum_dom_groups(r_u
, q_u
->start_idx
, num_entries
);
984 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__
));
990 /*******************************************************************
991 samr_reply_enum_dom_aliases
992 ********************************************************************/
994 NTSTATUS
_samr_enum_dom_aliases(pipes_struct
*p
, SAMR_Q_ENUM_DOM_ALIASES
*q_u
, SAMR_R_ENUM_DOM_ALIASES
*r_u
)
996 DOMAIN_GRP
*grp
=NULL
;
997 uint32 num_entries
= 0;
1003 r_u
->status
= NT_STATUS_OK
;
1005 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
1006 return NT_STATUS_INVALID_HANDLE
;
1008 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS
, "_samr_enum_dom_aliases"))) {
1012 sid_to_string(sid_str
, &sid
);
1013 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str
));
1015 status
= get_alias_entries(p
->mem_ctx
, &grp
, &sid
, q_u
->start_idx
,
1016 &num_entries
, MAX_SAM_ENTRIES
);
1017 if (!NT_STATUS_IS_OK(status
)) return status
;
1019 make_group_sam_entry_list(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_grp_name
, num_entries
, grp
);
1023 init_samr_r_enum_dom_aliases(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
1025 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__
));
1030 /*******************************************************************
1031 samr_reply_query_dispinfo
1032 ********************************************************************/
1034 NTSTATUS
_samr_query_dispinfo(pipes_struct
*p
, SAMR_Q_QUERY_DISPINFO
*q_u
,
1035 SAMR_R_QUERY_DISPINFO
*r_u
)
1037 struct samr_info
*info
= NULL
;
1038 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
1040 uint32 max_entries
=q_u
->max_entries
;
1041 uint32 enum_context
=q_u
->start_idx
;
1042 uint32 max_size
=q_u
->max_size
;
1044 SAM_DISPINFO_CTR
*ctr
;
1045 uint32 temp_size
=0, total_data_size
=0;
1047 uint32 num_account
= 0;
1048 enum remote_arch_types ra_type
= get_remote_arch();
1049 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
1052 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__
));
1053 r_u
->status
= NT_STATUS_OK
;
1055 /* find the policy handle. open a policy on it. */
1056 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
1057 return NT_STATUS_INVALID_HANDLE
;
1059 domain_sid
= info
->sid
;
1062 * calculate how many entries we will return.
1064 * - the number of entries the client asked
1065 * - our limit on that
1066 * - the starting point (enumeration context)
1067 * - the buffer size the client will accept
1071 * We are a lot more like W2K. Instead of reading the SAM
1072 * each time to find the records we need to send back,
1073 * we read it once and link that copy to the sam handle.
1074 * For large user list (over the MAX_SAM_ENTRIES)
1075 * it's a definitive win.
1076 * second point to notice: between enumerations
1077 * our sam is now the same as it's a snapshoot.
1078 * third point: got rid of the static SAM_USER_21 struct
1079 * no more intermediate.
1080 * con: it uses much more memory, as a full copy is stored
1083 * If you want to change it, think twice and think
1084 * of the second point , that's really important.
1089 /* Get what we need from the password database */
1090 switch (q_u
->switch_level
) {
1092 /* When playing with usrmgr, this is necessary
1093 if you want immediate refresh after editing
1094 a user. I would like to do this after the
1095 setuserinfo2, but we do not have access to
1096 the domain handle in that call, only to the
1097 user handle. Where else does this hurt?
1101 /* We cannot do this here - it kills performace. JRA. */
1102 free_samr_users(info
);
1107 /* Level 2 is for all machines, otherwise only 'normal' users */
1108 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
, q_u
->switch_level
==2);
1110 if (!NT_STATUS_IS_OK(r_u
->status
)) {
1111 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1114 num_account
= info
->disp_info
.num_user_account
;
1118 r_u
->status
= load_group_domain_entries(info
, &info
->sid
);
1119 if (!NT_STATUS_IS_OK(r_u
->status
))
1121 num_account
= info
->disp_info
.num_group_account
;
1124 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u
->switch_level
));
1125 return NT_STATUS_INVALID_INFO_CLASS
;
1128 /* first limit the number of entries we will return */
1129 if(max_entries
> max_sam_entries
) {
1130 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries
, max_sam_entries
));
1131 max_entries
= max_sam_entries
;
1134 if (enum_context
> num_account
) {
1135 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1136 return NT_STATUS_NO_MORE_ENTRIES
;
1139 /* verify we won't overflow */
1140 if (max_entries
> num_account
-enum_context
) {
1141 max_entries
= num_account
-enum_context
;
1142 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries
));
1145 /* calculate the size and limit on the number of entries we will return */
1146 temp_size
=max_entries
*struct_size
;
1148 if (temp_size
>max_size
) {
1149 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
1150 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries
));
1153 if (!(ctr
= TALLOC_ZERO_P(p
->mem_ctx
,SAM_DISPINFO_CTR
)))
1154 return NT_STATUS_NO_MEMORY
;
1158 /* Now create reply structure */
1159 switch (q_u
->switch_level
) {
1162 if (!(ctr
->sam
.info1
= TALLOC_ZERO_ARRAY(p
->mem_ctx
,SAM_DISPINFO_1
,max_entries
)))
1163 return NT_STATUS_NO_MEMORY
;
1165 disp_ret
= init_sam_dispinfo_1(p
->mem_ctx
, ctr
->sam
.info1
, max_entries
, enum_context
,
1166 info
->disp_info
.disp_user_info
, &domain_sid
);
1167 if (!NT_STATUS_IS_OK(disp_ret
))
1172 if (!(ctr
->sam
.info2
= TALLOC_ZERO_ARRAY(p
->mem_ctx
,SAM_DISPINFO_2
,max_entries
)))
1173 return NT_STATUS_NO_MEMORY
;
1175 disp_ret
= init_sam_dispinfo_2(p
->mem_ctx
, ctr
->sam
.info2
, max_entries
, enum_context
,
1176 info
->disp_info
.disp_user_info
, &domain_sid
);
1177 if (!NT_STATUS_IS_OK(disp_ret
))
1182 if (!(ctr
->sam
.info3
= TALLOC_ZERO_ARRAY(p
->mem_ctx
,SAM_DISPINFO_3
,max_entries
)))
1183 return NT_STATUS_NO_MEMORY
;
1185 disp_ret
= init_sam_dispinfo_3(p
->mem_ctx
, ctr
->sam
.info3
, max_entries
, enum_context
, info
->disp_info
.disp_group_info
);
1186 if (!NT_STATUS_IS_OK(disp_ret
))
1191 if (!(ctr
->sam
.info4
= TALLOC_ZERO_ARRAY(p
->mem_ctx
,SAM_DISPINFO_4
,max_entries
)))
1192 return NT_STATUS_NO_MEMORY
;
1194 disp_ret
= init_sam_dispinfo_4(p
->mem_ctx
, ctr
->sam
.info4
, max_entries
, enum_context
, info
->disp_info
.disp_user_info
);
1195 if (!NT_STATUS_IS_OK(disp_ret
))
1200 if (!(ctr
->sam
.info5
= TALLOC_ZERO_ARRAY(p
->mem_ctx
,SAM_DISPINFO_5
,max_entries
)))
1201 return NT_STATUS_NO_MEMORY
;
1203 disp_ret
= init_sam_dispinfo_5(p
->mem_ctx
, ctr
->sam
.info5
, max_entries
, enum_context
, info
->disp_info
.disp_group_info
);
1204 if (!NT_STATUS_IS_OK(disp_ret
))
1209 ctr
->sam
.info
= NULL
;
1210 return NT_STATUS_INVALID_INFO_CLASS
;
1213 /* calculate the total size */
1214 total_data_size
=num_account
*struct_size
;
1216 if (enum_context
+max_entries
< num_account
)
1217 r_u
->status
= STATUS_MORE_ENTRIES
;
1219 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__
));
1221 init_samr_r_query_dispinfo(r_u
, max_entries
, total_data_size
, temp_size
, q_u
->switch_level
, ctr
, r_u
->status
);
1227 /*******************************************************************
1228 samr_reply_query_aliasinfo
1229 ********************************************************************/
1231 NTSTATUS
_samr_query_aliasinfo(pipes_struct
*p
, SAMR_Q_QUERY_ALIASINFO
*q_u
, SAMR_R_QUERY_ALIASINFO
*r_u
)
1234 struct acct_info info
;
1238 r_u
->status
= NT_STATUS_OK
;
1240 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1242 /* find the policy handle. open a policy on it. */
1243 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
1244 return NT_STATUS_INVALID_HANDLE
;
1245 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_LOOKUP_INFO
, "_samr_query_aliasinfo"))) {
1250 ret
= pdb_get_aliasinfo(&sid
, &info
);
1254 return NT_STATUS_NO_SUCH_ALIAS
;
1256 switch (q_u
->switch_level
) {
1259 r_u
->ctr
.switch_value1
= 1;
1260 init_samr_alias_info1(&r_u
->ctr
.alias
.info1
,
1261 info
.acct_name
, 1, info
.acct_desc
);
1265 r_u
->ctr
.switch_value1
= 3;
1266 init_samr_alias_info3(&r_u
->ctr
.alias
.info3
, info
.acct_desc
);
1269 return NT_STATUS_INVALID_INFO_CLASS
;
1272 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__
));
1278 /*******************************************************************
1279 samr_reply_lookup_ids
1280 ********************************************************************/
1282 uint32
_samr_lookup_ids(pipes_struct
*p
, SAMR_Q_LOOKUP_IDS
*q_u
, SAMR_R_LOOKUP_IDS
*r_u
)
1284 uint32 rid
[MAX_SAM_ENTRIES
];
1285 int num_rids
= q_u
->num_sids1
;
1287 r_u
->status
= NT_STATUS_OK
;
1289 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1291 if (num_rids
> MAX_SAM_ENTRIES
) {
1292 num_rids
= MAX_SAM_ENTRIES
;
1293 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids
));
1298 SMB_ASSERT_ARRAY(q_u
->uni_user_name
, num_rids
);
1300 for (i
= 0; i
< num_rids
&& status
== 0; i
++)
1302 struct sam_passwd
*sam_pass
;
1306 fstrcpy(user_name
, unistrn2(q_u
->uni_user_name
[i
].buffer
,
1307 q_u
->uni_user_name
[i
].uni_str_len
));
1309 /* find the user account */
1311 sam_pass
= get_smb21pwd_entry(user_name
, 0);
1314 if (sam_pass
== NULL
)
1316 status
= 0xC0000000 | NT_STATUS_NO_SUCH_USER
;
1321 rid
[i
] = sam_pass
->user_rid
;
1327 rid
[0] = BUILTIN_ALIAS_RID_USERS
;
1329 init_samr_r_lookup_ids(&r_u
, num_rids
, rid
, NT_STATUS_OK
);
1331 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__
));
1337 /*******************************************************************
1339 ********************************************************************/
1341 NTSTATUS
_samr_lookup_names(pipes_struct
*p
, SAMR_Q_LOOKUP_NAMES
*q_u
, SAMR_R_LOOKUP_NAMES
*r_u
)
1343 uint32 rid
[MAX_SAM_ENTRIES
];
1345 enum SID_NAME_USE type
[MAX_SAM_ENTRIES
];
1346 enum SID_NAME_USE local_type
;
1348 int num_rids
= q_u
->num_names2
;
1353 r_u
->status
= NT_STATUS_OK
;
1355 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1360 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
, &acc_granted
)) {
1361 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, 0, NULL
, NULL
, NT_STATUS_OBJECT_TYPE_MISMATCH
);
1365 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 */
1369 if (num_rids
> MAX_SAM_ENTRIES
) {
1370 num_rids
= MAX_SAM_ENTRIES
;
1371 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids
));
1374 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str
, &pol_sid
)));
1376 for (i
= 0; i
< num_rids
; i
++) {
1381 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1383 rid
[i
] = 0xffffffff;
1384 type
[i
] = SID_NAME_UNKNOWN
;
1386 ret
= rpcstr_pull(name
, q_u
->uni_name
[i
].buffer
, sizeof(name
), q_u
->uni_name
[i
].uni_str_len
*2, 0);
1389 * we are only looking for a name
1390 * the SID we get back can be outside
1391 * the scope of the pol_sid
1393 * in clear: it prevents to reply to domain\group: yes
1394 * when only builtin\group exists.
1396 * a cleaner code is to add the sid of the domain we're looking in
1397 * to the local_lookup_name function.
1400 if ((ret
> 0) && local_lookup_name(name
, &sid
, &local_type
)) {
1401 sid_split_rid(&sid
, &local_rid
);
1403 if (sid_equal(&sid
, &pol_sid
)) {
1406 /* Windows does not return WKN_GRP here, even
1407 * on lookups in builtin */
1408 type
[i
] = (local_type
== SID_NAME_WKN_GRP
) ?
1409 SID_NAME_ALIAS
: local_type
;
1411 r_u
->status
= NT_STATUS_OK
;
1416 init_samr_r_lookup_names(p
->mem_ctx
, r_u
, num_rids
, rid
, (uint32
*)type
, r_u
->status
);
1418 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__
));
1423 /*******************************************************************
1424 _samr_chgpasswd_user
1425 ********************************************************************/
1427 NTSTATUS
_samr_chgpasswd_user(pipes_struct
*p
, SAMR_Q_CHGPASSWD_USER
*q_u
, SAMR_R_CHGPASSWD_USER
*r_u
)
1432 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1434 r_u
->status
= NT_STATUS_OK
;
1436 rpcstr_pull(user_name
, q_u
->uni_user_name
.buffer
, sizeof(user_name
), q_u
->uni_user_name
.uni_str_len
*2, 0);
1437 rpcstr_pull(wks
, q_u
->uni_dest_host
.buffer
, sizeof(wks
), q_u
->uni_dest_host
.uni_str_len
*2,0);
1439 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name
, wks
));
1442 * Pass the user through the NT -> unix user mapping
1446 (void)map_username(user_name
);
1449 * UNIX username case mangling not required, pass_oem_change
1450 * is case insensitive.
1453 r_u
->status
= pass_oem_change(user_name
, q_u
->lm_newpass
.pass
, q_u
->lm_oldhash
.hash
,
1454 q_u
->nt_newpass
.pass
, q_u
->nt_oldhash
.hash
);
1456 init_samr_r_chgpasswd_user(r_u
, r_u
->status
);
1458 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__
));
1463 /*******************************************************************
1464 makes a SAMR_R_LOOKUP_RIDS structure.
1465 ********************************************************************/
1467 static BOOL
make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
, fstring names
[],
1468 UNIHDR
**pp_hdr_name
, UNISTR2
**pp_uni_name
)
1471 UNIHDR
*hdr_name
=NULL
;
1472 UNISTR2
*uni_name
=NULL
;
1474 *pp_uni_name
= NULL
;
1475 *pp_hdr_name
= NULL
;
1477 if (num_names
!= 0) {
1478 hdr_name
= TALLOC_ZERO_ARRAY(ctx
, UNIHDR
, num_names
);
1479 if (hdr_name
== NULL
)
1482 uni_name
= TALLOC_ZERO_ARRAY(ctx
,UNISTR2
, num_names
);
1483 if (uni_name
== NULL
)
1487 for (i
= 0; i
< num_names
; i
++) {
1488 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
] ? names
[i
] : ""));
1489 init_unistr2(&uni_name
[i
], names
[i
], UNI_FLAGS_NONE
);
1490 init_uni_hdr(&hdr_name
[i
], &uni_name
[i
]);
1493 *pp_uni_name
= uni_name
;
1494 *pp_hdr_name
= hdr_name
;
1499 /*******************************************************************
1501 ********************************************************************/
1503 NTSTATUS
_samr_lookup_rids(pipes_struct
*p
, SAMR_Q_LOOKUP_RIDS
*q_u
, SAMR_R_LOOKUP_RIDS
*r_u
)
1505 fstring group_names
[MAX_SAM_ENTRIES
];
1506 uint32
*group_attrs
= NULL
;
1507 UNIHDR
*hdr_name
= NULL
;
1508 UNISTR2
*uni_name
= NULL
;
1510 int num_rids
= q_u
->num_rids1
;
1513 BOOL have_mapped
= False
;
1514 BOOL have_unmapped
= False
;
1516 r_u
->status
= NT_STATUS_OK
;
1518 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1520 /* find the policy handle. open a policy on it. */
1521 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &pol_sid
, &acc_granted
))
1522 return NT_STATUS_INVALID_HANDLE
;
1524 if (num_rids
> 1000) {
1525 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
1526 "to samba4 idl this is not possible\n", num_rids
));
1527 return NT_STATUS_UNSUCCESSFUL
;
1531 if ((group_attrs
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_rids
)) == NULL
)
1532 return NT_STATUS_NO_MEMORY
;
1535 if (!sid_equal(&pol_sid
, get_global_sam_sid())) {
1536 /* TODO: Sooner or later we need to look up BUILTIN rids as
1541 become_root(); /* lookup_sid can require root privs */
1543 for (i
= 0; i
< num_rids
; i
++) {
1547 enum SID_NAME_USE type
;
1549 group_attrs
[i
] = SID_NAME_UNKNOWN
;
1550 *group_names
[i
] = '\0';
1552 sid_copy(&sid
, &pol_sid
);
1553 sid_append_rid(&sid
, q_u
->rid
[i
]);
1555 if (lookup_sid(&sid
, domname
, tmpname
, &type
)) {
1556 group_attrs
[i
] = (uint32
)type
;
1557 fstrcpy(group_names
[i
],tmpname
);
1558 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names
[i
],
1562 have_unmapped
= True
;
1570 r_u
->status
= NT_STATUS_NONE_MAPPED
;
1574 have_unmapped
? STATUS_SOME_UNMAPPED
: NT_STATUS_OK
;
1576 if(!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, group_names
, &hdr_name
, &uni_name
))
1577 return NT_STATUS_NO_MEMORY
;
1579 init_samr_r_lookup_rids(r_u
, num_rids
, hdr_name
, uni_name
, group_attrs
);
1581 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__
));
1586 /*******************************************************************
1587 _samr_open_user. Safe - gives out no passwd info.
1588 ********************************************************************/
1590 NTSTATUS
_samr_open_user(pipes_struct
*p
, SAMR_Q_OPEN_USER
*q_u
, SAMR_R_OPEN_USER
*r_u
)
1592 SAM_ACCOUNT
*sampass
=NULL
;
1594 POLICY_HND domain_pol
= q_u
->domain_pol
;
1595 POLICY_HND
*user_pol
= &r_u
->user_pol
;
1596 struct samr_info
*info
= NULL
;
1597 SEC_DESC
*psd
= NULL
;
1599 uint32 des_access
= q_u
->access_mask
;
1605 r_u
->status
= NT_STATUS_OK
;
1607 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1609 if ( !get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
, &acc_granted
) )
1610 return NT_STATUS_INVALID_HANDLE
;
1612 nt_status
= access_check_samr_function( acc_granted
,
1613 SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_open_user" );
1615 if ( !NT_STATUS_IS_OK(nt_status
) )
1618 nt_status
= pdb_init_sam_talloc(p
->mem_ctx
, &sampass
);
1620 if (!NT_STATUS_IS_OK(nt_status
))
1623 /* append the user's RID to it */
1625 if (!sid_append_rid(&sid
, q_u
->user_rid
))
1626 return NT_STATUS_NO_SUCH_USER
;
1628 /* check if access can be granted as requested by client. */
1630 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
, &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
1631 se_map_generic(&des_access
, &usr_generic_mapping
);
1633 se_priv_copy( &se_rights
, &se_machine_account
);
1634 se_priv_add( &se_rights
, &se_add_users
);
1636 nt_status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
1637 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
1638 &acc_granted
, "_samr_open_user");
1640 if ( !NT_STATUS_IS_OK(nt_status
) )
1644 ret
=pdb_getsampwsid(sampass
, &sid
);
1647 /* check that the SID exists in our domain. */
1649 return NT_STATUS_NO_SUCH_USER
;
1652 pdb_free_sam(&sampass
);
1654 /* associate the user's SID and access bits with the new handle. */
1655 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
)
1656 return NT_STATUS_NO_MEMORY
;
1657 info
->acc_granted
= acc_granted
;
1659 /* get a (unique) handle. open a policy on it. */
1660 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
))
1661 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1666 /*************************************************************************
1667 get_user_info_7. Safe. Only gives out account_name.
1668 *************************************************************************/
1670 static NTSTATUS
get_user_info_7(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_7
*id7
, DOM_SID
*user_sid
)
1672 SAM_ACCOUNT
*smbpass
=NULL
;
1676 nt_status
= pdb_init_sam_talloc(mem_ctx
, &smbpass
);
1678 if (!NT_STATUS_IS_OK(nt_status
)) {
1683 ret
= pdb_getsampwsid(smbpass
, user_sid
);
1687 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1688 return NT_STATUS_NO_SUCH_USER
;
1691 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass
) ));
1694 init_sam_user_info7(id7
, pdb_get_username(smbpass
) );
1696 pdb_free_sam(&smbpass
);
1698 return NT_STATUS_OK
;
1700 /*************************************************************************
1701 get_user_info_10. Safe. Only gives out acb bits.
1702 *************************************************************************/
1704 static NTSTATUS
get_user_info_10(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_10
*id10
, DOM_SID
*user_sid
)
1706 SAM_ACCOUNT
*smbpass
=NULL
;
1710 nt_status
= pdb_init_sam_talloc(mem_ctx
, &smbpass
);
1712 if (!NT_STATUS_IS_OK(nt_status
)) {
1717 ret
= pdb_getsampwsid(smbpass
, user_sid
);
1721 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1722 return NT_STATUS_NO_SUCH_USER
;
1725 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass
) ));
1728 init_sam_user_info10(id10
, pdb_get_acct_ctrl(smbpass
) );
1730 pdb_free_sam(&smbpass
);
1732 return NT_STATUS_OK
;
1735 /*************************************************************************
1736 get_user_info_12. OK - this is the killer as it gives out password info.
1737 Ensure that this is only allowed on an encrypted connection with a root
1739 *************************************************************************/
1741 static NTSTATUS
get_user_info_12(pipes_struct
*p
, TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_12
* id12
, DOM_SID
*user_sid
)
1743 SAM_ACCOUNT
*smbpass
=NULL
;
1747 if (!p
->ntlmssp_auth_validated
)
1748 return NT_STATUS_ACCESS_DENIED
;
1750 if (!(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SIGN
) || !(p
->ntlmssp_chal_flags
& NTLMSSP_NEGOTIATE_SEAL
))
1751 return NT_STATUS_ACCESS_DENIED
;
1754 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1757 nt_status
= pdb_init_sam_talloc(mem_ctx
, &smbpass
);
1759 if (!NT_STATUS_IS_OK(nt_status
)) {
1763 ret
= pdb_getsampwsid(smbpass
, user_sid
);
1766 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid
)));
1767 pdb_free_sam(&smbpass
);
1768 return (geteuid() == (uid_t
)0) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
1771 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
1773 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
1774 pdb_free_sam(&smbpass
);
1775 return NT_STATUS_ACCOUNT_DISABLED
;
1779 init_sam_user_info12(id12
, pdb_get_lanman_passwd(smbpass
), pdb_get_nt_passwd(smbpass
));
1781 pdb_free_sam(&smbpass
);
1783 return NT_STATUS_OK
;
1786 /*************************************************************************
1788 *************************************************************************/
1790 static NTSTATUS
get_user_info_20(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_20
*id20
, DOM_SID
*user_sid
)
1792 SAM_ACCOUNT
*sampass
=NULL
;
1795 pdb_init_sam_talloc(mem_ctx
, &sampass
);
1798 ret
= pdb_getsampwsid(sampass
, user_sid
);
1802 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1803 return NT_STATUS_NO_SUCH_USER
;
1806 samr_clear_sam_passwd(sampass
);
1808 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1811 init_sam_user_info20A(id20
, sampass
);
1813 pdb_free_sam(&sampass
);
1815 return NT_STATUS_OK
;
1818 /*************************************************************************
1820 *************************************************************************/
1822 static NTSTATUS
get_user_info_21(TALLOC_CTX
*mem_ctx
, SAM_USER_INFO_21
*id21
,
1823 DOM_SID
*user_sid
, DOM_SID
*domain_sid
)
1825 SAM_ACCOUNT
*sampass
=NULL
;
1829 nt_status
= pdb_init_sam_talloc(mem_ctx
, &sampass
);
1830 if (!NT_STATUS_IS_OK(nt_status
)) {
1835 ret
= pdb_getsampwsid(sampass
, user_sid
);
1839 DEBUG(4,("User %s not found\n", sid_string_static(user_sid
)));
1840 return NT_STATUS_NO_SUCH_USER
;
1843 samr_clear_sam_passwd(sampass
);
1845 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
1848 nt_status
= init_sam_user_info21A(id21
, sampass
, domain_sid
);
1850 pdb_free_sam(&sampass
);
1852 return NT_STATUS_OK
;
1855 /*******************************************************************
1856 _samr_query_userinfo
1857 ********************************************************************/
1859 NTSTATUS
_samr_query_userinfo(pipes_struct
*p
, SAMR_Q_QUERY_USERINFO
*q_u
, SAMR_R_QUERY_USERINFO
*r_u
)
1861 SAM_USERINFO_CTR
*ctr
;
1862 struct samr_info
*info
= NULL
;
1866 r_u
->status
=NT_STATUS_OK
;
1868 /* search for the handle */
1869 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
1870 return NT_STATUS_INVALID_HANDLE
;
1872 domain_sid
= info
->sid
;
1874 sid_split_rid(&domain_sid
, &rid
);
1876 if (!sid_check_is_in_our_domain(&info
->sid
))
1877 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1879 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info
->sid
)));
1881 ctr
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_USERINFO_CTR
);
1883 return NT_STATUS_NO_MEMORY
;
1887 /* ok! user info levels (lots: see MSDEV help), off we go... */
1888 ctr
->switch_value
= q_u
->switch_value
;
1890 switch (q_u
->switch_value
) {
1892 ctr
->info
.id7
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_USER_INFO_7
);
1893 if (ctr
->info
.id7
== NULL
)
1894 return NT_STATUS_NO_MEMORY
;
1896 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_7(p
->mem_ctx
, ctr
->info
.id7
, &info
->sid
)))
1900 ctr
->info
.id10
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_USER_INFO_10
);
1901 if (ctr
->info
.id10
== NULL
)
1902 return NT_STATUS_NO_MEMORY
;
1904 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_10(p
->mem_ctx
, ctr
->info
.id10
, &info
->sid
)))
1909 /* whoops - got this wrong. i think. or don't understand what's happening. */
1913 info
= (void *)&id11
;
1915 expire
.low
= 0xffffffff;
1916 expire
.high
= 0x7fffffff;
1918 ctr
->info
.id
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_USER_INFO_11
));
1919 ZERO_STRUCTP(ctr
->info
.id11
);
1920 init_sam_user_info11(ctr
->info
.id11
, &expire
,
1921 "BROOKFIELDS$", /* name */
1922 0x03ef, /* user rid */
1923 0x201, /* group rid */
1924 0x0080); /* acb info */
1931 ctr
->info
.id12
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_USER_INFO_12
);
1932 if (ctr
->info
.id12
== NULL
)
1933 return NT_STATUS_NO_MEMORY
;
1935 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_12(p
, p
->mem_ctx
, ctr
->info
.id12
, &info
->sid
)))
1940 ctr
->info
.id20
= TALLOC_ZERO_P(p
->mem_ctx
,SAM_USER_INFO_20
);
1941 if (ctr
->info
.id20
== NULL
)
1942 return NT_STATUS_NO_MEMORY
;
1943 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_20(p
->mem_ctx
, ctr
->info
.id20
, &info
->sid
)))
1948 ctr
->info
.id21
= TALLOC_ZERO_P(p
->mem_ctx
,SAM_USER_INFO_21
);
1949 if (ctr
->info
.id21
== NULL
)
1950 return NT_STATUS_NO_MEMORY
;
1951 if (!NT_STATUS_IS_OK(r_u
->status
= get_user_info_21(p
->mem_ctx
, ctr
->info
.id21
,
1952 &info
->sid
, &domain_sid
)))
1957 return NT_STATUS_INVALID_INFO_CLASS
;
1960 init_samr_r_query_userinfo(r_u
, ctr
, r_u
->status
);
1962 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__
));
1967 /*******************************************************************
1968 samr_reply_query_usergroups
1969 ********************************************************************/
1971 NTSTATUS
_samr_query_usergroups(pipes_struct
*p
, SAMR_Q_QUERY_USERGROUPS
*q_u
, SAMR_R_QUERY_USERGROUPS
*r_u
)
1973 SAM_ACCOUNT
*sam_pass
=NULL
;
1974 struct passwd
*passwd
;
1977 DOM_GID
*gids
= NULL
;
1980 int i
, num_gids
, num_sids
;
1986 * from the SID in the request:
1987 * we should send back the list of DOMAIN GROUPS
1988 * the user is a member of
1990 * and only the DOMAIN GROUPS
1991 * no ALIASES !!! neither aliases of the domain
1992 * nor aliases of the builtin SID
1997 r_u
->status
= NT_STATUS_OK
;
1999 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
2001 /* find the policy handle. open a policy on it. */
2002 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &sid
, &acc_granted
))
2003 return NT_STATUS_INVALID_HANDLE
;
2005 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_USER_GET_GROUPS
, "_samr_query_usergroups"))) {
2009 if (!sid_check_is_in_our_domain(&sid
))
2010 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
2012 pdb_init_sam(&sam_pass
);
2015 ret
= pdb_getsampwsid(sam_pass
, &sid
);
2019 pdb_free_sam(&sam_pass
);
2020 return NT_STATUS_NO_SUCH_USER
;
2023 passwd
= getpwnam_alloc(pdb_get_username(sam_pass
));
2024 if (passwd
== NULL
) {
2025 pdb_free_sam(&sam_pass
);
2026 return NT_STATUS_NO_SUCH_USER
;
2033 result
= pdb_enum_group_memberships(pdb_get_username(sam_pass
),
2035 &sids
, &unix_gids
, &num_groups
);
2038 pdb_free_sam(&sam_pass
);
2039 passwd_free(&passwd
);
2041 if (!NT_STATUS_IS_OK(result
))
2044 SAFE_FREE(unix_gids
);
2049 for (i
=0; i
<num_groups
; i
++) {
2052 if (!sid_peek_check_rid(get_global_sam_sid(),
2056 gids
= TALLOC_REALLOC_ARRAY(p
->mem_ctx
, gids
, DOM_GID
, num_gids
+1);
2057 gids
[num_gids
].attr
=7;
2058 gids
[num_gids
].g_rid
= rid
;
2063 /* construct the response. lkclXXXX: gids are not copied! */
2064 init_samr_r_query_usergroups(r_u
, num_groups
, gids
, r_u
->status
);
2066 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__
));
2071 /*******************************************************************
2072 _samr_query_dom_info
2073 ********************************************************************/
2075 NTSTATUS
_samr_query_dom_info(pipes_struct
*p
, SAMR_Q_QUERY_DOMAIN_INFO
*q_u
, SAMR_R_QUERY_DOMAIN_INFO
*r_u
)
2077 struct samr_info
*info
= NULL
;
2079 uint32 min_pass_len
,pass_hist
,flag
;
2080 time_t u_expire
, u_min_age
;
2081 NTTIME nt_expire
, nt_min_age
;
2083 time_t u_lock_duration
, u_reset_time
;
2084 NTTIME nt_lock_duration
, nt_reset_time
;
2090 uint32 account_policy_temp
;
2093 uint32 num_users
=0, num_groups
=0, num_aliases
=0;
2095 if ((ctr
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_UNK_CTR
)) == NULL
)
2096 return NT_STATUS_NO_MEMORY
;
2100 r_u
->status
= NT_STATUS_OK
;
2102 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
2104 /* find the policy handle. open a policy on it. */
2105 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
2106 return NT_STATUS_INVALID_HANDLE
;
2108 switch (q_u
->switch_value
) {
2111 account_policy_get(AP_MIN_PASSWORD_LEN
, &account_policy_temp
);
2112 min_pass_len
= account_policy_temp
;
2114 account_policy_get(AP_PASSWORD_HISTORY
, &account_policy_temp
);
2115 pass_hist
= account_policy_temp
;
2117 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS
, &account_policy_temp
);
2118 flag
= account_policy_temp
;
2120 account_policy_get(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
2121 u_expire
= account_policy_temp
;
2123 account_policy_get(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
2124 u_min_age
= account_policy_temp
;
2126 unix_to_nt_time_abs(&nt_expire
, u_expire
);
2127 unix_to_nt_time_abs(&nt_min_age
, u_min_age
);
2129 init_unk_info1(&ctr
->info
.inf1
, (uint16
)min_pass_len
, (uint16
)pass_hist
,
2130 flag
, nt_expire
, nt_min_age
);
2134 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
, False
);
2136 if (!NT_STATUS_IS_OK(r_u
->status
)) {
2137 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2140 num_users
=info
->disp_info
.num_user_account
;
2143 r_u
->status
=load_group_domain_entries(info
, get_global_sam_sid());
2144 if (!NT_STATUS_IS_OK(r_u
->status
)) {
2145 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2148 num_groups
=info
->disp_info
.num_group_account
;
2151 account_policy_get(AP_TIME_TO_LOGOUT
, &account_policy_temp
);
2152 u_logout
= account_policy_temp
;
2154 unix_to_nt_time_abs(&nt_logout
, u_logout
);
2156 server_role
= ROLE_DOMAIN_PDC
;
2157 if (lp_server_role() == ROLE_DOMAIN_BDC
)
2158 server_role
= ROLE_DOMAIN_BDC
;
2160 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2161 init_unk_info2(&ctr
->info
.inf2
, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL
),
2162 num_users
, num_groups
, num_aliases
, nt_logout
, server_role
);
2165 account_policy_get(AP_TIME_TO_LOGOUT
, (unsigned int *)&u_logout
);
2166 unix_to_nt_time_abs(&nt_logout
, u_logout
);
2168 init_unk_info3(&ctr
->info
.inf3
, nt_logout
);
2171 init_unk_info5(&ctr
->info
.inf5
, global_myname());
2174 init_unk_info6(&ctr
->info
.inf6
);
2177 server_role
= ROLE_DOMAIN_PDC
;
2178 if (lp_server_role() == ROLE_DOMAIN_BDC
)
2179 server_role
= ROLE_DOMAIN_BDC
;
2181 init_unk_info7(&ctr
->info
.inf7
, server_role
);
2184 init_unk_info8(&ctr
->info
.inf8
, (uint32
) time(NULL
));
2187 account_policy_get(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
2188 u_lock_duration
= account_policy_temp
;
2189 if (u_lock_duration
!= -1)
2190 u_lock_duration
*= 60;
2192 account_policy_get(AP_RESET_COUNT_TIME
, &account_policy_temp
);
2193 u_reset_time
= account_policy_temp
* 60;
2195 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
2196 lockout
= account_policy_temp
;
2198 unix_to_nt_time_abs(&nt_lock_duration
, u_lock_duration
);
2199 unix_to_nt_time_abs(&nt_reset_time
, u_reset_time
);
2201 init_unk_info12(&ctr
->info
.inf12
, nt_lock_duration
, nt_reset_time
, (uint16
)lockout
);
2204 return NT_STATUS_INVALID_INFO_CLASS
;
2207 init_samr_r_query_dom_info(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_OK
);
2209 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__
));
2214 /*******************************************************************
2216 Create an account, can be either a normal user or a machine.
2217 This funcion will need to be updated for bdc/domain trusts.
2218 ********************************************************************/
2220 NTSTATUS
_samr_create_user(pipes_struct
*p
, SAMR_Q_CREATE_USER
*q_u
, SAMR_R_CREATE_USER
*r_u
)
2222 SAM_ACCOUNT
*sam_pass
=NULL
;
2226 POLICY_HND dom_pol
= q_u
->domain_pol
;
2227 UNISTR2 user_account
= q_u
->uni_name
;
2228 uint16 acb_info
= q_u
->acb_info
;
2229 POLICY_HND
*user_pol
= &r_u
->user_pol
;
2230 struct samr_info
*info
= NULL
;
2238 /* check this, when giving away 'add computer to domain' privs */
2239 uint32 des_access
= GENERIC_RIGHTS_USER_ALL_ACCESS
;
2240 BOOL can_add_account
= False
;
2243 /* Get the domain SID stored in the domain policy */
2244 if (!get_lsa_policy_samr_sid(p
, &dom_pol
, &sid
, &acc_granted
))
2245 return NT_STATUS_INVALID_HANDLE
;
2247 if (!NT_STATUS_IS_OK(nt_status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_CREATE_USER
, "_samr_create_user"))) {
2251 if (!(acb_info
== ACB_NORMAL
|| acb_info
== ACB_DOMTRUST
|| acb_info
== ACB_WSTRUST
|| acb_info
== ACB_SVRTRUST
)) {
2252 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2253 this parameter is not an account type */
2254 return NT_STATUS_INVALID_PARAMETER
;
2257 rpcstr_pull(account
, user_account
.buffer
, sizeof(account
), user_account
.uni_str_len
*2, 0);
2258 strlower_m(account
);
2260 pdb_init_sam(&sam_pass
);
2263 ret
= pdb_getsampwnam(sam_pass
, account
);
2266 /* this account exists: say so */
2267 pdb_free_sam(&sam_pass
);
2268 return NT_STATUS_USER_EXISTS
;
2271 pdb_free_sam(&sam_pass
);
2273 /*********************************************************************
2274 * HEADS UP! If we have to create a new user account, we have to get
2275 * a new RID from somewhere. This used to be done by the passdb
2276 * backend. It has been moved into idmap now. Since idmap is now
2277 * wrapped up behind winbind, this means you have to run winbindd if you
2278 * want new accounts to get a new RID when "enable rid algorithm = no".
2279 * Tough. We now have a uniform way of allocating RIDs regardless
2280 * of what ever passdb backend people may use.
2281 * --jerry (2003-07-10)
2282 *********************************************************************/
2284 pw
= Get_Pwnam(account
);
2286 /* determine which user right we need to check based on the acb_info */
2288 if ( acb_info
& ACB_WSTRUST
)
2290 pstrcpy(add_script
, lp_addmachine_script());
2291 se_priv_copy( &se_rights
, &se_machine_account
);
2292 can_add_account
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
2294 else if ( acb_info
& ACB_NORMAL
)
2296 pstrcpy(add_script
, lp_adduser_script());
2297 se_priv_copy( &se_rights
, &se_add_users
);
2298 can_add_account
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
2300 else if ( acb_info
& (ACB_SVRTRUST
|ACB_DOMTRUST
) )
2302 pstrcpy(add_script
, lp_addmachine_script());
2303 if ( lp_enable_privileges() ) {
2304 /* only Domain Admins can add a BDC or domain trust */
2305 se_priv_copy( &se_rights
, &se_priv_none
);
2306 can_add_account
= nt_token_check_domain_rid( p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
);
2310 DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2311 p
->pipe_user_name
, can_add_account
? "True":"False" ));
2313 /********** BEGIN Admin BLOCK **********/
2315 if ( can_add_account
)
2322 all_string_sub(add_script
, "%u", account
, sizeof(add_script
));
2323 add_ret
= smbrun(add_script
,NULL
);
2324 DEBUG(add_ret
? 0 : 3,("_samr_create_user: Running the command `%s' gave %d\n", add_script
, add_ret
));
2326 else /* no add user script -- ask winbindd to do it */
2328 if ( !winbind_create_user( account
, &new_rid
) ) {
2329 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2336 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2338 flush_pwnam_cache();
2339 nt_status
= pdb_init_sam_new(&sam_pass
, account
, new_rid
);
2341 /* this code is order such that we have no unnecessary retuns
2342 out of the admin block of code */
2344 if ( NT_STATUS_IS_OK(nt_status
) ) {
2345 pdb_set_acct_ctrl(sam_pass
, acb_info
, PDB_CHANGED
);
2347 if ( !(ret
= pdb_add_sam_account(sam_pass
)) ) {
2348 pdb_free_sam(&sam_pass
);
2349 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2351 nt_status
= NT_STATUS_ACCESS_DENIED
;
2355 if ( can_add_account
)
2358 /********** END Admin BLOCK **********/
2360 /* now check for failure */
2362 if ( !NT_STATUS_IS_OK(nt_status
) )
2365 /* Get the user's SID */
2367 sid_copy(&sid
, pdb_get_user_sid(sam_pass
));
2369 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
, &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
2370 se_map_generic(&des_access
, &usr_generic_mapping
);
2372 nt_status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2373 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
2374 &acc_granted
, "_samr_create_user");
2376 if ( !NT_STATUS_IS_OK(nt_status
) ) {
2380 /* associate the user's SID with the new handle. */
2381 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
) {
2382 pdb_free_sam(&sam_pass
);
2383 return NT_STATUS_NO_MEMORY
;
2388 info
->acc_granted
= acc_granted
;
2390 /* get a (unique) handle. open a policy on it. */
2391 if (!create_policy_hnd(p
, user_pol
, free_samr_info
, (void *)info
)) {
2392 pdb_free_sam(&sam_pass
);
2393 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2396 r_u
->user_rid
=pdb_get_user_rid(sam_pass
);
2398 r_u
->access_granted
= acc_granted
;
2400 pdb_free_sam(&sam_pass
);
2402 return NT_STATUS_OK
;
2405 /*******************************************************************
2406 samr_reply_connect_anon
2407 ********************************************************************/
2409 NTSTATUS
_samr_connect_anon(pipes_struct
*p
, SAMR_Q_CONNECT_ANON
*q_u
, SAMR_R_CONNECT_ANON
*r_u
)
2411 struct samr_info
*info
= NULL
;
2412 uint32 des_access
= q_u
->access_mask
;
2416 if (!pipe_access_check(p
)) {
2417 DEBUG(3, ("access denied to samr_connect_anon\n"));
2418 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2422 /* set up the SAMR connect_anon response */
2424 r_u
->status
= NT_STATUS_OK
;
2426 /* associate the user's SID with the new handle. */
2427 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2428 return NT_STATUS_NO_MEMORY
;
2430 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2431 was observed from a win98 client trying to enumerate users (when configured
2432 user level access control on shares) --jerry */
2434 se_map_generic( &des_access
, &sam_generic_mapping
);
2435 info
->acc_granted
= des_access
& (SA_RIGHT_SAM_ENUM_DOMAINS
|SA_RIGHT_SAM_OPEN_DOMAIN
);
2437 info
->status
= q_u
->unknown_0
;
2439 /* get a (unique) handle. open a policy on it. */
2440 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2441 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2446 /*******************************************************************
2448 ********************************************************************/
2450 NTSTATUS
_samr_connect(pipes_struct
*p
, SAMR_Q_CONNECT
*q_u
, SAMR_R_CONNECT
*r_u
)
2452 struct samr_info
*info
= NULL
;
2453 SEC_DESC
*psd
= NULL
;
2455 uint32 des_access
= q_u
->access_mask
;
2460 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2464 if (!pipe_access_check(p
)) {
2465 DEBUG(3, ("access denied to samr_connect\n"));
2466 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2470 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
2471 se_map_generic(&des_access
, &sam_generic_mapping
);
2473 nt_status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2474 NULL
, 0, des_access
, &acc_granted
, "_samr_connect");
2476 if ( !NT_STATUS_IS_OK(nt_status
) )
2479 r_u
->status
= NT_STATUS_OK
;
2481 /* associate the user's SID and access granted with the new handle. */
2482 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2483 return NT_STATUS_NO_MEMORY
;
2485 info
->acc_granted
= acc_granted
;
2486 info
->status
= q_u
->access_mask
;
2488 /* get a (unique) handle. open a policy on it. */
2489 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2490 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2492 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2497 /*******************************************************************
2499 ********************************************************************/
2501 NTSTATUS
_samr_connect4(pipes_struct
*p
, SAMR_Q_CONNECT4
*q_u
, SAMR_R_CONNECT4
*r_u
)
2503 struct samr_info
*info
= NULL
;
2504 SEC_DESC
*psd
= NULL
;
2506 uint32 des_access
= q_u
->access_mask
;
2511 DEBUG(5,("_samr_connect4: %d\n", __LINE__
));
2515 if (!pipe_access_check(p
)) {
2516 DEBUG(3, ("access denied to samr_connect4\n"));
2517 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
2521 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
2522 se_map_generic(&des_access
, &sam_generic_mapping
);
2524 nt_status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2525 NULL
, 0, des_access
, &acc_granted
, "_samr_connect4");
2527 if ( !NT_STATUS_IS_OK(nt_status
) )
2530 r_u
->status
= NT_STATUS_OK
;
2532 /* associate the user's SID and access granted with the new handle. */
2533 if ((info
= get_samr_info_by_sid(NULL
)) == NULL
)
2534 return NT_STATUS_NO_MEMORY
;
2536 info
->acc_granted
= acc_granted
;
2537 info
->status
= q_u
->access_mask
;
2539 /* get a (unique) handle. open a policy on it. */
2540 if (!create_policy_hnd(p
, &r_u
->connect_pol
, free_samr_info
, (void *)info
))
2541 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2543 DEBUG(5,("_samr_connect: %d\n", __LINE__
));
2548 /**********************************************************************
2549 api_samr_lookup_domain
2550 **********************************************************************/
2552 NTSTATUS
_samr_lookup_domain(pipes_struct
*p
, SAMR_Q_LOOKUP_DOMAIN
*q_u
, SAMR_R_LOOKUP_DOMAIN
*r_u
)
2554 struct samr_info
*info
;
2555 fstring domain_name
;
2558 r_u
->status
= NT_STATUS_OK
;
2560 if (!find_policy_by_hnd(p
, &q_u
->connect_pol
, (void**)&info
))
2561 return NT_STATUS_INVALID_HANDLE
;
2563 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
2564 Reverted that change so we will work with RAS servers again */
2566 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
,
2567 SA_RIGHT_SAM_OPEN_DOMAIN
, "_samr_lookup_domain")))
2572 rpcstr_pull(domain_name
, q_u
->uni_domain
.buffer
, sizeof(domain_name
), q_u
->uni_domain
.uni_str_len
*2, 0);
2576 if (!secrets_fetch_domain_sid(domain_name
, &sid
)) {
2577 r_u
->status
= NT_STATUS_NO_SUCH_DOMAIN
;
2580 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
, sid_string_static(&sid
)));
2582 init_samr_r_lookup_domain(r_u
, &sid
, r_u
->status
);
2587 /******************************************************************
2588 makes a SAMR_R_ENUM_DOMAINS structure.
2589 ********************************************************************/
2591 static BOOL
make_enum_domains(TALLOC_CTX
*ctx
, SAM_ENTRY
**pp_sam
,
2592 UNISTR2
**pp_uni_name
, uint32 num_sam_entries
, fstring doms
[])
2598 DEBUG(5, ("make_enum_domains\n"));
2601 *pp_uni_name
= NULL
;
2603 if (num_sam_entries
== 0)
2606 sam
= TALLOC_ZERO_ARRAY(ctx
, SAM_ENTRY
, num_sam_entries
);
2607 uni_name
= TALLOC_ZERO_ARRAY(ctx
, UNISTR2
, num_sam_entries
);
2609 if (sam
== NULL
|| uni_name
== NULL
)
2612 for (i
= 0; i
< num_sam_entries
; i
++) {
2613 init_unistr2(&uni_name
[i
], doms
[i
], UNI_FLAGS_NONE
);
2614 init_sam_entry(&sam
[i
], &uni_name
[i
], 0);
2618 *pp_uni_name
= uni_name
;
2623 /**********************************************************************
2624 api_samr_enum_domains
2625 **********************************************************************/
2627 NTSTATUS
_samr_enum_domains(pipes_struct
*p
, SAMR_Q_ENUM_DOMAINS
*q_u
, SAMR_R_ENUM_DOMAINS
*r_u
)
2629 struct samr_info
*info
;
2630 uint32 num_entries
= 2;
2634 r_u
->status
= NT_STATUS_OK
;
2636 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void**)&info
))
2637 return NT_STATUS_INVALID_HANDLE
;
2639 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_SAM_ENUM_DOMAINS
, "_samr_enum_domains"))) {
2643 name
= get_global_sam_name();
2645 fstrcpy(dom
[0],name
);
2647 fstrcpy(dom
[1],"Builtin");
2649 if (!make_enum_domains(p
->mem_ctx
, &r_u
->sam
, &r_u
->uni_dom_name
, num_entries
, dom
))
2650 return NT_STATUS_NO_MEMORY
;
2652 init_samr_r_enum_domains(r_u
, q_u
->start_idx
+ num_entries
, num_entries
);
2657 /*******************************************************************
2659 ********************************************************************/
2661 NTSTATUS
_samr_open_alias(pipes_struct
*p
, SAMR_Q_OPEN_ALIAS
*q_u
, SAMR_R_OPEN_ALIAS
*r_u
)
2664 POLICY_HND domain_pol
= q_u
->dom_pol
;
2665 uint32 alias_rid
= q_u
->rid_alias
;
2666 POLICY_HND
*alias_pol
= &r_u
->pol
;
2667 struct samr_info
*info
= NULL
;
2668 SEC_DESC
*psd
= NULL
;
2670 uint32 des_access
= q_u
->access_mask
;
2675 r_u
->status
= NT_STATUS_OK
;
2677 /* find the domain policy and get the SID / access bits stored in the domain policy */
2679 if ( !get_lsa_policy_samr_sid(p
, &domain_pol
, &sid
, &acc_granted
) )
2680 return NT_STATUS_INVALID_HANDLE
;
2682 status
= access_check_samr_function(acc_granted
,
2683 SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_open_alias");
2685 if ( !NT_STATUS_IS_OK(status
) )
2688 /* append the alias' RID to it */
2690 if (!sid_append_rid(&sid
, alias_rid
))
2691 return NT_STATUS_NO_SUCH_USER
;
2693 /*check if access can be granted as requested by client. */
2695 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &ali_generic_mapping
, NULL
, 0);
2696 se_map_generic(&des_access
,&ali_generic_mapping
);
2698 se_priv_add( &se_rights
, &se_add_users
);
2701 status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
2702 &se_rights
, GENERIC_RIGHTS_ALIAS_WRITE
, des_access
,
2703 &acc_granted
, "_samr_open_alias");
2705 if ( !NT_STATUS_IS_OK(status
) )
2709 * we should check if the rid really exist !!!
2713 /* associate the user's SID with the new handle. */
2714 if ((info
= get_samr_info_by_sid(&sid
)) == NULL
)
2715 return NT_STATUS_NO_MEMORY
;
2717 info
->acc_granted
= acc_granted
;
2719 /* get a (unique) handle. open a policy on it. */
2720 if (!create_policy_hnd(p
, alias_pol
, free_samr_info
, (void *)info
))
2721 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2726 /*******************************************************************
2728 ********************************************************************/
2730 static BOOL
set_user_info_10(const SAM_USER_INFO_10
*id10
, SAM_ACCOUNT
*pwd
)
2733 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2738 /* FIX ME: check if the value is really changed --metze */
2739 if (!pdb_set_acct_ctrl(pwd
, id10
->acb_info
, PDB_CHANGED
)) {
2744 if(!pdb_update_sam_account(pwd
)) {
2754 /*******************************************************************
2756 ********************************************************************/
2758 static BOOL
set_user_info_12(SAM_USER_INFO_12
*id12
, SAM_ACCOUNT
*pwd
)
2762 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2767 if (!pdb_set_lanman_passwd (pwd
, id12
->lm_pwd
, PDB_CHANGED
)) {
2771 if (!pdb_set_nt_passwd (pwd
, id12
->nt_pwd
, PDB_CHANGED
)) {
2775 if (!pdb_set_pass_changed_now (pwd
)) {
2780 if(!pdb_update_sam_account(pwd
)) {
2789 /*******************************************************************
2790 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2791 ********************************************************************/
2792 static BOOL
set_unix_primary_group(SAM_ACCOUNT
*sampass
)
2797 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass
),
2799 DEBUG(2,("Could not get gid for primary group of "
2800 "user %s\n", pdb_get_username(sampass
)));
2804 grp
= getgrgid(gid
);
2807 DEBUG(2,("Could not find primary group %lu for "
2808 "user %s\n", (unsigned long)gid
,
2809 pdb_get_username(sampass
)));
2813 if (smb_set_primary_group(grp
->gr_name
,
2814 pdb_get_username(sampass
)) != 0) {
2815 DEBUG(2,("Could not set primary group for user %s to "
2817 pdb_get_username(sampass
), grp
->gr_name
));
2825 /*******************************************************************
2827 ********************************************************************/
2829 static BOOL
set_user_info_20(SAM_USER_INFO_20
*id20
, SAM_ACCOUNT
*pwd
)
2832 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2836 copy_id20_to_sam_passwd(pwd
, id20
);
2838 /* write the change out */
2839 if(!pdb_update_sam_account(pwd
)) {
2848 /*******************************************************************
2850 ********************************************************************/
2852 static BOOL
set_user_info_21(SAM_USER_INFO_21
*id21
, SAM_ACCOUNT
*pwd
)
2856 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2860 copy_id21_to_sam_passwd(pwd
, id21
);
2863 * The funny part about the previous two calls is
2864 * that pwd still has the password hashes from the
2865 * passdb entry. These have not been updated from
2866 * id21. I don't know if they need to be set. --jerry
2869 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
))
2870 set_unix_primary_group(pwd
);
2872 /* write the change out */
2873 if(!pdb_update_sam_account(pwd
)) {
2883 /*******************************************************************
2885 ********************************************************************/
2887 static BOOL
set_user_info_23(SAM_USER_INFO_23
*id23
, SAM_ACCOUNT
*pwd
)
2889 pstring plaintext_buf
;
2894 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2898 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2899 pdb_get_username(pwd
)));
2901 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2903 if (!decode_pw_buffer((char*)id23
->pass
, plaintext_buf
, 256, &len
, STR_UNICODE
)) {
2908 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
2913 copy_id23_to_sam_passwd(pwd
, id23
);
2915 /* if it's a trust account, don't update /etc/passwd */
2916 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2917 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2918 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2919 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2921 /* update the UNIX password */
2922 if (lp_unix_password_sync() ) {
2923 struct passwd
*passwd
= Get_Pwnam(pdb_get_username(pwd
));
2925 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2928 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
2935 ZERO_STRUCT(plaintext_buf
);
2937 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
))
2938 set_unix_primary_group(pwd
);
2940 if(!pdb_update_sam_account(pwd
)) {
2950 /*******************************************************************
2952 ********************************************************************/
2954 static BOOL
set_user_info_pw(char *pass
, SAM_ACCOUNT
*pwd
)
2957 pstring plaintext_buf
;
2960 DEBUG(5, ("Attempting administrator password change for user %s\n",
2961 pdb_get_username(pwd
)));
2963 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
2965 ZERO_STRUCT(plaintext_buf
);
2967 if (!decode_pw_buffer(pass
, plaintext_buf
, 256, &len
, STR_UNICODE
)) {
2972 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
2977 /* if it's a trust account, don't update /etc/passwd */
2978 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
2979 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
2980 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
2981 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2983 /* update the UNIX password */
2984 if (lp_unix_password_sync()) {
2985 struct passwd
*passwd
= Get_Pwnam(pdb_get_username(pwd
));
2987 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2990 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
2997 ZERO_STRUCT(plaintext_buf
);
2999 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3001 /* update the SAMBA password */
3002 if(!pdb_update_sam_account(pwd
)) {
3012 /*******************************************************************
3013 samr_reply_set_userinfo
3014 ********************************************************************/
3016 NTSTATUS
_samr_set_userinfo(pipes_struct
*p
, SAMR_Q_SET_USERINFO
*q_u
, SAMR_R_SET_USERINFO
*r_u
)
3018 SAM_ACCOUNT
*pwd
= NULL
;
3020 POLICY_HND
*pol
= &q_u
->pol
;
3021 uint16 switch_value
= q_u
->switch_value
;
3022 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
3024 uint32 acc_required
;
3026 BOOL has_enough_rights
= False
;
3029 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__
));
3031 r_u
->status
= NT_STATUS_OK
;
3033 /* find the policy handle. open a policy on it. */
3034 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
, &acc_granted
))
3035 return NT_STATUS_INVALID_HANDLE
;
3037 /* observed when joining an XP client to a Samba domain */
3039 acc_required
= SA_RIGHT_USER_SET_PASSWORD
| SA_RIGHT_USER_SET_ATTRIBUTES
| SA_RIGHT_USER_ACCT_FLAGS_EXPIRY
;
3041 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, acc_required
, "_samr_set_userinfo"))) {
3045 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid
), switch_value
));
3048 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3049 return NT_STATUS_INVALID_INFO_CLASS
;
3055 ret
= pdb_getsampwsid(pwd
, &sid
);
3060 return NT_STATUS_NO_SUCH_USER
;
3063 /* deal with machine password changes differently from userinfo changes */
3064 /* check to see if we have the sufficient rights */
3066 acb_info
= pdb_get_acct_ctrl(pwd
);
3067 if ( acb_info
& ACB_WSTRUST
)
3068 has_enough_rights
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_machine_account
);
3069 else if ( acb_info
& ACB_NORMAL
)
3070 has_enough_rights
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_add_users
);
3071 else if ( acb_info
& (ACB_SVRTRUST
|ACB_DOMTRUST
) ) {
3072 if ( lp_enable_privileges() )
3073 has_enough_rights
= nt_token_check_domain_rid( p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
);
3076 DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3077 p
->pipe_user_name
, has_enough_rights
? "" : " not"));
3079 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3081 if ( has_enough_rights
)
3084 /* ok! user info levels (lots: see MSDEV help), off we go... */
3086 switch (switch_value
) {
3088 if (!set_user_info_12(ctr
->info
.id12
, pwd
))
3089 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3093 if (!p
->session_key
.length
) {
3094 r_u
->status
= NT_STATUS_NO_USER_SESSION_KEY
;
3096 SamOEMhashBlob(ctr
->info
.id24
->pass
, 516, &p
->session_key
);
3098 dump_data(100, (char *)ctr
->info
.id24
->pass
, 516);
3100 if (!set_user_info_pw((char *)ctr
->info
.id24
->pass
, pwd
))
3101 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3107 * Currently we don't really know how to unmarshall
3108 * the level 25 struct, and the password encryption
3109 * is different. This is a placeholder for when we
3110 * do understand it. In the meantime just return INVALID
3111 * info level and W2K SP2 drops down to level 23... JRA.
3114 if (!p
->session_key
.length
) {
3115 r_u
->status
= NT_STATUS_NO_USER_SESSION_KEY
;
3117 SamOEMhashBlob(ctr
->info
.id25
->pass
, 532, &p
->session_key
);
3119 dump_data(100, (char *)ctr
->info
.id25
->pass
, 532);
3121 if (!set_user_info_pw(ctr
->info
.id25
->pass
, &sid
))
3122 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3125 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
3129 if (!p
->session_key
.length
) {
3130 r_u
->status
= NT_STATUS_NO_USER_SESSION_KEY
;
3132 SamOEMhashBlob(ctr
->info
.id23
->pass
, 516, &p
->session_key
);
3134 dump_data(100, (char *)ctr
->info
.id23
->pass
, 516);
3136 if (!set_user_info_23(ctr
->info
.id23
, pwd
))
3137 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3141 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
3145 if ( has_enough_rights
)
3148 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3153 /*******************************************************************
3154 samr_reply_set_userinfo2
3155 ********************************************************************/
3157 NTSTATUS
_samr_set_userinfo2(pipes_struct
*p
, SAMR_Q_SET_USERINFO2
*q_u
, SAMR_R_SET_USERINFO2
*r_u
)
3159 SAM_ACCOUNT
*pwd
= NULL
;
3161 SAM_USERINFO_CTR
*ctr
= q_u
->ctr
;
3162 POLICY_HND
*pol
= &q_u
->pol
;
3163 uint16 switch_value
= q_u
->switch_value
;
3165 uint32 acc_required
;
3167 BOOL has_enough_rights
= False
;
3170 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__
));
3172 r_u
->status
= NT_STATUS_OK
;
3174 /* find the policy handle. open a policy on it. */
3175 if (!get_lsa_policy_samr_sid(p
, pol
, &sid
, &acc_granted
))
3176 return NT_STATUS_INVALID_HANDLE
;
3178 /* observed when joining XP client to Samba domain */
3180 acc_required
= SA_RIGHT_USER_SET_PASSWORD
| SA_RIGHT_USER_SET_ATTRIBUTES
| SA_RIGHT_USER_ACCT_FLAGS_EXPIRY
;
3182 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, acc_required
, "_samr_set_userinfo2"))) {
3186 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid
)));
3189 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3190 return NT_STATUS_INVALID_INFO_CLASS
;
3193 switch_value
=ctr
->switch_value
;
3198 ret
= pdb_getsampwsid(pwd
, &sid
);
3203 return NT_STATUS_NO_SUCH_USER
;
3206 acb_info
= pdb_get_acct_ctrl(pwd
);
3207 if ( acb_info
& ACB_WSTRUST
)
3208 has_enough_rights
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_machine_account
);
3209 else if ( acb_info
& ACB_NORMAL
)
3210 has_enough_rights
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_add_users
);
3211 else if ( acb_info
& (ACB_SVRTRUST
|ACB_DOMTRUST
) ) {
3212 if ( lp_enable_privileges() )
3213 has_enough_rights
= nt_token_check_domain_rid( p
->pipe_user
.nt_user_token
, DOMAIN_GROUP_RID_ADMINS
);
3216 DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3217 p
->pipe_user_name
, has_enough_rights
? "" : " not"));
3219 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3221 if ( has_enough_rights
)
3224 /* ok! user info levels (lots: see MSDEV help), off we go... */
3226 switch (switch_value
) {
3228 if (!set_user_info_10(ctr
->info
.id10
, pwd
))
3229 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3232 /* Used by AS/U JRA. */
3233 if (!set_user_info_12(ctr
->info
.id12
, pwd
))
3234 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3237 if (!set_user_info_20(ctr
->info
.id20
, pwd
))
3238 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
3241 if (!set_user_info_21(ctr
->info
.id21
, pwd
))
3242 return NT_STATUS_ACCESS_DENIED
;
3245 r_u
->status
= NT_STATUS_INVALID_INFO_CLASS
;
3248 if ( has_enough_rights
)
3251 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3256 /*********************************************************************
3257 _samr_query_aliasmem
3258 *********************************************************************/
3260 NTSTATUS
_samr_query_useraliases(pipes_struct
*p
, SAMR_Q_QUERY_USERALIASES
*q_u
, SAMR_R_QUERY_USERALIASES
*r_u
)
3264 struct samr_info
*info
= NULL
;
3275 r_u
->status
= NT_STATUS_OK
;
3277 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__
));
3279 /* find the policy handle. open a policy on it. */
3280 if (!find_policy_by_hnd(p
, &q_u
->pol
, (void **)&info
))
3281 return NT_STATUS_INVALID_HANDLE
;
3283 ntstatus1
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM
, "_samr_query_useraliases");
3284 ntstatus2
= access_check_samr_function(info
->acc_granted
, SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_query_useraliases");
3286 if (!NT_STATUS_IS_OK(ntstatus1
) || !NT_STATUS_IS_OK(ntstatus2
)) {
3287 if (!(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus2
)) &&
3288 !(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus1
))) {
3289 return (NT_STATUS_IS_OK(ntstatus1
)) ? ntstatus2
: ntstatus1
;
3293 if (!sid_check_is_domain(&info
->sid
) &&
3294 !sid_check_is_builtin(&info
->sid
))
3295 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3297 members
= TALLOC_ARRAY(p
->mem_ctx
, DOM_SID
, q_u
->num_sids1
);
3299 if (members
== NULL
)
3300 return NT_STATUS_NO_MEMORY
;
3302 for (i
=0; i
<q_u
->num_sids1
; i
++)
3303 sid_copy(&members
[i
], &q_u
->sid
[i
].sid
);
3306 res
= pdb_enum_alias_memberships(members
,
3307 q_u
->num_sids1
, &aliases
,
3312 return NT_STATUS_UNSUCCESSFUL
;
3317 for (i
=0; i
<num_aliases
; i
++) {
3320 if (!sid_peek_check_rid(&info
->sid
, &aliases
[i
], &rid
))
3323 rids
= TALLOC_REALLOC_ARRAY(p
->mem_ctx
, rids
, uint32
, num_groups
+1);
3326 return NT_STATUS_NO_MEMORY
;
3328 rids
[num_groups
] = rid
;
3333 init_samr_r_query_useraliases(r_u
, num_groups
, rids
, NT_STATUS_OK
);
3334 return NT_STATUS_OK
;
3337 /*********************************************************************
3338 _samr_query_aliasmem
3339 *********************************************************************/
3341 NTSTATUS
_samr_query_aliasmem(pipes_struct
*p
, SAMR_Q_QUERY_ALIASMEM
*q_u
, SAMR_R_QUERY_ALIASMEM
*r_u
)
3353 /* find the policy handle. open a policy on it. */
3354 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3355 return NT_STATUS_INVALID_HANDLE
;
3357 if (!NT_STATUS_IS_OK(r_u
->status
=
3358 access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_GET_MEMBERS
, "_samr_query_aliasmem"))) {
3362 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid
)));
3364 if (!pdb_enum_aliasmem(&alias_sid
, &sids
, &num_sids
))
3365 return NT_STATUS_NO_SUCH_ALIAS
;
3367 sid
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, DOM_SID2
, num_sids
);
3368 if (num_sids
!=0 && sid
== NULL
) {
3370 return NT_STATUS_NO_MEMORY
;
3373 for (i
= 0; i
< num_sids
; i
++) {
3374 init_dom_sid2(&sid
[i
], &sids
[i
]);
3377 init_samr_r_query_aliasmem(r_u
, num_sids
, sid
, NT_STATUS_OK
);
3381 return NT_STATUS_OK
;
3384 static void add_uid_to_array_unique(uid_t uid
, uid_t
**uids
, int *num
)
3388 for (i
=0; i
<*num
; i
++) {
3389 if ((*uids
)[i
] == uid
)
3393 *uids
= SMB_REALLOC_ARRAY(*uids
, uid_t
, *num
+1);
3398 (*uids
)[*num
] = uid
;
3403 static BOOL
get_memberuids(gid_t gid
, uid_t
**uids
, int *num
)
3407 struct sys_pwent
*userlist
, *user
;
3412 /* We only look at our own sam, so don't care about imported stuff */
3416 if ((grp
= getgrgid(gid
)) == NULL
) {
3421 /* Primary group members */
3423 userlist
= getpwent_list();
3425 for (user
= userlist
; user
!= NULL
; user
= user
->next
) {
3426 if (user
->pw_gid
!= gid
)
3428 add_uid_to_array_unique(user
->pw_uid
, uids
, num
);
3431 pwent_free(userlist
);
3433 /* Secondary group members */
3435 for (gr
= grp
->gr_mem
; (*gr
!= NULL
) && ((*gr
)[0] != '\0'); gr
+= 1) {
3436 struct passwd
*pw
= getpwnam(*gr
);
3440 add_uid_to_array_unique(pw
->pw_uid
, uids
, num
);
3448 /*********************************************************************
3449 _samr_query_groupmem
3450 *********************************************************************/
3452 NTSTATUS
_samr_query_groupmem(pipes_struct
*p
, SAMR_Q_QUERY_GROUPMEM
*q_u
, SAMR_R_QUERY_GROUPMEM
*r_u
)
3455 fstring group_sid_str
;
3465 /* find the policy handle. open a policy on it. */
3466 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
, &acc_granted
))
3467 return NT_STATUS_INVALID_HANDLE
;
3469 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_GET_MEMBERS
, "_samr_query_groupmem"))) {
3473 sid_to_string(group_sid_str
, &group_sid
);
3474 DEBUG(10, ("sid is %s\n", group_sid_str
));
3476 if (!sid_check_is_in_our_domain(&group_sid
)) {
3477 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str
));
3478 return NT_STATUS_NO_SUCH_GROUP
;
3481 DEBUG(10, ("lookup on Domain SID\n"));
3484 result
= pdb_enum_group_members(p
->mem_ctx
, &group_sid
,
3485 &rid
, &num_members
);
3488 if (!NT_STATUS_IS_OK(result
))
3491 attr
=TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_members
);
3493 if ((num_members
!=0) && (rid
==NULL
))
3494 return NT_STATUS_NO_MEMORY
;
3496 for (i
=0; i
<num_members
; i
++)
3497 attr
[i
] = SID_NAME_USER
;
3499 init_samr_r_query_groupmem(r_u
, num_members
, rid
, attr
, NT_STATUS_OK
);
3501 return NT_STATUS_OK
;
3504 /*********************************************************************
3506 *********************************************************************/
3508 NTSTATUS
_samr_add_aliasmem(pipes_struct
*p
, SAMR_Q_ADD_ALIASMEM
*q_u
, SAMR_R_ADD_ALIASMEM
*r_u
)
3513 BOOL can_add_accounts
;
3517 /* Find the policy handle. Open a policy on it. */
3518 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3519 return NT_STATUS_INVALID_HANDLE
;
3521 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_ADD_MEMBER
, "_samr_add_aliasmem"))) {
3525 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid
)));
3527 se_priv_copy( &se_rights
, &se_add_users
);
3528 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
3530 /******** BEGIN SeAddUsers BLOCK *********/
3532 if ( can_add_accounts
)
3535 ret
= pdb_add_aliasmem(&alias_sid
, &q_u
->sid
.sid
);
3537 if ( can_add_accounts
)
3540 /******** END SeAddUsers BLOCK *********/
3542 return ret
? NT_STATUS_OK
: NT_STATUS_ACCESS_DENIED
;
3545 /*********************************************************************
3547 *********************************************************************/
3549 NTSTATUS
_samr_del_aliasmem(pipes_struct
*p
, SAMR_Q_DEL_ALIASMEM
*q_u
, SAMR_R_DEL_ALIASMEM
*r_u
)
3554 BOOL can_add_accounts
;
3557 /* Find the policy handle. Open a policy on it. */
3558 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3559 return NT_STATUS_INVALID_HANDLE
;
3561 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_REMOVE_MEMBER
, "_samr_del_aliasmem"))) {
3565 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3566 sid_string_static(&alias_sid
)));
3568 se_priv_copy( &se_rights
, &se_add_users
);
3569 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
3571 /******** BEGIN SeAddUsers BLOCK *********/
3573 if ( can_add_accounts
)
3576 ret
= pdb_del_aliasmem(&alias_sid
, &q_u
->sid
.sid
);
3578 if ( can_add_accounts
)
3581 /******** END SeAddUsers BLOCK *********/
3583 return ret
? NT_STATUS_OK
: NT_STATUS_ACCESS_DENIED
;
3586 /*********************************************************************
3588 *********************************************************************/
3590 NTSTATUS
_samr_add_groupmem(pipes_struct
*p
, SAMR_Q_ADD_GROUPMEM
*q_u
, SAMR_R_ADD_GROUPMEM
*r_u
)
3594 fstring group_sid_str
;
3601 SAM_ACCOUNT
*sam_user
=NULL
;
3605 BOOL can_add_accounts
;
3607 /* Find the policy handle. Open a policy on it. */
3608 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
3609 return NT_STATUS_INVALID_HANDLE
;
3611 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_ADD_MEMBER
, "_samr_add_groupmem"))) {
3615 sid_to_string(group_sid_str
, &group_sid
);
3616 DEBUG(10, ("sid is %s\n", group_sid_str
));
3618 if (sid_compare(&group_sid
, get_global_sam_sid())<=0)
3619 return NT_STATUS_NO_SUCH_GROUP
;
3621 DEBUG(10, ("lookup on Domain SID\n"));
3623 if(!get_domain_group_from_sid(group_sid
, &map
))
3624 return NT_STATUS_NO_SUCH_GROUP
;
3626 sid_copy(&user_sid
, get_global_sam_sid());
3627 sid_append_rid(&user_sid
, q_u
->rid
);
3629 ret
= pdb_init_sam(&sam_user
);
3630 if (!NT_STATUS_IS_OK(ret
))
3633 check
= pdb_getsampwsid(sam_user
, &user_sid
);
3635 if (check
!= True
) {
3636 pdb_free_sam(&sam_user
);
3637 return NT_STATUS_NO_SUCH_USER
;
3640 /* check a real user exist before we run the script to add a user to a group */
3641 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user
), &uid
))) {
3642 pdb_free_sam(&sam_user
);
3643 return NT_STATUS_NO_SUCH_USER
;
3646 pdb_free_sam(&sam_user
);
3648 if ((pwd
=getpwuid_alloc(uid
)) == NULL
) {
3649 return NT_STATUS_NO_SUCH_USER
;
3652 if ((grp
=getgrgid(map
.gid
)) == NULL
) {
3654 return NT_STATUS_NO_SUCH_GROUP
;
3657 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3658 fstrcpy(grp_name
, grp
->gr_name
);
3660 /* if the user is already in the group */
3661 if(user_in_unix_group_list(pwd
->pw_name
, grp_name
)) {
3663 return NT_STATUS_MEMBER_IN_GROUP
;
3666 se_priv_copy( &se_rights
, &se_add_users
);
3667 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
3669 /******** BEGIN SeAddUsers BLOCK *********/
3671 if ( can_add_accounts
)
3675 * ok, the group exist, the user exist, the user is not in the group,
3677 * we can (finally) add it to the group !
3680 smb_add_user_group(grp_name
, pwd
->pw_name
);
3682 if ( can_add_accounts
)
3685 /******** END SeAddUsers BLOCK *********/
3687 /* check if the user has been added then ... */
3688 if(!user_in_unix_group_list(pwd
->pw_name
, grp_name
)) {
3690 return NT_STATUS_MEMBER_NOT_IN_GROUP
; /* don't know what to reply else */
3694 return NT_STATUS_OK
;
3697 /*********************************************************************
3699 *********************************************************************/
3701 NTSTATUS
_samr_del_groupmem(pipes_struct
*p
, SAMR_Q_DEL_GROUPMEM
*q_u
, SAMR_R_DEL_GROUPMEM
*r_u
)
3705 SAM_ACCOUNT
*sam_pass
=NULL
;
3711 BOOL can_add_accounts
;
3714 * delete the group member named q_u->rid
3715 * who is a member of the sid associated with the handle
3716 * the rid is a user's rid as the group is a domain group.
3719 /* Find the policy handle. Open a policy on it. */
3720 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
3721 return NT_STATUS_INVALID_HANDLE
;
3723 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_REMOVE_MEMBER
, "_samr_del_groupmem"))) {
3727 if (!sid_check_is_in_our_domain(&group_sid
))
3728 return NT_STATUS_NO_SUCH_GROUP
;
3730 sid_copy(&user_sid
, get_global_sam_sid());
3731 sid_append_rid(&user_sid
, q_u
->rid
);
3733 if (!get_domain_group_from_sid(group_sid
, &map
))
3734 return NT_STATUS_NO_SUCH_GROUP
;
3736 if ((grp
=getgrgid(map
.gid
)) == NULL
)
3737 return NT_STATUS_NO_SUCH_GROUP
;
3739 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3740 fstrcpy(grp_name
, grp
->gr_name
);
3742 /* check if the user exists before trying to remove it from the group */
3743 pdb_init_sam(&sam_pass
);
3744 if (!pdb_getsampwsid(sam_pass
, &user_sid
)) {
3745 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass
)));
3746 pdb_free_sam(&sam_pass
);
3747 return NT_STATUS_NO_SUCH_USER
;
3750 /* if the user is not in the group */
3751 if (!user_in_unix_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3752 pdb_free_sam(&sam_pass
);
3753 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
3757 se_priv_copy( &se_rights
, &se_add_users
);
3758 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
3760 /******** BEGIN SeAddUsers BLOCK *********/
3762 if ( can_add_accounts
)
3765 smb_delete_user_group(grp_name
, pdb_get_username(sam_pass
));
3767 if ( can_add_accounts
)
3770 /******** END SeAddUsers BLOCK *********/
3772 /* check if the user has been removed then ... */
3773 if (user_in_unix_group_list(pdb_get_username(sam_pass
), grp_name
)) {
3774 pdb_free_sam(&sam_pass
);
3775 return NT_STATUS_ACCESS_DENIED
; /* don't know what to reply else */
3778 pdb_free_sam(&sam_pass
);
3779 return NT_STATUS_OK
;
3783 /****************************************************************************
3784 Delete a UNIX user on demand.
3785 ****************************************************************************/
3787 static int smb_delete_user(const char *unix_user
)
3792 /* try winbindd first since it is impossible to determine where
3793 a user came from via NSS. Try the delete user script if this fails
3794 meaning the user did not exist in winbindd's list of accounts */
3796 if ( winbind_delete_user( unix_user
) ) {
3797 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user
));
3802 /* fall back to 'delete user script' */
3804 pstrcpy(del_script
, lp_deluser_script());
3807 all_string_sub(del_script
, "%u", unix_user
, sizeof(del_script
));
3808 ret
= smbrun(del_script
,NULL
);
3809 flush_pwnam_cache();
3810 DEBUG(ret
? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script
,ret
));
3815 /*********************************************************************
3816 _samr_delete_dom_user
3817 *********************************************************************/
3819 NTSTATUS
_samr_delete_dom_user(pipes_struct
*p
, SAMR_Q_DELETE_DOM_USER
*q_u
, SAMR_R_DELETE_DOM_USER
*r_u
)
3822 SAM_ACCOUNT
*sam_pass
=NULL
;
3825 BOOL can_add_accounts
;
3828 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__
));
3830 /* Find the policy handle. Open a policy on it. */
3831 if (!get_lsa_policy_samr_sid(p
, &q_u
->user_pol
, &user_sid
, &acc_granted
))
3832 return NT_STATUS_INVALID_HANDLE
;
3834 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_user"))) {
3838 if (!sid_check_is_in_our_domain(&user_sid
))
3839 return NT_STATUS_CANNOT_DELETE
;
3841 /* check if the user exists before trying to delete */
3842 pdb_init_sam(&sam_pass
);
3843 if(!pdb_getsampwsid(sam_pass
, &user_sid
)) {
3844 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3845 sid_string_static(&user_sid
)));
3846 pdb_free_sam(&sam_pass
);
3847 return NT_STATUS_NO_SUCH_USER
;
3850 se_priv_copy( &se_rights
, &se_add_users
);
3851 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
3853 /******** BEGIN SeAddUsers BLOCK *********/
3855 if ( can_add_accounts
)
3858 /* First delete the samba side....
3859 code is order to prevent unnecessary returns out of the admin
3862 if ( (ret
= pdb_delete_sam_account(sam_pass
)) == True
) {
3864 * Now delete the unix side ....
3865 * note: we don't check if the delete really happened
3866 * as the script is not necessary present
3867 * and maybe the sysadmin doesn't want to delete the unix side
3869 smb_delete_user( pdb_get_username(sam_pass
) );
3872 if ( can_add_accounts
)
3875 /******** END SeAddUsers BLOCK *********/
3878 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass
)));
3879 pdb_free_sam(&sam_pass
);
3880 return NT_STATUS_CANNOT_DELETE
;
3884 pdb_free_sam(&sam_pass
);
3886 if (!close_policy_hnd(p
, &q_u
->user_pol
))
3887 return NT_STATUS_OBJECT_NAME_INVALID
;
3889 return NT_STATUS_OK
;
3892 /*********************************************************************
3893 _samr_delete_dom_group
3894 *********************************************************************/
3896 NTSTATUS
_samr_delete_dom_group(pipes_struct
*p
, SAMR_Q_DELETE_DOM_GROUP
*q_u
, SAMR_R_DELETE_DOM_GROUP
*r_u
)
3901 fstring group_sid_str
;
3907 BOOL can_add_accounts
;
3910 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__
));
3912 /* Find the policy handle. Open a policy on it. */
3913 if (!get_lsa_policy_samr_sid(p
, &q_u
->group_pol
, &group_sid
, &acc_granted
))
3914 return NT_STATUS_INVALID_HANDLE
;
3916 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_group"))) {
3920 sid_copy(&dom_sid
, &group_sid
);
3921 sid_to_string(group_sid_str
, &dom_sid
);
3922 sid_split_rid(&dom_sid
, &group_rid
);
3924 DEBUG(10, ("sid is %s\n", group_sid_str
));
3926 /* we check if it's our SID before deleting */
3927 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
3928 return NT_STATUS_NO_SUCH_GROUP
;
3930 DEBUG(10, ("lookup on Domain SID\n"));
3932 if(!get_domain_group_from_sid(group_sid
, &map
))
3933 return NT_STATUS_NO_SUCH_GROUP
;
3937 /* check if group really exists */
3938 if ( (grp
=getgrgid(gid
)) == NULL
)
3939 return NT_STATUS_NO_SUCH_GROUP
;
3941 se_priv_copy( &se_rights
, &se_add_users
);
3942 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
3944 /******** BEGIN SeAddUsers BLOCK *********/
3946 if ( can_add_accounts
)
3949 /* delete mapping first */
3951 if ( (ret
= pdb_delete_group_mapping_entry(group_sid
)) == True
) {
3952 smb_delete_group( grp
->gr_name
);
3955 if ( can_add_accounts
)
3958 /******** END SeAddUsers BLOCK *********/
3961 DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n",
3963 return NT_STATUS_ACCESS_DENIED
;
3966 /* don't check that the unix group has been deleted. Work like
3967 _samr_delet_dom_user() */
3969 if (!close_policy_hnd(p
, &q_u
->group_pol
))
3970 return NT_STATUS_OBJECT_NAME_INVALID
;
3972 return NT_STATUS_OK
;
3975 /*********************************************************************
3976 _samr_delete_dom_alias
3977 *********************************************************************/
3979 NTSTATUS
_samr_delete_dom_alias(pipes_struct
*p
, SAMR_Q_DELETE_DOM_ALIAS
*q_u
, SAMR_R_DELETE_DOM_ALIAS
*r_u
)
3984 BOOL can_add_accounts
;
3987 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__
));
3989 /* Find the policy handle. Open a policy on it. */
3990 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &alias_sid
, &acc_granted
))
3991 return NT_STATUS_INVALID_HANDLE
;
3993 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
, "_samr_delete_dom_alias"))) {
3997 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid
)));
3999 if (!sid_check_is_in_our_domain(&alias_sid
))
4000 return NT_STATUS_NO_SUCH_ALIAS
;
4002 DEBUG(10, ("lookup on Local SID\n"));
4004 se_priv_copy( &se_rights
, &se_add_users
);
4005 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
4007 /******** BEGIN SeAddUsers BLOCK *********/
4009 if ( can_add_accounts
)
4012 /* Have passdb delete the alias */
4013 ret
= pdb_delete_alias(&alias_sid
);
4015 if ( can_add_accounts
)
4018 /******** END SeAddUsers BLOCK *********/
4021 return NT_STATUS_ACCESS_DENIED
;
4023 if (!close_policy_hnd(p
, &q_u
->alias_pol
))
4024 return NT_STATUS_OBJECT_NAME_INVALID
;
4026 return NT_STATUS_OK
;
4029 /*********************************************************************
4030 _samr_create_dom_group
4031 *********************************************************************/
4033 NTSTATUS
_samr_create_dom_group(pipes_struct
*p
, SAMR_Q_CREATE_DOM_GROUP
*q_u
, SAMR_R_CREATE_DOM_GROUP
*r_u
)
4040 struct samr_info
*info
;
4044 BOOL can_add_accounts
;
4047 /* Find the policy handle. Open a policy on it. */
4048 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &dom_sid
, &acc_granted
))
4049 return NT_STATUS_INVALID_HANDLE
;
4051 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_CREATE_GROUP
, "_samr_create_dom_group"))) {
4055 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
4056 return NT_STATUS_ACCESS_DENIED
;
4058 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
4060 /* check if group already exist */
4061 if ((grp
=getgrnam(name
)) != NULL
)
4062 return NT_STATUS_GROUP_EXISTS
;
4064 se_priv_copy( &se_rights
, &se_add_users
);
4065 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
4067 /******** BEGIN SeAddUsers BLOCK *********/
4069 if ( can_add_accounts
)
4072 /* check that we successfully create the UNIX group */
4074 result
= NT_STATUS_ACCESS_DENIED
;
4075 if ( (smb_create_group(name
, &gid
) == 0) && ((grp
=getgrgid(gid
)) != NULL
) ) {
4077 /* so far, so good */
4079 result
= NT_STATUS_OK
;
4081 r_u
->rid
= pdb_gid_to_group_rid( grp
->gr_gid
);
4083 /* add the group to the mapping table */
4085 sid_copy( &info_sid
, get_global_sam_sid() );
4086 sid_append_rid( &info_sid
, r_u
->rid
);
4087 sid_to_string( sid_string
, &info_sid
);
4089 /* reset the error code if we fail to add the mapping entry */
4091 if ( !add_initial_entry(grp
->gr_gid
, sid_string
, SID_NAME_DOM_GRP
, name
, NULL
) )
4092 result
= NT_STATUS_ACCESS_DENIED
;
4095 if ( can_add_accounts
)
4098 /******** END SeAddUsers BLOCK *********/
4100 /* check if we should bail out here */
4102 if ( !NT_STATUS_IS_OK(result
) )
4105 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4106 return NT_STATUS_NO_MEMORY
;
4108 /* get a (unique) handle. open a policy on it. */
4109 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
4110 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4112 return NT_STATUS_OK
;
4115 /*********************************************************************
4116 _samr_create_dom_alias
4117 *********************************************************************/
4119 NTSTATUS
_samr_create_dom_alias(pipes_struct
*p
, SAMR_Q_CREATE_DOM_ALIAS
*q_u
, SAMR_R_CREATE_DOM_ALIAS
*r_u
)
4125 struct samr_info
*info
;
4130 BOOL can_add_accounts
;
4132 /* Find the policy handle. Open a policy on it. */
4133 if (!get_lsa_policy_samr_sid(p
, &q_u
->dom_pol
, &dom_sid
, &acc_granted
))
4134 return NT_STATUS_INVALID_HANDLE
;
4136 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_DOMAIN_CREATE_ALIAS
, "_samr_create_alias"))) {
4140 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
4141 return NT_STATUS_ACCESS_DENIED
;
4143 unistr2_to_ascii(name
, &q_u
->uni_acct_desc
, sizeof(name
)-1);
4145 se_priv_copy( &se_rights
, &se_add_users
);
4146 can_add_accounts
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_rights
);
4148 /******** BEGIN SeAddUsers BLOCK *********/
4150 if ( can_add_accounts
)
4153 /* Have passdb create the alias */
4154 result
= pdb_create_alias(name
, &r_u
->rid
);
4156 if ( can_add_accounts
)
4159 /******** END SeAddUsers BLOCK *********/
4161 if (!NT_STATUS_IS_OK(result
))
4164 sid_copy(&info_sid
, get_global_sam_sid());
4165 sid_append_rid(&info_sid
, r_u
->rid
);
4167 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid
, &gid
)))
4168 return NT_STATUS_ACCESS_DENIED
;
4170 /* check if the group has been successfully created */
4171 if ((grp
=getgrgid(gid
)) == NULL
)
4172 return NT_STATUS_ACCESS_DENIED
;
4174 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4175 return NT_STATUS_NO_MEMORY
;
4177 /* get a (unique) handle. open a policy on it. */
4178 if (!create_policy_hnd(p
, &r_u
->alias_pol
, free_samr_info
, (void *)info
))
4179 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4181 return NT_STATUS_OK
;
4184 /*********************************************************************
4185 _samr_query_groupinfo
4187 sends the name/comment pair of a domain group
4188 level 1 send also the number of users of that group
4189 *********************************************************************/
4191 NTSTATUS
_samr_query_groupinfo(pipes_struct
*p
, SAMR_Q_QUERY_GROUPINFO
*q_u
, SAMR_R_QUERY_GROUPINFO
*r_u
)
4198 GROUP_INFO_CTR
*ctr
;
4202 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
4203 return NT_STATUS_INVALID_HANDLE
;
4205 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_LOOKUP_INFO
, "_samr_query_groupinfo"))) {
4210 ret
= get_domain_group_from_sid(group_sid
, &map
);
4213 return NT_STATUS_INVALID_HANDLE
;
4215 ctr
=TALLOC_ZERO_P(p
->mem_ctx
, GROUP_INFO_CTR
);
4217 return NT_STATUS_NO_MEMORY
;
4219 switch (q_u
->switch_level
) {
4221 ctr
->switch_value1
= 1;
4222 if(!get_memberuids(map
.gid
, &uids
, &num
))
4223 return NT_STATUS_NO_SUCH_GROUP
;
4225 init_samr_group_info1(&ctr
->group
.info1
, map
.nt_name
, map
.comment
, num
);
4229 ctr
->switch_value1
= 3;
4230 init_samr_group_info3(&ctr
->group
.info3
);
4233 ctr
->switch_value1
= 4;
4234 init_samr_group_info4(&ctr
->group
.info4
, map
.comment
);
4237 return NT_STATUS_INVALID_INFO_CLASS
;
4240 init_samr_r_query_groupinfo(r_u
, ctr
, NT_STATUS_OK
);
4242 return NT_STATUS_OK
;
4245 /*********************************************************************
4248 update a domain group's comment.
4249 *********************************************************************/
4251 NTSTATUS
_samr_set_groupinfo(pipes_struct
*p
, SAMR_Q_SET_GROUPINFO
*q_u
, SAMR_R_SET_GROUPINFO
*r_u
)
4255 GROUP_INFO_CTR
*ctr
;
4258 if (!get_lsa_policy_samr_sid(p
, &q_u
->pol
, &group_sid
, &acc_granted
))
4259 return NT_STATUS_INVALID_HANDLE
;
4261 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_GROUP_SET_INFO
, "_samr_set_groupinfo"))) {
4265 if (!get_domain_group_from_sid(group_sid
, &map
))
4266 return NT_STATUS_NO_SUCH_GROUP
;
4270 switch (ctr
->switch_value1
) {
4272 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info1
.uni_acct_desc
), sizeof(map
.comment
)-1);
4275 unistr2_to_ascii(map
.comment
, &(ctr
->group
.info4
.uni_acct_desc
), sizeof(map
.comment
)-1);
4278 return NT_STATUS_INVALID_INFO_CLASS
;
4281 if(!pdb_update_group_mapping_entry(&map
)) {
4282 return NT_STATUS_NO_SUCH_GROUP
;
4285 return NT_STATUS_OK
;
4288 /*********************************************************************
4291 update an alias's comment.
4292 *********************************************************************/
4294 NTSTATUS
_samr_set_aliasinfo(pipes_struct
*p
, SAMR_Q_SET_ALIASINFO
*q_u
, SAMR_R_SET_ALIASINFO
*r_u
)
4297 struct acct_info info
;
4298 ALIAS_INFO_CTR
*ctr
;
4301 if (!get_lsa_policy_samr_sid(p
, &q_u
->alias_pol
, &group_sid
, &acc_granted
))
4302 return NT_STATUS_INVALID_HANDLE
;
4304 if (!NT_STATUS_IS_OK(r_u
->status
= access_check_samr_function(acc_granted
, SA_RIGHT_ALIAS_SET_INFO
, "_samr_set_aliasinfo"))) {
4310 switch (ctr
->switch_value1
) {
4312 unistr2_to_ascii(info
.acct_desc
,
4313 &(ctr
->alias
.info3
.uni_acct_desc
),
4314 sizeof(info
.acct_desc
)-1);
4317 return NT_STATUS_INVALID_INFO_CLASS
;
4320 if(!pdb_set_aliasinfo(&group_sid
, &info
)) {
4321 return NT_STATUS_ACCESS_DENIED
;
4324 return NT_STATUS_OK
;
4327 /*********************************************************************
4328 _samr_get_dom_pwinfo
4329 *********************************************************************/
4331 NTSTATUS
_samr_get_dom_pwinfo(pipes_struct
*p
, SAMR_Q_GET_DOM_PWINFO
*q_u
, SAMR_R_GET_DOM_PWINFO
*r_u
)
4333 /* Perform access check. Since this rpc does not require a
4334 policy handle it will not be caught by the access checks on
4335 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4337 if (!pipe_access_check(p
)) {
4338 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4339 r_u
->status
= NT_STATUS_ACCESS_DENIED
;
4343 /* Actually, returning zeros here works quite well :-). */
4345 return NT_STATUS_OK
;
4348 /*********************************************************************
4350 *********************************************************************/
4352 NTSTATUS
_samr_open_group(pipes_struct
*p
, SAMR_Q_OPEN_GROUP
*q_u
, SAMR_R_OPEN_GROUP
*r_u
)
4357 struct samr_info
*info
;
4358 SEC_DESC
*psd
= NULL
;
4360 uint32 des_access
= q_u
->access_mask
;
4367 if (!get_lsa_policy_samr_sid(p
, &q_u
->domain_pol
, &sid
, &acc_granted
))
4368 return NT_STATUS_INVALID_HANDLE
;
4370 status
= access_check_samr_function(acc_granted
,
4371 SA_RIGHT_DOMAIN_OPEN_ACCOUNT
, "_samr_open_group");
4373 if ( !NT_STATUS_IS_OK(status
) )
4376 /*check if access can be granted as requested by client. */
4377 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &grp_generic_mapping
, NULL
, 0);
4378 se_map_generic(&des_access
,&grp_generic_mapping
);
4380 se_priv_copy( &se_rights
, &se_add_users
);
4382 status
= access_check_samr_object(psd
, p
->pipe_user
.nt_user_token
,
4383 &se_rights
, GENERIC_RIGHTS_GROUP_WRITE
, des_access
,
4384 &acc_granted
, "_samr_open_group");
4386 if ( !NT_STATUS_IS_OK(status
) )
4389 /* this should not be hard-coded like this */
4391 if (!sid_equal(&sid
, get_global_sam_sid()))
4392 return NT_STATUS_ACCESS_DENIED
;
4394 sid_copy(&info_sid
, get_global_sam_sid());
4395 sid_append_rid(&info_sid
, q_u
->rid_group
);
4396 sid_to_string(sid_string
, &info_sid
);
4398 if ((info
= get_samr_info_by_sid(&info_sid
)) == NULL
)
4399 return NT_STATUS_NO_MEMORY
;
4401 info
->acc_granted
= acc_granted
;
4403 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string
));
4405 /* check if that group really exists */
4407 ret
= get_domain_group_from_sid(info
->sid
, &map
);
4410 return NT_STATUS_NO_SUCH_GROUP
;
4412 /* get a (unique) handle. open a policy on it. */
4413 if (!create_policy_hnd(p
, &r_u
->pol
, free_samr_info
, (void *)info
))
4414 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4416 return NT_STATUS_OK
;
4419 /*********************************************************************
4420 _samr_remove_sid_foreign_domain
4421 *********************************************************************/
4423 NTSTATUS
_samr_remove_sid_foreign_domain(pipes_struct
*p
,
4424 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN
*q_u
,
4425 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN
*r_u
)
4427 DOM_SID delete_sid
, alias_sid
;
4428 SAM_ACCOUNT
*sam_pass
=NULL
;
4431 BOOL is_user
= False
;
4433 enum SID_NAME_USE type
= SID_NAME_UNKNOWN
;
4435 sid_copy( &delete_sid
, &q_u
->sid
.sid
);
4437 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4438 sid_string_static(&delete_sid
)));
4440 /* Find the policy handle. Open a policy on it. */
4442 if (!get_lsa_policy_samr_sid(p
, &q_u
->dom_pol
, &alias_sid
, &acc_granted
))
4443 return NT_STATUS_INVALID_HANDLE
;
4445 result
= access_check_samr_function(acc_granted
, STD_RIGHT_DELETE_ACCESS
,
4446 "_samr_remove_sid_foreign_domain");
4448 if (!NT_STATUS_IS_OK(result
))
4451 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4452 sid_string_static(&alias_sid
)));
4454 /* make sure we can handle this */
4456 if ( sid_check_is_domain(&alias_sid
) )
4457 type
= SID_NAME_DOM_GRP
;
4458 else if ( sid_check_is_builtin(&alias_sid
) )
4459 type
= SID_NAME_ALIAS
;
4461 if ( type
== SID_NAME_UNKNOWN
) {
4462 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4463 return NT_STATUS_OK
;
4466 /* check if the user exists before trying to delete */
4468 pdb_init_sam(&sam_pass
);
4470 if ( pdb_getsampwsid(sam_pass
, &delete_sid
) ) {
4473 /* maybe it is a group */
4474 if( !pdb_getgrsid(&map
, delete_sid
) ) {
4475 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4476 sid_string_static(&delete_sid
)));
4477 result
= NT_STATUS_INVALID_SID
;
4482 /* we can only delete a user from a group since we don't have
4483 nested groups anyways. So in the latter case, just say OK */
4486 GROUP_MAP
*mappings
= NULL
;
4490 if ( pdb_enum_group_mapping(type
, &mappings
, &num_groups
, False
) && num_groups
>0 ) {
4492 /* interate over the groups */
4493 for ( i
=0; i
<num_groups
; i
++ ) {
4495 grp2
= getgrgid(mappings
[i
].gid
);
4498 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4502 if ( !user_in_unix_group_list(pdb_get_username(sam_pass
), grp2
->gr_name
) )
4505 smb_delete_user_group(grp2
->gr_name
, pdb_get_username(sam_pass
));
4507 if ( user_in_unix_group_list(pdb_get_username(sam_pass
), grp2
->gr_name
) ) {
4508 /* should we fail here ? */
4509 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4510 pdb_get_username(sam_pass
), grp2
->gr_name
));
4514 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4515 pdb_get_username(sam_pass
), grp2
->gr_name
));
4518 SAFE_FREE(mappings
);
4522 result
= NT_STATUS_OK
;
4525 pdb_free_sam(&sam_pass
);
4530 /*******************************************************************
4532 ********************************************************************/
4534 NTSTATUS
_samr_unknown_2e(pipes_struct
*p
, SAMR_Q_UNKNOWN_2E
*q_u
, SAMR_R_UNKNOWN_2E
*r_u
)
4536 struct samr_info
*info
= NULL
;
4538 uint32 min_pass_len
,pass_hist
,flag
;
4539 time_t u_expire
, u_min_age
;
4540 NTTIME nt_expire
, nt_min_age
;
4542 time_t u_lock_duration
, u_reset_time
;
4543 NTTIME nt_lock_duration
, nt_reset_time
;
4549 uint32 num_users
=0, num_groups
=0, num_aliases
=0;
4551 uint32 account_policy_temp
;
4554 if ((ctr
= TALLOC_ZERO_P(p
->mem_ctx
, SAM_UNK_CTR
)) == NULL
)
4555 return NT_STATUS_NO_MEMORY
;
4559 r_u
->status
= NT_STATUS_OK
;
4561 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__
));
4563 /* find the policy handle. open a policy on it. */
4564 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, (void **)&info
))
4565 return NT_STATUS_INVALID_HANDLE
;
4567 switch (q_u
->switch_value
) {
4569 account_policy_get(AP_MIN_PASSWORD_LEN
, &account_policy_temp
);
4570 min_pass_len
= account_policy_temp
;
4572 account_policy_get(AP_PASSWORD_HISTORY
, &account_policy_temp
);
4573 pass_hist
= account_policy_temp
;
4575 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS
, &account_policy_temp
);
4576 flag
= account_policy_temp
;
4578 account_policy_get(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
4579 u_expire
= account_policy_temp
;
4581 account_policy_get(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
4582 u_min_age
= account_policy_temp
;
4584 unix_to_nt_time_abs(&nt_expire
, u_expire
);
4585 unix_to_nt_time_abs(&nt_min_age
, u_min_age
);
4587 init_unk_info1(&ctr
->info
.inf1
, (uint16
)min_pass_len
, (uint16
)pass_hist
,
4588 flag
, nt_expire
, nt_min_age
);
4592 r_u
->status
=load_sampwd_entries(info
, ACB_NORMAL
, False
);
4594 if (!NT_STATUS_IS_OK(r_u
->status
)) {
4595 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4598 num_users
=info
->disp_info
.num_user_account
;
4601 r_u
->status
=load_group_domain_entries(info
, get_global_sam_sid());
4602 if (NT_STATUS_IS_ERR(r_u
->status
)) {
4603 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4606 num_groups
=info
->disp_info
.num_group_account
;
4609 account_policy_get(AP_TIME_TO_LOGOUT
, &account_policy_temp
);
4610 u_logout
= account_policy_temp
;
4612 unix_to_nt_time_abs(&nt_logout
, u_logout
);
4614 server_role
= ROLE_DOMAIN_PDC
;
4615 if (lp_server_role() == ROLE_DOMAIN_BDC
)
4616 server_role
= ROLE_DOMAIN_BDC
;
4618 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4619 init_unk_info2(&ctr
->info
.inf2
, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL
),
4620 num_users
, num_groups
, num_aliases
, nt_logout
, server_role
);
4623 account_policy_get(AP_TIME_TO_LOGOUT
, &account_policy_temp
);
4624 u_logout
= account_policy_temp
;
4626 unix_to_nt_time_abs(&nt_logout
, u_logout
);
4628 init_unk_info3(&ctr
->info
.inf3
, nt_logout
);
4631 init_unk_info5(&ctr
->info
.inf5
, global_myname());
4634 init_unk_info6(&ctr
->info
.inf6
);
4637 server_role
= ROLE_DOMAIN_PDC
;
4638 if (lp_server_role() == ROLE_DOMAIN_BDC
)
4639 server_role
= ROLE_DOMAIN_BDC
;
4640 init_unk_info7(&ctr
->info
.inf7
, server_role
);
4643 init_unk_info8(&ctr
->info
.inf8
, (uint32
) time(NULL
));
4646 account_policy_get(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
4647 u_lock_duration
= account_policy_temp
;
4648 if (u_lock_duration
!= -1)
4649 u_lock_duration
*= 60;
4651 account_policy_get(AP_RESET_COUNT_TIME
, &account_policy_temp
);
4652 u_reset_time
= account_policy_temp
* 60;
4654 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
4655 lockout
= account_policy_temp
;
4657 unix_to_nt_time_abs(&nt_lock_duration
, u_lock_duration
);
4658 unix_to_nt_time_abs(&nt_reset_time
, u_reset_time
);
4660 init_unk_info12(&ctr
->info
.inf12
, nt_lock_duration
, nt_reset_time
, (uint16
)lockout
);
4663 return NT_STATUS_INVALID_INFO_CLASS
;
4666 init_samr_r_samr_unknown_2e(r_u
, q_u
->switch_value
, ctr
, NT_STATUS_OK
);
4668 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__
));
4673 /*******************************************************************
4675 ********************************************************************/
4677 NTSTATUS
_samr_set_dom_info(pipes_struct
*p
, SAMR_Q_SET_DOMAIN_INFO
*q_u
, SAMR_R_SET_DOMAIN_INFO
*r_u
)
4679 time_t u_expire
, u_min_age
;
4681 time_t u_lock_duration
, u_reset_time
;
4683 r_u
->status
= NT_STATUS_OK
;
4685 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__
));
4687 /* find the policy handle. open a policy on it. */
4688 if (!find_policy_by_hnd(p
, &q_u
->domain_pol
, NULL
))
4689 return NT_STATUS_INVALID_HANDLE
;
4691 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u
->switch_value
));
4693 switch (q_u
->switch_value
) {
4695 u_expire
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf1
.expire
);
4696 u_min_age
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf1
.min_passwordage
);
4698 account_policy_set(AP_MIN_PASSWORD_LEN
, (uint32
)q_u
->ctr
->info
.inf1
.min_length_password
);
4699 account_policy_set(AP_PASSWORD_HISTORY
, (uint32
)q_u
->ctr
->info
.inf1
.password_history
);
4700 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS
, (uint32
)q_u
->ctr
->info
.inf1
.flag
);
4701 account_policy_set(AP_MAX_PASSWORD_AGE
, (int)u_expire
);
4702 account_policy_set(AP_MIN_PASSWORD_AGE
, (int)u_min_age
);
4707 u_logout
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf3
.logout
);
4708 account_policy_set(AP_TIME_TO_LOGOUT
, (int)u_logout
);
4717 u_lock_duration
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf12
.duration
);
4718 if (u_lock_duration
!= -1)
4719 u_lock_duration
/= 60;
4721 u_reset_time
=nt_time_to_unix_abs(&q_u
->ctr
->info
.inf12
.reset_count
)/60;
4723 account_policy_set(AP_LOCK_ACCOUNT_DURATION
, (int)u_lock_duration
);
4724 account_policy_set(AP_RESET_COUNT_TIME
, (int)u_reset_time
);
4725 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT
, (uint32
)q_u
->ctr
->info
.inf12
.bad_attempt_lockout
);
4728 return NT_STATUS_INVALID_INFO_CLASS
;
4731 init_samr_r_set_domain_info(r_u
, NT_STATUS_OK
);
4733 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__
));