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-2008,
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,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
42 SAMR_USER_ACCESS_SET_LOC_COM)
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
49 #define MAX_SAM_ENTRIES_W95 50
51 typedef struct disp_info
{
52 DOM_SID sid
; /* identify which domain this is. */
53 bool builtin_domain
; /* Quick flag to check if this is the builtin domain. */
54 struct pdb_search
*users
; /* querydispinfo 1 and 4 */
55 struct pdb_search
*machines
; /* querydispinfo 2 */
56 struct pdb_search
*groups
; /* querydispinfo 3 and 5, enumgroups */
57 struct pdb_search
*aliases
; /* enumaliases */
60 struct pdb_search
*enum_users
; /* enumusers with a mask */
62 struct timed_event
*cache_timeout_event
; /* cache idle timeout
66 /* We keep a static list of these by SID as modern clients close down
67 all resources between each request in a complete enumeration. */
70 /* for use by the \PIPE\samr policy */
72 bool builtin_domain
; /* Quick flag to check if this is the builtin domain. */
73 uint32 status
; /* some sort of flag. best to record it. comes from opnum 0x39 */
78 static const struct generic_mapping sam_generic_mapping
= {
79 GENERIC_RIGHTS_SAM_READ
,
80 GENERIC_RIGHTS_SAM_WRITE
,
81 GENERIC_RIGHTS_SAM_EXECUTE
,
82 GENERIC_RIGHTS_SAM_ALL_ACCESS
};
83 static const struct generic_mapping dom_generic_mapping
= {
84 GENERIC_RIGHTS_DOMAIN_READ
,
85 GENERIC_RIGHTS_DOMAIN_WRITE
,
86 GENERIC_RIGHTS_DOMAIN_EXECUTE
,
87 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS
};
88 static const struct generic_mapping usr_generic_mapping
= {
89 GENERIC_RIGHTS_USER_READ
,
90 GENERIC_RIGHTS_USER_WRITE
,
91 GENERIC_RIGHTS_USER_EXECUTE
,
92 GENERIC_RIGHTS_USER_ALL_ACCESS
};
93 static const struct generic_mapping usr_nopwchange_generic_mapping
= {
94 GENERIC_RIGHTS_USER_READ
,
95 GENERIC_RIGHTS_USER_WRITE
,
96 GENERIC_RIGHTS_USER_EXECUTE
& ~SAMR_USER_ACCESS_CHANGE_PASSWORD
,
97 GENERIC_RIGHTS_USER_ALL_ACCESS
};
98 static const struct generic_mapping grp_generic_mapping
= {
99 GENERIC_RIGHTS_GROUP_READ
,
100 GENERIC_RIGHTS_GROUP_WRITE
,
101 GENERIC_RIGHTS_GROUP_EXECUTE
,
102 GENERIC_RIGHTS_GROUP_ALL_ACCESS
};
103 static const struct generic_mapping ali_generic_mapping
= {
104 GENERIC_RIGHTS_ALIAS_READ
,
105 GENERIC_RIGHTS_ALIAS_WRITE
,
106 GENERIC_RIGHTS_ALIAS_EXECUTE
,
107 GENERIC_RIGHTS_ALIAS_ALL_ACCESS
};
109 /*******************************************************************
110 *******************************************************************/
112 static NTSTATUS
make_samr_object_sd( TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
,
113 const struct generic_mapping
*map
,
114 DOM_SID
*sid
, uint32 sid_access
)
116 DOM_SID domadmin_sid
;
117 SEC_ACE ace
[5]; /* at most 5 entries */
122 /* basic access for Everyone */
124 init_sec_ace(&ace
[i
++], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
125 map
->generic_execute
| map
->generic_read
, 0);
127 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
129 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Administrators
,
130 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
131 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Account_Operators
,
132 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
134 /* Add Full Access for Domain Admins if we are a DC */
137 sid_copy( &domadmin_sid
, get_global_sam_sid() );
138 sid_append_rid( &domadmin_sid
, DOMAIN_GROUP_RID_ADMINS
);
139 init_sec_ace(&ace
[i
++], &domadmin_sid
,
140 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
143 /* if we have a sid, give it some special access */
146 init_sec_ace(&ace
[i
++], sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, sid_access
, 0);
149 /* create the security descriptor */
151 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, i
, ace
)) == NULL
)
152 return NT_STATUS_NO_MEMORY
;
154 if ((*psd
= make_sec_desc(ctx
, SECURITY_DESCRIPTOR_REVISION_1
,
155 SEC_DESC_SELF_RELATIVE
, NULL
, NULL
, NULL
,
156 psa
, sd_size
)) == NULL
)
157 return NT_STATUS_NO_MEMORY
;
162 /*******************************************************************
163 Checks if access to an object should be granted, and returns that
164 level of access for further checks.
165 ********************************************************************/
167 static NTSTATUS
access_check_samr_object( SEC_DESC
*psd
, NT_USER_TOKEN
*token
,
168 SE_PRIV
*rights
, uint32 rights_mask
,
169 uint32 des_access
, uint32
*acc_granted
,
172 NTSTATUS status
= NT_STATUS_ACCESS_DENIED
;
173 uint32 saved_mask
= 0;
175 /* check privileges; certain SAM access bits should be overridden
176 by privileges (mostly having to do with creating/modifying/deleting
179 if ( rights
&& user_has_any_privilege( token
, rights
) ) {
181 saved_mask
= (des_access
& rights_mask
);
182 des_access
&= ~saved_mask
;
184 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
189 /* check the security descriptor first */
191 status
= se_access_check(psd
, token
, des_access
, acc_granted
);
192 if (NT_STATUS_IS_OK(status
)) {
196 /* give root a free pass */
198 if ( geteuid() == sec_initial_uid() ) {
200 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug
, des_access
));
201 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
203 *acc_granted
= des_access
;
205 status
= NT_STATUS_OK
;
211 /* add in any bits saved during the privilege check (only
212 matters is status is ok) */
214 *acc_granted
|= rights_mask
;
216 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
217 debug
, NT_STATUS_IS_OK(status
) ? "GRANTED" : "DENIED",
218 des_access
, *acc_granted
));
223 /*******************************************************************
224 Checks if access to a function can be granted
225 ********************************************************************/
227 static NTSTATUS
access_check_samr_function(uint32 acc_granted
, uint32 acc_required
, const char *debug
)
229 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
230 debug
, acc_granted
, acc_required
));
232 /* check the security descriptor first */
234 if ( (acc_granted
&acc_required
) == acc_required
)
237 /* give root a free pass */
239 if (geteuid() == sec_initial_uid()) {
241 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
242 debug
, acc_granted
, acc_required
));
243 DEBUGADD(4,("but overwritten by euid == 0\n"));
248 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
249 debug
, acc_granted
, acc_required
));
251 return NT_STATUS_ACCESS_DENIED
;
254 /*******************************************************************
255 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
256 ********************************************************************/
258 static void map_max_allowed_access(const NT_USER_TOKEN
*token
,
259 uint32_t *pacc_requested
)
261 if (!((*pacc_requested
) & MAXIMUM_ALLOWED_ACCESS
)) {
264 *pacc_requested
&= ~MAXIMUM_ALLOWED_ACCESS
;
266 /* At least try for generic read. */
267 *pacc_requested
= GENERIC_READ_ACCESS
;
269 /* root gets anything. */
270 if (geteuid() == sec_initial_uid()) {
271 *pacc_requested
|= GENERIC_ALL_ACCESS
;
275 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
277 if (is_sid_in_token(token
, &global_sid_Builtin_Administrators
) ||
278 is_sid_in_token(token
, &global_sid_Builtin_Account_Operators
)) {
279 *pacc_requested
|= GENERIC_ALL_ACCESS
;
283 /* Full access for DOMAIN\Domain Admins. */
285 DOM_SID domadmin_sid
;
286 sid_copy( &domadmin_sid
, get_global_sam_sid() );
287 sid_append_rid( &domadmin_sid
, DOMAIN_GROUP_RID_ADMINS
);
288 if (is_sid_in_token(token
, &domadmin_sid
)) {
289 *pacc_requested
|= GENERIC_ALL_ACCESS
;
293 /* TODO ! Check privileges. */
296 /*******************************************************************
297 Fetch or create a dispinfo struct.
298 ********************************************************************/
300 static DISP_INFO
*get_samr_dispinfo_by_sid(DOM_SID
*psid
)
303 * We do a static cache for DISP_INFO's here. Explanation can be found
304 * in Jeremy's checkin message to r11793:
306 * Fix the SAMR cache so it works across completely insane
307 * client behaviour (ie.:
308 * open pipe/open SAMR handle/enumerate 0 - 1024
309 * close SAMR handle, close pipe.
310 * open pipe/open SAMR handle/enumerate 1024 - 2048...
311 * close SAMR handle, close pipe.
312 * And on ad-nausium. Amazing.... probably object-oriented
313 * client side programming in action yet again.
314 * This change should *massively* improve performance when
315 * enumerating users from an LDAP database.
318 * "Our" and the builtin domain are the only ones where we ever
319 * enumerate stuff, so just cache 2 entries.
322 static struct disp_info
*builtin_dispinfo
;
323 static struct disp_info
*domain_dispinfo
;
325 /* There are two cases to consider here:
326 1) The SID is a domain SID and we look for an equality match, or
327 2) This is an account SID and so we return the DISP_INFO* for our
334 if (sid_check_is_builtin(psid
) || sid_check_is_in_builtin(psid
)) {
336 * Necessary only once, but it does not really hurt.
338 if (builtin_dispinfo
== NULL
) {
339 builtin_dispinfo
= talloc_zero(
340 talloc_autofree_context(), struct disp_info
);
341 if (builtin_dispinfo
== NULL
) {
345 sid_copy(&builtin_dispinfo
->sid
, &global_sid_Builtin
);
346 builtin_dispinfo
->builtin_domain
= true;
348 return builtin_dispinfo
;
351 if (sid_check_is_domain(psid
) || sid_check_is_in_our_domain(psid
)) {
353 * Necessary only once, but it does not really hurt.
355 if (domain_dispinfo
== NULL
) {
356 domain_dispinfo
= talloc_zero(
357 talloc_autofree_context(), struct disp_info
);
358 if (domain_dispinfo
== NULL
) {
362 sid_copy(&domain_dispinfo
->sid
, get_global_sam_sid());
363 domain_dispinfo
->builtin_domain
= false;
365 return domain_dispinfo
;
371 /*******************************************************************
372 Create a samr_info struct.
373 ********************************************************************/
375 static int samr_info_destructor(struct samr_info
*info
);
377 static struct samr_info
*get_samr_info_by_sid(TALLOC_CTX
*mem_ctx
,
380 struct samr_info
*info
;
384 sid_to_fstring(sid_str
, psid
);
386 fstrcpy(sid_str
,"(NULL)");
389 if ((info
= TALLOC_ZERO_P(mem_ctx
, struct samr_info
)) == NULL
) {
392 talloc_set_destructor(info
, samr_info_destructor
);
394 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str
));
396 sid_copy( &info
->sid
, psid
);
397 info
->builtin_domain
= sid_check_is_builtin(psid
);
399 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
400 info
->builtin_domain
= False
;
403 info
->disp_info
= get_samr_dispinfo_by_sid(psid
);
408 /*******************************************************************
409 Function to free the per SID data.
410 ********************************************************************/
412 static void free_samr_cache(DISP_INFO
*disp_info
)
414 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
415 sid_string_dbg(&disp_info
->sid
)));
417 /* We need to become root here because the paged search might have to
418 * tell the LDAP server we're not interested in the rest anymore. */
422 TALLOC_FREE(disp_info
->users
);
423 TALLOC_FREE(disp_info
->machines
);
424 TALLOC_FREE(disp_info
->groups
);
425 TALLOC_FREE(disp_info
->aliases
);
426 TALLOC_FREE(disp_info
->enum_users
);
431 static int samr_info_destructor(struct samr_info
*info
)
433 /* Only free the dispinfo cache if no one bothered to set up
436 if (info
->disp_info
&& info
->disp_info
->cache_timeout_event
== NULL
) {
437 free_samr_cache(info
->disp_info
);
442 /*******************************************************************
443 Idle event handler. Throw away the disp info cache.
444 ********************************************************************/
446 static void disp_info_cache_idle_timeout_handler(struct event_context
*ev_ctx
,
447 struct timed_event
*te
,
451 DISP_INFO
*disp_info
= (DISP_INFO
*)private_data
;
453 TALLOC_FREE(disp_info
->cache_timeout_event
);
455 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
457 free_samr_cache(disp_info
);
460 /*******************************************************************
461 Setup cache removal idle event handler.
462 ********************************************************************/
464 static void set_disp_info_cache_timeout(DISP_INFO
*disp_info
, time_t secs_fromnow
)
466 /* Remove any pending timeout and update. */
468 TALLOC_FREE(disp_info
->cache_timeout_event
);
470 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
471 "SID %s for %u seconds\n", sid_string_dbg(&disp_info
->sid
),
472 (unsigned int)secs_fromnow
));
474 disp_info
->cache_timeout_event
= event_add_timed(
475 smbd_event_context(), NULL
,
476 timeval_current_ofs(secs_fromnow
, 0),
477 disp_info_cache_idle_timeout_handler
, (void *)disp_info
);
480 /*******************************************************************
481 Force flush any cache. We do this on any samr_set_xxx call.
482 We must also remove the timeout handler.
483 ********************************************************************/
485 static void force_flush_samr_cache(DISP_INFO
*disp_info
)
487 if ((disp_info
== NULL
) || (disp_info
->cache_timeout_event
== NULL
)) {
491 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
492 TALLOC_FREE(disp_info
->cache_timeout_event
);
493 free_samr_cache(disp_info
);
496 /*******************************************************************
497 Ensure password info is never given out. Paranioa... JRA.
498 ********************************************************************/
500 static void samr_clear_sam_passwd(struct samu
*sam_pass
)
506 /* These now zero out the old password */
508 pdb_set_lanman_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
509 pdb_set_nt_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
512 static uint32
count_sam_users(struct disp_info
*info
, uint32 acct_flags
)
514 struct samr_displayentry
*entry
;
516 if (info
->builtin_domain
) {
517 /* No users in builtin. */
521 if (info
->users
== NULL
) {
522 info
->users
= pdb_search_users(info
, acct_flags
);
523 if (info
->users
== NULL
) {
527 /* Fetch the last possible entry, thus trigger an enumeration */
528 pdb_search_entries(info
->users
, 0xffffffff, 1, &entry
);
530 /* Ensure we cache this enumeration. */
531 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
533 return info
->users
->num_entries
;
536 static uint32
count_sam_groups(struct disp_info
*info
)
538 struct samr_displayentry
*entry
;
540 if (info
->builtin_domain
) {
541 /* No groups in builtin. */
545 if (info
->groups
== NULL
) {
546 info
->groups
= pdb_search_groups(info
);
547 if (info
->groups
== NULL
) {
551 /* Fetch the last possible entry, thus trigger an enumeration */
552 pdb_search_entries(info
->groups
, 0xffffffff, 1, &entry
);
554 /* Ensure we cache this enumeration. */
555 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
557 return info
->groups
->num_entries
;
560 static uint32
count_sam_aliases(struct disp_info
*info
)
562 struct samr_displayentry
*entry
;
564 if (info
->aliases
== NULL
) {
565 info
->aliases
= pdb_search_aliases(info
, &info
->sid
);
566 if (info
->aliases
== NULL
) {
570 /* Fetch the last possible entry, thus trigger an enumeration */
571 pdb_search_entries(info
->aliases
, 0xffffffff, 1, &entry
);
573 /* Ensure we cache this enumeration. */
574 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
576 return info
->aliases
->num_entries
;
579 /*******************************************************************
581 ********************************************************************/
583 NTSTATUS
_samr_Close(pipes_struct
*p
, struct samr_Close
*r
)
585 if (!close_policy_hnd(p
, r
->in
.handle
)) {
586 return NT_STATUS_INVALID_HANDLE
;
589 ZERO_STRUCTP(r
->out
.handle
);
594 /*******************************************************************
596 ********************************************************************/
598 NTSTATUS
_samr_OpenDomain(pipes_struct
*p
,
599 struct samr_OpenDomain
*r
)
601 struct samr_info
*info
;
602 SEC_DESC
*psd
= NULL
;
604 uint32 des_access
= r
->in
.access_mask
;
609 /* find the connection policy handle. */
611 if ( !find_policy_by_hnd(p
, r
->in
.connect_handle
, (void**)(void *)&info
) )
612 return NT_STATUS_INVALID_HANDLE
;
614 /*check if access can be granted as requested by client. */
615 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
617 make_samr_object_sd( p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0 );
618 se_map_generic( &des_access
, &dom_generic_mapping
);
620 se_priv_copy( &se_rights
, &se_machine_account
);
621 se_priv_add( &se_rights
, &se_add_users
);
623 status
= access_check_samr_object( psd
, p
->server_info
->ptok
,
624 &se_rights
, GENERIC_RIGHTS_DOMAIN_WRITE
, des_access
,
625 &acc_granted
, "_samr_OpenDomain" );
627 if ( !NT_STATUS_IS_OK(status
) )
630 if (!sid_check_is_domain(r
->in
.sid
) &&
631 !sid_check_is_builtin(r
->in
.sid
)) {
632 return NT_STATUS_NO_SUCH_DOMAIN
;
635 /* associate the domain SID with the (unique) handle. */
636 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, r
->in
.sid
))==NULL
)
637 return NT_STATUS_NO_MEMORY
;
638 info
->acc_granted
= acc_granted
;
640 /* get a (unique) handle. open a policy on it. */
641 if (!create_policy_hnd(p
, r
->out
.domain_handle
, info
))
642 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
644 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__
));
649 /*******************************************************************
651 ********************************************************************/
653 NTSTATUS
_samr_GetUserPwInfo(pipes_struct
*p
,
654 struct samr_GetUserPwInfo
*r
)
656 struct samr_info
*info
= NULL
;
657 enum lsa_SidType sid_type
;
658 uint32_t min_password_length
= 0;
659 uint32_t password_properties
= 0;
663 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__
));
665 /* find the policy handle. open a policy on it. */
666 if (!find_policy_by_hnd(p
, r
->in
.user_handle
, (void **)(void *)&info
)) {
667 return NT_STATUS_INVALID_HANDLE
;
670 status
= access_check_samr_function(info
->acc_granted
,
671 SAMR_USER_ACCESS_GET_ATTRIBUTES
,
672 "_samr_GetUserPwInfo" );
673 if (!NT_STATUS_IS_OK(status
)) {
677 if (!sid_check_is_in_our_domain(&info
->sid
)) {
678 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
682 ret
= lookup_sid(p
->mem_ctx
, &info
->sid
, NULL
, NULL
, &sid_type
);
685 return NT_STATUS_NO_SUCH_USER
;
691 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
,
692 &min_password_length
);
693 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
694 &password_properties
);
697 if (lp_check_password_script() && *lp_check_password_script()) {
698 password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
706 r
->out
.info
->min_password_length
= min_password_length
;
707 r
->out
.info
->password_properties
= password_properties
;
709 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__
));
714 /*******************************************************************
715 ********************************************************************/
717 static bool get_lsa_policy_samr_sid( pipes_struct
*p
, struct policy_handle
*pol
,
718 DOM_SID
*sid
, uint32
*acc_granted
,
719 DISP_INFO
**ppdisp_info
)
721 struct samr_info
*info
= NULL
;
723 /* find the policy handle. open a policy on it. */
724 if (!find_policy_by_hnd(p
, pol
, (void **)(void *)&info
))
731 *acc_granted
= info
->acc_granted
;
733 *ppdisp_info
= info
->disp_info
;
739 /*******************************************************************
741 ********************************************************************/
743 NTSTATUS
_samr_SetSecurity(pipes_struct
*p
,
744 struct samr_SetSecurity
*r
)
747 uint32 acc_granted
, i
;
750 struct samu
*sampass
=NULL
;
753 if (!get_lsa_policy_samr_sid(p
, r
->in
.handle
, &pol_sid
, &acc_granted
, NULL
))
754 return NT_STATUS_INVALID_HANDLE
;
756 if (!(sampass
= samu_new( p
->mem_ctx
))) {
757 DEBUG(0,("No memory!\n"));
758 return NT_STATUS_NO_MEMORY
;
761 /* get the user record */
763 ret
= pdb_getsampwsid(sampass
, &pol_sid
);
767 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid
)));
768 TALLOC_FREE(sampass
);
769 return NT_STATUS_INVALID_HANDLE
;
772 dacl
= r
->in
.sdbuf
->sd
->dacl
;
773 for (i
=0; i
< dacl
->num_aces
; i
++) {
774 if (sid_equal(&pol_sid
, &dacl
->aces
[i
].trustee
)) {
775 ret
= pdb_set_pass_can_change(sampass
,
776 (dacl
->aces
[i
].access_mask
&
777 SAMR_USER_ACCESS_CHANGE_PASSWORD
) ?
784 TALLOC_FREE(sampass
);
785 return NT_STATUS_ACCESS_DENIED
;
788 status
= access_check_samr_function(acc_granted
,
789 SAMR_USER_ACCESS_SET_ATTRIBUTES
,
790 "_samr_SetSecurity");
791 if (NT_STATUS_IS_OK(status
)) {
793 status
= pdb_update_sam_account(sampass
);
797 TALLOC_FREE(sampass
);
802 /*******************************************************************
803 build correct perms based on policies and password times for _samr_query_sec_obj
804 *******************************************************************/
805 static bool check_change_pw_access(TALLOC_CTX
*mem_ctx
, DOM_SID
*user_sid
)
807 struct samu
*sampass
=NULL
;
810 if ( !(sampass
= samu_new( mem_ctx
)) ) {
811 DEBUG(0,("No memory!\n"));
816 ret
= pdb_getsampwsid(sampass
, user_sid
);
820 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid
)));
821 TALLOC_FREE(sampass
);
825 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
827 if (pdb_get_pass_can_change(sampass
)) {
828 TALLOC_FREE(sampass
);
831 TALLOC_FREE(sampass
);
836 /*******************************************************************
838 ********************************************************************/
840 NTSTATUS
_samr_QuerySecurity(pipes_struct
*p
,
841 struct samr_QuerySecurity
*r
)
845 SEC_DESC
* psd
= NULL
;
850 if (!get_lsa_policy_samr_sid(p
, r
->in
.handle
, &pol_sid
, &acc_granted
, NULL
))
851 return NT_STATUS_INVALID_HANDLE
;
853 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
854 sid_string_dbg(&pol_sid
)));
856 status
= access_check_samr_function(acc_granted
,
857 STD_RIGHT_READ_CONTROL_ACCESS
,
858 "_samr_QuerySecurity");
859 if (!NT_STATUS_IS_OK(status
)) {
863 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
865 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
866 if (pol_sid
.sid_rev_num
== 0) {
867 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
868 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
869 } else if (sid_equal(&pol_sid
,get_global_sam_sid())) {
870 /* check if it is our domain SID */
871 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
872 "with SID: %s\n", sid_string_dbg(&pol_sid
)));
873 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0);
874 } else if (sid_equal(&pol_sid
,&global_sid_Builtin
)) {
875 /* check if it is the Builtin Domain */
876 /* TODO: Builtin probably needs a different SD with restricted write access*/
877 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
878 "Domain with SID: %s\n", sid_string_dbg(&pol_sid
)));
879 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0);
880 } else if (sid_check_is_in_our_domain(&pol_sid
) ||
881 sid_check_is_in_builtin(&pol_sid
)) {
882 /* TODO: different SDs have to be generated for aliases groups and users.
883 Currently all three get a default user SD */
884 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
885 "with SID: %s\n", sid_string_dbg(&pol_sid
)));
886 if (check_change_pw_access(p
->mem_ctx
, &pol_sid
)) {
887 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
,
888 &pol_sid
, SAMR_USR_RIGHTS_WRITE_PW
);
890 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_nopwchange_generic_mapping
,
891 &pol_sid
, SAMR_USR_RIGHTS_CANT_WRITE_PW
);
894 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
897 if ((*r
->out
.sdbuf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
898 return NT_STATUS_NO_MEMORY
;
903 /*******************************************************************
904 makes a SAM_ENTRY / UNISTR2* structure from a user list.
905 ********************************************************************/
907 static NTSTATUS
make_user_sam_entry_list(TALLOC_CTX
*ctx
,
908 struct samr_SamEntry
**sam_pp
,
909 uint32_t num_entries
,
911 struct samr_displayentry
*entries
)
914 struct samr_SamEntry
*sam
;
918 if (num_entries
== 0) {
922 sam
= TALLOC_ZERO_ARRAY(ctx
, struct samr_SamEntry
, num_entries
);
924 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
925 return NT_STATUS_NO_MEMORY
;
928 for (i
= 0; i
< num_entries
; i
++) {
931 * usrmgr expects a non-NULL terminated string with
932 * trust relationships
934 if (entries
[i
].acct_flags
& ACB_DOMTRUST
) {
935 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
938 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
942 init_lsa_String(&sam
[i
].name
, entries
[i
].account_name
);
943 sam
[i
].idx
= entries
[i
].rid
;
951 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
953 /*******************************************************************
954 _samr_EnumDomainUsers
955 ********************************************************************/
957 NTSTATUS
_samr_EnumDomainUsers(pipes_struct
*p
,
958 struct samr_EnumDomainUsers
*r
)
961 struct samr_info
*info
= NULL
;
963 uint32 enum_context
= *r
->in
.resume_handle
;
964 enum remote_arch_types ra_type
= get_remote_arch();
965 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
966 uint32 max_entries
= max_sam_entries
;
967 struct samr_displayentry
*entries
= NULL
;
968 struct samr_SamArray
*samr_array
= NULL
;
969 struct samr_SamEntry
*samr_entries
= NULL
;
971 /* find the policy handle. open a policy on it. */
972 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
973 return NT_STATUS_INVALID_HANDLE
;
975 status
= access_check_samr_function(info
->acc_granted
,
976 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
977 "_samr_EnumDomainUsers");
978 if (!NT_STATUS_IS_OK(status
)) {
982 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__
));
984 if (info
->builtin_domain
) {
985 /* No users in builtin. */
986 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
987 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
991 samr_array
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
993 return NT_STATUS_NO_MEMORY
;
995 *r
->out
.sam
= samr_array
;
1001 if ((info
->disp_info
->enum_users
!= NULL
) &&
1002 (info
->disp_info
->enum_acb_mask
!= r
->in
.acct_flags
)) {
1003 TALLOC_FREE(info
->disp_info
->enum_users
);
1006 if (info
->disp_info
->enum_users
== NULL
) {
1007 info
->disp_info
->enum_users
= pdb_search_users(
1008 info
->disp_info
, r
->in
.acct_flags
);
1009 info
->disp_info
->enum_acb_mask
= r
->in
.acct_flags
;
1012 if (info
->disp_info
->enum_users
== NULL
) {
1013 /* END AS ROOT !!!! */
1015 return NT_STATUS_ACCESS_DENIED
;
1018 num_account
= pdb_search_entries(info
->disp_info
->enum_users
,
1019 enum_context
, max_entries
,
1022 /* END AS ROOT !!!! */
1026 if (num_account
== 0) {
1027 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1028 "total entries\n"));
1029 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
1030 return NT_STATUS_OK
;
1033 status
= make_user_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1034 num_account
, enum_context
,
1036 if (!NT_STATUS_IS_OK(status
)) {
1040 if (max_entries
<= num_account
) {
1041 status
= STATUS_MORE_ENTRIES
;
1043 status
= NT_STATUS_OK
;
1046 /* Ensure we cache this enumeration. */
1047 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1049 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__
));
1051 samr_array
->count
= num_account
;
1052 samr_array
->entries
= samr_entries
;
1054 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ num_account
;
1055 *r
->out
.num_entries
= num_account
;
1057 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__
));
1062 /*******************************************************************
1063 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1064 ********************************************************************/
1066 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
,
1067 struct samr_SamEntry
**sam_pp
,
1068 uint32_t num_sam_entries
,
1069 struct samr_displayentry
*entries
)
1071 struct samr_SamEntry
*sam
;
1076 if (num_sam_entries
== 0) {
1080 sam
= TALLOC_ZERO_ARRAY(ctx
, struct samr_SamEntry
, num_sam_entries
);
1085 for (i
= 0; i
< num_sam_entries
; i
++) {
1087 * JRA. I think this should include the null. TNG does not.
1089 init_lsa_String(&sam
[i
].name
, entries
[i
].account_name
);
1090 sam
[i
].idx
= entries
[i
].rid
;
1096 /*******************************************************************
1097 _samr_EnumDomainGroups
1098 ********************************************************************/
1100 NTSTATUS
_samr_EnumDomainGroups(pipes_struct
*p
,
1101 struct samr_EnumDomainGroups
*r
)
1104 struct samr_info
*info
= NULL
;
1105 struct samr_displayentry
*groups
;
1107 struct samr_SamArray
*samr_array
= NULL
;
1108 struct samr_SamEntry
*samr_entries
= NULL
;
1110 /* find the policy handle. open a policy on it. */
1111 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
1112 return NT_STATUS_INVALID_HANDLE
;
1114 status
= access_check_samr_function(info
->acc_granted
,
1115 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
1116 "_samr_EnumDomainGroups");
1117 if (!NT_STATUS_IS_OK(status
)) {
1121 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__
));
1123 if (info
->builtin_domain
) {
1124 /* No groups in builtin. */
1125 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
1126 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1130 samr_array
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
1132 return NT_STATUS_NO_MEMORY
;
1135 /* the domain group array is being allocated in the function below */
1139 if (info
->disp_info
->groups
== NULL
) {
1140 info
->disp_info
->groups
= pdb_search_groups(info
->disp_info
);
1142 if (info
->disp_info
->groups
== NULL
) {
1144 return NT_STATUS_ACCESS_DENIED
;
1148 num_groups
= pdb_search_entries(info
->disp_info
->groups
,
1149 *r
->in
.resume_handle
,
1150 MAX_SAM_ENTRIES
, &groups
);
1153 /* Ensure we cache this enumeration. */
1154 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1156 make_group_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1157 num_groups
, groups
);
1159 samr_array
->count
= num_groups
;
1160 samr_array
->entries
= samr_entries
;
1162 *r
->out
.sam
= samr_array
;
1163 *r
->out
.num_entries
= num_groups
;
1164 *r
->out
.resume_handle
= num_groups
+ *r
->in
.resume_handle
;
1166 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__
));
1171 /*******************************************************************
1172 _samr_EnumDomainAliases
1173 ********************************************************************/
1175 NTSTATUS
_samr_EnumDomainAliases(pipes_struct
*p
,
1176 struct samr_EnumDomainAliases
*r
)
1179 struct samr_info
*info
;
1180 struct samr_displayentry
*aliases
;
1181 uint32 num_aliases
= 0;
1182 struct samr_SamArray
*samr_array
= NULL
;
1183 struct samr_SamEntry
*samr_entries
= NULL
;
1185 /* find the policy handle. open a policy on it. */
1186 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
1187 return NT_STATUS_INVALID_HANDLE
;
1189 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1190 sid_string_dbg(&info
->sid
)));
1192 status
= access_check_samr_function(info
->acc_granted
,
1193 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
1194 "_samr_EnumDomainAliases");
1195 if (!NT_STATUS_IS_OK(status
)) {
1199 samr_array
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
1201 return NT_STATUS_NO_MEMORY
;
1206 if (info
->disp_info
->aliases
== NULL
) {
1207 info
->disp_info
->aliases
= pdb_search_aliases(
1208 info
->disp_info
, &info
->sid
);
1209 if (info
->disp_info
->aliases
== NULL
) {
1211 return NT_STATUS_ACCESS_DENIED
;
1215 num_aliases
= pdb_search_entries(info
->disp_info
->aliases
,
1216 *r
->in
.resume_handle
,
1217 MAX_SAM_ENTRIES
, &aliases
);
1220 /* Ensure we cache this enumeration. */
1221 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1223 make_group_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1224 num_aliases
, aliases
);
1226 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__
));
1228 samr_array
->count
= num_aliases
;
1229 samr_array
->entries
= samr_entries
;
1231 *r
->out
.sam
= samr_array
;
1232 *r
->out
.num_entries
= num_aliases
;
1233 *r
->out
.resume_handle
= num_aliases
+ *r
->in
.resume_handle
;
1238 /*******************************************************************
1239 inits a samr_DispInfoGeneral structure.
1240 ********************************************************************/
1242 static NTSTATUS
init_samr_dispinfo_1(TALLOC_CTX
*ctx
,
1243 struct samr_DispInfoGeneral
*r
,
1244 uint32_t num_entries
,
1246 struct samr_displayentry
*entries
)
1250 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries
));
1252 if (num_entries
== 0) {
1253 return NT_STATUS_OK
;
1256 r
->count
= num_entries
;
1258 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryGeneral
, num_entries
);
1260 return NT_STATUS_NO_MEMORY
;
1263 for (i
= 0; i
< num_entries
; i
++) {
1265 init_lsa_String(&r
->entries
[i
].account_name
,
1266 entries
[i
].account_name
);
1268 init_lsa_String(&r
->entries
[i
].description
,
1269 entries
[i
].description
);
1271 init_lsa_String(&r
->entries
[i
].full_name
,
1272 entries
[i
].fullname
);
1274 r
->entries
[i
].rid
= entries
[i
].rid
;
1275 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1276 r
->entries
[i
].idx
= start_idx
+i
+1;
1279 return NT_STATUS_OK
;
1282 /*******************************************************************
1283 inits a samr_DispInfoFull structure.
1284 ********************************************************************/
1286 static NTSTATUS
init_samr_dispinfo_2(TALLOC_CTX
*ctx
,
1287 struct samr_DispInfoFull
*r
,
1288 uint32_t num_entries
,
1290 struct samr_displayentry
*entries
)
1294 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries
));
1296 if (num_entries
== 0) {
1297 return NT_STATUS_OK
;
1300 r
->count
= num_entries
;
1302 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryFull
, num_entries
);
1304 return NT_STATUS_NO_MEMORY
;
1307 for (i
= 0; i
< num_entries
; i
++) {
1309 init_lsa_String(&r
->entries
[i
].account_name
,
1310 entries
[i
].account_name
);
1312 init_lsa_String(&r
->entries
[i
].description
,
1313 entries
[i
].description
);
1315 r
->entries
[i
].rid
= entries
[i
].rid
;
1316 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1317 r
->entries
[i
].idx
= start_idx
+i
+1;
1320 return NT_STATUS_OK
;
1323 /*******************************************************************
1324 inits a samr_DispInfoFullGroups structure.
1325 ********************************************************************/
1327 static NTSTATUS
init_samr_dispinfo_3(TALLOC_CTX
*ctx
,
1328 struct samr_DispInfoFullGroups
*r
,
1329 uint32_t num_entries
,
1331 struct samr_displayentry
*entries
)
1335 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries
));
1337 if (num_entries
== 0) {
1338 return NT_STATUS_OK
;
1341 r
->count
= num_entries
;
1343 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryFullGroup
, num_entries
);
1345 return NT_STATUS_NO_MEMORY
;
1348 for (i
= 0; i
< num_entries
; i
++) {
1350 init_lsa_String(&r
->entries
[i
].account_name
,
1351 entries
[i
].account_name
);
1353 init_lsa_String(&r
->entries
[i
].description
,
1354 entries
[i
].description
);
1356 r
->entries
[i
].rid
= entries
[i
].rid
;
1357 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1358 r
->entries
[i
].idx
= start_idx
+i
+1;
1361 return NT_STATUS_OK
;
1364 /*******************************************************************
1365 inits a samr_DispInfoAscii structure.
1366 ********************************************************************/
1368 static NTSTATUS
init_samr_dispinfo_4(TALLOC_CTX
*ctx
,
1369 struct samr_DispInfoAscii
*r
,
1370 uint32_t num_entries
,
1372 struct samr_displayentry
*entries
)
1376 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries
));
1378 if (num_entries
== 0) {
1379 return NT_STATUS_OK
;
1382 r
->count
= num_entries
;
1384 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryAscii
, num_entries
);
1386 return NT_STATUS_NO_MEMORY
;
1389 for (i
= 0; i
< num_entries
; i
++) {
1391 init_lsa_AsciiStringLarge(&r
->entries
[i
].account_name
,
1392 entries
[i
].account_name
);
1394 r
->entries
[i
].idx
= start_idx
+i
+1;
1397 return NT_STATUS_OK
;
1400 /*******************************************************************
1401 inits a samr_DispInfoAscii structure.
1402 ********************************************************************/
1404 static NTSTATUS
init_samr_dispinfo_5(TALLOC_CTX
*ctx
,
1405 struct samr_DispInfoAscii
*r
,
1406 uint32_t num_entries
,
1408 struct samr_displayentry
*entries
)
1412 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries
));
1414 if (num_entries
== 0) {
1415 return NT_STATUS_OK
;
1418 r
->count
= num_entries
;
1420 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryAscii
, num_entries
);
1422 return NT_STATUS_NO_MEMORY
;
1425 for (i
= 0; i
< num_entries
; i
++) {
1427 init_lsa_AsciiStringLarge(&r
->entries
[i
].account_name
,
1428 entries
[i
].account_name
);
1430 r
->entries
[i
].idx
= start_idx
+i
+1;
1433 return NT_STATUS_OK
;
1436 /*******************************************************************
1437 _samr_QueryDisplayInfo
1438 ********************************************************************/
1440 NTSTATUS
_samr_QueryDisplayInfo(pipes_struct
*p
,
1441 struct samr_QueryDisplayInfo
*r
)
1444 struct samr_info
*info
= NULL
;
1445 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
1447 uint32 max_entries
= r
->in
.max_entries
;
1448 uint32 enum_context
= r
->in
.start_idx
;
1449 uint32 max_size
= r
->in
.buf_size
;
1451 union samr_DispInfo
*disp_info
= r
->out
.info
;
1453 uint32 temp_size
=0, total_data_size
=0;
1454 NTSTATUS disp_ret
= NT_STATUS_UNSUCCESSFUL
;
1455 uint32 num_account
= 0;
1456 enum remote_arch_types ra_type
= get_remote_arch();
1457 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
1458 struct samr_displayentry
*entries
= NULL
;
1460 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__
));
1462 /* find the policy handle. open a policy on it. */
1463 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
1464 return NT_STATUS_INVALID_HANDLE
;
1466 if (info
->builtin_domain
) {
1467 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1468 return NT_STATUS_OK
;
1471 status
= access_check_samr_function(info
->acc_granted
,
1472 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
1473 "_samr_QueryDisplayInfo");
1474 if (!NT_STATUS_IS_OK(status
)) {
1479 * calculate how many entries we will return.
1481 * - the number of entries the client asked
1482 * - our limit on that
1483 * - the starting point (enumeration context)
1484 * - the buffer size the client will accept
1488 * We are a lot more like W2K. Instead of reading the SAM
1489 * each time to find the records we need to send back,
1490 * we read it once and link that copy to the sam handle.
1491 * For large user list (over the MAX_SAM_ENTRIES)
1492 * it's a definitive win.
1493 * second point to notice: between enumerations
1494 * our sam is now the same as it's a snapshoot.
1495 * third point: got rid of the static SAM_USER_21 struct
1496 * no more intermediate.
1497 * con: it uses much more memory, as a full copy is stored
1500 * If you want to change it, think twice and think
1501 * of the second point , that's really important.
1506 if ((r
->in
.level
< 1) || (r
->in
.level
> 5)) {
1507 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1508 (unsigned int)r
->in
.level
));
1509 return NT_STATUS_INVALID_INFO_CLASS
;
1512 /* first limit the number of entries we will return */
1513 if(max_entries
> max_sam_entries
) {
1514 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1515 "entries, limiting to %d\n", max_entries
,
1517 max_entries
= max_sam_entries
;
1520 /* calculate the size and limit on the number of entries we will
1523 temp_size
=max_entries
*struct_size
;
1525 if (temp_size
>max_size
) {
1526 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
1527 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1528 "only %d entries\n", max_entries
));
1533 /* THe following done as ROOT. Don't return without unbecome_root(). */
1535 switch (r
->in
.level
) {
1538 if (info
->disp_info
->users
== NULL
) {
1539 info
->disp_info
->users
= pdb_search_users(
1540 info
->disp_info
, ACB_NORMAL
);
1541 if (info
->disp_info
->users
== NULL
) {
1543 return NT_STATUS_ACCESS_DENIED
;
1545 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1546 (unsigned int)enum_context
));
1548 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1549 (unsigned int)enum_context
));
1552 num_account
= pdb_search_entries(info
->disp_info
->users
,
1553 enum_context
, max_entries
,
1557 if (info
->disp_info
->machines
== NULL
) {
1558 info
->disp_info
->machines
= pdb_search_users(
1559 info
->disp_info
, ACB_WSTRUST
|ACB_SVRTRUST
);
1560 if (info
->disp_info
->machines
== NULL
) {
1562 return NT_STATUS_ACCESS_DENIED
;
1564 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1565 (unsigned int)enum_context
));
1567 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1568 (unsigned int)enum_context
));
1571 num_account
= pdb_search_entries(info
->disp_info
->machines
,
1572 enum_context
, max_entries
,
1577 if (info
->disp_info
->groups
== NULL
) {
1578 info
->disp_info
->groups
= pdb_search_groups(
1580 if (info
->disp_info
->groups
== NULL
) {
1582 return NT_STATUS_ACCESS_DENIED
;
1584 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1585 (unsigned int)enum_context
));
1587 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1588 (unsigned int)enum_context
));
1591 num_account
= pdb_search_entries(info
->disp_info
->groups
,
1592 enum_context
, max_entries
,
1597 smb_panic("info class changed");
1603 /* Now create reply structure */
1604 switch (r
->in
.level
) {
1606 disp_ret
= init_samr_dispinfo_1(p
->mem_ctx
, &disp_info
->info1
,
1607 num_account
, enum_context
,
1611 disp_ret
= init_samr_dispinfo_2(p
->mem_ctx
, &disp_info
->info2
,
1612 num_account
, enum_context
,
1616 disp_ret
= init_samr_dispinfo_3(p
->mem_ctx
, &disp_info
->info3
,
1617 num_account
, enum_context
,
1621 disp_ret
= init_samr_dispinfo_4(p
->mem_ctx
, &disp_info
->info4
,
1622 num_account
, enum_context
,
1626 disp_ret
= init_samr_dispinfo_5(p
->mem_ctx
, &disp_info
->info5
,
1627 num_account
, enum_context
,
1631 smb_panic("info class changed");
1635 if (!NT_STATUS_IS_OK(disp_ret
))
1638 /* calculate the total size */
1639 total_data_size
=num_account
*struct_size
;
1641 if (max_entries
<= num_account
) {
1642 status
= STATUS_MORE_ENTRIES
;
1644 status
= NT_STATUS_OK
;
1647 /* Ensure we cache this enumeration. */
1648 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1650 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__
));
1652 *r
->out
.total_size
= total_data_size
;
1653 *r
->out
.returned_size
= temp_size
;
1658 /****************************************************************
1659 _samr_QueryDisplayInfo2
1660 ****************************************************************/
1662 NTSTATUS
_samr_QueryDisplayInfo2(pipes_struct
*p
,
1663 struct samr_QueryDisplayInfo2
*r
)
1665 struct samr_QueryDisplayInfo q
;
1667 q
.in
.domain_handle
= r
->in
.domain_handle
;
1668 q
.in
.level
= r
->in
.level
;
1669 q
.in
.start_idx
= r
->in
.start_idx
;
1670 q
.in
.max_entries
= r
->in
.max_entries
;
1671 q
.in
.buf_size
= r
->in
.buf_size
;
1673 q
.out
.total_size
= r
->out
.total_size
;
1674 q
.out
.returned_size
= r
->out
.returned_size
;
1675 q
.out
.info
= r
->out
.info
;
1677 return _samr_QueryDisplayInfo(p
, &q
);
1680 /****************************************************************
1681 _samr_QueryDisplayInfo3
1682 ****************************************************************/
1684 NTSTATUS
_samr_QueryDisplayInfo3(pipes_struct
*p
,
1685 struct samr_QueryDisplayInfo3
*r
)
1687 struct samr_QueryDisplayInfo q
;
1689 q
.in
.domain_handle
= r
->in
.domain_handle
;
1690 q
.in
.level
= r
->in
.level
;
1691 q
.in
.start_idx
= r
->in
.start_idx
;
1692 q
.in
.max_entries
= r
->in
.max_entries
;
1693 q
.in
.buf_size
= r
->in
.buf_size
;
1695 q
.out
.total_size
= r
->out
.total_size
;
1696 q
.out
.returned_size
= r
->out
.returned_size
;
1697 q
.out
.info
= r
->out
.info
;
1699 return _samr_QueryDisplayInfo(p
, &q
);
1702 /*******************************************************************
1703 _samr_QueryAliasInfo
1704 ********************************************************************/
1706 NTSTATUS
_samr_QueryAliasInfo(pipes_struct
*p
,
1707 struct samr_QueryAliasInfo
*r
)
1710 struct acct_info info
;
1713 union samr_AliasInfo
*alias_info
= NULL
;
1714 const char *alias_name
= NULL
;
1715 const char *alias_description
= NULL
;
1717 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__
));
1719 alias_info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_AliasInfo
);
1721 return NT_STATUS_NO_MEMORY
;
1724 /* find the policy handle. open a policy on it. */
1725 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &sid
, &acc_granted
, NULL
))
1726 return NT_STATUS_INVALID_HANDLE
;
1728 status
= access_check_samr_function(acc_granted
,
1729 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
1730 "_samr_QueryAliasInfo");
1731 if (!NT_STATUS_IS_OK(status
)) {
1736 status
= pdb_get_aliasinfo(&sid
, &info
);
1739 if ( !NT_STATUS_IS_OK(status
))
1742 /* FIXME: info contains fstrings */
1743 alias_name
= talloc_strdup(r
, info
.acct_name
);
1744 alias_description
= talloc_strdup(r
, info
.acct_desc
);
1746 switch (r
->in
.level
) {
1748 alias_info
->all
.name
.string
= alias_name
;
1749 alias_info
->all
.num_members
= 1; /* ??? */
1750 alias_info
->all
.description
.string
= alias_description
;
1752 case ALIASINFODESCRIPTION
:
1753 alias_info
->description
.string
= alias_description
;
1756 return NT_STATUS_INVALID_INFO_CLASS
;
1759 *r
->out
.info
= alias_info
;
1761 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__
));
1763 return NT_STATUS_OK
;
1766 /*******************************************************************
1768 ********************************************************************/
1770 NTSTATUS
_samr_LookupNames(pipes_struct
*p
,
1771 struct samr_LookupNames
*r
)
1775 enum lsa_SidType
*type
;
1777 int num_rids
= r
->in
.num_names
;
1780 struct samr_Ids rids
, types
;
1781 uint32_t num_mapped
= 0;
1783 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1785 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &pol_sid
, &acc_granted
, NULL
)) {
1786 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1789 status
= access_check_samr_function(acc_granted
,
1790 0, /* Don't know the acc_bits yet */
1791 "_samr_LookupNames");
1792 if (!NT_STATUS_IS_OK(status
)) {
1796 if (num_rids
> MAX_SAM_ENTRIES
) {
1797 num_rids
= MAX_SAM_ENTRIES
;
1798 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids
));
1801 rid
= talloc_array(p
->mem_ctx
, uint32
, num_rids
);
1802 NT_STATUS_HAVE_NO_MEMORY(rid
);
1804 type
= talloc_array(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
1805 NT_STATUS_HAVE_NO_MEMORY(type
);
1807 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1808 sid_string_dbg(&pol_sid
)));
1810 for (i
= 0; i
< num_rids
; i
++) {
1812 status
= NT_STATUS_NONE_MAPPED
;
1813 type
[i
] = SID_NAME_UNKNOWN
;
1815 rid
[i
] = 0xffffffff;
1817 if (sid_check_is_builtin(&pol_sid
)) {
1818 if (lookup_builtin_name(r
->in
.names
[i
].string
,
1821 type
[i
] = SID_NAME_ALIAS
;
1824 lookup_global_sam_name(r
->in
.names
[i
].string
, 0,
1828 if (type
[i
] != SID_NAME_UNKNOWN
) {
1833 if (num_mapped
== num_rids
) {
1834 status
= NT_STATUS_OK
;
1835 } else if (num_mapped
== 0) {
1836 status
= NT_STATUS_NONE_MAPPED
;
1838 status
= STATUS_SOME_UNMAPPED
;
1841 rids
.count
= num_rids
;
1844 types
.count
= num_rids
;
1847 *r
->out
.rids
= rids
;
1848 *r
->out
.types
= types
;
1850 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1855 /****************************************************************
1856 _samr_ChangePasswordUser
1857 ****************************************************************/
1859 NTSTATUS
_samr_ChangePasswordUser(pipes_struct
*p
,
1860 struct samr_ChangePasswordUser
*r
)
1865 struct samr_Password new_lmPwdHash
, new_ntPwdHash
, checkHash
;
1866 struct samr_Password lm_pwd
, nt_pwd
;
1867 uint32_t acc_granted
;
1870 DISP_INFO
*disp_info
= NULL
;
1872 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &sid
, &acc_granted
, &disp_info
)) {
1873 return NT_STATUS_INVALID_HANDLE
;
1876 status
= access_check_samr_function(acc_granted
,
1877 SAMR_USER_ACCESS_SET_PASSWORD
,
1878 "_samr_ChangePasswordUser");
1879 if (!NT_STATUS_IS_OK(status
)) {
1883 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1884 sid_string_dbg(&sid
)));
1886 if (!(pwd
= samu_new(NULL
))) {
1887 return NT_STATUS_NO_MEMORY
;
1891 ret
= pdb_getsampwsid(pwd
, &sid
);
1896 return NT_STATUS_WRONG_PASSWORD
;
1900 const uint8_t *lm_pass
, *nt_pass
;
1902 lm_pass
= pdb_get_lanman_passwd(pwd
);
1903 nt_pass
= pdb_get_nt_passwd(pwd
);
1905 if (!lm_pass
|| !nt_pass
) {
1906 status
= NT_STATUS_WRONG_PASSWORD
;
1910 memcpy(&lm_pwd
.hash
, lm_pass
, sizeof(lm_pwd
.hash
));
1911 memcpy(&nt_pwd
.hash
, nt_pass
, sizeof(nt_pwd
.hash
));
1914 /* basic sanity checking on parameters. Do this before any database ops */
1915 if (!r
->in
.lm_present
|| !r
->in
.nt_present
||
1916 !r
->in
.old_lm_crypted
|| !r
->in
.new_lm_crypted
||
1917 !r
->in
.old_nt_crypted
|| !r
->in
.new_nt_crypted
) {
1918 /* we should really handle a change with lm not
1920 status
= NT_STATUS_INVALID_PARAMETER_MIX
;
1924 /* decrypt and check the new lm hash */
1925 D_P16(lm_pwd
.hash
, r
->in
.new_lm_crypted
->hash
, new_lmPwdHash
.hash
);
1926 D_P16(new_lmPwdHash
.hash
, r
->in
.old_lm_crypted
->hash
, checkHash
.hash
);
1927 if (memcmp(checkHash
.hash
, lm_pwd
.hash
, 16) != 0) {
1928 status
= NT_STATUS_WRONG_PASSWORD
;
1932 /* decrypt and check the new nt hash */
1933 D_P16(nt_pwd
.hash
, r
->in
.new_nt_crypted
->hash
, new_ntPwdHash
.hash
);
1934 D_P16(new_ntPwdHash
.hash
, r
->in
.old_nt_crypted
->hash
, checkHash
.hash
);
1935 if (memcmp(checkHash
.hash
, nt_pwd
.hash
, 16) != 0) {
1936 status
= NT_STATUS_WRONG_PASSWORD
;
1940 /* The NT Cross is not required by Win2k3 R2, but if present
1941 check the nt cross hash */
1942 if (r
->in
.cross1_present
&& r
->in
.nt_cross
) {
1943 D_P16(lm_pwd
.hash
, r
->in
.nt_cross
->hash
, checkHash
.hash
);
1944 if (memcmp(checkHash
.hash
, new_ntPwdHash
.hash
, 16) != 0) {
1945 status
= NT_STATUS_WRONG_PASSWORD
;
1950 /* The LM Cross is not required by Win2k3 R2, but if present
1951 check the lm cross hash */
1952 if (r
->in
.cross2_present
&& r
->in
.lm_cross
) {
1953 D_P16(nt_pwd
.hash
, r
->in
.lm_cross
->hash
, checkHash
.hash
);
1954 if (memcmp(checkHash
.hash
, new_lmPwdHash
.hash
, 16) != 0) {
1955 status
= NT_STATUS_WRONG_PASSWORD
;
1960 if (!pdb_set_nt_passwd(pwd
, new_ntPwdHash
.hash
, PDB_CHANGED
) ||
1961 !pdb_set_lanman_passwd(pwd
, new_lmPwdHash
.hash
, PDB_CHANGED
)) {
1962 status
= NT_STATUS_ACCESS_DENIED
;
1966 status
= pdb_update_sam_account(pwd
);
1973 /*******************************************************************
1974 _samr_ChangePasswordUser2
1975 ********************************************************************/
1977 NTSTATUS
_samr_ChangePasswordUser2(pipes_struct
*p
,
1978 struct samr_ChangePasswordUser2
*r
)
1984 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
1986 fstrcpy(user_name
, r
->in
.account
->string
);
1987 fstrcpy(wks
, r
->in
.server
->string
);
1989 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
1992 * Pass the user through the NT -> unix user mapping
1996 (void)map_username(user_name
);
1999 * UNIX username case mangling not required, pass_oem_change
2000 * is case insensitive.
2003 status
= pass_oem_change(user_name
,
2004 r
->in
.lm_password
->data
,
2005 r
->in
.lm_verifier
->hash
,
2006 r
->in
.nt_password
->data
,
2007 r
->in
.nt_verifier
->hash
,
2010 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
2012 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
2013 return NT_STATUS_WRONG_PASSWORD
;
2019 /****************************************************************
2020 _samr_OemChangePasswordUser2
2021 ****************************************************************/
2023 NTSTATUS
_samr_OemChangePasswordUser2(pipes_struct
*p
,
2024 struct samr_OemChangePasswordUser2
*r
)
2028 const char *wks
= NULL
;
2030 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
2032 fstrcpy(user_name
, r
->in
.account
->string
);
2033 if (r
->in
.server
&& r
->in
.server
->string
) {
2034 wks
= r
->in
.server
->string
;
2037 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
2040 * Pass the user through the NT -> unix user mapping
2044 (void)map_username(user_name
);
2047 * UNIX username case mangling not required, pass_oem_change
2048 * is case insensitive.
2051 if (!r
->in
.hash
|| !r
->in
.password
) {
2052 return NT_STATUS_INVALID_PARAMETER
;
2055 status
= pass_oem_change(user_name
,
2056 r
->in
.password
->data
,
2062 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
2063 return NT_STATUS_WRONG_PASSWORD
;
2066 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
2071 /*******************************************************************
2072 _samr_ChangePasswordUser3
2073 ********************************************************************/
2075 NTSTATUS
_samr_ChangePasswordUser3(pipes_struct
*p
,
2076 struct samr_ChangePasswordUser3
*r
)
2080 const char *wks
= NULL
;
2081 uint32 reject_reason
;
2082 struct samr_DomInfo1
*dominfo
= NULL
;
2083 struct samr_ChangeReject
*reject
= NULL
;
2086 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
2088 fstrcpy(user_name
, r
->in
.account
->string
);
2089 if (r
->in
.server
&& r
->in
.server
->string
) {
2090 wks
= r
->in
.server
->string
;
2093 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name
, wks
));
2096 * Pass the user through the NT -> unix user mapping
2100 (void)map_username(user_name
);
2103 * UNIX username case mangling not required, pass_oem_change
2104 * is case insensitive.
2107 status
= pass_oem_change(user_name
,
2108 r
->in
.lm_password
->data
,
2109 r
->in
.lm_verifier
->hash
,
2110 r
->in
.nt_password
->data
,
2111 r
->in
.nt_verifier
->hash
,
2113 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
2114 return NT_STATUS_WRONG_PASSWORD
;
2117 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) ||
2118 NT_STATUS_EQUAL(status
, NT_STATUS_ACCOUNT_RESTRICTION
)) {
2120 time_t u_expire
, u_min_age
;
2121 uint32 account_policy_temp
;
2123 dominfo
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_DomInfo1
);
2125 return NT_STATUS_NO_MEMORY
;
2128 reject
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_ChangeReject
);
2130 return NT_STATUS_NO_MEMORY
;
2137 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
, &tmp
);
2138 dominfo
->min_password_length
= tmp
;
2140 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &tmp
);
2141 dominfo
->password_history_length
= tmp
;
2143 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
2144 &dominfo
->password_properties
);
2146 pdb_get_account_policy(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
2147 u_expire
= account_policy_temp
;
2149 pdb_get_account_policy(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
2150 u_min_age
= account_policy_temp
;
2156 unix_to_nt_time_abs((NTTIME
*)&dominfo
->max_password_age
, u_expire
);
2157 unix_to_nt_time_abs((NTTIME
*)&dominfo
->min_password_age
, u_min_age
);
2159 if (lp_check_password_script() && *lp_check_password_script()) {
2160 dominfo
->password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
2163 reject
->reason
= reject_reason
;
2165 *r
->out
.dominfo
= dominfo
;
2166 *r
->out
.reject
= reject
;
2169 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
2174 /*******************************************************************
2175 makes a SAMR_R_LOOKUP_RIDS structure.
2176 ********************************************************************/
2178 static bool make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
,
2180 struct lsa_String
**lsa_name_array_p
)
2182 struct lsa_String
*lsa_name_array
= NULL
;
2185 *lsa_name_array_p
= NULL
;
2187 if (num_names
!= 0) {
2188 lsa_name_array
= TALLOC_ZERO_ARRAY(ctx
, struct lsa_String
, num_names
);
2189 if (!lsa_name_array
) {
2194 for (i
= 0; i
< num_names
; i
++) {
2195 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
] && *names
[i
] ? names
[i
] : ""));
2196 init_lsa_String(&lsa_name_array
[i
], names
[i
]);
2199 *lsa_name_array_p
= lsa_name_array
;
2204 /*******************************************************************
2206 ********************************************************************/
2208 NTSTATUS
_samr_LookupRids(pipes_struct
*p
,
2209 struct samr_LookupRids
*r
)
2213 enum lsa_SidType
*attrs
= NULL
;
2214 uint32
*wire_attrs
= NULL
;
2216 int num_rids
= (int)r
->in
.num_rids
;
2219 struct lsa_Strings names_array
;
2220 struct samr_Ids types_array
;
2221 struct lsa_String
*lsa_names
= NULL
;
2223 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2225 /* find the policy handle. open a policy on it. */
2226 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &pol_sid
, &acc_granted
, NULL
))
2227 return NT_STATUS_INVALID_HANDLE
;
2229 status
= access_check_samr_function(acc_granted
,
2230 0, /* Don't know the acc_bits yet */
2231 "_samr_LookupRids");
2232 if (!NT_STATUS_IS_OK(status
)) {
2236 if (num_rids
> 1000) {
2237 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2238 "to samba4 idl this is not possible\n", num_rids
));
2239 return NT_STATUS_UNSUCCESSFUL
;
2243 names
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, const char *, num_rids
);
2244 attrs
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
2245 wire_attrs
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_rids
);
2247 if ((names
== NULL
) || (attrs
== NULL
) || (wire_attrs
==NULL
))
2248 return NT_STATUS_NO_MEMORY
;
2255 become_root(); /* lookup_sid can require root privs */
2256 status
= pdb_lookup_rids(&pol_sid
, num_rids
, r
->in
.rids
,
2260 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
) && (num_rids
== 0)) {
2261 status
= NT_STATUS_OK
;
2264 if (!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, names
,
2266 return NT_STATUS_NO_MEMORY
;
2269 /* Convert from enum lsa_SidType to uint32 for wire format. */
2270 for (i
= 0; i
< num_rids
; i
++) {
2271 wire_attrs
[i
] = (uint32
)attrs
[i
];
2274 names_array
.count
= num_rids
;
2275 names_array
.names
= lsa_names
;
2277 types_array
.count
= num_rids
;
2278 types_array
.ids
= wire_attrs
;
2280 *r
->out
.names
= names_array
;
2281 *r
->out
.types
= types_array
;
2283 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2288 /*******************************************************************
2290 ********************************************************************/
2292 NTSTATUS
_samr_OpenUser(pipes_struct
*p
,
2293 struct samr_OpenUser
*r
)
2295 struct samu
*sampass
=NULL
;
2297 struct samr_info
*info
= NULL
;
2298 SEC_DESC
*psd
= NULL
;
2300 uint32 des_access
= r
->in
.access_mask
;
2306 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2308 if ( !get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
, NULL
) )
2309 return NT_STATUS_INVALID_HANDLE
;
2311 nt_status
= access_check_samr_function(acc_granted
,
2312 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
2315 if ( !NT_STATUS_IS_OK(nt_status
) )
2318 if ( !(sampass
= samu_new( p
->mem_ctx
)) ) {
2319 return NT_STATUS_NO_MEMORY
;
2322 /* append the user's RID to it */
2324 if (!sid_append_rid(&sid
, r
->in
.rid
))
2325 return NT_STATUS_NO_SUCH_USER
;
2327 /* check if access can be granted as requested by client. */
2329 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
2331 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
, &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
2332 se_map_generic(&des_access
, &usr_generic_mapping
);
2334 se_priv_copy( &se_rights
, &se_machine_account
);
2335 se_priv_add( &se_rights
, &se_add_users
);
2337 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
2338 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
2339 &acc_granted
, "_samr_OpenUser");
2341 if ( !NT_STATUS_IS_OK(nt_status
) )
2345 ret
=pdb_getsampwsid(sampass
, &sid
);
2348 /* check that the SID exists in our domain. */
2350 return NT_STATUS_NO_SUCH_USER
;
2353 TALLOC_FREE(sampass
);
2355 /* associate the user's SID and access bits with the new handle. */
2356 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &sid
)) == NULL
)
2357 return NT_STATUS_NO_MEMORY
;
2358 info
->acc_granted
= acc_granted
;
2360 /* get a (unique) handle. open a policy on it. */
2361 if (!create_policy_hnd(p
, r
->out
.user_handle
, info
))
2362 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2364 return NT_STATUS_OK
;
2367 /*************************************************************************
2368 *************************************************************************/
2370 static NTSTATUS
init_samr_parameters_string(TALLOC_CTX
*mem_ctx
,
2372 struct lsa_BinaryString
**_r
)
2374 struct lsa_BinaryString
*r
;
2377 return NT_STATUS_INVALID_PARAMETER
;
2380 r
= TALLOC_ZERO_P(mem_ctx
, struct lsa_BinaryString
);
2382 return NT_STATUS_NO_MEMORY
;
2385 r
->array
= TALLOC_ZERO_ARRAY(mem_ctx
, uint16_t, blob
->length
/2);
2387 return NT_STATUS_NO_MEMORY
;
2389 memcpy(r
->array
, blob
->data
, blob
->length
);
2390 r
->size
= blob
->length
;
2391 r
->length
= blob
->length
;
2394 return NT_STATUS_NO_MEMORY
;
2399 return NT_STATUS_OK
;
2402 /*************************************************************************
2404 *************************************************************************/
2406 static NTSTATUS
get_user_info_1(TALLOC_CTX
*mem_ctx
,
2407 struct samr_UserInfo1
*r
,
2409 DOM_SID
*domain_sid
)
2411 const DOM_SID
*sid_group
;
2412 uint32_t primary_gid
;
2415 sid_group
= pdb_get_group_sid(pw
);
2418 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2419 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2420 "which conflicts with the domain sid %s. Failing operation.\n",
2421 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2422 sid_string_dbg(domain_sid
)));
2423 return NT_STATUS_UNSUCCESSFUL
;
2426 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2427 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2428 r
->primary_gid
= primary_gid
;
2429 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2430 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2432 return NT_STATUS_OK
;
2435 /*************************************************************************
2437 *************************************************************************/
2439 static NTSTATUS
get_user_info_2(TALLOC_CTX
*mem_ctx
,
2440 struct samr_UserInfo2
*r
,
2443 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2444 r
->unknown
.string
= NULL
;
2445 r
->country_code
= 0;
2448 return NT_STATUS_OK
;
2451 /*************************************************************************
2453 *************************************************************************/
2455 static NTSTATUS
get_user_info_3(TALLOC_CTX
*mem_ctx
,
2456 struct samr_UserInfo3
*r
,
2458 DOM_SID
*domain_sid
)
2460 const DOM_SID
*sid_user
, *sid_group
;
2461 uint32_t rid
, primary_gid
;
2463 sid_user
= pdb_get_user_sid(pw
);
2465 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2466 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2467 "the domain sid %s. Failing operation.\n",
2468 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2469 sid_string_dbg(domain_sid
)));
2470 return NT_STATUS_UNSUCCESSFUL
;
2474 sid_group
= pdb_get_group_sid(pw
);
2477 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2478 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2479 "which conflicts with the domain sid %s. Failing operation.\n",
2480 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2481 sid_string_dbg(domain_sid
)));
2482 return NT_STATUS_UNSUCCESSFUL
;
2485 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2486 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2487 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2488 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2489 unix_to_nt_time(&r
->force_password_change
, pdb_get_pass_must_change_time(pw
));
2491 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2492 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2493 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2494 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2495 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2496 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2497 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2499 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2501 r
->primary_gid
= primary_gid
;
2502 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2503 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2504 r
->logon_count
= pdb_get_logon_count(pw
);
2506 return NT_STATUS_OK
;
2509 /*************************************************************************
2511 *************************************************************************/
2513 static NTSTATUS
get_user_info_4(TALLOC_CTX
*mem_ctx
,
2514 struct samr_UserInfo4
*r
,
2517 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2519 return NT_STATUS_OK
;
2522 /*************************************************************************
2524 *************************************************************************/
2526 static NTSTATUS
get_user_info_5(TALLOC_CTX
*mem_ctx
,
2527 struct samr_UserInfo5
*r
,
2529 DOM_SID
*domain_sid
)
2531 const DOM_SID
*sid_user
, *sid_group
;
2532 uint32_t rid
, primary_gid
;
2534 sid_user
= pdb_get_user_sid(pw
);
2536 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2537 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2538 "the domain sid %s. Failing operation.\n",
2539 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2540 sid_string_dbg(domain_sid
)));
2541 return NT_STATUS_UNSUCCESSFUL
;
2545 sid_group
= pdb_get_group_sid(pw
);
2548 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2549 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2550 "which conflicts with the domain sid %s. Failing operation.\n",
2551 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2552 sid_string_dbg(domain_sid
)));
2553 return NT_STATUS_UNSUCCESSFUL
;
2556 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2557 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2558 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2559 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2561 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2562 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2563 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2564 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2565 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2566 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2567 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2568 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2570 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2572 r
->primary_gid
= primary_gid
;
2573 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2574 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2575 r
->logon_count
= pdb_get_logon_count(pw
);
2577 return NT_STATUS_OK
;
2580 /*************************************************************************
2582 *************************************************************************/
2584 static NTSTATUS
get_user_info_6(TALLOC_CTX
*mem_ctx
,
2585 struct samr_UserInfo6
*r
,
2588 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2589 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2591 return NT_STATUS_OK
;
2594 /*************************************************************************
2595 get_user_info_7. Safe. Only gives out account_name.
2596 *************************************************************************/
2598 static NTSTATUS
get_user_info_7(TALLOC_CTX
*mem_ctx
,
2599 struct samr_UserInfo7
*r
,
2600 struct samu
*smbpass
)
2602 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(smbpass
));
2603 if (!r
->account_name
.string
) {
2604 return NT_STATUS_NO_MEMORY
;
2607 return NT_STATUS_OK
;
2610 /*************************************************************************
2612 *************************************************************************/
2614 static NTSTATUS
get_user_info_8(TALLOC_CTX
*mem_ctx
,
2615 struct samr_UserInfo8
*r
,
2618 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2620 return NT_STATUS_OK
;
2623 /*************************************************************************
2624 get_user_info_9. Only gives out primary group SID.
2625 *************************************************************************/
2627 static NTSTATUS
get_user_info_9(TALLOC_CTX
*mem_ctx
,
2628 struct samr_UserInfo9
*r
,
2629 struct samu
*smbpass
)
2631 r
->primary_gid
= pdb_get_group_rid(smbpass
);
2633 return NT_STATUS_OK
;
2636 /*************************************************************************
2638 *************************************************************************/
2640 static NTSTATUS
get_user_info_10(TALLOC_CTX
*mem_ctx
,
2641 struct samr_UserInfo10
*r
,
2644 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2645 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2647 return NT_STATUS_OK
;
2650 /*************************************************************************
2652 *************************************************************************/
2654 static NTSTATUS
get_user_info_11(TALLOC_CTX
*mem_ctx
,
2655 struct samr_UserInfo11
*r
,
2658 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2660 return NT_STATUS_OK
;
2663 /*************************************************************************
2665 *************************************************************************/
2667 static NTSTATUS
get_user_info_12(TALLOC_CTX
*mem_ctx
,
2668 struct samr_UserInfo12
*r
,
2671 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2673 return NT_STATUS_OK
;
2676 /*************************************************************************
2678 *************************************************************************/
2680 static NTSTATUS
get_user_info_13(TALLOC_CTX
*mem_ctx
,
2681 struct samr_UserInfo13
*r
,
2684 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2686 return NT_STATUS_OK
;
2689 /*************************************************************************
2691 *************************************************************************/
2693 static NTSTATUS
get_user_info_14(TALLOC_CTX
*mem_ctx
,
2694 struct samr_UserInfo14
*r
,
2697 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2699 return NT_STATUS_OK
;
2702 /*************************************************************************
2703 get_user_info_16. Safe. Only gives out acb bits.
2704 *************************************************************************/
2706 static NTSTATUS
get_user_info_16(TALLOC_CTX
*mem_ctx
,
2707 struct samr_UserInfo16
*r
,
2708 struct samu
*smbpass
)
2710 r
->acct_flags
= pdb_get_acct_ctrl(smbpass
);
2712 return NT_STATUS_OK
;
2715 /*************************************************************************
2717 *************************************************************************/
2719 static NTSTATUS
get_user_info_17(TALLOC_CTX
*mem_ctx
,
2720 struct samr_UserInfo17
*r
,
2723 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2725 return NT_STATUS_OK
;
2728 /*************************************************************************
2729 get_user_info_18. OK - this is the killer as it gives out password info.
2730 Ensure that this is only allowed on an encrypted connection with a root
2732 *************************************************************************/
2734 static NTSTATUS
get_user_info_18(pipes_struct
*p
,
2735 TALLOC_CTX
*mem_ctx
,
2736 struct samr_UserInfo18
*r
,
2739 struct samu
*smbpass
=NULL
;
2744 if (p
->auth
.auth_type
!= PIPE_AUTH_TYPE_NTLMSSP
|| p
->auth
.auth_type
!= PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
) {
2745 return NT_STATUS_ACCESS_DENIED
;
2748 if (p
->auth
.auth_level
!= PIPE_AUTH_LEVEL_PRIVACY
) {
2749 return NT_STATUS_ACCESS_DENIED
;
2753 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2756 if ( !(smbpass
= samu_new( mem_ctx
)) ) {
2757 return NT_STATUS_NO_MEMORY
;
2760 ret
= pdb_getsampwsid(smbpass
, user_sid
);
2763 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid
)));
2764 TALLOC_FREE(smbpass
);
2765 return (geteuid() == (uid_t
)0) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
2768 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
2770 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
2771 TALLOC_FREE(smbpass
);
2772 return NT_STATUS_ACCOUNT_DISABLED
;
2775 r
->lm_pwd_active
= true;
2776 r
->nt_pwd_active
= true;
2777 memcpy(r
->lm_pwd
.hash
, pdb_get_lanman_passwd(smbpass
), 16);
2778 memcpy(r
->nt_pwd
.hash
, pdb_get_nt_passwd(smbpass
), 16);
2779 r
->password_expired
= 0; /* FIXME */
2781 TALLOC_FREE(smbpass
);
2783 return NT_STATUS_OK
;
2786 /*************************************************************************
2788 *************************************************************************/
2790 static NTSTATUS
get_user_info_20(TALLOC_CTX
*mem_ctx
,
2791 struct samr_UserInfo20
*r
,
2792 struct samu
*sampass
)
2794 const char *munged_dial
= NULL
;
2797 struct lsa_BinaryString
*parameters
= NULL
;
2801 munged_dial
= pdb_get_munged_dial(sampass
);
2803 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass
),
2804 munged_dial
, (int)strlen(munged_dial
)));
2807 blob
= base64_decode_data_blob(munged_dial
);
2809 blob
= data_blob_string_const_null("");
2812 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2813 data_blob_free(&blob
);
2814 if (!NT_STATUS_IS_OK(status
)) {
2818 r
->parameters
= *parameters
;
2820 return NT_STATUS_OK
;
2824 /*************************************************************************
2826 *************************************************************************/
2828 static NTSTATUS
get_user_info_21(TALLOC_CTX
*mem_ctx
,
2829 struct samr_UserInfo21
*r
,
2831 DOM_SID
*domain_sid
)
2834 const DOM_SID
*sid_user
, *sid_group
;
2835 uint32_t rid
, primary_gid
;
2836 NTTIME force_password_change
;
2837 time_t must_change_time
;
2838 struct lsa_BinaryString
*parameters
= NULL
;
2839 const char *munged_dial
= NULL
;
2844 sid_user
= pdb_get_user_sid(pw
);
2846 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2847 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2848 "the domain sid %s. Failing operation.\n",
2849 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2850 sid_string_dbg(domain_sid
)));
2851 return NT_STATUS_UNSUCCESSFUL
;
2855 sid_group
= pdb_get_group_sid(pw
);
2858 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2859 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2860 "which conflicts with the domain sid %s. Failing operation.\n",
2861 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2862 sid_string_dbg(domain_sid
)));
2863 return NT_STATUS_UNSUCCESSFUL
;
2866 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2867 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2868 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2869 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2870 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2872 must_change_time
= pdb_get_pass_must_change_time(pw
);
2873 if (must_change_time
== get_time_t_max()) {
2874 unix_to_nt_time_abs(&force_password_change
, must_change_time
);
2876 unix_to_nt_time(&force_password_change
, must_change_time
);
2879 munged_dial
= pdb_get_munged_dial(pw
);
2881 blob
= base64_decode_data_blob(munged_dial
);
2883 blob
= data_blob_string_const_null("");
2886 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2887 data_blob_free(&blob
);
2888 if (!NT_STATUS_IS_OK(status
)) {
2892 r
->force_password_change
= force_password_change
;
2894 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2895 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2896 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2897 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2898 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2899 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2900 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2901 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2902 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2904 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2905 r
->parameters
= *parameters
;
2907 r
->primary_gid
= primary_gid
;
2908 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2909 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2910 r
->logon_count
= pdb_get_logon_count(pw
);
2911 r
->fields_present
= pdb_build_fields_present(pw
);
2912 r
->password_expired
= (pdb_get_pass_must_change_time(pw
) == 0) ?
2913 PASS_MUST_CHANGE_AT_NEXT_LOGON
: 0;
2914 r
->country_code
= 0;
2916 r
->lm_password_set
= 0;
2917 r
->nt_password_set
= 0;
2922 Look at a user on a real NT4 PDC with usrmgr, press
2923 'ok'. Then you will see that fields_present is set to
2924 0x08f827fa. Look at the user immediately after that again,
2925 and you will see that 0x00fffff is returned. This solves
2926 the problem that you get access denied after having looked
2934 return NT_STATUS_OK
;
2937 /*******************************************************************
2939 ********************************************************************/
2941 NTSTATUS
_samr_QueryUserInfo(pipes_struct
*p
,
2942 struct samr_QueryUserInfo
*r
)
2945 union samr_UserInfo
*user_info
= NULL
;
2946 struct samr_info
*info
= NULL
;
2950 struct samu
*pwd
= NULL
;
2952 /* search for the handle */
2953 if (!find_policy_by_hnd(p
, r
->in
.user_handle
, (void **)(void *)&info
))
2954 return NT_STATUS_INVALID_HANDLE
;
2956 status
= access_check_samr_function(info
->acc_granted
,
2957 SAMR_USER_ACCESS_GET_ATTRIBUTES
,
2958 "_samr_QueryUserInfo");
2959 if (!NT_STATUS_IS_OK(status
)) {
2963 domain_sid
= info
->sid
;
2965 sid_split_rid(&domain_sid
, &rid
);
2967 if (!sid_check_is_in_our_domain(&info
->sid
))
2968 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
2970 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2971 sid_string_dbg(&info
->sid
)));
2973 user_info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_UserInfo
);
2975 return NT_STATUS_NO_MEMORY
;
2978 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r
->in
.level
));
2980 if (!(pwd
= samu_new(p
->mem_ctx
))) {
2981 return NT_STATUS_NO_MEMORY
;
2985 ret
= pdb_getsampwsid(pwd
, &info
->sid
);
2989 DEBUG(4,("User %s not found\n", sid_string_dbg(&info
->sid
)));
2991 return NT_STATUS_NO_SUCH_USER
;
2994 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd
)));
2996 samr_clear_sam_passwd(pwd
);
2998 switch (r
->in
.level
) {
3000 status
= get_user_info_1(p
->mem_ctx
, &user_info
->info1
, pwd
, &domain_sid
);
3003 status
= get_user_info_2(p
->mem_ctx
, &user_info
->info2
, pwd
);
3006 status
= get_user_info_3(p
->mem_ctx
, &user_info
->info3
, pwd
, &domain_sid
);
3009 status
= get_user_info_4(p
->mem_ctx
, &user_info
->info4
, pwd
);
3012 status
= get_user_info_5(p
->mem_ctx
, &user_info
->info5
, pwd
, &domain_sid
);
3015 status
= get_user_info_6(p
->mem_ctx
, &user_info
->info6
, pwd
);
3018 status
= get_user_info_7(p
->mem_ctx
, &user_info
->info7
, pwd
);
3021 status
= get_user_info_8(p
->mem_ctx
, &user_info
->info8
, pwd
);
3024 status
= get_user_info_9(p
->mem_ctx
, &user_info
->info9
, pwd
);
3027 status
= get_user_info_10(p
->mem_ctx
, &user_info
->info10
, pwd
);
3030 status
= get_user_info_11(p
->mem_ctx
, &user_info
->info11
, pwd
);
3033 status
= get_user_info_12(p
->mem_ctx
, &user_info
->info12
, pwd
);
3036 status
= get_user_info_13(p
->mem_ctx
, &user_info
->info13
, pwd
);
3039 status
= get_user_info_14(p
->mem_ctx
, &user_info
->info14
, pwd
);
3042 status
= get_user_info_16(p
->mem_ctx
, &user_info
->info16
, pwd
);
3045 status
= get_user_info_17(p
->mem_ctx
, &user_info
->info17
, pwd
);
3048 /* level 18 is special */
3049 status
= get_user_info_18(p
, p
->mem_ctx
, &user_info
->info18
, &info
->sid
);
3052 status
= get_user_info_20(p
->mem_ctx
, &user_info
->info20
, pwd
);
3055 status
= get_user_info_21(p
->mem_ctx
, &user_info
->info21
, pwd
, &domain_sid
);
3058 status
= NT_STATUS_INVALID_INFO_CLASS
;
3064 *r
->out
.info
= user_info
;
3066 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__
));
3071 /****************************************************************
3072 ****************************************************************/
3074 NTSTATUS
_samr_QueryUserInfo2(pipes_struct
*p
,
3075 struct samr_QueryUserInfo2
*r
)
3077 struct samr_QueryUserInfo u
;
3079 u
.in
.user_handle
= r
->in
.user_handle
;
3080 u
.in
.level
= r
->in
.level
;
3081 u
.out
.info
= r
->out
.info
;
3083 return _samr_QueryUserInfo(p
, &u
);
3086 /*******************************************************************
3087 _samr_GetGroupsForUser
3088 ********************************************************************/
3090 NTSTATUS
_samr_GetGroupsForUser(pipes_struct
*p
,
3091 struct samr_GetGroupsForUser
*r
)
3093 struct samu
*sam_pass
=NULL
;
3096 struct samr_RidWithAttribute dom_gid
;
3097 struct samr_RidWithAttribute
*gids
= NULL
;
3098 uint32 primary_group_rid
;
3099 size_t num_groups
= 0;
3105 bool success
= False
;
3107 struct samr_RidWithAttributeArray
*rids
= NULL
;
3110 * from the SID in the request:
3111 * we should send back the list of DOMAIN GROUPS
3112 * the user is a member of
3114 * and only the DOMAIN GROUPS
3115 * no ALIASES !!! neither aliases of the domain
3116 * nor aliases of the builtin SID
3121 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3123 rids
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_RidWithAttributeArray
);
3125 return NT_STATUS_NO_MEMORY
;
3128 /* find the policy handle. open a policy on it. */
3129 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &sid
, &acc_granted
, NULL
))
3130 return NT_STATUS_INVALID_HANDLE
;
3132 result
= access_check_samr_function(acc_granted
,
3133 SAMR_USER_ACCESS_GET_GROUPS
,
3134 "_samr_GetGroupsForUser");
3135 if (!NT_STATUS_IS_OK(result
)) {
3139 if (!sid_check_is_in_our_domain(&sid
))
3140 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3142 if ( !(sam_pass
= samu_new( p
->mem_ctx
)) ) {
3143 return NT_STATUS_NO_MEMORY
;
3147 ret
= pdb_getsampwsid(sam_pass
, &sid
);
3151 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3152 sid_string_dbg(&sid
)));
3153 return NT_STATUS_NO_SUCH_USER
;
3158 /* make both calls inside the root block */
3160 result
= pdb_enum_group_memberships(p
->mem_ctx
, sam_pass
,
3161 &sids
, &unix_gids
, &num_groups
);
3162 if ( NT_STATUS_IS_OK(result
) ) {
3163 success
= sid_peek_check_rid(get_global_sam_sid(),
3164 pdb_get_group_sid(sam_pass
),
3165 &primary_group_rid
);
3169 if (!NT_STATUS_IS_OK(result
)) {
3170 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3171 sid_string_dbg(&sid
)));
3176 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3177 sid_string_dbg(pdb_get_group_sid(sam_pass
)),
3178 pdb_get_username(sam_pass
)));
3179 TALLOC_FREE(sam_pass
);
3180 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
3186 dom_gid
.attributes
= (SE_GROUP_MANDATORY
|SE_GROUP_ENABLED_BY_DEFAULT
|
3188 dom_gid
.rid
= primary_group_rid
;
3189 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3191 for (i
=0; i
<num_groups
; i
++) {
3193 if (!sid_peek_check_rid(get_global_sam_sid(),
3194 &(sids
[i
]), &dom_gid
.rid
)) {
3195 DEBUG(10, ("Found sid %s not in our domain\n",
3196 sid_string_dbg(&sids
[i
])));
3200 if (dom_gid
.rid
== primary_group_rid
) {
3201 /* We added the primary group directly from the
3202 * sam_account. The other SIDs are unique from
3203 * enum_group_memberships */
3207 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3210 rids
->count
= num_gids
;
3213 *r
->out
.rids
= rids
;
3215 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3220 /*******************************************************************
3221 _samr_QueryDomainInfo
3222 ********************************************************************/
3224 NTSTATUS
_samr_QueryDomainInfo(pipes_struct
*p
,
3225 struct samr_QueryDomainInfo
*r
)
3227 NTSTATUS status
= NT_STATUS_OK
;
3228 struct samr_info
*info
= NULL
;
3229 union samr_DomainInfo
*dom_info
;
3230 time_t u_expire
, u_min_age
;
3232 time_t u_lock_duration
, u_reset_time
;
3235 uint32 account_policy_temp
;
3240 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3242 dom_info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_DomainInfo
);
3244 return NT_STATUS_NO_MEMORY
;
3247 /* find the policy handle. open a policy on it. */
3248 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
)) {
3249 return NT_STATUS_INVALID_HANDLE
;
3252 status
= access_check_samr_function(info
->acc_granted
,
3253 SAMR_ACCESS_LOOKUP_DOMAIN
,
3254 "_samr_QueryDomainInfo" );
3256 if ( !NT_STATUS_IS_OK(status
) )
3259 switch (r
->in
.level
) {
3266 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
,
3267 &account_policy_temp
);
3268 dom_info
->info1
.min_password_length
= account_policy_temp
;
3270 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &account_policy_temp
);
3271 dom_info
->info1
.password_history_length
= account_policy_temp
;
3273 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
3274 &dom_info
->info1
.password_properties
);
3276 pdb_get_account_policy(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
3277 u_expire
= account_policy_temp
;
3279 pdb_get_account_policy(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
3280 u_min_age
= account_policy_temp
;
3286 unix_to_nt_time_abs((NTTIME
*)&dom_info
->info1
.max_password_age
, u_expire
);
3287 unix_to_nt_time_abs((NTTIME
*)&dom_info
->info1
.min_password_age
, u_min_age
);
3289 if (lp_check_password_script() && *lp_check_password_script()) {
3290 dom_info
->info1
.password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
3300 dom_info
->general
.num_users
= count_sam_users(info
->disp_info
, ACB_NORMAL
);
3301 dom_info
->general
.num_groups
= count_sam_groups(info
->disp_info
);
3302 dom_info
->general
.num_aliases
= count_sam_aliases(info
->disp_info
);
3304 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &u_logout
);
3306 unix_to_nt_time_abs(&dom_info
->general
.force_logoff_time
, u_logout
);
3308 if (!pdb_get_seq_num(&seq_num
))
3309 seq_num
= time(NULL
);
3315 server_role
= ROLE_DOMAIN_PDC
;
3316 if (lp_server_role() == ROLE_DOMAIN_BDC
)
3317 server_role
= ROLE_DOMAIN_BDC
;
3319 dom_info
->general
.oem_information
.string
= lp_serverstring();
3320 dom_info
->general
.domain_name
.string
= lp_workgroup();
3321 dom_info
->general
.primary
.string
= global_myname();
3322 dom_info
->general
.sequence_num
= seq_num
;
3323 dom_info
->general
.domain_server_state
= DOMAIN_SERVER_ENABLED
;
3324 dom_info
->general
.role
= server_role
;
3325 dom_info
->general
.unknown3
= 1;
3336 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &ul
);
3337 u_logout
= (time_t)ul
;
3344 unix_to_nt_time_abs(&dom_info
->info3
.force_logoff_time
, u_logout
);
3348 dom_info
->oem
.oem_information
.string
= lp_serverstring();
3351 dom_info
->info5
.domain_name
.string
= get_global_sam_name();
3354 /* NT returns its own name when a PDC. win2k and later
3355 * only the name of the PDC if itself is a BDC (samba4
3357 dom_info
->info6
.primary
.string
= global_myname();
3360 server_role
= ROLE_DOMAIN_PDC
;
3361 if (lp_server_role() == ROLE_DOMAIN_BDC
)
3362 server_role
= ROLE_DOMAIN_BDC
;
3364 dom_info
->info7
.role
= server_role
;
3372 if (!pdb_get_seq_num(&seq_num
)) {
3373 seq_num
= time(NULL
);
3380 dom_info
->info8
.sequence_num
= seq_num
;
3381 dom_info
->info8
.domain_create_time
= 0;
3390 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
3391 u_lock_duration
= account_policy_temp
;
3392 if (u_lock_duration
!= -1) {
3393 u_lock_duration
*= 60;
3396 pdb_get_account_policy(AP_RESET_COUNT_TIME
, &account_policy_temp
);
3397 u_reset_time
= account_policy_temp
* 60;
3399 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
,
3400 &account_policy_temp
);
3401 dom_info
->info12
.lockout_threshold
= account_policy_temp
;
3407 unix_to_nt_time_abs(&dom_info
->info12
.lockout_duration
,
3409 unix_to_nt_time_abs(&dom_info
->info12
.lockout_window
,
3414 return NT_STATUS_INVALID_INFO_CLASS
;
3417 *r
->out
.info
= dom_info
;
3419 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3424 /* W2k3 seems to use the same check for all 3 objects that can be created via
3425 * SAMR, if you try to create for example "Dialup" as an alias it says
3426 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3429 static NTSTATUS
can_create(TALLOC_CTX
*mem_ctx
, const char *new_name
)
3431 enum lsa_SidType type
;
3434 DEBUG(10, ("Checking whether [%s] can be created\n", new_name
));
3437 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3438 * whether the name already exists */
3439 result
= lookup_name(mem_ctx
, new_name
, LOOKUP_NAME_LOCAL
,
3440 NULL
, NULL
, NULL
, &type
);
3444 DEBUG(10, ("%s does not exist, can create it\n", new_name
));
3445 return NT_STATUS_OK
;
3448 DEBUG(5, ("trying to create %s, exists as %s\n",
3449 new_name
, sid_type_lookup(type
)));
3451 if (type
== SID_NAME_DOM_GRP
) {
3452 return NT_STATUS_GROUP_EXISTS
;
3454 if (type
== SID_NAME_ALIAS
) {
3455 return NT_STATUS_ALIAS_EXISTS
;
3458 /* Yes, the default is NT_STATUS_USER_EXISTS */
3459 return NT_STATUS_USER_EXISTS
;
3462 /*******************************************************************
3464 ********************************************************************/
3466 NTSTATUS
_samr_CreateUser2(pipes_struct
*p
,
3467 struct samr_CreateUser2
*r
)
3469 const char *account
= NULL
;
3471 uint32_t acb_info
= r
->in
.acct_flags
;
3472 struct samr_info
*info
= NULL
;
3477 /* check this, when giving away 'add computer to domain' privs */
3478 uint32 des_access
= GENERIC_RIGHTS_USER_ALL_ACCESS
;
3479 bool can_add_account
= False
;
3481 DISP_INFO
*disp_info
= NULL
;
3483 /* Get the domain SID stored in the domain policy */
3484 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
,
3486 return NT_STATUS_INVALID_HANDLE
;
3488 if (disp_info
->builtin_domain
) {
3489 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3490 return NT_STATUS_ACCESS_DENIED
;
3493 nt_status
= access_check_samr_function(acc_granted
,
3494 SAMR_DOMAIN_ACCESS_CREATE_USER
,
3495 "_samr_CreateUser2");
3496 if (!NT_STATUS_IS_OK(nt_status
)) {
3500 if (!(acb_info
== ACB_NORMAL
|| acb_info
== ACB_DOMTRUST
||
3501 acb_info
== ACB_WSTRUST
|| acb_info
== ACB_SVRTRUST
)) {
3502 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3503 this parameter is not an account type */
3504 return NT_STATUS_INVALID_PARAMETER
;
3507 account
= r
->in
.account_name
->string
;
3508 if (account
== NULL
) {
3509 return NT_STATUS_NO_MEMORY
;
3512 nt_status
= can_create(p
->mem_ctx
, account
);
3513 if (!NT_STATUS_IS_OK(nt_status
)) {
3517 /* determine which user right we need to check based on the acb_info */
3519 if ( acb_info
& ACB_WSTRUST
)
3521 se_priv_copy( &se_rights
, &se_machine_account
);
3522 can_add_account
= user_has_privileges(
3523 p
->server_info
->ptok
, &se_rights
);
3525 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3526 account for domain trusts and changes the ACB flags later */
3527 else if ( acb_info
& ACB_NORMAL
&&
3528 (account
[strlen(account
)-1] != '$') )
3530 se_priv_copy( &se_rights
, &se_add_users
);
3531 can_add_account
= user_has_privileges(
3532 p
->server_info
->ptok
, &se_rights
);
3534 else /* implicit assumption of a BDC or domain trust account here
3535 * (we already check the flags earlier) */
3537 if ( lp_enable_privileges() ) {
3538 /* only Domain Admins can add a BDC or domain trust */
3539 se_priv_copy( &se_rights
, &se_priv_none
);
3540 can_add_account
= nt_token_check_domain_rid(
3541 p
->server_info
->ptok
,
3542 DOMAIN_GROUP_RID_ADMINS
);
3546 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3547 uidtoname(p
->server_info
->utok
.uid
),
3548 can_add_account
? "True":"False" ));
3550 /********** BEGIN Admin BLOCK **********/
3552 if ( can_add_account
)
3555 nt_status
= pdb_create_user(p
->mem_ctx
, account
, acb_info
,
3558 if ( can_add_account
)
3561 /********** END Admin BLOCK **********/
3563 /* now check for failure */
3565 if ( !NT_STATUS_IS_OK(nt_status
) )
3568 /* Get the user's SID */
3570 sid_compose(&sid
, get_global_sam_sid(), *r
->out
.rid
);
3572 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3574 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
,
3575 &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
3576 se_map_generic(&des_access
, &usr_generic_mapping
);
3578 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
3579 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
3580 &acc_granted
, "_samr_CreateUser2");
3582 if ( !NT_STATUS_IS_OK(nt_status
) ) {
3586 /* associate the user's SID with the new handle. */
3587 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &sid
)) == NULL
) {
3588 return NT_STATUS_NO_MEMORY
;
3593 info
->acc_granted
= acc_granted
;
3595 /* get a (unique) handle. open a policy on it. */
3596 if (!create_policy_hnd(p
, r
->out
.user_handle
, info
)) {
3597 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3600 /* After a "set" ensure we have no cached display info. */
3601 force_flush_samr_cache(info
->disp_info
);
3603 *r
->out
.access_granted
= acc_granted
;
3605 return NT_STATUS_OK
;
3608 /****************************************************************
3609 ****************************************************************/
3611 NTSTATUS
_samr_CreateUser(pipes_struct
*p
,
3612 struct samr_CreateUser
*r
)
3614 struct samr_CreateUser2 c
;
3615 uint32_t access_granted
;
3617 c
.in
.domain_handle
= r
->in
.domain_handle
;
3618 c
.in
.account_name
= r
->in
.account_name
;
3619 c
.in
.acct_flags
= ACB_NORMAL
;
3620 c
.in
.access_mask
= r
->in
.access_mask
;
3621 c
.out
.user_handle
= r
->out
.user_handle
;
3622 c
.out
.access_granted
= &access_granted
;
3623 c
.out
.rid
= r
->out
.rid
;
3625 return _samr_CreateUser2(p
, &c
);
3628 /*******************************************************************
3630 ********************************************************************/
3632 NTSTATUS
_samr_Connect(pipes_struct
*p
,
3633 struct samr_Connect
*r
)
3635 struct samr_info
*info
= NULL
;
3636 uint32 des_access
= r
->in
.access_mask
;
3640 if (!pipe_access_check(p
)) {
3641 DEBUG(3, ("access denied to _samr_Connect\n"));
3642 return NT_STATUS_ACCESS_DENIED
;
3645 /* set up the SAMR connect_anon response */
3647 /* associate the user's SID with the new handle. */
3648 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, NULL
)) == NULL
)
3649 return NT_STATUS_NO_MEMORY
;
3651 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3652 was observed from a win98 client trying to enumerate users (when configured
3653 user level access control on shares) --jerry */
3655 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3657 se_map_generic( &des_access
, &sam_generic_mapping
);
3658 info
->acc_granted
= des_access
& (SAMR_ACCESS_ENUM_DOMAINS
|SAMR_ACCESS_LOOKUP_DOMAIN
);
3660 /* get a (unique) handle. open a policy on it. */
3661 if (!create_policy_hnd(p
, r
->out
.connect_handle
, info
))
3662 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3664 return NT_STATUS_OK
;
3667 /*******************************************************************
3669 ********************************************************************/
3671 NTSTATUS
_samr_Connect2(pipes_struct
*p
,
3672 struct samr_Connect2
*r
)
3674 struct samr_info
*info
= NULL
;
3675 SEC_DESC
*psd
= NULL
;
3677 uint32 des_access
= r
->in
.access_mask
;
3680 const char *fn
= "_samr_Connect2";
3682 switch (p
->hdr_req
.opnum
) {
3683 case NDR_SAMR_CONNECT2
:
3684 fn
= "_samr_Connect2";
3686 case NDR_SAMR_CONNECT3
:
3687 fn
= "_samr_Connect3";
3689 case NDR_SAMR_CONNECT4
:
3690 fn
= "_samr_Connect4";
3692 case NDR_SAMR_CONNECT5
:
3693 fn
= "_samr_Connect5";
3697 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3701 if (!pipe_access_check(p
)) {
3702 DEBUG(3, ("access denied to %s\n", fn
));
3703 return NT_STATUS_ACCESS_DENIED
;
3706 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3708 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
3709 se_map_generic(&des_access
, &sam_generic_mapping
);
3711 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
3712 NULL
, 0, des_access
, &acc_granted
, fn
);
3714 if ( !NT_STATUS_IS_OK(nt_status
) )
3717 /* associate the user's SID and access granted with the new handle. */
3718 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, NULL
)) == NULL
)
3719 return NT_STATUS_NO_MEMORY
;
3721 info
->acc_granted
= acc_granted
;
3722 info
->status
= r
->in
.access_mask
; /* this looks so wrong... - gd */
3724 /* get a (unique) handle. open a policy on it. */
3725 if (!create_policy_hnd(p
, r
->out
.connect_handle
, info
))
3726 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3728 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3733 /****************************************************************
3735 ****************************************************************/
3737 NTSTATUS
_samr_Connect3(pipes_struct
*p
,
3738 struct samr_Connect3
*r
)
3740 struct samr_Connect2 c
;
3742 c
.in
.system_name
= r
->in
.system_name
;
3743 c
.in
.access_mask
= r
->in
.access_mask
;
3744 c
.out
.connect_handle
= r
->out
.connect_handle
;
3746 return _samr_Connect2(p
, &c
);
3749 /*******************************************************************
3751 ********************************************************************/
3753 NTSTATUS
_samr_Connect4(pipes_struct
*p
,
3754 struct samr_Connect4
*r
)
3756 struct samr_Connect2 c
;
3758 c
.in
.system_name
= r
->in
.system_name
;
3759 c
.in
.access_mask
= r
->in
.access_mask
;
3760 c
.out
.connect_handle
= r
->out
.connect_handle
;
3762 return _samr_Connect2(p
, &c
);
3765 /*******************************************************************
3767 ********************************************************************/
3769 NTSTATUS
_samr_Connect5(pipes_struct
*p
,
3770 struct samr_Connect5
*r
)
3773 struct samr_Connect2 c
;
3774 struct samr_ConnectInfo1 info1
;
3776 info1
.client_version
= SAMR_CONNECT_AFTER_W2K
;
3779 c
.in
.system_name
= r
->in
.system_name
;
3780 c
.in
.access_mask
= r
->in
.access_mask
;
3781 c
.out
.connect_handle
= r
->out
.connect_handle
;
3783 *r
->out
.level_out
= 1;
3785 status
= _samr_Connect2(p
, &c
);
3786 if (!NT_STATUS_IS_OK(status
)) {
3790 r
->out
.info_out
->info1
= info1
;
3792 return NT_STATUS_OK
;
3795 /**********************************************************************
3797 **********************************************************************/
3799 NTSTATUS
_samr_LookupDomain(pipes_struct
*p
,
3800 struct samr_LookupDomain
*r
)
3802 NTSTATUS status
= NT_STATUS_OK
;
3803 struct samr_info
*info
;
3804 const char *domain_name
;
3805 DOM_SID
*sid
= NULL
;
3807 if (!find_policy_by_hnd(p
, r
->in
.connect_handle
, (void**)(void *)&info
))
3808 return NT_STATUS_INVALID_HANDLE
;
3810 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3811 Reverted that change so we will work with RAS servers again */
3813 status
= access_check_samr_function(info
->acc_granted
,
3814 SAMR_ACCESS_LOOKUP_DOMAIN
,
3815 "_samr_LookupDomain");
3816 if (!NT_STATUS_IS_OK(status
)) {
3820 domain_name
= r
->in
.domain_name
->string
;
3822 return NT_STATUS_INVALID_PARAMETER
;
3825 sid
= TALLOC_ZERO_P(p
->mem_ctx
, struct dom_sid2
);
3827 return NT_STATUS_NO_MEMORY
;
3830 if (strequal(domain_name
, builtin_domain_name())) {
3831 sid_copy(sid
, &global_sid_Builtin
);
3833 if (!secrets_fetch_domain_sid(domain_name
, sid
)) {
3834 status
= NT_STATUS_NO_SUCH_DOMAIN
;
3838 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
,
3839 sid_string_dbg(sid
)));
3846 /**********************************************************************
3848 **********************************************************************/
3850 NTSTATUS
_samr_EnumDomains(pipes_struct
*p
,
3851 struct samr_EnumDomains
*r
)
3854 struct samr_info
*info
;
3855 uint32_t num_entries
= 2;
3856 struct samr_SamEntry
*entry_array
= NULL
;
3857 struct samr_SamArray
*sam
;
3859 if (!find_policy_by_hnd(p
, r
->in
.connect_handle
, (void**)(void *)&info
))
3860 return NT_STATUS_INVALID_HANDLE
;
3862 status
= access_check_samr_function(info
->acc_granted
,
3863 SAMR_ACCESS_ENUM_DOMAINS
,
3864 "_samr_EnumDomains");
3865 if (!NT_STATUS_IS_OK(status
)) {
3869 sam
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
3871 return NT_STATUS_NO_MEMORY
;
3874 entry_array
= TALLOC_ZERO_ARRAY(p
->mem_ctx
,
3875 struct samr_SamEntry
,
3878 return NT_STATUS_NO_MEMORY
;
3881 entry_array
[0].idx
= 0;
3882 init_lsa_String(&entry_array
[0].name
, get_global_sam_name());
3884 entry_array
[1].idx
= 1;
3885 init_lsa_String(&entry_array
[1].name
, "Builtin");
3887 sam
->count
= num_entries
;
3888 sam
->entries
= entry_array
;
3891 *r
->out
.num_entries
= num_entries
;
3896 /*******************************************************************
3898 ********************************************************************/
3900 NTSTATUS
_samr_OpenAlias(pipes_struct
*p
,
3901 struct samr_OpenAlias
*r
)
3904 uint32 alias_rid
= r
->in
.rid
;
3905 struct samr_info
*info
= NULL
;
3906 SEC_DESC
*psd
= NULL
;
3908 uint32 des_access
= r
->in
.access_mask
;
3913 /* find the domain policy and get the SID / access bits stored in the domain policy */
3915 if ( !get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
, NULL
) )
3916 return NT_STATUS_INVALID_HANDLE
;
3918 status
= access_check_samr_function(acc_granted
,
3919 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
3922 if ( !NT_STATUS_IS_OK(status
) )
3925 /* append the alias' RID to it */
3927 if (!sid_append_rid(&sid
, alias_rid
))
3928 return NT_STATUS_NO_SUCH_ALIAS
;
3930 /*check if access can be granted as requested by client. */
3932 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3934 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &ali_generic_mapping
, NULL
, 0);
3935 se_map_generic(&des_access
,&ali_generic_mapping
);
3937 se_priv_copy( &se_rights
, &se_add_users
);
3940 status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
3941 &se_rights
, GENERIC_RIGHTS_ALIAS_WRITE
, des_access
,
3942 &acc_granted
, "_samr_OpenAlias");
3944 if ( !NT_STATUS_IS_OK(status
) )
3948 /* Check we actually have the requested alias */
3949 enum lsa_SidType type
;
3954 result
= lookup_sid(NULL
, &sid
, NULL
, NULL
, &type
);
3957 if (!result
|| (type
!= SID_NAME_ALIAS
)) {
3958 return NT_STATUS_NO_SUCH_ALIAS
;
3961 /* make sure there is a mapping */
3963 if ( !sid_to_gid( &sid
, &gid
) ) {
3964 return NT_STATUS_NO_SUCH_ALIAS
;
3969 /* associate the alias SID with the new handle. */
3970 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &sid
)) == NULL
)
3971 return NT_STATUS_NO_MEMORY
;
3973 info
->acc_granted
= acc_granted
;
3975 /* get a (unique) handle. open a policy on it. */
3976 if (!create_policy_hnd(p
, r
->out
.alias_handle
, info
))
3977 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3979 return NT_STATUS_OK
;
3982 /*******************************************************************
3984 ********************************************************************/
3986 static NTSTATUS
set_user_info_2(TALLOC_CTX
*mem_ctx
,
3987 struct samr_UserInfo2
*id2
,
3991 DEBUG(5,("set_user_info_2: NULL id2\n"));
3992 return NT_STATUS_ACCESS_DENIED
;
3995 copy_id2_to_sam_passwd(pwd
, id2
);
3997 return pdb_update_sam_account(pwd
);
4000 /*******************************************************************
4002 ********************************************************************/
4004 static NTSTATUS
set_user_info_4(TALLOC_CTX
*mem_ctx
,
4005 struct samr_UserInfo4
*id4
,
4009 DEBUG(5,("set_user_info_2: NULL id4\n"));
4010 return NT_STATUS_ACCESS_DENIED
;
4013 copy_id4_to_sam_passwd(pwd
, id4
);
4015 return pdb_update_sam_account(pwd
);
4018 /*******************************************************************
4020 ********************************************************************/
4022 static NTSTATUS
set_user_info_6(TALLOC_CTX
*mem_ctx
,
4023 struct samr_UserInfo6
*id6
,
4027 DEBUG(5,("set_user_info_6: NULL id6\n"));
4028 return NT_STATUS_ACCESS_DENIED
;
4031 copy_id6_to_sam_passwd(pwd
, id6
);
4033 return pdb_update_sam_account(pwd
);
4036 /*******************************************************************
4038 ********************************************************************/
4040 static NTSTATUS
set_user_info_7(TALLOC_CTX
*mem_ctx
,
4041 struct samr_UserInfo7
*id7
,
4047 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4048 return NT_STATUS_ACCESS_DENIED
;
4051 if (!id7
->account_name
.string
) {
4052 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4053 return NT_STATUS_ACCESS_DENIED
;
4056 /* check to see if the new username already exists. Note: we can't
4057 reliably lock all backends, so there is potentially the
4058 possibility that a user can be created in between this check and
4059 the rename. The rename should fail, but may not get the
4060 exact same failure status code. I think this is small enough
4061 of a window for this type of operation and the results are
4062 simply that the rename fails with a slightly different status
4063 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4065 rc
= can_create(mem_ctx
, id7
->account_name
.string
);
4066 if (!NT_STATUS_IS_OK(rc
)) {
4070 rc
= pdb_rename_sam_account(pwd
, id7
->account_name
.string
);
4075 /*******************************************************************
4077 ********************************************************************/
4079 static NTSTATUS
set_user_info_8(TALLOC_CTX
*mem_ctx
,
4080 struct samr_UserInfo8
*id8
,
4084 DEBUG(5,("set_user_info_8: NULL id8\n"));
4085 return NT_STATUS_ACCESS_DENIED
;
4088 copy_id8_to_sam_passwd(pwd
, id8
);
4090 return pdb_update_sam_account(pwd
);
4093 /*******************************************************************
4095 ********************************************************************/
4097 static NTSTATUS
set_user_info_10(TALLOC_CTX
*mem_ctx
,
4098 struct samr_UserInfo10
*id10
,
4102 DEBUG(5,("set_user_info_8: NULL id10\n"));
4103 return NT_STATUS_ACCESS_DENIED
;
4106 copy_id10_to_sam_passwd(pwd
, id10
);
4108 return pdb_update_sam_account(pwd
);
4111 /*******************************************************************
4113 ********************************************************************/
4115 static NTSTATUS
set_user_info_11(TALLOC_CTX
*mem_ctx
,
4116 struct samr_UserInfo11
*id11
,
4120 DEBUG(5,("set_user_info_11: NULL id11\n"));
4121 return NT_STATUS_ACCESS_DENIED
;
4124 copy_id11_to_sam_passwd(pwd
, id11
);
4126 return pdb_update_sam_account(pwd
);
4129 /*******************************************************************
4131 ********************************************************************/
4133 static NTSTATUS
set_user_info_12(TALLOC_CTX
*mem_ctx
,
4134 struct samr_UserInfo12
*id12
,
4138 DEBUG(5,("set_user_info_12: NULL id12\n"));
4139 return NT_STATUS_ACCESS_DENIED
;
4142 copy_id12_to_sam_passwd(pwd
, id12
);
4144 return pdb_update_sam_account(pwd
);
4147 /*******************************************************************
4149 ********************************************************************/
4151 static NTSTATUS
set_user_info_13(TALLOC_CTX
*mem_ctx
,
4152 struct samr_UserInfo13
*id13
,
4156 DEBUG(5,("set_user_info_13: NULL id13\n"));
4157 return NT_STATUS_ACCESS_DENIED
;
4160 copy_id13_to_sam_passwd(pwd
, id13
);
4162 return pdb_update_sam_account(pwd
);
4165 /*******************************************************************
4167 ********************************************************************/
4169 static NTSTATUS
set_user_info_14(TALLOC_CTX
*mem_ctx
,
4170 struct samr_UserInfo14
*id14
,
4174 DEBUG(5,("set_user_info_14: NULL id14\n"));
4175 return NT_STATUS_ACCESS_DENIED
;
4178 copy_id14_to_sam_passwd(pwd
, id14
);
4180 return pdb_update_sam_account(pwd
);
4183 /*******************************************************************
4185 ********************************************************************/
4187 static NTSTATUS
set_user_info_16(TALLOC_CTX
*mem_ctx
,
4188 struct samr_UserInfo16
*id16
,
4192 DEBUG(5,("set_user_info_16: NULL id16\n"));
4193 return NT_STATUS_ACCESS_DENIED
;
4196 copy_id16_to_sam_passwd(pwd
, id16
);
4198 return pdb_update_sam_account(pwd
);
4201 /*******************************************************************
4203 ********************************************************************/
4205 static NTSTATUS
set_user_info_17(TALLOC_CTX
*mem_ctx
,
4206 struct samr_UserInfo17
*id17
,
4210 DEBUG(5,("set_user_info_17: NULL id17\n"));
4211 return NT_STATUS_ACCESS_DENIED
;
4214 copy_id17_to_sam_passwd(pwd
, id17
);
4216 return pdb_update_sam_account(pwd
);
4219 /*******************************************************************
4221 ********************************************************************/
4223 static NTSTATUS
set_user_info_18(struct samr_UserInfo18
*id18
,
4224 TALLOC_CTX
*mem_ctx
,
4225 DATA_BLOB
*session_key
,
4229 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4230 return NT_STATUS_INVALID_PARAMETER
;
4233 if (id18
->nt_pwd_active
|| id18
->lm_pwd_active
) {
4234 if (!session_key
->length
) {
4235 return NT_STATUS_NO_USER_SESSION_KEY
;
4239 if (id18
->nt_pwd_active
) {
4243 in
= data_blob_const(id18
->nt_pwd
.hash
, 16);
4244 out
= data_blob_talloc_zero(mem_ctx
, 16);
4246 sess_crypt_blob(&out
, &in
, session_key
, false);
4248 if (!pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4249 return NT_STATUS_ACCESS_DENIED
;
4252 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4255 if (id18
->lm_pwd_active
) {
4259 in
= data_blob_const(id18
->lm_pwd
.hash
, 16);
4260 out
= data_blob_talloc_zero(mem_ctx
, 16);
4262 sess_crypt_blob(&out
, &in
, session_key
, false);
4264 if (!pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4265 return NT_STATUS_ACCESS_DENIED
;
4268 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4271 copy_id18_to_sam_passwd(pwd
, id18
);
4273 return pdb_update_sam_account(pwd
);
4276 /*******************************************************************
4278 ********************************************************************/
4280 static NTSTATUS
set_user_info_20(TALLOC_CTX
*mem_ctx
,
4281 struct samr_UserInfo20
*id20
,
4285 DEBUG(5,("set_user_info_20: NULL id20\n"));
4286 return NT_STATUS_ACCESS_DENIED
;
4289 copy_id20_to_sam_passwd(pwd
, id20
);
4291 return pdb_update_sam_account(pwd
);
4294 /*******************************************************************
4296 ********************************************************************/
4298 static NTSTATUS
set_user_info_21(struct samr_UserInfo21
*id21
,
4299 TALLOC_CTX
*mem_ctx
,
4300 DATA_BLOB
*session_key
,
4306 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4307 return NT_STATUS_INVALID_PARAMETER
;
4310 if (id21
->fields_present
== 0) {
4311 return NT_STATUS_INVALID_PARAMETER
;
4314 if (id21
->fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4315 return NT_STATUS_ACCESS_DENIED
;
4318 if (id21
->fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
4319 if (id21
->nt_password_set
) {
4322 if ((id21
->nt_owf_password
.length
!= 16) ||
4323 (id21
->nt_owf_password
.size
!= 16)) {
4324 return NT_STATUS_INVALID_PARAMETER
;
4327 if (!session_key
->length
) {
4328 return NT_STATUS_NO_USER_SESSION_KEY
;
4331 in
= data_blob_const(id21
->nt_owf_password
.array
, 16);
4332 out
= data_blob_talloc_zero(mem_ctx
, 16);
4334 sess_crypt_blob(&out
, &in
, session_key
, false);
4336 pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
);
4337 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4341 if (id21
->fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4342 if (id21
->lm_password_set
) {
4345 if ((id21
->lm_owf_password
.length
!= 16) ||
4346 (id21
->lm_owf_password
.size
!= 16)) {
4347 return NT_STATUS_INVALID_PARAMETER
;
4350 if (!session_key
->length
) {
4351 return NT_STATUS_NO_USER_SESSION_KEY
;
4354 in
= data_blob_const(id21
->lm_owf_password
.array
, 16);
4355 out
= data_blob_talloc_zero(mem_ctx
, 16);
4357 sess_crypt_blob(&out
, &in
, session_key
, false);
4359 pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
);
4360 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4364 /* we need to separately check for an account rename first */
4366 if (id21
->account_name
.string
&&
4367 (!strequal(id21
->account_name
.string
, pdb_get_username(pwd
))))
4370 /* check to see if the new username already exists. Note: we can't
4371 reliably lock all backends, so there is potentially the
4372 possibility that a user can be created in between this check and
4373 the rename. The rename should fail, but may not get the
4374 exact same failure status code. I think this is small enough
4375 of a window for this type of operation and the results are
4376 simply that the rename fails with a slightly different status
4377 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4379 status
= can_create(mem_ctx
, id21
->account_name
.string
);
4380 if (!NT_STATUS_IS_OK(status
)) {
4384 status
= pdb_rename_sam_account(pwd
, id21
->account_name
.string
);
4386 if (!NT_STATUS_IS_OK(status
)) {
4387 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4388 nt_errstr(status
)));
4392 /* set the new username so that later
4393 functions can work on the new account */
4394 pdb_set_username(pwd
, id21
->account_name
.string
, PDB_SET
);
4397 copy_id21_to_sam_passwd("INFO_21", pwd
, id21
);
4400 * The funny part about the previous two calls is
4401 * that pwd still has the password hashes from the
4402 * passdb entry. These have not been updated from
4403 * id21. I don't know if they need to be set. --jerry
4406 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4407 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4408 if ( !NT_STATUS_IS_OK(status
) ) {
4413 /* Don't worry about writing out the user account since the
4414 primary group SID is generated solely from the user's Unix
4417 /* write the change out */
4418 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4422 return NT_STATUS_OK
;
4425 /*******************************************************************
4427 ********************************************************************/
4429 static NTSTATUS
set_user_info_23(TALLOC_CTX
*mem_ctx
,
4430 struct samr_UserInfo23
*id23
,
4433 char *plaintext_buf
= NULL
;
4439 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4440 return NT_STATUS_INVALID_PARAMETER
;
4443 if (id23
->info
.fields_present
== 0) {
4444 return NT_STATUS_INVALID_PARAMETER
;
4447 if (id23
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4448 return NT_STATUS_ACCESS_DENIED
;
4451 if ((id23
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4452 (id23
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4454 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4455 pdb_get_username(pwd
)));
4457 if (!decode_pw_buffer(mem_ctx
,
4458 id23
->password
.data
,
4462 return NT_STATUS_WRONG_PASSWORD
;
4465 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4466 return NT_STATUS_ACCESS_DENIED
;
4470 copy_id23_to_sam_passwd(pwd
, id23
);
4472 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4474 /* if it's a trust account, don't update /etc/passwd */
4475 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4476 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4477 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4478 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4479 } else if (plaintext_buf
) {
4480 /* update the UNIX password */
4481 if (lp_unix_password_sync() ) {
4482 struct passwd
*passwd
;
4483 if (pdb_get_username(pwd
) == NULL
) {
4484 DEBUG(1, ("chgpasswd: User without name???\n"));
4485 return NT_STATUS_ACCESS_DENIED
;
4488 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4489 if (passwd
== NULL
) {
4490 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4493 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
4494 return NT_STATUS_ACCESS_DENIED
;
4496 TALLOC_FREE(passwd
);
4500 if (plaintext_buf
) {
4501 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4504 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) &&
4505 (!NT_STATUS_IS_OK(status
= pdb_set_unix_primary_group(mem_ctx
,
4510 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4514 return NT_STATUS_OK
;
4517 /*******************************************************************
4519 ********************************************************************/
4521 static bool set_user_info_pw(uint8
*pass
, struct samu
*pwd
)
4524 char *plaintext_buf
= NULL
;
4527 DEBUG(5, ("Attempting administrator password change for user %s\n",
4528 pdb_get_username(pwd
)));
4530 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4532 if (!decode_pw_buffer(talloc_tos(),
4540 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4544 /* if it's a trust account, don't update /etc/passwd */
4545 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4546 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4547 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4548 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4550 /* update the UNIX password */
4551 if (lp_unix_password_sync()) {
4552 struct passwd
*passwd
;
4554 if (pdb_get_username(pwd
) == NULL
) {
4555 DEBUG(1, ("chgpasswd: User without name???\n"));
4559 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4560 if (passwd
== NULL
) {
4561 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4564 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
4567 TALLOC_FREE(passwd
);
4571 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4573 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4578 /*******************************************************************
4580 ********************************************************************/
4582 static NTSTATUS
set_user_info_24(TALLOC_CTX
*mem_ctx
,
4583 struct samr_UserInfo24
*id24
,
4589 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4590 return NT_STATUS_INVALID_PARAMETER
;
4593 if (!set_user_info_pw(id24
->password
.data
, pwd
)) {
4594 return NT_STATUS_WRONG_PASSWORD
;
4597 copy_id24_to_sam_passwd(pwd
, id24
);
4599 status
= pdb_update_sam_account(pwd
);
4600 if (!NT_STATUS_IS_OK(status
)) {
4604 return NT_STATUS_OK
;
4607 /*******************************************************************
4609 ********************************************************************/
4611 static NTSTATUS
set_user_info_25(TALLOC_CTX
*mem_ctx
,
4612 struct samr_UserInfo25
*id25
,
4618 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4619 return NT_STATUS_INVALID_PARAMETER
;
4622 if (id25
->info
.fields_present
== 0) {
4623 return NT_STATUS_INVALID_PARAMETER
;
4626 if (id25
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4627 return NT_STATUS_ACCESS_DENIED
;
4630 if ((id25
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4631 (id25
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4633 if (!set_user_info_pw(id25
->password
.data
, pwd
)) {
4634 return NT_STATUS_WRONG_PASSWORD
;
4638 copy_id25_to_sam_passwd(pwd
, id25
);
4640 /* write the change out */
4641 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4646 * We need to "pdb_update_sam_account" before the unix primary group
4647 * is set, because the idealx scripts would also change the
4648 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4649 * the delete explicit / add explicit, which would then fail to find
4650 * the previous primaryGroupSid value.
4653 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4654 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4655 if ( !NT_STATUS_IS_OK(status
) ) {
4660 return NT_STATUS_OK
;
4663 /*******************************************************************
4665 ********************************************************************/
4667 static NTSTATUS
set_user_info_26(TALLOC_CTX
*mem_ctx
,
4668 struct samr_UserInfo26
*id26
,
4674 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4675 return NT_STATUS_INVALID_PARAMETER
;
4678 if (!set_user_info_pw(id26
->password
.data
, pwd
)) {
4679 return NT_STATUS_WRONG_PASSWORD
;
4682 copy_id26_to_sam_passwd(pwd
, id26
);
4684 status
= pdb_update_sam_account(pwd
);
4685 if (!NT_STATUS_IS_OK(status
)) {
4689 return NT_STATUS_OK
;
4693 /*******************************************************************
4695 ********************************************************************/
4697 NTSTATUS
_samr_SetUserInfo(pipes_struct
*p
,
4698 struct samr_SetUserInfo
*r
)
4701 struct samu
*pwd
= NULL
;
4703 union samr_UserInfo
*info
= r
->in
.info
;
4704 uint16_t switch_value
= r
->in
.level
;
4705 uint32_t acc_granted
;
4706 uint32_t acc_required
;
4708 bool has_enough_rights
= False
;
4710 DISP_INFO
*disp_info
= NULL
;
4712 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__
));
4714 /* find the policy handle. open a policy on it. */
4715 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &sid
, &acc_granted
, &disp_info
)) {
4716 return NT_STATUS_INVALID_HANDLE
;
4719 /* This is tricky. A WinXP domain join sets
4720 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4721 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4722 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4723 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4724 we'll use the set from the WinXP join as the basis. */
4726 switch (switch_value
) {
4731 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
;
4734 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
|
4735 SAMR_USER_ACCESS_SET_ATTRIBUTES
|
4736 SAMR_USER_ACCESS_GET_ATTRIBUTES
;
4740 status
= access_check_samr_function(acc_granted
,
4742 "_samr_SetUserInfo");
4743 if (!NT_STATUS_IS_OK(status
)) {
4747 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4748 sid_string_dbg(&sid
), switch_value
));
4751 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4752 return NT_STATUS_INVALID_INFO_CLASS
;
4755 if (!(pwd
= samu_new(NULL
))) {
4756 return NT_STATUS_NO_MEMORY
;
4760 ret
= pdb_getsampwsid(pwd
, &sid
);
4765 return NT_STATUS_NO_SUCH_USER
;
4768 /* deal with machine password changes differently from userinfo changes */
4769 /* check to see if we have the sufficient rights */
4771 acb_info
= pdb_get_acct_ctrl(pwd
);
4772 if (acb_info
& ACB_WSTRUST
)
4773 has_enough_rights
= user_has_privileges(p
->server_info
->ptok
,
4774 &se_machine_account
);
4775 else if (acb_info
& ACB_NORMAL
)
4776 has_enough_rights
= user_has_privileges(p
->server_info
->ptok
,
4778 else if (acb_info
& (ACB_SVRTRUST
|ACB_DOMTRUST
)) {
4779 if (lp_enable_privileges()) {
4780 has_enough_rights
= nt_token_check_domain_rid(p
->server_info
->ptok
,
4781 DOMAIN_GROUP_RID_ADMINS
);
4785 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4786 uidtoname(p
->server_info
->utok
.uid
),
4787 has_enough_rights
? "" : " not"));
4789 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4791 if (has_enough_rights
) {
4795 /* ok! user info levels (lots: see MSDEV help), off we go... */
4797 switch (switch_value
) {
4800 status
= set_user_info_2(p
->mem_ctx
,
4805 status
= set_user_info_4(p
->mem_ctx
,
4810 status
= set_user_info_6(p
->mem_ctx
,
4815 status
= set_user_info_7(p
->mem_ctx
,
4820 status
= set_user_info_8(p
->mem_ctx
,
4825 status
= set_user_info_10(p
->mem_ctx
,
4826 &info
->info10
, pwd
);
4830 status
= set_user_info_11(p
->mem_ctx
,
4831 &info
->info11
, pwd
);
4835 status
= set_user_info_12(p
->mem_ctx
,
4836 &info
->info12
, pwd
);
4840 status
= set_user_info_13(p
->mem_ctx
,
4841 &info
->info13
, pwd
);
4845 status
= set_user_info_14(p
->mem_ctx
,
4846 &info
->info14
, pwd
);
4850 status
= set_user_info_16(p
->mem_ctx
,
4851 &info
->info16
, pwd
);
4855 status
= set_user_info_17(p
->mem_ctx
,
4856 &info
->info17
, pwd
);
4860 /* Used by AS/U JRA. */
4861 status
= set_user_info_18(&info
->info18
,
4863 &p
->server_info
->user_session_key
,
4868 status
= set_user_info_20(p
->mem_ctx
,
4869 &info
->info20
, pwd
);
4873 status
= set_user_info_21(&info
->info21
,
4875 &p
->server_info
->user_session_key
,
4880 if (!p
->server_info
->user_session_key
.length
) {
4881 status
= NT_STATUS_NO_USER_SESSION_KEY
;
4883 SamOEMhashBlob(info
->info23
.password
.data
, 516,
4884 &p
->server_info
->user_session_key
);
4886 dump_data(100, info
->info23
.password
.data
, 516);
4888 status
= set_user_info_23(p
->mem_ctx
,
4889 &info
->info23
, pwd
);
4893 if (!p
->server_info
->user_session_key
.length
) {
4894 status
= NT_STATUS_NO_USER_SESSION_KEY
;
4896 SamOEMhashBlob(info
->info24
.password
.data
,
4898 &p
->server_info
->user_session_key
);
4900 dump_data(100, info
->info24
.password
.data
, 516);
4902 status
= set_user_info_24(p
->mem_ctx
,
4903 &info
->info24
, pwd
);
4907 if (!p
->server_info
->user_session_key
.length
) {
4908 status
= NT_STATUS_NO_USER_SESSION_KEY
;
4910 encode_or_decode_arc4_passwd_buffer(
4911 info
->info25
.password
.data
,
4912 &p
->server_info
->user_session_key
);
4914 dump_data(100, info
->info25
.password
.data
, 532);
4916 status
= set_user_info_25(p
->mem_ctx
,
4917 &info
->info25
, pwd
);
4921 if (!p
->server_info
->user_session_key
.length
) {
4922 status
= NT_STATUS_NO_USER_SESSION_KEY
;
4924 encode_or_decode_arc4_passwd_buffer(
4925 info
->info26
.password
.data
,
4926 &p
->server_info
->user_session_key
);
4928 dump_data(100, info
->info26
.password
.data
, 516);
4930 status
= set_user_info_26(p
->mem_ctx
,
4931 &info
->info26
, pwd
);
4935 status
= NT_STATUS_INVALID_INFO_CLASS
;
4940 if (has_enough_rights
) {
4944 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4946 if (NT_STATUS_IS_OK(status
)) {
4947 force_flush_samr_cache(disp_info
);
4953 /*******************************************************************
4955 ********************************************************************/
4957 NTSTATUS
_samr_SetUserInfo2(pipes_struct
*p
,
4958 struct samr_SetUserInfo2
*r
)
4960 struct samr_SetUserInfo q
;
4962 q
.in
.user_handle
= r
->in
.user_handle
;
4963 q
.in
.level
= r
->in
.level
;
4964 q
.in
.info
= r
->in
.info
;
4966 return _samr_SetUserInfo(p
, &q
);
4969 /*********************************************************************
4970 _samr_GetAliasMembership
4971 *********************************************************************/
4973 NTSTATUS
_samr_GetAliasMembership(pipes_struct
*p
,
4974 struct samr_GetAliasMembership
*r
)
4976 size_t num_alias_rids
;
4978 struct samr_info
*info
= NULL
;
4986 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__
));
4988 /* find the policy handle. open a policy on it. */
4989 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
4990 return NT_STATUS_INVALID_HANDLE
;
4992 ntstatus1
= access_check_samr_function(info
->acc_granted
,
4993 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
4994 "_samr_GetAliasMembership");
4995 ntstatus2
= access_check_samr_function(info
->acc_granted
,
4996 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
4997 "_samr_GetAliasMembership");
4999 if (!NT_STATUS_IS_OK(ntstatus1
) || !NT_STATUS_IS_OK(ntstatus2
)) {
5000 if (!(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus2
)) &&
5001 !(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus1
))) {
5002 return (NT_STATUS_IS_OK(ntstatus1
)) ? ntstatus2
: ntstatus1
;
5006 if (!sid_check_is_domain(&info
->sid
) &&
5007 !sid_check_is_builtin(&info
->sid
))
5008 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
5010 if (r
->in
.sids
->num_sids
) {
5011 members
= TALLOC_ARRAY(p
->mem_ctx
, DOM_SID
, r
->in
.sids
->num_sids
);
5013 if (members
== NULL
)
5014 return NT_STATUS_NO_MEMORY
;
5019 for (i
=0; i
<r
->in
.sids
->num_sids
; i
++)
5020 sid_copy(&members
[i
], r
->in
.sids
->sids
[i
].sid
);
5026 ntstatus1
= pdb_enum_alias_memberships(p
->mem_ctx
, &info
->sid
, members
,
5027 r
->in
.sids
->num_sids
,
5028 &alias_rids
, &num_alias_rids
);
5031 if (!NT_STATUS_IS_OK(ntstatus1
)) {
5035 r
->out
.rids
->count
= num_alias_rids
;
5036 r
->out
.rids
->ids
= alias_rids
;
5038 return NT_STATUS_OK
;
5041 /*********************************************************************
5042 _samr_GetMembersInAlias
5043 *********************************************************************/
5045 NTSTATUS
_samr_GetMembersInAlias(pipes_struct
*p
,
5046 struct samr_GetMembersInAlias
*r
)
5050 size_t num_sids
= 0;
5051 struct lsa_SidPtr
*sids
= NULL
;
5052 DOM_SID
*pdb_sids
= NULL
;
5058 /* find the policy handle. open a policy on it. */
5059 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, NULL
))
5060 return NT_STATUS_INVALID_HANDLE
;
5062 status
= access_check_samr_function(acc_granted
,
5063 SAMR_ALIAS_ACCESS_GET_MEMBERS
,
5064 "_samr_GetMembersInAlias");
5065 if (!NT_STATUS_IS_OK(status
)) {
5069 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid
)));
5072 status
= pdb_enum_aliasmem(&alias_sid
, &pdb_sids
, &num_sids
);
5075 if (!NT_STATUS_IS_OK(status
)) {
5080 sids
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, struct lsa_SidPtr
, num_sids
);
5082 TALLOC_FREE(pdb_sids
);
5083 return NT_STATUS_NO_MEMORY
;
5087 for (i
= 0; i
< num_sids
; i
++) {
5088 sids
[i
].sid
= sid_dup_talloc(p
->mem_ctx
, &pdb_sids
[i
]);
5090 TALLOC_FREE(pdb_sids
);
5091 return NT_STATUS_NO_MEMORY
;
5095 r
->out
.sids
->num_sids
= num_sids
;
5096 r
->out
.sids
->sids
= sids
;
5098 TALLOC_FREE(pdb_sids
);
5100 return NT_STATUS_OK
;
5103 /*********************************************************************
5104 _samr_QueryGroupMember
5105 *********************************************************************/
5107 NTSTATUS
_samr_QueryGroupMember(pipes_struct
*p
,
5108 struct samr_QueryGroupMember
*r
)
5111 size_t i
, num_members
;
5119 struct samr_RidTypeArray
*rids
= NULL
;
5121 rids
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_RidTypeArray
);
5123 return NT_STATUS_NO_MEMORY
;
5126 /* find the policy handle. open a policy on it. */
5127 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, NULL
))
5128 return NT_STATUS_INVALID_HANDLE
;
5130 status
= access_check_samr_function(acc_granted
,
5131 SAMR_GROUP_ACCESS_GET_MEMBERS
,
5132 "_samr_QueryGroupMember");
5133 if (!NT_STATUS_IS_OK(status
)) {
5137 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid
)));
5139 if (!sid_check_is_in_our_domain(&group_sid
)) {
5140 DEBUG(3, ("sid %s is not in our domain\n",
5141 sid_string_dbg(&group_sid
)));
5142 return NT_STATUS_NO_SUCH_GROUP
;
5145 DEBUG(10, ("lookup on Domain SID\n"));
5148 status
= pdb_enum_group_members(p
->mem_ctx
, &group_sid
,
5149 &rid
, &num_members
);
5152 if (!NT_STATUS_IS_OK(status
))
5156 attr
=TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_members
);
5158 return NT_STATUS_NO_MEMORY
;
5164 for (i
=0; i
<num_members
; i
++)
5165 attr
[i
] = SID_NAME_USER
;
5167 rids
->count
= num_members
;
5171 *r
->out
.rids
= rids
;
5173 return NT_STATUS_OK
;
5176 /*********************************************************************
5177 _samr_AddAliasMember
5178 *********************************************************************/
5180 NTSTATUS
_samr_AddAliasMember(pipes_struct
*p
,
5181 struct samr_AddAliasMember
*r
)
5186 bool can_add_accounts
;
5188 DISP_INFO
*disp_info
= NULL
;
5190 /* Find the policy handle. Open a policy on it. */
5191 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, &disp_info
))
5192 return NT_STATUS_INVALID_HANDLE
;
5194 status
= access_check_samr_function(acc_granted
,
5195 SAMR_ALIAS_ACCESS_ADD_MEMBER
,
5196 "_samr_AddAliasMember");
5197 if (!NT_STATUS_IS_OK(status
)) {
5201 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid
)));
5203 se_priv_copy( &se_rights
, &se_add_users
);
5204 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5206 /******** BEGIN SeAddUsers BLOCK *********/
5208 if ( can_add_accounts
)
5211 status
= pdb_add_aliasmem(&alias_sid
, r
->in
.sid
);
5213 if ( can_add_accounts
)
5216 /******** END SeAddUsers BLOCK *********/
5218 if (NT_STATUS_IS_OK(status
)) {
5219 force_flush_samr_cache(disp_info
);
5225 /*********************************************************************
5226 _samr_DeleteAliasMember
5227 *********************************************************************/
5229 NTSTATUS
_samr_DeleteAliasMember(pipes_struct
*p
,
5230 struct samr_DeleteAliasMember
*r
)
5235 bool can_add_accounts
;
5237 DISP_INFO
*disp_info
= NULL
;
5239 /* Find the policy handle. Open a policy on it. */
5240 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, &disp_info
))
5241 return NT_STATUS_INVALID_HANDLE
;
5243 status
= access_check_samr_function(acc_granted
,
5244 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
,
5245 "_samr_DeleteAliasMember");
5246 if (!NT_STATUS_IS_OK(status
)) {
5250 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5251 sid_string_dbg(&alias_sid
)));
5253 se_priv_copy( &se_rights
, &se_add_users
);
5254 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5256 /******** BEGIN SeAddUsers BLOCK *********/
5258 if ( can_add_accounts
)
5261 status
= pdb_del_aliasmem(&alias_sid
, r
->in
.sid
);
5263 if ( can_add_accounts
)
5266 /******** END SeAddUsers BLOCK *********/
5268 if (NT_STATUS_IS_OK(status
)) {
5269 force_flush_samr_cache(disp_info
);
5275 /*********************************************************************
5276 _samr_AddGroupMember
5277 *********************************************************************/
5279 NTSTATUS
_samr_AddGroupMember(pipes_struct
*p
,
5280 struct samr_AddGroupMember
*r
)
5287 bool can_add_accounts
;
5288 DISP_INFO
*disp_info
= NULL
;
5290 /* Find the policy handle. Open a policy on it. */
5291 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5292 return NT_STATUS_INVALID_HANDLE
;
5294 status
= access_check_samr_function(acc_granted
,
5295 SAMR_GROUP_ACCESS_ADD_MEMBER
,
5296 "_samr_AddGroupMember");
5297 if (!NT_STATUS_IS_OK(status
)) {
5301 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid
)));
5303 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid
,
5305 return NT_STATUS_INVALID_HANDLE
;
5308 se_priv_copy( &se_rights
, &se_add_users
);
5309 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5311 /******** BEGIN SeAddUsers BLOCK *********/
5313 if ( can_add_accounts
)
5316 status
= pdb_add_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5318 if ( can_add_accounts
)
5321 /******** END SeAddUsers BLOCK *********/
5323 force_flush_samr_cache(disp_info
);
5328 /*********************************************************************
5329 _samr_DeleteGroupMember
5330 *********************************************************************/
5332 NTSTATUS
_samr_DeleteGroupMember(pipes_struct
*p
,
5333 struct samr_DeleteGroupMember
*r
)
5341 bool can_add_accounts
;
5342 DISP_INFO
*disp_info
= NULL
;
5345 * delete the group member named r->in.rid
5346 * who is a member of the sid associated with the handle
5347 * the rid is a user's rid as the group is a domain group.
5350 /* Find the policy handle. Open a policy on it. */
5351 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5352 return NT_STATUS_INVALID_HANDLE
;
5354 status
= access_check_samr_function(acc_granted
,
5355 SAMR_GROUP_ACCESS_REMOVE_MEMBER
,
5356 "_samr_DeleteGroupMember");
5357 if (!NT_STATUS_IS_OK(status
)) {
5361 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid
,
5363 return NT_STATUS_INVALID_HANDLE
;
5366 se_priv_copy( &se_rights
, &se_add_users
);
5367 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5369 /******** BEGIN SeAddUsers BLOCK *********/
5371 if ( can_add_accounts
)
5374 status
= pdb_del_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5376 if ( can_add_accounts
)
5379 /******** END SeAddUsers BLOCK *********/
5381 force_flush_samr_cache(disp_info
);
5386 /*********************************************************************
5388 *********************************************************************/
5390 NTSTATUS
_samr_DeleteUser(pipes_struct
*p
,
5391 struct samr_DeleteUser
*r
)
5395 struct samu
*sam_pass
=NULL
;
5397 bool can_add_accounts
;
5399 DISP_INFO
*disp_info
= NULL
;
5402 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__
));
5404 /* Find the policy handle. Open a policy on it. */
5405 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &user_sid
, &acc_granted
, &disp_info
))
5406 return NT_STATUS_INVALID_HANDLE
;
5408 status
= access_check_samr_function(acc_granted
,
5409 STD_RIGHT_DELETE_ACCESS
,
5410 "_samr_DeleteUser");
5411 if (!NT_STATUS_IS_OK(status
)) {
5415 if (!sid_check_is_in_our_domain(&user_sid
))
5416 return NT_STATUS_CANNOT_DELETE
;
5418 /* check if the user exists before trying to delete */
5419 if ( !(sam_pass
= samu_new( NULL
)) ) {
5420 return NT_STATUS_NO_MEMORY
;
5424 ret
= pdb_getsampwsid(sam_pass
, &user_sid
);
5428 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5429 sid_string_dbg(&user_sid
)));
5430 TALLOC_FREE(sam_pass
);
5431 return NT_STATUS_NO_SUCH_USER
;
5434 acb_info
= pdb_get_acct_ctrl(sam_pass
);
5436 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
5437 if ( acb_info
& ACB_WSTRUST
) {
5438 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_machine_account
);
5440 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_add_users
);
5443 /******** BEGIN SeAddUsers BLOCK *********/
5445 if ( can_add_accounts
)
5448 status
= pdb_delete_user(p
->mem_ctx
, sam_pass
);
5450 if ( can_add_accounts
)
5453 /******** END SeAddUsers BLOCK *********/
5455 if ( !NT_STATUS_IS_OK(status
) ) {
5456 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5457 "user %s: %s.\n", pdb_get_username(sam_pass
),
5458 nt_errstr(status
)));
5459 TALLOC_FREE(sam_pass
);
5464 TALLOC_FREE(sam_pass
);
5466 if (!close_policy_hnd(p
, r
->in
.user_handle
))
5467 return NT_STATUS_OBJECT_NAME_INVALID
;
5469 ZERO_STRUCTP(r
->out
.user_handle
);
5471 force_flush_samr_cache(disp_info
);
5473 return NT_STATUS_OK
;
5476 /*********************************************************************
5477 _samr_DeleteDomainGroup
5478 *********************************************************************/
5480 NTSTATUS
_samr_DeleteDomainGroup(pipes_struct
*p
,
5481 struct samr_DeleteDomainGroup
*r
)
5488 bool can_add_accounts
;
5489 DISP_INFO
*disp_info
= NULL
;
5491 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__
));
5493 /* Find the policy handle. Open a policy on it. */
5494 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5495 return NT_STATUS_INVALID_HANDLE
;
5497 status
= access_check_samr_function(acc_granted
,
5498 STD_RIGHT_DELETE_ACCESS
,
5499 "_samr_DeleteDomainGroup");
5500 if (!NT_STATUS_IS_OK(status
)) {
5504 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid
)));
5506 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid
,
5508 return NT_STATUS_NO_SUCH_GROUP
;
5511 se_priv_copy( &se_rights
, &se_add_users
);
5512 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5514 /******** BEGIN SeAddUsers BLOCK *********/
5516 if ( can_add_accounts
)
5519 status
= pdb_delete_dom_group(p
->mem_ctx
, group_rid
);
5521 if ( can_add_accounts
)
5524 /******** END SeAddUsers BLOCK *********/
5526 if ( !NT_STATUS_IS_OK(status
) ) {
5527 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5528 "entry for group %s: %s\n",
5529 sid_string_dbg(&group_sid
),
5530 nt_errstr(status
)));
5534 if (!close_policy_hnd(p
, r
->in
.group_handle
))
5535 return NT_STATUS_OBJECT_NAME_INVALID
;
5537 force_flush_samr_cache(disp_info
);
5539 return NT_STATUS_OK
;
5542 /*********************************************************************
5543 _samr_DeleteDomAlias
5544 *********************************************************************/
5546 NTSTATUS
_samr_DeleteDomAlias(pipes_struct
*p
,
5547 struct samr_DeleteDomAlias
*r
)
5552 bool can_add_accounts
;
5554 DISP_INFO
*disp_info
= NULL
;
5556 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__
));
5558 /* Find the policy handle. Open a policy on it. */
5559 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, &disp_info
))
5560 return NT_STATUS_INVALID_HANDLE
;
5562 /* copy the handle to the outgoing reply */
5564 memcpy(r
->out
.alias_handle
, r
->in
.alias_handle
, sizeof(r
->out
.alias_handle
));
5566 status
= access_check_samr_function(acc_granted
,
5567 STD_RIGHT_DELETE_ACCESS
,
5568 "_samr_DeleteDomAlias");
5569 if (!NT_STATUS_IS_OK(status
)) {
5573 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid
)));
5575 /* Don't let Windows delete builtin groups */
5577 if ( sid_check_is_in_builtin( &alias_sid
) ) {
5578 return NT_STATUS_SPECIAL_ACCOUNT
;
5581 if (!sid_check_is_in_our_domain(&alias_sid
))
5582 return NT_STATUS_NO_SUCH_ALIAS
;
5584 DEBUG(10, ("lookup on Local SID\n"));
5586 se_priv_copy( &se_rights
, &se_add_users
);
5587 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5589 /******** BEGIN SeAddUsers BLOCK *********/
5591 if ( can_add_accounts
)
5594 /* Have passdb delete the alias */
5595 status
= pdb_delete_alias(&alias_sid
);
5597 if ( can_add_accounts
)
5600 /******** END SeAddUsers BLOCK *********/
5602 if ( !NT_STATUS_IS_OK(status
))
5605 if (!close_policy_hnd(p
, r
->in
.alias_handle
))
5606 return NT_STATUS_OBJECT_NAME_INVALID
;
5608 force_flush_samr_cache(disp_info
);
5610 return NT_STATUS_OK
;
5613 /*********************************************************************
5614 _samr_CreateDomainGroup
5615 *********************************************************************/
5617 NTSTATUS
_samr_CreateDomainGroup(pipes_struct
*p
,
5618 struct samr_CreateDomainGroup
*r
)
5625 struct samr_info
*info
;
5628 bool can_add_accounts
;
5629 DISP_INFO
*disp_info
= NULL
;
5631 /* Find the policy handle. Open a policy on it. */
5632 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &dom_sid
, &acc_granted
, &disp_info
))
5633 return NT_STATUS_INVALID_HANDLE
;
5635 status
= access_check_samr_function(acc_granted
,
5636 SAMR_DOMAIN_ACCESS_CREATE_GROUP
,
5637 "_samr_CreateDomainGroup");
5638 if (!NT_STATUS_IS_OK(status
)) {
5642 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
5643 return NT_STATUS_ACCESS_DENIED
;
5645 name
= r
->in
.name
->string
;
5647 return NT_STATUS_NO_MEMORY
;
5650 status
= can_create(p
->mem_ctx
, name
);
5651 if (!NT_STATUS_IS_OK(status
)) {
5655 se_priv_copy( &se_rights
, &se_add_users
);
5656 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5658 /******** BEGIN SeAddUsers BLOCK *********/
5660 if ( can_add_accounts
)
5663 /* check that we successfully create the UNIX group */
5665 status
= pdb_create_dom_group(p
->mem_ctx
, name
, r
->out
.rid
);
5667 if ( can_add_accounts
)
5670 /******** END SeAddUsers BLOCK *********/
5672 /* check if we should bail out here */
5674 if ( !NT_STATUS_IS_OK(status
) )
5677 sid_compose(&info_sid
, get_global_sam_sid(), *r
->out
.rid
);
5679 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &info_sid
)) == NULL
)
5680 return NT_STATUS_NO_MEMORY
;
5682 /* they created it; let the user do what he wants with it */
5684 info
->acc_granted
= GENERIC_RIGHTS_GROUP_ALL_ACCESS
;
5686 /* get a (unique) handle. open a policy on it. */
5687 if (!create_policy_hnd(p
, r
->out
.group_handle
, info
))
5688 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5690 force_flush_samr_cache(disp_info
);
5692 return NT_STATUS_OK
;
5695 /*********************************************************************
5696 _samr_CreateDomAlias
5697 *********************************************************************/
5699 NTSTATUS
_samr_CreateDomAlias(pipes_struct
*p
,
5700 struct samr_CreateDomAlias
*r
)
5704 const char *name
= NULL
;
5705 struct samr_info
*info
;
5710 bool can_add_accounts
;
5711 DISP_INFO
*disp_info
= NULL
;
5713 /* Find the policy handle. Open a policy on it. */
5714 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &dom_sid
, &acc_granted
, &disp_info
))
5715 return NT_STATUS_INVALID_HANDLE
;
5717 result
= access_check_samr_function(acc_granted
,
5718 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
,
5719 "_samr_CreateDomAlias");
5720 if (!NT_STATUS_IS_OK(result
)) {
5724 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
5725 return NT_STATUS_ACCESS_DENIED
;
5727 name
= r
->in
.alias_name
->string
;
5729 se_priv_copy( &se_rights
, &se_add_users
);
5730 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5732 result
= can_create(p
->mem_ctx
, name
);
5733 if (!NT_STATUS_IS_OK(result
)) {
5737 /******** BEGIN SeAddUsers BLOCK *********/
5739 if ( can_add_accounts
)
5742 /* Have passdb create the alias */
5743 result
= pdb_create_alias(name
, r
->out
.rid
);
5745 if ( can_add_accounts
)
5748 /******** END SeAddUsers BLOCK *********/
5750 if (!NT_STATUS_IS_OK(result
)) {
5751 DEBUG(10, ("pdb_create_alias failed: %s\n",
5752 nt_errstr(result
)));
5756 sid_copy(&info_sid
, get_global_sam_sid());
5757 sid_append_rid(&info_sid
, *r
->out
.rid
);
5759 if (!sid_to_gid(&info_sid
, &gid
)) {
5760 DEBUG(10, ("Could not find alias just created\n"));
5761 return NT_STATUS_ACCESS_DENIED
;
5764 /* check if the group has been successfully created */
5765 if ( getgrgid(gid
) == NULL
) {
5766 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5768 return NT_STATUS_ACCESS_DENIED
;
5771 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &info_sid
)) == NULL
)
5772 return NT_STATUS_NO_MEMORY
;
5774 /* they created it; let the user do what he wants with it */
5776 info
->acc_granted
= GENERIC_RIGHTS_ALIAS_ALL_ACCESS
;
5778 /* get a (unique) handle. open a policy on it. */
5779 if (!create_policy_hnd(p
, r
->out
.alias_handle
, info
))
5780 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5782 force_flush_samr_cache(disp_info
);
5784 return NT_STATUS_OK
;
5787 /*********************************************************************
5788 _samr_QueryGroupInfo
5789 *********************************************************************/
5791 NTSTATUS
_samr_QueryGroupInfo(pipes_struct
*p
,
5792 struct samr_QueryGroupInfo
*r
)
5797 union samr_GroupInfo
*info
= NULL
;
5800 uint32_t attributes
= SE_GROUP_MANDATORY
|
5801 SE_GROUP_ENABLED_BY_DEFAULT
|
5803 const char *group_name
= NULL
;
5804 const char *group_description
= NULL
;
5806 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, NULL
))
5807 return NT_STATUS_INVALID_HANDLE
;
5809 status
= access_check_samr_function(acc_granted
,
5810 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
5811 "_samr_QueryGroupInfo");
5812 if (!NT_STATUS_IS_OK(status
)) {
5817 ret
= get_domain_group_from_sid(group_sid
, &map
);
5820 return NT_STATUS_INVALID_HANDLE
;
5822 /* FIXME: map contains fstrings */
5823 group_name
= talloc_strdup(r
, map
.nt_name
);
5824 group_description
= talloc_strdup(r
, map
.comment
);
5826 info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_GroupInfo
);
5828 return NT_STATUS_NO_MEMORY
;
5831 switch (r
->in
.level
) {
5837 status
= pdb_enum_group_members(
5838 p
->mem_ctx
, &group_sid
, &members
, &num_members
);
5841 if (!NT_STATUS_IS_OK(status
)) {
5845 info
->all
.name
.string
= group_name
;
5846 info
->all
.attributes
= attributes
;
5847 info
->all
.num_members
= num_members
;
5848 info
->all
.description
.string
= group_description
;
5852 info
->name
.string
= group_name
;
5855 info
->attributes
.attributes
= attributes
;
5858 info
->description
.string
= group_description
;
5868 status = pdb_enum_group_members(
5869 p->mem_ctx, &group_sid, &members, &num_members);
5872 if (!NT_STATUS_IS_OK(status)) {
5876 info
->all2
.name
.string
= group_name
;
5877 info
->all2
.attributes
= attributes
;
5878 info
->all2
.num_members
= 0; /* num_members - in w2k3 this is always 0 */
5879 info
->all2
.description
.string
= group_description
;
5884 return NT_STATUS_INVALID_INFO_CLASS
;
5887 *r
->out
.info
= info
;
5889 return NT_STATUS_OK
;
5892 /*********************************************************************
5894 *********************************************************************/
5896 NTSTATUS
_samr_SetGroupInfo(pipes_struct
*p
,
5897 struct samr_SetGroupInfo
*r
)
5904 bool can_mod_accounts
;
5905 DISP_INFO
*disp_info
= NULL
;
5907 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5908 return NT_STATUS_INVALID_HANDLE
;
5910 status
= access_check_samr_function(acc_granted
,
5911 SAMR_GROUP_ACCESS_SET_INFO
,
5912 "_samr_SetGroupInfo");
5913 if (!NT_STATUS_IS_OK(status
)) {
5918 ret
= get_domain_group_from_sid(group_sid
, &map
);
5921 return NT_STATUS_NO_SUCH_GROUP
;
5923 switch (r
->in
.level
) {
5925 fstrcpy(map
.comment
, r
->in
.info
->all
.description
.string
);
5928 /* group rename is not supported yet */
5929 return NT_STATUS_NOT_SUPPORTED
;
5931 fstrcpy(map
.comment
, r
->in
.info
->description
.string
);
5934 return NT_STATUS_INVALID_INFO_CLASS
;
5937 can_mod_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_add_users
);
5939 /******** BEGIN SeAddUsers BLOCK *********/
5941 if ( can_mod_accounts
)
5944 status
= pdb_update_group_mapping_entry(&map
);
5946 if ( can_mod_accounts
)
5949 /******** End SeAddUsers BLOCK *********/
5951 if (NT_STATUS_IS_OK(status
)) {
5952 force_flush_samr_cache(disp_info
);
5958 /*********************************************************************
5960 *********************************************************************/
5962 NTSTATUS
_samr_SetAliasInfo(pipes_struct
*p
,
5963 struct samr_SetAliasInfo
*r
)
5966 struct acct_info info
;
5968 bool can_mod_accounts
;
5970 DISP_INFO
*disp_info
= NULL
;
5972 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &group_sid
, &acc_granted
, &disp_info
))
5973 return NT_STATUS_INVALID_HANDLE
;
5975 status
= access_check_samr_function(acc_granted
,
5976 SAMR_ALIAS_ACCESS_SET_INFO
,
5977 "_samr_SetAliasInfo");
5978 if (!NT_STATUS_IS_OK(status
)) {
5982 /* get the current group information */
5985 status
= pdb_get_aliasinfo( &group_sid
, &info
);
5988 if ( !NT_STATUS_IS_OK(status
))
5991 switch (r
->in
.level
) {
5996 /* We currently do not support renaming groups in the
5997 the BUILTIN domain. Refer to util_builtin.c to understand
5998 why. The eventually needs to be fixed to be like Windows
5999 where you can rename builtin groups, just not delete them */
6001 if ( sid_check_is_in_builtin( &group_sid
) ) {
6002 return NT_STATUS_SPECIAL_ACCOUNT
;
6005 /* There has to be a valid name (and it has to be different) */
6007 if ( !r
->in
.info
->name
.string
)
6008 return NT_STATUS_INVALID_PARAMETER
;
6010 /* If the name is the same just reply "ok". Yes this
6011 doesn't allow you to change the case of a group name. */
6013 if ( strequal( r
->in
.info
->name
.string
, info
.acct_name
) )
6014 return NT_STATUS_OK
;
6016 fstrcpy( info
.acct_name
, r
->in
.info
->name
.string
);
6018 /* make sure the name doesn't already exist as a user
6021 fstr_sprintf( group_name
, "%s\\%s", global_myname(), info
.acct_name
);
6022 status
= can_create( p
->mem_ctx
, group_name
);
6023 if ( !NT_STATUS_IS_OK( status
) )
6027 case ALIASINFODESCRIPTION
:
6028 if (r
->in
.info
->description
.string
) {
6029 fstrcpy(info
.acct_desc
,
6030 r
->in
.info
->description
.string
);
6032 fstrcpy( info
.acct_desc
, "" );
6036 return NT_STATUS_INVALID_INFO_CLASS
;
6039 can_mod_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_add_users
);
6041 /******** BEGIN SeAddUsers BLOCK *********/
6043 if ( can_mod_accounts
)
6046 status
= pdb_set_aliasinfo( &group_sid
, &info
);
6048 if ( can_mod_accounts
)
6051 /******** End SeAddUsers BLOCK *********/
6053 if (NT_STATUS_IS_OK(status
))
6054 force_flush_samr_cache(disp_info
);
6059 /****************************************************************
6061 ****************************************************************/
6063 NTSTATUS
_samr_GetDomPwInfo(pipes_struct
*p
,
6064 struct samr_GetDomPwInfo
*r
)
6066 uint32_t min_password_length
= 0;
6067 uint32_t password_properties
= 0;
6069 /* Perform access check. Since this rpc does not require a
6070 policy handle it will not be caught by the access checks on
6071 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6073 if (!pipe_access_check(p
)) {
6074 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6075 return NT_STATUS_ACCESS_DENIED
;
6079 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
,
6080 &min_password_length
);
6081 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
6082 &password_properties
);
6085 if (lp_check_password_script() && *lp_check_password_script()) {
6086 password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
6089 r
->out
.info
->min_password_length
= min_password_length
;
6090 r
->out
.info
->password_properties
= password_properties
;
6092 return NT_STATUS_OK
;
6095 /*********************************************************************
6097 *********************************************************************/
6099 NTSTATUS
_samr_OpenGroup(pipes_struct
*p
,
6100 struct samr_OpenGroup
*r
)
6106 struct samr_info
*info
;
6107 SEC_DESC
*psd
= NULL
;
6109 uint32 des_access
= r
->in
.access_mask
;
6116 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
, NULL
))
6117 return NT_STATUS_INVALID_HANDLE
;
6119 status
= access_check_samr_function(acc_granted
,
6120 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
6123 if ( !NT_STATUS_IS_OK(status
) )
6126 /*check if access can be granted as requested by client. */
6127 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
6129 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &grp_generic_mapping
, NULL
, 0);
6130 se_map_generic(&des_access
,&grp_generic_mapping
);
6132 se_priv_copy( &se_rights
, &se_add_users
);
6134 status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
6135 &se_rights
, GENERIC_RIGHTS_GROUP_WRITE
, des_access
,
6136 &acc_granted
, "_samr_OpenGroup");
6138 if ( !NT_STATUS_IS_OK(status
) )
6141 /* this should not be hard-coded like this */
6143 if (!sid_equal(&sid
, get_global_sam_sid()))
6144 return NT_STATUS_ACCESS_DENIED
;
6146 sid_copy(&info_sid
, get_global_sam_sid());
6147 sid_append_rid(&info_sid
, r
->in
.rid
);
6148 sid_to_fstring(sid_string
, &info_sid
);
6150 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &info_sid
)) == NULL
)
6151 return NT_STATUS_NO_MEMORY
;
6153 info
->acc_granted
= acc_granted
;
6155 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string
));
6157 /* check if that group really exists */
6159 ret
= get_domain_group_from_sid(info
->sid
, &map
);
6162 return NT_STATUS_NO_SUCH_GROUP
;
6164 /* get a (unique) handle. open a policy on it. */
6165 if (!create_policy_hnd(p
, r
->out
.group_handle
, info
))
6166 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6168 return NT_STATUS_OK
;
6171 /*********************************************************************
6172 _samr_RemoveMemberFromForeignDomain
6173 *********************************************************************/
6175 NTSTATUS
_samr_RemoveMemberFromForeignDomain(pipes_struct
*p
,
6176 struct samr_RemoveMemberFromForeignDomain
*r
)
6178 DOM_SID delete_sid
, domain_sid
;
6181 DISP_INFO
*disp_info
= NULL
;
6183 sid_copy( &delete_sid
, r
->in
.sid
);
6185 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6186 sid_string_dbg(&delete_sid
)));
6188 /* Find the policy handle. Open a policy on it. */
6190 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &domain_sid
,
6191 &acc_granted
, &disp_info
))
6192 return NT_STATUS_INVALID_HANDLE
;
6194 result
= access_check_samr_function(acc_granted
,
6195 STD_RIGHT_DELETE_ACCESS
,
6196 "_samr_RemoveMemberFromForeignDomain");
6198 if (!NT_STATUS_IS_OK(result
))
6201 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6202 sid_string_dbg(&domain_sid
)));
6204 /* we can only delete a user from a group since we don't have
6205 nested groups anyways. So in the latter case, just say OK */
6207 /* TODO: The above comment nowadays is bogus. Since we have nested
6208 * groups now, and aliases members are never reported out of the unix
6209 * group membership, the "just say OK" makes this call a no-op. For
6210 * us. This needs fixing however. */
6212 /* I've only ever seen this in the wild when deleting a user from
6213 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6214 * is the user about to be deleted. I very much suspect this is the
6215 * only application of this call. To verify this, let people report
6218 if (!sid_check_is_builtin(&domain_sid
)) {
6219 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6220 "global_sam_sid() = %s\n",
6221 sid_string_dbg(&domain_sid
),
6222 sid_string_dbg(get_global_sam_sid())));
6223 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6224 return NT_STATUS_OK
;
6227 force_flush_samr_cache(disp_info
);
6229 result
= NT_STATUS_OK
;
6234 /*******************************************************************
6235 _samr_QueryDomainInfo2
6236 ********************************************************************/
6238 NTSTATUS
_samr_QueryDomainInfo2(pipes_struct
*p
,
6239 struct samr_QueryDomainInfo2
*r
)
6241 struct samr_QueryDomainInfo q
;
6243 q
.in
.domain_handle
= r
->in
.domain_handle
;
6244 q
.in
.level
= r
->in
.level
;
6246 q
.out
.info
= r
->out
.info
;
6248 return _samr_QueryDomainInfo(p
, &q
);
6251 /*******************************************************************
6253 ********************************************************************/
6255 NTSTATUS
_samr_SetDomainInfo(pipes_struct
*p
,
6256 struct samr_SetDomainInfo
*r
)
6258 struct samr_info
*info
= NULL
;
6259 time_t u_expire
, u_min_age
;
6261 time_t u_lock_duration
, u_reset_time
;
6264 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6266 /* find the policy handle. open a policy on it. */
6267 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
6268 return NT_STATUS_INVALID_HANDLE
;
6270 /* We do have different access bits for info
6271 * levels here, but we're really just looking for
6272 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
6273 * this maps to different specific bits. So
6274 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
6277 result
= access_check_samr_function(info
->acc_granted
,
6278 SAMR_DOMAIN_ACCESS_SET_INFO_1
,
6279 "_samr_SetDomainInfo");
6281 if (!NT_STATUS_IS_OK(result
))
6284 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r
->in
.level
));
6286 switch (r
->in
.level
) {
6288 u_expire
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info1
.max_password_age
);
6289 u_min_age
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info1
.min_password_age
);
6290 pdb_set_account_policy(AP_MIN_PASSWORD_LEN
, (uint32
)r
->in
.info
->info1
.min_password_length
);
6291 pdb_set_account_policy(AP_PASSWORD_HISTORY
, (uint32
)r
->in
.info
->info1
.password_history_length
);
6292 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
, (uint32
)r
->in
.info
->info1
.password_properties
);
6293 pdb_set_account_policy(AP_MAX_PASSWORD_AGE
, (int)u_expire
);
6294 pdb_set_account_policy(AP_MIN_PASSWORD_AGE
, (int)u_min_age
);
6299 u_logout
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info3
.force_logoff_time
);
6300 pdb_set_account_policy(AP_TIME_TO_LOGOUT
, (int)u_logout
);
6309 u_lock_duration
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info12
.lockout_duration
);
6310 if (u_lock_duration
!= -1)
6311 u_lock_duration
/= 60;
6313 u_reset_time
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info12
.lockout_window
)/60;
6315 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION
, (int)u_lock_duration
);
6316 pdb_set_account_policy(AP_RESET_COUNT_TIME
, (int)u_reset_time
);
6317 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, (uint32
)r
->in
.info
->info12
.lockout_threshold
);
6320 return NT_STATUS_INVALID_INFO_CLASS
;
6323 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6325 return NT_STATUS_OK
;
6328 /****************************************************************
6329 _samr_GetDisplayEnumerationIndex
6330 ****************************************************************/
6332 NTSTATUS
_samr_GetDisplayEnumerationIndex(pipes_struct
*p
,
6333 struct samr_GetDisplayEnumerationIndex
*r
)
6335 struct samr_info
*info
= NULL
;
6336 uint32_t max_entries
= (uint32_t) -1;
6337 uint32_t enum_context
= 0;
6339 uint32_t num_account
= 0;
6340 struct samr_displayentry
*entries
= NULL
;
6343 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__
));
6345 /* find the policy handle. open a policy on it. */
6346 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
)) {
6347 return NT_STATUS_INVALID_HANDLE
;
6350 status
= access_check_samr_function(info
->acc_granted
,
6351 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
6352 "_samr_GetDisplayEnumerationIndex");
6353 if (!NT_STATUS_IS_OK(status
)) {
6357 if ((r
->in
.level
< 1) || (r
->in
.level
> 3)) {
6358 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6359 "Unknown info level (%u)\n",
6361 return NT_STATUS_INVALID_INFO_CLASS
;
6366 /* The following done as ROOT. Don't return without unbecome_root(). */
6368 switch (r
->in
.level
) {
6370 if (info
->disp_info
->users
== NULL
) {
6371 info
->disp_info
->users
= pdb_search_users(
6372 info
->disp_info
, ACB_NORMAL
);
6373 if (info
->disp_info
->users
== NULL
) {
6375 return NT_STATUS_ACCESS_DENIED
;
6377 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6378 "starting user enumeration at index %u\n",
6379 (unsigned int)enum_context
));
6381 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6382 "using cached user enumeration at index %u\n",
6383 (unsigned int)enum_context
));
6385 num_account
= pdb_search_entries(info
->disp_info
->users
,
6386 enum_context
, max_entries
,
6390 if (info
->disp_info
->machines
== NULL
) {
6391 info
->disp_info
->machines
= pdb_search_users(
6392 info
->disp_info
, ACB_WSTRUST
|ACB_SVRTRUST
);
6393 if (info
->disp_info
->machines
== NULL
) {
6395 return NT_STATUS_ACCESS_DENIED
;
6397 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6398 "starting machine enumeration at index %u\n",
6399 (unsigned int)enum_context
));
6401 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6402 "using cached machine enumeration at index %u\n",
6403 (unsigned int)enum_context
));
6405 num_account
= pdb_search_entries(info
->disp_info
->machines
,
6406 enum_context
, max_entries
,
6410 if (info
->disp_info
->groups
== NULL
) {
6411 info
->disp_info
->groups
= pdb_search_groups(
6413 if (info
->disp_info
->groups
== NULL
) {
6415 return NT_STATUS_ACCESS_DENIED
;
6417 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6418 "starting group enumeration at index %u\n",
6419 (unsigned int)enum_context
));
6421 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6422 "using cached group enumeration at index %u\n",
6423 (unsigned int)enum_context
));
6425 num_account
= pdb_search_entries(info
->disp_info
->groups
,
6426 enum_context
, max_entries
,
6431 smb_panic("info class changed");
6437 /* Ensure we cache this enumeration. */
6438 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
6440 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6441 r
->in
.name
->string
));
6443 for (i
=0; i
<num_account
; i
++) {
6444 if (strequal(entries
[i
].account_name
, r
->in
.name
->string
)) {
6445 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6446 "found %s at idx %d\n",
6447 r
->in
.name
->string
, i
));
6449 return NT_STATUS_OK
;
6453 /* assuming account_name lives at the very end */
6454 *r
->out
.idx
= num_account
;
6456 return NT_STATUS_NO_MORE_ENTRIES
;
6459 /****************************************************************
6460 _samr_GetDisplayEnumerationIndex2
6461 ****************************************************************/
6463 NTSTATUS
_samr_GetDisplayEnumerationIndex2(pipes_struct
*p
,
6464 struct samr_GetDisplayEnumerationIndex2
*r
)
6466 struct samr_GetDisplayEnumerationIndex q
;
6468 q
.in
.domain_handle
= r
->in
.domain_handle
;
6469 q
.in
.level
= r
->in
.level
;
6470 q
.in
.name
= r
->in
.name
;
6472 q
.out
.idx
= r
->out
.idx
;
6474 return _samr_GetDisplayEnumerationIndex(p
, &q
);
6477 /****************************************************************
6478 ****************************************************************/
6480 NTSTATUS
_samr_Shutdown(pipes_struct
*p
,
6481 struct samr_Shutdown
*r
)
6483 p
->rng_fault_state
= true;
6484 return NT_STATUS_NOT_IMPLEMENTED
;
6487 /****************************************************************
6488 ****************************************************************/
6490 NTSTATUS
_samr_SetMemberAttributesOfGroup(pipes_struct
*p
,
6491 struct samr_SetMemberAttributesOfGroup
*r
)
6493 p
->rng_fault_state
= true;
6494 return NT_STATUS_NOT_IMPLEMENTED
;
6497 /****************************************************************
6498 ****************************************************************/
6500 NTSTATUS
_samr_TestPrivateFunctionsDomain(pipes_struct
*p
,
6501 struct samr_TestPrivateFunctionsDomain
*r
)
6503 p
->rng_fault_state
= true;
6504 return NT_STATUS_NOT_IMPLEMENTED
;
6507 /****************************************************************
6508 ****************************************************************/
6510 NTSTATUS
_samr_TestPrivateFunctionsUser(pipes_struct
*p
,
6511 struct samr_TestPrivateFunctionsUser
*r
)
6513 return NT_STATUS_NOT_IMPLEMENTED
;
6516 /****************************************************************
6517 ****************************************************************/
6519 NTSTATUS
_samr_AddMultipleMembersToAlias(pipes_struct
*p
,
6520 struct samr_AddMultipleMembersToAlias
*r
)
6522 p
->rng_fault_state
= true;
6523 return NT_STATUS_NOT_IMPLEMENTED
;
6526 /****************************************************************
6527 ****************************************************************/
6529 NTSTATUS
_samr_RemoveMultipleMembersFromAlias(pipes_struct
*p
,
6530 struct samr_RemoveMultipleMembersFromAlias
*r
)
6532 p
->rng_fault_state
= true;
6533 return NT_STATUS_NOT_IMPLEMENTED
;
6536 /****************************************************************
6537 ****************************************************************/
6539 NTSTATUS
_samr_SetBootKeyInformation(pipes_struct
*p
,
6540 struct samr_SetBootKeyInformation
*r
)
6542 p
->rng_fault_state
= true;
6543 return NT_STATUS_NOT_IMPLEMENTED
;
6546 /****************************************************************
6547 ****************************************************************/
6549 NTSTATUS
_samr_GetBootKeyInformation(pipes_struct
*p
,
6550 struct samr_GetBootKeyInformation
*r
)
6552 p
->rng_fault_state
= true;
6553 return NT_STATUS_NOT_IMPLEMENTED
;
6556 /****************************************************************
6557 ****************************************************************/
6559 NTSTATUS
_samr_RidToSid(pipes_struct
*p
,
6560 struct samr_RidToSid
*r
)
6562 p
->rng_fault_state
= true;
6563 return NT_STATUS_NOT_IMPLEMENTED
;
6566 /****************************************************************
6567 ****************************************************************/
6569 NTSTATUS
_samr_SetDsrmPassword(pipes_struct
*p
,
6570 struct samr_SetDsrmPassword
*r
)
6572 p
->rng_fault_state
= true;
6573 return NT_STATUS_NOT_IMPLEMENTED
;
6576 /****************************************************************
6577 ****************************************************************/
6579 NTSTATUS
_samr_ValidatePassword(pipes_struct
*p
,
6580 struct samr_ValidatePassword
*r
)
6582 p
->rng_fault_state
= true;
6583 return NT_STATUS_NOT_IMPLEMENTED
;