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
;
1753 alias_info
->name
.string
= alias_name
;
1755 case ALIASINFODESCRIPTION
:
1756 alias_info
->description
.string
= alias_description
;
1759 return NT_STATUS_INVALID_INFO_CLASS
;
1762 *r
->out
.info
= alias_info
;
1764 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__
));
1766 return NT_STATUS_OK
;
1769 /*******************************************************************
1771 ********************************************************************/
1773 NTSTATUS
_samr_LookupNames(pipes_struct
*p
,
1774 struct samr_LookupNames
*r
)
1778 enum lsa_SidType
*type
;
1780 int num_rids
= r
->in
.num_names
;
1783 struct samr_Ids rids
, types
;
1784 uint32_t num_mapped
= 0;
1786 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1788 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &pol_sid
, &acc_granted
, NULL
)) {
1789 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1792 status
= access_check_samr_function(acc_granted
,
1793 0, /* Don't know the acc_bits yet */
1794 "_samr_LookupNames");
1795 if (!NT_STATUS_IS_OK(status
)) {
1799 if (num_rids
> MAX_SAM_ENTRIES
) {
1800 num_rids
= MAX_SAM_ENTRIES
;
1801 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids
));
1804 rid
= talloc_array(p
->mem_ctx
, uint32
, num_rids
);
1805 NT_STATUS_HAVE_NO_MEMORY(rid
);
1807 type
= talloc_array(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
1808 NT_STATUS_HAVE_NO_MEMORY(type
);
1810 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1811 sid_string_dbg(&pol_sid
)));
1813 for (i
= 0; i
< num_rids
; i
++) {
1815 status
= NT_STATUS_NONE_MAPPED
;
1816 type
[i
] = SID_NAME_UNKNOWN
;
1818 rid
[i
] = 0xffffffff;
1820 if (sid_check_is_builtin(&pol_sid
)) {
1821 if (lookup_builtin_name(r
->in
.names
[i
].string
,
1824 type
[i
] = SID_NAME_ALIAS
;
1827 lookup_global_sam_name(r
->in
.names
[i
].string
, 0,
1831 if (type
[i
] != SID_NAME_UNKNOWN
) {
1836 if (num_mapped
== num_rids
) {
1837 status
= NT_STATUS_OK
;
1838 } else if (num_mapped
== 0) {
1839 status
= NT_STATUS_NONE_MAPPED
;
1841 status
= STATUS_SOME_UNMAPPED
;
1844 rids
.count
= num_rids
;
1847 types
.count
= num_rids
;
1850 *r
->out
.rids
= rids
;
1851 *r
->out
.types
= types
;
1853 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1858 /****************************************************************
1859 _samr_ChangePasswordUser
1860 ****************************************************************/
1862 NTSTATUS
_samr_ChangePasswordUser(pipes_struct
*p
,
1863 struct samr_ChangePasswordUser
*r
)
1868 struct samr_Password new_lmPwdHash
, new_ntPwdHash
, checkHash
;
1869 struct samr_Password lm_pwd
, nt_pwd
;
1870 uint32_t acc_granted
;
1873 DISP_INFO
*disp_info
= NULL
;
1875 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &sid
, &acc_granted
, &disp_info
)) {
1876 return NT_STATUS_INVALID_HANDLE
;
1879 status
= access_check_samr_function(acc_granted
,
1880 SAMR_USER_ACCESS_SET_PASSWORD
,
1881 "_samr_ChangePasswordUser");
1882 if (!NT_STATUS_IS_OK(status
)) {
1886 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1887 sid_string_dbg(&sid
)));
1889 if (!(pwd
= samu_new(NULL
))) {
1890 return NT_STATUS_NO_MEMORY
;
1894 ret
= pdb_getsampwsid(pwd
, &sid
);
1899 return NT_STATUS_WRONG_PASSWORD
;
1903 const uint8_t *lm_pass
, *nt_pass
;
1905 lm_pass
= pdb_get_lanman_passwd(pwd
);
1906 nt_pass
= pdb_get_nt_passwd(pwd
);
1908 if (!lm_pass
|| !nt_pass
) {
1909 status
= NT_STATUS_WRONG_PASSWORD
;
1913 memcpy(&lm_pwd
.hash
, lm_pass
, sizeof(lm_pwd
.hash
));
1914 memcpy(&nt_pwd
.hash
, nt_pass
, sizeof(nt_pwd
.hash
));
1917 /* basic sanity checking on parameters. Do this before any database ops */
1918 if (!r
->in
.lm_present
|| !r
->in
.nt_present
||
1919 !r
->in
.old_lm_crypted
|| !r
->in
.new_lm_crypted
||
1920 !r
->in
.old_nt_crypted
|| !r
->in
.new_nt_crypted
) {
1921 /* we should really handle a change with lm not
1923 status
= NT_STATUS_INVALID_PARAMETER_MIX
;
1927 /* decrypt and check the new lm hash */
1928 D_P16(lm_pwd
.hash
, r
->in
.new_lm_crypted
->hash
, new_lmPwdHash
.hash
);
1929 D_P16(new_lmPwdHash
.hash
, r
->in
.old_lm_crypted
->hash
, checkHash
.hash
);
1930 if (memcmp(checkHash
.hash
, lm_pwd
.hash
, 16) != 0) {
1931 status
= NT_STATUS_WRONG_PASSWORD
;
1935 /* decrypt and check the new nt hash */
1936 D_P16(nt_pwd
.hash
, r
->in
.new_nt_crypted
->hash
, new_ntPwdHash
.hash
);
1937 D_P16(new_ntPwdHash
.hash
, r
->in
.old_nt_crypted
->hash
, checkHash
.hash
);
1938 if (memcmp(checkHash
.hash
, nt_pwd
.hash
, 16) != 0) {
1939 status
= NT_STATUS_WRONG_PASSWORD
;
1943 /* The NT Cross is not required by Win2k3 R2, but if present
1944 check the nt cross hash */
1945 if (r
->in
.cross1_present
&& r
->in
.nt_cross
) {
1946 D_P16(lm_pwd
.hash
, r
->in
.nt_cross
->hash
, checkHash
.hash
);
1947 if (memcmp(checkHash
.hash
, new_ntPwdHash
.hash
, 16) != 0) {
1948 status
= NT_STATUS_WRONG_PASSWORD
;
1953 /* The LM Cross is not required by Win2k3 R2, but if present
1954 check the lm cross hash */
1955 if (r
->in
.cross2_present
&& r
->in
.lm_cross
) {
1956 D_P16(nt_pwd
.hash
, r
->in
.lm_cross
->hash
, checkHash
.hash
);
1957 if (memcmp(checkHash
.hash
, new_lmPwdHash
.hash
, 16) != 0) {
1958 status
= NT_STATUS_WRONG_PASSWORD
;
1963 if (!pdb_set_nt_passwd(pwd
, new_ntPwdHash
.hash
, PDB_CHANGED
) ||
1964 !pdb_set_lanman_passwd(pwd
, new_lmPwdHash
.hash
, PDB_CHANGED
)) {
1965 status
= NT_STATUS_ACCESS_DENIED
;
1969 status
= pdb_update_sam_account(pwd
);
1976 /*******************************************************************
1977 _samr_ChangePasswordUser2
1978 ********************************************************************/
1980 NTSTATUS
_samr_ChangePasswordUser2(pipes_struct
*p
,
1981 struct samr_ChangePasswordUser2
*r
)
1987 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
1989 fstrcpy(user_name
, r
->in
.account
->string
);
1990 fstrcpy(wks
, r
->in
.server
->string
);
1992 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
1995 * Pass the user through the NT -> unix user mapping
1999 (void)map_username(user_name
);
2002 * UNIX username case mangling not required, pass_oem_change
2003 * is case insensitive.
2006 status
= pass_oem_change(user_name
,
2007 r
->in
.lm_password
->data
,
2008 r
->in
.lm_verifier
->hash
,
2009 r
->in
.nt_password
->data
,
2010 r
->in
.nt_verifier
->hash
,
2013 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
2015 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
2016 return NT_STATUS_WRONG_PASSWORD
;
2022 /****************************************************************
2023 _samr_OemChangePasswordUser2
2024 ****************************************************************/
2026 NTSTATUS
_samr_OemChangePasswordUser2(pipes_struct
*p
,
2027 struct samr_OemChangePasswordUser2
*r
)
2031 const char *wks
= NULL
;
2033 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
2035 fstrcpy(user_name
, r
->in
.account
->string
);
2036 if (r
->in
.server
&& r
->in
.server
->string
) {
2037 wks
= r
->in
.server
->string
;
2040 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
2043 * Pass the user through the NT -> unix user mapping
2047 (void)map_username(user_name
);
2050 * UNIX username case mangling not required, pass_oem_change
2051 * is case insensitive.
2054 if (!r
->in
.hash
|| !r
->in
.password
) {
2055 return NT_STATUS_INVALID_PARAMETER
;
2058 status
= pass_oem_change(user_name
,
2059 r
->in
.password
->data
,
2065 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
2066 return NT_STATUS_WRONG_PASSWORD
;
2069 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
2074 /*******************************************************************
2075 _samr_ChangePasswordUser3
2076 ********************************************************************/
2078 NTSTATUS
_samr_ChangePasswordUser3(pipes_struct
*p
,
2079 struct samr_ChangePasswordUser3
*r
)
2083 const char *wks
= NULL
;
2084 uint32 reject_reason
;
2085 struct samr_DomInfo1
*dominfo
= NULL
;
2086 struct samr_ChangeReject
*reject
= NULL
;
2089 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
2091 fstrcpy(user_name
, r
->in
.account
->string
);
2092 if (r
->in
.server
&& r
->in
.server
->string
) {
2093 wks
= r
->in
.server
->string
;
2096 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name
, wks
));
2099 * Pass the user through the NT -> unix user mapping
2103 (void)map_username(user_name
);
2106 * UNIX username case mangling not required, pass_oem_change
2107 * is case insensitive.
2110 status
= pass_oem_change(user_name
,
2111 r
->in
.lm_password
->data
,
2112 r
->in
.lm_verifier
->hash
,
2113 r
->in
.nt_password
->data
,
2114 r
->in
.nt_verifier
->hash
,
2116 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
2117 return NT_STATUS_WRONG_PASSWORD
;
2120 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) ||
2121 NT_STATUS_EQUAL(status
, NT_STATUS_ACCOUNT_RESTRICTION
)) {
2123 time_t u_expire
, u_min_age
;
2124 uint32 account_policy_temp
;
2126 dominfo
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_DomInfo1
);
2128 return NT_STATUS_NO_MEMORY
;
2131 reject
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_ChangeReject
);
2133 return NT_STATUS_NO_MEMORY
;
2140 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
, &tmp
);
2141 dominfo
->min_password_length
= tmp
;
2143 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &tmp
);
2144 dominfo
->password_history_length
= tmp
;
2146 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
2147 &dominfo
->password_properties
);
2149 pdb_get_account_policy(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
2150 u_expire
= account_policy_temp
;
2152 pdb_get_account_policy(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
2153 u_min_age
= account_policy_temp
;
2159 unix_to_nt_time_abs((NTTIME
*)&dominfo
->max_password_age
, u_expire
);
2160 unix_to_nt_time_abs((NTTIME
*)&dominfo
->min_password_age
, u_min_age
);
2162 if (lp_check_password_script() && *lp_check_password_script()) {
2163 dominfo
->password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
2166 reject
->reason
= reject_reason
;
2168 *r
->out
.dominfo
= dominfo
;
2169 *r
->out
.reject
= reject
;
2172 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
2177 /*******************************************************************
2178 makes a SAMR_R_LOOKUP_RIDS structure.
2179 ********************************************************************/
2181 static bool make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
,
2183 struct lsa_String
**lsa_name_array_p
)
2185 struct lsa_String
*lsa_name_array
= NULL
;
2188 *lsa_name_array_p
= NULL
;
2190 if (num_names
!= 0) {
2191 lsa_name_array
= TALLOC_ZERO_ARRAY(ctx
, struct lsa_String
, num_names
);
2192 if (!lsa_name_array
) {
2197 for (i
= 0; i
< num_names
; i
++) {
2198 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
] && *names
[i
] ? names
[i
] : ""));
2199 init_lsa_String(&lsa_name_array
[i
], names
[i
]);
2202 *lsa_name_array_p
= lsa_name_array
;
2207 /*******************************************************************
2209 ********************************************************************/
2211 NTSTATUS
_samr_LookupRids(pipes_struct
*p
,
2212 struct samr_LookupRids
*r
)
2216 enum lsa_SidType
*attrs
= NULL
;
2217 uint32
*wire_attrs
= NULL
;
2219 int num_rids
= (int)r
->in
.num_rids
;
2222 struct lsa_Strings names_array
;
2223 struct samr_Ids types_array
;
2224 struct lsa_String
*lsa_names
= NULL
;
2226 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2228 /* find the policy handle. open a policy on it. */
2229 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &pol_sid
, &acc_granted
, NULL
))
2230 return NT_STATUS_INVALID_HANDLE
;
2232 status
= access_check_samr_function(acc_granted
,
2233 0, /* Don't know the acc_bits yet */
2234 "_samr_LookupRids");
2235 if (!NT_STATUS_IS_OK(status
)) {
2239 if (num_rids
> 1000) {
2240 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2241 "to samba4 idl this is not possible\n", num_rids
));
2242 return NT_STATUS_UNSUCCESSFUL
;
2246 names
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, const char *, num_rids
);
2247 attrs
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
2248 wire_attrs
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_rids
);
2250 if ((names
== NULL
) || (attrs
== NULL
) || (wire_attrs
==NULL
))
2251 return NT_STATUS_NO_MEMORY
;
2258 become_root(); /* lookup_sid can require root privs */
2259 status
= pdb_lookup_rids(&pol_sid
, num_rids
, r
->in
.rids
,
2263 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
) && (num_rids
== 0)) {
2264 status
= NT_STATUS_OK
;
2267 if (!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, names
,
2269 return NT_STATUS_NO_MEMORY
;
2272 /* Convert from enum lsa_SidType to uint32 for wire format. */
2273 for (i
= 0; i
< num_rids
; i
++) {
2274 wire_attrs
[i
] = (uint32
)attrs
[i
];
2277 names_array
.count
= num_rids
;
2278 names_array
.names
= lsa_names
;
2280 types_array
.count
= num_rids
;
2281 types_array
.ids
= wire_attrs
;
2283 *r
->out
.names
= names_array
;
2284 *r
->out
.types
= types_array
;
2286 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2291 /*******************************************************************
2293 ********************************************************************/
2295 NTSTATUS
_samr_OpenUser(pipes_struct
*p
,
2296 struct samr_OpenUser
*r
)
2298 struct samu
*sampass
=NULL
;
2300 struct samr_info
*info
= NULL
;
2301 SEC_DESC
*psd
= NULL
;
2303 uint32 des_access
= r
->in
.access_mask
;
2309 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2311 if ( !get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
, NULL
) )
2312 return NT_STATUS_INVALID_HANDLE
;
2314 nt_status
= access_check_samr_function(acc_granted
,
2315 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
2318 if ( !NT_STATUS_IS_OK(nt_status
) )
2321 if ( !(sampass
= samu_new( p
->mem_ctx
)) ) {
2322 return NT_STATUS_NO_MEMORY
;
2325 /* append the user's RID to it */
2327 if (!sid_append_rid(&sid
, r
->in
.rid
))
2328 return NT_STATUS_NO_SUCH_USER
;
2330 /* check if access can be granted as requested by client. */
2332 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
2334 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
, &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
2335 se_map_generic(&des_access
, &usr_generic_mapping
);
2337 se_priv_copy( &se_rights
, &se_machine_account
);
2338 se_priv_add( &se_rights
, &se_add_users
);
2340 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
2341 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
2342 &acc_granted
, "_samr_OpenUser");
2344 if ( !NT_STATUS_IS_OK(nt_status
) )
2348 ret
=pdb_getsampwsid(sampass
, &sid
);
2351 /* check that the SID exists in our domain. */
2353 return NT_STATUS_NO_SUCH_USER
;
2356 TALLOC_FREE(sampass
);
2358 /* associate the user's SID and access bits with the new handle. */
2359 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &sid
)) == NULL
)
2360 return NT_STATUS_NO_MEMORY
;
2361 info
->acc_granted
= acc_granted
;
2363 /* get a (unique) handle. open a policy on it. */
2364 if (!create_policy_hnd(p
, r
->out
.user_handle
, info
))
2365 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2367 return NT_STATUS_OK
;
2370 /*************************************************************************
2371 *************************************************************************/
2373 static NTSTATUS
init_samr_parameters_string(TALLOC_CTX
*mem_ctx
,
2375 struct lsa_BinaryString
**_r
)
2377 struct lsa_BinaryString
*r
;
2380 return NT_STATUS_INVALID_PARAMETER
;
2383 r
= TALLOC_ZERO_P(mem_ctx
, struct lsa_BinaryString
);
2385 return NT_STATUS_NO_MEMORY
;
2388 r
->array
= TALLOC_ZERO_ARRAY(mem_ctx
, uint16_t, blob
->length
/2);
2390 return NT_STATUS_NO_MEMORY
;
2392 memcpy(r
->array
, blob
->data
, blob
->length
);
2393 r
->size
= blob
->length
;
2394 r
->length
= blob
->length
;
2397 return NT_STATUS_NO_MEMORY
;
2402 return NT_STATUS_OK
;
2405 /*************************************************************************
2407 *************************************************************************/
2409 static NTSTATUS
get_user_info_1(TALLOC_CTX
*mem_ctx
,
2410 struct samr_UserInfo1
*r
,
2412 DOM_SID
*domain_sid
)
2414 const DOM_SID
*sid_group
;
2415 uint32_t primary_gid
;
2418 sid_group
= pdb_get_group_sid(pw
);
2421 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2422 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2423 "which conflicts with the domain sid %s. Failing operation.\n",
2424 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2425 sid_string_dbg(domain_sid
)));
2426 return NT_STATUS_UNSUCCESSFUL
;
2429 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2430 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2431 r
->primary_gid
= primary_gid
;
2432 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2433 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2435 return NT_STATUS_OK
;
2438 /*************************************************************************
2440 *************************************************************************/
2442 static NTSTATUS
get_user_info_2(TALLOC_CTX
*mem_ctx
,
2443 struct samr_UserInfo2
*r
,
2446 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2447 r
->unknown
.string
= NULL
;
2448 r
->country_code
= 0;
2451 return NT_STATUS_OK
;
2454 /*************************************************************************
2456 *************************************************************************/
2458 static NTSTATUS
get_user_info_3(TALLOC_CTX
*mem_ctx
,
2459 struct samr_UserInfo3
*r
,
2461 DOM_SID
*domain_sid
)
2463 const DOM_SID
*sid_user
, *sid_group
;
2464 uint32_t rid
, primary_gid
;
2466 sid_user
= pdb_get_user_sid(pw
);
2468 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2469 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2470 "the domain sid %s. Failing operation.\n",
2471 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2472 sid_string_dbg(domain_sid
)));
2473 return NT_STATUS_UNSUCCESSFUL
;
2477 sid_group
= pdb_get_group_sid(pw
);
2480 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2481 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2482 "which conflicts with the domain sid %s. Failing operation.\n",
2483 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2484 sid_string_dbg(domain_sid
)));
2485 return NT_STATUS_UNSUCCESSFUL
;
2488 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2489 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2490 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2491 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2492 unix_to_nt_time(&r
->force_password_change
, pdb_get_pass_must_change_time(pw
));
2494 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2495 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2496 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2497 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2498 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2499 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2500 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2502 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2504 r
->primary_gid
= primary_gid
;
2505 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2506 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2507 r
->logon_count
= pdb_get_logon_count(pw
);
2509 return NT_STATUS_OK
;
2512 /*************************************************************************
2514 *************************************************************************/
2516 static NTSTATUS
get_user_info_4(TALLOC_CTX
*mem_ctx
,
2517 struct samr_UserInfo4
*r
,
2520 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2522 return NT_STATUS_OK
;
2525 /*************************************************************************
2527 *************************************************************************/
2529 static NTSTATUS
get_user_info_5(TALLOC_CTX
*mem_ctx
,
2530 struct samr_UserInfo5
*r
,
2532 DOM_SID
*domain_sid
)
2534 const DOM_SID
*sid_user
, *sid_group
;
2535 uint32_t rid
, primary_gid
;
2537 sid_user
= pdb_get_user_sid(pw
);
2539 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2540 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2541 "the domain sid %s. Failing operation.\n",
2542 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2543 sid_string_dbg(domain_sid
)));
2544 return NT_STATUS_UNSUCCESSFUL
;
2548 sid_group
= pdb_get_group_sid(pw
);
2551 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2552 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2553 "which conflicts with the domain sid %s. Failing operation.\n",
2554 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2555 sid_string_dbg(domain_sid
)));
2556 return NT_STATUS_UNSUCCESSFUL
;
2559 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2560 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2561 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2562 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2564 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2565 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2566 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2567 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2568 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2569 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2570 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2571 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2573 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2575 r
->primary_gid
= primary_gid
;
2576 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2577 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2578 r
->logon_count
= pdb_get_logon_count(pw
);
2580 return NT_STATUS_OK
;
2583 /*************************************************************************
2585 *************************************************************************/
2587 static NTSTATUS
get_user_info_6(TALLOC_CTX
*mem_ctx
,
2588 struct samr_UserInfo6
*r
,
2591 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2592 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2594 return NT_STATUS_OK
;
2597 /*************************************************************************
2598 get_user_info_7. Safe. Only gives out account_name.
2599 *************************************************************************/
2601 static NTSTATUS
get_user_info_7(TALLOC_CTX
*mem_ctx
,
2602 struct samr_UserInfo7
*r
,
2603 struct samu
*smbpass
)
2605 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(smbpass
));
2606 if (!r
->account_name
.string
) {
2607 return NT_STATUS_NO_MEMORY
;
2610 return NT_STATUS_OK
;
2613 /*************************************************************************
2615 *************************************************************************/
2617 static NTSTATUS
get_user_info_8(TALLOC_CTX
*mem_ctx
,
2618 struct samr_UserInfo8
*r
,
2621 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2623 return NT_STATUS_OK
;
2626 /*************************************************************************
2627 get_user_info_9. Only gives out primary group SID.
2628 *************************************************************************/
2630 static NTSTATUS
get_user_info_9(TALLOC_CTX
*mem_ctx
,
2631 struct samr_UserInfo9
*r
,
2632 struct samu
*smbpass
)
2634 r
->primary_gid
= pdb_get_group_rid(smbpass
);
2636 return NT_STATUS_OK
;
2639 /*************************************************************************
2641 *************************************************************************/
2643 static NTSTATUS
get_user_info_10(TALLOC_CTX
*mem_ctx
,
2644 struct samr_UserInfo10
*r
,
2647 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2648 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2650 return NT_STATUS_OK
;
2653 /*************************************************************************
2655 *************************************************************************/
2657 static NTSTATUS
get_user_info_11(TALLOC_CTX
*mem_ctx
,
2658 struct samr_UserInfo11
*r
,
2661 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2663 return NT_STATUS_OK
;
2666 /*************************************************************************
2668 *************************************************************************/
2670 static NTSTATUS
get_user_info_12(TALLOC_CTX
*mem_ctx
,
2671 struct samr_UserInfo12
*r
,
2674 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2676 return NT_STATUS_OK
;
2679 /*************************************************************************
2681 *************************************************************************/
2683 static NTSTATUS
get_user_info_13(TALLOC_CTX
*mem_ctx
,
2684 struct samr_UserInfo13
*r
,
2687 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2689 return NT_STATUS_OK
;
2692 /*************************************************************************
2694 *************************************************************************/
2696 static NTSTATUS
get_user_info_14(TALLOC_CTX
*mem_ctx
,
2697 struct samr_UserInfo14
*r
,
2700 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2702 return NT_STATUS_OK
;
2705 /*************************************************************************
2706 get_user_info_16. Safe. Only gives out acb bits.
2707 *************************************************************************/
2709 static NTSTATUS
get_user_info_16(TALLOC_CTX
*mem_ctx
,
2710 struct samr_UserInfo16
*r
,
2711 struct samu
*smbpass
)
2713 r
->acct_flags
= pdb_get_acct_ctrl(smbpass
);
2715 return NT_STATUS_OK
;
2718 /*************************************************************************
2720 *************************************************************************/
2722 static NTSTATUS
get_user_info_17(TALLOC_CTX
*mem_ctx
,
2723 struct samr_UserInfo17
*r
,
2726 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2728 return NT_STATUS_OK
;
2731 /*************************************************************************
2732 get_user_info_18. OK - this is the killer as it gives out password info.
2733 Ensure that this is only allowed on an encrypted connection with a root
2735 *************************************************************************/
2737 static NTSTATUS
get_user_info_18(pipes_struct
*p
,
2738 TALLOC_CTX
*mem_ctx
,
2739 struct samr_UserInfo18
*r
,
2742 struct samu
*smbpass
=NULL
;
2747 if (p
->auth
.auth_type
!= PIPE_AUTH_TYPE_NTLMSSP
|| p
->auth
.auth_type
!= PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
) {
2748 return NT_STATUS_ACCESS_DENIED
;
2751 if (p
->auth
.auth_level
!= PIPE_AUTH_LEVEL_PRIVACY
) {
2752 return NT_STATUS_ACCESS_DENIED
;
2756 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2759 if ( !(smbpass
= samu_new( mem_ctx
)) ) {
2760 return NT_STATUS_NO_MEMORY
;
2763 ret
= pdb_getsampwsid(smbpass
, user_sid
);
2766 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid
)));
2767 TALLOC_FREE(smbpass
);
2768 return (geteuid() == (uid_t
)0) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
2771 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
2773 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
2774 TALLOC_FREE(smbpass
);
2775 return NT_STATUS_ACCOUNT_DISABLED
;
2778 r
->lm_pwd_active
= true;
2779 r
->nt_pwd_active
= true;
2780 memcpy(r
->lm_pwd
.hash
, pdb_get_lanman_passwd(smbpass
), 16);
2781 memcpy(r
->nt_pwd
.hash
, pdb_get_nt_passwd(smbpass
), 16);
2782 r
->password_expired
= 0; /* FIXME */
2784 TALLOC_FREE(smbpass
);
2786 return NT_STATUS_OK
;
2789 /*************************************************************************
2791 *************************************************************************/
2793 static NTSTATUS
get_user_info_20(TALLOC_CTX
*mem_ctx
,
2794 struct samr_UserInfo20
*r
,
2795 struct samu
*sampass
)
2797 const char *munged_dial
= NULL
;
2800 struct lsa_BinaryString
*parameters
= NULL
;
2804 munged_dial
= pdb_get_munged_dial(sampass
);
2806 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass
),
2807 munged_dial
, (int)strlen(munged_dial
)));
2810 blob
= base64_decode_data_blob(munged_dial
);
2812 blob
= data_blob_string_const_null("");
2815 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2816 data_blob_free(&blob
);
2817 if (!NT_STATUS_IS_OK(status
)) {
2821 r
->parameters
= *parameters
;
2823 return NT_STATUS_OK
;
2827 /*************************************************************************
2829 *************************************************************************/
2831 static NTSTATUS
get_user_info_21(TALLOC_CTX
*mem_ctx
,
2832 struct samr_UserInfo21
*r
,
2834 DOM_SID
*domain_sid
)
2837 const DOM_SID
*sid_user
, *sid_group
;
2838 uint32_t rid
, primary_gid
;
2839 NTTIME force_password_change
;
2840 time_t must_change_time
;
2841 struct lsa_BinaryString
*parameters
= NULL
;
2842 const char *munged_dial
= NULL
;
2847 sid_user
= pdb_get_user_sid(pw
);
2849 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2850 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2851 "the domain sid %s. Failing operation.\n",
2852 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2853 sid_string_dbg(domain_sid
)));
2854 return NT_STATUS_UNSUCCESSFUL
;
2858 sid_group
= pdb_get_group_sid(pw
);
2861 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2862 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2863 "which conflicts with the domain sid %s. Failing operation.\n",
2864 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2865 sid_string_dbg(domain_sid
)));
2866 return NT_STATUS_UNSUCCESSFUL
;
2869 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2870 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2871 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2872 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2873 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2875 must_change_time
= pdb_get_pass_must_change_time(pw
);
2876 if (must_change_time
== get_time_t_max()) {
2877 unix_to_nt_time_abs(&force_password_change
, must_change_time
);
2879 unix_to_nt_time(&force_password_change
, must_change_time
);
2882 munged_dial
= pdb_get_munged_dial(pw
);
2884 blob
= base64_decode_data_blob(munged_dial
);
2886 blob
= data_blob_string_const_null("");
2889 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2890 data_blob_free(&blob
);
2891 if (!NT_STATUS_IS_OK(status
)) {
2895 r
->force_password_change
= force_password_change
;
2897 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2898 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2899 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2900 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2901 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2902 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2903 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2904 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2905 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2907 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2908 r
->parameters
= *parameters
;
2910 r
->primary_gid
= primary_gid
;
2911 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2912 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2913 r
->logon_count
= pdb_get_logon_count(pw
);
2914 r
->fields_present
= pdb_build_fields_present(pw
);
2915 r
->password_expired
= (pdb_get_pass_must_change_time(pw
) == 0) ?
2916 PASS_MUST_CHANGE_AT_NEXT_LOGON
: 0;
2917 r
->country_code
= 0;
2919 r
->lm_password_set
= 0;
2920 r
->nt_password_set
= 0;
2925 Look at a user on a real NT4 PDC with usrmgr, press
2926 'ok'. Then you will see that fields_present is set to
2927 0x08f827fa. Look at the user immediately after that again,
2928 and you will see that 0x00fffff is returned. This solves
2929 the problem that you get access denied after having looked
2937 return NT_STATUS_OK
;
2940 /*******************************************************************
2942 ********************************************************************/
2944 NTSTATUS
_samr_QueryUserInfo(pipes_struct
*p
,
2945 struct samr_QueryUserInfo
*r
)
2948 union samr_UserInfo
*user_info
= NULL
;
2949 struct samr_info
*info
= NULL
;
2953 struct samu
*pwd
= NULL
;
2955 /* search for the handle */
2956 if (!find_policy_by_hnd(p
, r
->in
.user_handle
, (void **)(void *)&info
))
2957 return NT_STATUS_INVALID_HANDLE
;
2959 status
= access_check_samr_function(info
->acc_granted
,
2960 SAMR_USER_ACCESS_GET_ATTRIBUTES
,
2961 "_samr_QueryUserInfo");
2962 if (!NT_STATUS_IS_OK(status
)) {
2966 domain_sid
= info
->sid
;
2968 sid_split_rid(&domain_sid
, &rid
);
2970 if (!sid_check_is_in_our_domain(&info
->sid
))
2971 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
2973 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2974 sid_string_dbg(&info
->sid
)));
2976 user_info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_UserInfo
);
2978 return NT_STATUS_NO_MEMORY
;
2981 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r
->in
.level
));
2983 if (!(pwd
= samu_new(p
->mem_ctx
))) {
2984 return NT_STATUS_NO_MEMORY
;
2988 ret
= pdb_getsampwsid(pwd
, &info
->sid
);
2992 DEBUG(4,("User %s not found\n", sid_string_dbg(&info
->sid
)));
2994 return NT_STATUS_NO_SUCH_USER
;
2997 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd
)));
2999 samr_clear_sam_passwd(pwd
);
3001 switch (r
->in
.level
) {
3003 status
= get_user_info_1(p
->mem_ctx
, &user_info
->info1
, pwd
, &domain_sid
);
3006 status
= get_user_info_2(p
->mem_ctx
, &user_info
->info2
, pwd
);
3009 status
= get_user_info_3(p
->mem_ctx
, &user_info
->info3
, pwd
, &domain_sid
);
3012 status
= get_user_info_4(p
->mem_ctx
, &user_info
->info4
, pwd
);
3015 status
= get_user_info_5(p
->mem_ctx
, &user_info
->info5
, pwd
, &domain_sid
);
3018 status
= get_user_info_6(p
->mem_ctx
, &user_info
->info6
, pwd
);
3021 status
= get_user_info_7(p
->mem_ctx
, &user_info
->info7
, pwd
);
3024 status
= get_user_info_8(p
->mem_ctx
, &user_info
->info8
, pwd
);
3027 status
= get_user_info_9(p
->mem_ctx
, &user_info
->info9
, pwd
);
3030 status
= get_user_info_10(p
->mem_ctx
, &user_info
->info10
, pwd
);
3033 status
= get_user_info_11(p
->mem_ctx
, &user_info
->info11
, pwd
);
3036 status
= get_user_info_12(p
->mem_ctx
, &user_info
->info12
, pwd
);
3039 status
= get_user_info_13(p
->mem_ctx
, &user_info
->info13
, pwd
);
3042 status
= get_user_info_14(p
->mem_ctx
, &user_info
->info14
, pwd
);
3045 status
= get_user_info_16(p
->mem_ctx
, &user_info
->info16
, pwd
);
3048 status
= get_user_info_17(p
->mem_ctx
, &user_info
->info17
, pwd
);
3051 /* level 18 is special */
3052 status
= get_user_info_18(p
, p
->mem_ctx
, &user_info
->info18
, &info
->sid
);
3055 status
= get_user_info_20(p
->mem_ctx
, &user_info
->info20
, pwd
);
3058 status
= get_user_info_21(p
->mem_ctx
, &user_info
->info21
, pwd
, &domain_sid
);
3061 status
= NT_STATUS_INVALID_INFO_CLASS
;
3067 *r
->out
.info
= user_info
;
3069 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__
));
3074 /****************************************************************
3075 ****************************************************************/
3077 NTSTATUS
_samr_QueryUserInfo2(pipes_struct
*p
,
3078 struct samr_QueryUserInfo2
*r
)
3080 struct samr_QueryUserInfo u
;
3082 u
.in
.user_handle
= r
->in
.user_handle
;
3083 u
.in
.level
= r
->in
.level
;
3084 u
.out
.info
= r
->out
.info
;
3086 return _samr_QueryUserInfo(p
, &u
);
3089 /*******************************************************************
3090 _samr_GetGroupsForUser
3091 ********************************************************************/
3093 NTSTATUS
_samr_GetGroupsForUser(pipes_struct
*p
,
3094 struct samr_GetGroupsForUser
*r
)
3096 struct samu
*sam_pass
=NULL
;
3099 struct samr_RidWithAttribute dom_gid
;
3100 struct samr_RidWithAttribute
*gids
= NULL
;
3101 uint32 primary_group_rid
;
3102 size_t num_groups
= 0;
3108 bool success
= False
;
3110 struct samr_RidWithAttributeArray
*rids
= NULL
;
3113 * from the SID in the request:
3114 * we should send back the list of DOMAIN GROUPS
3115 * the user is a member of
3117 * and only the DOMAIN GROUPS
3118 * no ALIASES !!! neither aliases of the domain
3119 * nor aliases of the builtin SID
3124 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3126 rids
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_RidWithAttributeArray
);
3128 return NT_STATUS_NO_MEMORY
;
3131 /* find the policy handle. open a policy on it. */
3132 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &sid
, &acc_granted
, NULL
))
3133 return NT_STATUS_INVALID_HANDLE
;
3135 result
= access_check_samr_function(acc_granted
,
3136 SAMR_USER_ACCESS_GET_GROUPS
,
3137 "_samr_GetGroupsForUser");
3138 if (!NT_STATUS_IS_OK(result
)) {
3142 if (!sid_check_is_in_our_domain(&sid
))
3143 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3145 if ( !(sam_pass
= samu_new( p
->mem_ctx
)) ) {
3146 return NT_STATUS_NO_MEMORY
;
3150 ret
= pdb_getsampwsid(sam_pass
, &sid
);
3154 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3155 sid_string_dbg(&sid
)));
3156 return NT_STATUS_NO_SUCH_USER
;
3161 /* make both calls inside the root block */
3163 result
= pdb_enum_group_memberships(p
->mem_ctx
, sam_pass
,
3164 &sids
, &unix_gids
, &num_groups
);
3165 if ( NT_STATUS_IS_OK(result
) ) {
3166 success
= sid_peek_check_rid(get_global_sam_sid(),
3167 pdb_get_group_sid(sam_pass
),
3168 &primary_group_rid
);
3172 if (!NT_STATUS_IS_OK(result
)) {
3173 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3174 sid_string_dbg(&sid
)));
3179 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3180 sid_string_dbg(pdb_get_group_sid(sam_pass
)),
3181 pdb_get_username(sam_pass
)));
3182 TALLOC_FREE(sam_pass
);
3183 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
3189 dom_gid
.attributes
= (SE_GROUP_MANDATORY
|SE_GROUP_ENABLED_BY_DEFAULT
|
3191 dom_gid
.rid
= primary_group_rid
;
3192 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3194 for (i
=0; i
<num_groups
; i
++) {
3196 if (!sid_peek_check_rid(get_global_sam_sid(),
3197 &(sids
[i
]), &dom_gid
.rid
)) {
3198 DEBUG(10, ("Found sid %s not in our domain\n",
3199 sid_string_dbg(&sids
[i
])));
3203 if (dom_gid
.rid
== primary_group_rid
) {
3204 /* We added the primary group directly from the
3205 * sam_account. The other SIDs are unique from
3206 * enum_group_memberships */
3210 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3213 rids
->count
= num_gids
;
3216 *r
->out
.rids
= rids
;
3218 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3223 /*******************************************************************
3224 _samr_QueryDomainInfo
3225 ********************************************************************/
3227 NTSTATUS
_samr_QueryDomainInfo(pipes_struct
*p
,
3228 struct samr_QueryDomainInfo
*r
)
3230 NTSTATUS status
= NT_STATUS_OK
;
3231 struct samr_info
*info
= NULL
;
3232 union samr_DomainInfo
*dom_info
;
3233 time_t u_expire
, u_min_age
;
3235 time_t u_lock_duration
, u_reset_time
;
3238 uint32 account_policy_temp
;
3243 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3245 dom_info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_DomainInfo
);
3247 return NT_STATUS_NO_MEMORY
;
3250 /* find the policy handle. open a policy on it. */
3251 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
)) {
3252 return NT_STATUS_INVALID_HANDLE
;
3255 status
= access_check_samr_function(info
->acc_granted
,
3256 SAMR_ACCESS_LOOKUP_DOMAIN
,
3257 "_samr_QueryDomainInfo" );
3259 if ( !NT_STATUS_IS_OK(status
) )
3262 switch (r
->in
.level
) {
3269 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
,
3270 &account_policy_temp
);
3271 dom_info
->info1
.min_password_length
= account_policy_temp
;
3273 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &account_policy_temp
);
3274 dom_info
->info1
.password_history_length
= account_policy_temp
;
3276 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
3277 &dom_info
->info1
.password_properties
);
3279 pdb_get_account_policy(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
3280 u_expire
= account_policy_temp
;
3282 pdb_get_account_policy(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
3283 u_min_age
= account_policy_temp
;
3289 unix_to_nt_time_abs((NTTIME
*)&dom_info
->info1
.max_password_age
, u_expire
);
3290 unix_to_nt_time_abs((NTTIME
*)&dom_info
->info1
.min_password_age
, u_min_age
);
3292 if (lp_check_password_script() && *lp_check_password_script()) {
3293 dom_info
->info1
.password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
3303 dom_info
->general
.num_users
= count_sam_users(info
->disp_info
, ACB_NORMAL
);
3304 dom_info
->general
.num_groups
= count_sam_groups(info
->disp_info
);
3305 dom_info
->general
.num_aliases
= count_sam_aliases(info
->disp_info
);
3307 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &u_logout
);
3309 unix_to_nt_time_abs(&dom_info
->general
.force_logoff_time
, u_logout
);
3311 if (!pdb_get_seq_num(&seq_num
))
3312 seq_num
= time(NULL
);
3318 server_role
= ROLE_DOMAIN_PDC
;
3319 if (lp_server_role() == ROLE_DOMAIN_BDC
)
3320 server_role
= ROLE_DOMAIN_BDC
;
3322 dom_info
->general
.oem_information
.string
= lp_serverstring();
3323 dom_info
->general
.domain_name
.string
= lp_workgroup();
3324 dom_info
->general
.primary
.string
= global_myname();
3325 dom_info
->general
.sequence_num
= seq_num
;
3326 dom_info
->general
.domain_server_state
= DOMAIN_SERVER_ENABLED
;
3327 dom_info
->general
.role
= server_role
;
3328 dom_info
->general
.unknown3
= 1;
3339 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &ul
);
3340 u_logout
= (time_t)ul
;
3347 unix_to_nt_time_abs(&dom_info
->info3
.force_logoff_time
, u_logout
);
3351 dom_info
->oem
.oem_information
.string
= lp_serverstring();
3354 dom_info
->info5
.domain_name
.string
= get_global_sam_name();
3357 /* NT returns its own name when a PDC. win2k and later
3358 * only the name of the PDC if itself is a BDC (samba4
3360 dom_info
->info6
.primary
.string
= global_myname();
3363 server_role
= ROLE_DOMAIN_PDC
;
3364 if (lp_server_role() == ROLE_DOMAIN_BDC
)
3365 server_role
= ROLE_DOMAIN_BDC
;
3367 dom_info
->info7
.role
= server_role
;
3375 if (!pdb_get_seq_num(&seq_num
)) {
3376 seq_num
= time(NULL
);
3383 dom_info
->info8
.sequence_num
= seq_num
;
3384 dom_info
->info8
.domain_create_time
= 0;
3389 dom_info
->info9
.domain_server_state
= DOMAIN_SERVER_ENABLED
;
3398 dom_info
->general2
.general
.num_users
= count_sam_users(
3399 info
->disp_info
, ACB_NORMAL
);
3400 dom_info
->general2
.general
.num_groups
= count_sam_groups(
3402 dom_info
->general2
.general
.num_aliases
= count_sam_aliases(
3405 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &u_logout
);
3407 unix_to_nt_time_abs(&dom_info
->general2
.general
.force_logoff_time
, u_logout
);
3409 if (!pdb_get_seq_num(&seq_num
))
3410 seq_num
= time(NULL
);
3412 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
3413 u_lock_duration
= account_policy_temp
;
3414 if (u_lock_duration
!= -1) {
3415 u_lock_duration
*= 60;
3418 pdb_get_account_policy(AP_RESET_COUNT_TIME
, &account_policy_temp
);
3419 u_reset_time
= account_policy_temp
* 60;
3421 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
,
3422 &account_policy_temp
);
3423 dom_info
->general2
.lockout_threshold
= account_policy_temp
;
3429 server_role
= ROLE_DOMAIN_PDC
;
3430 if (lp_server_role() == ROLE_DOMAIN_BDC
)
3431 server_role
= ROLE_DOMAIN_BDC
;
3433 dom_info
->general2
.general
.oem_information
.string
= lp_serverstring();
3434 dom_info
->general2
.general
.domain_name
.string
= lp_workgroup();
3435 dom_info
->general2
.general
.primary
.string
= global_myname();
3436 dom_info
->general2
.general
.sequence_num
= seq_num
;
3437 dom_info
->general2
.general
.domain_server_state
= DOMAIN_SERVER_ENABLED
;
3438 dom_info
->general2
.general
.role
= server_role
;
3439 dom_info
->general2
.general
.unknown3
= 1;
3441 unix_to_nt_time_abs(&dom_info
->general2
.lockout_duration
,
3443 unix_to_nt_time_abs(&dom_info
->general2
.lockout_window
,
3453 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
3454 u_lock_duration
= account_policy_temp
;
3455 if (u_lock_duration
!= -1) {
3456 u_lock_duration
*= 60;
3459 pdb_get_account_policy(AP_RESET_COUNT_TIME
, &account_policy_temp
);
3460 u_reset_time
= account_policy_temp
* 60;
3462 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
,
3463 &account_policy_temp
);
3464 dom_info
->info12
.lockout_threshold
= account_policy_temp
;
3470 unix_to_nt_time_abs(&dom_info
->info12
.lockout_duration
,
3472 unix_to_nt_time_abs(&dom_info
->info12
.lockout_window
,
3482 if (!pdb_get_seq_num(&seq_num
)) {
3483 seq_num
= time(NULL
);
3490 dom_info
->info13
.sequence_num
= seq_num
;
3491 dom_info
->info13
.domain_create_time
= 0;
3492 dom_info
->info13
.modified_count_at_last_promotion
= 0;
3496 return NT_STATUS_INVALID_INFO_CLASS
;
3499 *r
->out
.info
= dom_info
;
3501 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3506 /* W2k3 seems to use the same check for all 3 objects that can be created via
3507 * SAMR, if you try to create for example "Dialup" as an alias it says
3508 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3511 static NTSTATUS
can_create(TALLOC_CTX
*mem_ctx
, const char *new_name
)
3513 enum lsa_SidType type
;
3516 DEBUG(10, ("Checking whether [%s] can be created\n", new_name
));
3519 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3520 * whether the name already exists */
3521 result
= lookup_name(mem_ctx
, new_name
, LOOKUP_NAME_LOCAL
,
3522 NULL
, NULL
, NULL
, &type
);
3526 DEBUG(10, ("%s does not exist, can create it\n", new_name
));
3527 return NT_STATUS_OK
;
3530 DEBUG(5, ("trying to create %s, exists as %s\n",
3531 new_name
, sid_type_lookup(type
)));
3533 if (type
== SID_NAME_DOM_GRP
) {
3534 return NT_STATUS_GROUP_EXISTS
;
3536 if (type
== SID_NAME_ALIAS
) {
3537 return NT_STATUS_ALIAS_EXISTS
;
3540 /* Yes, the default is NT_STATUS_USER_EXISTS */
3541 return NT_STATUS_USER_EXISTS
;
3544 /*******************************************************************
3546 ********************************************************************/
3548 NTSTATUS
_samr_CreateUser2(pipes_struct
*p
,
3549 struct samr_CreateUser2
*r
)
3551 const char *account
= NULL
;
3553 uint32_t acb_info
= r
->in
.acct_flags
;
3554 struct samr_info
*info
= NULL
;
3559 /* check this, when giving away 'add computer to domain' privs */
3560 uint32 des_access
= GENERIC_RIGHTS_USER_ALL_ACCESS
;
3561 bool can_add_account
= False
;
3563 DISP_INFO
*disp_info
= NULL
;
3565 /* Get the domain SID stored in the domain policy */
3566 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
,
3568 return NT_STATUS_INVALID_HANDLE
;
3570 if (disp_info
->builtin_domain
) {
3571 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3572 return NT_STATUS_ACCESS_DENIED
;
3575 nt_status
= access_check_samr_function(acc_granted
,
3576 SAMR_DOMAIN_ACCESS_CREATE_USER
,
3577 "_samr_CreateUser2");
3578 if (!NT_STATUS_IS_OK(nt_status
)) {
3582 if (!(acb_info
== ACB_NORMAL
|| acb_info
== ACB_DOMTRUST
||
3583 acb_info
== ACB_WSTRUST
|| acb_info
== ACB_SVRTRUST
)) {
3584 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3585 this parameter is not an account type */
3586 return NT_STATUS_INVALID_PARAMETER
;
3589 account
= r
->in
.account_name
->string
;
3590 if (account
== NULL
) {
3591 return NT_STATUS_NO_MEMORY
;
3594 nt_status
= can_create(p
->mem_ctx
, account
);
3595 if (!NT_STATUS_IS_OK(nt_status
)) {
3599 /* determine which user right we need to check based on the acb_info */
3601 if ( acb_info
& ACB_WSTRUST
)
3603 se_priv_copy( &se_rights
, &se_machine_account
);
3604 can_add_account
= user_has_privileges(
3605 p
->server_info
->ptok
, &se_rights
);
3607 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3608 account for domain trusts and changes the ACB flags later */
3609 else if ( acb_info
& ACB_NORMAL
&&
3610 (account
[strlen(account
)-1] != '$') )
3612 se_priv_copy( &se_rights
, &se_add_users
);
3613 can_add_account
= user_has_privileges(
3614 p
->server_info
->ptok
, &se_rights
);
3616 else /* implicit assumption of a BDC or domain trust account here
3617 * (we already check the flags earlier) */
3619 if ( lp_enable_privileges() ) {
3620 /* only Domain Admins can add a BDC or domain trust */
3621 se_priv_copy( &se_rights
, &se_priv_none
);
3622 can_add_account
= nt_token_check_domain_rid(
3623 p
->server_info
->ptok
,
3624 DOMAIN_GROUP_RID_ADMINS
);
3628 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3629 uidtoname(p
->server_info
->utok
.uid
),
3630 can_add_account
? "True":"False" ));
3632 /********** BEGIN Admin BLOCK **********/
3634 if ( can_add_account
)
3637 nt_status
= pdb_create_user(p
->mem_ctx
, account
, acb_info
,
3640 if ( can_add_account
)
3643 /********** END Admin BLOCK **********/
3645 /* now check for failure */
3647 if ( !NT_STATUS_IS_OK(nt_status
) )
3650 /* Get the user's SID */
3652 sid_compose(&sid
, get_global_sam_sid(), *r
->out
.rid
);
3654 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3656 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
,
3657 &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
3658 se_map_generic(&des_access
, &usr_generic_mapping
);
3660 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
3661 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
3662 &acc_granted
, "_samr_CreateUser2");
3664 if ( !NT_STATUS_IS_OK(nt_status
) ) {
3668 /* associate the user's SID with the new handle. */
3669 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &sid
)) == NULL
) {
3670 return NT_STATUS_NO_MEMORY
;
3675 info
->acc_granted
= acc_granted
;
3677 /* get a (unique) handle. open a policy on it. */
3678 if (!create_policy_hnd(p
, r
->out
.user_handle
, info
)) {
3679 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3682 /* After a "set" ensure we have no cached display info. */
3683 force_flush_samr_cache(info
->disp_info
);
3685 *r
->out
.access_granted
= acc_granted
;
3687 return NT_STATUS_OK
;
3690 /****************************************************************
3691 ****************************************************************/
3693 NTSTATUS
_samr_CreateUser(pipes_struct
*p
,
3694 struct samr_CreateUser
*r
)
3696 struct samr_CreateUser2 c
;
3697 uint32_t access_granted
;
3699 c
.in
.domain_handle
= r
->in
.domain_handle
;
3700 c
.in
.account_name
= r
->in
.account_name
;
3701 c
.in
.acct_flags
= ACB_NORMAL
;
3702 c
.in
.access_mask
= r
->in
.access_mask
;
3703 c
.out
.user_handle
= r
->out
.user_handle
;
3704 c
.out
.access_granted
= &access_granted
;
3705 c
.out
.rid
= r
->out
.rid
;
3707 return _samr_CreateUser2(p
, &c
);
3710 /*******************************************************************
3712 ********************************************************************/
3714 NTSTATUS
_samr_Connect(pipes_struct
*p
,
3715 struct samr_Connect
*r
)
3717 struct samr_info
*info
= NULL
;
3718 uint32 des_access
= r
->in
.access_mask
;
3722 if (!pipe_access_check(p
)) {
3723 DEBUG(3, ("access denied to _samr_Connect\n"));
3724 return NT_STATUS_ACCESS_DENIED
;
3727 /* set up the SAMR connect_anon response */
3729 /* associate the user's SID with the new handle. */
3730 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, NULL
)) == NULL
)
3731 return NT_STATUS_NO_MEMORY
;
3733 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3734 was observed from a win98 client trying to enumerate users (when configured
3735 user level access control on shares) --jerry */
3737 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3739 se_map_generic( &des_access
, &sam_generic_mapping
);
3740 info
->acc_granted
= des_access
& (SAMR_ACCESS_ENUM_DOMAINS
|SAMR_ACCESS_LOOKUP_DOMAIN
);
3742 /* get a (unique) handle. open a policy on it. */
3743 if (!create_policy_hnd(p
, r
->out
.connect_handle
, info
))
3744 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3746 return NT_STATUS_OK
;
3749 /*******************************************************************
3751 ********************************************************************/
3753 NTSTATUS
_samr_Connect2(pipes_struct
*p
,
3754 struct samr_Connect2
*r
)
3756 struct samr_info
*info
= NULL
;
3757 SEC_DESC
*psd
= NULL
;
3759 uint32 des_access
= r
->in
.access_mask
;
3762 const char *fn
= "_samr_Connect2";
3764 switch (p
->hdr_req
.opnum
) {
3765 case NDR_SAMR_CONNECT2
:
3766 fn
= "_samr_Connect2";
3768 case NDR_SAMR_CONNECT3
:
3769 fn
= "_samr_Connect3";
3771 case NDR_SAMR_CONNECT4
:
3772 fn
= "_samr_Connect4";
3774 case NDR_SAMR_CONNECT5
:
3775 fn
= "_samr_Connect5";
3779 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3783 if (!pipe_access_check(p
)) {
3784 DEBUG(3, ("access denied to %s\n", fn
));
3785 return NT_STATUS_ACCESS_DENIED
;
3788 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3790 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
3791 se_map_generic(&des_access
, &sam_generic_mapping
);
3793 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
3794 NULL
, 0, des_access
, &acc_granted
, fn
);
3796 if ( !NT_STATUS_IS_OK(nt_status
) )
3799 /* associate the user's SID and access granted with the new handle. */
3800 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, NULL
)) == NULL
)
3801 return NT_STATUS_NO_MEMORY
;
3803 info
->acc_granted
= acc_granted
;
3804 info
->status
= r
->in
.access_mask
; /* this looks so wrong... - gd */
3806 /* get a (unique) handle. open a policy on it. */
3807 if (!create_policy_hnd(p
, r
->out
.connect_handle
, info
))
3808 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3810 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3815 /****************************************************************
3817 ****************************************************************/
3819 NTSTATUS
_samr_Connect3(pipes_struct
*p
,
3820 struct samr_Connect3
*r
)
3822 struct samr_Connect2 c
;
3824 c
.in
.system_name
= r
->in
.system_name
;
3825 c
.in
.access_mask
= r
->in
.access_mask
;
3826 c
.out
.connect_handle
= r
->out
.connect_handle
;
3828 return _samr_Connect2(p
, &c
);
3831 /*******************************************************************
3833 ********************************************************************/
3835 NTSTATUS
_samr_Connect4(pipes_struct
*p
,
3836 struct samr_Connect4
*r
)
3838 struct samr_Connect2 c
;
3840 c
.in
.system_name
= r
->in
.system_name
;
3841 c
.in
.access_mask
= r
->in
.access_mask
;
3842 c
.out
.connect_handle
= r
->out
.connect_handle
;
3844 return _samr_Connect2(p
, &c
);
3847 /*******************************************************************
3849 ********************************************************************/
3851 NTSTATUS
_samr_Connect5(pipes_struct
*p
,
3852 struct samr_Connect5
*r
)
3855 struct samr_Connect2 c
;
3856 struct samr_ConnectInfo1 info1
;
3858 info1
.client_version
= SAMR_CONNECT_AFTER_W2K
;
3861 c
.in
.system_name
= r
->in
.system_name
;
3862 c
.in
.access_mask
= r
->in
.access_mask
;
3863 c
.out
.connect_handle
= r
->out
.connect_handle
;
3865 *r
->out
.level_out
= 1;
3867 status
= _samr_Connect2(p
, &c
);
3868 if (!NT_STATUS_IS_OK(status
)) {
3872 r
->out
.info_out
->info1
= info1
;
3874 return NT_STATUS_OK
;
3877 /**********************************************************************
3879 **********************************************************************/
3881 NTSTATUS
_samr_LookupDomain(pipes_struct
*p
,
3882 struct samr_LookupDomain
*r
)
3884 NTSTATUS status
= NT_STATUS_OK
;
3885 struct samr_info
*info
;
3886 const char *domain_name
;
3887 DOM_SID
*sid
= NULL
;
3889 if (!find_policy_by_hnd(p
, r
->in
.connect_handle
, (void**)(void *)&info
))
3890 return NT_STATUS_INVALID_HANDLE
;
3892 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3893 Reverted that change so we will work with RAS servers again */
3895 status
= access_check_samr_function(info
->acc_granted
,
3896 SAMR_ACCESS_LOOKUP_DOMAIN
,
3897 "_samr_LookupDomain");
3898 if (!NT_STATUS_IS_OK(status
)) {
3902 domain_name
= r
->in
.domain_name
->string
;
3904 return NT_STATUS_INVALID_PARAMETER
;
3907 sid
= TALLOC_ZERO_P(p
->mem_ctx
, struct dom_sid2
);
3909 return NT_STATUS_NO_MEMORY
;
3912 if (strequal(domain_name
, builtin_domain_name())) {
3913 sid_copy(sid
, &global_sid_Builtin
);
3915 if (!secrets_fetch_domain_sid(domain_name
, sid
)) {
3916 status
= NT_STATUS_NO_SUCH_DOMAIN
;
3920 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
,
3921 sid_string_dbg(sid
)));
3928 /**********************************************************************
3930 **********************************************************************/
3932 NTSTATUS
_samr_EnumDomains(pipes_struct
*p
,
3933 struct samr_EnumDomains
*r
)
3936 struct samr_info
*info
;
3937 uint32_t num_entries
= 2;
3938 struct samr_SamEntry
*entry_array
= NULL
;
3939 struct samr_SamArray
*sam
;
3941 if (!find_policy_by_hnd(p
, r
->in
.connect_handle
, (void**)(void *)&info
))
3942 return NT_STATUS_INVALID_HANDLE
;
3944 status
= access_check_samr_function(info
->acc_granted
,
3945 SAMR_ACCESS_ENUM_DOMAINS
,
3946 "_samr_EnumDomains");
3947 if (!NT_STATUS_IS_OK(status
)) {
3951 sam
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
3953 return NT_STATUS_NO_MEMORY
;
3956 entry_array
= TALLOC_ZERO_ARRAY(p
->mem_ctx
,
3957 struct samr_SamEntry
,
3960 return NT_STATUS_NO_MEMORY
;
3963 entry_array
[0].idx
= 0;
3964 init_lsa_String(&entry_array
[0].name
, get_global_sam_name());
3966 entry_array
[1].idx
= 1;
3967 init_lsa_String(&entry_array
[1].name
, "Builtin");
3969 sam
->count
= num_entries
;
3970 sam
->entries
= entry_array
;
3973 *r
->out
.num_entries
= num_entries
;
3978 /*******************************************************************
3980 ********************************************************************/
3982 NTSTATUS
_samr_OpenAlias(pipes_struct
*p
,
3983 struct samr_OpenAlias
*r
)
3986 uint32 alias_rid
= r
->in
.rid
;
3987 struct samr_info
*info
= NULL
;
3988 SEC_DESC
*psd
= NULL
;
3990 uint32 des_access
= r
->in
.access_mask
;
3995 /* find the domain policy and get the SID / access bits stored in the domain policy */
3997 if ( !get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
, NULL
) )
3998 return NT_STATUS_INVALID_HANDLE
;
4000 status
= access_check_samr_function(acc_granted
,
4001 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
4004 if ( !NT_STATUS_IS_OK(status
) )
4007 /* append the alias' RID to it */
4009 if (!sid_append_rid(&sid
, alias_rid
))
4010 return NT_STATUS_NO_SUCH_ALIAS
;
4012 /*check if access can be granted as requested by client. */
4014 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
4016 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &ali_generic_mapping
, NULL
, 0);
4017 se_map_generic(&des_access
,&ali_generic_mapping
);
4019 se_priv_copy( &se_rights
, &se_add_users
);
4022 status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
4023 &se_rights
, GENERIC_RIGHTS_ALIAS_WRITE
, des_access
,
4024 &acc_granted
, "_samr_OpenAlias");
4026 if ( !NT_STATUS_IS_OK(status
) )
4030 /* Check we actually have the requested alias */
4031 enum lsa_SidType type
;
4036 result
= lookup_sid(NULL
, &sid
, NULL
, NULL
, &type
);
4039 if (!result
|| (type
!= SID_NAME_ALIAS
)) {
4040 return NT_STATUS_NO_SUCH_ALIAS
;
4043 /* make sure there is a mapping */
4045 if ( !sid_to_gid( &sid
, &gid
) ) {
4046 return NT_STATUS_NO_SUCH_ALIAS
;
4051 /* associate the alias SID with the new handle. */
4052 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &sid
)) == NULL
)
4053 return NT_STATUS_NO_MEMORY
;
4055 info
->acc_granted
= acc_granted
;
4057 /* get a (unique) handle. open a policy on it. */
4058 if (!create_policy_hnd(p
, r
->out
.alias_handle
, info
))
4059 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4061 return NT_STATUS_OK
;
4064 /*******************************************************************
4066 ********************************************************************/
4068 static NTSTATUS
set_user_info_2(TALLOC_CTX
*mem_ctx
,
4069 struct samr_UserInfo2
*id2
,
4073 DEBUG(5,("set_user_info_2: NULL id2\n"));
4074 return NT_STATUS_ACCESS_DENIED
;
4077 copy_id2_to_sam_passwd(pwd
, id2
);
4079 return pdb_update_sam_account(pwd
);
4082 /*******************************************************************
4084 ********************************************************************/
4086 static NTSTATUS
set_user_info_4(TALLOC_CTX
*mem_ctx
,
4087 struct samr_UserInfo4
*id4
,
4091 DEBUG(5,("set_user_info_2: NULL id4\n"));
4092 return NT_STATUS_ACCESS_DENIED
;
4095 copy_id4_to_sam_passwd(pwd
, id4
);
4097 return pdb_update_sam_account(pwd
);
4100 /*******************************************************************
4102 ********************************************************************/
4104 static NTSTATUS
set_user_info_6(TALLOC_CTX
*mem_ctx
,
4105 struct samr_UserInfo6
*id6
,
4109 DEBUG(5,("set_user_info_6: NULL id6\n"));
4110 return NT_STATUS_ACCESS_DENIED
;
4113 copy_id6_to_sam_passwd(pwd
, id6
);
4115 return pdb_update_sam_account(pwd
);
4118 /*******************************************************************
4120 ********************************************************************/
4122 static NTSTATUS
set_user_info_7(TALLOC_CTX
*mem_ctx
,
4123 struct samr_UserInfo7
*id7
,
4129 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4130 return NT_STATUS_ACCESS_DENIED
;
4133 if (!id7
->account_name
.string
) {
4134 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4135 return NT_STATUS_ACCESS_DENIED
;
4138 /* check to see if the new username already exists. Note: we can't
4139 reliably lock all backends, so there is potentially the
4140 possibility that a user can be created in between this check and
4141 the rename. The rename should fail, but may not get the
4142 exact same failure status code. I think this is small enough
4143 of a window for this type of operation and the results are
4144 simply that the rename fails with a slightly different status
4145 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4147 rc
= can_create(mem_ctx
, id7
->account_name
.string
);
4149 /* when there is nothing to change, we're done here */
4150 if (NT_STATUS_EQUAL(rc
, NT_STATUS_USER_EXISTS
) &&
4151 strequal(id7
->account_name
.string
, pdb_get_username(pwd
))) {
4152 return NT_STATUS_OK
;
4154 if (!NT_STATUS_IS_OK(rc
)) {
4158 rc
= pdb_rename_sam_account(pwd
, id7
->account_name
.string
);
4163 /*******************************************************************
4165 ********************************************************************/
4167 static NTSTATUS
set_user_info_8(TALLOC_CTX
*mem_ctx
,
4168 struct samr_UserInfo8
*id8
,
4172 DEBUG(5,("set_user_info_8: NULL id8\n"));
4173 return NT_STATUS_ACCESS_DENIED
;
4176 copy_id8_to_sam_passwd(pwd
, id8
);
4178 return pdb_update_sam_account(pwd
);
4181 /*******************************************************************
4183 ********************************************************************/
4185 static NTSTATUS
set_user_info_10(TALLOC_CTX
*mem_ctx
,
4186 struct samr_UserInfo10
*id10
,
4190 DEBUG(5,("set_user_info_8: NULL id10\n"));
4191 return NT_STATUS_ACCESS_DENIED
;
4194 copy_id10_to_sam_passwd(pwd
, id10
);
4196 return pdb_update_sam_account(pwd
);
4199 /*******************************************************************
4201 ********************************************************************/
4203 static NTSTATUS
set_user_info_11(TALLOC_CTX
*mem_ctx
,
4204 struct samr_UserInfo11
*id11
,
4208 DEBUG(5,("set_user_info_11: NULL id11\n"));
4209 return NT_STATUS_ACCESS_DENIED
;
4212 copy_id11_to_sam_passwd(pwd
, id11
);
4214 return pdb_update_sam_account(pwd
);
4217 /*******************************************************************
4219 ********************************************************************/
4221 static NTSTATUS
set_user_info_12(TALLOC_CTX
*mem_ctx
,
4222 struct samr_UserInfo12
*id12
,
4226 DEBUG(5,("set_user_info_12: NULL id12\n"));
4227 return NT_STATUS_ACCESS_DENIED
;
4230 copy_id12_to_sam_passwd(pwd
, id12
);
4232 return pdb_update_sam_account(pwd
);
4235 /*******************************************************************
4237 ********************************************************************/
4239 static NTSTATUS
set_user_info_13(TALLOC_CTX
*mem_ctx
,
4240 struct samr_UserInfo13
*id13
,
4244 DEBUG(5,("set_user_info_13: NULL id13\n"));
4245 return NT_STATUS_ACCESS_DENIED
;
4248 copy_id13_to_sam_passwd(pwd
, id13
);
4250 return pdb_update_sam_account(pwd
);
4253 /*******************************************************************
4255 ********************************************************************/
4257 static NTSTATUS
set_user_info_14(TALLOC_CTX
*mem_ctx
,
4258 struct samr_UserInfo14
*id14
,
4262 DEBUG(5,("set_user_info_14: NULL id14\n"));
4263 return NT_STATUS_ACCESS_DENIED
;
4266 copy_id14_to_sam_passwd(pwd
, id14
);
4268 return pdb_update_sam_account(pwd
);
4271 /*******************************************************************
4273 ********************************************************************/
4275 static NTSTATUS
set_user_info_16(TALLOC_CTX
*mem_ctx
,
4276 struct samr_UserInfo16
*id16
,
4280 DEBUG(5,("set_user_info_16: NULL id16\n"));
4281 return NT_STATUS_ACCESS_DENIED
;
4284 copy_id16_to_sam_passwd(pwd
, id16
);
4286 return pdb_update_sam_account(pwd
);
4289 /*******************************************************************
4291 ********************************************************************/
4293 static NTSTATUS
set_user_info_17(TALLOC_CTX
*mem_ctx
,
4294 struct samr_UserInfo17
*id17
,
4298 DEBUG(5,("set_user_info_17: NULL id17\n"));
4299 return NT_STATUS_ACCESS_DENIED
;
4302 copy_id17_to_sam_passwd(pwd
, id17
);
4304 return pdb_update_sam_account(pwd
);
4307 /*******************************************************************
4309 ********************************************************************/
4311 static NTSTATUS
set_user_info_18(struct samr_UserInfo18
*id18
,
4312 TALLOC_CTX
*mem_ctx
,
4313 DATA_BLOB
*session_key
,
4317 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4318 return NT_STATUS_INVALID_PARAMETER
;
4321 if (id18
->nt_pwd_active
|| id18
->lm_pwd_active
) {
4322 if (!session_key
->length
) {
4323 return NT_STATUS_NO_USER_SESSION_KEY
;
4327 if (id18
->nt_pwd_active
) {
4331 in
= data_blob_const(id18
->nt_pwd
.hash
, 16);
4332 out
= data_blob_talloc_zero(mem_ctx
, 16);
4334 sess_crypt_blob(&out
, &in
, session_key
, false);
4336 if (!pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4337 return NT_STATUS_ACCESS_DENIED
;
4340 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4343 if (id18
->lm_pwd_active
) {
4347 in
= data_blob_const(id18
->lm_pwd
.hash
, 16);
4348 out
= data_blob_talloc_zero(mem_ctx
, 16);
4350 sess_crypt_blob(&out
, &in
, session_key
, false);
4352 if (!pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4353 return NT_STATUS_ACCESS_DENIED
;
4356 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4359 copy_id18_to_sam_passwd(pwd
, id18
);
4361 return pdb_update_sam_account(pwd
);
4364 /*******************************************************************
4366 ********************************************************************/
4368 static NTSTATUS
set_user_info_20(TALLOC_CTX
*mem_ctx
,
4369 struct samr_UserInfo20
*id20
,
4373 DEBUG(5,("set_user_info_20: NULL id20\n"));
4374 return NT_STATUS_ACCESS_DENIED
;
4377 copy_id20_to_sam_passwd(pwd
, id20
);
4379 return pdb_update_sam_account(pwd
);
4382 /*******************************************************************
4384 ********************************************************************/
4386 static NTSTATUS
set_user_info_21(struct samr_UserInfo21
*id21
,
4387 TALLOC_CTX
*mem_ctx
,
4388 DATA_BLOB
*session_key
,
4394 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4395 return NT_STATUS_INVALID_PARAMETER
;
4398 if (id21
->fields_present
== 0) {
4399 return NT_STATUS_INVALID_PARAMETER
;
4402 if (id21
->fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4403 return NT_STATUS_ACCESS_DENIED
;
4406 if (id21
->fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
4407 if (id21
->nt_password_set
) {
4410 if ((id21
->nt_owf_password
.length
!= 16) ||
4411 (id21
->nt_owf_password
.size
!= 16)) {
4412 return NT_STATUS_INVALID_PARAMETER
;
4415 if (!session_key
->length
) {
4416 return NT_STATUS_NO_USER_SESSION_KEY
;
4419 in
= data_blob_const(id21
->nt_owf_password
.array
, 16);
4420 out
= data_blob_talloc_zero(mem_ctx
, 16);
4422 sess_crypt_blob(&out
, &in
, session_key
, false);
4424 pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
);
4425 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4429 if (id21
->fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4430 if (id21
->lm_password_set
) {
4433 if ((id21
->lm_owf_password
.length
!= 16) ||
4434 (id21
->lm_owf_password
.size
!= 16)) {
4435 return NT_STATUS_INVALID_PARAMETER
;
4438 if (!session_key
->length
) {
4439 return NT_STATUS_NO_USER_SESSION_KEY
;
4442 in
= data_blob_const(id21
->lm_owf_password
.array
, 16);
4443 out
= data_blob_talloc_zero(mem_ctx
, 16);
4445 sess_crypt_blob(&out
, &in
, session_key
, false);
4447 pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
);
4448 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4452 /* we need to separately check for an account rename first */
4454 if (id21
->account_name
.string
&&
4455 (!strequal(id21
->account_name
.string
, pdb_get_username(pwd
))))
4458 /* check to see if the new username already exists. Note: we can't
4459 reliably lock all backends, so there is potentially the
4460 possibility that a user can be created in between this check and
4461 the rename. The rename should fail, but may not get the
4462 exact same failure status code. I think this is small enough
4463 of a window for this type of operation and the results are
4464 simply that the rename fails with a slightly different status
4465 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4467 status
= can_create(mem_ctx
, id21
->account_name
.string
);
4468 if (!NT_STATUS_IS_OK(status
)) {
4472 status
= pdb_rename_sam_account(pwd
, id21
->account_name
.string
);
4474 if (!NT_STATUS_IS_OK(status
)) {
4475 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4476 nt_errstr(status
)));
4480 /* set the new username so that later
4481 functions can work on the new account */
4482 pdb_set_username(pwd
, id21
->account_name
.string
, PDB_SET
);
4485 copy_id21_to_sam_passwd("INFO_21", pwd
, id21
);
4488 * The funny part about the previous two calls is
4489 * that pwd still has the password hashes from the
4490 * passdb entry. These have not been updated from
4491 * id21. I don't know if they need to be set. --jerry
4494 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4495 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4496 if ( !NT_STATUS_IS_OK(status
) ) {
4501 /* Don't worry about writing out the user account since the
4502 primary group SID is generated solely from the user's Unix
4505 /* write the change out */
4506 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4510 return NT_STATUS_OK
;
4513 /*******************************************************************
4515 ********************************************************************/
4517 static NTSTATUS
set_user_info_23(TALLOC_CTX
*mem_ctx
,
4518 struct samr_UserInfo23
*id23
,
4521 char *plaintext_buf
= NULL
;
4527 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4528 return NT_STATUS_INVALID_PARAMETER
;
4531 if (id23
->info
.fields_present
== 0) {
4532 return NT_STATUS_INVALID_PARAMETER
;
4535 if (id23
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4536 return NT_STATUS_ACCESS_DENIED
;
4539 if ((id23
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4540 (id23
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4542 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4543 pdb_get_username(pwd
)));
4545 if (!decode_pw_buffer(mem_ctx
,
4546 id23
->password
.data
,
4550 return NT_STATUS_WRONG_PASSWORD
;
4553 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4554 return NT_STATUS_ACCESS_DENIED
;
4558 copy_id23_to_sam_passwd(pwd
, id23
);
4560 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4562 /* if it's a trust account, don't update /etc/passwd */
4563 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4564 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4565 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4566 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4567 } else if (plaintext_buf
) {
4568 /* update the UNIX password */
4569 if (lp_unix_password_sync() ) {
4570 struct passwd
*passwd
;
4571 if (pdb_get_username(pwd
) == NULL
) {
4572 DEBUG(1, ("chgpasswd: User without name???\n"));
4573 return NT_STATUS_ACCESS_DENIED
;
4576 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4577 if (passwd
== NULL
) {
4578 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4581 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
4582 return NT_STATUS_ACCESS_DENIED
;
4584 TALLOC_FREE(passwd
);
4588 if (plaintext_buf
) {
4589 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4592 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) &&
4593 (!NT_STATUS_IS_OK(status
= pdb_set_unix_primary_group(mem_ctx
,
4598 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4602 return NT_STATUS_OK
;
4605 /*******************************************************************
4607 ********************************************************************/
4609 static bool set_user_info_pw(uint8
*pass
, struct samu
*pwd
)
4612 char *plaintext_buf
= NULL
;
4615 DEBUG(5, ("Attempting administrator password change for user %s\n",
4616 pdb_get_username(pwd
)));
4618 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4620 if (!decode_pw_buffer(talloc_tos(),
4628 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4632 /* if it's a trust account, don't update /etc/passwd */
4633 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4634 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4635 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4636 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4638 /* update the UNIX password */
4639 if (lp_unix_password_sync()) {
4640 struct passwd
*passwd
;
4642 if (pdb_get_username(pwd
) == NULL
) {
4643 DEBUG(1, ("chgpasswd: User without name???\n"));
4647 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4648 if (passwd
== NULL
) {
4649 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4652 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
4655 TALLOC_FREE(passwd
);
4659 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4661 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4666 /*******************************************************************
4668 ********************************************************************/
4670 static NTSTATUS
set_user_info_24(TALLOC_CTX
*mem_ctx
,
4671 struct samr_UserInfo24
*id24
,
4677 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4678 return NT_STATUS_INVALID_PARAMETER
;
4681 if (!set_user_info_pw(id24
->password
.data
, pwd
)) {
4682 return NT_STATUS_WRONG_PASSWORD
;
4685 copy_id24_to_sam_passwd(pwd
, id24
);
4687 status
= pdb_update_sam_account(pwd
);
4688 if (!NT_STATUS_IS_OK(status
)) {
4692 return NT_STATUS_OK
;
4695 /*******************************************************************
4697 ********************************************************************/
4699 static NTSTATUS
set_user_info_25(TALLOC_CTX
*mem_ctx
,
4700 struct samr_UserInfo25
*id25
,
4706 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4707 return NT_STATUS_INVALID_PARAMETER
;
4710 if (id25
->info
.fields_present
== 0) {
4711 return NT_STATUS_INVALID_PARAMETER
;
4714 if (id25
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4715 return NT_STATUS_ACCESS_DENIED
;
4718 if ((id25
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4719 (id25
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4721 if (!set_user_info_pw(id25
->password
.data
, pwd
)) {
4722 return NT_STATUS_WRONG_PASSWORD
;
4726 copy_id25_to_sam_passwd(pwd
, id25
);
4728 /* write the change out */
4729 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4734 * We need to "pdb_update_sam_account" before the unix primary group
4735 * is set, because the idealx scripts would also change the
4736 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4737 * the delete explicit / add explicit, which would then fail to find
4738 * the previous primaryGroupSid value.
4741 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4742 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4743 if ( !NT_STATUS_IS_OK(status
) ) {
4748 return NT_STATUS_OK
;
4751 /*******************************************************************
4753 ********************************************************************/
4755 static NTSTATUS
set_user_info_26(TALLOC_CTX
*mem_ctx
,
4756 struct samr_UserInfo26
*id26
,
4762 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4763 return NT_STATUS_INVALID_PARAMETER
;
4766 if (!set_user_info_pw(id26
->password
.data
, pwd
)) {
4767 return NT_STATUS_WRONG_PASSWORD
;
4770 copy_id26_to_sam_passwd(pwd
, id26
);
4772 status
= pdb_update_sam_account(pwd
);
4773 if (!NT_STATUS_IS_OK(status
)) {
4777 return NT_STATUS_OK
;
4781 /*******************************************************************
4783 ********************************************************************/
4785 NTSTATUS
_samr_SetUserInfo(pipes_struct
*p
,
4786 struct samr_SetUserInfo
*r
)
4789 struct samu
*pwd
= NULL
;
4791 union samr_UserInfo
*info
= r
->in
.info
;
4792 uint16_t switch_value
= r
->in
.level
;
4793 uint32_t acc_granted
;
4794 uint32_t acc_required
;
4796 bool has_enough_rights
= False
;
4798 DISP_INFO
*disp_info
= NULL
;
4800 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__
));
4802 /* find the policy handle. open a policy on it. */
4803 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &sid
, &acc_granted
, &disp_info
)) {
4804 return NT_STATUS_INVALID_HANDLE
;
4807 /* This is tricky. A WinXP domain join sets
4808 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4809 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4810 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4811 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4812 we'll use the set from the WinXP join as the basis. */
4814 switch (switch_value
) {
4819 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
;
4822 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
|
4823 SAMR_USER_ACCESS_SET_ATTRIBUTES
|
4824 SAMR_USER_ACCESS_GET_ATTRIBUTES
;
4828 status
= access_check_samr_function(acc_granted
,
4830 "_samr_SetUserInfo");
4831 if (!NT_STATUS_IS_OK(status
)) {
4835 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4836 sid_string_dbg(&sid
), switch_value
));
4839 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4840 return NT_STATUS_INVALID_INFO_CLASS
;
4843 if (!(pwd
= samu_new(NULL
))) {
4844 return NT_STATUS_NO_MEMORY
;
4848 ret
= pdb_getsampwsid(pwd
, &sid
);
4853 return NT_STATUS_NO_SUCH_USER
;
4856 /* deal with machine password changes differently from userinfo changes */
4857 /* check to see if we have the sufficient rights */
4859 acb_info
= pdb_get_acct_ctrl(pwd
);
4860 if (acb_info
& ACB_WSTRUST
)
4861 has_enough_rights
= user_has_privileges(p
->server_info
->ptok
,
4862 &se_machine_account
);
4863 else if (acb_info
& ACB_NORMAL
)
4864 has_enough_rights
= user_has_privileges(p
->server_info
->ptok
,
4866 else if (acb_info
& (ACB_SVRTRUST
|ACB_DOMTRUST
)) {
4867 if (lp_enable_privileges()) {
4868 has_enough_rights
= nt_token_check_domain_rid(p
->server_info
->ptok
,
4869 DOMAIN_GROUP_RID_ADMINS
);
4873 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4874 uidtoname(p
->server_info
->utok
.uid
),
4875 has_enough_rights
? "" : " not"));
4877 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4879 if (has_enough_rights
) {
4883 /* ok! user info levels (lots: see MSDEV help), off we go... */
4885 switch (switch_value
) {
4888 status
= set_user_info_2(p
->mem_ctx
,
4893 status
= set_user_info_4(p
->mem_ctx
,
4898 status
= set_user_info_6(p
->mem_ctx
,
4903 status
= set_user_info_7(p
->mem_ctx
,
4908 status
= set_user_info_8(p
->mem_ctx
,
4913 status
= set_user_info_10(p
->mem_ctx
,
4914 &info
->info10
, pwd
);
4918 status
= set_user_info_11(p
->mem_ctx
,
4919 &info
->info11
, pwd
);
4923 status
= set_user_info_12(p
->mem_ctx
,
4924 &info
->info12
, pwd
);
4928 status
= set_user_info_13(p
->mem_ctx
,
4929 &info
->info13
, pwd
);
4933 status
= set_user_info_14(p
->mem_ctx
,
4934 &info
->info14
, pwd
);
4938 status
= set_user_info_16(p
->mem_ctx
,
4939 &info
->info16
, pwd
);
4943 status
= set_user_info_17(p
->mem_ctx
,
4944 &info
->info17
, pwd
);
4948 /* Used by AS/U JRA. */
4949 status
= set_user_info_18(&info
->info18
,
4951 &p
->server_info
->user_session_key
,
4956 status
= set_user_info_20(p
->mem_ctx
,
4957 &info
->info20
, pwd
);
4961 status
= set_user_info_21(&info
->info21
,
4963 &p
->server_info
->user_session_key
,
4968 if (!p
->server_info
->user_session_key
.length
) {
4969 status
= NT_STATUS_NO_USER_SESSION_KEY
;
4971 SamOEMhashBlob(info
->info23
.password
.data
, 516,
4972 &p
->server_info
->user_session_key
);
4974 dump_data(100, info
->info23
.password
.data
, 516);
4976 status
= set_user_info_23(p
->mem_ctx
,
4977 &info
->info23
, pwd
);
4981 if (!p
->server_info
->user_session_key
.length
) {
4982 status
= NT_STATUS_NO_USER_SESSION_KEY
;
4984 SamOEMhashBlob(info
->info24
.password
.data
,
4986 &p
->server_info
->user_session_key
);
4988 dump_data(100, info
->info24
.password
.data
, 516);
4990 status
= set_user_info_24(p
->mem_ctx
,
4991 &info
->info24
, pwd
);
4995 if (!p
->server_info
->user_session_key
.length
) {
4996 status
= NT_STATUS_NO_USER_SESSION_KEY
;
4998 encode_or_decode_arc4_passwd_buffer(
4999 info
->info25
.password
.data
,
5000 &p
->server_info
->user_session_key
);
5002 dump_data(100, info
->info25
.password
.data
, 532);
5004 status
= set_user_info_25(p
->mem_ctx
,
5005 &info
->info25
, pwd
);
5009 if (!p
->server_info
->user_session_key
.length
) {
5010 status
= NT_STATUS_NO_USER_SESSION_KEY
;
5012 encode_or_decode_arc4_passwd_buffer(
5013 info
->info26
.password
.data
,
5014 &p
->server_info
->user_session_key
);
5016 dump_data(100, info
->info26
.password
.data
, 516);
5018 status
= set_user_info_26(p
->mem_ctx
,
5019 &info
->info26
, pwd
);
5023 status
= NT_STATUS_INVALID_INFO_CLASS
;
5028 if (has_enough_rights
) {
5032 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
5034 if (NT_STATUS_IS_OK(status
)) {
5035 force_flush_samr_cache(disp_info
);
5041 /*******************************************************************
5043 ********************************************************************/
5045 NTSTATUS
_samr_SetUserInfo2(pipes_struct
*p
,
5046 struct samr_SetUserInfo2
*r
)
5048 struct samr_SetUserInfo q
;
5050 q
.in
.user_handle
= r
->in
.user_handle
;
5051 q
.in
.level
= r
->in
.level
;
5052 q
.in
.info
= r
->in
.info
;
5054 return _samr_SetUserInfo(p
, &q
);
5057 /*********************************************************************
5058 _samr_GetAliasMembership
5059 *********************************************************************/
5061 NTSTATUS
_samr_GetAliasMembership(pipes_struct
*p
,
5062 struct samr_GetAliasMembership
*r
)
5064 size_t num_alias_rids
;
5066 struct samr_info
*info
= NULL
;
5074 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__
));
5076 /* find the policy handle. open a policy on it. */
5077 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
5078 return NT_STATUS_INVALID_HANDLE
;
5080 ntstatus1
= access_check_samr_function(info
->acc_granted
,
5081 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
5082 "_samr_GetAliasMembership");
5083 ntstatus2
= access_check_samr_function(info
->acc_granted
,
5084 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
5085 "_samr_GetAliasMembership");
5087 if (!NT_STATUS_IS_OK(ntstatus1
) || !NT_STATUS_IS_OK(ntstatus2
)) {
5088 if (!(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus2
)) &&
5089 !(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus1
))) {
5090 return (NT_STATUS_IS_OK(ntstatus1
)) ? ntstatus2
: ntstatus1
;
5094 if (!sid_check_is_domain(&info
->sid
) &&
5095 !sid_check_is_builtin(&info
->sid
))
5096 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
5098 if (r
->in
.sids
->num_sids
) {
5099 members
= TALLOC_ARRAY(p
->mem_ctx
, DOM_SID
, r
->in
.sids
->num_sids
);
5101 if (members
== NULL
)
5102 return NT_STATUS_NO_MEMORY
;
5107 for (i
=0; i
<r
->in
.sids
->num_sids
; i
++)
5108 sid_copy(&members
[i
], r
->in
.sids
->sids
[i
].sid
);
5114 ntstatus1
= pdb_enum_alias_memberships(p
->mem_ctx
, &info
->sid
, members
,
5115 r
->in
.sids
->num_sids
,
5116 &alias_rids
, &num_alias_rids
);
5119 if (!NT_STATUS_IS_OK(ntstatus1
)) {
5123 r
->out
.rids
->count
= num_alias_rids
;
5124 r
->out
.rids
->ids
= alias_rids
;
5126 return NT_STATUS_OK
;
5129 /*********************************************************************
5130 _samr_GetMembersInAlias
5131 *********************************************************************/
5133 NTSTATUS
_samr_GetMembersInAlias(pipes_struct
*p
,
5134 struct samr_GetMembersInAlias
*r
)
5138 size_t num_sids
= 0;
5139 struct lsa_SidPtr
*sids
= NULL
;
5140 DOM_SID
*pdb_sids
= NULL
;
5146 /* find the policy handle. open a policy on it. */
5147 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, NULL
))
5148 return NT_STATUS_INVALID_HANDLE
;
5150 status
= access_check_samr_function(acc_granted
,
5151 SAMR_ALIAS_ACCESS_GET_MEMBERS
,
5152 "_samr_GetMembersInAlias");
5153 if (!NT_STATUS_IS_OK(status
)) {
5157 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid
)));
5160 status
= pdb_enum_aliasmem(&alias_sid
, &pdb_sids
, &num_sids
);
5163 if (!NT_STATUS_IS_OK(status
)) {
5168 sids
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, struct lsa_SidPtr
, num_sids
);
5170 TALLOC_FREE(pdb_sids
);
5171 return NT_STATUS_NO_MEMORY
;
5175 for (i
= 0; i
< num_sids
; i
++) {
5176 sids
[i
].sid
= sid_dup_talloc(p
->mem_ctx
, &pdb_sids
[i
]);
5178 TALLOC_FREE(pdb_sids
);
5179 return NT_STATUS_NO_MEMORY
;
5183 r
->out
.sids
->num_sids
= num_sids
;
5184 r
->out
.sids
->sids
= sids
;
5186 TALLOC_FREE(pdb_sids
);
5188 return NT_STATUS_OK
;
5191 /*********************************************************************
5192 _samr_QueryGroupMember
5193 *********************************************************************/
5195 NTSTATUS
_samr_QueryGroupMember(pipes_struct
*p
,
5196 struct samr_QueryGroupMember
*r
)
5199 size_t i
, num_members
;
5207 struct samr_RidTypeArray
*rids
= NULL
;
5209 rids
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_RidTypeArray
);
5211 return NT_STATUS_NO_MEMORY
;
5214 /* find the policy handle. open a policy on it. */
5215 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, NULL
))
5216 return NT_STATUS_INVALID_HANDLE
;
5218 status
= access_check_samr_function(acc_granted
,
5219 SAMR_GROUP_ACCESS_GET_MEMBERS
,
5220 "_samr_QueryGroupMember");
5221 if (!NT_STATUS_IS_OK(status
)) {
5225 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid
)));
5227 if (!sid_check_is_in_our_domain(&group_sid
)) {
5228 DEBUG(3, ("sid %s is not in our domain\n",
5229 sid_string_dbg(&group_sid
)));
5230 return NT_STATUS_NO_SUCH_GROUP
;
5233 DEBUG(10, ("lookup on Domain SID\n"));
5236 status
= pdb_enum_group_members(p
->mem_ctx
, &group_sid
,
5237 &rid
, &num_members
);
5240 if (!NT_STATUS_IS_OK(status
))
5244 attr
=TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_members
);
5246 return NT_STATUS_NO_MEMORY
;
5252 for (i
=0; i
<num_members
; i
++)
5253 attr
[i
] = SID_NAME_USER
;
5255 rids
->count
= num_members
;
5259 *r
->out
.rids
= rids
;
5261 return NT_STATUS_OK
;
5264 /*********************************************************************
5265 _samr_AddAliasMember
5266 *********************************************************************/
5268 NTSTATUS
_samr_AddAliasMember(pipes_struct
*p
,
5269 struct samr_AddAliasMember
*r
)
5274 bool can_add_accounts
;
5276 DISP_INFO
*disp_info
= NULL
;
5278 /* Find the policy handle. Open a policy on it. */
5279 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, &disp_info
))
5280 return NT_STATUS_INVALID_HANDLE
;
5282 status
= access_check_samr_function(acc_granted
,
5283 SAMR_ALIAS_ACCESS_ADD_MEMBER
,
5284 "_samr_AddAliasMember");
5285 if (!NT_STATUS_IS_OK(status
)) {
5289 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid
)));
5291 se_priv_copy( &se_rights
, &se_add_users
);
5292 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5294 /******** BEGIN SeAddUsers BLOCK *********/
5296 if ( can_add_accounts
)
5299 status
= pdb_add_aliasmem(&alias_sid
, r
->in
.sid
);
5301 if ( can_add_accounts
)
5304 /******** END SeAddUsers BLOCK *********/
5306 if (NT_STATUS_IS_OK(status
)) {
5307 force_flush_samr_cache(disp_info
);
5313 /*********************************************************************
5314 _samr_DeleteAliasMember
5315 *********************************************************************/
5317 NTSTATUS
_samr_DeleteAliasMember(pipes_struct
*p
,
5318 struct samr_DeleteAliasMember
*r
)
5323 bool can_add_accounts
;
5325 DISP_INFO
*disp_info
= NULL
;
5327 /* Find the policy handle. Open a policy on it. */
5328 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, &disp_info
))
5329 return NT_STATUS_INVALID_HANDLE
;
5331 status
= access_check_samr_function(acc_granted
,
5332 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
,
5333 "_samr_DeleteAliasMember");
5334 if (!NT_STATUS_IS_OK(status
)) {
5338 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5339 sid_string_dbg(&alias_sid
)));
5341 se_priv_copy( &se_rights
, &se_add_users
);
5342 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5344 /******** BEGIN SeAddUsers BLOCK *********/
5346 if ( can_add_accounts
)
5349 status
= pdb_del_aliasmem(&alias_sid
, r
->in
.sid
);
5351 if ( can_add_accounts
)
5354 /******** END SeAddUsers BLOCK *********/
5356 if (NT_STATUS_IS_OK(status
)) {
5357 force_flush_samr_cache(disp_info
);
5363 /*********************************************************************
5364 _samr_AddGroupMember
5365 *********************************************************************/
5367 NTSTATUS
_samr_AddGroupMember(pipes_struct
*p
,
5368 struct samr_AddGroupMember
*r
)
5375 bool can_add_accounts
;
5376 DISP_INFO
*disp_info
= NULL
;
5378 /* Find the policy handle. Open a policy on it. */
5379 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5380 return NT_STATUS_INVALID_HANDLE
;
5382 status
= access_check_samr_function(acc_granted
,
5383 SAMR_GROUP_ACCESS_ADD_MEMBER
,
5384 "_samr_AddGroupMember");
5385 if (!NT_STATUS_IS_OK(status
)) {
5389 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid
)));
5391 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid
,
5393 return NT_STATUS_INVALID_HANDLE
;
5396 se_priv_copy( &se_rights
, &se_add_users
);
5397 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5399 /******** BEGIN SeAddUsers BLOCK *********/
5401 if ( can_add_accounts
)
5404 status
= pdb_add_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5406 if ( can_add_accounts
)
5409 /******** END SeAddUsers BLOCK *********/
5411 force_flush_samr_cache(disp_info
);
5416 /*********************************************************************
5417 _samr_DeleteGroupMember
5418 *********************************************************************/
5420 NTSTATUS
_samr_DeleteGroupMember(pipes_struct
*p
,
5421 struct samr_DeleteGroupMember
*r
)
5429 bool can_add_accounts
;
5430 DISP_INFO
*disp_info
= NULL
;
5433 * delete the group member named r->in.rid
5434 * who is a member of the sid associated with the handle
5435 * the rid is a user's rid as the group is a domain group.
5438 /* Find the policy handle. Open a policy on it. */
5439 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5440 return NT_STATUS_INVALID_HANDLE
;
5442 status
= access_check_samr_function(acc_granted
,
5443 SAMR_GROUP_ACCESS_REMOVE_MEMBER
,
5444 "_samr_DeleteGroupMember");
5445 if (!NT_STATUS_IS_OK(status
)) {
5449 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid
,
5451 return NT_STATUS_INVALID_HANDLE
;
5454 se_priv_copy( &se_rights
, &se_add_users
);
5455 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5457 /******** BEGIN SeAddUsers BLOCK *********/
5459 if ( can_add_accounts
)
5462 status
= pdb_del_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5464 if ( can_add_accounts
)
5467 /******** END SeAddUsers BLOCK *********/
5469 force_flush_samr_cache(disp_info
);
5474 /*********************************************************************
5476 *********************************************************************/
5478 NTSTATUS
_samr_DeleteUser(pipes_struct
*p
,
5479 struct samr_DeleteUser
*r
)
5483 struct samu
*sam_pass
=NULL
;
5485 bool can_add_accounts
;
5487 DISP_INFO
*disp_info
= NULL
;
5490 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__
));
5492 /* Find the policy handle. Open a policy on it. */
5493 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &user_sid
, &acc_granted
, &disp_info
))
5494 return NT_STATUS_INVALID_HANDLE
;
5496 status
= access_check_samr_function(acc_granted
,
5497 STD_RIGHT_DELETE_ACCESS
,
5498 "_samr_DeleteUser");
5499 if (!NT_STATUS_IS_OK(status
)) {
5503 if (!sid_check_is_in_our_domain(&user_sid
))
5504 return NT_STATUS_CANNOT_DELETE
;
5506 /* check if the user exists before trying to delete */
5507 if ( !(sam_pass
= samu_new( NULL
)) ) {
5508 return NT_STATUS_NO_MEMORY
;
5512 ret
= pdb_getsampwsid(sam_pass
, &user_sid
);
5516 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5517 sid_string_dbg(&user_sid
)));
5518 TALLOC_FREE(sam_pass
);
5519 return NT_STATUS_NO_SUCH_USER
;
5522 acb_info
= pdb_get_acct_ctrl(sam_pass
);
5524 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
5525 if ( acb_info
& ACB_WSTRUST
) {
5526 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_machine_account
);
5528 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_add_users
);
5531 /******** BEGIN SeAddUsers BLOCK *********/
5533 if ( can_add_accounts
)
5536 status
= pdb_delete_user(p
->mem_ctx
, sam_pass
);
5538 if ( can_add_accounts
)
5541 /******** END SeAddUsers BLOCK *********/
5543 if ( !NT_STATUS_IS_OK(status
) ) {
5544 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5545 "user %s: %s.\n", pdb_get_username(sam_pass
),
5546 nt_errstr(status
)));
5547 TALLOC_FREE(sam_pass
);
5552 TALLOC_FREE(sam_pass
);
5554 if (!close_policy_hnd(p
, r
->in
.user_handle
))
5555 return NT_STATUS_OBJECT_NAME_INVALID
;
5557 ZERO_STRUCTP(r
->out
.user_handle
);
5559 force_flush_samr_cache(disp_info
);
5561 return NT_STATUS_OK
;
5564 /*********************************************************************
5565 _samr_DeleteDomainGroup
5566 *********************************************************************/
5568 NTSTATUS
_samr_DeleteDomainGroup(pipes_struct
*p
,
5569 struct samr_DeleteDomainGroup
*r
)
5576 bool can_add_accounts
;
5577 DISP_INFO
*disp_info
= NULL
;
5579 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__
));
5581 /* Find the policy handle. Open a policy on it. */
5582 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5583 return NT_STATUS_INVALID_HANDLE
;
5585 status
= access_check_samr_function(acc_granted
,
5586 STD_RIGHT_DELETE_ACCESS
,
5587 "_samr_DeleteDomainGroup");
5588 if (!NT_STATUS_IS_OK(status
)) {
5592 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid
)));
5594 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid
,
5596 return NT_STATUS_NO_SUCH_GROUP
;
5599 se_priv_copy( &se_rights
, &se_add_users
);
5600 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5602 /******** BEGIN SeAddUsers BLOCK *********/
5604 if ( can_add_accounts
)
5607 status
= pdb_delete_dom_group(p
->mem_ctx
, group_rid
);
5609 if ( can_add_accounts
)
5612 /******** END SeAddUsers BLOCK *********/
5614 if ( !NT_STATUS_IS_OK(status
) ) {
5615 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5616 "entry for group %s: %s\n",
5617 sid_string_dbg(&group_sid
),
5618 nt_errstr(status
)));
5622 if (!close_policy_hnd(p
, r
->in
.group_handle
))
5623 return NT_STATUS_OBJECT_NAME_INVALID
;
5625 force_flush_samr_cache(disp_info
);
5627 return NT_STATUS_OK
;
5630 /*********************************************************************
5631 _samr_DeleteDomAlias
5632 *********************************************************************/
5634 NTSTATUS
_samr_DeleteDomAlias(pipes_struct
*p
,
5635 struct samr_DeleteDomAlias
*r
)
5640 bool can_add_accounts
;
5642 DISP_INFO
*disp_info
= NULL
;
5644 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__
));
5646 /* Find the policy handle. Open a policy on it. */
5647 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, &disp_info
))
5648 return NT_STATUS_INVALID_HANDLE
;
5650 /* copy the handle to the outgoing reply */
5652 memcpy(r
->out
.alias_handle
, r
->in
.alias_handle
, sizeof(r
->out
.alias_handle
));
5654 status
= access_check_samr_function(acc_granted
,
5655 STD_RIGHT_DELETE_ACCESS
,
5656 "_samr_DeleteDomAlias");
5657 if (!NT_STATUS_IS_OK(status
)) {
5661 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid
)));
5663 /* Don't let Windows delete builtin groups */
5665 if ( sid_check_is_in_builtin( &alias_sid
) ) {
5666 return NT_STATUS_SPECIAL_ACCOUNT
;
5669 if (!sid_check_is_in_our_domain(&alias_sid
))
5670 return NT_STATUS_NO_SUCH_ALIAS
;
5672 DEBUG(10, ("lookup on Local SID\n"));
5674 se_priv_copy( &se_rights
, &se_add_users
);
5675 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5677 /******** BEGIN SeAddUsers BLOCK *********/
5679 if ( can_add_accounts
)
5682 /* Have passdb delete the alias */
5683 status
= pdb_delete_alias(&alias_sid
);
5685 if ( can_add_accounts
)
5688 /******** END SeAddUsers BLOCK *********/
5690 if ( !NT_STATUS_IS_OK(status
))
5693 if (!close_policy_hnd(p
, r
->in
.alias_handle
))
5694 return NT_STATUS_OBJECT_NAME_INVALID
;
5696 force_flush_samr_cache(disp_info
);
5698 return NT_STATUS_OK
;
5701 /*********************************************************************
5702 _samr_CreateDomainGroup
5703 *********************************************************************/
5705 NTSTATUS
_samr_CreateDomainGroup(pipes_struct
*p
,
5706 struct samr_CreateDomainGroup
*r
)
5713 struct samr_info
*info
;
5716 bool can_add_accounts
;
5717 DISP_INFO
*disp_info
= NULL
;
5719 /* Find the policy handle. Open a policy on it. */
5720 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &dom_sid
, &acc_granted
, &disp_info
))
5721 return NT_STATUS_INVALID_HANDLE
;
5723 status
= access_check_samr_function(acc_granted
,
5724 SAMR_DOMAIN_ACCESS_CREATE_GROUP
,
5725 "_samr_CreateDomainGroup");
5726 if (!NT_STATUS_IS_OK(status
)) {
5730 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
5731 return NT_STATUS_ACCESS_DENIED
;
5733 name
= r
->in
.name
->string
;
5735 return NT_STATUS_NO_MEMORY
;
5738 status
= can_create(p
->mem_ctx
, name
);
5739 if (!NT_STATUS_IS_OK(status
)) {
5743 se_priv_copy( &se_rights
, &se_add_users
);
5744 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5746 /******** BEGIN SeAddUsers BLOCK *********/
5748 if ( can_add_accounts
)
5751 /* check that we successfully create the UNIX group */
5753 status
= pdb_create_dom_group(p
->mem_ctx
, name
, r
->out
.rid
);
5755 if ( can_add_accounts
)
5758 /******** END SeAddUsers BLOCK *********/
5760 /* check if we should bail out here */
5762 if ( !NT_STATUS_IS_OK(status
) )
5765 sid_compose(&info_sid
, get_global_sam_sid(), *r
->out
.rid
);
5767 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &info_sid
)) == NULL
)
5768 return NT_STATUS_NO_MEMORY
;
5770 /* they created it; let the user do what he wants with it */
5772 info
->acc_granted
= GENERIC_RIGHTS_GROUP_ALL_ACCESS
;
5774 /* get a (unique) handle. open a policy on it. */
5775 if (!create_policy_hnd(p
, r
->out
.group_handle
, info
))
5776 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5778 force_flush_samr_cache(disp_info
);
5780 return NT_STATUS_OK
;
5783 /*********************************************************************
5784 _samr_CreateDomAlias
5785 *********************************************************************/
5787 NTSTATUS
_samr_CreateDomAlias(pipes_struct
*p
,
5788 struct samr_CreateDomAlias
*r
)
5792 const char *name
= NULL
;
5793 struct samr_info
*info
;
5798 bool can_add_accounts
;
5799 DISP_INFO
*disp_info
= NULL
;
5801 /* Find the policy handle. Open a policy on it. */
5802 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &dom_sid
, &acc_granted
, &disp_info
))
5803 return NT_STATUS_INVALID_HANDLE
;
5805 result
= access_check_samr_function(acc_granted
,
5806 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
,
5807 "_samr_CreateDomAlias");
5808 if (!NT_STATUS_IS_OK(result
)) {
5812 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
5813 return NT_STATUS_ACCESS_DENIED
;
5815 name
= r
->in
.alias_name
->string
;
5817 se_priv_copy( &se_rights
, &se_add_users
);
5818 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5820 result
= can_create(p
->mem_ctx
, name
);
5821 if (!NT_STATUS_IS_OK(result
)) {
5825 /******** BEGIN SeAddUsers BLOCK *********/
5827 if ( can_add_accounts
)
5830 /* Have passdb create the alias */
5831 result
= pdb_create_alias(name
, r
->out
.rid
);
5833 if ( can_add_accounts
)
5836 /******** END SeAddUsers BLOCK *********/
5838 if (!NT_STATUS_IS_OK(result
)) {
5839 DEBUG(10, ("pdb_create_alias failed: %s\n",
5840 nt_errstr(result
)));
5844 sid_copy(&info_sid
, get_global_sam_sid());
5845 sid_append_rid(&info_sid
, *r
->out
.rid
);
5847 if (!sid_to_gid(&info_sid
, &gid
)) {
5848 DEBUG(10, ("Could not find alias just created\n"));
5849 return NT_STATUS_ACCESS_DENIED
;
5852 /* check if the group has been successfully created */
5853 if ( getgrgid(gid
) == NULL
) {
5854 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5856 return NT_STATUS_ACCESS_DENIED
;
5859 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &info_sid
)) == NULL
)
5860 return NT_STATUS_NO_MEMORY
;
5862 /* they created it; let the user do what he wants with it */
5864 info
->acc_granted
= GENERIC_RIGHTS_ALIAS_ALL_ACCESS
;
5866 /* get a (unique) handle. open a policy on it. */
5867 if (!create_policy_hnd(p
, r
->out
.alias_handle
, info
))
5868 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5870 force_flush_samr_cache(disp_info
);
5872 return NT_STATUS_OK
;
5875 /*********************************************************************
5876 _samr_QueryGroupInfo
5877 *********************************************************************/
5879 NTSTATUS
_samr_QueryGroupInfo(pipes_struct
*p
,
5880 struct samr_QueryGroupInfo
*r
)
5885 union samr_GroupInfo
*info
= NULL
;
5888 uint32_t attributes
= SE_GROUP_MANDATORY
|
5889 SE_GROUP_ENABLED_BY_DEFAULT
|
5891 const char *group_name
= NULL
;
5892 const char *group_description
= NULL
;
5894 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, NULL
))
5895 return NT_STATUS_INVALID_HANDLE
;
5897 status
= access_check_samr_function(acc_granted
,
5898 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
5899 "_samr_QueryGroupInfo");
5900 if (!NT_STATUS_IS_OK(status
)) {
5905 ret
= get_domain_group_from_sid(group_sid
, &map
);
5908 return NT_STATUS_INVALID_HANDLE
;
5910 /* FIXME: map contains fstrings */
5911 group_name
= talloc_strdup(r
, map
.nt_name
);
5912 group_description
= talloc_strdup(r
, map
.comment
);
5914 info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_GroupInfo
);
5916 return NT_STATUS_NO_MEMORY
;
5919 switch (r
->in
.level
) {
5925 status
= pdb_enum_group_members(
5926 p
->mem_ctx
, &group_sid
, &members
, &num_members
);
5929 if (!NT_STATUS_IS_OK(status
)) {
5933 info
->all
.name
.string
= group_name
;
5934 info
->all
.attributes
= attributes
;
5935 info
->all
.num_members
= num_members
;
5936 info
->all
.description
.string
= group_description
;
5940 info
->name
.string
= group_name
;
5943 info
->attributes
.attributes
= attributes
;
5946 info
->description
.string
= group_description
;
5956 status = pdb_enum_group_members(
5957 p->mem_ctx, &group_sid, &members, &num_members);
5960 if (!NT_STATUS_IS_OK(status)) {
5964 info
->all2
.name
.string
= group_name
;
5965 info
->all2
.attributes
= attributes
;
5966 info
->all2
.num_members
= 0; /* num_members - in w2k3 this is always 0 */
5967 info
->all2
.description
.string
= group_description
;
5972 return NT_STATUS_INVALID_INFO_CLASS
;
5975 *r
->out
.info
= info
;
5977 return NT_STATUS_OK
;
5980 /*********************************************************************
5982 *********************************************************************/
5984 NTSTATUS
_samr_SetGroupInfo(pipes_struct
*p
,
5985 struct samr_SetGroupInfo
*r
)
5992 bool can_mod_accounts
;
5993 DISP_INFO
*disp_info
= NULL
;
5995 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5996 return NT_STATUS_INVALID_HANDLE
;
5998 status
= access_check_samr_function(acc_granted
,
5999 SAMR_GROUP_ACCESS_SET_INFO
,
6000 "_samr_SetGroupInfo");
6001 if (!NT_STATUS_IS_OK(status
)) {
6006 ret
= get_domain_group_from_sid(group_sid
, &map
);
6009 return NT_STATUS_NO_SUCH_GROUP
;
6011 switch (r
->in
.level
) {
6013 fstrcpy(map
.comment
, r
->in
.info
->all
.description
.string
);
6016 /* group rename is not supported yet */
6017 return NT_STATUS_NOT_SUPPORTED
;
6019 fstrcpy(map
.comment
, r
->in
.info
->description
.string
);
6022 return NT_STATUS_INVALID_INFO_CLASS
;
6025 can_mod_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_add_users
);
6027 /******** BEGIN SeAddUsers BLOCK *********/
6029 if ( can_mod_accounts
)
6032 status
= pdb_update_group_mapping_entry(&map
);
6034 if ( can_mod_accounts
)
6037 /******** End SeAddUsers BLOCK *********/
6039 if (NT_STATUS_IS_OK(status
)) {
6040 force_flush_samr_cache(disp_info
);
6046 /*********************************************************************
6048 *********************************************************************/
6050 NTSTATUS
_samr_SetAliasInfo(pipes_struct
*p
,
6051 struct samr_SetAliasInfo
*r
)
6054 struct acct_info info
;
6056 bool can_mod_accounts
;
6058 DISP_INFO
*disp_info
= NULL
;
6060 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &group_sid
, &acc_granted
, &disp_info
))
6061 return NT_STATUS_INVALID_HANDLE
;
6063 status
= access_check_samr_function(acc_granted
,
6064 SAMR_ALIAS_ACCESS_SET_INFO
,
6065 "_samr_SetAliasInfo");
6066 if (!NT_STATUS_IS_OK(status
)) {
6070 /* get the current group information */
6073 status
= pdb_get_aliasinfo( &group_sid
, &info
);
6076 if ( !NT_STATUS_IS_OK(status
))
6079 switch (r
->in
.level
) {
6084 /* We currently do not support renaming groups in the
6085 the BUILTIN domain. Refer to util_builtin.c to understand
6086 why. The eventually needs to be fixed to be like Windows
6087 where you can rename builtin groups, just not delete them */
6089 if ( sid_check_is_in_builtin( &group_sid
) ) {
6090 return NT_STATUS_SPECIAL_ACCOUNT
;
6093 /* There has to be a valid name (and it has to be different) */
6095 if ( !r
->in
.info
->name
.string
)
6096 return NT_STATUS_INVALID_PARAMETER
;
6098 /* If the name is the same just reply "ok". Yes this
6099 doesn't allow you to change the case of a group name. */
6101 if ( strequal( r
->in
.info
->name
.string
, info
.acct_name
) )
6102 return NT_STATUS_OK
;
6104 fstrcpy( info
.acct_name
, r
->in
.info
->name
.string
);
6106 /* make sure the name doesn't already exist as a user
6109 fstr_sprintf( group_name
, "%s\\%s", global_myname(), info
.acct_name
);
6110 status
= can_create( p
->mem_ctx
, group_name
);
6111 if ( !NT_STATUS_IS_OK( status
) )
6115 case ALIASINFODESCRIPTION
:
6116 if (r
->in
.info
->description
.string
) {
6117 fstrcpy(info
.acct_desc
,
6118 r
->in
.info
->description
.string
);
6120 fstrcpy( info
.acct_desc
, "" );
6124 return NT_STATUS_INVALID_INFO_CLASS
;
6127 can_mod_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_add_users
);
6129 /******** BEGIN SeAddUsers BLOCK *********/
6131 if ( can_mod_accounts
)
6134 status
= pdb_set_aliasinfo( &group_sid
, &info
);
6136 if ( can_mod_accounts
)
6139 /******** End SeAddUsers BLOCK *********/
6141 if (NT_STATUS_IS_OK(status
))
6142 force_flush_samr_cache(disp_info
);
6147 /****************************************************************
6149 ****************************************************************/
6151 NTSTATUS
_samr_GetDomPwInfo(pipes_struct
*p
,
6152 struct samr_GetDomPwInfo
*r
)
6154 uint32_t min_password_length
= 0;
6155 uint32_t password_properties
= 0;
6157 /* Perform access check. Since this rpc does not require a
6158 policy handle it will not be caught by the access checks on
6159 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6161 if (!pipe_access_check(p
)) {
6162 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6163 return NT_STATUS_ACCESS_DENIED
;
6167 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
,
6168 &min_password_length
);
6169 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
6170 &password_properties
);
6173 if (lp_check_password_script() && *lp_check_password_script()) {
6174 password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
6177 r
->out
.info
->min_password_length
= min_password_length
;
6178 r
->out
.info
->password_properties
= password_properties
;
6180 return NT_STATUS_OK
;
6183 /*********************************************************************
6185 *********************************************************************/
6187 NTSTATUS
_samr_OpenGroup(pipes_struct
*p
,
6188 struct samr_OpenGroup
*r
)
6194 struct samr_info
*info
;
6195 SEC_DESC
*psd
= NULL
;
6197 uint32 des_access
= r
->in
.access_mask
;
6204 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
, NULL
))
6205 return NT_STATUS_INVALID_HANDLE
;
6207 status
= access_check_samr_function(acc_granted
,
6208 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
6211 if ( !NT_STATUS_IS_OK(status
) )
6214 /*check if access can be granted as requested by client. */
6215 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
6217 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &grp_generic_mapping
, NULL
, 0);
6218 se_map_generic(&des_access
,&grp_generic_mapping
);
6220 se_priv_copy( &se_rights
, &se_add_users
);
6222 status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
6223 &se_rights
, GENERIC_RIGHTS_GROUP_WRITE
, des_access
,
6224 &acc_granted
, "_samr_OpenGroup");
6226 if ( !NT_STATUS_IS_OK(status
) )
6229 /* this should not be hard-coded like this */
6231 if (!sid_equal(&sid
, get_global_sam_sid()))
6232 return NT_STATUS_ACCESS_DENIED
;
6234 sid_copy(&info_sid
, get_global_sam_sid());
6235 sid_append_rid(&info_sid
, r
->in
.rid
);
6236 sid_to_fstring(sid_string
, &info_sid
);
6238 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &info_sid
)) == NULL
)
6239 return NT_STATUS_NO_MEMORY
;
6241 info
->acc_granted
= acc_granted
;
6243 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string
));
6245 /* check if that group really exists */
6247 ret
= get_domain_group_from_sid(info
->sid
, &map
);
6250 return NT_STATUS_NO_SUCH_GROUP
;
6252 /* get a (unique) handle. open a policy on it. */
6253 if (!create_policy_hnd(p
, r
->out
.group_handle
, info
))
6254 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6256 return NT_STATUS_OK
;
6259 /*********************************************************************
6260 _samr_RemoveMemberFromForeignDomain
6261 *********************************************************************/
6263 NTSTATUS
_samr_RemoveMemberFromForeignDomain(pipes_struct
*p
,
6264 struct samr_RemoveMemberFromForeignDomain
*r
)
6266 DOM_SID delete_sid
, domain_sid
;
6269 DISP_INFO
*disp_info
= NULL
;
6271 sid_copy( &delete_sid
, r
->in
.sid
);
6273 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6274 sid_string_dbg(&delete_sid
)));
6276 /* Find the policy handle. Open a policy on it. */
6278 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &domain_sid
,
6279 &acc_granted
, &disp_info
))
6280 return NT_STATUS_INVALID_HANDLE
;
6282 result
= access_check_samr_function(acc_granted
,
6283 STD_RIGHT_DELETE_ACCESS
,
6284 "_samr_RemoveMemberFromForeignDomain");
6286 if (!NT_STATUS_IS_OK(result
))
6289 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6290 sid_string_dbg(&domain_sid
)));
6292 /* we can only delete a user from a group since we don't have
6293 nested groups anyways. So in the latter case, just say OK */
6295 /* TODO: The above comment nowadays is bogus. Since we have nested
6296 * groups now, and aliases members are never reported out of the unix
6297 * group membership, the "just say OK" makes this call a no-op. For
6298 * us. This needs fixing however. */
6300 /* I've only ever seen this in the wild when deleting a user from
6301 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6302 * is the user about to be deleted. I very much suspect this is the
6303 * only application of this call. To verify this, let people report
6306 if (!sid_check_is_builtin(&domain_sid
)) {
6307 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6308 "global_sam_sid() = %s\n",
6309 sid_string_dbg(&domain_sid
),
6310 sid_string_dbg(get_global_sam_sid())));
6311 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6312 return NT_STATUS_OK
;
6315 force_flush_samr_cache(disp_info
);
6317 result
= NT_STATUS_OK
;
6322 /*******************************************************************
6323 _samr_QueryDomainInfo2
6324 ********************************************************************/
6326 NTSTATUS
_samr_QueryDomainInfo2(pipes_struct
*p
,
6327 struct samr_QueryDomainInfo2
*r
)
6329 struct samr_QueryDomainInfo q
;
6331 q
.in
.domain_handle
= r
->in
.domain_handle
;
6332 q
.in
.level
= r
->in
.level
;
6334 q
.out
.info
= r
->out
.info
;
6336 return _samr_QueryDomainInfo(p
, &q
);
6339 /*******************************************************************
6341 ********************************************************************/
6343 NTSTATUS
_samr_SetDomainInfo(pipes_struct
*p
,
6344 struct samr_SetDomainInfo
*r
)
6346 struct samr_info
*info
= NULL
;
6347 time_t u_expire
, u_min_age
;
6349 time_t u_lock_duration
, u_reset_time
;
6352 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6354 /* find the policy handle. open a policy on it. */
6355 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
6356 return NT_STATUS_INVALID_HANDLE
;
6358 /* We do have different access bits for info
6359 * levels here, but we're really just looking for
6360 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
6361 * this maps to different specific bits. So
6362 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
6365 result
= access_check_samr_function(info
->acc_granted
,
6366 SAMR_DOMAIN_ACCESS_SET_INFO_1
,
6367 "_samr_SetDomainInfo");
6369 if (!NT_STATUS_IS_OK(result
))
6372 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r
->in
.level
));
6374 switch (r
->in
.level
) {
6376 u_expire
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info1
.max_password_age
);
6377 u_min_age
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info1
.min_password_age
);
6378 pdb_set_account_policy(AP_MIN_PASSWORD_LEN
, (uint32
)r
->in
.info
->info1
.min_password_length
);
6379 pdb_set_account_policy(AP_PASSWORD_HISTORY
, (uint32
)r
->in
.info
->info1
.password_history_length
);
6380 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
, (uint32
)r
->in
.info
->info1
.password_properties
);
6381 pdb_set_account_policy(AP_MAX_PASSWORD_AGE
, (int)u_expire
);
6382 pdb_set_account_policy(AP_MIN_PASSWORD_AGE
, (int)u_min_age
);
6385 u_logout
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info3
.force_logoff_time
);
6386 pdb_set_account_policy(AP_TIME_TO_LOGOUT
, (int)u_logout
);
6397 u_lock_duration
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info12
.lockout_duration
);
6398 if (u_lock_duration
!= -1)
6399 u_lock_duration
/= 60;
6401 u_reset_time
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info12
.lockout_window
)/60;
6403 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION
, (int)u_lock_duration
);
6404 pdb_set_account_policy(AP_RESET_COUNT_TIME
, (int)u_reset_time
);
6405 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, (uint32
)r
->in
.info
->info12
.lockout_threshold
);
6408 return NT_STATUS_INVALID_INFO_CLASS
;
6411 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6413 return NT_STATUS_OK
;
6416 /****************************************************************
6417 _samr_GetDisplayEnumerationIndex
6418 ****************************************************************/
6420 NTSTATUS
_samr_GetDisplayEnumerationIndex(pipes_struct
*p
,
6421 struct samr_GetDisplayEnumerationIndex
*r
)
6423 struct samr_info
*info
= NULL
;
6424 uint32_t max_entries
= (uint32_t) -1;
6425 uint32_t enum_context
= 0;
6427 uint32_t num_account
= 0;
6428 struct samr_displayentry
*entries
= NULL
;
6431 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__
));
6433 /* find the policy handle. open a policy on it. */
6434 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
)) {
6435 return NT_STATUS_INVALID_HANDLE
;
6438 status
= access_check_samr_function(info
->acc_granted
,
6439 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
6440 "_samr_GetDisplayEnumerationIndex");
6441 if (!NT_STATUS_IS_OK(status
)) {
6445 if ((r
->in
.level
< 1) || (r
->in
.level
> 3)) {
6446 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6447 "Unknown info level (%u)\n",
6449 return NT_STATUS_INVALID_INFO_CLASS
;
6454 /* The following done as ROOT. Don't return without unbecome_root(). */
6456 switch (r
->in
.level
) {
6458 if (info
->disp_info
->users
== NULL
) {
6459 info
->disp_info
->users
= pdb_search_users(
6460 info
->disp_info
, ACB_NORMAL
);
6461 if (info
->disp_info
->users
== NULL
) {
6463 return NT_STATUS_ACCESS_DENIED
;
6465 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6466 "starting user enumeration at index %u\n",
6467 (unsigned int)enum_context
));
6469 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6470 "using cached user enumeration at index %u\n",
6471 (unsigned int)enum_context
));
6473 num_account
= pdb_search_entries(info
->disp_info
->users
,
6474 enum_context
, max_entries
,
6478 if (info
->disp_info
->machines
== NULL
) {
6479 info
->disp_info
->machines
= pdb_search_users(
6480 info
->disp_info
, ACB_WSTRUST
|ACB_SVRTRUST
);
6481 if (info
->disp_info
->machines
== NULL
) {
6483 return NT_STATUS_ACCESS_DENIED
;
6485 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6486 "starting machine enumeration at index %u\n",
6487 (unsigned int)enum_context
));
6489 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6490 "using cached machine enumeration at index %u\n",
6491 (unsigned int)enum_context
));
6493 num_account
= pdb_search_entries(info
->disp_info
->machines
,
6494 enum_context
, max_entries
,
6498 if (info
->disp_info
->groups
== NULL
) {
6499 info
->disp_info
->groups
= pdb_search_groups(
6501 if (info
->disp_info
->groups
== NULL
) {
6503 return NT_STATUS_ACCESS_DENIED
;
6505 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6506 "starting group enumeration at index %u\n",
6507 (unsigned int)enum_context
));
6509 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6510 "using cached group enumeration at index %u\n",
6511 (unsigned int)enum_context
));
6513 num_account
= pdb_search_entries(info
->disp_info
->groups
,
6514 enum_context
, max_entries
,
6519 smb_panic("info class changed");
6525 /* Ensure we cache this enumeration. */
6526 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
6528 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6529 r
->in
.name
->string
));
6531 for (i
=0; i
<num_account
; i
++) {
6532 if (strequal(entries
[i
].account_name
, r
->in
.name
->string
)) {
6533 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6534 "found %s at idx %d\n",
6535 r
->in
.name
->string
, i
));
6537 return NT_STATUS_OK
;
6541 /* assuming account_name lives at the very end */
6542 *r
->out
.idx
= num_account
;
6544 return NT_STATUS_NO_MORE_ENTRIES
;
6547 /****************************************************************
6548 _samr_GetDisplayEnumerationIndex2
6549 ****************************************************************/
6551 NTSTATUS
_samr_GetDisplayEnumerationIndex2(pipes_struct
*p
,
6552 struct samr_GetDisplayEnumerationIndex2
*r
)
6554 struct samr_GetDisplayEnumerationIndex q
;
6556 q
.in
.domain_handle
= r
->in
.domain_handle
;
6557 q
.in
.level
= r
->in
.level
;
6558 q
.in
.name
= r
->in
.name
;
6560 q
.out
.idx
= r
->out
.idx
;
6562 return _samr_GetDisplayEnumerationIndex(p
, &q
);
6565 /****************************************************************
6566 ****************************************************************/
6568 NTSTATUS
_samr_Shutdown(pipes_struct
*p
,
6569 struct samr_Shutdown
*r
)
6571 p
->rng_fault_state
= true;
6572 return NT_STATUS_NOT_IMPLEMENTED
;
6575 /****************************************************************
6576 ****************************************************************/
6578 NTSTATUS
_samr_SetMemberAttributesOfGroup(pipes_struct
*p
,
6579 struct samr_SetMemberAttributesOfGroup
*r
)
6581 p
->rng_fault_state
= true;
6582 return NT_STATUS_NOT_IMPLEMENTED
;
6585 /****************************************************************
6586 ****************************************************************/
6588 NTSTATUS
_samr_TestPrivateFunctionsDomain(pipes_struct
*p
,
6589 struct samr_TestPrivateFunctionsDomain
*r
)
6591 p
->rng_fault_state
= true;
6592 return NT_STATUS_NOT_IMPLEMENTED
;
6595 /****************************************************************
6596 ****************************************************************/
6598 NTSTATUS
_samr_TestPrivateFunctionsUser(pipes_struct
*p
,
6599 struct samr_TestPrivateFunctionsUser
*r
)
6601 return NT_STATUS_NOT_IMPLEMENTED
;
6604 /****************************************************************
6605 ****************************************************************/
6607 NTSTATUS
_samr_AddMultipleMembersToAlias(pipes_struct
*p
,
6608 struct samr_AddMultipleMembersToAlias
*r
)
6610 p
->rng_fault_state
= true;
6611 return NT_STATUS_NOT_IMPLEMENTED
;
6614 /****************************************************************
6615 ****************************************************************/
6617 NTSTATUS
_samr_RemoveMultipleMembersFromAlias(pipes_struct
*p
,
6618 struct samr_RemoveMultipleMembersFromAlias
*r
)
6620 p
->rng_fault_state
= true;
6621 return NT_STATUS_NOT_IMPLEMENTED
;
6624 /****************************************************************
6625 ****************************************************************/
6627 NTSTATUS
_samr_SetBootKeyInformation(pipes_struct
*p
,
6628 struct samr_SetBootKeyInformation
*r
)
6630 p
->rng_fault_state
= true;
6631 return NT_STATUS_NOT_IMPLEMENTED
;
6634 /****************************************************************
6635 ****************************************************************/
6637 NTSTATUS
_samr_GetBootKeyInformation(pipes_struct
*p
,
6638 struct samr_GetBootKeyInformation
*r
)
6640 p
->rng_fault_state
= true;
6641 return NT_STATUS_NOT_IMPLEMENTED
;
6644 /****************************************************************
6645 ****************************************************************/
6647 NTSTATUS
_samr_RidToSid(pipes_struct
*p
,
6648 struct samr_RidToSid
*r
)
6650 p
->rng_fault_state
= true;
6651 return NT_STATUS_NOT_IMPLEMENTED
;
6654 /****************************************************************
6655 ****************************************************************/
6657 NTSTATUS
_samr_SetDsrmPassword(pipes_struct
*p
,
6658 struct samr_SetDsrmPassword
*r
)
6660 p
->rng_fault_state
= true;
6661 return NT_STATUS_NOT_IMPLEMENTED
;
6664 /****************************************************************
6665 ****************************************************************/
6667 NTSTATUS
_samr_ValidatePassword(pipes_struct
*p
,
6668 struct samr_ValidatePassword
*r
)
6670 p
->rng_fault_state
= true;
6671 return NT_STATUS_NOT_IMPLEMENTED
;