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.
35 #include "../libcli/auth/libcli_auth.h"
38 #define DBGC_CLASS DBGC_RPC_SRV
40 #define SAMR_USR_RIGHTS_WRITE_PW \
41 ( READ_CONTROL_ACCESS | \
42 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
43 SAMR_USER_ACCESS_SET_LOC_COM)
44 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
45 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
47 #define DISP_INFO_CACHE_TIMEOUT 10
49 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
50 #define MAX_SAM_ENTRIES_W95 50
52 struct samr_connect_info
{
56 struct samr_domain_info
{
58 struct disp_info
*disp_info
;
61 struct samr_user_info
{
65 struct samr_group_info
{
69 struct samr_alias_info
{
73 typedef struct disp_info
{
74 DOM_SID sid
; /* identify which domain this is. */
75 struct pdb_search
*users
; /* querydispinfo 1 and 4 */
76 struct pdb_search
*machines
; /* querydispinfo 2 */
77 struct pdb_search
*groups
; /* querydispinfo 3 and 5, enumgroups */
78 struct pdb_search
*aliases
; /* enumaliases */
81 struct pdb_search
*enum_users
; /* enumusers with a mask */
83 struct timed_event
*cache_timeout_event
; /* cache idle timeout
87 static const struct generic_mapping sam_generic_mapping
= {
88 GENERIC_RIGHTS_SAM_READ
,
89 GENERIC_RIGHTS_SAM_WRITE
,
90 GENERIC_RIGHTS_SAM_EXECUTE
,
91 GENERIC_RIGHTS_SAM_ALL_ACCESS
};
92 static const struct generic_mapping dom_generic_mapping
= {
93 GENERIC_RIGHTS_DOMAIN_READ
,
94 GENERIC_RIGHTS_DOMAIN_WRITE
,
95 GENERIC_RIGHTS_DOMAIN_EXECUTE
,
96 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS
};
97 static const struct generic_mapping usr_generic_mapping
= {
98 GENERIC_RIGHTS_USER_READ
,
99 GENERIC_RIGHTS_USER_WRITE
,
100 GENERIC_RIGHTS_USER_EXECUTE
,
101 GENERIC_RIGHTS_USER_ALL_ACCESS
};
102 static const struct generic_mapping usr_nopwchange_generic_mapping
= {
103 GENERIC_RIGHTS_USER_READ
,
104 GENERIC_RIGHTS_USER_WRITE
,
105 GENERIC_RIGHTS_USER_EXECUTE
& ~SAMR_USER_ACCESS_CHANGE_PASSWORD
,
106 GENERIC_RIGHTS_USER_ALL_ACCESS
};
107 static const struct generic_mapping grp_generic_mapping
= {
108 GENERIC_RIGHTS_GROUP_READ
,
109 GENERIC_RIGHTS_GROUP_WRITE
,
110 GENERIC_RIGHTS_GROUP_EXECUTE
,
111 GENERIC_RIGHTS_GROUP_ALL_ACCESS
};
112 static const struct generic_mapping ali_generic_mapping
= {
113 GENERIC_RIGHTS_ALIAS_READ
,
114 GENERIC_RIGHTS_ALIAS_WRITE
,
115 GENERIC_RIGHTS_ALIAS_EXECUTE
,
116 GENERIC_RIGHTS_ALIAS_ALL_ACCESS
};
118 /*******************************************************************
119 *******************************************************************/
121 static NTSTATUS
make_samr_object_sd( TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
,
122 const struct generic_mapping
*map
,
123 DOM_SID
*sid
, uint32 sid_access
)
125 DOM_SID domadmin_sid
;
126 SEC_ACE ace
[5]; /* at most 5 entries */
131 /* basic access for Everyone */
133 init_sec_ace(&ace
[i
++], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
134 map
->generic_execute
| map
->generic_read
, 0);
136 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
138 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Administrators
,
139 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
140 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Account_Operators
,
141 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
143 /* Add Full Access for Domain Admins if we are a DC */
146 sid_copy( &domadmin_sid
, get_global_sam_sid() );
147 sid_append_rid( &domadmin_sid
, DOMAIN_GROUP_RID_ADMINS
);
148 init_sec_ace(&ace
[i
++], &domadmin_sid
,
149 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
152 /* if we have a sid, give it some special access */
155 init_sec_ace(&ace
[i
++], sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, sid_access
, 0);
158 /* create the security descriptor */
160 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, i
, ace
)) == NULL
)
161 return NT_STATUS_NO_MEMORY
;
163 if ((*psd
= make_sec_desc(ctx
, SECURITY_DESCRIPTOR_REVISION_1
,
164 SEC_DESC_SELF_RELATIVE
, NULL
, NULL
, NULL
,
165 psa
, sd_size
)) == NULL
)
166 return NT_STATUS_NO_MEMORY
;
171 /*******************************************************************
172 Checks if access to an object should be granted, and returns that
173 level of access for further checks.
174 ********************************************************************/
176 static NTSTATUS
access_check_samr_object( SEC_DESC
*psd
, NT_USER_TOKEN
*token
,
177 SE_PRIV
*rights
, uint32 rights_mask
,
178 uint32 des_access
, uint32
*acc_granted
,
181 NTSTATUS status
= NT_STATUS_ACCESS_DENIED
;
182 uint32 saved_mask
= 0;
184 /* check privileges; certain SAM access bits should be overridden
185 by privileges (mostly having to do with creating/modifying/deleting
188 if (rights
&& !se_priv_equal(rights
, &se_priv_none
) &&
189 user_has_any_privilege(token
, rights
)) {
191 saved_mask
= (des_access
& rights_mask
);
192 des_access
&= ~saved_mask
;
194 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
199 /* check the security descriptor first */
201 status
= se_access_check(psd
, token
, des_access
, acc_granted
);
202 if (NT_STATUS_IS_OK(status
)) {
206 /* give root a free pass */
208 if ( geteuid() == sec_initial_uid() ) {
210 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug
, des_access
));
211 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
213 *acc_granted
= des_access
;
215 status
= NT_STATUS_OK
;
221 /* add in any bits saved during the privilege check (only
222 matters is status is ok) */
224 *acc_granted
|= rights_mask
;
226 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
227 debug
, NT_STATUS_IS_OK(status
) ? "GRANTED" : "DENIED",
228 des_access
, *acc_granted
));
234 /*******************************************************************
235 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
236 ********************************************************************/
238 static void map_max_allowed_access(const NT_USER_TOKEN
*token
,
239 uint32_t *pacc_requested
)
241 if (!((*pacc_requested
) & MAXIMUM_ALLOWED_ACCESS
)) {
244 *pacc_requested
&= ~MAXIMUM_ALLOWED_ACCESS
;
246 /* At least try for generic read. */
247 *pacc_requested
= GENERIC_READ_ACCESS
;
249 /* root gets anything. */
250 if (geteuid() == sec_initial_uid()) {
251 *pacc_requested
|= GENERIC_ALL_ACCESS
;
255 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
257 if (is_sid_in_token(token
, &global_sid_Builtin_Administrators
) ||
258 is_sid_in_token(token
, &global_sid_Builtin_Account_Operators
)) {
259 *pacc_requested
|= GENERIC_ALL_ACCESS
;
263 /* Full access for DOMAIN\Domain Admins. */
265 DOM_SID domadmin_sid
;
266 sid_copy( &domadmin_sid
, get_global_sam_sid() );
267 sid_append_rid( &domadmin_sid
, DOMAIN_GROUP_RID_ADMINS
);
268 if (is_sid_in_token(token
, &domadmin_sid
)) {
269 *pacc_requested
|= GENERIC_ALL_ACCESS
;
273 /* TODO ! Check privileges. */
276 /*******************************************************************
277 Fetch or create a dispinfo struct.
278 ********************************************************************/
280 static DISP_INFO
*get_samr_dispinfo_by_sid(const struct dom_sid
*psid
)
283 * We do a static cache for DISP_INFO's here. Explanation can be found
284 * in Jeremy's checkin message to r11793:
286 * Fix the SAMR cache so it works across completely insane
287 * client behaviour (ie.:
288 * open pipe/open SAMR handle/enumerate 0 - 1024
289 * close SAMR handle, close pipe.
290 * open pipe/open SAMR handle/enumerate 1024 - 2048...
291 * close SAMR handle, close pipe.
292 * And on ad-nausium. Amazing.... probably object-oriented
293 * client side programming in action yet again.
294 * This change should *massively* improve performance when
295 * enumerating users from an LDAP database.
298 * "Our" and the builtin domain are the only ones where we ever
299 * enumerate stuff, so just cache 2 entries.
302 static struct disp_info
*builtin_dispinfo
;
303 static struct disp_info
*domain_dispinfo
;
305 /* There are two cases to consider here:
306 1) The SID is a domain SID and we look for an equality match, or
307 2) This is an account SID and so we return the DISP_INFO* for our
314 if (sid_check_is_builtin(psid
) || sid_check_is_in_builtin(psid
)) {
316 * Necessary only once, but it does not really hurt.
318 if (builtin_dispinfo
== NULL
) {
319 builtin_dispinfo
= talloc_zero(
320 talloc_autofree_context(), struct disp_info
);
321 if (builtin_dispinfo
== NULL
) {
325 sid_copy(&builtin_dispinfo
->sid
, &global_sid_Builtin
);
327 return builtin_dispinfo
;
330 if (sid_check_is_domain(psid
) || sid_check_is_in_our_domain(psid
)) {
332 * Necessary only once, but it does not really hurt.
334 if (domain_dispinfo
== NULL
) {
335 domain_dispinfo
= talloc_zero(
336 talloc_autofree_context(), struct disp_info
);
337 if (domain_dispinfo
== NULL
) {
341 sid_copy(&domain_dispinfo
->sid
, get_global_sam_sid());
343 return domain_dispinfo
;
349 /*******************************************************************
350 Function to free the per SID data.
351 ********************************************************************/
353 static void free_samr_cache(DISP_INFO
*disp_info
)
355 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
356 sid_string_dbg(&disp_info
->sid
)));
358 /* We need to become root here because the paged search might have to
359 * tell the LDAP server we're not interested in the rest anymore. */
363 TALLOC_FREE(disp_info
->users
);
364 TALLOC_FREE(disp_info
->machines
);
365 TALLOC_FREE(disp_info
->groups
);
366 TALLOC_FREE(disp_info
->aliases
);
367 TALLOC_FREE(disp_info
->enum_users
);
372 /*******************************************************************
373 Idle event handler. Throw away the disp info cache.
374 ********************************************************************/
376 static void disp_info_cache_idle_timeout_handler(struct event_context
*ev_ctx
,
377 struct timed_event
*te
,
381 DISP_INFO
*disp_info
= (DISP_INFO
*)private_data
;
383 TALLOC_FREE(disp_info
->cache_timeout_event
);
385 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
387 free_samr_cache(disp_info
);
390 /*******************************************************************
391 Setup cache removal idle event handler.
392 ********************************************************************/
394 static void set_disp_info_cache_timeout(DISP_INFO
*disp_info
, time_t secs_fromnow
)
396 /* Remove any pending timeout and update. */
398 TALLOC_FREE(disp_info
->cache_timeout_event
);
400 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
401 "SID %s for %u seconds\n", sid_string_dbg(&disp_info
->sid
),
402 (unsigned int)secs_fromnow
));
404 disp_info
->cache_timeout_event
= event_add_timed(
405 smbd_event_context(), NULL
,
406 timeval_current_ofs(secs_fromnow
, 0),
407 disp_info_cache_idle_timeout_handler
, (void *)disp_info
);
410 /*******************************************************************
411 Force flush any cache. We do this on any samr_set_xxx call.
412 We must also remove the timeout handler.
413 ********************************************************************/
415 static void force_flush_samr_cache(const struct dom_sid
*sid
)
417 struct disp_info
*disp_info
= get_samr_dispinfo_by_sid(sid
);
419 if ((disp_info
== NULL
) || (disp_info
->cache_timeout_event
== NULL
)) {
423 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
424 TALLOC_FREE(disp_info
->cache_timeout_event
);
425 free_samr_cache(disp_info
);
428 /*******************************************************************
429 Ensure password info is never given out. Paranioa... JRA.
430 ********************************************************************/
432 static void samr_clear_sam_passwd(struct samu
*sam_pass
)
438 /* These now zero out the old password */
440 pdb_set_lanman_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
441 pdb_set_nt_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
444 static uint32
count_sam_users(struct disp_info
*info
, uint32 acct_flags
)
446 struct samr_displayentry
*entry
;
448 if (sid_check_is_builtin(&info
->sid
)) {
449 /* No users in builtin. */
453 if (info
->users
== NULL
) {
454 info
->users
= pdb_search_users(info
, acct_flags
);
455 if (info
->users
== NULL
) {
459 /* Fetch the last possible entry, thus trigger an enumeration */
460 pdb_search_entries(info
->users
, 0xffffffff, 1, &entry
);
462 /* Ensure we cache this enumeration. */
463 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
465 return info
->users
->num_entries
;
468 static uint32
count_sam_groups(struct disp_info
*info
)
470 struct samr_displayentry
*entry
;
472 if (sid_check_is_builtin(&info
->sid
)) {
473 /* No groups in builtin. */
477 if (info
->groups
== NULL
) {
478 info
->groups
= pdb_search_groups(info
);
479 if (info
->groups
== NULL
) {
483 /* Fetch the last possible entry, thus trigger an enumeration */
484 pdb_search_entries(info
->groups
, 0xffffffff, 1, &entry
);
486 /* Ensure we cache this enumeration. */
487 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
489 return info
->groups
->num_entries
;
492 static uint32
count_sam_aliases(struct disp_info
*info
)
494 struct samr_displayentry
*entry
;
496 if (info
->aliases
== NULL
) {
497 info
->aliases
= pdb_search_aliases(info
, &info
->sid
);
498 if (info
->aliases
== NULL
) {
502 /* Fetch the last possible entry, thus trigger an enumeration */
503 pdb_search_entries(info
->aliases
, 0xffffffff, 1, &entry
);
505 /* Ensure we cache this enumeration. */
506 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
508 return info
->aliases
->num_entries
;
511 /*******************************************************************
513 ********************************************************************/
515 NTSTATUS
_samr_Close(pipes_struct
*p
, struct samr_Close
*r
)
517 if (!close_policy_hnd(p
, r
->in
.handle
)) {
518 return NT_STATUS_INVALID_HANDLE
;
521 ZERO_STRUCTP(r
->out
.handle
);
526 /*******************************************************************
528 ********************************************************************/
530 NTSTATUS
_samr_OpenDomain(pipes_struct
*p
,
531 struct samr_OpenDomain
*r
)
533 struct samr_connect_info
*cinfo
;
534 struct samr_domain_info
*dinfo
;
535 SEC_DESC
*psd
= NULL
;
537 uint32 des_access
= r
->in
.access_mask
;
540 uint32_t extra_access
= SAMR_DOMAIN_ACCESS_CREATE_USER
;
543 /* find the connection policy handle. */
545 cinfo
= policy_handle_find(p
, r
->in
.connect_handle
, 0, NULL
,
546 struct samr_connect_info
, &status
);
547 if (!NT_STATUS_IS_OK(status
)) {
551 /*check if access can be granted as requested by client. */
552 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
554 make_samr_object_sd( p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0 );
555 se_map_generic( &des_access
, &dom_generic_mapping
);
558 * Users with SeMachineAccount or SeAddUser get additional
559 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
561 se_priv_copy( &se_rights
, &se_machine_account
);
562 se_priv_add( &se_rights
, &se_add_users
);
565 * Users with SeAddUser get the ability to manipulate groups
568 if (user_has_any_privilege(p
->server_info
->ptok
, &se_add_users
)) {
569 extra_access
|= (SAMR_DOMAIN_ACCESS_CREATE_GROUP
|
570 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
571 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
572 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
|
573 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
);
576 status
= access_check_samr_object( psd
, p
->server_info
->ptok
,
577 &se_rights
, extra_access
, des_access
,
578 &acc_granted
, "_samr_OpenDomain" );
580 if ( !NT_STATUS_IS_OK(status
) )
583 if (!sid_check_is_domain(r
->in
.sid
) &&
584 !sid_check_is_builtin(r
->in
.sid
)) {
585 return NT_STATUS_NO_SUCH_DOMAIN
;
588 dinfo
= policy_handle_create(p
, r
->out
.domain_handle
, acc_granted
,
589 struct samr_domain_info
, &status
);
590 if (!NT_STATUS_IS_OK(status
)) {
593 dinfo
->sid
= *r
->in
.sid
;
594 dinfo
->disp_info
= get_samr_dispinfo_by_sid(r
->in
.sid
);
596 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__
));
601 /*******************************************************************
603 ********************************************************************/
605 NTSTATUS
_samr_GetUserPwInfo(pipes_struct
*p
,
606 struct samr_GetUserPwInfo
*r
)
608 struct samr_user_info
*uinfo
;
609 enum lsa_SidType sid_type
;
610 uint32_t min_password_length
= 0;
611 uint32_t password_properties
= 0;
615 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__
));
617 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
618 SAMR_USER_ACCESS_GET_ATTRIBUTES
, NULL
,
619 struct samr_user_info
, &status
);
620 if (!NT_STATUS_IS_OK(status
)) {
624 if (!sid_check_is_in_our_domain(&uinfo
->sid
)) {
625 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
629 ret
= lookup_sid(p
->mem_ctx
, &uinfo
->sid
, NULL
, NULL
, &sid_type
);
632 return NT_STATUS_NO_SUCH_USER
;
638 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
,
639 &min_password_length
);
640 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
641 &password_properties
);
644 if (lp_check_password_script() && *lp_check_password_script()) {
645 password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
653 r
->out
.info
->min_password_length
= min_password_length
;
654 r
->out
.info
->password_properties
= password_properties
;
656 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__
));
661 /*******************************************************************
663 ********************************************************************/
665 NTSTATUS
_samr_SetSecurity(pipes_struct
*p
,
666 struct samr_SetSecurity
*r
)
668 struct samr_user_info
*uinfo
;
672 struct samu
*sampass
=NULL
;
675 uinfo
= policy_handle_find(p
, r
->in
.handle
,
676 SAMR_USER_ACCESS_SET_ATTRIBUTES
, NULL
,
677 struct samr_user_info
, &status
);
678 if (!NT_STATUS_IS_OK(status
)) {
682 if (!(sampass
= samu_new( p
->mem_ctx
))) {
683 DEBUG(0,("No memory!\n"));
684 return NT_STATUS_NO_MEMORY
;
687 /* get the user record */
689 ret
= pdb_getsampwsid(sampass
, &uinfo
->sid
);
693 DEBUG(4, ("User %s not found\n",
694 sid_string_dbg(&uinfo
->sid
)));
695 TALLOC_FREE(sampass
);
696 return NT_STATUS_INVALID_HANDLE
;
699 dacl
= r
->in
.sdbuf
->sd
->dacl
;
700 for (i
=0; i
< dacl
->num_aces
; i
++) {
701 if (sid_equal(&uinfo
->sid
, &dacl
->aces
[i
].trustee
)) {
702 ret
= pdb_set_pass_can_change(sampass
,
703 (dacl
->aces
[i
].access_mask
&
704 SAMR_USER_ACCESS_CHANGE_PASSWORD
) ?
711 TALLOC_FREE(sampass
);
712 return NT_STATUS_ACCESS_DENIED
;
716 status
= pdb_update_sam_account(sampass
);
719 TALLOC_FREE(sampass
);
724 /*******************************************************************
725 build correct perms based on policies and password times for _samr_query_sec_obj
726 *******************************************************************/
727 static bool check_change_pw_access(TALLOC_CTX
*mem_ctx
, DOM_SID
*user_sid
)
729 struct samu
*sampass
=NULL
;
732 if ( !(sampass
= samu_new( mem_ctx
)) ) {
733 DEBUG(0,("No memory!\n"));
738 ret
= pdb_getsampwsid(sampass
, user_sid
);
742 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid
)));
743 TALLOC_FREE(sampass
);
747 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
749 if (pdb_get_pass_can_change(sampass
)) {
750 TALLOC_FREE(sampass
);
753 TALLOC_FREE(sampass
);
758 /*******************************************************************
760 ********************************************************************/
762 NTSTATUS
_samr_QuerySecurity(pipes_struct
*p
,
763 struct samr_QuerySecurity
*r
)
765 struct samr_connect_info
*cinfo
;
766 struct samr_domain_info
*dinfo
;
767 struct samr_user_info
*uinfo
;
768 struct samr_group_info
*ginfo
;
769 struct samr_alias_info
*ainfo
;
771 SEC_DESC
* psd
= NULL
;
774 cinfo
= policy_handle_find(p
, r
->in
.handle
,
775 STD_RIGHT_READ_CONTROL_ACCESS
, NULL
,
776 struct samr_connect_info
, &status
);
777 if (NT_STATUS_IS_OK(status
)) {
778 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
779 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
780 &sam_generic_mapping
, NULL
, 0);
784 dinfo
= policy_handle_find(p
, r
->in
.handle
,
785 STD_RIGHT_READ_CONTROL_ACCESS
, NULL
,
786 struct samr_domain_info
, &status
);
787 if (NT_STATUS_IS_OK(status
)) {
788 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
789 "with SID: %s\n", sid_string_dbg(&dinfo
->sid
)));
791 * TODO: Builtin probably needs a different SD with restricted
794 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
795 &dom_generic_mapping
, NULL
, 0);
799 uinfo
= policy_handle_find(p
, r
->in
.handle
,
800 STD_RIGHT_READ_CONTROL_ACCESS
, NULL
,
801 struct samr_user_info
, &status
);
802 if (NT_STATUS_IS_OK(status
)) {
803 DEBUG(10,("_samr_QuerySecurity: querying security on user "
804 "Object with SID: %s\n",
805 sid_string_dbg(&uinfo
->sid
)));
806 if (check_change_pw_access(p
->mem_ctx
, &uinfo
->sid
)) {
807 status
= make_samr_object_sd(
808 p
->mem_ctx
, &psd
, &sd_size
,
809 &usr_generic_mapping
,
810 &uinfo
->sid
, SAMR_USR_RIGHTS_WRITE_PW
);
812 status
= make_samr_object_sd(
813 p
->mem_ctx
, &psd
, &sd_size
,
814 &usr_nopwchange_generic_mapping
,
815 &uinfo
->sid
, SAMR_USR_RIGHTS_CANT_WRITE_PW
);
820 ginfo
= policy_handle_find(p
, r
->in
.handle
,
821 STD_RIGHT_READ_CONTROL_ACCESS
, NULL
,
822 struct samr_group_info
, &status
);
823 if (NT_STATUS_IS_OK(status
)) {
825 * TODO: different SDs have to be generated for aliases groups
826 * and users. Currently all three get a default user SD
828 DEBUG(10,("_samr_QuerySecurity: querying security on group "
829 "Object with SID: %s\n",
830 sid_string_dbg(&ginfo
->sid
)));
831 status
= make_samr_object_sd(
832 p
->mem_ctx
, &psd
, &sd_size
,
833 &usr_nopwchange_generic_mapping
,
834 &ginfo
->sid
, SAMR_USR_RIGHTS_CANT_WRITE_PW
);
838 ainfo
= policy_handle_find(p
, r
->in
.handle
,
839 STD_RIGHT_READ_CONTROL_ACCESS
, NULL
,
840 struct samr_alias_info
, &status
);
841 if (NT_STATUS_IS_OK(status
)) {
843 * TODO: different SDs have to be generated for aliases groups
844 * and users. Currently all three get a default user SD
846 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
847 "Object with SID: %s\n",
848 sid_string_dbg(&ainfo
->sid
)));
849 status
= make_samr_object_sd(
850 p
->mem_ctx
, &psd
, &sd_size
,
851 &usr_nopwchange_generic_mapping
,
852 &ainfo
->sid
, SAMR_USR_RIGHTS_CANT_WRITE_PW
);
856 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
858 if ((*r
->out
.sdbuf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
859 return NT_STATUS_NO_MEMORY
;
864 /*******************************************************************
865 makes a SAM_ENTRY / UNISTR2* structure from a user list.
866 ********************************************************************/
868 static NTSTATUS
make_user_sam_entry_list(TALLOC_CTX
*ctx
,
869 struct samr_SamEntry
**sam_pp
,
870 uint32_t num_entries
,
872 struct samr_displayentry
*entries
)
875 struct samr_SamEntry
*sam
;
879 if (num_entries
== 0) {
883 sam
= TALLOC_ZERO_ARRAY(ctx
, struct samr_SamEntry
, num_entries
);
885 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
886 return NT_STATUS_NO_MEMORY
;
889 for (i
= 0; i
< num_entries
; i
++) {
892 * usrmgr expects a non-NULL terminated string with
893 * trust relationships
895 if (entries
[i
].acct_flags
& ACB_DOMTRUST
) {
896 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
899 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
903 init_lsa_String(&sam
[i
].name
, entries
[i
].account_name
);
904 sam
[i
].idx
= entries
[i
].rid
;
912 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
914 /*******************************************************************
915 _samr_EnumDomainUsers
916 ********************************************************************/
918 NTSTATUS
_samr_EnumDomainUsers(pipes_struct
*p
,
919 struct samr_EnumDomainUsers
*r
)
922 struct samr_domain_info
*dinfo
;
924 uint32 enum_context
= *r
->in
.resume_handle
;
925 enum remote_arch_types ra_type
= get_remote_arch();
926 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
927 uint32 max_entries
= max_sam_entries
;
928 struct samr_displayentry
*entries
= NULL
;
929 struct samr_SamArray
*samr_array
= NULL
;
930 struct samr_SamEntry
*samr_entries
= NULL
;
932 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__
));
934 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
935 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
936 struct samr_domain_info
, &status
);
937 if (!NT_STATUS_IS_OK(status
)) {
941 if (sid_check_is_builtin(&dinfo
->sid
)) {
942 /* No users in builtin. */
943 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
944 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
948 samr_array
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
950 return NT_STATUS_NO_MEMORY
;
952 *r
->out
.sam
= samr_array
;
958 if ((dinfo
->disp_info
->enum_users
!= NULL
) &&
959 (dinfo
->disp_info
->enum_acb_mask
!= r
->in
.acct_flags
)) {
960 TALLOC_FREE(dinfo
->disp_info
->enum_users
);
963 if (dinfo
->disp_info
->enum_users
== NULL
) {
964 dinfo
->disp_info
->enum_users
= pdb_search_users(
965 dinfo
->disp_info
, r
->in
.acct_flags
);
966 dinfo
->disp_info
->enum_acb_mask
= r
->in
.acct_flags
;
969 if (dinfo
->disp_info
->enum_users
== NULL
) {
970 /* END AS ROOT !!!! */
972 return NT_STATUS_ACCESS_DENIED
;
975 num_account
= pdb_search_entries(dinfo
->disp_info
->enum_users
,
976 enum_context
, max_entries
,
979 /* END AS ROOT !!!! */
983 if (num_account
== 0) {
984 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
986 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
990 status
= make_user_sam_entry_list(p
->mem_ctx
, &samr_entries
,
991 num_account
, enum_context
,
993 if (!NT_STATUS_IS_OK(status
)) {
997 if (max_entries
<= num_account
) {
998 status
= STATUS_MORE_ENTRIES
;
1000 status
= NT_STATUS_OK
;
1003 /* Ensure we cache this enumeration. */
1004 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1006 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__
));
1008 samr_array
->count
= num_account
;
1009 samr_array
->entries
= samr_entries
;
1011 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ num_account
;
1012 *r
->out
.num_entries
= num_account
;
1014 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__
));
1019 /*******************************************************************
1020 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1021 ********************************************************************/
1023 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
,
1024 struct samr_SamEntry
**sam_pp
,
1025 uint32_t num_sam_entries
,
1026 struct samr_displayentry
*entries
)
1028 struct samr_SamEntry
*sam
;
1033 if (num_sam_entries
== 0) {
1037 sam
= TALLOC_ZERO_ARRAY(ctx
, struct samr_SamEntry
, num_sam_entries
);
1042 for (i
= 0; i
< num_sam_entries
; i
++) {
1044 * JRA. I think this should include the null. TNG does not.
1046 init_lsa_String(&sam
[i
].name
, entries
[i
].account_name
);
1047 sam
[i
].idx
= entries
[i
].rid
;
1053 /*******************************************************************
1054 _samr_EnumDomainGroups
1055 ********************************************************************/
1057 NTSTATUS
_samr_EnumDomainGroups(pipes_struct
*p
,
1058 struct samr_EnumDomainGroups
*r
)
1061 struct samr_domain_info
*dinfo
;
1062 struct samr_displayentry
*groups
;
1064 struct samr_SamArray
*samr_array
= NULL
;
1065 struct samr_SamEntry
*samr_entries
= NULL
;
1067 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
1068 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
1069 struct samr_domain_info
, &status
);
1070 if (!NT_STATUS_IS_OK(status
)) {
1074 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__
));
1076 if (sid_check_is_builtin(&dinfo
->sid
)) {
1077 /* No groups in builtin. */
1078 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
1079 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1083 samr_array
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
1085 return NT_STATUS_NO_MEMORY
;
1088 /* the domain group array is being allocated in the function below */
1092 if (dinfo
->disp_info
->groups
== NULL
) {
1093 dinfo
->disp_info
->groups
= pdb_search_groups(dinfo
->disp_info
);
1095 if (dinfo
->disp_info
->groups
== NULL
) {
1097 return NT_STATUS_ACCESS_DENIED
;
1101 num_groups
= pdb_search_entries(dinfo
->disp_info
->groups
,
1102 *r
->in
.resume_handle
,
1103 MAX_SAM_ENTRIES
, &groups
);
1106 /* Ensure we cache this enumeration. */
1107 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1109 make_group_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1110 num_groups
, groups
);
1112 samr_array
->count
= num_groups
;
1113 samr_array
->entries
= samr_entries
;
1115 *r
->out
.sam
= samr_array
;
1116 *r
->out
.num_entries
= num_groups
;
1117 *r
->out
.resume_handle
= num_groups
+ *r
->in
.resume_handle
;
1119 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__
));
1124 /*******************************************************************
1125 _samr_EnumDomainAliases
1126 ********************************************************************/
1128 NTSTATUS
_samr_EnumDomainAliases(pipes_struct
*p
,
1129 struct samr_EnumDomainAliases
*r
)
1132 struct samr_domain_info
*dinfo
;
1133 struct samr_displayentry
*aliases
;
1134 uint32 num_aliases
= 0;
1135 struct samr_SamArray
*samr_array
= NULL
;
1136 struct samr_SamEntry
*samr_entries
= NULL
;
1138 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
1139 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
1140 struct samr_domain_info
, &status
);
1141 if (!NT_STATUS_IS_OK(status
)) {
1145 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1146 sid_string_dbg(&dinfo
->sid
)));
1148 samr_array
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
1150 return NT_STATUS_NO_MEMORY
;
1155 if (dinfo
->disp_info
->aliases
== NULL
) {
1156 dinfo
->disp_info
->aliases
= pdb_search_aliases(
1157 dinfo
->disp_info
, &dinfo
->sid
);
1158 if (dinfo
->disp_info
->aliases
== NULL
) {
1160 return NT_STATUS_ACCESS_DENIED
;
1164 num_aliases
= pdb_search_entries(dinfo
->disp_info
->aliases
,
1165 *r
->in
.resume_handle
,
1166 MAX_SAM_ENTRIES
, &aliases
);
1169 /* Ensure we cache this enumeration. */
1170 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1172 make_group_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1173 num_aliases
, aliases
);
1175 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__
));
1177 samr_array
->count
= num_aliases
;
1178 samr_array
->entries
= samr_entries
;
1180 *r
->out
.sam
= samr_array
;
1181 *r
->out
.num_entries
= num_aliases
;
1182 *r
->out
.resume_handle
= num_aliases
+ *r
->in
.resume_handle
;
1187 /*******************************************************************
1188 inits a samr_DispInfoGeneral structure.
1189 ********************************************************************/
1191 static NTSTATUS
init_samr_dispinfo_1(TALLOC_CTX
*ctx
,
1192 struct samr_DispInfoGeneral
*r
,
1193 uint32_t num_entries
,
1195 struct samr_displayentry
*entries
)
1199 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries
));
1201 if (num_entries
== 0) {
1202 return NT_STATUS_OK
;
1205 r
->count
= num_entries
;
1207 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryGeneral
, num_entries
);
1209 return NT_STATUS_NO_MEMORY
;
1212 for (i
= 0; i
< num_entries
; i
++) {
1214 init_lsa_String(&r
->entries
[i
].account_name
,
1215 entries
[i
].account_name
);
1217 init_lsa_String(&r
->entries
[i
].description
,
1218 entries
[i
].description
);
1220 init_lsa_String(&r
->entries
[i
].full_name
,
1221 entries
[i
].fullname
);
1223 r
->entries
[i
].rid
= entries
[i
].rid
;
1224 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1225 r
->entries
[i
].idx
= start_idx
+i
+1;
1228 return NT_STATUS_OK
;
1231 /*******************************************************************
1232 inits a samr_DispInfoFull structure.
1233 ********************************************************************/
1235 static NTSTATUS
init_samr_dispinfo_2(TALLOC_CTX
*ctx
,
1236 struct samr_DispInfoFull
*r
,
1237 uint32_t num_entries
,
1239 struct samr_displayentry
*entries
)
1243 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries
));
1245 if (num_entries
== 0) {
1246 return NT_STATUS_OK
;
1249 r
->count
= num_entries
;
1251 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryFull
, num_entries
);
1253 return NT_STATUS_NO_MEMORY
;
1256 for (i
= 0; i
< num_entries
; i
++) {
1258 init_lsa_String(&r
->entries
[i
].account_name
,
1259 entries
[i
].account_name
);
1261 init_lsa_String(&r
->entries
[i
].description
,
1262 entries
[i
].description
);
1264 r
->entries
[i
].rid
= entries
[i
].rid
;
1265 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1266 r
->entries
[i
].idx
= start_idx
+i
+1;
1269 return NT_STATUS_OK
;
1272 /*******************************************************************
1273 inits a samr_DispInfoFullGroups structure.
1274 ********************************************************************/
1276 static NTSTATUS
init_samr_dispinfo_3(TALLOC_CTX
*ctx
,
1277 struct samr_DispInfoFullGroups
*r
,
1278 uint32_t num_entries
,
1280 struct samr_displayentry
*entries
)
1284 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries
));
1286 if (num_entries
== 0) {
1287 return NT_STATUS_OK
;
1290 r
->count
= num_entries
;
1292 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryFullGroup
, num_entries
);
1294 return NT_STATUS_NO_MEMORY
;
1297 for (i
= 0; i
< num_entries
; i
++) {
1299 init_lsa_String(&r
->entries
[i
].account_name
,
1300 entries
[i
].account_name
);
1302 init_lsa_String(&r
->entries
[i
].description
,
1303 entries
[i
].description
);
1305 r
->entries
[i
].rid
= entries
[i
].rid
;
1306 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1307 r
->entries
[i
].idx
= start_idx
+i
+1;
1310 return NT_STATUS_OK
;
1313 /*******************************************************************
1314 inits a samr_DispInfoAscii structure.
1315 ********************************************************************/
1317 static NTSTATUS
init_samr_dispinfo_4(TALLOC_CTX
*ctx
,
1318 struct samr_DispInfoAscii
*r
,
1319 uint32_t num_entries
,
1321 struct samr_displayentry
*entries
)
1325 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries
));
1327 if (num_entries
== 0) {
1328 return NT_STATUS_OK
;
1331 r
->count
= num_entries
;
1333 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryAscii
, num_entries
);
1335 return NT_STATUS_NO_MEMORY
;
1338 for (i
= 0; i
< num_entries
; i
++) {
1340 init_lsa_AsciiStringLarge(&r
->entries
[i
].account_name
,
1341 entries
[i
].account_name
);
1343 r
->entries
[i
].idx
= start_idx
+i
+1;
1346 return NT_STATUS_OK
;
1349 /*******************************************************************
1350 inits a samr_DispInfoAscii structure.
1351 ********************************************************************/
1353 static NTSTATUS
init_samr_dispinfo_5(TALLOC_CTX
*ctx
,
1354 struct samr_DispInfoAscii
*r
,
1355 uint32_t num_entries
,
1357 struct samr_displayentry
*entries
)
1361 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries
));
1363 if (num_entries
== 0) {
1364 return NT_STATUS_OK
;
1367 r
->count
= num_entries
;
1369 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryAscii
, num_entries
);
1371 return NT_STATUS_NO_MEMORY
;
1374 for (i
= 0; i
< num_entries
; i
++) {
1376 init_lsa_AsciiStringLarge(&r
->entries
[i
].account_name
,
1377 entries
[i
].account_name
);
1379 r
->entries
[i
].idx
= start_idx
+i
+1;
1382 return NT_STATUS_OK
;
1385 /*******************************************************************
1386 _samr_QueryDisplayInfo
1387 ********************************************************************/
1389 NTSTATUS
_samr_QueryDisplayInfo(pipes_struct
*p
,
1390 struct samr_QueryDisplayInfo
*r
)
1393 struct samr_domain_info
*dinfo
;
1394 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
1396 uint32 max_entries
= r
->in
.max_entries
;
1397 uint32 enum_context
= r
->in
.start_idx
;
1398 uint32 max_size
= r
->in
.buf_size
;
1400 union samr_DispInfo
*disp_info
= r
->out
.info
;
1402 uint32 temp_size
=0, total_data_size
=0;
1403 NTSTATUS disp_ret
= NT_STATUS_UNSUCCESSFUL
;
1404 uint32 num_account
= 0;
1405 enum remote_arch_types ra_type
= get_remote_arch();
1406 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
1407 struct samr_displayentry
*entries
= NULL
;
1409 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__
));
1411 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
1412 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
1413 struct samr_domain_info
, &status
);
1414 if (!NT_STATUS_IS_OK(status
)) {
1418 if (sid_check_is_builtin(&dinfo
->sid
)) {
1419 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1420 return NT_STATUS_OK
;
1424 * calculate how many entries we will return.
1426 * - the number of entries the client asked
1427 * - our limit on that
1428 * - the starting point (enumeration context)
1429 * - the buffer size the client will accept
1433 * We are a lot more like W2K. Instead of reading the SAM
1434 * each time to find the records we need to send back,
1435 * we read it once and link that copy to the sam handle.
1436 * For large user list (over the MAX_SAM_ENTRIES)
1437 * it's a definitive win.
1438 * second point to notice: between enumerations
1439 * our sam is now the same as it's a snapshoot.
1440 * third point: got rid of the static SAM_USER_21 struct
1441 * no more intermediate.
1442 * con: it uses much more memory, as a full copy is stored
1445 * If you want to change it, think twice and think
1446 * of the second point , that's really important.
1451 if ((r
->in
.level
< 1) || (r
->in
.level
> 5)) {
1452 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1453 (unsigned int)r
->in
.level
));
1454 return NT_STATUS_INVALID_INFO_CLASS
;
1457 /* first limit the number of entries we will return */
1458 if(max_entries
> max_sam_entries
) {
1459 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1460 "entries, limiting to %d\n", max_entries
,
1462 max_entries
= max_sam_entries
;
1465 /* calculate the size and limit on the number of entries we will
1468 temp_size
=max_entries
*struct_size
;
1470 if (temp_size
>max_size
) {
1471 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
1472 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1473 "only %d entries\n", max_entries
));
1478 /* THe following done as ROOT. Don't return without unbecome_root(). */
1480 switch (r
->in
.level
) {
1483 if (dinfo
->disp_info
->users
== NULL
) {
1484 dinfo
->disp_info
->users
= pdb_search_users(
1485 dinfo
->disp_info
, ACB_NORMAL
);
1486 if (dinfo
->disp_info
->users
== NULL
) {
1488 return NT_STATUS_ACCESS_DENIED
;
1490 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1491 (unsigned int)enum_context
));
1493 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1494 (unsigned int)enum_context
));
1497 num_account
= pdb_search_entries(dinfo
->disp_info
->users
,
1498 enum_context
, max_entries
,
1502 if (dinfo
->disp_info
->machines
== NULL
) {
1503 dinfo
->disp_info
->machines
= pdb_search_users(
1504 dinfo
->disp_info
, ACB_WSTRUST
|ACB_SVRTRUST
);
1505 if (dinfo
->disp_info
->machines
== NULL
) {
1507 return NT_STATUS_ACCESS_DENIED
;
1509 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1510 (unsigned int)enum_context
));
1512 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1513 (unsigned int)enum_context
));
1516 num_account
= pdb_search_entries(dinfo
->disp_info
->machines
,
1517 enum_context
, max_entries
,
1522 if (dinfo
->disp_info
->groups
== NULL
) {
1523 dinfo
->disp_info
->groups
= pdb_search_groups(
1525 if (dinfo
->disp_info
->groups
== NULL
) {
1527 return NT_STATUS_ACCESS_DENIED
;
1529 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1530 (unsigned int)enum_context
));
1532 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1533 (unsigned int)enum_context
));
1536 num_account
= pdb_search_entries(dinfo
->disp_info
->groups
,
1537 enum_context
, max_entries
,
1542 smb_panic("info class changed");
1548 /* Now create reply structure */
1549 switch (r
->in
.level
) {
1551 disp_ret
= init_samr_dispinfo_1(p
->mem_ctx
, &disp_info
->info1
,
1552 num_account
, enum_context
,
1556 disp_ret
= init_samr_dispinfo_2(p
->mem_ctx
, &disp_info
->info2
,
1557 num_account
, enum_context
,
1561 disp_ret
= init_samr_dispinfo_3(p
->mem_ctx
, &disp_info
->info3
,
1562 num_account
, enum_context
,
1566 disp_ret
= init_samr_dispinfo_4(p
->mem_ctx
, &disp_info
->info4
,
1567 num_account
, enum_context
,
1571 disp_ret
= init_samr_dispinfo_5(p
->mem_ctx
, &disp_info
->info5
,
1572 num_account
, enum_context
,
1576 smb_panic("info class changed");
1580 if (!NT_STATUS_IS_OK(disp_ret
))
1583 /* calculate the total size */
1584 total_data_size
=num_account
*struct_size
;
1586 if (max_entries
<= num_account
) {
1587 status
= STATUS_MORE_ENTRIES
;
1589 status
= NT_STATUS_OK
;
1592 /* Ensure we cache this enumeration. */
1593 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1595 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__
));
1597 *r
->out
.total_size
= total_data_size
;
1598 *r
->out
.returned_size
= temp_size
;
1603 /****************************************************************
1604 _samr_QueryDisplayInfo2
1605 ****************************************************************/
1607 NTSTATUS
_samr_QueryDisplayInfo2(pipes_struct
*p
,
1608 struct samr_QueryDisplayInfo2
*r
)
1610 struct samr_QueryDisplayInfo q
;
1612 q
.in
.domain_handle
= r
->in
.domain_handle
;
1613 q
.in
.level
= r
->in
.level
;
1614 q
.in
.start_idx
= r
->in
.start_idx
;
1615 q
.in
.max_entries
= r
->in
.max_entries
;
1616 q
.in
.buf_size
= r
->in
.buf_size
;
1618 q
.out
.total_size
= r
->out
.total_size
;
1619 q
.out
.returned_size
= r
->out
.returned_size
;
1620 q
.out
.info
= r
->out
.info
;
1622 return _samr_QueryDisplayInfo(p
, &q
);
1625 /****************************************************************
1626 _samr_QueryDisplayInfo3
1627 ****************************************************************/
1629 NTSTATUS
_samr_QueryDisplayInfo3(pipes_struct
*p
,
1630 struct samr_QueryDisplayInfo3
*r
)
1632 struct samr_QueryDisplayInfo q
;
1634 q
.in
.domain_handle
= r
->in
.domain_handle
;
1635 q
.in
.level
= r
->in
.level
;
1636 q
.in
.start_idx
= r
->in
.start_idx
;
1637 q
.in
.max_entries
= r
->in
.max_entries
;
1638 q
.in
.buf_size
= r
->in
.buf_size
;
1640 q
.out
.total_size
= r
->out
.total_size
;
1641 q
.out
.returned_size
= r
->out
.returned_size
;
1642 q
.out
.info
= r
->out
.info
;
1644 return _samr_QueryDisplayInfo(p
, &q
);
1647 /*******************************************************************
1648 _samr_QueryAliasInfo
1649 ********************************************************************/
1651 NTSTATUS
_samr_QueryAliasInfo(pipes_struct
*p
,
1652 struct samr_QueryAliasInfo
*r
)
1654 struct samr_alias_info
*ainfo
;
1655 struct acct_info info
;
1657 union samr_AliasInfo
*alias_info
= NULL
;
1658 const char *alias_name
= NULL
;
1659 const char *alias_description
= NULL
;
1661 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__
));
1663 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
1664 SAMR_ALIAS_ACCESS_LOOKUP_INFO
, NULL
,
1665 struct samr_alias_info
, &status
);
1666 if (!NT_STATUS_IS_OK(status
)) {
1670 alias_info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_AliasInfo
);
1672 return NT_STATUS_NO_MEMORY
;
1676 status
= pdb_get_aliasinfo(&ainfo
->sid
, &info
);
1679 if ( !NT_STATUS_IS_OK(status
))
1682 /* FIXME: info contains fstrings */
1683 alias_name
= talloc_strdup(r
, info
.acct_name
);
1684 alias_description
= talloc_strdup(r
, info
.acct_desc
);
1686 switch (r
->in
.level
) {
1688 alias_info
->all
.name
.string
= alias_name
;
1689 alias_info
->all
.num_members
= 1; /* ??? */
1690 alias_info
->all
.description
.string
= alias_description
;
1693 alias_info
->name
.string
= alias_name
;
1695 case ALIASINFODESCRIPTION
:
1696 alias_info
->description
.string
= alias_description
;
1699 return NT_STATUS_INVALID_INFO_CLASS
;
1702 *r
->out
.info
= alias_info
;
1704 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__
));
1706 return NT_STATUS_OK
;
1709 /*******************************************************************
1711 ********************************************************************/
1713 NTSTATUS
_samr_LookupNames(pipes_struct
*p
,
1714 struct samr_LookupNames
*r
)
1716 struct samr_domain_info
*dinfo
;
1719 enum lsa_SidType
*type
;
1721 int num_rids
= r
->in
.num_names
;
1722 struct samr_Ids rids
, types
;
1723 uint32_t num_mapped
= 0;
1725 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1727 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
1728 0 /* Don't know the acc_bits yet */, NULL
,
1729 struct samr_domain_info
, &status
);
1730 if (!NT_STATUS_IS_OK(status
)) {
1734 if (num_rids
> MAX_SAM_ENTRIES
) {
1735 num_rids
= MAX_SAM_ENTRIES
;
1736 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids
));
1739 rid
= talloc_array(p
->mem_ctx
, uint32
, num_rids
);
1740 NT_STATUS_HAVE_NO_MEMORY(rid
);
1742 type
= talloc_array(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
1743 NT_STATUS_HAVE_NO_MEMORY(type
);
1745 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1746 sid_string_dbg(&dinfo
->sid
)));
1748 for (i
= 0; i
< num_rids
; i
++) {
1750 status
= NT_STATUS_NONE_MAPPED
;
1751 type
[i
] = SID_NAME_UNKNOWN
;
1753 rid
[i
] = 0xffffffff;
1755 if (sid_check_is_builtin(&dinfo
->sid
)) {
1756 if (lookup_builtin_name(r
->in
.names
[i
].string
,
1759 type
[i
] = SID_NAME_ALIAS
;
1762 lookup_global_sam_name(r
->in
.names
[i
].string
, 0,
1766 if (type
[i
] != SID_NAME_UNKNOWN
) {
1771 if (num_mapped
== num_rids
) {
1772 status
= NT_STATUS_OK
;
1773 } else if (num_mapped
== 0) {
1774 status
= NT_STATUS_NONE_MAPPED
;
1776 status
= STATUS_SOME_UNMAPPED
;
1779 rids
.count
= num_rids
;
1782 types
.count
= num_rids
;
1785 *r
->out
.rids
= rids
;
1786 *r
->out
.types
= types
;
1788 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1793 /****************************************************************
1794 _samr_ChangePasswordUser
1795 ****************************************************************/
1797 NTSTATUS
_samr_ChangePasswordUser(pipes_struct
*p
,
1798 struct samr_ChangePasswordUser
*r
)
1802 struct samr_user_info
*uinfo
;
1804 struct samr_Password new_lmPwdHash
, new_ntPwdHash
, checkHash
;
1805 struct samr_Password lm_pwd
, nt_pwd
;
1807 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
1808 SAMR_USER_ACCESS_SET_PASSWORD
, NULL
,
1809 struct samr_user_info
, &status
);
1810 if (!NT_STATUS_IS_OK(status
)) {
1814 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1815 sid_string_dbg(&uinfo
->sid
)));
1817 if (!(pwd
= samu_new(NULL
))) {
1818 return NT_STATUS_NO_MEMORY
;
1822 ret
= pdb_getsampwsid(pwd
, &uinfo
->sid
);
1827 return NT_STATUS_WRONG_PASSWORD
;
1831 const uint8_t *lm_pass
, *nt_pass
;
1833 lm_pass
= pdb_get_lanman_passwd(pwd
);
1834 nt_pass
= pdb_get_nt_passwd(pwd
);
1836 if (!lm_pass
|| !nt_pass
) {
1837 status
= NT_STATUS_WRONG_PASSWORD
;
1841 memcpy(&lm_pwd
.hash
, lm_pass
, sizeof(lm_pwd
.hash
));
1842 memcpy(&nt_pwd
.hash
, nt_pass
, sizeof(nt_pwd
.hash
));
1845 /* basic sanity checking on parameters. Do this before any database ops */
1846 if (!r
->in
.lm_present
|| !r
->in
.nt_present
||
1847 !r
->in
.old_lm_crypted
|| !r
->in
.new_lm_crypted
||
1848 !r
->in
.old_nt_crypted
|| !r
->in
.new_nt_crypted
) {
1849 /* we should really handle a change with lm not
1851 status
= NT_STATUS_INVALID_PARAMETER_MIX
;
1855 /* decrypt and check the new lm hash */
1856 D_P16(lm_pwd
.hash
, r
->in
.new_lm_crypted
->hash
, new_lmPwdHash
.hash
);
1857 D_P16(new_lmPwdHash
.hash
, r
->in
.old_lm_crypted
->hash
, checkHash
.hash
);
1858 if (memcmp(checkHash
.hash
, lm_pwd
.hash
, 16) != 0) {
1859 status
= NT_STATUS_WRONG_PASSWORD
;
1863 /* decrypt and check the new nt hash */
1864 D_P16(nt_pwd
.hash
, r
->in
.new_nt_crypted
->hash
, new_ntPwdHash
.hash
);
1865 D_P16(new_ntPwdHash
.hash
, r
->in
.old_nt_crypted
->hash
, checkHash
.hash
);
1866 if (memcmp(checkHash
.hash
, nt_pwd
.hash
, 16) != 0) {
1867 status
= NT_STATUS_WRONG_PASSWORD
;
1871 /* The NT Cross is not required by Win2k3 R2, but if present
1872 check the nt cross hash */
1873 if (r
->in
.cross1_present
&& r
->in
.nt_cross
) {
1874 D_P16(lm_pwd
.hash
, r
->in
.nt_cross
->hash
, checkHash
.hash
);
1875 if (memcmp(checkHash
.hash
, new_ntPwdHash
.hash
, 16) != 0) {
1876 status
= NT_STATUS_WRONG_PASSWORD
;
1881 /* The LM Cross is not required by Win2k3 R2, but if present
1882 check the lm cross hash */
1883 if (r
->in
.cross2_present
&& r
->in
.lm_cross
) {
1884 D_P16(nt_pwd
.hash
, r
->in
.lm_cross
->hash
, checkHash
.hash
);
1885 if (memcmp(checkHash
.hash
, new_lmPwdHash
.hash
, 16) != 0) {
1886 status
= NT_STATUS_WRONG_PASSWORD
;
1891 if (!pdb_set_nt_passwd(pwd
, new_ntPwdHash
.hash
, PDB_CHANGED
) ||
1892 !pdb_set_lanman_passwd(pwd
, new_lmPwdHash
.hash
, PDB_CHANGED
)) {
1893 status
= NT_STATUS_ACCESS_DENIED
;
1897 status
= pdb_update_sam_account(pwd
);
1904 /*******************************************************************
1905 _samr_ChangePasswordUser2
1906 ********************************************************************/
1908 NTSTATUS
_samr_ChangePasswordUser2(pipes_struct
*p
,
1909 struct samr_ChangePasswordUser2
*r
)
1915 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
1917 fstrcpy(user_name
, r
->in
.account
->string
);
1918 fstrcpy(wks
, r
->in
.server
->string
);
1920 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
1923 * Pass the user through the NT -> unix user mapping
1927 (void)map_username(user_name
);
1930 * UNIX username case mangling not required, pass_oem_change
1931 * is case insensitive.
1934 status
= pass_oem_change(user_name
,
1935 r
->in
.lm_password
->data
,
1936 r
->in
.lm_verifier
->hash
,
1937 r
->in
.nt_password
->data
,
1938 r
->in
.nt_verifier
->hash
,
1941 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
1943 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
1944 return NT_STATUS_WRONG_PASSWORD
;
1950 /****************************************************************
1951 _samr_OemChangePasswordUser2
1952 ****************************************************************/
1954 NTSTATUS
_samr_OemChangePasswordUser2(pipes_struct
*p
,
1955 struct samr_OemChangePasswordUser2
*r
)
1959 const char *wks
= NULL
;
1961 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
1963 fstrcpy(user_name
, r
->in
.account
->string
);
1964 if (r
->in
.server
&& r
->in
.server
->string
) {
1965 wks
= r
->in
.server
->string
;
1968 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
1971 * Pass the user through the NT -> unix user mapping
1975 (void)map_username(user_name
);
1978 * UNIX username case mangling not required, pass_oem_change
1979 * is case insensitive.
1982 if (!r
->in
.hash
|| !r
->in
.password
) {
1983 return NT_STATUS_INVALID_PARAMETER
;
1986 status
= pass_oem_change(user_name
,
1987 r
->in
.password
->data
,
1993 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
1994 return NT_STATUS_WRONG_PASSWORD
;
1997 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
2002 /*******************************************************************
2003 _samr_ChangePasswordUser3
2004 ********************************************************************/
2006 NTSTATUS
_samr_ChangePasswordUser3(pipes_struct
*p
,
2007 struct samr_ChangePasswordUser3
*r
)
2011 const char *wks
= NULL
;
2012 uint32 reject_reason
;
2013 struct samr_DomInfo1
*dominfo
= NULL
;
2014 struct samr_ChangeReject
*reject
= NULL
;
2017 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
2019 fstrcpy(user_name
, r
->in
.account
->string
);
2020 if (r
->in
.server
&& r
->in
.server
->string
) {
2021 wks
= r
->in
.server
->string
;
2024 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name
, wks
));
2027 * Pass the user through the NT -> unix user mapping
2031 (void)map_username(user_name
);
2034 * UNIX username case mangling not required, pass_oem_change
2035 * is case insensitive.
2038 status
= pass_oem_change(user_name
,
2039 r
->in
.lm_password
->data
,
2040 r
->in
.lm_verifier
->hash
,
2041 r
->in
.nt_password
->data
,
2042 r
->in
.nt_verifier
->hash
,
2044 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
2045 return NT_STATUS_WRONG_PASSWORD
;
2048 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) ||
2049 NT_STATUS_EQUAL(status
, NT_STATUS_ACCOUNT_RESTRICTION
)) {
2051 time_t u_expire
, u_min_age
;
2052 uint32 account_policy_temp
;
2054 dominfo
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_DomInfo1
);
2056 return NT_STATUS_NO_MEMORY
;
2059 reject
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_ChangeReject
);
2061 return NT_STATUS_NO_MEMORY
;
2068 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
, &tmp
);
2069 dominfo
->min_password_length
= tmp
;
2071 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &tmp
);
2072 dominfo
->password_history_length
= tmp
;
2074 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
2075 &dominfo
->password_properties
);
2077 pdb_get_account_policy(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
2078 u_expire
= account_policy_temp
;
2080 pdb_get_account_policy(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
2081 u_min_age
= account_policy_temp
;
2087 unix_to_nt_time_abs((NTTIME
*)&dominfo
->max_password_age
, u_expire
);
2088 unix_to_nt_time_abs((NTTIME
*)&dominfo
->min_password_age
, u_min_age
);
2090 if (lp_check_password_script() && *lp_check_password_script()) {
2091 dominfo
->password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
2094 reject
->reason
= reject_reason
;
2096 *r
->out
.dominfo
= dominfo
;
2097 *r
->out
.reject
= reject
;
2100 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
2105 /*******************************************************************
2106 makes a SAMR_R_LOOKUP_RIDS structure.
2107 ********************************************************************/
2109 static bool make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
,
2111 struct lsa_String
**lsa_name_array_p
)
2113 struct lsa_String
*lsa_name_array
= NULL
;
2116 *lsa_name_array_p
= NULL
;
2118 if (num_names
!= 0) {
2119 lsa_name_array
= TALLOC_ZERO_ARRAY(ctx
, struct lsa_String
, num_names
);
2120 if (!lsa_name_array
) {
2125 for (i
= 0; i
< num_names
; i
++) {
2126 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
] && *names
[i
] ? names
[i
] : ""));
2127 init_lsa_String(&lsa_name_array
[i
], names
[i
]);
2130 *lsa_name_array_p
= lsa_name_array
;
2135 /*******************************************************************
2137 ********************************************************************/
2139 NTSTATUS
_samr_LookupRids(pipes_struct
*p
,
2140 struct samr_LookupRids
*r
)
2142 struct samr_domain_info
*dinfo
;
2145 enum lsa_SidType
*attrs
= NULL
;
2146 uint32
*wire_attrs
= NULL
;
2147 int num_rids
= (int)r
->in
.num_rids
;
2149 struct lsa_Strings names_array
;
2150 struct samr_Ids types_array
;
2151 struct lsa_String
*lsa_names
= NULL
;
2153 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2155 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
2156 0 /* Don't know the acc_bits yet */, NULL
,
2157 struct samr_domain_info
, &status
);
2158 if (!NT_STATUS_IS_OK(status
)) {
2162 if (num_rids
> 1000) {
2163 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2164 "to samba4 idl this is not possible\n", num_rids
));
2165 return NT_STATUS_UNSUCCESSFUL
;
2169 names
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, const char *, num_rids
);
2170 attrs
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
2171 wire_attrs
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_rids
);
2173 if ((names
== NULL
) || (attrs
== NULL
) || (wire_attrs
==NULL
))
2174 return NT_STATUS_NO_MEMORY
;
2181 become_root(); /* lookup_sid can require root privs */
2182 status
= pdb_lookup_rids(&dinfo
->sid
, num_rids
, r
->in
.rids
,
2186 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
) && (num_rids
== 0)) {
2187 status
= NT_STATUS_OK
;
2190 if (!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, names
,
2192 return NT_STATUS_NO_MEMORY
;
2195 /* Convert from enum lsa_SidType to uint32 for wire format. */
2196 for (i
= 0; i
< num_rids
; i
++) {
2197 wire_attrs
[i
] = (uint32
)attrs
[i
];
2200 names_array
.count
= num_rids
;
2201 names_array
.names
= lsa_names
;
2203 types_array
.count
= num_rids
;
2204 types_array
.ids
= wire_attrs
;
2206 *r
->out
.names
= names_array
;
2207 *r
->out
.types
= types_array
;
2209 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2214 /*******************************************************************
2216 ********************************************************************/
2218 NTSTATUS
_samr_OpenUser(pipes_struct
*p
,
2219 struct samr_OpenUser
*r
)
2221 struct samu
*sampass
=NULL
;
2223 struct samr_domain_info
*dinfo
;
2224 struct samr_user_info
*uinfo
;
2225 SEC_DESC
*psd
= NULL
;
2227 uint32 des_access
= r
->in
.access_mask
;
2228 uint32_t extra_access
= 0;
2235 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
2236 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
2237 struct samr_domain_info
, &status
);
2238 if (!NT_STATUS_IS_OK(status
)) {
2242 if ( !(sampass
= samu_new( p
->mem_ctx
)) ) {
2243 return NT_STATUS_NO_MEMORY
;
2246 /* append the user's RID to it */
2248 if (!sid_compose(&sid
, &dinfo
->sid
, r
->in
.rid
))
2249 return NT_STATUS_NO_SUCH_USER
;
2251 /* check if access can be granted as requested by client. */
2253 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
2255 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
, &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
2256 se_map_generic(&des_access
, &usr_generic_mapping
);
2259 * Get the sampass first as we need to check privilages
2260 * based on what kind of user object this is.
2261 * But don't reveal info too early if it didn't exist.
2265 ret
=pdb_getsampwsid(sampass
, &sid
);
2268 se_priv_copy(&se_rights
, &se_priv_none
);
2271 * We do the override access checks on *open*, not at
2275 uint32_t acb_info
= pdb_get_acct_ctrl(sampass
);
2277 if ((acb_info
& ACB_WSTRUST
) &&
2278 user_has_any_privilege(p
->server_info
->ptok
,
2279 &se_machine_account
)) {
2281 * SeMachineAccount is needed to add
2282 * GENERIC_RIGHTS_USER_WRITE to a machine
2285 se_priv_add(&se_rights
, &se_machine_account
);
2286 DEBUG(10,("_samr_OpenUser: adding machine account "
2287 "rights to handle for user %s\n",
2288 pdb_get_username(sampass
) ));
2290 if ((acb_info
& ACB_NORMAL
) &&
2291 user_has_any_privilege(p
->server_info
->ptok
,
2294 * SeAddUsers is needed to add
2295 * GENERIC_RIGHTS_USER_WRITE to a normal
2298 se_priv_add(&se_rights
, &se_add_users
);
2299 DEBUG(10,("_samr_OpenUser: adding add user "
2300 "rights to handle for user %s\n",
2301 pdb_get_username(sampass
) ));
2304 * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
2305 * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not
2306 * what Windows does but is a hack for people who haven't
2307 * set up privilages on groups in Samba.
2309 if (acb_info
& (ACB_SVRTRUST
|ACB_DOMTRUST
)) {
2310 if (lp_enable_privileges() && nt_token_check_domain_rid(p
->server_info
->ptok
,
2311 DOMAIN_GROUP_RID_ADMINS
)) {
2312 des_access
&= ~GENERIC_RIGHTS_USER_WRITE
;
2313 extra_access
= GENERIC_RIGHTS_USER_WRITE
;
2314 DEBUG(4,("_samr_OpenUser: Allowing "
2315 "GENERIC_RIGHTS_USER_WRITE for "
2321 TALLOC_FREE(sampass
);
2323 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
2324 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
2325 &acc_granted
, "_samr_OpenUser");
2327 if ( !NT_STATUS_IS_OK(nt_status
) )
2330 /* check that the SID exists in our domain. */
2332 return NT_STATUS_NO_SUCH_USER
;
2335 /* If we did the rid admins hack above, allow access. */
2336 acc_granted
|= extra_access
;
2338 uinfo
= policy_handle_create(p
, r
->out
.user_handle
, acc_granted
,
2339 struct samr_user_info
, &nt_status
);
2340 if (!NT_STATUS_IS_OK(nt_status
)) {
2345 return NT_STATUS_OK
;
2348 /*************************************************************************
2349 *************************************************************************/
2351 static NTSTATUS
init_samr_parameters_string(TALLOC_CTX
*mem_ctx
,
2353 struct lsa_BinaryString
**_r
)
2355 struct lsa_BinaryString
*r
;
2358 return NT_STATUS_INVALID_PARAMETER
;
2361 r
= TALLOC_ZERO_P(mem_ctx
, struct lsa_BinaryString
);
2363 return NT_STATUS_NO_MEMORY
;
2366 r
->array
= TALLOC_ZERO_ARRAY(mem_ctx
, uint16_t, blob
->length
/2);
2368 return NT_STATUS_NO_MEMORY
;
2370 memcpy(r
->array
, blob
->data
, blob
->length
);
2371 r
->size
= blob
->length
;
2372 r
->length
= blob
->length
;
2375 return NT_STATUS_NO_MEMORY
;
2380 return NT_STATUS_OK
;
2383 /*************************************************************************
2385 *************************************************************************/
2387 static NTSTATUS
get_user_info_1(TALLOC_CTX
*mem_ctx
,
2388 struct samr_UserInfo1
*r
,
2390 DOM_SID
*domain_sid
)
2392 const DOM_SID
*sid_group
;
2393 uint32_t primary_gid
;
2396 sid_group
= pdb_get_group_sid(pw
);
2399 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2400 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2401 "which conflicts with the domain sid %s. Failing operation.\n",
2402 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2403 sid_string_dbg(domain_sid
)));
2404 return NT_STATUS_UNSUCCESSFUL
;
2407 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2408 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2409 r
->primary_gid
= primary_gid
;
2410 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2411 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2413 return NT_STATUS_OK
;
2416 /*************************************************************************
2418 *************************************************************************/
2420 static NTSTATUS
get_user_info_2(TALLOC_CTX
*mem_ctx
,
2421 struct samr_UserInfo2
*r
,
2424 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2425 r
->unknown
.string
= NULL
;
2426 r
->country_code
= 0;
2429 return NT_STATUS_OK
;
2432 /*************************************************************************
2434 *************************************************************************/
2436 static NTSTATUS
get_user_info_3(TALLOC_CTX
*mem_ctx
,
2437 struct samr_UserInfo3
*r
,
2439 DOM_SID
*domain_sid
)
2441 const DOM_SID
*sid_user
, *sid_group
;
2442 uint32_t rid
, primary_gid
;
2444 sid_user
= pdb_get_user_sid(pw
);
2446 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2447 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2448 "the domain sid %s. Failing operation.\n",
2449 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2450 sid_string_dbg(domain_sid
)));
2451 return NT_STATUS_UNSUCCESSFUL
;
2455 sid_group
= pdb_get_group_sid(pw
);
2458 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2459 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2460 "which conflicts with the domain sid %s. Failing operation.\n",
2461 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2462 sid_string_dbg(domain_sid
)));
2463 return NT_STATUS_UNSUCCESSFUL
;
2466 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2467 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2468 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2469 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2470 unix_to_nt_time(&r
->force_password_change
, pdb_get_pass_must_change_time(pw
));
2472 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2473 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2474 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2475 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2476 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2477 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2478 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2480 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2482 r
->primary_gid
= primary_gid
;
2483 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2484 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2485 r
->logon_count
= pdb_get_logon_count(pw
);
2487 return NT_STATUS_OK
;
2490 /*************************************************************************
2492 *************************************************************************/
2494 static NTSTATUS
get_user_info_4(TALLOC_CTX
*mem_ctx
,
2495 struct samr_UserInfo4
*r
,
2498 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2500 return NT_STATUS_OK
;
2503 /*************************************************************************
2505 *************************************************************************/
2507 static NTSTATUS
get_user_info_5(TALLOC_CTX
*mem_ctx
,
2508 struct samr_UserInfo5
*r
,
2510 DOM_SID
*domain_sid
)
2512 const DOM_SID
*sid_user
, *sid_group
;
2513 uint32_t rid
, primary_gid
;
2515 sid_user
= pdb_get_user_sid(pw
);
2517 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2518 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2519 "the domain sid %s. Failing operation.\n",
2520 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2521 sid_string_dbg(domain_sid
)));
2522 return NT_STATUS_UNSUCCESSFUL
;
2526 sid_group
= pdb_get_group_sid(pw
);
2529 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2530 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2531 "which conflicts with the domain sid %s. Failing operation.\n",
2532 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2533 sid_string_dbg(domain_sid
)));
2534 return NT_STATUS_UNSUCCESSFUL
;
2537 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2538 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2539 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2540 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2542 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2543 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2544 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2545 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2546 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2547 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2548 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2549 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2551 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2553 r
->primary_gid
= primary_gid
;
2554 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2555 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2556 r
->logon_count
= pdb_get_logon_count(pw
);
2558 return NT_STATUS_OK
;
2561 /*************************************************************************
2563 *************************************************************************/
2565 static NTSTATUS
get_user_info_6(TALLOC_CTX
*mem_ctx
,
2566 struct samr_UserInfo6
*r
,
2569 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2570 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2572 return NT_STATUS_OK
;
2575 /*************************************************************************
2576 get_user_info_7. Safe. Only gives out account_name.
2577 *************************************************************************/
2579 static NTSTATUS
get_user_info_7(TALLOC_CTX
*mem_ctx
,
2580 struct samr_UserInfo7
*r
,
2581 struct samu
*smbpass
)
2583 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(smbpass
));
2584 if (!r
->account_name
.string
) {
2585 return NT_STATUS_NO_MEMORY
;
2588 return NT_STATUS_OK
;
2591 /*************************************************************************
2593 *************************************************************************/
2595 static NTSTATUS
get_user_info_8(TALLOC_CTX
*mem_ctx
,
2596 struct samr_UserInfo8
*r
,
2599 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2601 return NT_STATUS_OK
;
2604 /*************************************************************************
2605 get_user_info_9. Only gives out primary group SID.
2606 *************************************************************************/
2608 static NTSTATUS
get_user_info_9(TALLOC_CTX
*mem_ctx
,
2609 struct samr_UserInfo9
*r
,
2610 struct samu
*smbpass
)
2612 r
->primary_gid
= pdb_get_group_rid(smbpass
);
2614 return NT_STATUS_OK
;
2617 /*************************************************************************
2619 *************************************************************************/
2621 static NTSTATUS
get_user_info_10(TALLOC_CTX
*mem_ctx
,
2622 struct samr_UserInfo10
*r
,
2625 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2626 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2628 return NT_STATUS_OK
;
2631 /*************************************************************************
2633 *************************************************************************/
2635 static NTSTATUS
get_user_info_11(TALLOC_CTX
*mem_ctx
,
2636 struct samr_UserInfo11
*r
,
2639 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2641 return NT_STATUS_OK
;
2644 /*************************************************************************
2646 *************************************************************************/
2648 static NTSTATUS
get_user_info_12(TALLOC_CTX
*mem_ctx
,
2649 struct samr_UserInfo12
*r
,
2652 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2654 return NT_STATUS_OK
;
2657 /*************************************************************************
2659 *************************************************************************/
2661 static NTSTATUS
get_user_info_13(TALLOC_CTX
*mem_ctx
,
2662 struct samr_UserInfo13
*r
,
2665 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2667 return NT_STATUS_OK
;
2670 /*************************************************************************
2672 *************************************************************************/
2674 static NTSTATUS
get_user_info_14(TALLOC_CTX
*mem_ctx
,
2675 struct samr_UserInfo14
*r
,
2678 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2680 return NT_STATUS_OK
;
2683 /*************************************************************************
2684 get_user_info_16. Safe. Only gives out acb bits.
2685 *************************************************************************/
2687 static NTSTATUS
get_user_info_16(TALLOC_CTX
*mem_ctx
,
2688 struct samr_UserInfo16
*r
,
2689 struct samu
*smbpass
)
2691 r
->acct_flags
= pdb_get_acct_ctrl(smbpass
);
2693 return NT_STATUS_OK
;
2696 /*************************************************************************
2698 *************************************************************************/
2700 static NTSTATUS
get_user_info_17(TALLOC_CTX
*mem_ctx
,
2701 struct samr_UserInfo17
*r
,
2704 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2706 return NT_STATUS_OK
;
2709 /*************************************************************************
2710 get_user_info_18. OK - this is the killer as it gives out password info.
2711 Ensure that this is only allowed on an encrypted connection with a root
2713 *************************************************************************/
2715 static NTSTATUS
get_user_info_18(pipes_struct
*p
,
2716 TALLOC_CTX
*mem_ctx
,
2717 struct samr_UserInfo18
*r
,
2720 struct samu
*smbpass
=NULL
;
2725 if (p
->auth
.auth_type
!= PIPE_AUTH_TYPE_NTLMSSP
|| p
->auth
.auth_type
!= PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
) {
2726 return NT_STATUS_ACCESS_DENIED
;
2729 if (p
->auth
.auth_level
!= PIPE_AUTH_LEVEL_PRIVACY
) {
2730 return NT_STATUS_ACCESS_DENIED
;
2734 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2737 if ( !(smbpass
= samu_new( mem_ctx
)) ) {
2738 return NT_STATUS_NO_MEMORY
;
2741 ret
= pdb_getsampwsid(smbpass
, user_sid
);
2744 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid
)));
2745 TALLOC_FREE(smbpass
);
2746 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
2749 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
2751 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
2752 TALLOC_FREE(smbpass
);
2753 return NT_STATUS_ACCOUNT_DISABLED
;
2756 r
->lm_pwd_active
= true;
2757 r
->nt_pwd_active
= true;
2758 memcpy(r
->lm_pwd
.hash
, pdb_get_lanman_passwd(smbpass
), 16);
2759 memcpy(r
->nt_pwd
.hash
, pdb_get_nt_passwd(smbpass
), 16);
2760 r
->password_expired
= 0; /* FIXME */
2762 TALLOC_FREE(smbpass
);
2764 return NT_STATUS_OK
;
2767 /*************************************************************************
2769 *************************************************************************/
2771 static NTSTATUS
get_user_info_20(TALLOC_CTX
*mem_ctx
,
2772 struct samr_UserInfo20
*r
,
2773 struct samu
*sampass
)
2775 const char *munged_dial
= NULL
;
2778 struct lsa_BinaryString
*parameters
= NULL
;
2782 munged_dial
= pdb_get_munged_dial(sampass
);
2784 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass
),
2785 munged_dial
, (int)strlen(munged_dial
)));
2788 blob
= base64_decode_data_blob(munged_dial
);
2790 blob
= data_blob_string_const_null("");
2793 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2794 data_blob_free(&blob
);
2795 if (!NT_STATUS_IS_OK(status
)) {
2799 r
->parameters
= *parameters
;
2801 return NT_STATUS_OK
;
2805 /*************************************************************************
2807 *************************************************************************/
2809 static NTSTATUS
get_user_info_21(TALLOC_CTX
*mem_ctx
,
2810 struct samr_UserInfo21
*r
,
2812 DOM_SID
*domain_sid
,
2813 uint32_t acc_granted
)
2816 const DOM_SID
*sid_user
, *sid_group
;
2817 uint32_t rid
, primary_gid
;
2818 NTTIME force_password_change
;
2819 time_t must_change_time
;
2820 struct lsa_BinaryString
*parameters
= NULL
;
2821 const char *munged_dial
= NULL
;
2826 sid_user
= pdb_get_user_sid(pw
);
2828 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2829 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2830 "the domain sid %s. Failing operation.\n",
2831 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2832 sid_string_dbg(domain_sid
)));
2833 return NT_STATUS_UNSUCCESSFUL
;
2837 sid_group
= pdb_get_group_sid(pw
);
2840 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2841 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2842 "which conflicts with the domain sid %s. Failing operation.\n",
2843 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2844 sid_string_dbg(domain_sid
)));
2845 return NT_STATUS_UNSUCCESSFUL
;
2848 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2849 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2850 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2851 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2852 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2854 must_change_time
= pdb_get_pass_must_change_time(pw
);
2855 if (must_change_time
== get_time_t_max()) {
2856 unix_to_nt_time_abs(&force_password_change
, must_change_time
);
2858 unix_to_nt_time(&force_password_change
, must_change_time
);
2861 munged_dial
= pdb_get_munged_dial(pw
);
2863 blob
= base64_decode_data_blob(munged_dial
);
2865 blob
= data_blob_string_const_null("");
2868 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2869 data_blob_free(&blob
);
2870 if (!NT_STATUS_IS_OK(status
)) {
2874 r
->force_password_change
= force_password_change
;
2876 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2877 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2878 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2879 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2880 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2881 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2882 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2883 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2884 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2886 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2887 r
->parameters
= *parameters
;
2889 r
->primary_gid
= primary_gid
;
2890 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2891 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2892 r
->logon_count
= pdb_get_logon_count(pw
);
2893 r
->fields_present
= pdb_build_fields_present(pw
);
2894 r
->password_expired
= (pdb_get_pass_must_change_time(pw
) == 0) ?
2895 PASS_MUST_CHANGE_AT_NEXT_LOGON
: 0;
2896 r
->country_code
= 0;
2898 r
->lm_password_set
= 0;
2899 r
->nt_password_set
= 0;
2904 Look at a user on a real NT4 PDC with usrmgr, press
2905 'ok'. Then you will see that fields_present is set to
2906 0x08f827fa. Look at the user immediately after that again,
2907 and you will see that 0x00fffff is returned. This solves
2908 the problem that you get access denied after having looked
2916 return NT_STATUS_OK
;
2919 /*******************************************************************
2921 ********************************************************************/
2923 NTSTATUS
_samr_QueryUserInfo(pipes_struct
*p
,
2924 struct samr_QueryUserInfo
*r
)
2927 union samr_UserInfo
*user_info
= NULL
;
2928 struct samr_user_info
*uinfo
;
2932 struct samu
*pwd
= NULL
;
2933 uint32_t acc_required
, acc_granted
;
2935 switch (r
->in
.level
) {
2936 case 1: /* UserGeneralInformation */
2937 /* USER_READ_GENERAL */
2938 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
;
2940 case 2: /* UserPreferencesInformation */
2941 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2942 acc_required
= SAMR_USER_ACCESS_GET_LOCALE
|
2943 SAMR_USER_ACCESS_GET_NAME_ETC
;
2945 case 3: /* UserLogonInformation */
2946 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2947 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
|
2948 SAMR_USER_ACCESS_GET_LOCALE
|
2949 SAMR_USER_ACCESS_GET_LOGONINFO
|
2950 SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2952 case 4: /* UserLogonHoursInformation */
2953 /* USER_READ_LOGON */
2954 acc_required
= SAMR_USER_ACCESS_GET_LOGONINFO
;
2956 case 5: /* UserAccountInformation */
2957 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2958 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
|
2959 SAMR_USER_ACCESS_GET_LOCALE
|
2960 SAMR_USER_ACCESS_GET_LOGONINFO
|
2961 SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2963 case 6: /* UserNameInformation */
2964 case 7: /* UserAccountNameInformation */
2965 case 8: /* UserFullNameInformation */
2966 case 9: /* UserPrimaryGroupInformation */
2967 case 13: /* UserAdminCommentInformation */
2968 /* USER_READ_GENERAL */
2969 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
;
2971 case 10: /* UserHomeInformation */
2972 case 11: /* UserScriptInformation */
2973 case 12: /* UserProfileInformation */
2974 case 14: /* UserWorkStationsInformation */
2975 /* USER_READ_LOGON */
2976 acc_required
= SAMR_USER_ACCESS_GET_LOGONINFO
;
2978 case 16: /* UserControlInformation */
2979 case 17: /* UserExpiresInformation */
2980 case 20: /* UserParametersInformation */
2981 /* USER_READ_ACCOUNT */
2982 acc_required
= SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2984 case 21: /* UserAllInformation */
2986 acc_required
= SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2988 case 18: /* UserInternal1Information */
2990 acc_required
= SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2992 case 23: /* UserInternal4Information */
2993 case 24: /* UserInternal4InformationNew */
2994 case 25: /* UserInternal4InformationNew */
2995 case 26: /* UserInternal5InformationNew */
2997 return NT_STATUS_INVALID_INFO_CLASS
;
3001 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
3002 acc_required
, &acc_granted
,
3003 struct samr_user_info
, &status
);
3004 if (!NT_STATUS_IS_OK(status
)) {
3008 domain_sid
= uinfo
->sid
;
3010 sid_split_rid(&domain_sid
, &rid
);
3012 if (!sid_check_is_in_our_domain(&uinfo
->sid
))
3013 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3015 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3016 sid_string_dbg(&uinfo
->sid
)));
3018 user_info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_UserInfo
);
3020 return NT_STATUS_NO_MEMORY
;
3023 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r
->in
.level
));
3025 if (!(pwd
= samu_new(p
->mem_ctx
))) {
3026 return NT_STATUS_NO_MEMORY
;
3030 ret
= pdb_getsampwsid(pwd
, &uinfo
->sid
);
3034 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo
->sid
)));
3036 return NT_STATUS_NO_SUCH_USER
;
3039 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd
)));
3041 samr_clear_sam_passwd(pwd
);
3043 switch (r
->in
.level
) {
3045 status
= get_user_info_1(p
->mem_ctx
, &user_info
->info1
, pwd
, &domain_sid
);
3048 status
= get_user_info_2(p
->mem_ctx
, &user_info
->info2
, pwd
);
3051 status
= get_user_info_3(p
->mem_ctx
, &user_info
->info3
, pwd
, &domain_sid
);
3054 status
= get_user_info_4(p
->mem_ctx
, &user_info
->info4
, pwd
);
3057 status
= get_user_info_5(p
->mem_ctx
, &user_info
->info5
, pwd
, &domain_sid
);
3060 status
= get_user_info_6(p
->mem_ctx
, &user_info
->info6
, pwd
);
3063 status
= get_user_info_7(p
->mem_ctx
, &user_info
->info7
, pwd
);
3066 status
= get_user_info_8(p
->mem_ctx
, &user_info
->info8
, pwd
);
3069 status
= get_user_info_9(p
->mem_ctx
, &user_info
->info9
, pwd
);
3072 status
= get_user_info_10(p
->mem_ctx
, &user_info
->info10
, pwd
);
3075 status
= get_user_info_11(p
->mem_ctx
, &user_info
->info11
, pwd
);
3078 status
= get_user_info_12(p
->mem_ctx
, &user_info
->info12
, pwd
);
3081 status
= get_user_info_13(p
->mem_ctx
, &user_info
->info13
, pwd
);
3084 status
= get_user_info_14(p
->mem_ctx
, &user_info
->info14
, pwd
);
3087 status
= get_user_info_16(p
->mem_ctx
, &user_info
->info16
, pwd
);
3090 status
= get_user_info_17(p
->mem_ctx
, &user_info
->info17
, pwd
);
3093 /* level 18 is special */
3094 status
= get_user_info_18(p
, p
->mem_ctx
, &user_info
->info18
,
3098 status
= get_user_info_20(p
->mem_ctx
, &user_info
->info20
, pwd
);
3101 status
= get_user_info_21(p
->mem_ctx
, &user_info
->info21
, pwd
, &domain_sid
, acc_granted
);
3104 status
= NT_STATUS_INVALID_INFO_CLASS
;
3108 if (!NT_STATUS_IS_OK(status
)) {
3112 *r
->out
.info
= user_info
;
3117 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__
));
3122 /****************************************************************
3123 ****************************************************************/
3125 NTSTATUS
_samr_QueryUserInfo2(pipes_struct
*p
,
3126 struct samr_QueryUserInfo2
*r
)
3128 struct samr_QueryUserInfo u
;
3130 u
.in
.user_handle
= r
->in
.user_handle
;
3131 u
.in
.level
= r
->in
.level
;
3132 u
.out
.info
= r
->out
.info
;
3134 return _samr_QueryUserInfo(p
, &u
);
3137 /*******************************************************************
3138 _samr_GetGroupsForUser
3139 ********************************************************************/
3141 NTSTATUS
_samr_GetGroupsForUser(pipes_struct
*p
,
3142 struct samr_GetGroupsForUser
*r
)
3144 struct samr_user_info
*uinfo
;
3145 struct samu
*sam_pass
=NULL
;
3147 struct samr_RidWithAttribute dom_gid
;
3148 struct samr_RidWithAttribute
*gids
= NULL
;
3149 uint32 primary_group_rid
;
3150 size_t num_groups
= 0;
3155 bool success
= False
;
3157 struct samr_RidWithAttributeArray
*rids
= NULL
;
3160 * from the SID in the request:
3161 * we should send back the list of DOMAIN GROUPS
3162 * the user is a member of
3164 * and only the DOMAIN GROUPS
3165 * no ALIASES !!! neither aliases of the domain
3166 * nor aliases of the builtin SID
3171 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3173 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
3174 SAMR_USER_ACCESS_GET_GROUPS
, NULL
,
3175 struct samr_user_info
, &result
);
3176 if (!NT_STATUS_IS_OK(result
)) {
3180 rids
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_RidWithAttributeArray
);
3182 return NT_STATUS_NO_MEMORY
;
3185 if (!sid_check_is_in_our_domain(&uinfo
->sid
))
3186 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3188 if ( !(sam_pass
= samu_new( p
->mem_ctx
)) ) {
3189 return NT_STATUS_NO_MEMORY
;
3193 ret
= pdb_getsampwsid(sam_pass
, &uinfo
->sid
);
3197 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3198 sid_string_dbg(&uinfo
->sid
)));
3199 return NT_STATUS_NO_SUCH_USER
;
3204 /* make both calls inside the root block */
3206 result
= pdb_enum_group_memberships(p
->mem_ctx
, sam_pass
,
3207 &sids
, &unix_gids
, &num_groups
);
3208 if ( NT_STATUS_IS_OK(result
) ) {
3209 success
= sid_peek_check_rid(get_global_sam_sid(),
3210 pdb_get_group_sid(sam_pass
),
3211 &primary_group_rid
);
3215 if (!NT_STATUS_IS_OK(result
)) {
3216 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3217 sid_string_dbg(&uinfo
->sid
)));
3222 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3223 sid_string_dbg(pdb_get_group_sid(sam_pass
)),
3224 pdb_get_username(sam_pass
)));
3225 TALLOC_FREE(sam_pass
);
3226 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
3232 dom_gid
.attributes
= (SE_GROUP_MANDATORY
|SE_GROUP_ENABLED_BY_DEFAULT
|
3234 dom_gid
.rid
= primary_group_rid
;
3235 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3237 for (i
=0; i
<num_groups
; i
++) {
3239 if (!sid_peek_check_rid(get_global_sam_sid(),
3240 &(sids
[i
]), &dom_gid
.rid
)) {
3241 DEBUG(10, ("Found sid %s not in our domain\n",
3242 sid_string_dbg(&sids
[i
])));
3246 if (dom_gid
.rid
== primary_group_rid
) {
3247 /* We added the primary group directly from the
3248 * sam_account. The other SIDs are unique from
3249 * enum_group_memberships */
3253 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3256 rids
->count
= num_gids
;
3259 *r
->out
.rids
= rids
;
3261 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3266 /*******************************************************************
3267 _samr_QueryDomainInfo
3268 ********************************************************************/
3270 NTSTATUS
_samr_QueryDomainInfo(pipes_struct
*p
,
3271 struct samr_QueryDomainInfo
*r
)
3273 NTSTATUS status
= NT_STATUS_OK
;
3274 struct samr_domain_info
*dinfo
;
3275 union samr_DomainInfo
*dom_info
;
3276 time_t u_expire
, u_min_age
;
3278 time_t u_lock_duration
, u_reset_time
;
3281 uint32 account_policy_temp
;
3285 uint32_t acc_required
;
3287 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3289 switch (r
->in
.level
) {
3290 case 1: /* DomainPasswordInformation */
3291 case 12: /* DomainLockoutInformation */
3292 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3293 acc_required
= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
;
3295 case 11: /* DomainGeneralInformation2 */
3296 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3297 * DOMAIN_READ_OTHER_PARAMETERS */
3298 acc_required
= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
3299 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
3301 case 2: /* DomainGeneralInformation */
3302 case 3: /* DomainLogoffInformation */
3303 case 4: /* DomainOemInformation */
3304 case 5: /* DomainReplicationInformation */
3305 case 6: /* DomainReplicationInformation */
3306 case 7: /* DomainServerRoleInformation */
3307 case 8: /* DomainModifiedInformation */
3308 case 9: /* DomainStateInformation */
3309 case 10: /* DomainUasInformation */
3310 case 13: /* DomainModifiedInformation2 */
3311 /* DOMAIN_READ_OTHER_PARAMETERS */
3312 acc_required
= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
3315 return NT_STATUS_INVALID_INFO_CLASS
;
3318 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
3320 struct samr_domain_info
, &status
);
3321 if (!NT_STATUS_IS_OK(status
)) {
3325 dom_info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_DomainInfo
);
3327 return NT_STATUS_NO_MEMORY
;
3330 switch (r
->in
.level
) {
3337 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
,
3338 &account_policy_temp
);
3339 dom_info
->info1
.min_password_length
= account_policy_temp
;
3341 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &account_policy_temp
);
3342 dom_info
->info1
.password_history_length
= account_policy_temp
;
3344 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
3345 &dom_info
->info1
.password_properties
);
3347 pdb_get_account_policy(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
3348 u_expire
= account_policy_temp
;
3350 pdb_get_account_policy(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
3351 u_min_age
= account_policy_temp
;
3357 unix_to_nt_time_abs((NTTIME
*)&dom_info
->info1
.max_password_age
, u_expire
);
3358 unix_to_nt_time_abs((NTTIME
*)&dom_info
->info1
.min_password_age
, u_min_age
);
3360 if (lp_check_password_script() && *lp_check_password_script()) {
3361 dom_info
->info1
.password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
3371 dom_info
->general
.num_users
= count_sam_users(
3372 dinfo
->disp_info
, ACB_NORMAL
);
3373 dom_info
->general
.num_groups
= count_sam_groups(
3375 dom_info
->general
.num_aliases
= count_sam_aliases(
3378 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &u_logout
);
3380 unix_to_nt_time_abs(&dom_info
->general
.force_logoff_time
, u_logout
);
3382 if (!pdb_get_seq_num(&seq_num
))
3383 seq_num
= time(NULL
);
3389 server_role
= ROLE_DOMAIN_PDC
;
3390 if (lp_server_role() == ROLE_DOMAIN_BDC
)
3391 server_role
= ROLE_DOMAIN_BDC
;
3393 dom_info
->general
.oem_information
.string
= lp_serverstring();
3394 dom_info
->general
.domain_name
.string
= lp_workgroup();
3395 dom_info
->general
.primary
.string
= global_myname();
3396 dom_info
->general
.sequence_num
= seq_num
;
3397 dom_info
->general
.domain_server_state
= DOMAIN_SERVER_ENABLED
;
3398 dom_info
->general
.role
= server_role
;
3399 dom_info
->general
.unknown3
= 1;
3410 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &ul
);
3411 u_logout
= (time_t)ul
;
3418 unix_to_nt_time_abs(&dom_info
->info3
.force_logoff_time
, u_logout
);
3422 dom_info
->oem
.oem_information
.string
= lp_serverstring();
3425 dom_info
->info5
.domain_name
.string
= get_global_sam_name();
3428 /* NT returns its own name when a PDC. win2k and later
3429 * only the name of the PDC if itself is a BDC (samba4
3431 dom_info
->info6
.primary
.string
= global_myname();
3434 server_role
= ROLE_DOMAIN_PDC
;
3435 if (lp_server_role() == ROLE_DOMAIN_BDC
)
3436 server_role
= ROLE_DOMAIN_BDC
;
3438 dom_info
->info7
.role
= server_role
;
3446 if (!pdb_get_seq_num(&seq_num
)) {
3447 seq_num
= time(NULL
);
3454 dom_info
->info8
.sequence_num
= seq_num
;
3455 dom_info
->info8
.domain_create_time
= 0;
3460 dom_info
->info9
.domain_server_state
= DOMAIN_SERVER_ENABLED
;
3469 dom_info
->general2
.general
.num_users
= count_sam_users(
3470 dinfo
->disp_info
, ACB_NORMAL
);
3471 dom_info
->general2
.general
.num_groups
= count_sam_groups(
3473 dom_info
->general2
.general
.num_aliases
= count_sam_aliases(
3476 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &u_logout
);
3478 unix_to_nt_time_abs(&dom_info
->general2
.general
.force_logoff_time
, u_logout
);
3480 if (!pdb_get_seq_num(&seq_num
))
3481 seq_num
= time(NULL
);
3483 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
3484 u_lock_duration
= account_policy_temp
;
3485 if (u_lock_duration
!= -1) {
3486 u_lock_duration
*= 60;
3489 pdb_get_account_policy(AP_RESET_COUNT_TIME
, &account_policy_temp
);
3490 u_reset_time
= account_policy_temp
* 60;
3492 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
,
3493 &account_policy_temp
);
3494 dom_info
->general2
.lockout_threshold
= account_policy_temp
;
3500 server_role
= ROLE_DOMAIN_PDC
;
3501 if (lp_server_role() == ROLE_DOMAIN_BDC
)
3502 server_role
= ROLE_DOMAIN_BDC
;
3504 dom_info
->general2
.general
.oem_information
.string
= lp_serverstring();
3505 dom_info
->general2
.general
.domain_name
.string
= lp_workgroup();
3506 dom_info
->general2
.general
.primary
.string
= global_myname();
3507 dom_info
->general2
.general
.sequence_num
= seq_num
;
3508 dom_info
->general2
.general
.domain_server_state
= DOMAIN_SERVER_ENABLED
;
3509 dom_info
->general2
.general
.role
= server_role
;
3510 dom_info
->general2
.general
.unknown3
= 1;
3512 unix_to_nt_time_abs(&dom_info
->general2
.lockout_duration
,
3514 unix_to_nt_time_abs(&dom_info
->general2
.lockout_window
,
3524 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
3525 u_lock_duration
= account_policy_temp
;
3526 if (u_lock_duration
!= -1) {
3527 u_lock_duration
*= 60;
3530 pdb_get_account_policy(AP_RESET_COUNT_TIME
, &account_policy_temp
);
3531 u_reset_time
= account_policy_temp
* 60;
3533 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
,
3534 &account_policy_temp
);
3535 dom_info
->info12
.lockout_threshold
= account_policy_temp
;
3541 unix_to_nt_time_abs(&dom_info
->info12
.lockout_duration
,
3543 unix_to_nt_time_abs(&dom_info
->info12
.lockout_window
,
3553 if (!pdb_get_seq_num(&seq_num
)) {
3554 seq_num
= time(NULL
);
3561 dom_info
->info13
.sequence_num
= seq_num
;
3562 dom_info
->info13
.domain_create_time
= 0;
3563 dom_info
->info13
.modified_count_at_last_promotion
= 0;
3567 return NT_STATUS_INVALID_INFO_CLASS
;
3570 *r
->out
.info
= dom_info
;
3572 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3577 /* W2k3 seems to use the same check for all 3 objects that can be created via
3578 * SAMR, if you try to create for example "Dialup" as an alias it says
3579 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3582 static NTSTATUS
can_create(TALLOC_CTX
*mem_ctx
, const char *new_name
)
3584 enum lsa_SidType type
;
3587 DEBUG(10, ("Checking whether [%s] can be created\n", new_name
));
3590 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3591 * whether the name already exists */
3592 result
= lookup_name(mem_ctx
, new_name
, LOOKUP_NAME_LOCAL
,
3593 NULL
, NULL
, NULL
, &type
);
3597 DEBUG(10, ("%s does not exist, can create it\n", new_name
));
3598 return NT_STATUS_OK
;
3601 DEBUG(5, ("trying to create %s, exists as %s\n",
3602 new_name
, sid_type_lookup(type
)));
3604 if (type
== SID_NAME_DOM_GRP
) {
3605 return NT_STATUS_GROUP_EXISTS
;
3607 if (type
== SID_NAME_ALIAS
) {
3608 return NT_STATUS_ALIAS_EXISTS
;
3611 /* Yes, the default is NT_STATUS_USER_EXISTS */
3612 return NT_STATUS_USER_EXISTS
;
3615 /*******************************************************************
3617 ********************************************************************/
3619 NTSTATUS
_samr_CreateUser2(pipes_struct
*p
,
3620 struct samr_CreateUser2
*r
)
3622 const char *account
= NULL
;
3624 uint32_t acb_info
= r
->in
.acct_flags
;
3625 struct samr_domain_info
*dinfo
;
3626 struct samr_user_info
*uinfo
;
3631 /* check this, when giving away 'add computer to domain' privs */
3632 uint32 des_access
= GENERIC_RIGHTS_USER_ALL_ACCESS
;
3633 bool can_add_account
= False
;
3636 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
3637 SAMR_DOMAIN_ACCESS_CREATE_USER
, NULL
,
3638 struct samr_domain_info
, &nt_status
);
3639 if (!NT_STATUS_IS_OK(nt_status
)) {
3643 if (sid_check_is_builtin(&dinfo
->sid
)) {
3644 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3645 return NT_STATUS_ACCESS_DENIED
;
3648 if (!(acb_info
== ACB_NORMAL
|| acb_info
== ACB_DOMTRUST
||
3649 acb_info
== ACB_WSTRUST
|| acb_info
== ACB_SVRTRUST
)) {
3650 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3651 this parameter is not an account type */
3652 return NT_STATUS_INVALID_PARAMETER
;
3655 account
= r
->in
.account_name
->string
;
3656 if (account
== NULL
) {
3657 return NT_STATUS_NO_MEMORY
;
3660 nt_status
= can_create(p
->mem_ctx
, account
);
3661 if (!NT_STATUS_IS_OK(nt_status
)) {
3665 /* determine which user right we need to check based on the acb_info */
3667 if (geteuid() == sec_initial_uid()) {
3668 se_priv_copy(&se_rights
, &se_priv_none
);
3669 can_add_account
= true;
3670 } else if (acb_info
& ACB_WSTRUST
) {
3671 se_priv_copy(&se_rights
, &se_machine_account
);
3672 can_add_account
= user_has_privileges(
3673 p
->server_info
->ptok
, &se_rights
);
3674 } else if (acb_info
& ACB_NORMAL
&&
3675 (account
[strlen(account
)-1] != '$')) {
3676 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3677 account for domain trusts and changes the ACB flags later */
3678 se_priv_copy(&se_rights
, &se_add_users
);
3679 can_add_account
= user_has_privileges(
3680 p
->server_info
->ptok
, &se_rights
);
3681 } else if (lp_enable_privileges()) {
3682 /* implicit assumption of a BDC or domain trust account here
3683 * (we already check the flags earlier) */
3684 /* only Domain Admins can add a BDC or domain trust */
3685 se_priv_copy(&se_rights
, &se_priv_none
);
3686 can_add_account
= nt_token_check_domain_rid(
3687 p
->server_info
->ptok
,
3688 DOMAIN_GROUP_RID_ADMINS
);
3691 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3692 uidtoname(p
->server_info
->utok
.uid
),
3693 can_add_account
? "True":"False" ));
3695 if (!can_add_account
) {
3696 return NT_STATUS_ACCESS_DENIED
;
3699 /********** BEGIN Admin BLOCK **********/
3702 nt_status
= pdb_create_user(p
->mem_ctx
, account
, acb_info
,
3706 /********** END Admin BLOCK **********/
3708 /* now check for failure */
3710 if ( !NT_STATUS_IS_OK(nt_status
) )
3713 /* Get the user's SID */
3715 sid_compose(&sid
, get_global_sam_sid(), *r
->out
.rid
);
3717 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3719 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
,
3720 &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
3721 se_map_generic(&des_access
, &usr_generic_mapping
);
3724 * JRA - TESTME. We just created this user so we
3725 * had rights to create them. Do we need to check
3726 * any further access on this object ? Can't we
3727 * just assume we have all the rights we need ?
3730 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
3731 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
3732 &acc_granted
, "_samr_CreateUser2");
3734 if ( !NT_STATUS_IS_OK(nt_status
) ) {
3738 uinfo
= policy_handle_create(p
, r
->out
.user_handle
, acc_granted
,
3739 struct samr_user_info
, &nt_status
);
3740 if (!NT_STATUS_IS_OK(nt_status
)) {
3745 /* After a "set" ensure we have no cached display info. */
3746 force_flush_samr_cache(&sid
);
3748 *r
->out
.access_granted
= acc_granted
;
3750 return NT_STATUS_OK
;
3753 /****************************************************************
3754 ****************************************************************/
3756 NTSTATUS
_samr_CreateUser(pipes_struct
*p
,
3757 struct samr_CreateUser
*r
)
3759 struct samr_CreateUser2 c
;
3760 uint32_t access_granted
;
3762 c
.in
.domain_handle
= r
->in
.domain_handle
;
3763 c
.in
.account_name
= r
->in
.account_name
;
3764 c
.in
.acct_flags
= ACB_NORMAL
;
3765 c
.in
.access_mask
= r
->in
.access_mask
;
3766 c
.out
.user_handle
= r
->out
.user_handle
;
3767 c
.out
.access_granted
= &access_granted
;
3768 c
.out
.rid
= r
->out
.rid
;
3770 return _samr_CreateUser2(p
, &c
);
3773 /*******************************************************************
3775 ********************************************************************/
3777 NTSTATUS
_samr_Connect(pipes_struct
*p
,
3778 struct samr_Connect
*r
)
3780 struct samr_connect_info
*info
;
3781 uint32_t acc_granted
;
3782 struct policy_handle hnd
;
3783 uint32 des_access
= r
->in
.access_mask
;
3788 if (!pipe_access_check(p
)) {
3789 DEBUG(3, ("access denied to _samr_Connect\n"));
3790 return NT_STATUS_ACCESS_DENIED
;
3793 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3794 was observed from a win98 client trying to enumerate users (when configured
3795 user level access control on shares) --jerry */
3797 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3799 se_map_generic( &des_access
, &sam_generic_mapping
);
3801 acc_granted
= des_access
& (SAMR_ACCESS_ENUM_DOMAINS
3802 |SAMR_ACCESS_LOOKUP_DOMAIN
);
3804 /* set up the SAMR connect_anon response */
3806 info
= policy_handle_create(p
, &hnd
, acc_granted
,
3807 struct samr_connect_info
,
3809 if (!NT_STATUS_IS_OK(status
)) {
3813 *r
->out
.connect_handle
= hnd
;
3814 return NT_STATUS_OK
;
3817 /*******************************************************************
3819 ********************************************************************/
3821 NTSTATUS
_samr_Connect2(pipes_struct
*p
,
3822 struct samr_Connect2
*r
)
3824 struct samr_connect_info
*info
= NULL
;
3825 struct policy_handle hnd
;
3826 SEC_DESC
*psd
= NULL
;
3828 uint32 des_access
= r
->in
.access_mask
;
3831 const char *fn
= "_samr_Connect2";
3833 switch (p
->hdr_req
.opnum
) {
3834 case NDR_SAMR_CONNECT2
:
3835 fn
= "_samr_Connect2";
3837 case NDR_SAMR_CONNECT3
:
3838 fn
= "_samr_Connect3";
3840 case NDR_SAMR_CONNECT4
:
3841 fn
= "_samr_Connect4";
3843 case NDR_SAMR_CONNECT5
:
3844 fn
= "_samr_Connect5";
3848 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3852 if (!pipe_access_check(p
)) {
3853 DEBUG(3, ("access denied to %s\n", fn
));
3854 return NT_STATUS_ACCESS_DENIED
;
3857 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3859 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
3860 se_map_generic(&des_access
, &sam_generic_mapping
);
3862 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
3863 NULL
, 0, des_access
, &acc_granted
, fn
);
3865 if ( !NT_STATUS_IS_OK(nt_status
) )
3868 info
= policy_handle_create(p
, &hnd
, acc_granted
,
3869 struct samr_connect_info
, &nt_status
);
3870 if (!NT_STATUS_IS_OK(nt_status
)) {
3874 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3876 *r
->out
.connect_handle
= hnd
;
3877 return NT_STATUS_OK
;
3880 /****************************************************************
3882 ****************************************************************/
3884 NTSTATUS
_samr_Connect3(pipes_struct
*p
,
3885 struct samr_Connect3
*r
)
3887 struct samr_Connect2 c
;
3889 c
.in
.system_name
= r
->in
.system_name
;
3890 c
.in
.access_mask
= r
->in
.access_mask
;
3891 c
.out
.connect_handle
= r
->out
.connect_handle
;
3893 return _samr_Connect2(p
, &c
);
3896 /*******************************************************************
3898 ********************************************************************/
3900 NTSTATUS
_samr_Connect4(pipes_struct
*p
,
3901 struct samr_Connect4
*r
)
3903 struct samr_Connect2 c
;
3905 c
.in
.system_name
= r
->in
.system_name
;
3906 c
.in
.access_mask
= r
->in
.access_mask
;
3907 c
.out
.connect_handle
= r
->out
.connect_handle
;
3909 return _samr_Connect2(p
, &c
);
3912 /*******************************************************************
3914 ********************************************************************/
3916 NTSTATUS
_samr_Connect5(pipes_struct
*p
,
3917 struct samr_Connect5
*r
)
3920 struct samr_Connect2 c
;
3921 struct samr_ConnectInfo1 info1
;
3923 info1
.client_version
= SAMR_CONNECT_AFTER_W2K
;
3926 c
.in
.system_name
= r
->in
.system_name
;
3927 c
.in
.access_mask
= r
->in
.access_mask
;
3928 c
.out
.connect_handle
= r
->out
.connect_handle
;
3930 *r
->out
.level_out
= 1;
3932 status
= _samr_Connect2(p
, &c
);
3933 if (!NT_STATUS_IS_OK(status
)) {
3937 r
->out
.info_out
->info1
= info1
;
3939 return NT_STATUS_OK
;
3942 /**********************************************************************
3944 **********************************************************************/
3946 NTSTATUS
_samr_LookupDomain(pipes_struct
*p
,
3947 struct samr_LookupDomain
*r
)
3950 struct samr_connect_info
*info
;
3951 const char *domain_name
;
3952 DOM_SID
*sid
= NULL
;
3954 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3955 Reverted that change so we will work with RAS servers again */
3957 info
= policy_handle_find(p
, r
->in
.connect_handle
,
3958 SAMR_ACCESS_LOOKUP_DOMAIN
, NULL
,
3959 struct samr_connect_info
,
3961 if (!NT_STATUS_IS_OK(status
)) {
3965 domain_name
= r
->in
.domain_name
->string
;
3967 return NT_STATUS_INVALID_PARAMETER
;
3970 sid
= TALLOC_ZERO_P(p
->mem_ctx
, struct dom_sid2
);
3972 return NT_STATUS_NO_MEMORY
;
3975 if (strequal(domain_name
, builtin_domain_name())) {
3976 sid_copy(sid
, &global_sid_Builtin
);
3978 if (!secrets_fetch_domain_sid(domain_name
, sid
)) {
3979 status
= NT_STATUS_NO_SUCH_DOMAIN
;
3983 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
,
3984 sid_string_dbg(sid
)));
3991 /**********************************************************************
3993 **********************************************************************/
3995 NTSTATUS
_samr_EnumDomains(pipes_struct
*p
,
3996 struct samr_EnumDomains
*r
)
3999 struct samr_connect_info
*info
;
4000 uint32_t num_entries
= 2;
4001 struct samr_SamEntry
*entry_array
= NULL
;
4002 struct samr_SamArray
*sam
;
4004 info
= policy_handle_find(p
, r
->in
.connect_handle
,
4005 SAMR_ACCESS_ENUM_DOMAINS
, NULL
,
4006 struct samr_connect_info
, &status
);
4007 if (!NT_STATUS_IS_OK(status
)) {
4011 sam
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
4013 return NT_STATUS_NO_MEMORY
;
4016 entry_array
= TALLOC_ZERO_ARRAY(p
->mem_ctx
,
4017 struct samr_SamEntry
,
4020 return NT_STATUS_NO_MEMORY
;
4023 entry_array
[0].idx
= 0;
4024 init_lsa_String(&entry_array
[0].name
, get_global_sam_name());
4026 entry_array
[1].idx
= 1;
4027 init_lsa_String(&entry_array
[1].name
, "Builtin");
4029 sam
->count
= num_entries
;
4030 sam
->entries
= entry_array
;
4033 *r
->out
.num_entries
= num_entries
;
4038 /*******************************************************************
4040 ********************************************************************/
4042 NTSTATUS
_samr_OpenAlias(pipes_struct
*p
,
4043 struct samr_OpenAlias
*r
)
4046 uint32 alias_rid
= r
->in
.rid
;
4047 struct samr_alias_info
*ainfo
;
4048 struct samr_domain_info
*dinfo
;
4049 SEC_DESC
*psd
= NULL
;
4051 uint32 des_access
= r
->in
.access_mask
;
4056 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
4057 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
4058 struct samr_domain_info
, &status
);
4059 if (!NT_STATUS_IS_OK(status
)) {
4063 /* append the alias' RID to it */
4065 if (!sid_compose(&sid
, &dinfo
->sid
, alias_rid
))
4066 return NT_STATUS_NO_SUCH_ALIAS
;
4068 /*check if access can be granted as requested by client. */
4070 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
4072 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &ali_generic_mapping
, NULL
, 0);
4073 se_map_generic(&des_access
,&ali_generic_mapping
);
4075 se_priv_copy( &se_rights
, &se_add_users
);
4077 status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
4078 &se_rights
, SAMR_ALIAS_ACCESS_ADD_MEMBER
,
4079 des_access
, &acc_granted
, "_samr_OpenAlias");
4081 if ( !NT_STATUS_IS_OK(status
) )
4085 /* Check we actually have the requested alias */
4086 enum lsa_SidType type
;
4091 result
= lookup_sid(NULL
, &sid
, NULL
, NULL
, &type
);
4094 if (!result
|| (type
!= SID_NAME_ALIAS
)) {
4095 return NT_STATUS_NO_SUCH_ALIAS
;
4098 /* make sure there is a mapping */
4100 if ( !sid_to_gid( &sid
, &gid
) ) {
4101 return NT_STATUS_NO_SUCH_ALIAS
;
4106 ainfo
= policy_handle_create(p
, r
->out
.alias_handle
, acc_granted
,
4107 struct samr_alias_info
, &status
);
4108 if (!NT_STATUS_IS_OK(status
)) {
4113 return NT_STATUS_OK
;
4116 /*******************************************************************
4118 ********************************************************************/
4120 static NTSTATUS
set_user_info_2(TALLOC_CTX
*mem_ctx
,
4121 struct samr_UserInfo2
*id2
,
4125 DEBUG(5,("set_user_info_2: NULL id2\n"));
4126 return NT_STATUS_ACCESS_DENIED
;
4129 copy_id2_to_sam_passwd(pwd
, id2
);
4131 return pdb_update_sam_account(pwd
);
4134 /*******************************************************************
4136 ********************************************************************/
4138 static NTSTATUS
set_user_info_4(TALLOC_CTX
*mem_ctx
,
4139 struct samr_UserInfo4
*id4
,
4143 DEBUG(5,("set_user_info_2: NULL id4\n"));
4144 return NT_STATUS_ACCESS_DENIED
;
4147 copy_id4_to_sam_passwd(pwd
, id4
);
4149 return pdb_update_sam_account(pwd
);
4152 /*******************************************************************
4154 ********************************************************************/
4156 static NTSTATUS
set_user_info_6(TALLOC_CTX
*mem_ctx
,
4157 struct samr_UserInfo6
*id6
,
4161 DEBUG(5,("set_user_info_6: NULL id6\n"));
4162 return NT_STATUS_ACCESS_DENIED
;
4165 copy_id6_to_sam_passwd(pwd
, id6
);
4167 return pdb_update_sam_account(pwd
);
4170 /*******************************************************************
4172 ********************************************************************/
4174 static NTSTATUS
set_user_info_7(TALLOC_CTX
*mem_ctx
,
4175 struct samr_UserInfo7
*id7
,
4181 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4182 return NT_STATUS_ACCESS_DENIED
;
4185 if (!id7
->account_name
.string
) {
4186 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4187 return NT_STATUS_ACCESS_DENIED
;
4190 /* check to see if the new username already exists. Note: we can't
4191 reliably lock all backends, so there is potentially the
4192 possibility that a user can be created in between this check and
4193 the rename. The rename should fail, but may not get the
4194 exact same failure status code. I think this is small enough
4195 of a window for this type of operation and the results are
4196 simply that the rename fails with a slightly different status
4197 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4199 rc
= can_create(mem_ctx
, id7
->account_name
.string
);
4201 /* when there is nothing to change, we're done here */
4202 if (NT_STATUS_EQUAL(rc
, NT_STATUS_USER_EXISTS
) &&
4203 strequal(id7
->account_name
.string
, pdb_get_username(pwd
))) {
4204 return NT_STATUS_OK
;
4206 if (!NT_STATUS_IS_OK(rc
)) {
4210 rc
= pdb_rename_sam_account(pwd
, id7
->account_name
.string
);
4215 /*******************************************************************
4217 ********************************************************************/
4219 static NTSTATUS
set_user_info_8(TALLOC_CTX
*mem_ctx
,
4220 struct samr_UserInfo8
*id8
,
4224 DEBUG(5,("set_user_info_8: NULL id8\n"));
4225 return NT_STATUS_ACCESS_DENIED
;
4228 copy_id8_to_sam_passwd(pwd
, id8
);
4230 return pdb_update_sam_account(pwd
);
4233 /*******************************************************************
4235 ********************************************************************/
4237 static NTSTATUS
set_user_info_10(TALLOC_CTX
*mem_ctx
,
4238 struct samr_UserInfo10
*id10
,
4242 DEBUG(5,("set_user_info_8: NULL id10\n"));
4243 return NT_STATUS_ACCESS_DENIED
;
4246 copy_id10_to_sam_passwd(pwd
, id10
);
4248 return pdb_update_sam_account(pwd
);
4251 /*******************************************************************
4253 ********************************************************************/
4255 static NTSTATUS
set_user_info_11(TALLOC_CTX
*mem_ctx
,
4256 struct samr_UserInfo11
*id11
,
4260 DEBUG(5,("set_user_info_11: NULL id11\n"));
4261 return NT_STATUS_ACCESS_DENIED
;
4264 copy_id11_to_sam_passwd(pwd
, id11
);
4266 return pdb_update_sam_account(pwd
);
4269 /*******************************************************************
4271 ********************************************************************/
4273 static NTSTATUS
set_user_info_12(TALLOC_CTX
*mem_ctx
,
4274 struct samr_UserInfo12
*id12
,
4278 DEBUG(5,("set_user_info_12: NULL id12\n"));
4279 return NT_STATUS_ACCESS_DENIED
;
4282 copy_id12_to_sam_passwd(pwd
, id12
);
4284 return pdb_update_sam_account(pwd
);
4287 /*******************************************************************
4289 ********************************************************************/
4291 static NTSTATUS
set_user_info_13(TALLOC_CTX
*mem_ctx
,
4292 struct samr_UserInfo13
*id13
,
4296 DEBUG(5,("set_user_info_13: NULL id13\n"));
4297 return NT_STATUS_ACCESS_DENIED
;
4300 copy_id13_to_sam_passwd(pwd
, id13
);
4302 return pdb_update_sam_account(pwd
);
4305 /*******************************************************************
4307 ********************************************************************/
4309 static NTSTATUS
set_user_info_14(TALLOC_CTX
*mem_ctx
,
4310 struct samr_UserInfo14
*id14
,
4314 DEBUG(5,("set_user_info_14: NULL id14\n"));
4315 return NT_STATUS_ACCESS_DENIED
;
4318 copy_id14_to_sam_passwd(pwd
, id14
);
4320 return pdb_update_sam_account(pwd
);
4323 /*******************************************************************
4325 ********************************************************************/
4327 static NTSTATUS
set_user_info_16(TALLOC_CTX
*mem_ctx
,
4328 struct samr_UserInfo16
*id16
,
4332 DEBUG(5,("set_user_info_16: NULL id16\n"));
4333 return NT_STATUS_ACCESS_DENIED
;
4336 copy_id16_to_sam_passwd(pwd
, id16
);
4338 return pdb_update_sam_account(pwd
);
4341 /*******************************************************************
4343 ********************************************************************/
4345 static NTSTATUS
set_user_info_17(TALLOC_CTX
*mem_ctx
,
4346 struct samr_UserInfo17
*id17
,
4350 DEBUG(5,("set_user_info_17: NULL id17\n"));
4351 return NT_STATUS_ACCESS_DENIED
;
4354 copy_id17_to_sam_passwd(pwd
, id17
);
4356 return pdb_update_sam_account(pwd
);
4359 /*******************************************************************
4361 ********************************************************************/
4363 static NTSTATUS
set_user_info_18(struct samr_UserInfo18
*id18
,
4364 TALLOC_CTX
*mem_ctx
,
4365 DATA_BLOB
*session_key
,
4369 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4370 return NT_STATUS_INVALID_PARAMETER
;
4373 if (id18
->nt_pwd_active
|| id18
->lm_pwd_active
) {
4374 if (!session_key
->length
) {
4375 return NT_STATUS_NO_USER_SESSION_KEY
;
4379 if (id18
->nt_pwd_active
) {
4383 in
= data_blob_const(id18
->nt_pwd
.hash
, 16);
4384 out
= data_blob_talloc_zero(mem_ctx
, 16);
4386 sess_crypt_blob(&out
, &in
, session_key
, false);
4388 if (!pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4389 return NT_STATUS_ACCESS_DENIED
;
4392 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4395 if (id18
->lm_pwd_active
) {
4399 in
= data_blob_const(id18
->lm_pwd
.hash
, 16);
4400 out
= data_blob_talloc_zero(mem_ctx
, 16);
4402 sess_crypt_blob(&out
, &in
, session_key
, false);
4404 if (!pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4405 return NT_STATUS_ACCESS_DENIED
;
4408 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4411 copy_id18_to_sam_passwd(pwd
, id18
);
4413 return pdb_update_sam_account(pwd
);
4416 /*******************************************************************
4418 ********************************************************************/
4420 static NTSTATUS
set_user_info_20(TALLOC_CTX
*mem_ctx
,
4421 struct samr_UserInfo20
*id20
,
4425 DEBUG(5,("set_user_info_20: NULL id20\n"));
4426 return NT_STATUS_ACCESS_DENIED
;
4429 copy_id20_to_sam_passwd(pwd
, id20
);
4431 return pdb_update_sam_account(pwd
);
4434 /*******************************************************************
4436 ********************************************************************/
4438 static NTSTATUS
set_user_info_21(struct samr_UserInfo21
*id21
,
4439 TALLOC_CTX
*mem_ctx
,
4440 DATA_BLOB
*session_key
,
4446 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4447 return NT_STATUS_INVALID_PARAMETER
;
4450 if (id21
->fields_present
== 0) {
4451 return NT_STATUS_INVALID_PARAMETER
;
4454 if (id21
->fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4455 return NT_STATUS_ACCESS_DENIED
;
4458 if (id21
->fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
4459 if (id21
->nt_password_set
) {
4462 if ((id21
->nt_owf_password
.length
!= 16) ||
4463 (id21
->nt_owf_password
.size
!= 16)) {
4464 return NT_STATUS_INVALID_PARAMETER
;
4467 if (!session_key
->length
) {
4468 return NT_STATUS_NO_USER_SESSION_KEY
;
4471 in
= data_blob_const(id21
->nt_owf_password
.array
, 16);
4472 out
= data_blob_talloc_zero(mem_ctx
, 16);
4474 sess_crypt_blob(&out
, &in
, session_key
, false);
4476 pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
);
4477 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4481 if (id21
->fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4482 if (id21
->lm_password_set
) {
4485 if ((id21
->lm_owf_password
.length
!= 16) ||
4486 (id21
->lm_owf_password
.size
!= 16)) {
4487 return NT_STATUS_INVALID_PARAMETER
;
4490 if (!session_key
->length
) {
4491 return NT_STATUS_NO_USER_SESSION_KEY
;
4494 in
= data_blob_const(id21
->lm_owf_password
.array
, 16);
4495 out
= data_blob_talloc_zero(mem_ctx
, 16);
4497 sess_crypt_blob(&out
, &in
, session_key
, false);
4499 pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
);
4500 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4504 /* we need to separately check for an account rename first */
4506 if (id21
->account_name
.string
&&
4507 (!strequal(id21
->account_name
.string
, pdb_get_username(pwd
))))
4510 /* check to see if the new username already exists. Note: we can't
4511 reliably lock all backends, so there is potentially the
4512 possibility that a user can be created in between this check and
4513 the rename. The rename should fail, but may not get the
4514 exact same failure status code. I think this is small enough
4515 of a window for this type of operation and the results are
4516 simply that the rename fails with a slightly different status
4517 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4519 status
= can_create(mem_ctx
, id21
->account_name
.string
);
4520 if (!NT_STATUS_IS_OK(status
)) {
4524 status
= pdb_rename_sam_account(pwd
, id21
->account_name
.string
);
4526 if (!NT_STATUS_IS_OK(status
)) {
4527 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4528 nt_errstr(status
)));
4532 /* set the new username so that later
4533 functions can work on the new account */
4534 pdb_set_username(pwd
, id21
->account_name
.string
, PDB_SET
);
4537 copy_id21_to_sam_passwd("INFO_21", pwd
, id21
);
4540 * The funny part about the previous two calls is
4541 * that pwd still has the password hashes from the
4542 * passdb entry. These have not been updated from
4543 * id21. I don't know if they need to be set. --jerry
4546 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4547 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4548 if ( !NT_STATUS_IS_OK(status
) ) {
4553 /* Don't worry about writing out the user account since the
4554 primary group SID is generated solely from the user's Unix
4557 /* write the change out */
4558 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4562 return NT_STATUS_OK
;
4565 /*******************************************************************
4567 ********************************************************************/
4569 static NTSTATUS
set_user_info_23(TALLOC_CTX
*mem_ctx
,
4570 struct samr_UserInfo23
*id23
,
4573 char *plaintext_buf
= NULL
;
4579 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4580 return NT_STATUS_INVALID_PARAMETER
;
4583 if (id23
->info
.fields_present
== 0) {
4584 return NT_STATUS_INVALID_PARAMETER
;
4587 if (id23
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4588 return NT_STATUS_ACCESS_DENIED
;
4591 if ((id23
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4592 (id23
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4594 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4595 pdb_get_username(pwd
)));
4597 if (!decode_pw_buffer(mem_ctx
,
4598 id23
->password
.data
,
4602 return NT_STATUS_WRONG_PASSWORD
;
4605 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4606 return NT_STATUS_ACCESS_DENIED
;
4610 copy_id23_to_sam_passwd(pwd
, id23
);
4612 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4614 /* if it's a trust account, don't update /etc/passwd */
4615 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4616 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4617 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4618 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4619 } else if (plaintext_buf
) {
4620 /* update the UNIX password */
4621 if (lp_unix_password_sync() ) {
4622 struct passwd
*passwd
;
4623 if (pdb_get_username(pwd
) == NULL
) {
4624 DEBUG(1, ("chgpasswd: User without name???\n"));
4625 return NT_STATUS_ACCESS_DENIED
;
4628 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4629 if (passwd
== NULL
) {
4630 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4633 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
4634 return NT_STATUS_ACCESS_DENIED
;
4636 TALLOC_FREE(passwd
);
4640 if (plaintext_buf
) {
4641 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4644 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) &&
4645 (!NT_STATUS_IS_OK(status
= pdb_set_unix_primary_group(mem_ctx
,
4650 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4654 return NT_STATUS_OK
;
4657 /*******************************************************************
4659 ********************************************************************/
4661 static bool set_user_info_pw(uint8
*pass
, struct samu
*pwd
)
4664 char *plaintext_buf
= NULL
;
4667 DEBUG(5, ("Attempting administrator password change for user %s\n",
4668 pdb_get_username(pwd
)));
4670 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4672 if (!decode_pw_buffer(talloc_tos(),
4680 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4684 /* if it's a trust account, don't update /etc/passwd */
4685 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4686 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4687 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4688 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4690 /* update the UNIX password */
4691 if (lp_unix_password_sync()) {
4692 struct passwd
*passwd
;
4694 if (pdb_get_username(pwd
) == NULL
) {
4695 DEBUG(1, ("chgpasswd: User without name???\n"));
4699 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4700 if (passwd
== NULL
) {
4701 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4704 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
4707 TALLOC_FREE(passwd
);
4711 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4713 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4718 /*******************************************************************
4720 ********************************************************************/
4722 static NTSTATUS
set_user_info_24(TALLOC_CTX
*mem_ctx
,
4723 struct samr_UserInfo24
*id24
,
4729 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4730 return NT_STATUS_INVALID_PARAMETER
;
4733 if (!set_user_info_pw(id24
->password
.data
, pwd
)) {
4734 return NT_STATUS_WRONG_PASSWORD
;
4737 copy_id24_to_sam_passwd(pwd
, id24
);
4739 status
= pdb_update_sam_account(pwd
);
4740 if (!NT_STATUS_IS_OK(status
)) {
4744 return NT_STATUS_OK
;
4747 /*******************************************************************
4749 ********************************************************************/
4751 static NTSTATUS
set_user_info_25(TALLOC_CTX
*mem_ctx
,
4752 struct samr_UserInfo25
*id25
,
4758 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4759 return NT_STATUS_INVALID_PARAMETER
;
4762 if (id25
->info
.fields_present
== 0) {
4763 return NT_STATUS_INVALID_PARAMETER
;
4766 if (id25
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4767 return NT_STATUS_ACCESS_DENIED
;
4770 if ((id25
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4771 (id25
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4773 if (!set_user_info_pw(id25
->password
.data
, pwd
)) {
4774 return NT_STATUS_WRONG_PASSWORD
;
4778 copy_id25_to_sam_passwd(pwd
, id25
);
4780 /* write the change out */
4781 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4786 * We need to "pdb_update_sam_account" before the unix primary group
4787 * is set, because the idealx scripts would also change the
4788 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4789 * the delete explicit / add explicit, which would then fail to find
4790 * the previous primaryGroupSid value.
4793 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4794 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4795 if ( !NT_STATUS_IS_OK(status
) ) {
4800 return NT_STATUS_OK
;
4803 /*******************************************************************
4805 ********************************************************************/
4807 static NTSTATUS
set_user_info_26(TALLOC_CTX
*mem_ctx
,
4808 struct samr_UserInfo26
*id26
,
4814 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4815 return NT_STATUS_INVALID_PARAMETER
;
4818 if (!set_user_info_pw(id26
->password
.data
, pwd
)) {
4819 return NT_STATUS_WRONG_PASSWORD
;
4822 copy_id26_to_sam_passwd(pwd
, id26
);
4824 status
= pdb_update_sam_account(pwd
);
4825 if (!NT_STATUS_IS_OK(status
)) {
4829 return NT_STATUS_OK
;
4832 /*************************************************************
4833 **************************************************************/
4835 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields
)
4837 uint32_t acc_required
= 0;
4839 /* USER_ALL_USERNAME */
4840 if (fields
& SAMR_FIELD_ACCOUNT_NAME
)
4841 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4842 /* USER_ALL_FULLNAME */
4843 if (fields
& SAMR_FIELD_FULL_NAME
)
4844 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4845 /* USER_ALL_PRIMARYGROUPID */
4846 if (fields
& SAMR_FIELD_PRIMARY_GID
)
4847 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4848 /* USER_ALL_HOMEDIRECTORY */
4849 if (fields
& SAMR_FIELD_HOME_DIRECTORY
)
4850 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4851 /* USER_ALL_HOMEDIRECTORYDRIVE */
4852 if (fields
& SAMR_FIELD_HOME_DRIVE
)
4853 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4854 /* USER_ALL_SCRIPTPATH */
4855 if (fields
& SAMR_FIELD_LOGON_SCRIPT
)
4856 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4857 /* USER_ALL_PROFILEPATH */
4858 if (fields
& SAMR_FIELD_PROFILE_PATH
)
4859 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4860 /* USER_ALL_ADMINCOMMENT */
4861 if (fields
& SAMR_FIELD_COMMENT
)
4862 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4863 /* USER_ALL_WORKSTATIONS */
4864 if (fields
& SAMR_FIELD_WORKSTATIONS
)
4865 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4866 /* USER_ALL_LOGONHOURS */
4867 if (fields
& SAMR_FIELD_LOGON_HOURS
)
4868 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4869 /* USER_ALL_ACCOUNTEXPIRES */
4870 if (fields
& SAMR_FIELD_ACCT_EXPIRY
)
4871 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4872 /* USER_ALL_USERACCOUNTCONTROL */
4873 if (fields
& SAMR_FIELD_ACCT_FLAGS
)
4874 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4875 /* USER_ALL_PARAMETERS */
4876 if (fields
& SAMR_FIELD_PARAMETERS
)
4877 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4878 /* USER_ALL_USERCOMMENT */
4879 if (fields
& SAMR_FIELD_COMMENT
)
4880 acc_required
|= SAMR_USER_ACCESS_SET_LOC_COM
;
4881 /* USER_ALL_COUNTRYCODE */
4882 if (fields
& SAMR_FIELD_COUNTRY_CODE
)
4883 acc_required
|= SAMR_USER_ACCESS_SET_LOC_COM
;
4884 /* USER_ALL_CODEPAGE */
4885 if (fields
& SAMR_FIELD_CODE_PAGE
)
4886 acc_required
|= SAMR_USER_ACCESS_SET_LOC_COM
;
4887 /* USER_ALL_NTPASSWORDPRESENT */
4888 if (fields
& SAMR_FIELD_NT_PASSWORD_PRESENT
)
4889 acc_required
|= SAMR_USER_ACCESS_SET_PASSWORD
;
4890 /* USER_ALL_LMPASSWORDPRESENT */
4891 if (fields
& SAMR_FIELD_LM_PASSWORD_PRESENT
)
4892 acc_required
|= SAMR_USER_ACCESS_SET_PASSWORD
;
4893 /* USER_ALL_PASSWORDEXPIRED */
4894 if (fields
& SAMR_FIELD_EXPIRED_FLAG
)
4895 acc_required
|= SAMR_USER_ACCESS_SET_PASSWORD
;
4897 return acc_required
;
4900 /*******************************************************************
4902 ********************************************************************/
4904 NTSTATUS
_samr_SetUserInfo(pipes_struct
*p
,
4905 struct samr_SetUserInfo
*r
)
4907 struct samr_user_info
*uinfo
;
4909 struct samu
*pwd
= NULL
;
4910 union samr_UserInfo
*info
= r
->in
.info
;
4911 uint32_t acc_required
= 0;
4912 uint32_t fields
= 0;
4915 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__
));
4917 /* This is tricky. A WinXP domain join sets
4918 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4919 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4920 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4921 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4922 we'll use the set from the WinXP join as the basis. */
4924 switch (r
->in
.level
) {
4925 case 2: /* UserPreferencesInformation */
4926 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
4927 acc_required
= SAMR_USER_ACCESS_SET_ATTRIBUTES
| SAMR_USER_ACCESS_SET_LOC_COM
;
4929 case 4: /* UserLogonHoursInformation */
4930 case 6: /* UserNameInformation */
4931 case 7: /* UserAccountNameInformation */
4932 case 8: /* UserFullNameInformation */
4933 case 9: /* UserPrimaryGroupInformation */
4934 case 10: /* UserHomeInformation */
4935 case 11: /* UserScriptInformation */
4936 case 12: /* UserProfileInformation */
4937 case 13: /* UserAdminCommentInformation */
4938 case 14: /* UserWorkStationsInformation */
4939 case 16: /* UserControlInformation */
4940 case 17: /* UserExpiresInformation */
4941 case 20: /* UserParametersInformation */
4942 /* USER_WRITE_ACCOUNT */
4943 acc_required
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4945 case 18: /* UserInternal1Information */
4946 /* FIXME: gd, this is a guess */
4947 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
;
4949 case 21: /* UserAllInformation */
4950 fields
= info
->info21
.fields_present
;
4951 acc_required
= samr_set_user_info_map_fields_to_access_mask(fields
);
4953 case 23: /* UserInternal4Information */
4954 fields
= info
->info23
.info
.fields_present
;
4955 acc_required
= samr_set_user_info_map_fields_to_access_mask(fields
);
4957 case 25: /* UserInternal4InformationNew */
4958 fields
= info
->info25
.info
.fields_present
;
4959 acc_required
= samr_set_user_info_map_fields_to_access_mask(fields
);
4961 case 24: /* UserInternal5Information */
4962 case 26: /* UserInternal5InformationNew */
4963 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
;
4966 return NT_STATUS_INVALID_INFO_CLASS
;
4969 uinfo
= policy_handle_find(p
, r
->in
.user_handle
, acc_required
, NULL
,
4970 struct samr_user_info
, &status
);
4971 if (!NT_STATUS_IS_OK(status
)) {
4975 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4976 sid_string_dbg(&uinfo
->sid
), r
->in
.level
));
4979 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4980 return NT_STATUS_INVALID_INFO_CLASS
;
4983 if (!(pwd
= samu_new(NULL
))) {
4984 return NT_STATUS_NO_MEMORY
;
4988 ret
= pdb_getsampwsid(pwd
, &uinfo
->sid
);
4993 return NT_STATUS_NO_SUCH_USER
;
4996 /* ================ BEGIN Privilege BLOCK ================ */
5000 /* ok! user info levels (lots: see MSDEV help), off we go... */
5002 switch (r
->in
.level
) {
5005 status
= set_user_info_2(p
->mem_ctx
,
5010 status
= set_user_info_4(p
->mem_ctx
,
5015 status
= set_user_info_6(p
->mem_ctx
,
5020 status
= set_user_info_7(p
->mem_ctx
,
5025 status
= set_user_info_8(p
->mem_ctx
,
5030 status
= set_user_info_10(p
->mem_ctx
,
5031 &info
->info10
, pwd
);
5035 status
= set_user_info_11(p
->mem_ctx
,
5036 &info
->info11
, pwd
);
5040 status
= set_user_info_12(p
->mem_ctx
,
5041 &info
->info12
, pwd
);
5045 status
= set_user_info_13(p
->mem_ctx
,
5046 &info
->info13
, pwd
);
5050 status
= set_user_info_14(p
->mem_ctx
,
5051 &info
->info14
, pwd
);
5055 status
= set_user_info_16(p
->mem_ctx
,
5056 &info
->info16
, pwd
);
5060 status
= set_user_info_17(p
->mem_ctx
,
5061 &info
->info17
, pwd
);
5065 /* Used by AS/U JRA. */
5066 status
= set_user_info_18(&info
->info18
,
5068 &p
->server_info
->user_session_key
,
5073 status
= set_user_info_20(p
->mem_ctx
,
5074 &info
->info20
, pwd
);
5078 status
= set_user_info_21(&info
->info21
,
5080 &p
->server_info
->user_session_key
,
5085 if (!p
->server_info
->user_session_key
.length
) {
5086 status
= NT_STATUS_NO_USER_SESSION_KEY
;
5088 arcfour_crypt_blob(info
->info23
.password
.data
, 516,
5089 &p
->server_info
->user_session_key
);
5091 dump_data(100, info
->info23
.password
.data
, 516);
5093 status
= set_user_info_23(p
->mem_ctx
,
5094 &info
->info23
, pwd
);
5098 if (!p
->server_info
->user_session_key
.length
) {
5099 status
= NT_STATUS_NO_USER_SESSION_KEY
;
5101 arcfour_crypt_blob(info
->info24
.password
.data
,
5103 &p
->server_info
->user_session_key
);
5105 dump_data(100, info
->info24
.password
.data
, 516);
5107 status
= set_user_info_24(p
->mem_ctx
,
5108 &info
->info24
, pwd
);
5112 if (!p
->server_info
->user_session_key
.length
) {
5113 status
= NT_STATUS_NO_USER_SESSION_KEY
;
5115 encode_or_decode_arc4_passwd_buffer(
5116 info
->info25
.password
.data
,
5117 &p
->server_info
->user_session_key
);
5119 dump_data(100, info
->info25
.password
.data
, 532);
5121 status
= set_user_info_25(p
->mem_ctx
,
5122 &info
->info25
, pwd
);
5126 if (!p
->server_info
->user_session_key
.length
) {
5127 status
= NT_STATUS_NO_USER_SESSION_KEY
;
5129 encode_or_decode_arc4_passwd_buffer(
5130 info
->info26
.password
.data
,
5131 &p
->server_info
->user_session_key
);
5133 dump_data(100, info
->info26
.password
.data
, 516);
5135 status
= set_user_info_26(p
->mem_ctx
,
5136 &info
->info26
, pwd
);
5140 status
= NT_STATUS_INVALID_INFO_CLASS
;
5147 /* ================ END Privilege BLOCK ================ */
5149 if (NT_STATUS_IS_OK(status
)) {
5150 force_flush_samr_cache(&uinfo
->sid
);
5156 /*******************************************************************
5158 ********************************************************************/
5160 NTSTATUS
_samr_SetUserInfo2(pipes_struct
*p
,
5161 struct samr_SetUserInfo2
*r
)
5163 struct samr_SetUserInfo q
;
5165 q
.in
.user_handle
= r
->in
.user_handle
;
5166 q
.in
.level
= r
->in
.level
;
5167 q
.in
.info
= r
->in
.info
;
5169 return _samr_SetUserInfo(p
, &q
);
5172 /*********************************************************************
5173 _samr_GetAliasMembership
5174 *********************************************************************/
5176 NTSTATUS
_samr_GetAliasMembership(pipes_struct
*p
,
5177 struct samr_GetAliasMembership
*r
)
5179 size_t num_alias_rids
;
5181 struct samr_domain_info
*dinfo
;
5188 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__
));
5190 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
5191 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5192 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
5193 struct samr_domain_info
, &status
);
5194 if (!NT_STATUS_IS_OK(status
)) {
5198 if (!sid_check_is_domain(&dinfo
->sid
) &&
5199 !sid_check_is_builtin(&dinfo
->sid
))
5200 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
5202 if (r
->in
.sids
->num_sids
) {
5203 members
= TALLOC_ARRAY(p
->mem_ctx
, DOM_SID
, r
->in
.sids
->num_sids
);
5205 if (members
== NULL
)
5206 return NT_STATUS_NO_MEMORY
;
5211 for (i
=0; i
<r
->in
.sids
->num_sids
; i
++)
5212 sid_copy(&members
[i
], r
->in
.sids
->sids
[i
].sid
);
5218 status
= pdb_enum_alias_memberships(p
->mem_ctx
, &dinfo
->sid
, members
,
5219 r
->in
.sids
->num_sids
,
5220 &alias_rids
, &num_alias_rids
);
5223 if (!NT_STATUS_IS_OK(status
)) {
5227 r
->out
.rids
->count
= num_alias_rids
;
5228 r
->out
.rids
->ids
= alias_rids
;
5230 return NT_STATUS_OK
;
5233 /*********************************************************************
5234 _samr_GetMembersInAlias
5235 *********************************************************************/
5237 NTSTATUS
_samr_GetMembersInAlias(pipes_struct
*p
,
5238 struct samr_GetMembersInAlias
*r
)
5240 struct samr_alias_info
*ainfo
;
5243 size_t num_sids
= 0;
5244 struct lsa_SidPtr
*sids
= NULL
;
5245 DOM_SID
*pdb_sids
= NULL
;
5247 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5248 SAMR_ALIAS_ACCESS_GET_MEMBERS
, NULL
,
5249 struct samr_alias_info
, &status
);
5250 if (!NT_STATUS_IS_OK(status
)) {
5254 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo
->sid
)));
5257 status
= pdb_enum_aliasmem(&ainfo
->sid
, &pdb_sids
, &num_sids
);
5260 if (!NT_STATUS_IS_OK(status
)) {
5265 sids
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, struct lsa_SidPtr
, num_sids
);
5267 TALLOC_FREE(pdb_sids
);
5268 return NT_STATUS_NO_MEMORY
;
5272 for (i
= 0; i
< num_sids
; i
++) {
5273 sids
[i
].sid
= sid_dup_talloc(p
->mem_ctx
, &pdb_sids
[i
]);
5275 TALLOC_FREE(pdb_sids
);
5276 return NT_STATUS_NO_MEMORY
;
5280 r
->out
.sids
->num_sids
= num_sids
;
5281 r
->out
.sids
->sids
= sids
;
5283 TALLOC_FREE(pdb_sids
);
5285 return NT_STATUS_OK
;
5288 /*********************************************************************
5289 _samr_QueryGroupMember
5290 *********************************************************************/
5292 NTSTATUS
_samr_QueryGroupMember(pipes_struct
*p
,
5293 struct samr_QueryGroupMember
*r
)
5295 struct samr_group_info
*ginfo
;
5296 size_t i
, num_members
;
5302 struct samr_RidTypeArray
*rids
= NULL
;
5304 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5305 SAMR_GROUP_ACCESS_GET_MEMBERS
, NULL
,
5306 struct samr_group_info
, &status
);
5307 if (!NT_STATUS_IS_OK(status
)) {
5311 rids
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_RidTypeArray
);
5313 return NT_STATUS_NO_MEMORY
;
5316 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo
->sid
)));
5318 if (!sid_check_is_in_our_domain(&ginfo
->sid
)) {
5319 DEBUG(3, ("sid %s is not in our domain\n",
5320 sid_string_dbg(&ginfo
->sid
)));
5321 return NT_STATUS_NO_SUCH_GROUP
;
5324 DEBUG(10, ("lookup on Domain SID\n"));
5327 status
= pdb_enum_group_members(p
->mem_ctx
, &ginfo
->sid
,
5328 &rid
, &num_members
);
5331 if (!NT_STATUS_IS_OK(status
))
5335 attr
=TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_members
);
5337 return NT_STATUS_NO_MEMORY
;
5343 for (i
=0; i
<num_members
; i
++)
5344 attr
[i
] = SID_NAME_USER
;
5346 rids
->count
= num_members
;
5350 *r
->out
.rids
= rids
;
5352 return NT_STATUS_OK
;
5355 /*********************************************************************
5356 _samr_AddAliasMember
5357 *********************************************************************/
5359 NTSTATUS
_samr_AddAliasMember(pipes_struct
*p
,
5360 struct samr_AddAliasMember
*r
)
5362 struct samr_alias_info
*ainfo
;
5365 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5366 SAMR_ALIAS_ACCESS_ADD_MEMBER
, NULL
,
5367 struct samr_alias_info
, &status
);
5368 if (!NT_STATUS_IS_OK(status
)) {
5372 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo
->sid
)));
5374 /******** BEGIN SeAddUsers BLOCK *********/
5377 status
= pdb_add_aliasmem(&ainfo
->sid
, r
->in
.sid
);
5380 /******** END SeAddUsers BLOCK *********/
5382 if (NT_STATUS_IS_OK(status
)) {
5383 force_flush_samr_cache(&ainfo
->sid
);
5389 /*********************************************************************
5390 _samr_DeleteAliasMember
5391 *********************************************************************/
5393 NTSTATUS
_samr_DeleteAliasMember(pipes_struct
*p
,
5394 struct samr_DeleteAliasMember
*r
)
5396 struct samr_alias_info
*ainfo
;
5399 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5400 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
, NULL
,
5401 struct samr_alias_info
, &status
);
5402 if (!NT_STATUS_IS_OK(status
)) {
5406 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5407 sid_string_dbg(&ainfo
->sid
)));
5409 /******** BEGIN SeAddUsers BLOCK *********/
5412 status
= pdb_del_aliasmem(&ainfo
->sid
, r
->in
.sid
);
5415 /******** END SeAddUsers BLOCK *********/
5417 if (NT_STATUS_IS_OK(status
)) {
5418 force_flush_samr_cache(&ainfo
->sid
);
5424 /*********************************************************************
5425 _samr_AddGroupMember
5426 *********************************************************************/
5428 NTSTATUS
_samr_AddGroupMember(pipes_struct
*p
,
5429 struct samr_AddGroupMember
*r
)
5431 struct samr_group_info
*ginfo
;
5435 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5436 SAMR_GROUP_ACCESS_ADD_MEMBER
, NULL
,
5437 struct samr_group_info
, &status
);
5438 if (!NT_STATUS_IS_OK(status
)) {
5442 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo
->sid
)));
5444 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo
->sid
,
5446 return NT_STATUS_INVALID_HANDLE
;
5449 /******** BEGIN SeAddUsers BLOCK *********/
5452 status
= pdb_add_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5455 /******** END SeAddUsers BLOCK *********/
5457 force_flush_samr_cache(&ginfo
->sid
);
5462 /*********************************************************************
5463 _samr_DeleteGroupMember
5464 *********************************************************************/
5466 NTSTATUS
_samr_DeleteGroupMember(pipes_struct
*p
,
5467 struct samr_DeleteGroupMember
*r
)
5470 struct samr_group_info
*ginfo
;
5475 * delete the group member named r->in.rid
5476 * who is a member of the sid associated with the handle
5477 * the rid is a user's rid as the group is a domain group.
5480 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5481 SAMR_GROUP_ACCESS_REMOVE_MEMBER
, NULL
,
5482 struct samr_group_info
, &status
);
5483 if (!NT_STATUS_IS_OK(status
)) {
5487 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo
->sid
,
5489 return NT_STATUS_INVALID_HANDLE
;
5492 /******** BEGIN SeAddUsers BLOCK *********/
5495 status
= pdb_del_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5498 /******** END SeAddUsers BLOCK *********/
5500 force_flush_samr_cache(&ginfo
->sid
);
5505 /*********************************************************************
5507 *********************************************************************/
5509 NTSTATUS
_samr_DeleteUser(pipes_struct
*p
,
5510 struct samr_DeleteUser
*r
)
5512 struct samr_user_info
*uinfo
;
5514 struct samu
*sam_pass
=NULL
;
5517 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__
));
5519 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
5520 STD_RIGHT_DELETE_ACCESS
, NULL
,
5521 struct samr_user_info
, &status
);
5522 if (!NT_STATUS_IS_OK(status
)) {
5526 if (!sid_check_is_in_our_domain(&uinfo
->sid
))
5527 return NT_STATUS_CANNOT_DELETE
;
5529 /* check if the user exists before trying to delete */
5530 if ( !(sam_pass
= samu_new( NULL
)) ) {
5531 return NT_STATUS_NO_MEMORY
;
5535 ret
= pdb_getsampwsid(sam_pass
, &uinfo
->sid
);
5539 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5540 sid_string_dbg(&uinfo
->sid
)));
5541 TALLOC_FREE(sam_pass
);
5542 return NT_STATUS_NO_SUCH_USER
;
5545 /******** BEGIN SeAddUsers BLOCK *********/
5548 status
= pdb_delete_user(p
->mem_ctx
, sam_pass
);
5551 /******** END SeAddUsers BLOCK *********/
5553 if ( !NT_STATUS_IS_OK(status
) ) {
5554 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5555 "user %s: %s.\n", pdb_get_username(sam_pass
),
5556 nt_errstr(status
)));
5557 TALLOC_FREE(sam_pass
);
5562 TALLOC_FREE(sam_pass
);
5564 if (!close_policy_hnd(p
, r
->in
.user_handle
))
5565 return NT_STATUS_OBJECT_NAME_INVALID
;
5567 ZERO_STRUCTP(r
->out
.user_handle
);
5569 force_flush_samr_cache(&uinfo
->sid
);
5571 return NT_STATUS_OK
;
5574 /*********************************************************************
5575 _samr_DeleteDomainGroup
5576 *********************************************************************/
5578 NTSTATUS
_samr_DeleteDomainGroup(pipes_struct
*p
,
5579 struct samr_DeleteDomainGroup
*r
)
5581 struct samr_group_info
*ginfo
;
5585 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__
));
5587 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5588 STD_RIGHT_DELETE_ACCESS
, NULL
,
5589 struct samr_group_info
, &status
);
5590 if (!NT_STATUS_IS_OK(status
)) {
5594 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo
->sid
)));
5596 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo
->sid
,
5598 return NT_STATUS_NO_SUCH_GROUP
;
5601 /******** BEGIN SeAddUsers BLOCK *********/
5604 status
= pdb_delete_dom_group(p
->mem_ctx
, group_rid
);
5607 /******** END SeAddUsers BLOCK *********/
5609 if ( !NT_STATUS_IS_OK(status
) ) {
5610 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5611 "entry for group %s: %s\n",
5612 sid_string_dbg(&ginfo
->sid
),
5613 nt_errstr(status
)));
5617 if (!close_policy_hnd(p
, r
->in
.group_handle
))
5618 return NT_STATUS_OBJECT_NAME_INVALID
;
5620 force_flush_samr_cache(&ginfo
->sid
);
5622 return NT_STATUS_OK
;
5625 /*********************************************************************
5626 _samr_DeleteDomAlias
5627 *********************************************************************/
5629 NTSTATUS
_samr_DeleteDomAlias(pipes_struct
*p
,
5630 struct samr_DeleteDomAlias
*r
)
5632 struct samr_alias_info
*ainfo
;
5635 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__
));
5637 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5638 STD_RIGHT_DELETE_ACCESS
, NULL
,
5639 struct samr_alias_info
, &status
);
5640 if (!NT_STATUS_IS_OK(status
)) {
5644 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo
->sid
)));
5646 /* Don't let Windows delete builtin groups */
5648 if ( sid_check_is_in_builtin( &ainfo
->sid
) ) {
5649 return NT_STATUS_SPECIAL_ACCOUNT
;
5652 if (!sid_check_is_in_our_domain(&ainfo
->sid
))
5653 return NT_STATUS_NO_SUCH_ALIAS
;
5655 DEBUG(10, ("lookup on Local SID\n"));
5657 /******** BEGIN SeAddUsers BLOCK *********/
5660 /* Have passdb delete the alias */
5661 status
= pdb_delete_alias(&ainfo
->sid
);
5664 /******** END SeAddUsers BLOCK *********/
5666 if ( !NT_STATUS_IS_OK(status
))
5669 if (!close_policy_hnd(p
, r
->in
.alias_handle
))
5670 return NT_STATUS_OBJECT_NAME_INVALID
;
5672 force_flush_samr_cache(&ainfo
->sid
);
5674 return NT_STATUS_OK
;
5677 /*********************************************************************
5678 _samr_CreateDomainGroup
5679 *********************************************************************/
5681 NTSTATUS
_samr_CreateDomainGroup(pipes_struct
*p
,
5682 struct samr_CreateDomainGroup
*r
)
5687 struct samr_domain_info
*dinfo
;
5688 struct samr_group_info
*ginfo
;
5690 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
5691 SAMR_DOMAIN_ACCESS_CREATE_GROUP
, NULL
,
5692 struct samr_domain_info
, &status
);
5693 if (!NT_STATUS_IS_OK(status
)) {
5697 if (!sid_equal(&dinfo
->sid
, get_global_sam_sid()))
5698 return NT_STATUS_ACCESS_DENIED
;
5700 name
= r
->in
.name
->string
;
5702 return NT_STATUS_NO_MEMORY
;
5705 status
= can_create(p
->mem_ctx
, name
);
5706 if (!NT_STATUS_IS_OK(status
)) {
5710 /******** BEGIN SeAddUsers BLOCK *********/
5713 /* check that we successfully create the UNIX group */
5714 status
= pdb_create_dom_group(p
->mem_ctx
, name
, r
->out
.rid
);
5717 /******** END SeAddUsers BLOCK *********/
5719 /* check if we should bail out here */
5721 if ( !NT_STATUS_IS_OK(status
) )
5724 ginfo
= policy_handle_create(p
, r
->out
.group_handle
,
5725 GENERIC_RIGHTS_GROUP_ALL_ACCESS
,
5726 struct samr_group_info
, &status
);
5727 if (!NT_STATUS_IS_OK(status
)) {
5730 sid_compose(&ginfo
->sid
, &dinfo
->sid
, *r
->out
.rid
);
5732 force_flush_samr_cache(&dinfo
->sid
);
5734 return NT_STATUS_OK
;
5737 /*********************************************************************
5738 _samr_CreateDomAlias
5739 *********************************************************************/
5741 NTSTATUS
_samr_CreateDomAlias(pipes_struct
*p
,
5742 struct samr_CreateDomAlias
*r
)
5745 const char *name
= NULL
;
5746 struct samr_domain_info
*dinfo
;
5747 struct samr_alias_info
*ainfo
;
5751 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
5752 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
, NULL
,
5753 struct samr_domain_info
, &result
);
5754 if (!NT_STATUS_IS_OK(result
)) {
5758 if (!sid_equal(&dinfo
->sid
, get_global_sam_sid()))
5759 return NT_STATUS_ACCESS_DENIED
;
5761 name
= r
->in
.alias_name
->string
;
5763 result
= can_create(p
->mem_ctx
, name
);
5764 if (!NT_STATUS_IS_OK(result
)) {
5768 /******** BEGIN SeAddUsers BLOCK *********/
5771 /* Have passdb create the alias */
5772 result
= pdb_create_alias(name
, r
->out
.rid
);
5775 /******** END SeAddUsers BLOCK *********/
5777 if (!NT_STATUS_IS_OK(result
)) {
5778 DEBUG(10, ("pdb_create_alias failed: %s\n",
5779 nt_errstr(result
)));
5783 sid_compose(&info_sid
, &dinfo
->sid
, *r
->out
.rid
);
5785 if (!sid_to_gid(&info_sid
, &gid
)) {
5786 DEBUG(10, ("Could not find alias just created\n"));
5787 return NT_STATUS_ACCESS_DENIED
;
5790 /* check if the group has been successfully created */
5791 if ( getgrgid(gid
) == NULL
) {
5792 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5793 (unsigned int)gid
));
5794 return NT_STATUS_ACCESS_DENIED
;
5797 ainfo
= policy_handle_create(p
, r
->out
.alias_handle
,
5798 GENERIC_RIGHTS_ALIAS_ALL_ACCESS
,
5799 struct samr_alias_info
, &result
);
5800 if (!NT_STATUS_IS_OK(result
)) {
5803 ainfo
->sid
= info_sid
;
5805 force_flush_samr_cache(&info_sid
);
5807 return NT_STATUS_OK
;
5810 /*********************************************************************
5811 _samr_QueryGroupInfo
5812 *********************************************************************/
5814 NTSTATUS
_samr_QueryGroupInfo(pipes_struct
*p
,
5815 struct samr_QueryGroupInfo
*r
)
5817 struct samr_group_info
*ginfo
;
5820 union samr_GroupInfo
*info
= NULL
;
5822 uint32_t attributes
= SE_GROUP_MANDATORY
|
5823 SE_GROUP_ENABLED_BY_DEFAULT
|
5825 const char *group_name
= NULL
;
5826 const char *group_description
= NULL
;
5828 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5829 SAMR_GROUP_ACCESS_LOOKUP_INFO
, NULL
,
5830 struct samr_group_info
, &status
);
5831 if (!NT_STATUS_IS_OK(status
)) {
5836 ret
= get_domain_group_from_sid(ginfo
->sid
, &map
);
5839 return NT_STATUS_INVALID_HANDLE
;
5841 /* FIXME: map contains fstrings */
5842 group_name
= talloc_strdup(r
, map
.nt_name
);
5843 group_description
= talloc_strdup(r
, map
.comment
);
5845 info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_GroupInfo
);
5847 return NT_STATUS_NO_MEMORY
;
5850 switch (r
->in
.level
) {
5856 status
= pdb_enum_group_members(
5857 p
->mem_ctx
, &ginfo
->sid
, &members
,
5861 if (!NT_STATUS_IS_OK(status
)) {
5865 info
->all
.name
.string
= group_name
;
5866 info
->all
.attributes
= attributes
;
5867 info
->all
.num_members
= num_members
;
5868 info
->all
.description
.string
= group_description
;
5872 info
->name
.string
= group_name
;
5875 info
->attributes
.attributes
= attributes
;
5878 info
->description
.string
= group_description
;
5888 status = pdb_enum_group_members(
5889 p->mem_ctx, &ginfo->sid, &members,
5893 if (!NT_STATUS_IS_OK(status)) {
5897 info
->all2
.name
.string
= group_name
;
5898 info
->all2
.attributes
= attributes
;
5899 info
->all2
.num_members
= 0; /* num_members - in w2k3 this is always 0 */
5900 info
->all2
.description
.string
= group_description
;
5905 return NT_STATUS_INVALID_INFO_CLASS
;
5908 *r
->out
.info
= info
;
5910 return NT_STATUS_OK
;
5913 /*********************************************************************
5915 *********************************************************************/
5917 NTSTATUS
_samr_SetGroupInfo(pipes_struct
*p
,
5918 struct samr_SetGroupInfo
*r
)
5920 struct samr_group_info
*ginfo
;
5925 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5926 SAMR_GROUP_ACCESS_SET_INFO
, NULL
,
5927 struct samr_group_info
, &status
);
5928 if (!NT_STATUS_IS_OK(status
)) {
5933 ret
= get_domain_group_from_sid(ginfo
->sid
, &map
);
5936 return NT_STATUS_NO_SUCH_GROUP
;
5938 switch (r
->in
.level
) {
5940 fstrcpy(map
.comment
, r
->in
.info
->all
.description
.string
);
5943 /* group rename is not supported yet */
5944 return NT_STATUS_NOT_SUPPORTED
;
5946 fstrcpy(map
.comment
, r
->in
.info
->description
.string
);
5949 return NT_STATUS_INVALID_INFO_CLASS
;
5952 /******** BEGIN SeAddUsers BLOCK *********/
5955 status
= pdb_update_group_mapping_entry(&map
);
5958 /******** End SeAddUsers BLOCK *********/
5960 if (NT_STATUS_IS_OK(status
)) {
5961 force_flush_samr_cache(&ginfo
->sid
);
5967 /*********************************************************************
5969 *********************************************************************/
5971 NTSTATUS
_samr_SetAliasInfo(pipes_struct
*p
,
5972 struct samr_SetAliasInfo
*r
)
5974 struct samr_alias_info
*ainfo
;
5975 struct acct_info info
;
5978 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5979 SAMR_ALIAS_ACCESS_SET_INFO
, NULL
,
5980 struct samr_alias_info
, &status
);
5981 if (!NT_STATUS_IS_OK(status
)) {
5985 /* get the current group information */
5988 status
= pdb_get_aliasinfo( &ainfo
->sid
, &info
);
5991 if ( !NT_STATUS_IS_OK(status
))
5994 switch (r
->in
.level
) {
5999 /* We currently do not support renaming groups in the
6000 the BUILTIN domain. Refer to util_builtin.c to understand
6001 why. The eventually needs to be fixed to be like Windows
6002 where you can rename builtin groups, just not delete them */
6004 if ( sid_check_is_in_builtin( &ainfo
->sid
) ) {
6005 return NT_STATUS_SPECIAL_ACCOUNT
;
6008 /* There has to be a valid name (and it has to be different) */
6010 if ( !r
->in
.info
->name
.string
)
6011 return NT_STATUS_INVALID_PARAMETER
;
6013 /* If the name is the same just reply "ok". Yes this
6014 doesn't allow you to change the case of a group name. */
6016 if ( strequal( r
->in
.info
->name
.string
, info
.acct_name
) )
6017 return NT_STATUS_OK
;
6019 fstrcpy( info
.acct_name
, r
->in
.info
->name
.string
);
6021 /* make sure the name doesn't already exist as a user
6024 fstr_sprintf( group_name
, "%s\\%s", global_myname(), info
.acct_name
);
6025 status
= can_create( p
->mem_ctx
, group_name
);
6026 if ( !NT_STATUS_IS_OK( status
) )
6030 case ALIASINFODESCRIPTION
:
6031 if (r
->in
.info
->description
.string
) {
6032 fstrcpy(info
.acct_desc
,
6033 r
->in
.info
->description
.string
);
6035 fstrcpy( info
.acct_desc
, "" );
6039 return NT_STATUS_INVALID_INFO_CLASS
;
6042 /******** BEGIN SeAddUsers BLOCK *********/
6045 status
= pdb_set_aliasinfo( &ainfo
->sid
, &info
);
6048 /******** End SeAddUsers BLOCK *********/
6050 if (NT_STATUS_IS_OK(status
))
6051 force_flush_samr_cache(&ainfo
->sid
);
6056 /****************************************************************
6058 ****************************************************************/
6060 NTSTATUS
_samr_GetDomPwInfo(pipes_struct
*p
,
6061 struct samr_GetDomPwInfo
*r
)
6063 uint32_t min_password_length
= 0;
6064 uint32_t password_properties
= 0;
6066 /* Perform access check. Since this rpc does not require a
6067 policy handle it will not be caught by the access checks on
6068 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6070 if (!pipe_access_check(p
)) {
6071 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6072 return NT_STATUS_ACCESS_DENIED
;
6076 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
,
6077 &min_password_length
);
6078 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
6079 &password_properties
);
6082 if (lp_check_password_script() && *lp_check_password_script()) {
6083 password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
6086 r
->out
.info
->min_password_length
= min_password_length
;
6087 r
->out
.info
->password_properties
= password_properties
;
6089 return NT_STATUS_OK
;
6092 /*********************************************************************
6094 *********************************************************************/
6096 NTSTATUS
_samr_OpenGroup(pipes_struct
*p
,
6097 struct samr_OpenGroup
*r
)
6102 struct samr_domain_info
*dinfo
;
6103 struct samr_group_info
*ginfo
;
6104 SEC_DESC
*psd
= NULL
;
6106 uint32 des_access
= r
->in
.access_mask
;
6112 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6113 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
6114 struct samr_domain_info
, &status
);
6115 if (!NT_STATUS_IS_OK(status
)) {
6119 /*check if access can be granted as requested by client. */
6120 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
6122 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &grp_generic_mapping
, NULL
, 0);
6123 se_map_generic(&des_access
,&grp_generic_mapping
);
6125 se_priv_copy( &se_rights
, &se_add_users
);
6127 status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
6128 &se_rights
, SAMR_GROUP_ACCESS_ADD_MEMBER
,
6129 des_access
, &acc_granted
, "_samr_OpenGroup");
6131 if ( !NT_STATUS_IS_OK(status
) )
6134 /* this should not be hard-coded like this */
6136 if (!sid_equal(&dinfo
->sid
, get_global_sam_sid()))
6137 return NT_STATUS_ACCESS_DENIED
;
6139 sid_compose(&info_sid
, &dinfo
->sid
, r
->in
.rid
);
6141 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6142 sid_string_dbg(&info_sid
)));
6144 /* check if that group really exists */
6146 ret
= get_domain_group_from_sid(info_sid
, &map
);
6149 return NT_STATUS_NO_SUCH_GROUP
;
6151 ginfo
= policy_handle_create(p
, r
->out
.group_handle
,
6152 GENERIC_RIGHTS_GROUP_ALL_ACCESS
,
6153 struct samr_group_info
, &status
);
6154 if (!NT_STATUS_IS_OK(status
)) {
6157 ginfo
->sid
= info_sid
;
6159 return NT_STATUS_OK
;
6162 /*********************************************************************
6163 _samr_RemoveMemberFromForeignDomain
6164 *********************************************************************/
6166 NTSTATUS
_samr_RemoveMemberFromForeignDomain(pipes_struct
*p
,
6167 struct samr_RemoveMemberFromForeignDomain
*r
)
6169 struct samr_domain_info
*dinfo
;
6172 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6173 sid_string_dbg(r
->in
.sid
)));
6175 /* Find the policy handle. Open a policy on it. */
6177 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6178 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
6179 struct samr_domain_info
, &result
);
6180 if (!NT_STATUS_IS_OK(result
)) {
6184 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6185 sid_string_dbg(&dinfo
->sid
)));
6187 /* we can only delete a user from a group since we don't have
6188 nested groups anyways. So in the latter case, just say OK */
6190 /* TODO: The above comment nowadays is bogus. Since we have nested
6191 * groups now, and aliases members are never reported out of the unix
6192 * group membership, the "just say OK" makes this call a no-op. For
6193 * us. This needs fixing however. */
6195 /* I've only ever seen this in the wild when deleting a user from
6196 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6197 * is the user about to be deleted. I very much suspect this is the
6198 * only application of this call. To verify this, let people report
6201 if (!sid_check_is_builtin(&dinfo
->sid
)) {
6202 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6203 "global_sam_sid() = %s\n",
6204 sid_string_dbg(&dinfo
->sid
),
6205 sid_string_dbg(get_global_sam_sid())));
6206 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6207 return NT_STATUS_OK
;
6210 force_flush_samr_cache(&dinfo
->sid
);
6212 result
= NT_STATUS_OK
;
6217 /*******************************************************************
6218 _samr_QueryDomainInfo2
6219 ********************************************************************/
6221 NTSTATUS
_samr_QueryDomainInfo2(pipes_struct
*p
,
6222 struct samr_QueryDomainInfo2
*r
)
6224 struct samr_QueryDomainInfo q
;
6226 q
.in
.domain_handle
= r
->in
.domain_handle
;
6227 q
.in
.level
= r
->in
.level
;
6229 q
.out
.info
= r
->out
.info
;
6231 return _samr_QueryDomainInfo(p
, &q
);
6234 /*******************************************************************
6236 ********************************************************************/
6238 NTSTATUS
_samr_SetDomainInfo(pipes_struct
*p
,
6239 struct samr_SetDomainInfo
*r
)
6241 struct samr_domain_info
*dinfo
;
6242 time_t u_expire
, u_min_age
;
6244 time_t u_lock_duration
, u_reset_time
;
6246 uint32_t acc_required
= 0;
6248 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6250 switch (r
->in
.level
) {
6251 case 1: /* DomainPasswordInformation */
6252 case 12: /* DomainLockoutInformation */
6253 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6254 acc_required
= SAMR_DOMAIN_ACCESS_SET_INFO_1
;
6256 case 3: /* DomainLogoffInformation */
6257 case 4: /* DomainOemInformation */
6258 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6259 acc_required
= SAMR_DOMAIN_ACCESS_SET_INFO_2
;
6261 case 6: /* DomainReplicationInformation */
6262 case 9: /* DomainStateInformation */
6263 case 7: /* DomainServerRoleInformation */
6264 /* DOMAIN_ADMINISTER_SERVER */
6265 acc_required
= SAMR_DOMAIN_ACCESS_SET_INFO_3
;
6268 return NT_STATUS_INVALID_INFO_CLASS
;
6271 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6273 struct samr_domain_info
, &result
);
6274 if (!NT_STATUS_IS_OK(result
)) {
6278 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r
->in
.level
));
6280 switch (r
->in
.level
) {
6282 u_expire
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info1
.max_password_age
);
6283 u_min_age
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info1
.min_password_age
);
6284 pdb_set_account_policy(AP_MIN_PASSWORD_LEN
, (uint32
)r
->in
.info
->info1
.min_password_length
);
6285 pdb_set_account_policy(AP_PASSWORD_HISTORY
, (uint32
)r
->in
.info
->info1
.password_history_length
);
6286 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
, (uint32
)r
->in
.info
->info1
.password_properties
);
6287 pdb_set_account_policy(AP_MAX_PASSWORD_AGE
, (int)u_expire
);
6288 pdb_set_account_policy(AP_MIN_PASSWORD_AGE
, (int)u_min_age
);
6291 u_logout
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info3
.force_logoff_time
);
6292 pdb_set_account_policy(AP_TIME_TO_LOGOUT
, (int)u_logout
);
6303 u_lock_duration
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info12
.lockout_duration
);
6304 if (u_lock_duration
!= -1)
6305 u_lock_duration
/= 60;
6307 u_reset_time
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info12
.lockout_window
)/60;
6309 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION
, (int)u_lock_duration
);
6310 pdb_set_account_policy(AP_RESET_COUNT_TIME
, (int)u_reset_time
);
6311 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, (uint32
)r
->in
.info
->info12
.lockout_threshold
);
6314 return NT_STATUS_INVALID_INFO_CLASS
;
6317 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6319 return NT_STATUS_OK
;
6322 /****************************************************************
6323 _samr_GetDisplayEnumerationIndex
6324 ****************************************************************/
6326 NTSTATUS
_samr_GetDisplayEnumerationIndex(pipes_struct
*p
,
6327 struct samr_GetDisplayEnumerationIndex
*r
)
6329 struct samr_domain_info
*dinfo
;
6330 uint32_t max_entries
= (uint32_t) -1;
6331 uint32_t enum_context
= 0;
6333 uint32_t num_account
= 0;
6334 struct samr_displayentry
*entries
= NULL
;
6337 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__
));
6339 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6340 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
6341 struct samr_domain_info
, &status
);
6342 if (!NT_STATUS_IS_OK(status
)) {
6346 if ((r
->in
.level
< 1) || (r
->in
.level
> 3)) {
6347 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6348 "Unknown info level (%u)\n",
6350 return NT_STATUS_INVALID_INFO_CLASS
;
6355 /* The following done as ROOT. Don't return without unbecome_root(). */
6357 switch (r
->in
.level
) {
6359 if (dinfo
->disp_info
->users
== NULL
) {
6360 dinfo
->disp_info
->users
= pdb_search_users(
6361 dinfo
->disp_info
, ACB_NORMAL
);
6362 if (dinfo
->disp_info
->users
== NULL
) {
6364 return NT_STATUS_ACCESS_DENIED
;
6366 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6367 "starting user enumeration at index %u\n",
6368 (unsigned int)enum_context
));
6370 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6371 "using cached user enumeration at index %u\n",
6372 (unsigned int)enum_context
));
6374 num_account
= pdb_search_entries(dinfo
->disp_info
->users
,
6375 enum_context
, max_entries
,
6379 if (dinfo
->disp_info
->machines
== NULL
) {
6380 dinfo
->disp_info
->machines
= pdb_search_users(
6381 dinfo
->disp_info
, ACB_WSTRUST
|ACB_SVRTRUST
);
6382 if (dinfo
->disp_info
->machines
== NULL
) {
6384 return NT_STATUS_ACCESS_DENIED
;
6386 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6387 "starting machine enumeration at index %u\n",
6388 (unsigned int)enum_context
));
6390 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6391 "using cached machine enumeration at index %u\n",
6392 (unsigned int)enum_context
));
6394 num_account
= pdb_search_entries(dinfo
->disp_info
->machines
,
6395 enum_context
, max_entries
,
6399 if (dinfo
->disp_info
->groups
== NULL
) {
6400 dinfo
->disp_info
->groups
= pdb_search_groups(
6402 if (dinfo
->disp_info
->groups
== NULL
) {
6404 return NT_STATUS_ACCESS_DENIED
;
6406 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6407 "starting group enumeration at index %u\n",
6408 (unsigned int)enum_context
));
6410 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6411 "using cached group enumeration at index %u\n",
6412 (unsigned int)enum_context
));
6414 num_account
= pdb_search_entries(dinfo
->disp_info
->groups
,
6415 enum_context
, max_entries
,
6420 smb_panic("info class changed");
6426 /* Ensure we cache this enumeration. */
6427 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
6429 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6430 r
->in
.name
->string
));
6432 for (i
=0; i
<num_account
; i
++) {
6433 if (strequal(entries
[i
].account_name
, r
->in
.name
->string
)) {
6434 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6435 "found %s at idx %d\n",
6436 r
->in
.name
->string
, i
));
6438 return NT_STATUS_OK
;
6442 /* assuming account_name lives at the very end */
6443 *r
->out
.idx
= num_account
;
6445 return NT_STATUS_NO_MORE_ENTRIES
;
6448 /****************************************************************
6449 _samr_GetDisplayEnumerationIndex2
6450 ****************************************************************/
6452 NTSTATUS
_samr_GetDisplayEnumerationIndex2(pipes_struct
*p
,
6453 struct samr_GetDisplayEnumerationIndex2
*r
)
6455 struct samr_GetDisplayEnumerationIndex q
;
6457 q
.in
.domain_handle
= r
->in
.domain_handle
;
6458 q
.in
.level
= r
->in
.level
;
6459 q
.in
.name
= r
->in
.name
;
6461 q
.out
.idx
= r
->out
.idx
;
6463 return _samr_GetDisplayEnumerationIndex(p
, &q
);
6466 /****************************************************************
6468 ****************************************************************/
6470 NTSTATUS
_samr_RidToSid(pipes_struct
*p
,
6471 struct samr_RidToSid
*r
)
6473 struct samr_domain_info
*dinfo
;
6477 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6479 struct samr_domain_info
, &status
);
6480 if (!NT_STATUS_IS_OK(status
)) {
6484 if (!sid_compose(&sid
, &dinfo
->sid
, r
->in
.rid
)) {
6485 return NT_STATUS_NO_MEMORY
;
6488 *r
->out
.sid
= sid_dup_talloc(p
->mem_ctx
, &sid
);
6490 return NT_STATUS_NO_MEMORY
;
6493 return NT_STATUS_OK
;
6496 /****************************************************************
6497 ****************************************************************/
6499 NTSTATUS
_samr_Shutdown(pipes_struct
*p
,
6500 struct samr_Shutdown
*r
)
6502 p
->rng_fault_state
= true;
6503 return NT_STATUS_NOT_IMPLEMENTED
;
6506 /****************************************************************
6507 ****************************************************************/
6509 NTSTATUS
_samr_SetMemberAttributesOfGroup(pipes_struct
*p
,
6510 struct samr_SetMemberAttributesOfGroup
*r
)
6512 p
->rng_fault_state
= true;
6513 return NT_STATUS_NOT_IMPLEMENTED
;
6516 /****************************************************************
6517 ****************************************************************/
6519 NTSTATUS
_samr_TestPrivateFunctionsDomain(pipes_struct
*p
,
6520 struct samr_TestPrivateFunctionsDomain
*r
)
6522 return NT_STATUS_NOT_IMPLEMENTED
;
6525 /****************************************************************
6526 ****************************************************************/
6528 NTSTATUS
_samr_TestPrivateFunctionsUser(pipes_struct
*p
,
6529 struct samr_TestPrivateFunctionsUser
*r
)
6531 return NT_STATUS_NOT_IMPLEMENTED
;
6534 /****************************************************************
6535 ****************************************************************/
6537 NTSTATUS
_samr_AddMultipleMembersToAlias(pipes_struct
*p
,
6538 struct samr_AddMultipleMembersToAlias
*r
)
6540 p
->rng_fault_state
= true;
6541 return NT_STATUS_NOT_IMPLEMENTED
;
6544 /****************************************************************
6545 ****************************************************************/
6547 NTSTATUS
_samr_RemoveMultipleMembersFromAlias(pipes_struct
*p
,
6548 struct samr_RemoveMultipleMembersFromAlias
*r
)
6550 p
->rng_fault_state
= true;
6551 return NT_STATUS_NOT_IMPLEMENTED
;
6554 /****************************************************************
6555 ****************************************************************/
6557 NTSTATUS
_samr_SetBootKeyInformation(pipes_struct
*p
,
6558 struct samr_SetBootKeyInformation
*r
)
6560 p
->rng_fault_state
= true;
6561 return NT_STATUS_NOT_IMPLEMENTED
;
6564 /****************************************************************
6565 ****************************************************************/
6567 NTSTATUS
_samr_GetBootKeyInformation(pipes_struct
*p
,
6568 struct samr_GetBootKeyInformation
*r
)
6570 p
->rng_fault_state
= true;
6571 return NT_STATUS_NOT_IMPLEMENTED
;
6574 /****************************************************************
6575 ****************************************************************/
6577 NTSTATUS
_samr_SetDsrmPassword(pipes_struct
*p
,
6578 struct samr_SetDsrmPassword
*r
)
6580 p
->rng_fault_state
= true;
6581 return NT_STATUS_NOT_IMPLEMENTED
;
6584 /****************************************************************
6585 ****************************************************************/
6587 NTSTATUS
_samr_ValidatePassword(pipes_struct
*p
,
6588 struct samr_ValidatePassword
*r
)
6590 p
->rng_fault_state
= true;
6591 return NT_STATUS_NOT_IMPLEMENTED
;