2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
42 SAMR_USER_ACCESS_SET_LOC_COM)
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
49 #define MAX_SAM_ENTRIES_W95 50
51 typedef struct disp_info
{
52 DOM_SID sid
; /* identify which domain this is. */
53 bool builtin_domain
; /* Quick flag to check if this is the builtin domain. */
54 struct pdb_search
*users
; /* querydispinfo 1 and 4 */
55 struct pdb_search
*machines
; /* querydispinfo 2 */
56 struct pdb_search
*groups
; /* querydispinfo 3 and 5, enumgroups */
57 struct pdb_search
*aliases
; /* enumaliases */
60 struct pdb_search
*enum_users
; /* enumusers with a mask */
62 struct timed_event
*cache_timeout_event
; /* cache idle timeout
66 /* We keep a static list of these by SID as modern clients close down
67 all resources between each request in a complete enumeration. */
70 /* for use by the \PIPE\samr policy */
72 bool builtin_domain
; /* Quick flag to check if this is the builtin domain. */
73 uint32 status
; /* some sort of flag. best to record it. comes from opnum 0x39 */
78 static const struct generic_mapping sam_generic_mapping
= {
79 GENERIC_RIGHTS_SAM_READ
,
80 GENERIC_RIGHTS_SAM_WRITE
,
81 GENERIC_RIGHTS_SAM_EXECUTE
,
82 GENERIC_RIGHTS_SAM_ALL_ACCESS
};
83 static const struct generic_mapping dom_generic_mapping
= {
84 GENERIC_RIGHTS_DOMAIN_READ
,
85 GENERIC_RIGHTS_DOMAIN_WRITE
,
86 GENERIC_RIGHTS_DOMAIN_EXECUTE
,
87 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS
};
88 static const struct generic_mapping usr_generic_mapping
= {
89 GENERIC_RIGHTS_USER_READ
,
90 GENERIC_RIGHTS_USER_WRITE
,
91 GENERIC_RIGHTS_USER_EXECUTE
,
92 GENERIC_RIGHTS_USER_ALL_ACCESS
};
93 static const struct generic_mapping usr_nopwchange_generic_mapping
= {
94 GENERIC_RIGHTS_USER_READ
,
95 GENERIC_RIGHTS_USER_WRITE
,
96 GENERIC_RIGHTS_USER_EXECUTE
& ~SAMR_USER_ACCESS_CHANGE_PASSWORD
,
97 GENERIC_RIGHTS_USER_ALL_ACCESS
};
98 static const struct generic_mapping grp_generic_mapping
= {
99 GENERIC_RIGHTS_GROUP_READ
,
100 GENERIC_RIGHTS_GROUP_WRITE
,
101 GENERIC_RIGHTS_GROUP_EXECUTE
,
102 GENERIC_RIGHTS_GROUP_ALL_ACCESS
};
103 static const struct generic_mapping ali_generic_mapping
= {
104 GENERIC_RIGHTS_ALIAS_READ
,
105 GENERIC_RIGHTS_ALIAS_WRITE
,
106 GENERIC_RIGHTS_ALIAS_EXECUTE
,
107 GENERIC_RIGHTS_ALIAS_ALL_ACCESS
};
109 /*******************************************************************
110 *******************************************************************/
112 static NTSTATUS
make_samr_object_sd( TALLOC_CTX
*ctx
, SEC_DESC
**psd
, size_t *sd_size
,
113 const struct generic_mapping
*map
,
114 DOM_SID
*sid
, uint32 sid_access
)
116 DOM_SID domadmin_sid
;
117 SEC_ACE ace
[5]; /* at most 5 entries */
122 /* basic access for Everyone */
124 init_sec_ace(&ace
[i
++], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
125 map
->generic_execute
| map
->generic_read
, 0);
127 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
129 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Administrators
,
130 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
131 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Account_Operators
,
132 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
134 /* Add Full Access for Domain Admins if we are a DC */
137 sid_copy( &domadmin_sid
, get_global_sam_sid() );
138 sid_append_rid( &domadmin_sid
, DOMAIN_GROUP_RID_ADMINS
);
139 init_sec_ace(&ace
[i
++], &domadmin_sid
,
140 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
143 /* if we have a sid, give it some special access */
146 init_sec_ace(&ace
[i
++], sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, sid_access
, 0);
149 /* create the security descriptor */
151 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, i
, ace
)) == NULL
)
152 return NT_STATUS_NO_MEMORY
;
154 if ((*psd
= make_sec_desc(ctx
, SECURITY_DESCRIPTOR_REVISION_1
,
155 SEC_DESC_SELF_RELATIVE
, NULL
, NULL
, NULL
,
156 psa
, sd_size
)) == NULL
)
157 return NT_STATUS_NO_MEMORY
;
162 /*******************************************************************
163 Checks if access to an object should be granted, and returns that
164 level of access for further checks.
165 ********************************************************************/
167 static NTSTATUS
access_check_samr_object( SEC_DESC
*psd
, NT_USER_TOKEN
*token
,
168 SE_PRIV
*rights
, uint32 rights_mask
,
169 uint32 des_access
, uint32
*acc_granted
,
172 NTSTATUS status
= NT_STATUS_ACCESS_DENIED
;
173 uint32 saved_mask
= 0;
175 /* check privileges; certain SAM access bits should be overridden
176 by privileges (mostly having to do with creating/modifying/deleting
179 if ( rights
&& user_has_any_privilege( token
, rights
) ) {
181 saved_mask
= (des_access
& rights_mask
);
182 des_access
&= ~saved_mask
;
184 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
189 /* check the security descriptor first */
191 status
= se_access_check(psd
, token
, des_access
, acc_granted
);
192 if (NT_STATUS_IS_OK(status
)) {
196 /* give root a free pass */
198 if ( geteuid() == sec_initial_uid() ) {
200 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug
, des_access
));
201 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
203 *acc_granted
= des_access
;
205 status
= NT_STATUS_OK
;
211 /* add in any bits saved during the privilege check (only
212 matters is status is ok) */
214 *acc_granted
|= rights_mask
;
216 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
217 debug
, NT_STATUS_IS_OK(status
) ? "GRANTED" : "DENIED",
218 des_access
, *acc_granted
));
223 /*******************************************************************
224 Checks if access to a function can be granted
225 ********************************************************************/
227 static NTSTATUS
access_check_samr_function(uint32 acc_granted
, uint32 acc_required
, const char *debug
)
229 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
230 debug
, acc_granted
, acc_required
));
232 /* check the security descriptor first */
234 if ( (acc_granted
&acc_required
) == acc_required
)
237 /* give root a free pass */
239 if (geteuid() == sec_initial_uid()) {
241 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
242 debug
, acc_granted
, acc_required
));
243 DEBUGADD(4,("but overwritten by euid == 0\n"));
248 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
249 debug
, acc_granted
, acc_required
));
251 return NT_STATUS_ACCESS_DENIED
;
254 /*******************************************************************
255 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
256 ********************************************************************/
258 static void map_max_allowed_access(const NT_USER_TOKEN
*token
,
259 uint32_t *pacc_requested
)
261 if (!((*pacc_requested
) & MAXIMUM_ALLOWED_ACCESS
)) {
264 *pacc_requested
&= ~MAXIMUM_ALLOWED_ACCESS
;
266 /* At least try for generic read. */
267 *pacc_requested
= GENERIC_READ_ACCESS
;
269 /* root gets anything. */
270 if (geteuid() == sec_initial_uid()) {
271 *pacc_requested
|= GENERIC_ALL_ACCESS
;
275 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
277 if (is_sid_in_token(token
, &global_sid_Builtin_Administrators
) ||
278 is_sid_in_token(token
, &global_sid_Builtin_Account_Operators
)) {
279 *pacc_requested
|= GENERIC_ALL_ACCESS
;
283 /* Full access for DOMAIN\Domain Admins. */
285 DOM_SID domadmin_sid
;
286 sid_copy( &domadmin_sid
, get_global_sam_sid() );
287 sid_append_rid( &domadmin_sid
, DOMAIN_GROUP_RID_ADMINS
);
288 if (is_sid_in_token(token
, &domadmin_sid
)) {
289 *pacc_requested
|= GENERIC_ALL_ACCESS
;
293 /* TODO ! Check privileges. */
296 /*******************************************************************
297 Fetch or create a dispinfo struct.
298 ********************************************************************/
300 static DISP_INFO
*get_samr_dispinfo_by_sid(DOM_SID
*psid
)
303 * We do a static cache for DISP_INFO's here. Explanation can be found
304 * in Jeremy's checkin message to r11793:
306 * Fix the SAMR cache so it works across completely insane
307 * client behaviour (ie.:
308 * open pipe/open SAMR handle/enumerate 0 - 1024
309 * close SAMR handle, close pipe.
310 * open pipe/open SAMR handle/enumerate 1024 - 2048...
311 * close SAMR handle, close pipe.
312 * And on ad-nausium. Amazing.... probably object-oriented
313 * client side programming in action yet again.
314 * This change should *massively* improve performance when
315 * enumerating users from an LDAP database.
318 * "Our" and the builtin domain are the only ones where we ever
319 * enumerate stuff, so just cache 2 entries.
322 static struct disp_info
*builtin_dispinfo
;
323 static struct disp_info
*domain_dispinfo
;
325 /* There are two cases to consider here:
326 1) The SID is a domain SID and we look for an equality match, or
327 2) This is an account SID and so we return the DISP_INFO* for our
334 if (sid_check_is_builtin(psid
) || sid_check_is_in_builtin(psid
)) {
336 * Necessary only once, but it does not really hurt.
338 if (builtin_dispinfo
== NULL
) {
339 builtin_dispinfo
= talloc_zero(
340 talloc_autofree_context(), struct disp_info
);
341 if (builtin_dispinfo
== NULL
) {
345 sid_copy(&builtin_dispinfo
->sid
, &global_sid_Builtin
);
346 builtin_dispinfo
->builtin_domain
= true;
348 return builtin_dispinfo
;
351 if (sid_check_is_domain(psid
) || sid_check_is_in_our_domain(psid
)) {
353 * Necessary only once, but it does not really hurt.
355 if (domain_dispinfo
== NULL
) {
356 domain_dispinfo
= talloc_zero(
357 talloc_autofree_context(), struct disp_info
);
358 if (domain_dispinfo
== NULL
) {
362 sid_copy(&domain_dispinfo
->sid
, get_global_sam_sid());
363 domain_dispinfo
->builtin_domain
= false;
365 return domain_dispinfo
;
371 /*******************************************************************
372 Create a samr_info struct.
373 ********************************************************************/
375 static int samr_info_destructor(struct samr_info
*info
);
377 static struct samr_info
*get_samr_info_by_sid(TALLOC_CTX
*mem_ctx
,
380 struct samr_info
*info
;
384 sid_to_fstring(sid_str
, psid
);
386 fstrcpy(sid_str
,"(NULL)");
389 if ((info
= TALLOC_ZERO_P(mem_ctx
, struct samr_info
)) == NULL
) {
392 talloc_set_destructor(info
, samr_info_destructor
);
394 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str
));
396 sid_copy( &info
->sid
, psid
);
397 info
->builtin_domain
= sid_check_is_builtin(psid
);
399 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
400 info
->builtin_domain
= False
;
403 info
->disp_info
= get_samr_dispinfo_by_sid(psid
);
408 /*******************************************************************
409 Function to free the per SID data.
410 ********************************************************************/
412 static void free_samr_cache(DISP_INFO
*disp_info
)
414 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
415 sid_string_dbg(&disp_info
->sid
)));
417 /* We need to become root here because the paged search might have to
418 * tell the LDAP server we're not interested in the rest anymore. */
422 TALLOC_FREE(disp_info
->users
);
423 TALLOC_FREE(disp_info
->machines
);
424 TALLOC_FREE(disp_info
->groups
);
425 TALLOC_FREE(disp_info
->aliases
);
426 TALLOC_FREE(disp_info
->enum_users
);
431 static int samr_info_destructor(struct samr_info
*info
)
433 /* Only free the dispinfo cache if no one bothered to set up
436 if (info
->disp_info
&& info
->disp_info
->cache_timeout_event
== NULL
) {
437 free_samr_cache(info
->disp_info
);
442 /*******************************************************************
443 Idle event handler. Throw away the disp info cache.
444 ********************************************************************/
446 static void disp_info_cache_idle_timeout_handler(struct event_context
*ev_ctx
,
447 struct timed_event
*te
,
451 DISP_INFO
*disp_info
= (DISP_INFO
*)private_data
;
453 TALLOC_FREE(disp_info
->cache_timeout_event
);
455 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
457 free_samr_cache(disp_info
);
460 /*******************************************************************
461 Setup cache removal idle event handler.
462 ********************************************************************/
464 static void set_disp_info_cache_timeout(DISP_INFO
*disp_info
, time_t secs_fromnow
)
466 /* Remove any pending timeout and update. */
468 TALLOC_FREE(disp_info
->cache_timeout_event
);
470 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
471 "SID %s for %u seconds\n", sid_string_dbg(&disp_info
->sid
),
472 (unsigned int)secs_fromnow
));
474 disp_info
->cache_timeout_event
= event_add_timed(
475 smbd_event_context(), NULL
,
476 timeval_current_ofs(secs_fromnow
, 0),
477 disp_info_cache_idle_timeout_handler
, (void *)disp_info
);
480 /*******************************************************************
481 Force flush any cache. We do this on any samr_set_xxx call.
482 We must also remove the timeout handler.
483 ********************************************************************/
485 static void force_flush_samr_cache(DISP_INFO
*disp_info
)
487 if ((disp_info
== NULL
) || (disp_info
->cache_timeout_event
== NULL
)) {
491 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
492 TALLOC_FREE(disp_info
->cache_timeout_event
);
493 free_samr_cache(disp_info
);
496 /*******************************************************************
497 Ensure password info is never given out. Paranioa... JRA.
498 ********************************************************************/
500 static void samr_clear_sam_passwd(struct samu
*sam_pass
)
506 /* These now zero out the old password */
508 pdb_set_lanman_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
509 pdb_set_nt_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
512 static uint32
count_sam_users(struct disp_info
*info
, uint32 acct_flags
)
514 struct samr_displayentry
*entry
;
516 if (info
->builtin_domain
) {
517 /* No users in builtin. */
521 if (info
->users
== NULL
) {
522 info
->users
= pdb_search_users(info
, acct_flags
);
523 if (info
->users
== NULL
) {
527 /* Fetch the last possible entry, thus trigger an enumeration */
528 pdb_search_entries(info
->users
, 0xffffffff, 1, &entry
);
530 /* Ensure we cache this enumeration. */
531 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
533 return info
->users
->num_entries
;
536 static uint32
count_sam_groups(struct disp_info
*info
)
538 struct samr_displayentry
*entry
;
540 if (info
->builtin_domain
) {
541 /* No groups in builtin. */
545 if (info
->groups
== NULL
) {
546 info
->groups
= pdb_search_groups(info
);
547 if (info
->groups
== NULL
) {
551 /* Fetch the last possible entry, thus trigger an enumeration */
552 pdb_search_entries(info
->groups
, 0xffffffff, 1, &entry
);
554 /* Ensure we cache this enumeration. */
555 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
557 return info
->groups
->num_entries
;
560 static uint32
count_sam_aliases(struct disp_info
*info
)
562 struct samr_displayentry
*entry
;
564 if (info
->aliases
== NULL
) {
565 info
->aliases
= pdb_search_aliases(info
, &info
->sid
);
566 if (info
->aliases
== NULL
) {
570 /* Fetch the last possible entry, thus trigger an enumeration */
571 pdb_search_entries(info
->aliases
, 0xffffffff, 1, &entry
);
573 /* Ensure we cache this enumeration. */
574 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
576 return info
->aliases
->num_entries
;
579 /*******************************************************************
581 ********************************************************************/
583 NTSTATUS
_samr_Close(pipes_struct
*p
, struct samr_Close
*r
)
585 if (!close_policy_hnd(p
, r
->in
.handle
)) {
586 return NT_STATUS_INVALID_HANDLE
;
589 ZERO_STRUCTP(r
->out
.handle
);
594 /*******************************************************************
596 ********************************************************************/
598 NTSTATUS
_samr_OpenDomain(pipes_struct
*p
,
599 struct samr_OpenDomain
*r
)
601 struct samr_info
*info
;
602 SEC_DESC
*psd
= NULL
;
604 uint32 des_access
= r
->in
.access_mask
;
609 /* find the connection policy handle. */
611 if ( !find_policy_by_hnd(p
, r
->in
.connect_handle
, (void**)(void *)&info
) )
612 return NT_STATUS_INVALID_HANDLE
;
614 /*check if access can be granted as requested by client. */
615 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
617 make_samr_object_sd( p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0 );
618 se_map_generic( &des_access
, &dom_generic_mapping
);
620 se_priv_copy( &se_rights
, &se_machine_account
);
621 se_priv_add( &se_rights
, &se_add_users
);
623 status
= access_check_samr_object( psd
, p
->server_info
->ptok
,
624 &se_rights
, GENERIC_RIGHTS_DOMAIN_WRITE
, des_access
,
625 &acc_granted
, "_samr_OpenDomain" );
627 if ( !NT_STATUS_IS_OK(status
) )
630 if (!sid_check_is_domain(r
->in
.sid
) &&
631 !sid_check_is_builtin(r
->in
.sid
)) {
632 return NT_STATUS_NO_SUCH_DOMAIN
;
635 /* associate the domain SID with the (unique) handle. */
636 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, r
->in
.sid
))==NULL
)
637 return NT_STATUS_NO_MEMORY
;
638 info
->acc_granted
= acc_granted
;
640 /* get a (unique) handle. open a policy on it. */
641 if (!create_policy_hnd(p
, r
->out
.domain_handle
, info
))
642 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
644 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__
));
649 /*******************************************************************
651 ********************************************************************/
653 NTSTATUS
_samr_GetUserPwInfo(pipes_struct
*p
,
654 struct samr_GetUserPwInfo
*r
)
656 struct samr_info
*info
= NULL
;
657 enum lsa_SidType sid_type
;
658 uint32_t min_password_length
= 0;
659 uint32_t password_properties
= 0;
663 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__
));
665 /* find the policy handle. open a policy on it. */
666 if (!find_policy_by_hnd(p
, r
->in
.user_handle
, (void **)(void *)&info
)) {
667 return NT_STATUS_INVALID_HANDLE
;
670 status
= access_check_samr_function(info
->acc_granted
,
671 SAMR_USER_ACCESS_GET_ATTRIBUTES
,
672 "_samr_GetUserPwInfo" );
673 if (!NT_STATUS_IS_OK(status
)) {
677 if (!sid_check_is_in_our_domain(&info
->sid
)) {
678 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
682 ret
= lookup_sid(p
->mem_ctx
, &info
->sid
, NULL
, NULL
, &sid_type
);
685 return NT_STATUS_NO_SUCH_USER
;
691 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
,
692 &min_password_length
);
693 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
694 &password_properties
);
697 if (lp_check_password_script() && *lp_check_password_script()) {
698 password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
706 r
->out
.info
->min_password_length
= min_password_length
;
707 r
->out
.info
->password_properties
= password_properties
;
709 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__
));
714 /*******************************************************************
715 ********************************************************************/
717 static bool get_lsa_policy_samr_sid( pipes_struct
*p
, struct policy_handle
*pol
,
718 DOM_SID
*sid
, uint32
*acc_granted
,
719 DISP_INFO
**ppdisp_info
)
721 struct samr_info
*info
= NULL
;
723 /* find the policy handle. open a policy on it. */
724 if (!find_policy_by_hnd(p
, pol
, (void **)(void *)&info
))
731 *acc_granted
= info
->acc_granted
;
733 *ppdisp_info
= info
->disp_info
;
739 /*******************************************************************
741 ********************************************************************/
743 NTSTATUS
_samr_SetSecurity(pipes_struct
*p
,
744 struct samr_SetSecurity
*r
)
747 uint32 acc_granted
, i
;
750 struct samu
*sampass
=NULL
;
753 if (!get_lsa_policy_samr_sid(p
, r
->in
.handle
, &pol_sid
, &acc_granted
, NULL
))
754 return NT_STATUS_INVALID_HANDLE
;
756 if (!(sampass
= samu_new( p
->mem_ctx
))) {
757 DEBUG(0,("No memory!\n"));
758 return NT_STATUS_NO_MEMORY
;
761 /* get the user record */
763 ret
= pdb_getsampwsid(sampass
, &pol_sid
);
767 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid
)));
768 TALLOC_FREE(sampass
);
769 return NT_STATUS_INVALID_HANDLE
;
772 dacl
= r
->in
.sdbuf
->sd
->dacl
;
773 for (i
=0; i
< dacl
->num_aces
; i
++) {
774 if (sid_equal(&pol_sid
, &dacl
->aces
[i
].trustee
)) {
775 ret
= pdb_set_pass_can_change(sampass
,
776 (dacl
->aces
[i
].access_mask
&
777 SAMR_USER_ACCESS_CHANGE_PASSWORD
) ?
784 TALLOC_FREE(sampass
);
785 return NT_STATUS_ACCESS_DENIED
;
788 status
= access_check_samr_function(acc_granted
,
789 SAMR_USER_ACCESS_SET_ATTRIBUTES
,
790 "_samr_SetSecurity");
791 if (NT_STATUS_IS_OK(status
)) {
793 status
= pdb_update_sam_account(sampass
);
797 TALLOC_FREE(sampass
);
802 /*******************************************************************
803 build correct perms based on policies and password times for _samr_query_sec_obj
804 *******************************************************************/
805 static bool check_change_pw_access(TALLOC_CTX
*mem_ctx
, DOM_SID
*user_sid
)
807 struct samu
*sampass
=NULL
;
810 if ( !(sampass
= samu_new( mem_ctx
)) ) {
811 DEBUG(0,("No memory!\n"));
816 ret
= pdb_getsampwsid(sampass
, user_sid
);
820 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid
)));
821 TALLOC_FREE(sampass
);
825 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
827 if (pdb_get_pass_can_change(sampass
)) {
828 TALLOC_FREE(sampass
);
831 TALLOC_FREE(sampass
);
836 /*******************************************************************
838 ********************************************************************/
840 NTSTATUS
_samr_QuerySecurity(pipes_struct
*p
,
841 struct samr_QuerySecurity
*r
)
845 SEC_DESC
* psd
= NULL
;
850 if (!get_lsa_policy_samr_sid(p
, r
->in
.handle
, &pol_sid
, &acc_granted
, NULL
))
851 return NT_STATUS_INVALID_HANDLE
;
853 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
854 sid_string_dbg(&pol_sid
)));
856 status
= access_check_samr_function(acc_granted
,
857 STD_RIGHT_READ_CONTROL_ACCESS
,
858 "_samr_QuerySecurity");
859 if (!NT_STATUS_IS_OK(status
)) {
863 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
865 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
866 if (pol_sid
.sid_rev_num
== 0) {
867 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
868 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
869 } else if (sid_equal(&pol_sid
,get_global_sam_sid())) {
870 /* check if it is our domain SID */
871 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
872 "with SID: %s\n", sid_string_dbg(&pol_sid
)));
873 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0);
874 } else if (sid_equal(&pol_sid
,&global_sid_Builtin
)) {
875 /* check if it is the Builtin Domain */
876 /* TODO: Builtin probably needs a different SD with restricted write access*/
877 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
878 "Domain with SID: %s\n", sid_string_dbg(&pol_sid
)));
879 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0);
880 } else if (sid_check_is_in_our_domain(&pol_sid
) ||
881 sid_check_is_in_builtin(&pol_sid
)) {
882 /* TODO: different SDs have to be generated for aliases groups and users.
883 Currently all three get a default user SD */
884 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
885 "with SID: %s\n", sid_string_dbg(&pol_sid
)));
886 if (check_change_pw_access(p
->mem_ctx
, &pol_sid
)) {
887 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
,
888 &pol_sid
, SAMR_USR_RIGHTS_WRITE_PW
);
890 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_nopwchange_generic_mapping
,
891 &pol_sid
, SAMR_USR_RIGHTS_CANT_WRITE_PW
);
894 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
897 if ((*r
->out
.sdbuf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
898 return NT_STATUS_NO_MEMORY
;
903 /*******************************************************************
904 makes a SAM_ENTRY / UNISTR2* structure from a user list.
905 ********************************************************************/
907 static NTSTATUS
make_user_sam_entry_list(TALLOC_CTX
*ctx
,
908 struct samr_SamEntry
**sam_pp
,
909 uint32_t num_entries
,
911 struct samr_displayentry
*entries
)
914 struct samr_SamEntry
*sam
;
918 if (num_entries
== 0) {
922 sam
= TALLOC_ZERO_ARRAY(ctx
, struct samr_SamEntry
, num_entries
);
924 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
925 return NT_STATUS_NO_MEMORY
;
928 for (i
= 0; i
< num_entries
; i
++) {
931 * usrmgr expects a non-NULL terminated string with
932 * trust relationships
934 if (entries
[i
].acct_flags
& ACB_DOMTRUST
) {
935 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
938 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
942 init_lsa_String(&sam
[i
].name
, entries
[i
].account_name
);
943 sam
[i
].idx
= entries
[i
].rid
;
951 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
953 /*******************************************************************
954 _samr_EnumDomainUsers
955 ********************************************************************/
957 NTSTATUS
_samr_EnumDomainUsers(pipes_struct
*p
,
958 struct samr_EnumDomainUsers
*r
)
961 struct samr_info
*info
= NULL
;
963 uint32 enum_context
= *r
->in
.resume_handle
;
964 enum remote_arch_types ra_type
= get_remote_arch();
965 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
966 uint32 max_entries
= max_sam_entries
;
967 struct samr_displayentry
*entries
= NULL
;
968 struct samr_SamArray
*samr_array
= NULL
;
969 struct samr_SamEntry
*samr_entries
= NULL
;
971 /* find the policy handle. open a policy on it. */
972 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
973 return NT_STATUS_INVALID_HANDLE
;
975 status
= access_check_samr_function(info
->acc_granted
,
976 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
977 "_samr_EnumDomainUsers");
978 if (!NT_STATUS_IS_OK(status
)) {
982 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__
));
984 if (info
->builtin_domain
) {
985 /* No users in builtin. */
986 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
987 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
991 samr_array
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
993 return NT_STATUS_NO_MEMORY
;
995 *r
->out
.sam
= samr_array
;
1001 if ((info
->disp_info
->enum_users
!= NULL
) &&
1002 (info
->disp_info
->enum_acb_mask
!= r
->in
.acct_flags
)) {
1003 TALLOC_FREE(info
->disp_info
->enum_users
);
1006 if (info
->disp_info
->enum_users
== NULL
) {
1007 info
->disp_info
->enum_users
= pdb_search_users(
1008 info
->disp_info
, r
->in
.acct_flags
);
1009 info
->disp_info
->enum_acb_mask
= r
->in
.acct_flags
;
1012 if (info
->disp_info
->enum_users
== NULL
) {
1013 /* END AS ROOT !!!! */
1015 return NT_STATUS_ACCESS_DENIED
;
1018 num_account
= pdb_search_entries(info
->disp_info
->enum_users
,
1019 enum_context
, max_entries
,
1022 /* END AS ROOT !!!! */
1026 if (num_account
== 0) {
1027 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1028 "total entries\n"));
1029 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
1030 return NT_STATUS_OK
;
1033 status
= make_user_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1034 num_account
, enum_context
,
1036 if (!NT_STATUS_IS_OK(status
)) {
1040 if (max_entries
<= num_account
) {
1041 status
= STATUS_MORE_ENTRIES
;
1043 status
= NT_STATUS_OK
;
1046 /* Ensure we cache this enumeration. */
1047 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1049 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__
));
1051 samr_array
->count
= num_account
;
1052 samr_array
->entries
= samr_entries
;
1054 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ num_account
;
1055 *r
->out
.num_entries
= num_account
;
1057 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__
));
1062 /*******************************************************************
1063 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1064 ********************************************************************/
1066 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
,
1067 struct samr_SamEntry
**sam_pp
,
1068 uint32_t num_sam_entries
,
1069 struct samr_displayentry
*entries
)
1071 struct samr_SamEntry
*sam
;
1076 if (num_sam_entries
== 0) {
1080 sam
= TALLOC_ZERO_ARRAY(ctx
, struct samr_SamEntry
, num_sam_entries
);
1085 for (i
= 0; i
< num_sam_entries
; i
++) {
1087 * JRA. I think this should include the null. TNG does not.
1089 init_lsa_String(&sam
[i
].name
, entries
[i
].account_name
);
1090 sam
[i
].idx
= entries
[i
].rid
;
1096 /*******************************************************************
1097 _samr_EnumDomainGroups
1098 ********************************************************************/
1100 NTSTATUS
_samr_EnumDomainGroups(pipes_struct
*p
,
1101 struct samr_EnumDomainGroups
*r
)
1104 struct samr_info
*info
= NULL
;
1105 struct samr_displayentry
*groups
;
1107 struct samr_SamArray
*samr_array
= NULL
;
1108 struct samr_SamEntry
*samr_entries
= NULL
;
1110 /* find the policy handle. open a policy on it. */
1111 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
1112 return NT_STATUS_INVALID_HANDLE
;
1114 status
= access_check_samr_function(info
->acc_granted
,
1115 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
1116 "_samr_EnumDomainGroups");
1117 if (!NT_STATUS_IS_OK(status
)) {
1121 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__
));
1123 if (info
->builtin_domain
) {
1124 /* No groups in builtin. */
1125 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
1126 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1130 samr_array
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
1132 return NT_STATUS_NO_MEMORY
;
1135 /* the domain group array is being allocated in the function below */
1139 if (info
->disp_info
->groups
== NULL
) {
1140 info
->disp_info
->groups
= pdb_search_groups(info
->disp_info
);
1142 if (info
->disp_info
->groups
== NULL
) {
1144 return NT_STATUS_ACCESS_DENIED
;
1148 num_groups
= pdb_search_entries(info
->disp_info
->groups
,
1149 *r
->in
.resume_handle
,
1150 MAX_SAM_ENTRIES
, &groups
);
1153 /* Ensure we cache this enumeration. */
1154 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1156 make_group_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1157 num_groups
, groups
);
1159 samr_array
->count
= num_groups
;
1160 samr_array
->entries
= samr_entries
;
1162 *r
->out
.sam
= samr_array
;
1163 *r
->out
.num_entries
= num_groups
;
1164 *r
->out
.resume_handle
= num_groups
+ *r
->in
.resume_handle
;
1166 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__
));
1171 /*******************************************************************
1172 _samr_EnumDomainAliases
1173 ********************************************************************/
1175 NTSTATUS
_samr_EnumDomainAliases(pipes_struct
*p
,
1176 struct samr_EnumDomainAliases
*r
)
1179 struct samr_info
*info
;
1180 struct samr_displayentry
*aliases
;
1181 uint32 num_aliases
= 0;
1182 struct samr_SamArray
*samr_array
= NULL
;
1183 struct samr_SamEntry
*samr_entries
= NULL
;
1185 /* find the policy handle. open a policy on it. */
1186 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
1187 return NT_STATUS_INVALID_HANDLE
;
1189 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1190 sid_string_dbg(&info
->sid
)));
1192 status
= access_check_samr_function(info
->acc_granted
,
1193 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
1194 "_samr_EnumDomainAliases");
1195 if (!NT_STATUS_IS_OK(status
)) {
1199 samr_array
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
1201 return NT_STATUS_NO_MEMORY
;
1206 if (info
->disp_info
->aliases
== NULL
) {
1207 info
->disp_info
->aliases
= pdb_search_aliases(
1208 info
->disp_info
, &info
->sid
);
1209 if (info
->disp_info
->aliases
== NULL
) {
1211 return NT_STATUS_ACCESS_DENIED
;
1215 num_aliases
= pdb_search_entries(info
->disp_info
->aliases
,
1216 *r
->in
.resume_handle
,
1217 MAX_SAM_ENTRIES
, &aliases
);
1220 /* Ensure we cache this enumeration. */
1221 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1223 make_group_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1224 num_aliases
, aliases
);
1226 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__
));
1228 samr_array
->count
= num_aliases
;
1229 samr_array
->entries
= samr_entries
;
1231 *r
->out
.sam
= samr_array
;
1232 *r
->out
.num_entries
= num_aliases
;
1233 *r
->out
.resume_handle
= num_aliases
+ *r
->in
.resume_handle
;
1238 /*******************************************************************
1239 inits a samr_DispInfoGeneral structure.
1240 ********************************************************************/
1242 static NTSTATUS
init_samr_dispinfo_1(TALLOC_CTX
*ctx
,
1243 struct samr_DispInfoGeneral
*r
,
1244 uint32_t num_entries
,
1246 struct samr_displayentry
*entries
)
1250 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries
));
1252 if (num_entries
== 0) {
1253 return NT_STATUS_OK
;
1256 r
->count
= num_entries
;
1258 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryGeneral
, num_entries
);
1260 return NT_STATUS_NO_MEMORY
;
1263 for (i
= 0; i
< num_entries
; i
++) {
1265 init_lsa_String(&r
->entries
[i
].account_name
,
1266 entries
[i
].account_name
);
1268 init_lsa_String(&r
->entries
[i
].description
,
1269 entries
[i
].description
);
1271 init_lsa_String(&r
->entries
[i
].full_name
,
1272 entries
[i
].fullname
);
1274 r
->entries
[i
].rid
= entries
[i
].rid
;
1275 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1276 r
->entries
[i
].idx
= start_idx
+i
+1;
1279 return NT_STATUS_OK
;
1282 /*******************************************************************
1283 inits a samr_DispInfoFull structure.
1284 ********************************************************************/
1286 static NTSTATUS
init_samr_dispinfo_2(TALLOC_CTX
*ctx
,
1287 struct samr_DispInfoFull
*r
,
1288 uint32_t num_entries
,
1290 struct samr_displayentry
*entries
)
1294 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries
));
1296 if (num_entries
== 0) {
1297 return NT_STATUS_OK
;
1300 r
->count
= num_entries
;
1302 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryFull
, num_entries
);
1304 return NT_STATUS_NO_MEMORY
;
1307 for (i
= 0; i
< num_entries
; i
++) {
1309 init_lsa_String(&r
->entries
[i
].account_name
,
1310 entries
[i
].account_name
);
1312 init_lsa_String(&r
->entries
[i
].description
,
1313 entries
[i
].description
);
1315 r
->entries
[i
].rid
= entries
[i
].rid
;
1316 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1317 r
->entries
[i
].idx
= start_idx
+i
+1;
1320 return NT_STATUS_OK
;
1323 /*******************************************************************
1324 inits a samr_DispInfoFullGroups structure.
1325 ********************************************************************/
1327 static NTSTATUS
init_samr_dispinfo_3(TALLOC_CTX
*ctx
,
1328 struct samr_DispInfoFullGroups
*r
,
1329 uint32_t num_entries
,
1331 struct samr_displayentry
*entries
)
1335 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries
));
1337 if (num_entries
== 0) {
1338 return NT_STATUS_OK
;
1341 r
->count
= num_entries
;
1343 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryFullGroup
, num_entries
);
1345 return NT_STATUS_NO_MEMORY
;
1348 for (i
= 0; i
< num_entries
; i
++) {
1350 init_lsa_String(&r
->entries
[i
].account_name
,
1351 entries
[i
].account_name
);
1353 init_lsa_String(&r
->entries
[i
].description
,
1354 entries
[i
].description
);
1356 r
->entries
[i
].rid
= entries
[i
].rid
;
1357 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1358 r
->entries
[i
].idx
= start_idx
+i
+1;
1361 return NT_STATUS_OK
;
1364 /*******************************************************************
1365 inits a samr_DispInfoAscii structure.
1366 ********************************************************************/
1368 static NTSTATUS
init_samr_dispinfo_4(TALLOC_CTX
*ctx
,
1369 struct samr_DispInfoAscii
*r
,
1370 uint32_t num_entries
,
1372 struct samr_displayentry
*entries
)
1376 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries
));
1378 if (num_entries
== 0) {
1379 return NT_STATUS_OK
;
1382 r
->count
= num_entries
;
1384 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryAscii
, num_entries
);
1386 return NT_STATUS_NO_MEMORY
;
1389 for (i
= 0; i
< num_entries
; i
++) {
1391 init_lsa_AsciiStringLarge(&r
->entries
[i
].account_name
,
1392 entries
[i
].account_name
);
1394 r
->entries
[i
].idx
= start_idx
+i
+1;
1397 return NT_STATUS_OK
;
1400 /*******************************************************************
1401 inits a samr_DispInfoAscii structure.
1402 ********************************************************************/
1404 static NTSTATUS
init_samr_dispinfo_5(TALLOC_CTX
*ctx
,
1405 struct samr_DispInfoAscii
*r
,
1406 uint32_t num_entries
,
1408 struct samr_displayentry
*entries
)
1412 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries
));
1414 if (num_entries
== 0) {
1415 return NT_STATUS_OK
;
1418 r
->count
= num_entries
;
1420 r
->entries
= TALLOC_ZERO_ARRAY(ctx
, struct samr_DispEntryAscii
, num_entries
);
1422 return NT_STATUS_NO_MEMORY
;
1425 for (i
= 0; i
< num_entries
; i
++) {
1427 init_lsa_AsciiStringLarge(&r
->entries
[i
].account_name
,
1428 entries
[i
].account_name
);
1430 r
->entries
[i
].idx
= start_idx
+i
+1;
1433 return NT_STATUS_OK
;
1436 /*******************************************************************
1437 _samr_QueryDisplayInfo
1438 ********************************************************************/
1440 NTSTATUS
_samr_QueryDisplayInfo(pipes_struct
*p
,
1441 struct samr_QueryDisplayInfo
*r
)
1444 struct samr_info
*info
= NULL
;
1445 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
1447 uint32 max_entries
= r
->in
.max_entries
;
1448 uint32 enum_context
= r
->in
.start_idx
;
1449 uint32 max_size
= r
->in
.buf_size
;
1451 union samr_DispInfo
*disp_info
= r
->out
.info
;
1453 uint32 temp_size
=0, total_data_size
=0;
1454 NTSTATUS disp_ret
= NT_STATUS_UNSUCCESSFUL
;
1455 uint32 num_account
= 0;
1456 enum remote_arch_types ra_type
= get_remote_arch();
1457 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
1458 struct samr_displayentry
*entries
= NULL
;
1460 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__
));
1462 /* find the policy handle. open a policy on it. */
1463 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
1464 return NT_STATUS_INVALID_HANDLE
;
1466 if (info
->builtin_domain
) {
1467 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1468 return NT_STATUS_OK
;
1471 status
= access_check_samr_function(info
->acc_granted
,
1472 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
1473 "_samr_QueryDisplayInfo");
1474 if (!NT_STATUS_IS_OK(status
)) {
1479 * calculate how many entries we will return.
1481 * - the number of entries the client asked
1482 * - our limit on that
1483 * - the starting point (enumeration context)
1484 * - the buffer size the client will accept
1488 * We are a lot more like W2K. Instead of reading the SAM
1489 * each time to find the records we need to send back,
1490 * we read it once and link that copy to the sam handle.
1491 * For large user list (over the MAX_SAM_ENTRIES)
1492 * it's a definitive win.
1493 * second point to notice: between enumerations
1494 * our sam is now the same as it's a snapshoot.
1495 * third point: got rid of the static SAM_USER_21 struct
1496 * no more intermediate.
1497 * con: it uses much more memory, as a full copy is stored
1500 * If you want to change it, think twice and think
1501 * of the second point , that's really important.
1506 if ((r
->in
.level
< 1) || (r
->in
.level
> 5)) {
1507 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1508 (unsigned int)r
->in
.level
));
1509 return NT_STATUS_INVALID_INFO_CLASS
;
1512 /* first limit the number of entries we will return */
1513 if(max_entries
> max_sam_entries
) {
1514 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1515 "entries, limiting to %d\n", max_entries
,
1517 max_entries
= max_sam_entries
;
1520 /* calculate the size and limit on the number of entries we will
1523 temp_size
=max_entries
*struct_size
;
1525 if (temp_size
>max_size
) {
1526 max_entries
=MIN((max_size
/struct_size
),max_entries
);;
1527 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1528 "only %d entries\n", max_entries
));
1533 /* THe following done as ROOT. Don't return without unbecome_root(). */
1535 switch (r
->in
.level
) {
1538 if (info
->disp_info
->users
== NULL
) {
1539 info
->disp_info
->users
= pdb_search_users(
1540 info
->disp_info
, ACB_NORMAL
);
1541 if (info
->disp_info
->users
== NULL
) {
1543 return NT_STATUS_ACCESS_DENIED
;
1545 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1546 (unsigned int)enum_context
));
1548 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1549 (unsigned int)enum_context
));
1552 num_account
= pdb_search_entries(info
->disp_info
->users
,
1553 enum_context
, max_entries
,
1557 if (info
->disp_info
->machines
== NULL
) {
1558 info
->disp_info
->machines
= pdb_search_users(
1559 info
->disp_info
, ACB_WSTRUST
|ACB_SVRTRUST
);
1560 if (info
->disp_info
->machines
== NULL
) {
1562 return NT_STATUS_ACCESS_DENIED
;
1564 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1565 (unsigned int)enum_context
));
1567 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1568 (unsigned int)enum_context
));
1571 num_account
= pdb_search_entries(info
->disp_info
->machines
,
1572 enum_context
, max_entries
,
1577 if (info
->disp_info
->groups
== NULL
) {
1578 info
->disp_info
->groups
= pdb_search_groups(
1580 if (info
->disp_info
->groups
== NULL
) {
1582 return NT_STATUS_ACCESS_DENIED
;
1584 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1585 (unsigned int)enum_context
));
1587 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1588 (unsigned int)enum_context
));
1591 num_account
= pdb_search_entries(info
->disp_info
->groups
,
1592 enum_context
, max_entries
,
1597 smb_panic("info class changed");
1603 /* Now create reply structure */
1604 switch (r
->in
.level
) {
1606 disp_ret
= init_samr_dispinfo_1(p
->mem_ctx
, &disp_info
->info1
,
1607 num_account
, enum_context
,
1611 disp_ret
= init_samr_dispinfo_2(p
->mem_ctx
, &disp_info
->info2
,
1612 num_account
, enum_context
,
1616 disp_ret
= init_samr_dispinfo_3(p
->mem_ctx
, &disp_info
->info3
,
1617 num_account
, enum_context
,
1621 disp_ret
= init_samr_dispinfo_4(p
->mem_ctx
, &disp_info
->info4
,
1622 num_account
, enum_context
,
1626 disp_ret
= init_samr_dispinfo_5(p
->mem_ctx
, &disp_info
->info5
,
1627 num_account
, enum_context
,
1631 smb_panic("info class changed");
1635 if (!NT_STATUS_IS_OK(disp_ret
))
1638 /* calculate the total size */
1639 total_data_size
=num_account
*struct_size
;
1641 if (max_entries
<= num_account
) {
1642 status
= STATUS_MORE_ENTRIES
;
1644 status
= NT_STATUS_OK
;
1647 /* Ensure we cache this enumeration. */
1648 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1650 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__
));
1652 *r
->out
.total_size
= total_data_size
;
1653 *r
->out
.returned_size
= temp_size
;
1658 /****************************************************************
1659 _samr_QueryDisplayInfo2
1660 ****************************************************************/
1662 NTSTATUS
_samr_QueryDisplayInfo2(pipes_struct
*p
,
1663 struct samr_QueryDisplayInfo2
*r
)
1665 struct samr_QueryDisplayInfo q
;
1667 q
.in
.domain_handle
= r
->in
.domain_handle
;
1668 q
.in
.level
= r
->in
.level
;
1669 q
.in
.start_idx
= r
->in
.start_idx
;
1670 q
.in
.max_entries
= r
->in
.max_entries
;
1671 q
.in
.buf_size
= r
->in
.buf_size
;
1673 q
.out
.total_size
= r
->out
.total_size
;
1674 q
.out
.returned_size
= r
->out
.returned_size
;
1675 q
.out
.info
= r
->out
.info
;
1677 return _samr_QueryDisplayInfo(p
, &q
);
1680 /****************************************************************
1681 _samr_QueryDisplayInfo3
1682 ****************************************************************/
1684 NTSTATUS
_samr_QueryDisplayInfo3(pipes_struct
*p
,
1685 struct samr_QueryDisplayInfo3
*r
)
1687 struct samr_QueryDisplayInfo q
;
1689 q
.in
.domain_handle
= r
->in
.domain_handle
;
1690 q
.in
.level
= r
->in
.level
;
1691 q
.in
.start_idx
= r
->in
.start_idx
;
1692 q
.in
.max_entries
= r
->in
.max_entries
;
1693 q
.in
.buf_size
= r
->in
.buf_size
;
1695 q
.out
.total_size
= r
->out
.total_size
;
1696 q
.out
.returned_size
= r
->out
.returned_size
;
1697 q
.out
.info
= r
->out
.info
;
1699 return _samr_QueryDisplayInfo(p
, &q
);
1702 /*******************************************************************
1703 _samr_QueryAliasInfo
1704 ********************************************************************/
1706 NTSTATUS
_samr_QueryAliasInfo(pipes_struct
*p
,
1707 struct samr_QueryAliasInfo
*r
)
1710 struct acct_info info
;
1713 union samr_AliasInfo
*alias_info
= NULL
;
1714 const char *alias_name
= NULL
;
1715 const char *alias_description
= NULL
;
1717 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__
));
1719 alias_info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_AliasInfo
);
1721 return NT_STATUS_NO_MEMORY
;
1724 /* find the policy handle. open a policy on it. */
1725 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &sid
, &acc_granted
, NULL
))
1726 return NT_STATUS_INVALID_HANDLE
;
1728 status
= access_check_samr_function(acc_granted
,
1729 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
1730 "_samr_QueryAliasInfo");
1731 if (!NT_STATUS_IS_OK(status
)) {
1736 status
= pdb_get_aliasinfo(&sid
, &info
);
1739 if ( !NT_STATUS_IS_OK(status
))
1742 /* FIXME: info contains fstrings */
1743 alias_name
= talloc_strdup(r
, info
.acct_name
);
1744 alias_description
= talloc_strdup(r
, info
.acct_desc
);
1746 switch (r
->in
.level
) {
1748 alias_info
->all
.name
.string
= alias_name
;
1749 alias_info
->all
.num_members
= 1; /* ??? */
1750 alias_info
->all
.description
.string
= alias_description
;
1753 alias_info
->name
.string
= alias_name
;
1755 case ALIASINFODESCRIPTION
:
1756 alias_info
->description
.string
= alias_description
;
1759 return NT_STATUS_INVALID_INFO_CLASS
;
1762 *r
->out
.info
= alias_info
;
1764 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__
));
1766 return NT_STATUS_OK
;
1769 /*******************************************************************
1771 ********************************************************************/
1773 NTSTATUS
_samr_LookupNames(pipes_struct
*p
,
1774 struct samr_LookupNames
*r
)
1778 enum lsa_SidType
*type
;
1780 int num_rids
= r
->in
.num_names
;
1783 struct samr_Ids rids
, types
;
1784 uint32_t num_mapped
= 0;
1786 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1788 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &pol_sid
, &acc_granted
, NULL
)) {
1789 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1792 status
= access_check_samr_function(acc_granted
,
1793 0, /* Don't know the acc_bits yet */
1794 "_samr_LookupNames");
1795 if (!NT_STATUS_IS_OK(status
)) {
1799 if (num_rids
> MAX_SAM_ENTRIES
) {
1800 num_rids
= MAX_SAM_ENTRIES
;
1801 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids
));
1804 rid
= talloc_array(p
->mem_ctx
, uint32
, num_rids
);
1805 NT_STATUS_HAVE_NO_MEMORY(rid
);
1807 type
= talloc_array(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
1808 NT_STATUS_HAVE_NO_MEMORY(type
);
1810 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1811 sid_string_dbg(&pol_sid
)));
1813 for (i
= 0; i
< num_rids
; i
++) {
1815 status
= NT_STATUS_NONE_MAPPED
;
1816 type
[i
] = SID_NAME_UNKNOWN
;
1818 rid
[i
] = 0xffffffff;
1820 if (sid_check_is_builtin(&pol_sid
)) {
1821 if (lookup_builtin_name(r
->in
.names
[i
].string
,
1824 type
[i
] = SID_NAME_ALIAS
;
1827 lookup_global_sam_name(r
->in
.names
[i
].string
, 0,
1831 if (type
[i
] != SID_NAME_UNKNOWN
) {
1836 if (num_mapped
== num_rids
) {
1837 status
= NT_STATUS_OK
;
1838 } else if (num_mapped
== 0) {
1839 status
= NT_STATUS_NONE_MAPPED
;
1841 status
= STATUS_SOME_UNMAPPED
;
1844 rids
.count
= num_rids
;
1847 types
.count
= num_rids
;
1850 *r
->out
.rids
= rids
;
1851 *r
->out
.types
= types
;
1853 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1858 /****************************************************************
1859 _samr_ChangePasswordUser
1860 ****************************************************************/
1862 NTSTATUS
_samr_ChangePasswordUser(pipes_struct
*p
,
1863 struct samr_ChangePasswordUser
*r
)
1868 struct samr_Password new_lmPwdHash
, new_ntPwdHash
, checkHash
;
1869 struct samr_Password lm_pwd
, nt_pwd
;
1870 uint32_t acc_granted
;
1873 DISP_INFO
*disp_info
= NULL
;
1875 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &sid
, &acc_granted
, &disp_info
)) {
1876 return NT_STATUS_INVALID_HANDLE
;
1879 status
= access_check_samr_function(acc_granted
,
1880 SAMR_USER_ACCESS_SET_PASSWORD
,
1881 "_samr_ChangePasswordUser");
1882 if (!NT_STATUS_IS_OK(status
)) {
1886 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1887 sid_string_dbg(&sid
)));
1889 if (!(pwd
= samu_new(NULL
))) {
1890 return NT_STATUS_NO_MEMORY
;
1894 ret
= pdb_getsampwsid(pwd
, &sid
);
1899 return NT_STATUS_WRONG_PASSWORD
;
1903 const uint8_t *lm_pass
, *nt_pass
;
1905 lm_pass
= pdb_get_lanman_passwd(pwd
);
1906 nt_pass
= pdb_get_nt_passwd(pwd
);
1908 if (!lm_pass
|| !nt_pass
) {
1909 status
= NT_STATUS_WRONG_PASSWORD
;
1913 memcpy(&lm_pwd
.hash
, lm_pass
, sizeof(lm_pwd
.hash
));
1914 memcpy(&nt_pwd
.hash
, nt_pass
, sizeof(nt_pwd
.hash
));
1917 /* basic sanity checking on parameters. Do this before any database ops */
1918 if (!r
->in
.lm_present
|| !r
->in
.nt_present
||
1919 !r
->in
.old_lm_crypted
|| !r
->in
.new_lm_crypted
||
1920 !r
->in
.old_nt_crypted
|| !r
->in
.new_nt_crypted
) {
1921 /* we should really handle a change with lm not
1923 status
= NT_STATUS_INVALID_PARAMETER_MIX
;
1927 /* decrypt and check the new lm hash */
1928 D_P16(lm_pwd
.hash
, r
->in
.new_lm_crypted
->hash
, new_lmPwdHash
.hash
);
1929 D_P16(new_lmPwdHash
.hash
, r
->in
.old_lm_crypted
->hash
, checkHash
.hash
);
1930 if (memcmp(checkHash
.hash
, lm_pwd
.hash
, 16) != 0) {
1931 status
= NT_STATUS_WRONG_PASSWORD
;
1935 /* decrypt and check the new nt hash */
1936 D_P16(nt_pwd
.hash
, r
->in
.new_nt_crypted
->hash
, new_ntPwdHash
.hash
);
1937 D_P16(new_ntPwdHash
.hash
, r
->in
.old_nt_crypted
->hash
, checkHash
.hash
);
1938 if (memcmp(checkHash
.hash
, nt_pwd
.hash
, 16) != 0) {
1939 status
= NT_STATUS_WRONG_PASSWORD
;
1943 /* The NT Cross is not required by Win2k3 R2, but if present
1944 check the nt cross hash */
1945 if (r
->in
.cross1_present
&& r
->in
.nt_cross
) {
1946 D_P16(lm_pwd
.hash
, r
->in
.nt_cross
->hash
, checkHash
.hash
);
1947 if (memcmp(checkHash
.hash
, new_ntPwdHash
.hash
, 16) != 0) {
1948 status
= NT_STATUS_WRONG_PASSWORD
;
1953 /* The LM Cross is not required by Win2k3 R2, but if present
1954 check the lm cross hash */
1955 if (r
->in
.cross2_present
&& r
->in
.lm_cross
) {
1956 D_P16(nt_pwd
.hash
, r
->in
.lm_cross
->hash
, checkHash
.hash
);
1957 if (memcmp(checkHash
.hash
, new_lmPwdHash
.hash
, 16) != 0) {
1958 status
= NT_STATUS_WRONG_PASSWORD
;
1963 if (!pdb_set_nt_passwd(pwd
, new_ntPwdHash
.hash
, PDB_CHANGED
) ||
1964 !pdb_set_lanman_passwd(pwd
, new_lmPwdHash
.hash
, PDB_CHANGED
)) {
1965 status
= NT_STATUS_ACCESS_DENIED
;
1969 status
= pdb_update_sam_account(pwd
);
1976 /*******************************************************************
1977 _samr_ChangePasswordUser2
1978 ********************************************************************/
1980 NTSTATUS
_samr_ChangePasswordUser2(pipes_struct
*p
,
1981 struct samr_ChangePasswordUser2
*r
)
1987 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
1989 fstrcpy(user_name
, r
->in
.account
->string
);
1990 fstrcpy(wks
, r
->in
.server
->string
);
1992 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
1995 * Pass the user through the NT -> unix user mapping
1999 (void)map_username(user_name
);
2002 * UNIX username case mangling not required, pass_oem_change
2003 * is case insensitive.
2006 status
= pass_oem_change(user_name
,
2007 r
->in
.lm_password
->data
,
2008 r
->in
.lm_verifier
->hash
,
2009 r
->in
.nt_password
->data
,
2010 r
->in
.nt_verifier
->hash
,
2013 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
2015 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
2016 return NT_STATUS_WRONG_PASSWORD
;
2022 /****************************************************************
2023 _samr_OemChangePasswordUser2
2024 ****************************************************************/
2026 NTSTATUS
_samr_OemChangePasswordUser2(pipes_struct
*p
,
2027 struct samr_OemChangePasswordUser2
*r
)
2031 const char *wks
= NULL
;
2033 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
2035 fstrcpy(user_name
, r
->in
.account
->string
);
2036 if (r
->in
.server
&& r
->in
.server
->string
) {
2037 wks
= r
->in
.server
->string
;
2040 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
2043 * Pass the user through the NT -> unix user mapping
2047 (void)map_username(user_name
);
2050 * UNIX username case mangling not required, pass_oem_change
2051 * is case insensitive.
2054 if (!r
->in
.hash
|| !r
->in
.password
) {
2055 return NT_STATUS_INVALID_PARAMETER
;
2058 status
= pass_oem_change(user_name
,
2059 r
->in
.password
->data
,
2065 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
2066 return NT_STATUS_WRONG_PASSWORD
;
2069 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
2074 /*******************************************************************
2075 _samr_ChangePasswordUser3
2076 ********************************************************************/
2078 NTSTATUS
_samr_ChangePasswordUser3(pipes_struct
*p
,
2079 struct samr_ChangePasswordUser3
*r
)
2083 const char *wks
= NULL
;
2084 uint32 reject_reason
;
2085 struct samr_DomInfo1
*dominfo
= NULL
;
2086 struct samr_ChangeReject
*reject
= NULL
;
2089 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
2091 fstrcpy(user_name
, r
->in
.account
->string
);
2092 if (r
->in
.server
&& r
->in
.server
->string
) {
2093 wks
= r
->in
.server
->string
;
2096 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name
, wks
));
2099 * Pass the user through the NT -> unix user mapping
2103 (void)map_username(user_name
);
2106 * UNIX username case mangling not required, pass_oem_change
2107 * is case insensitive.
2110 status
= pass_oem_change(user_name
,
2111 r
->in
.lm_password
->data
,
2112 r
->in
.lm_verifier
->hash
,
2113 r
->in
.nt_password
->data
,
2114 r
->in
.nt_verifier
->hash
,
2116 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
2117 return NT_STATUS_WRONG_PASSWORD
;
2120 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) ||
2121 NT_STATUS_EQUAL(status
, NT_STATUS_ACCOUNT_RESTRICTION
)) {
2123 time_t u_expire
, u_min_age
;
2124 uint32 account_policy_temp
;
2126 dominfo
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_DomInfo1
);
2128 return NT_STATUS_NO_MEMORY
;
2131 reject
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_ChangeReject
);
2133 return NT_STATUS_NO_MEMORY
;
2140 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
, &tmp
);
2141 dominfo
->min_password_length
= tmp
;
2143 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &tmp
);
2144 dominfo
->password_history_length
= tmp
;
2146 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
2147 &dominfo
->password_properties
);
2149 pdb_get_account_policy(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
2150 u_expire
= account_policy_temp
;
2152 pdb_get_account_policy(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
2153 u_min_age
= account_policy_temp
;
2159 unix_to_nt_time_abs((NTTIME
*)&dominfo
->max_password_age
, u_expire
);
2160 unix_to_nt_time_abs((NTTIME
*)&dominfo
->min_password_age
, u_min_age
);
2162 if (lp_check_password_script() && *lp_check_password_script()) {
2163 dominfo
->password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
2166 reject
->reason
= reject_reason
;
2168 *r
->out
.dominfo
= dominfo
;
2169 *r
->out
.reject
= reject
;
2172 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
2177 /*******************************************************************
2178 makes a SAMR_R_LOOKUP_RIDS structure.
2179 ********************************************************************/
2181 static bool make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
,
2183 struct lsa_String
**lsa_name_array_p
)
2185 struct lsa_String
*lsa_name_array
= NULL
;
2188 *lsa_name_array_p
= NULL
;
2190 if (num_names
!= 0) {
2191 lsa_name_array
= TALLOC_ZERO_ARRAY(ctx
, struct lsa_String
, num_names
);
2192 if (!lsa_name_array
) {
2197 for (i
= 0; i
< num_names
; i
++) {
2198 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
] && *names
[i
] ? names
[i
] : ""));
2199 init_lsa_String(&lsa_name_array
[i
], names
[i
]);
2202 *lsa_name_array_p
= lsa_name_array
;
2207 /*******************************************************************
2209 ********************************************************************/
2211 NTSTATUS
_samr_LookupRids(pipes_struct
*p
,
2212 struct samr_LookupRids
*r
)
2216 enum lsa_SidType
*attrs
= NULL
;
2217 uint32
*wire_attrs
= NULL
;
2219 int num_rids
= (int)r
->in
.num_rids
;
2222 struct lsa_Strings names_array
;
2223 struct samr_Ids types_array
;
2224 struct lsa_String
*lsa_names
= NULL
;
2226 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2228 /* find the policy handle. open a policy on it. */
2229 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &pol_sid
, &acc_granted
, NULL
))
2230 return NT_STATUS_INVALID_HANDLE
;
2232 status
= access_check_samr_function(acc_granted
,
2233 0, /* Don't know the acc_bits yet */
2234 "_samr_LookupRids");
2235 if (!NT_STATUS_IS_OK(status
)) {
2239 if (num_rids
> 1000) {
2240 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2241 "to samba4 idl this is not possible\n", num_rids
));
2242 return NT_STATUS_UNSUCCESSFUL
;
2246 names
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, const char *, num_rids
);
2247 attrs
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
2248 wire_attrs
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_rids
);
2250 if ((names
== NULL
) || (attrs
== NULL
) || (wire_attrs
==NULL
))
2251 return NT_STATUS_NO_MEMORY
;
2258 become_root(); /* lookup_sid can require root privs */
2259 status
= pdb_lookup_rids(&pol_sid
, num_rids
, r
->in
.rids
,
2263 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
) && (num_rids
== 0)) {
2264 status
= NT_STATUS_OK
;
2267 if (!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, names
,
2269 return NT_STATUS_NO_MEMORY
;
2272 /* Convert from enum lsa_SidType to uint32 for wire format. */
2273 for (i
= 0; i
< num_rids
; i
++) {
2274 wire_attrs
[i
] = (uint32
)attrs
[i
];
2277 names_array
.count
= num_rids
;
2278 names_array
.names
= lsa_names
;
2280 types_array
.count
= num_rids
;
2281 types_array
.ids
= wire_attrs
;
2283 *r
->out
.names
= names_array
;
2284 *r
->out
.types
= types_array
;
2286 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2291 /*******************************************************************
2293 ********************************************************************/
2295 NTSTATUS
_samr_OpenUser(pipes_struct
*p
,
2296 struct samr_OpenUser
*r
)
2298 struct samu
*sampass
=NULL
;
2300 struct samr_info
*info
= NULL
;
2301 SEC_DESC
*psd
= NULL
;
2303 uint32 des_access
= r
->in
.access_mask
;
2309 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2311 if ( !get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
, NULL
) )
2312 return NT_STATUS_INVALID_HANDLE
;
2314 nt_status
= access_check_samr_function(acc_granted
,
2315 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
2318 if ( !NT_STATUS_IS_OK(nt_status
) )
2321 if ( !(sampass
= samu_new( p
->mem_ctx
)) ) {
2322 return NT_STATUS_NO_MEMORY
;
2325 /* append the user's RID to it */
2327 if (!sid_append_rid(&sid
, r
->in
.rid
))
2328 return NT_STATUS_NO_SUCH_USER
;
2330 /* check if access can be granted as requested by client. */
2332 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
2334 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
, &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
2335 se_map_generic(&des_access
, &usr_generic_mapping
);
2337 se_priv_copy( &se_rights
, &se_machine_account
);
2338 se_priv_add( &se_rights
, &se_add_users
);
2340 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
2341 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
2342 &acc_granted
, "_samr_OpenUser");
2344 if ( !NT_STATUS_IS_OK(nt_status
) )
2348 ret
=pdb_getsampwsid(sampass
, &sid
);
2351 /* check that the SID exists in our domain. */
2353 return NT_STATUS_NO_SUCH_USER
;
2356 TALLOC_FREE(sampass
);
2358 /* associate the user's SID and access bits with the new handle. */
2359 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &sid
)) == NULL
)
2360 return NT_STATUS_NO_MEMORY
;
2361 info
->acc_granted
= acc_granted
;
2363 /* get a (unique) handle. open a policy on it. */
2364 if (!create_policy_hnd(p
, r
->out
.user_handle
, info
))
2365 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2367 return NT_STATUS_OK
;
2370 /*************************************************************************
2371 *************************************************************************/
2373 static NTSTATUS
init_samr_parameters_string(TALLOC_CTX
*mem_ctx
,
2375 struct lsa_BinaryString
**_r
)
2377 struct lsa_BinaryString
*r
;
2380 return NT_STATUS_INVALID_PARAMETER
;
2383 r
= TALLOC_ZERO_P(mem_ctx
, struct lsa_BinaryString
);
2385 return NT_STATUS_NO_MEMORY
;
2388 r
->array
= TALLOC_ZERO_ARRAY(mem_ctx
, uint16_t, blob
->length
/2);
2390 return NT_STATUS_NO_MEMORY
;
2392 memcpy(r
->array
, blob
->data
, blob
->length
);
2393 r
->size
= blob
->length
;
2394 r
->length
= blob
->length
;
2397 return NT_STATUS_NO_MEMORY
;
2402 return NT_STATUS_OK
;
2405 /*************************************************************************
2407 *************************************************************************/
2409 static NTSTATUS
get_user_info_1(TALLOC_CTX
*mem_ctx
,
2410 struct samr_UserInfo1
*r
,
2412 DOM_SID
*domain_sid
)
2414 const DOM_SID
*sid_group
;
2415 uint32_t primary_gid
;
2418 sid_group
= pdb_get_group_sid(pw
);
2421 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2422 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2423 "which conflicts with the domain sid %s. Failing operation.\n",
2424 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2425 sid_string_dbg(domain_sid
)));
2426 return NT_STATUS_UNSUCCESSFUL
;
2429 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2430 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2431 r
->primary_gid
= primary_gid
;
2432 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2433 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2435 return NT_STATUS_OK
;
2438 /*************************************************************************
2440 *************************************************************************/
2442 static NTSTATUS
get_user_info_2(TALLOC_CTX
*mem_ctx
,
2443 struct samr_UserInfo2
*r
,
2446 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2447 r
->unknown
.string
= NULL
;
2448 r
->country_code
= 0;
2451 return NT_STATUS_OK
;
2454 /*************************************************************************
2456 *************************************************************************/
2458 static NTSTATUS
get_user_info_3(TALLOC_CTX
*mem_ctx
,
2459 struct samr_UserInfo3
*r
,
2461 DOM_SID
*domain_sid
)
2463 const DOM_SID
*sid_user
, *sid_group
;
2464 uint32_t rid
, primary_gid
;
2466 sid_user
= pdb_get_user_sid(pw
);
2468 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2469 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2470 "the domain sid %s. Failing operation.\n",
2471 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2472 sid_string_dbg(domain_sid
)));
2473 return NT_STATUS_UNSUCCESSFUL
;
2477 sid_group
= pdb_get_group_sid(pw
);
2480 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2481 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2482 "which conflicts with the domain sid %s. Failing operation.\n",
2483 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2484 sid_string_dbg(domain_sid
)));
2485 return NT_STATUS_UNSUCCESSFUL
;
2488 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2489 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2490 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2491 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2492 unix_to_nt_time(&r
->force_password_change
, pdb_get_pass_must_change_time(pw
));
2494 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2495 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2496 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2497 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2498 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2499 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2500 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2502 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2504 r
->primary_gid
= primary_gid
;
2505 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2506 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2507 r
->logon_count
= pdb_get_logon_count(pw
);
2509 return NT_STATUS_OK
;
2512 /*************************************************************************
2514 *************************************************************************/
2516 static NTSTATUS
get_user_info_4(TALLOC_CTX
*mem_ctx
,
2517 struct samr_UserInfo4
*r
,
2520 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2522 return NT_STATUS_OK
;
2525 /*************************************************************************
2527 *************************************************************************/
2529 static NTSTATUS
get_user_info_5(TALLOC_CTX
*mem_ctx
,
2530 struct samr_UserInfo5
*r
,
2532 DOM_SID
*domain_sid
)
2534 const DOM_SID
*sid_user
, *sid_group
;
2535 uint32_t rid
, primary_gid
;
2537 sid_user
= pdb_get_user_sid(pw
);
2539 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2540 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2541 "the domain sid %s. Failing operation.\n",
2542 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2543 sid_string_dbg(domain_sid
)));
2544 return NT_STATUS_UNSUCCESSFUL
;
2548 sid_group
= pdb_get_group_sid(pw
);
2551 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2552 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2553 "which conflicts with the domain sid %s. Failing operation.\n",
2554 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2555 sid_string_dbg(domain_sid
)));
2556 return NT_STATUS_UNSUCCESSFUL
;
2559 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2560 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2561 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2562 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2564 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2565 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2566 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2567 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2568 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2569 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2570 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2571 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2573 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2575 r
->primary_gid
= primary_gid
;
2576 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2577 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2578 r
->logon_count
= pdb_get_logon_count(pw
);
2580 return NT_STATUS_OK
;
2583 /*************************************************************************
2585 *************************************************************************/
2587 static NTSTATUS
get_user_info_6(TALLOC_CTX
*mem_ctx
,
2588 struct samr_UserInfo6
*r
,
2591 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2592 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2594 return NT_STATUS_OK
;
2597 /*************************************************************************
2598 get_user_info_7. Safe. Only gives out account_name.
2599 *************************************************************************/
2601 static NTSTATUS
get_user_info_7(TALLOC_CTX
*mem_ctx
,
2602 struct samr_UserInfo7
*r
,
2603 struct samu
*smbpass
)
2605 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(smbpass
));
2606 if (!r
->account_name
.string
) {
2607 return NT_STATUS_NO_MEMORY
;
2610 return NT_STATUS_OK
;
2613 /*************************************************************************
2615 *************************************************************************/
2617 static NTSTATUS
get_user_info_8(TALLOC_CTX
*mem_ctx
,
2618 struct samr_UserInfo8
*r
,
2621 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2623 return NT_STATUS_OK
;
2626 /*************************************************************************
2627 get_user_info_9. Only gives out primary group SID.
2628 *************************************************************************/
2630 static NTSTATUS
get_user_info_9(TALLOC_CTX
*mem_ctx
,
2631 struct samr_UserInfo9
*r
,
2632 struct samu
*smbpass
)
2634 r
->primary_gid
= pdb_get_group_rid(smbpass
);
2636 return NT_STATUS_OK
;
2639 /*************************************************************************
2641 *************************************************************************/
2643 static NTSTATUS
get_user_info_10(TALLOC_CTX
*mem_ctx
,
2644 struct samr_UserInfo10
*r
,
2647 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2648 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2650 return NT_STATUS_OK
;
2653 /*************************************************************************
2655 *************************************************************************/
2657 static NTSTATUS
get_user_info_11(TALLOC_CTX
*mem_ctx
,
2658 struct samr_UserInfo11
*r
,
2661 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2663 return NT_STATUS_OK
;
2666 /*************************************************************************
2668 *************************************************************************/
2670 static NTSTATUS
get_user_info_12(TALLOC_CTX
*mem_ctx
,
2671 struct samr_UserInfo12
*r
,
2674 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2676 return NT_STATUS_OK
;
2679 /*************************************************************************
2681 *************************************************************************/
2683 static NTSTATUS
get_user_info_13(TALLOC_CTX
*mem_ctx
,
2684 struct samr_UserInfo13
*r
,
2687 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2689 return NT_STATUS_OK
;
2692 /*************************************************************************
2694 *************************************************************************/
2696 static NTSTATUS
get_user_info_14(TALLOC_CTX
*mem_ctx
,
2697 struct samr_UserInfo14
*r
,
2700 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2702 return NT_STATUS_OK
;
2705 /*************************************************************************
2706 get_user_info_16. Safe. Only gives out acb bits.
2707 *************************************************************************/
2709 static NTSTATUS
get_user_info_16(TALLOC_CTX
*mem_ctx
,
2710 struct samr_UserInfo16
*r
,
2711 struct samu
*smbpass
)
2713 r
->acct_flags
= pdb_get_acct_ctrl(smbpass
);
2715 return NT_STATUS_OK
;
2718 /*************************************************************************
2720 *************************************************************************/
2722 static NTSTATUS
get_user_info_17(TALLOC_CTX
*mem_ctx
,
2723 struct samr_UserInfo17
*r
,
2726 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2728 return NT_STATUS_OK
;
2731 /*************************************************************************
2732 get_user_info_18. OK - this is the killer as it gives out password info.
2733 Ensure that this is only allowed on an encrypted connection with a root
2735 *************************************************************************/
2737 static NTSTATUS
get_user_info_18(pipes_struct
*p
,
2738 TALLOC_CTX
*mem_ctx
,
2739 struct samr_UserInfo18
*r
,
2742 struct samu
*smbpass
=NULL
;
2747 if (p
->auth
.auth_type
!= PIPE_AUTH_TYPE_NTLMSSP
|| p
->auth
.auth_type
!= PIPE_AUTH_TYPE_SPNEGO_NTLMSSP
) {
2748 return NT_STATUS_ACCESS_DENIED
;
2751 if (p
->auth
.auth_level
!= PIPE_AUTH_LEVEL_PRIVACY
) {
2752 return NT_STATUS_ACCESS_DENIED
;
2756 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2759 if ( !(smbpass
= samu_new( mem_ctx
)) ) {
2760 return NT_STATUS_NO_MEMORY
;
2763 ret
= pdb_getsampwsid(smbpass
, user_sid
);
2766 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid
)));
2767 TALLOC_FREE(smbpass
);
2768 return (geteuid() == (uid_t
)0) ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
2771 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
2773 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
2774 TALLOC_FREE(smbpass
);
2775 return NT_STATUS_ACCOUNT_DISABLED
;
2778 r
->lm_pwd_active
= true;
2779 r
->nt_pwd_active
= true;
2780 memcpy(r
->lm_pwd
.hash
, pdb_get_lanman_passwd(smbpass
), 16);
2781 memcpy(r
->nt_pwd
.hash
, pdb_get_nt_passwd(smbpass
), 16);
2782 r
->password_expired
= 0; /* FIXME */
2784 TALLOC_FREE(smbpass
);
2786 return NT_STATUS_OK
;
2789 /*************************************************************************
2791 *************************************************************************/
2793 static NTSTATUS
get_user_info_20(TALLOC_CTX
*mem_ctx
,
2794 struct samr_UserInfo20
*r
,
2795 struct samu
*sampass
)
2797 const char *munged_dial
= NULL
;
2800 struct lsa_BinaryString
*parameters
= NULL
;
2804 munged_dial
= pdb_get_munged_dial(sampass
);
2806 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass
),
2807 munged_dial
, (int)strlen(munged_dial
)));
2810 blob
= base64_decode_data_blob(munged_dial
);
2812 blob
= data_blob_string_const_null("");
2815 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2816 data_blob_free(&blob
);
2817 if (!NT_STATUS_IS_OK(status
)) {
2821 r
->parameters
= *parameters
;
2823 return NT_STATUS_OK
;
2827 /*************************************************************************
2829 *************************************************************************/
2831 static NTSTATUS
get_user_info_21(TALLOC_CTX
*mem_ctx
,
2832 struct samr_UserInfo21
*r
,
2834 DOM_SID
*domain_sid
)
2837 const DOM_SID
*sid_user
, *sid_group
;
2838 uint32_t rid
, primary_gid
;
2839 NTTIME force_password_change
;
2840 time_t must_change_time
;
2841 struct lsa_BinaryString
*parameters
= NULL
;
2842 const char *munged_dial
= NULL
;
2847 sid_user
= pdb_get_user_sid(pw
);
2849 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2850 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2851 "the domain sid %s. Failing operation.\n",
2852 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2853 sid_string_dbg(domain_sid
)));
2854 return NT_STATUS_UNSUCCESSFUL
;
2858 sid_group
= pdb_get_group_sid(pw
);
2861 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2862 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2863 "which conflicts with the domain sid %s. Failing operation.\n",
2864 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2865 sid_string_dbg(domain_sid
)));
2866 return NT_STATUS_UNSUCCESSFUL
;
2869 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2870 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2871 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2872 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2873 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2875 must_change_time
= pdb_get_pass_must_change_time(pw
);
2876 if (must_change_time
== get_time_t_max()) {
2877 unix_to_nt_time_abs(&force_password_change
, must_change_time
);
2879 unix_to_nt_time(&force_password_change
, must_change_time
);
2882 munged_dial
= pdb_get_munged_dial(pw
);
2884 blob
= base64_decode_data_blob(munged_dial
);
2886 blob
= data_blob_string_const_null("");
2889 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2890 data_blob_free(&blob
);
2891 if (!NT_STATUS_IS_OK(status
)) {
2895 r
->force_password_change
= force_password_change
;
2897 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2898 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2899 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2900 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2901 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2902 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2903 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2904 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2905 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2907 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2908 r
->parameters
= *parameters
;
2910 r
->primary_gid
= primary_gid
;
2911 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2912 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2913 r
->logon_count
= pdb_get_logon_count(pw
);
2914 r
->fields_present
= pdb_build_fields_present(pw
);
2915 r
->password_expired
= (pdb_get_pass_must_change_time(pw
) == 0) ?
2916 PASS_MUST_CHANGE_AT_NEXT_LOGON
: 0;
2917 r
->country_code
= 0;
2919 r
->lm_password_set
= 0;
2920 r
->nt_password_set
= 0;
2925 Look at a user on a real NT4 PDC with usrmgr, press
2926 'ok'. Then you will see that fields_present is set to
2927 0x08f827fa. Look at the user immediately after that again,
2928 and you will see that 0x00fffff is returned. This solves
2929 the problem that you get access denied after having looked
2937 return NT_STATUS_OK
;
2940 /*******************************************************************
2942 ********************************************************************/
2944 NTSTATUS
_samr_QueryUserInfo(pipes_struct
*p
,
2945 struct samr_QueryUserInfo
*r
)
2948 union samr_UserInfo
*user_info
= NULL
;
2949 struct samr_info
*info
= NULL
;
2953 struct samu
*pwd
= NULL
;
2955 /* search for the handle */
2956 if (!find_policy_by_hnd(p
, r
->in
.user_handle
, (void **)(void *)&info
))
2957 return NT_STATUS_INVALID_HANDLE
;
2959 status
= access_check_samr_function(info
->acc_granted
,
2960 SAMR_USER_ACCESS_GET_ATTRIBUTES
,
2961 "_samr_QueryUserInfo");
2962 if (!NT_STATUS_IS_OK(status
)) {
2966 domain_sid
= info
->sid
;
2968 sid_split_rid(&domain_sid
, &rid
);
2970 if (!sid_check_is_in_our_domain(&info
->sid
))
2971 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
2973 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2974 sid_string_dbg(&info
->sid
)));
2976 user_info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_UserInfo
);
2978 return NT_STATUS_NO_MEMORY
;
2981 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r
->in
.level
));
2983 if (!(pwd
= samu_new(p
->mem_ctx
))) {
2984 return NT_STATUS_NO_MEMORY
;
2988 ret
= pdb_getsampwsid(pwd
, &info
->sid
);
2992 DEBUG(4,("User %s not found\n", sid_string_dbg(&info
->sid
)));
2994 return NT_STATUS_NO_SUCH_USER
;
2997 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd
)));
2999 samr_clear_sam_passwd(pwd
);
3001 switch (r
->in
.level
) {
3003 status
= get_user_info_1(p
->mem_ctx
, &user_info
->info1
, pwd
, &domain_sid
);
3006 status
= get_user_info_2(p
->mem_ctx
, &user_info
->info2
, pwd
);
3009 status
= get_user_info_3(p
->mem_ctx
, &user_info
->info3
, pwd
, &domain_sid
);
3012 status
= get_user_info_4(p
->mem_ctx
, &user_info
->info4
, pwd
);
3015 status
= get_user_info_5(p
->mem_ctx
, &user_info
->info5
, pwd
, &domain_sid
);
3018 status
= get_user_info_6(p
->mem_ctx
, &user_info
->info6
, pwd
);
3021 status
= get_user_info_7(p
->mem_ctx
, &user_info
->info7
, pwd
);
3024 status
= get_user_info_8(p
->mem_ctx
, &user_info
->info8
, pwd
);
3027 status
= get_user_info_9(p
->mem_ctx
, &user_info
->info9
, pwd
);
3030 status
= get_user_info_10(p
->mem_ctx
, &user_info
->info10
, pwd
);
3033 status
= get_user_info_11(p
->mem_ctx
, &user_info
->info11
, pwd
);
3036 status
= get_user_info_12(p
->mem_ctx
, &user_info
->info12
, pwd
);
3039 status
= get_user_info_13(p
->mem_ctx
, &user_info
->info13
, pwd
);
3042 status
= get_user_info_14(p
->mem_ctx
, &user_info
->info14
, pwd
);
3045 status
= get_user_info_16(p
->mem_ctx
, &user_info
->info16
, pwd
);
3048 status
= get_user_info_17(p
->mem_ctx
, &user_info
->info17
, pwd
);
3051 /* level 18 is special */
3052 status
= get_user_info_18(p
, p
->mem_ctx
, &user_info
->info18
, &info
->sid
);
3055 status
= get_user_info_20(p
->mem_ctx
, &user_info
->info20
, pwd
);
3058 status
= get_user_info_21(p
->mem_ctx
, &user_info
->info21
, pwd
, &domain_sid
);
3061 status
= NT_STATUS_INVALID_INFO_CLASS
;
3067 *r
->out
.info
= user_info
;
3069 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__
));
3074 /****************************************************************
3075 ****************************************************************/
3077 NTSTATUS
_samr_QueryUserInfo2(pipes_struct
*p
,
3078 struct samr_QueryUserInfo2
*r
)
3080 struct samr_QueryUserInfo u
;
3082 u
.in
.user_handle
= r
->in
.user_handle
;
3083 u
.in
.level
= r
->in
.level
;
3084 u
.out
.info
= r
->out
.info
;
3086 return _samr_QueryUserInfo(p
, &u
);
3089 /*******************************************************************
3090 _samr_GetGroupsForUser
3091 ********************************************************************/
3093 NTSTATUS
_samr_GetGroupsForUser(pipes_struct
*p
,
3094 struct samr_GetGroupsForUser
*r
)
3096 struct samu
*sam_pass
=NULL
;
3099 struct samr_RidWithAttribute dom_gid
;
3100 struct samr_RidWithAttribute
*gids
= NULL
;
3101 uint32 primary_group_rid
;
3102 size_t num_groups
= 0;
3108 bool success
= False
;
3110 struct samr_RidWithAttributeArray
*rids
= NULL
;
3113 * from the SID in the request:
3114 * we should send back the list of DOMAIN GROUPS
3115 * the user is a member of
3117 * and only the DOMAIN GROUPS
3118 * no ALIASES !!! neither aliases of the domain
3119 * nor aliases of the builtin SID
3124 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3126 rids
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_RidWithAttributeArray
);
3128 return NT_STATUS_NO_MEMORY
;
3131 /* find the policy handle. open a policy on it. */
3132 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &sid
, &acc_granted
, NULL
))
3133 return NT_STATUS_INVALID_HANDLE
;
3135 result
= access_check_samr_function(acc_granted
,
3136 SAMR_USER_ACCESS_GET_GROUPS
,
3137 "_samr_GetGroupsForUser");
3138 if (!NT_STATUS_IS_OK(result
)) {
3142 if (!sid_check_is_in_our_domain(&sid
))
3143 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3145 if ( !(sam_pass
= samu_new( p
->mem_ctx
)) ) {
3146 return NT_STATUS_NO_MEMORY
;
3150 ret
= pdb_getsampwsid(sam_pass
, &sid
);
3154 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3155 sid_string_dbg(&sid
)));
3156 return NT_STATUS_NO_SUCH_USER
;
3161 /* make both calls inside the root block */
3163 result
= pdb_enum_group_memberships(p
->mem_ctx
, sam_pass
,
3164 &sids
, &unix_gids
, &num_groups
);
3165 if ( NT_STATUS_IS_OK(result
) ) {
3166 success
= sid_peek_check_rid(get_global_sam_sid(),
3167 pdb_get_group_sid(sam_pass
),
3168 &primary_group_rid
);
3172 if (!NT_STATUS_IS_OK(result
)) {
3173 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3174 sid_string_dbg(&sid
)));
3179 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3180 sid_string_dbg(pdb_get_group_sid(sam_pass
)),
3181 pdb_get_username(sam_pass
)));
3182 TALLOC_FREE(sam_pass
);
3183 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
3189 dom_gid
.attributes
= (SE_GROUP_MANDATORY
|SE_GROUP_ENABLED_BY_DEFAULT
|
3191 dom_gid
.rid
= primary_group_rid
;
3192 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3194 for (i
=0; i
<num_groups
; i
++) {
3196 if (!sid_peek_check_rid(get_global_sam_sid(),
3197 &(sids
[i
]), &dom_gid
.rid
)) {
3198 DEBUG(10, ("Found sid %s not in our domain\n",
3199 sid_string_dbg(&sids
[i
])));
3203 if (dom_gid
.rid
== primary_group_rid
) {
3204 /* We added the primary group directly from the
3205 * sam_account. The other SIDs are unique from
3206 * enum_group_memberships */
3210 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3213 rids
->count
= num_gids
;
3216 *r
->out
.rids
= rids
;
3218 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3223 /*******************************************************************
3224 _samr_QueryDomainInfo
3225 ********************************************************************/
3227 NTSTATUS
_samr_QueryDomainInfo(pipes_struct
*p
,
3228 struct samr_QueryDomainInfo
*r
)
3230 NTSTATUS status
= NT_STATUS_OK
;
3231 struct samr_info
*info
= NULL
;
3232 union samr_DomainInfo
*dom_info
;
3233 time_t u_expire
, u_min_age
;
3235 time_t u_lock_duration
, u_reset_time
;
3238 uint32 account_policy_temp
;
3243 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3245 dom_info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_DomainInfo
);
3247 return NT_STATUS_NO_MEMORY
;
3250 /* find the policy handle. open a policy on it. */
3251 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
)) {
3252 return NT_STATUS_INVALID_HANDLE
;
3255 status
= access_check_samr_function(info
->acc_granted
,
3256 SAMR_ACCESS_LOOKUP_DOMAIN
,
3257 "_samr_QueryDomainInfo" );
3259 if ( !NT_STATUS_IS_OK(status
) )
3262 switch (r
->in
.level
) {
3269 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
,
3270 &account_policy_temp
);
3271 dom_info
->info1
.min_password_length
= account_policy_temp
;
3273 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &account_policy_temp
);
3274 dom_info
->info1
.password_history_length
= account_policy_temp
;
3276 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
3277 &dom_info
->info1
.password_properties
);
3279 pdb_get_account_policy(AP_MAX_PASSWORD_AGE
, &account_policy_temp
);
3280 u_expire
= account_policy_temp
;
3282 pdb_get_account_policy(AP_MIN_PASSWORD_AGE
, &account_policy_temp
);
3283 u_min_age
= account_policy_temp
;
3289 unix_to_nt_time_abs((NTTIME
*)&dom_info
->info1
.max_password_age
, u_expire
);
3290 unix_to_nt_time_abs((NTTIME
*)&dom_info
->info1
.min_password_age
, u_min_age
);
3292 if (lp_check_password_script() && *lp_check_password_script()) {
3293 dom_info
->info1
.password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
3303 dom_info
->general
.num_users
= count_sam_users(info
->disp_info
, ACB_NORMAL
);
3304 dom_info
->general
.num_groups
= count_sam_groups(info
->disp_info
);
3305 dom_info
->general
.num_aliases
= count_sam_aliases(info
->disp_info
);
3307 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &u_logout
);
3309 unix_to_nt_time_abs(&dom_info
->general
.force_logoff_time
, u_logout
);
3311 if (!pdb_get_seq_num(&seq_num
))
3312 seq_num
= time(NULL
);
3318 server_role
= ROLE_DOMAIN_PDC
;
3319 if (lp_server_role() == ROLE_DOMAIN_BDC
)
3320 server_role
= ROLE_DOMAIN_BDC
;
3322 dom_info
->general
.oem_information
.string
= lp_serverstring();
3323 dom_info
->general
.domain_name
.string
= lp_workgroup();
3324 dom_info
->general
.primary
.string
= global_myname();
3325 dom_info
->general
.sequence_num
= seq_num
;
3326 dom_info
->general
.domain_server_state
= DOMAIN_SERVER_ENABLED
;
3327 dom_info
->general
.role
= server_role
;
3328 dom_info
->general
.unknown3
= 1;
3339 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &ul
);
3340 u_logout
= (time_t)ul
;
3347 unix_to_nt_time_abs(&dom_info
->info3
.force_logoff_time
, u_logout
);
3351 dom_info
->oem
.oem_information
.string
= lp_serverstring();
3354 dom_info
->info5
.domain_name
.string
= get_global_sam_name();
3357 /* NT returns its own name when a PDC. win2k and later
3358 * only the name of the PDC if itself is a BDC (samba4
3360 dom_info
->info6
.primary
.string
= global_myname();
3363 server_role
= ROLE_DOMAIN_PDC
;
3364 if (lp_server_role() == ROLE_DOMAIN_BDC
)
3365 server_role
= ROLE_DOMAIN_BDC
;
3367 dom_info
->info7
.role
= server_role
;
3375 if (!pdb_get_seq_num(&seq_num
)) {
3376 seq_num
= time(NULL
);
3383 dom_info
->info8
.sequence_num
= seq_num
;
3384 dom_info
->info8
.domain_create_time
= 0;
3389 dom_info
->info9
.domain_server_state
= DOMAIN_SERVER_ENABLED
;
3398 dom_info
->general2
.general
.num_users
= count_sam_users(
3399 info
->disp_info
, ACB_NORMAL
);
3400 dom_info
->general2
.general
.num_groups
= count_sam_groups(
3402 dom_info
->general2
.general
.num_aliases
= count_sam_aliases(
3405 pdb_get_account_policy(AP_TIME_TO_LOGOUT
, &u_logout
);
3407 unix_to_nt_time_abs(&dom_info
->general2
.general
.force_logoff_time
, u_logout
);
3409 if (!pdb_get_seq_num(&seq_num
))
3410 seq_num
= time(NULL
);
3412 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
3413 u_lock_duration
= account_policy_temp
;
3414 if (u_lock_duration
!= -1) {
3415 u_lock_duration
*= 60;
3418 pdb_get_account_policy(AP_RESET_COUNT_TIME
, &account_policy_temp
);
3419 u_reset_time
= account_policy_temp
* 60;
3421 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
,
3422 &account_policy_temp
);
3423 dom_info
->general2
.lockout_threshold
= account_policy_temp
;
3429 server_role
= ROLE_DOMAIN_PDC
;
3430 if (lp_server_role() == ROLE_DOMAIN_BDC
)
3431 server_role
= ROLE_DOMAIN_BDC
;
3433 dom_info
->general2
.general
.oem_information
.string
= lp_serverstring();
3434 dom_info
->general2
.general
.domain_name
.string
= lp_workgroup();
3435 dom_info
->general2
.general
.primary
.string
= global_myname();
3436 dom_info
->general2
.general
.sequence_num
= seq_num
;
3437 dom_info
->general2
.general
.domain_server_state
= DOMAIN_SERVER_ENABLED
;
3438 dom_info
->general2
.general
.role
= server_role
;
3439 dom_info
->general2
.general
.unknown3
= 1;
3441 unix_to_nt_time_abs(&dom_info
->general2
.lockout_duration
,
3443 unix_to_nt_time_abs(&dom_info
->general2
.lockout_window
,
3453 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
3454 u_lock_duration
= account_policy_temp
;
3455 if (u_lock_duration
!= -1) {
3456 u_lock_duration
*= 60;
3459 pdb_get_account_policy(AP_RESET_COUNT_TIME
, &account_policy_temp
);
3460 u_reset_time
= account_policy_temp
* 60;
3462 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
,
3463 &account_policy_temp
);
3464 dom_info
->info12
.lockout_threshold
= account_policy_temp
;
3470 unix_to_nt_time_abs(&dom_info
->info12
.lockout_duration
,
3472 unix_to_nt_time_abs(&dom_info
->info12
.lockout_window
,
3482 if (!pdb_get_seq_num(&seq_num
)) {
3483 seq_num
= time(NULL
);
3490 dom_info
->info13
.sequence_num
= seq_num
;
3491 dom_info
->info13
.domain_create_time
= 0;
3492 dom_info
->info13
.modified_count_at_last_promotion
= 0;
3496 return NT_STATUS_INVALID_INFO_CLASS
;
3499 *r
->out
.info
= dom_info
;
3501 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3506 /* W2k3 seems to use the same check for all 3 objects that can be created via
3507 * SAMR, if you try to create for example "Dialup" as an alias it says
3508 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3511 static NTSTATUS
can_create(TALLOC_CTX
*mem_ctx
, const char *new_name
)
3513 enum lsa_SidType type
;
3516 DEBUG(10, ("Checking whether [%s] can be created\n", new_name
));
3519 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3520 * whether the name already exists */
3521 result
= lookup_name(mem_ctx
, new_name
, LOOKUP_NAME_LOCAL
,
3522 NULL
, NULL
, NULL
, &type
);
3526 DEBUG(10, ("%s does not exist, can create it\n", new_name
));
3527 return NT_STATUS_OK
;
3530 DEBUG(5, ("trying to create %s, exists as %s\n",
3531 new_name
, sid_type_lookup(type
)));
3533 if (type
== SID_NAME_DOM_GRP
) {
3534 return NT_STATUS_GROUP_EXISTS
;
3536 if (type
== SID_NAME_ALIAS
) {
3537 return NT_STATUS_ALIAS_EXISTS
;
3540 /* Yes, the default is NT_STATUS_USER_EXISTS */
3541 return NT_STATUS_USER_EXISTS
;
3544 /*******************************************************************
3546 ********************************************************************/
3548 NTSTATUS
_samr_CreateUser2(pipes_struct
*p
,
3549 struct samr_CreateUser2
*r
)
3551 const char *account
= NULL
;
3553 uint32_t acb_info
= r
->in
.acct_flags
;
3554 struct samr_info
*info
= NULL
;
3559 /* check this, when giving away 'add computer to domain' privs */
3560 uint32 des_access
= GENERIC_RIGHTS_USER_ALL_ACCESS
;
3561 bool can_add_account
= False
;
3563 DISP_INFO
*disp_info
= NULL
;
3565 /* Get the domain SID stored in the domain policy */
3566 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
,
3568 return NT_STATUS_INVALID_HANDLE
;
3570 if (disp_info
->builtin_domain
) {
3571 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3572 return NT_STATUS_ACCESS_DENIED
;
3575 nt_status
= access_check_samr_function(acc_granted
,
3576 SAMR_DOMAIN_ACCESS_CREATE_USER
,
3577 "_samr_CreateUser2");
3578 if (!NT_STATUS_IS_OK(nt_status
)) {
3582 if (!(acb_info
== ACB_NORMAL
|| acb_info
== ACB_DOMTRUST
||
3583 acb_info
== ACB_WSTRUST
|| acb_info
== ACB_SVRTRUST
)) {
3584 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3585 this parameter is not an account type */
3586 return NT_STATUS_INVALID_PARAMETER
;
3589 account
= r
->in
.account_name
->string
;
3590 if (account
== NULL
) {
3591 return NT_STATUS_NO_MEMORY
;
3594 nt_status
= can_create(p
->mem_ctx
, account
);
3595 if (!NT_STATUS_IS_OK(nt_status
)) {
3599 /* determine which user right we need to check based on the acb_info */
3601 if ( acb_info
& ACB_WSTRUST
)
3603 se_priv_copy( &se_rights
, &se_machine_account
);
3604 can_add_account
= user_has_privileges(
3605 p
->server_info
->ptok
, &se_rights
);
3607 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3608 account for domain trusts and changes the ACB flags later */
3609 else if ( acb_info
& ACB_NORMAL
&&
3610 (account
[strlen(account
)-1] != '$') )
3612 se_priv_copy( &se_rights
, &se_add_users
);
3613 can_add_account
= user_has_privileges(
3614 p
->server_info
->ptok
, &se_rights
);
3616 else /* implicit assumption of a BDC or domain trust account here
3617 * (we already check the flags earlier) */
3619 if ( lp_enable_privileges() ) {
3620 /* only Domain Admins can add a BDC or domain trust */
3621 se_priv_copy( &se_rights
, &se_priv_none
);
3622 can_add_account
= nt_token_check_domain_rid(
3623 p
->server_info
->ptok
,
3624 DOMAIN_GROUP_RID_ADMINS
);
3628 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3629 uidtoname(p
->server_info
->utok
.uid
),
3630 can_add_account
? "True":"False" ));
3632 /********** BEGIN Admin BLOCK **********/
3634 if ( can_add_account
)
3637 nt_status
= pdb_create_user(p
->mem_ctx
, account
, acb_info
,
3640 if ( can_add_account
)
3643 /********** END Admin BLOCK **********/
3645 /* now check for failure */
3647 if ( !NT_STATUS_IS_OK(nt_status
) )
3650 /* Get the user's SID */
3652 sid_compose(&sid
, get_global_sam_sid(), *r
->out
.rid
);
3654 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3656 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
,
3657 &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
3658 se_map_generic(&des_access
, &usr_generic_mapping
);
3660 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
3661 &se_rights
, GENERIC_RIGHTS_USER_WRITE
, des_access
,
3662 &acc_granted
, "_samr_CreateUser2");
3664 if ( !NT_STATUS_IS_OK(nt_status
) ) {
3668 /* associate the user's SID with the new handle. */
3669 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &sid
)) == NULL
) {
3670 return NT_STATUS_NO_MEMORY
;
3675 info
->acc_granted
= acc_granted
;
3677 /* get a (unique) handle. open a policy on it. */
3678 if (!create_policy_hnd(p
, r
->out
.user_handle
, info
)) {
3679 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3682 /* After a "set" ensure we have no cached display info. */
3683 force_flush_samr_cache(info
->disp_info
);
3685 *r
->out
.access_granted
= acc_granted
;
3687 return NT_STATUS_OK
;
3690 /****************************************************************
3691 ****************************************************************/
3693 NTSTATUS
_samr_CreateUser(pipes_struct
*p
,
3694 struct samr_CreateUser
*r
)
3696 struct samr_CreateUser2 c
;
3697 uint32_t access_granted
;
3699 c
.in
.domain_handle
= r
->in
.domain_handle
;
3700 c
.in
.account_name
= r
->in
.account_name
;
3701 c
.in
.acct_flags
= ACB_NORMAL
;
3702 c
.in
.access_mask
= r
->in
.access_mask
;
3703 c
.out
.user_handle
= r
->out
.user_handle
;
3704 c
.out
.access_granted
= &access_granted
;
3705 c
.out
.rid
= r
->out
.rid
;
3707 return _samr_CreateUser2(p
, &c
);
3710 /*******************************************************************
3712 ********************************************************************/
3714 NTSTATUS
_samr_Connect(pipes_struct
*p
,
3715 struct samr_Connect
*r
)
3717 struct samr_info
*info
= NULL
;
3718 uint32 des_access
= r
->in
.access_mask
;
3722 if (!pipe_access_check(p
)) {
3723 DEBUG(3, ("access denied to _samr_Connect\n"));
3724 return NT_STATUS_ACCESS_DENIED
;
3727 /* set up the SAMR connect_anon response */
3729 /* associate the user's SID with the new handle. */
3730 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, NULL
)) == NULL
)
3731 return NT_STATUS_NO_MEMORY
;
3733 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3734 was observed from a win98 client trying to enumerate users (when configured
3735 user level access control on shares) --jerry */
3737 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3739 se_map_generic( &des_access
, &sam_generic_mapping
);
3740 info
->acc_granted
= des_access
& (SAMR_ACCESS_ENUM_DOMAINS
|SAMR_ACCESS_LOOKUP_DOMAIN
);
3742 /* get a (unique) handle. open a policy on it. */
3743 if (!create_policy_hnd(p
, r
->out
.connect_handle
, info
))
3744 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3746 return NT_STATUS_OK
;
3749 /*******************************************************************
3751 ********************************************************************/
3753 NTSTATUS
_samr_Connect2(pipes_struct
*p
,
3754 struct samr_Connect2
*r
)
3756 struct samr_info
*info
= NULL
;
3757 SEC_DESC
*psd
= NULL
;
3759 uint32 des_access
= r
->in
.access_mask
;
3762 const char *fn
= "_samr_Connect2";
3764 switch (p
->hdr_req
.opnum
) {
3765 case NDR_SAMR_CONNECT2
:
3766 fn
= "_samr_Connect2";
3768 case NDR_SAMR_CONNECT3
:
3769 fn
= "_samr_Connect3";
3771 case NDR_SAMR_CONNECT4
:
3772 fn
= "_samr_Connect4";
3774 case NDR_SAMR_CONNECT5
:
3775 fn
= "_samr_Connect5";
3779 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3783 if (!pipe_access_check(p
)) {
3784 DEBUG(3, ("access denied to %s\n", fn
));
3785 return NT_STATUS_ACCESS_DENIED
;
3788 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
3790 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
3791 se_map_generic(&des_access
, &sam_generic_mapping
);
3793 nt_status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
3794 NULL
, 0, des_access
, &acc_granted
, fn
);
3796 if ( !NT_STATUS_IS_OK(nt_status
) )
3799 /* associate the user's SID and access granted with the new handle. */
3800 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, NULL
)) == NULL
)
3801 return NT_STATUS_NO_MEMORY
;
3803 info
->acc_granted
= acc_granted
;
3804 info
->status
= r
->in
.access_mask
; /* this looks so wrong... - gd */
3806 /* get a (unique) handle. open a policy on it. */
3807 if (!create_policy_hnd(p
, r
->out
.connect_handle
, info
))
3808 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3810 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3815 /****************************************************************
3817 ****************************************************************/
3819 NTSTATUS
_samr_Connect3(pipes_struct
*p
,
3820 struct samr_Connect3
*r
)
3822 struct samr_Connect2 c
;
3824 c
.in
.system_name
= r
->in
.system_name
;
3825 c
.in
.access_mask
= r
->in
.access_mask
;
3826 c
.out
.connect_handle
= r
->out
.connect_handle
;
3828 return _samr_Connect2(p
, &c
);
3831 /*******************************************************************
3833 ********************************************************************/
3835 NTSTATUS
_samr_Connect4(pipes_struct
*p
,
3836 struct samr_Connect4
*r
)
3838 struct samr_Connect2 c
;
3840 c
.in
.system_name
= r
->in
.system_name
;
3841 c
.in
.access_mask
= r
->in
.access_mask
;
3842 c
.out
.connect_handle
= r
->out
.connect_handle
;
3844 return _samr_Connect2(p
, &c
);
3847 /*******************************************************************
3849 ********************************************************************/
3851 NTSTATUS
_samr_Connect5(pipes_struct
*p
,
3852 struct samr_Connect5
*r
)
3855 struct samr_Connect2 c
;
3856 struct samr_ConnectInfo1 info1
;
3858 info1
.client_version
= SAMR_CONNECT_AFTER_W2K
;
3861 c
.in
.system_name
= r
->in
.system_name
;
3862 c
.in
.access_mask
= r
->in
.access_mask
;
3863 c
.out
.connect_handle
= r
->out
.connect_handle
;
3865 *r
->out
.level_out
= 1;
3867 status
= _samr_Connect2(p
, &c
);
3868 if (!NT_STATUS_IS_OK(status
)) {
3872 r
->out
.info_out
->info1
= info1
;
3874 return NT_STATUS_OK
;
3877 /**********************************************************************
3879 **********************************************************************/
3881 NTSTATUS
_samr_LookupDomain(pipes_struct
*p
,
3882 struct samr_LookupDomain
*r
)
3884 NTSTATUS status
= NT_STATUS_OK
;
3885 struct samr_info
*info
;
3886 const char *domain_name
;
3887 DOM_SID
*sid
= NULL
;
3889 if (!find_policy_by_hnd(p
, r
->in
.connect_handle
, (void**)(void *)&info
))
3890 return NT_STATUS_INVALID_HANDLE
;
3892 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3893 Reverted that change so we will work with RAS servers again */
3895 status
= access_check_samr_function(info
->acc_granted
,
3896 SAMR_ACCESS_LOOKUP_DOMAIN
,
3897 "_samr_LookupDomain");
3898 if (!NT_STATUS_IS_OK(status
)) {
3902 domain_name
= r
->in
.domain_name
->string
;
3904 return NT_STATUS_INVALID_PARAMETER
;
3907 sid
= TALLOC_ZERO_P(p
->mem_ctx
, struct dom_sid2
);
3909 return NT_STATUS_NO_MEMORY
;
3912 if (strequal(domain_name
, builtin_domain_name())) {
3913 sid_copy(sid
, &global_sid_Builtin
);
3915 if (!secrets_fetch_domain_sid(domain_name
, sid
)) {
3916 status
= NT_STATUS_NO_SUCH_DOMAIN
;
3920 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
,
3921 sid_string_dbg(sid
)));
3928 /**********************************************************************
3930 **********************************************************************/
3932 NTSTATUS
_samr_EnumDomains(pipes_struct
*p
,
3933 struct samr_EnumDomains
*r
)
3936 struct samr_info
*info
;
3937 uint32_t num_entries
= 2;
3938 struct samr_SamEntry
*entry_array
= NULL
;
3939 struct samr_SamArray
*sam
;
3941 if (!find_policy_by_hnd(p
, r
->in
.connect_handle
, (void**)(void *)&info
))
3942 return NT_STATUS_INVALID_HANDLE
;
3944 status
= access_check_samr_function(info
->acc_granted
,
3945 SAMR_ACCESS_ENUM_DOMAINS
,
3946 "_samr_EnumDomains");
3947 if (!NT_STATUS_IS_OK(status
)) {
3951 sam
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_SamArray
);
3953 return NT_STATUS_NO_MEMORY
;
3956 entry_array
= TALLOC_ZERO_ARRAY(p
->mem_ctx
,
3957 struct samr_SamEntry
,
3960 return NT_STATUS_NO_MEMORY
;
3963 entry_array
[0].idx
= 0;
3964 init_lsa_String(&entry_array
[0].name
, get_global_sam_name());
3966 entry_array
[1].idx
= 1;
3967 init_lsa_String(&entry_array
[1].name
, "Builtin");
3969 sam
->count
= num_entries
;
3970 sam
->entries
= entry_array
;
3973 *r
->out
.num_entries
= num_entries
;
3978 /*******************************************************************
3980 ********************************************************************/
3982 NTSTATUS
_samr_OpenAlias(pipes_struct
*p
,
3983 struct samr_OpenAlias
*r
)
3986 uint32 alias_rid
= r
->in
.rid
;
3987 struct samr_info
*info
= NULL
;
3988 SEC_DESC
*psd
= NULL
;
3990 uint32 des_access
= r
->in
.access_mask
;
3995 /* find the domain policy and get the SID / access bits stored in the domain policy */
3997 if ( !get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
, NULL
) )
3998 return NT_STATUS_INVALID_HANDLE
;
4000 status
= access_check_samr_function(acc_granted
,
4001 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
4004 if ( !NT_STATUS_IS_OK(status
) )
4007 /* append the alias' RID to it */
4009 if (!sid_append_rid(&sid
, alias_rid
))
4010 return NT_STATUS_NO_SUCH_ALIAS
;
4012 /*check if access can be granted as requested by client. */
4014 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
4016 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &ali_generic_mapping
, NULL
, 0);
4017 se_map_generic(&des_access
,&ali_generic_mapping
);
4019 se_priv_copy( &se_rights
, &se_add_users
);
4022 status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
4023 &se_rights
, GENERIC_RIGHTS_ALIAS_WRITE
, des_access
,
4024 &acc_granted
, "_samr_OpenAlias");
4026 if ( !NT_STATUS_IS_OK(status
) )
4030 /* Check we actually have the requested alias */
4031 enum lsa_SidType type
;
4036 result
= lookup_sid(NULL
, &sid
, NULL
, NULL
, &type
);
4039 if (!result
|| (type
!= SID_NAME_ALIAS
)) {
4040 return NT_STATUS_NO_SUCH_ALIAS
;
4043 /* make sure there is a mapping */
4045 if ( !sid_to_gid( &sid
, &gid
) ) {
4046 return NT_STATUS_NO_SUCH_ALIAS
;
4051 /* associate the alias SID with the new handle. */
4052 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &sid
)) == NULL
)
4053 return NT_STATUS_NO_MEMORY
;
4055 info
->acc_granted
= acc_granted
;
4057 /* get a (unique) handle. open a policy on it. */
4058 if (!create_policy_hnd(p
, r
->out
.alias_handle
, info
))
4059 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4061 return NT_STATUS_OK
;
4064 /*******************************************************************
4066 ********************************************************************/
4068 static NTSTATUS
set_user_info_2(TALLOC_CTX
*mem_ctx
,
4069 struct samr_UserInfo2
*id2
,
4073 DEBUG(5,("set_user_info_2: NULL id2\n"));
4074 return NT_STATUS_ACCESS_DENIED
;
4077 copy_id2_to_sam_passwd(pwd
, id2
);
4079 return pdb_update_sam_account(pwd
);
4082 /*******************************************************************
4084 ********************************************************************/
4086 static NTSTATUS
set_user_info_4(TALLOC_CTX
*mem_ctx
,
4087 struct samr_UserInfo4
*id4
,
4091 DEBUG(5,("set_user_info_2: NULL id4\n"));
4092 return NT_STATUS_ACCESS_DENIED
;
4095 copy_id4_to_sam_passwd(pwd
, id4
);
4097 return pdb_update_sam_account(pwd
);
4100 /*******************************************************************
4102 ********************************************************************/
4104 static NTSTATUS
set_user_info_6(TALLOC_CTX
*mem_ctx
,
4105 struct samr_UserInfo6
*id6
,
4109 DEBUG(5,("set_user_info_6: NULL id6\n"));
4110 return NT_STATUS_ACCESS_DENIED
;
4113 copy_id6_to_sam_passwd(pwd
, id6
);
4115 return pdb_update_sam_account(pwd
);
4118 /*******************************************************************
4120 ********************************************************************/
4122 static NTSTATUS
set_user_info_7(TALLOC_CTX
*mem_ctx
,
4123 struct samr_UserInfo7
*id7
,
4129 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4130 return NT_STATUS_ACCESS_DENIED
;
4133 if (!id7
->account_name
.string
) {
4134 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4135 return NT_STATUS_ACCESS_DENIED
;
4138 /* check to see if the new username already exists. Note: we can't
4139 reliably lock all backends, so there is potentially the
4140 possibility that a user can be created in between this check and
4141 the rename. The rename should fail, but may not get the
4142 exact same failure status code. I think this is small enough
4143 of a window for this type of operation and the results are
4144 simply that the rename fails with a slightly different status
4145 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4147 rc
= can_create(mem_ctx
, id7
->account_name
.string
);
4149 /* when there is nothing to change, we're done here */
4150 if (NT_STATUS_EQUAL(rc
, NT_STATUS_USER_EXISTS
) &&
4151 strequal(id7
->account_name
.string
, pdb_get_username(pwd
))) {
4152 return NT_STATUS_OK
;
4154 if (!NT_STATUS_IS_OK(rc
)) {
4158 rc
= pdb_rename_sam_account(pwd
, id7
->account_name
.string
);
4163 /*******************************************************************
4165 ********************************************************************/
4167 static NTSTATUS
set_user_info_8(TALLOC_CTX
*mem_ctx
,
4168 struct samr_UserInfo8
*id8
,
4172 DEBUG(5,("set_user_info_8: NULL id8\n"));
4173 return NT_STATUS_ACCESS_DENIED
;
4176 copy_id8_to_sam_passwd(pwd
, id8
);
4178 return pdb_update_sam_account(pwd
);
4181 /*******************************************************************
4183 ********************************************************************/
4185 static NTSTATUS
set_user_info_10(TALLOC_CTX
*mem_ctx
,
4186 struct samr_UserInfo10
*id10
,
4190 DEBUG(5,("set_user_info_8: NULL id10\n"));
4191 return NT_STATUS_ACCESS_DENIED
;
4194 copy_id10_to_sam_passwd(pwd
, id10
);
4196 return pdb_update_sam_account(pwd
);
4199 /*******************************************************************
4201 ********************************************************************/
4203 static NTSTATUS
set_user_info_11(TALLOC_CTX
*mem_ctx
,
4204 struct samr_UserInfo11
*id11
,
4208 DEBUG(5,("set_user_info_11: NULL id11\n"));
4209 return NT_STATUS_ACCESS_DENIED
;
4212 copy_id11_to_sam_passwd(pwd
, id11
);
4214 return pdb_update_sam_account(pwd
);
4217 /*******************************************************************
4219 ********************************************************************/
4221 static NTSTATUS
set_user_info_12(TALLOC_CTX
*mem_ctx
,
4222 struct samr_UserInfo12
*id12
,
4226 DEBUG(5,("set_user_info_12: NULL id12\n"));
4227 return NT_STATUS_ACCESS_DENIED
;
4230 copy_id12_to_sam_passwd(pwd
, id12
);
4232 return pdb_update_sam_account(pwd
);
4235 /*******************************************************************
4237 ********************************************************************/
4239 static NTSTATUS
set_user_info_13(TALLOC_CTX
*mem_ctx
,
4240 struct samr_UserInfo13
*id13
,
4244 DEBUG(5,("set_user_info_13: NULL id13\n"));
4245 return NT_STATUS_ACCESS_DENIED
;
4248 copy_id13_to_sam_passwd(pwd
, id13
);
4250 return pdb_update_sam_account(pwd
);
4253 /*******************************************************************
4255 ********************************************************************/
4257 static NTSTATUS
set_user_info_14(TALLOC_CTX
*mem_ctx
,
4258 struct samr_UserInfo14
*id14
,
4262 DEBUG(5,("set_user_info_14: NULL id14\n"));
4263 return NT_STATUS_ACCESS_DENIED
;
4266 copy_id14_to_sam_passwd(pwd
, id14
);
4268 return pdb_update_sam_account(pwd
);
4271 /*******************************************************************
4273 ********************************************************************/
4275 static NTSTATUS
set_user_info_16(TALLOC_CTX
*mem_ctx
,
4276 struct samr_UserInfo16
*id16
,
4280 DEBUG(5,("set_user_info_16: NULL id16\n"));
4281 return NT_STATUS_ACCESS_DENIED
;
4284 copy_id16_to_sam_passwd(pwd
, id16
);
4286 return pdb_update_sam_account(pwd
);
4289 /*******************************************************************
4291 ********************************************************************/
4293 static NTSTATUS
set_user_info_17(TALLOC_CTX
*mem_ctx
,
4294 struct samr_UserInfo17
*id17
,
4298 DEBUG(5,("set_user_info_17: NULL id17\n"));
4299 return NT_STATUS_ACCESS_DENIED
;
4302 copy_id17_to_sam_passwd(pwd
, id17
);
4304 return pdb_update_sam_account(pwd
);
4307 /*******************************************************************
4309 ********************************************************************/
4311 static NTSTATUS
set_user_info_18(struct samr_UserInfo18
*id18
,
4312 TALLOC_CTX
*mem_ctx
,
4313 DATA_BLOB
*session_key
,
4317 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4318 return NT_STATUS_INVALID_PARAMETER
;
4321 if (id18
->nt_pwd_active
|| id18
->lm_pwd_active
) {
4322 if (!session_key
->length
) {
4323 return NT_STATUS_NO_USER_SESSION_KEY
;
4327 if (id18
->nt_pwd_active
) {
4331 in
= data_blob_const(id18
->nt_pwd
.hash
, 16);
4332 out
= data_blob_talloc_zero(mem_ctx
, 16);
4334 sess_crypt_blob(&out
, &in
, session_key
, false);
4336 if (!pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4337 return NT_STATUS_ACCESS_DENIED
;
4340 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4343 if (id18
->lm_pwd_active
) {
4347 in
= data_blob_const(id18
->lm_pwd
.hash
, 16);
4348 out
= data_blob_talloc_zero(mem_ctx
, 16);
4350 sess_crypt_blob(&out
, &in
, session_key
, false);
4352 if (!pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4353 return NT_STATUS_ACCESS_DENIED
;
4356 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4359 copy_id18_to_sam_passwd(pwd
, id18
);
4361 return pdb_update_sam_account(pwd
);
4364 /*******************************************************************
4366 ********************************************************************/
4368 static NTSTATUS
set_user_info_20(TALLOC_CTX
*mem_ctx
,
4369 struct samr_UserInfo20
*id20
,
4373 DEBUG(5,("set_user_info_20: NULL id20\n"));
4374 return NT_STATUS_ACCESS_DENIED
;
4377 copy_id20_to_sam_passwd(pwd
, id20
);
4379 return pdb_update_sam_account(pwd
);
4382 /*******************************************************************
4384 ********************************************************************/
4386 static NTSTATUS
set_user_info_21(struct samr_UserInfo21
*id21
,
4387 TALLOC_CTX
*mem_ctx
,
4388 DATA_BLOB
*session_key
,
4394 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4395 return NT_STATUS_INVALID_PARAMETER
;
4398 if (id21
->fields_present
== 0) {
4399 return NT_STATUS_INVALID_PARAMETER
;
4402 if (id21
->fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4403 return NT_STATUS_ACCESS_DENIED
;
4406 if (id21
->fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
4407 if (id21
->nt_password_set
) {
4410 if ((id21
->nt_owf_password
.length
!= 16) ||
4411 (id21
->nt_owf_password
.size
!= 16)) {
4412 return NT_STATUS_INVALID_PARAMETER
;
4415 if (!session_key
->length
) {
4416 return NT_STATUS_NO_USER_SESSION_KEY
;
4419 in
= data_blob_const(id21
->nt_owf_password
.array
, 16);
4420 out
= data_blob_talloc_zero(mem_ctx
, 16);
4422 sess_crypt_blob(&out
, &in
, session_key
, false);
4424 pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
);
4425 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4429 if (id21
->fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4430 if (id21
->lm_password_set
) {
4433 if ((id21
->lm_owf_password
.length
!= 16) ||
4434 (id21
->lm_owf_password
.size
!= 16)) {
4435 return NT_STATUS_INVALID_PARAMETER
;
4438 if (!session_key
->length
) {
4439 return NT_STATUS_NO_USER_SESSION_KEY
;
4442 in
= data_blob_const(id21
->lm_owf_password
.array
, 16);
4443 out
= data_blob_talloc_zero(mem_ctx
, 16);
4445 sess_crypt_blob(&out
, &in
, session_key
, false);
4447 pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
);
4448 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4452 /* we need to separately check for an account rename first */
4454 if (id21
->account_name
.string
&&
4455 (!strequal(id21
->account_name
.string
, pdb_get_username(pwd
))))
4458 /* check to see if the new username already exists. Note: we can't
4459 reliably lock all backends, so there is potentially the
4460 possibility that a user can be created in between this check and
4461 the rename. The rename should fail, but may not get the
4462 exact same failure status code. I think this is small enough
4463 of a window for this type of operation and the results are
4464 simply that the rename fails with a slightly different status
4465 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4467 status
= can_create(mem_ctx
, id21
->account_name
.string
);
4468 if (!NT_STATUS_IS_OK(status
)) {
4472 status
= pdb_rename_sam_account(pwd
, id21
->account_name
.string
);
4474 if (!NT_STATUS_IS_OK(status
)) {
4475 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4476 nt_errstr(status
)));
4480 /* set the new username so that later
4481 functions can work on the new account */
4482 pdb_set_username(pwd
, id21
->account_name
.string
, PDB_SET
);
4485 copy_id21_to_sam_passwd("INFO_21", pwd
, id21
);
4488 * The funny part about the previous two calls is
4489 * that pwd still has the password hashes from the
4490 * passdb entry. These have not been updated from
4491 * id21. I don't know if they need to be set. --jerry
4494 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4495 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4496 if ( !NT_STATUS_IS_OK(status
) ) {
4501 /* Don't worry about writing out the user account since the
4502 primary group SID is generated solely from the user's Unix
4505 /* write the change out */
4506 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4510 return NT_STATUS_OK
;
4513 /*******************************************************************
4515 ********************************************************************/
4517 static NTSTATUS
set_user_info_23(TALLOC_CTX
*mem_ctx
,
4518 struct samr_UserInfo23
*id23
,
4521 char *plaintext_buf
= NULL
;
4527 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4528 return NT_STATUS_INVALID_PARAMETER
;
4531 if (id23
->info
.fields_present
== 0) {
4532 return NT_STATUS_INVALID_PARAMETER
;
4535 if (id23
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4536 return NT_STATUS_ACCESS_DENIED
;
4539 if ((id23
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4540 (id23
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4542 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4543 pdb_get_username(pwd
)));
4545 if (!decode_pw_buffer(mem_ctx
,
4546 id23
->password
.data
,
4550 return NT_STATUS_WRONG_PASSWORD
;
4553 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4554 return NT_STATUS_ACCESS_DENIED
;
4558 copy_id23_to_sam_passwd(pwd
, id23
);
4560 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4562 /* if it's a trust account, don't update /etc/passwd */
4563 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4564 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4565 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4566 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4567 } else if (plaintext_buf
) {
4568 /* update the UNIX password */
4569 if (lp_unix_password_sync() ) {
4570 struct passwd
*passwd
;
4571 if (pdb_get_username(pwd
) == NULL
) {
4572 DEBUG(1, ("chgpasswd: User without name???\n"));
4573 return NT_STATUS_ACCESS_DENIED
;
4576 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4577 if (passwd
== NULL
) {
4578 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4581 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
4582 return NT_STATUS_ACCESS_DENIED
;
4584 TALLOC_FREE(passwd
);
4588 if (plaintext_buf
) {
4589 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4592 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) &&
4593 (!NT_STATUS_IS_OK(status
= pdb_set_unix_primary_group(mem_ctx
,
4598 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4602 return NT_STATUS_OK
;
4605 /*******************************************************************
4607 ********************************************************************/
4609 static bool set_user_info_pw(uint8
*pass
, struct samu
*pwd
)
4612 char *plaintext_buf
= NULL
;
4615 DEBUG(5, ("Attempting administrator password change for user %s\n",
4616 pdb_get_username(pwd
)));
4618 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4620 if (!decode_pw_buffer(talloc_tos(),
4628 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4632 /* if it's a trust account, don't update /etc/passwd */
4633 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4634 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4635 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4636 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4638 /* update the UNIX password */
4639 if (lp_unix_password_sync()) {
4640 struct passwd
*passwd
;
4642 if (pdb_get_username(pwd
) == NULL
) {
4643 DEBUG(1, ("chgpasswd: User without name???\n"));
4647 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4648 if (passwd
== NULL
) {
4649 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4652 if(!chgpasswd(pdb_get_username(pwd
), passwd
, "", plaintext_buf
, True
)) {
4655 TALLOC_FREE(passwd
);
4659 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4661 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4666 /*******************************************************************
4668 ********************************************************************/
4670 static NTSTATUS
set_user_info_24(TALLOC_CTX
*mem_ctx
,
4671 struct samr_UserInfo24
*id24
,
4677 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4678 return NT_STATUS_INVALID_PARAMETER
;
4681 if (!set_user_info_pw(id24
->password
.data
, pwd
)) {
4682 return NT_STATUS_WRONG_PASSWORD
;
4685 copy_id24_to_sam_passwd(pwd
, id24
);
4687 status
= pdb_update_sam_account(pwd
);
4688 if (!NT_STATUS_IS_OK(status
)) {
4692 return NT_STATUS_OK
;
4695 /*******************************************************************
4697 ********************************************************************/
4699 static NTSTATUS
set_user_info_25(TALLOC_CTX
*mem_ctx
,
4700 struct samr_UserInfo25
*id25
,
4706 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4707 return NT_STATUS_INVALID_PARAMETER
;
4710 if (id25
->info
.fields_present
== 0) {
4711 return NT_STATUS_INVALID_PARAMETER
;
4714 if (id25
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4715 return NT_STATUS_ACCESS_DENIED
;
4718 if ((id25
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4719 (id25
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4721 if (!set_user_info_pw(id25
->password
.data
, pwd
)) {
4722 return NT_STATUS_WRONG_PASSWORD
;
4726 copy_id25_to_sam_passwd(pwd
, id25
);
4728 /* write the change out */
4729 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4734 * We need to "pdb_update_sam_account" before the unix primary group
4735 * is set, because the idealx scripts would also change the
4736 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4737 * the delete explicit / add explicit, which would then fail to find
4738 * the previous primaryGroupSid value.
4741 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4742 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4743 if ( !NT_STATUS_IS_OK(status
) ) {
4748 return NT_STATUS_OK
;
4751 /*******************************************************************
4753 ********************************************************************/
4755 static NTSTATUS
set_user_info_26(TALLOC_CTX
*mem_ctx
,
4756 struct samr_UserInfo26
*id26
,
4762 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4763 return NT_STATUS_INVALID_PARAMETER
;
4766 if (!set_user_info_pw(id26
->password
.data
, pwd
)) {
4767 return NT_STATUS_WRONG_PASSWORD
;
4770 copy_id26_to_sam_passwd(pwd
, id26
);
4772 status
= pdb_update_sam_account(pwd
);
4773 if (!NT_STATUS_IS_OK(status
)) {
4777 return NT_STATUS_OK
;
4781 /*******************************************************************
4783 ********************************************************************/
4785 NTSTATUS
_samr_SetUserInfo(pipes_struct
*p
,
4786 struct samr_SetUserInfo
*r
)
4789 struct samu
*pwd
= NULL
;
4791 union samr_UserInfo
*info
= r
->in
.info
;
4792 uint16_t switch_value
= r
->in
.level
;
4793 uint32_t acc_granted
;
4794 uint32_t acc_required
;
4796 bool has_enough_rights
= False
;
4798 DISP_INFO
*disp_info
= NULL
;
4800 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__
));
4802 /* find the policy handle. open a policy on it. */
4803 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &sid
, &acc_granted
, &disp_info
)) {
4804 return NT_STATUS_INVALID_HANDLE
;
4807 /* This is tricky. A WinXP domain join sets
4808 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4809 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4810 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4811 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4812 we'll use the set from the WinXP join as the basis. */
4814 switch (switch_value
) {
4816 acc_required
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4822 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
;
4825 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
|
4826 SAMR_USER_ACCESS_SET_ATTRIBUTES
|
4827 SAMR_USER_ACCESS_GET_ATTRIBUTES
;
4831 status
= access_check_samr_function(acc_granted
,
4833 "_samr_SetUserInfo");
4834 if (!NT_STATUS_IS_OK(status
)) {
4838 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4839 sid_string_dbg(&sid
), switch_value
));
4842 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4843 return NT_STATUS_INVALID_INFO_CLASS
;
4846 if (!(pwd
= samu_new(NULL
))) {
4847 return NT_STATUS_NO_MEMORY
;
4851 ret
= pdb_getsampwsid(pwd
, &sid
);
4856 return NT_STATUS_NO_SUCH_USER
;
4859 /* deal with machine password changes differently from userinfo changes */
4860 /* check to see if we have the sufficient rights */
4862 acb_info
= pdb_get_acct_ctrl(pwd
);
4863 if (acb_info
& ACB_WSTRUST
)
4864 has_enough_rights
= user_has_privileges(p
->server_info
->ptok
,
4865 &se_machine_account
);
4866 else if (acb_info
& ACB_NORMAL
)
4867 has_enough_rights
= user_has_privileges(p
->server_info
->ptok
,
4869 else if (acb_info
& (ACB_SVRTRUST
|ACB_DOMTRUST
)) {
4870 if (lp_enable_privileges()) {
4871 has_enough_rights
= nt_token_check_domain_rid(p
->server_info
->ptok
,
4872 DOMAIN_GROUP_RID_ADMINS
);
4876 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4877 uidtoname(p
->server_info
->utok
.uid
),
4878 has_enough_rights
? "" : " not"));
4880 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4882 if (has_enough_rights
) {
4886 /* ok! user info levels (lots: see MSDEV help), off we go... */
4888 switch (switch_value
) {
4891 status
= set_user_info_2(p
->mem_ctx
,
4896 status
= set_user_info_4(p
->mem_ctx
,
4901 status
= set_user_info_6(p
->mem_ctx
,
4906 status
= set_user_info_7(p
->mem_ctx
,
4911 status
= set_user_info_8(p
->mem_ctx
,
4916 status
= set_user_info_10(p
->mem_ctx
,
4917 &info
->info10
, pwd
);
4921 status
= set_user_info_11(p
->mem_ctx
,
4922 &info
->info11
, pwd
);
4926 status
= set_user_info_12(p
->mem_ctx
,
4927 &info
->info12
, pwd
);
4931 status
= set_user_info_13(p
->mem_ctx
,
4932 &info
->info13
, pwd
);
4936 status
= set_user_info_14(p
->mem_ctx
,
4937 &info
->info14
, pwd
);
4941 status
= set_user_info_16(p
->mem_ctx
,
4942 &info
->info16
, pwd
);
4946 status
= set_user_info_17(p
->mem_ctx
,
4947 &info
->info17
, pwd
);
4951 /* Used by AS/U JRA. */
4952 status
= set_user_info_18(&info
->info18
,
4954 &p
->server_info
->user_session_key
,
4959 status
= set_user_info_20(p
->mem_ctx
,
4960 &info
->info20
, pwd
);
4964 status
= set_user_info_21(&info
->info21
,
4966 &p
->server_info
->user_session_key
,
4971 if (!p
->server_info
->user_session_key
.length
) {
4972 status
= NT_STATUS_NO_USER_SESSION_KEY
;
4974 SamOEMhashBlob(info
->info23
.password
.data
, 516,
4975 &p
->server_info
->user_session_key
);
4977 dump_data(100, info
->info23
.password
.data
, 516);
4979 status
= set_user_info_23(p
->mem_ctx
,
4980 &info
->info23
, pwd
);
4984 if (!p
->server_info
->user_session_key
.length
) {
4985 status
= NT_STATUS_NO_USER_SESSION_KEY
;
4987 SamOEMhashBlob(info
->info24
.password
.data
,
4989 &p
->server_info
->user_session_key
);
4991 dump_data(100, info
->info24
.password
.data
, 516);
4993 status
= set_user_info_24(p
->mem_ctx
,
4994 &info
->info24
, pwd
);
4998 if (!p
->server_info
->user_session_key
.length
) {
4999 status
= NT_STATUS_NO_USER_SESSION_KEY
;
5001 encode_or_decode_arc4_passwd_buffer(
5002 info
->info25
.password
.data
,
5003 &p
->server_info
->user_session_key
);
5005 dump_data(100, info
->info25
.password
.data
, 532);
5007 status
= set_user_info_25(p
->mem_ctx
,
5008 &info
->info25
, pwd
);
5012 if (!p
->server_info
->user_session_key
.length
) {
5013 status
= NT_STATUS_NO_USER_SESSION_KEY
;
5015 encode_or_decode_arc4_passwd_buffer(
5016 info
->info26
.password
.data
,
5017 &p
->server_info
->user_session_key
);
5019 dump_data(100, info
->info26
.password
.data
, 516);
5021 status
= set_user_info_26(p
->mem_ctx
,
5022 &info
->info26
, pwd
);
5026 status
= NT_STATUS_INVALID_INFO_CLASS
;
5031 if (has_enough_rights
) {
5035 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
5037 if (NT_STATUS_IS_OK(status
)) {
5038 force_flush_samr_cache(disp_info
);
5044 /*******************************************************************
5046 ********************************************************************/
5048 NTSTATUS
_samr_SetUserInfo2(pipes_struct
*p
,
5049 struct samr_SetUserInfo2
*r
)
5051 struct samr_SetUserInfo q
;
5053 q
.in
.user_handle
= r
->in
.user_handle
;
5054 q
.in
.level
= r
->in
.level
;
5055 q
.in
.info
= r
->in
.info
;
5057 return _samr_SetUserInfo(p
, &q
);
5060 /*********************************************************************
5061 _samr_GetAliasMembership
5062 *********************************************************************/
5064 NTSTATUS
_samr_GetAliasMembership(pipes_struct
*p
,
5065 struct samr_GetAliasMembership
*r
)
5067 size_t num_alias_rids
;
5069 struct samr_info
*info
= NULL
;
5077 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__
));
5079 /* find the policy handle. open a policy on it. */
5080 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
5081 return NT_STATUS_INVALID_HANDLE
;
5083 ntstatus1
= access_check_samr_function(info
->acc_granted
,
5084 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
5085 "_samr_GetAliasMembership");
5086 ntstatus2
= access_check_samr_function(info
->acc_granted
,
5087 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
5088 "_samr_GetAliasMembership");
5090 if (!NT_STATUS_IS_OK(ntstatus1
) || !NT_STATUS_IS_OK(ntstatus2
)) {
5091 if (!(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus2
)) &&
5092 !(NT_STATUS_EQUAL(ntstatus1
,NT_STATUS_ACCESS_DENIED
) && NT_STATUS_IS_OK(ntstatus1
))) {
5093 return (NT_STATUS_IS_OK(ntstatus1
)) ? ntstatus2
: ntstatus1
;
5097 if (!sid_check_is_domain(&info
->sid
) &&
5098 !sid_check_is_builtin(&info
->sid
))
5099 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
5101 if (r
->in
.sids
->num_sids
) {
5102 members
= TALLOC_ARRAY(p
->mem_ctx
, DOM_SID
, r
->in
.sids
->num_sids
);
5104 if (members
== NULL
)
5105 return NT_STATUS_NO_MEMORY
;
5110 for (i
=0; i
<r
->in
.sids
->num_sids
; i
++)
5111 sid_copy(&members
[i
], r
->in
.sids
->sids
[i
].sid
);
5117 ntstatus1
= pdb_enum_alias_memberships(p
->mem_ctx
, &info
->sid
, members
,
5118 r
->in
.sids
->num_sids
,
5119 &alias_rids
, &num_alias_rids
);
5122 if (!NT_STATUS_IS_OK(ntstatus1
)) {
5126 r
->out
.rids
->count
= num_alias_rids
;
5127 r
->out
.rids
->ids
= alias_rids
;
5129 return NT_STATUS_OK
;
5132 /*********************************************************************
5133 _samr_GetMembersInAlias
5134 *********************************************************************/
5136 NTSTATUS
_samr_GetMembersInAlias(pipes_struct
*p
,
5137 struct samr_GetMembersInAlias
*r
)
5141 size_t num_sids
= 0;
5142 struct lsa_SidPtr
*sids
= NULL
;
5143 DOM_SID
*pdb_sids
= NULL
;
5149 /* find the policy handle. open a policy on it. */
5150 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, NULL
))
5151 return NT_STATUS_INVALID_HANDLE
;
5153 status
= access_check_samr_function(acc_granted
,
5154 SAMR_ALIAS_ACCESS_GET_MEMBERS
,
5155 "_samr_GetMembersInAlias");
5156 if (!NT_STATUS_IS_OK(status
)) {
5160 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid
)));
5163 status
= pdb_enum_aliasmem(&alias_sid
, &pdb_sids
, &num_sids
);
5166 if (!NT_STATUS_IS_OK(status
)) {
5171 sids
= TALLOC_ZERO_ARRAY(p
->mem_ctx
, struct lsa_SidPtr
, num_sids
);
5173 TALLOC_FREE(pdb_sids
);
5174 return NT_STATUS_NO_MEMORY
;
5178 for (i
= 0; i
< num_sids
; i
++) {
5179 sids
[i
].sid
= sid_dup_talloc(p
->mem_ctx
, &pdb_sids
[i
]);
5181 TALLOC_FREE(pdb_sids
);
5182 return NT_STATUS_NO_MEMORY
;
5186 r
->out
.sids
->num_sids
= num_sids
;
5187 r
->out
.sids
->sids
= sids
;
5189 TALLOC_FREE(pdb_sids
);
5191 return NT_STATUS_OK
;
5194 /*********************************************************************
5195 _samr_QueryGroupMember
5196 *********************************************************************/
5198 NTSTATUS
_samr_QueryGroupMember(pipes_struct
*p
,
5199 struct samr_QueryGroupMember
*r
)
5202 size_t i
, num_members
;
5210 struct samr_RidTypeArray
*rids
= NULL
;
5212 rids
= TALLOC_ZERO_P(p
->mem_ctx
, struct samr_RidTypeArray
);
5214 return NT_STATUS_NO_MEMORY
;
5217 /* find the policy handle. open a policy on it. */
5218 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, NULL
))
5219 return NT_STATUS_INVALID_HANDLE
;
5221 status
= access_check_samr_function(acc_granted
,
5222 SAMR_GROUP_ACCESS_GET_MEMBERS
,
5223 "_samr_QueryGroupMember");
5224 if (!NT_STATUS_IS_OK(status
)) {
5228 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid
)));
5230 if (!sid_check_is_in_our_domain(&group_sid
)) {
5231 DEBUG(3, ("sid %s is not in our domain\n",
5232 sid_string_dbg(&group_sid
)));
5233 return NT_STATUS_NO_SUCH_GROUP
;
5236 DEBUG(10, ("lookup on Domain SID\n"));
5239 status
= pdb_enum_group_members(p
->mem_ctx
, &group_sid
,
5240 &rid
, &num_members
);
5243 if (!NT_STATUS_IS_OK(status
))
5247 attr
=TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint32
, num_members
);
5249 return NT_STATUS_NO_MEMORY
;
5255 for (i
=0; i
<num_members
; i
++)
5256 attr
[i
] = SID_NAME_USER
;
5258 rids
->count
= num_members
;
5262 *r
->out
.rids
= rids
;
5264 return NT_STATUS_OK
;
5267 /*********************************************************************
5268 _samr_AddAliasMember
5269 *********************************************************************/
5271 NTSTATUS
_samr_AddAliasMember(pipes_struct
*p
,
5272 struct samr_AddAliasMember
*r
)
5277 bool can_add_accounts
;
5279 DISP_INFO
*disp_info
= NULL
;
5281 /* Find the policy handle. Open a policy on it. */
5282 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, &disp_info
))
5283 return NT_STATUS_INVALID_HANDLE
;
5285 status
= access_check_samr_function(acc_granted
,
5286 SAMR_ALIAS_ACCESS_ADD_MEMBER
,
5287 "_samr_AddAliasMember");
5288 if (!NT_STATUS_IS_OK(status
)) {
5292 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid
)));
5294 se_priv_copy( &se_rights
, &se_add_users
);
5295 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5297 /******** BEGIN SeAddUsers BLOCK *********/
5299 if ( can_add_accounts
)
5302 status
= pdb_add_aliasmem(&alias_sid
, r
->in
.sid
);
5304 if ( can_add_accounts
)
5307 /******** END SeAddUsers BLOCK *********/
5309 if (NT_STATUS_IS_OK(status
)) {
5310 force_flush_samr_cache(disp_info
);
5316 /*********************************************************************
5317 _samr_DeleteAliasMember
5318 *********************************************************************/
5320 NTSTATUS
_samr_DeleteAliasMember(pipes_struct
*p
,
5321 struct samr_DeleteAliasMember
*r
)
5326 bool can_add_accounts
;
5328 DISP_INFO
*disp_info
= NULL
;
5330 /* Find the policy handle. Open a policy on it. */
5331 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, &disp_info
))
5332 return NT_STATUS_INVALID_HANDLE
;
5334 status
= access_check_samr_function(acc_granted
,
5335 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
,
5336 "_samr_DeleteAliasMember");
5337 if (!NT_STATUS_IS_OK(status
)) {
5341 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5342 sid_string_dbg(&alias_sid
)));
5344 se_priv_copy( &se_rights
, &se_add_users
);
5345 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5347 /******** BEGIN SeAddUsers BLOCK *********/
5349 if ( can_add_accounts
)
5352 status
= pdb_del_aliasmem(&alias_sid
, r
->in
.sid
);
5354 if ( can_add_accounts
)
5357 /******** END SeAddUsers BLOCK *********/
5359 if (NT_STATUS_IS_OK(status
)) {
5360 force_flush_samr_cache(disp_info
);
5366 /*********************************************************************
5367 _samr_AddGroupMember
5368 *********************************************************************/
5370 NTSTATUS
_samr_AddGroupMember(pipes_struct
*p
,
5371 struct samr_AddGroupMember
*r
)
5378 bool can_add_accounts
;
5379 DISP_INFO
*disp_info
= NULL
;
5381 /* Find the policy handle. Open a policy on it. */
5382 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5383 return NT_STATUS_INVALID_HANDLE
;
5385 status
= access_check_samr_function(acc_granted
,
5386 SAMR_GROUP_ACCESS_ADD_MEMBER
,
5387 "_samr_AddGroupMember");
5388 if (!NT_STATUS_IS_OK(status
)) {
5392 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid
)));
5394 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid
,
5396 return NT_STATUS_INVALID_HANDLE
;
5399 se_priv_copy( &se_rights
, &se_add_users
);
5400 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5402 /******** BEGIN SeAddUsers BLOCK *********/
5404 if ( can_add_accounts
)
5407 status
= pdb_add_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5409 if ( can_add_accounts
)
5412 /******** END SeAddUsers BLOCK *********/
5414 force_flush_samr_cache(disp_info
);
5419 /*********************************************************************
5420 _samr_DeleteGroupMember
5421 *********************************************************************/
5423 NTSTATUS
_samr_DeleteGroupMember(pipes_struct
*p
,
5424 struct samr_DeleteGroupMember
*r
)
5432 bool can_add_accounts
;
5433 DISP_INFO
*disp_info
= NULL
;
5436 * delete the group member named r->in.rid
5437 * who is a member of the sid associated with the handle
5438 * the rid is a user's rid as the group is a domain group.
5441 /* Find the policy handle. Open a policy on it. */
5442 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5443 return NT_STATUS_INVALID_HANDLE
;
5445 status
= access_check_samr_function(acc_granted
,
5446 SAMR_GROUP_ACCESS_REMOVE_MEMBER
,
5447 "_samr_DeleteGroupMember");
5448 if (!NT_STATUS_IS_OK(status
)) {
5452 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid
,
5454 return NT_STATUS_INVALID_HANDLE
;
5457 se_priv_copy( &se_rights
, &se_add_users
);
5458 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5460 /******** BEGIN SeAddUsers BLOCK *********/
5462 if ( can_add_accounts
)
5465 status
= pdb_del_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5467 if ( can_add_accounts
)
5470 /******** END SeAddUsers BLOCK *********/
5472 force_flush_samr_cache(disp_info
);
5477 /*********************************************************************
5479 *********************************************************************/
5481 NTSTATUS
_samr_DeleteUser(pipes_struct
*p
,
5482 struct samr_DeleteUser
*r
)
5486 struct samu
*sam_pass
=NULL
;
5488 bool can_add_accounts
;
5490 DISP_INFO
*disp_info
= NULL
;
5493 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__
));
5495 /* Find the policy handle. Open a policy on it. */
5496 if (!get_lsa_policy_samr_sid(p
, r
->in
.user_handle
, &user_sid
, &acc_granted
, &disp_info
))
5497 return NT_STATUS_INVALID_HANDLE
;
5499 status
= access_check_samr_function(acc_granted
,
5500 STD_RIGHT_DELETE_ACCESS
,
5501 "_samr_DeleteUser");
5502 if (!NT_STATUS_IS_OK(status
)) {
5506 if (!sid_check_is_in_our_domain(&user_sid
))
5507 return NT_STATUS_CANNOT_DELETE
;
5509 /* check if the user exists before trying to delete */
5510 if ( !(sam_pass
= samu_new( NULL
)) ) {
5511 return NT_STATUS_NO_MEMORY
;
5515 ret
= pdb_getsampwsid(sam_pass
, &user_sid
);
5519 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5520 sid_string_dbg(&user_sid
)));
5521 TALLOC_FREE(sam_pass
);
5522 return NT_STATUS_NO_SUCH_USER
;
5525 acb_info
= pdb_get_acct_ctrl(sam_pass
);
5527 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
5528 if ( acb_info
& ACB_WSTRUST
) {
5529 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_machine_account
);
5531 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_add_users
);
5534 /******** BEGIN SeAddUsers BLOCK *********/
5536 if ( can_add_accounts
)
5539 status
= pdb_delete_user(p
->mem_ctx
, sam_pass
);
5541 if ( can_add_accounts
)
5544 /******** END SeAddUsers BLOCK *********/
5546 if ( !NT_STATUS_IS_OK(status
) ) {
5547 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5548 "user %s: %s.\n", pdb_get_username(sam_pass
),
5549 nt_errstr(status
)));
5550 TALLOC_FREE(sam_pass
);
5555 TALLOC_FREE(sam_pass
);
5557 if (!close_policy_hnd(p
, r
->in
.user_handle
))
5558 return NT_STATUS_OBJECT_NAME_INVALID
;
5560 ZERO_STRUCTP(r
->out
.user_handle
);
5562 force_flush_samr_cache(disp_info
);
5564 return NT_STATUS_OK
;
5567 /*********************************************************************
5568 _samr_DeleteDomainGroup
5569 *********************************************************************/
5571 NTSTATUS
_samr_DeleteDomainGroup(pipes_struct
*p
,
5572 struct samr_DeleteDomainGroup
*r
)
5579 bool can_add_accounts
;
5580 DISP_INFO
*disp_info
= NULL
;
5582 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__
));
5584 /* Find the policy handle. Open a policy on it. */
5585 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5586 return NT_STATUS_INVALID_HANDLE
;
5588 status
= access_check_samr_function(acc_granted
,
5589 STD_RIGHT_DELETE_ACCESS
,
5590 "_samr_DeleteDomainGroup");
5591 if (!NT_STATUS_IS_OK(status
)) {
5595 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid
)));
5597 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid
,
5599 return NT_STATUS_NO_SUCH_GROUP
;
5602 se_priv_copy( &se_rights
, &se_add_users
);
5603 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5605 /******** BEGIN SeAddUsers BLOCK *********/
5607 if ( can_add_accounts
)
5610 status
= pdb_delete_dom_group(p
->mem_ctx
, group_rid
);
5612 if ( can_add_accounts
)
5615 /******** END SeAddUsers BLOCK *********/
5617 if ( !NT_STATUS_IS_OK(status
) ) {
5618 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5619 "entry for group %s: %s\n",
5620 sid_string_dbg(&group_sid
),
5621 nt_errstr(status
)));
5625 if (!close_policy_hnd(p
, r
->in
.group_handle
))
5626 return NT_STATUS_OBJECT_NAME_INVALID
;
5628 force_flush_samr_cache(disp_info
);
5630 return NT_STATUS_OK
;
5633 /*********************************************************************
5634 _samr_DeleteDomAlias
5635 *********************************************************************/
5637 NTSTATUS
_samr_DeleteDomAlias(pipes_struct
*p
,
5638 struct samr_DeleteDomAlias
*r
)
5643 bool can_add_accounts
;
5645 DISP_INFO
*disp_info
= NULL
;
5647 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__
));
5649 /* Find the policy handle. Open a policy on it. */
5650 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &alias_sid
, &acc_granted
, &disp_info
))
5651 return NT_STATUS_INVALID_HANDLE
;
5653 /* copy the handle to the outgoing reply */
5655 memcpy(r
->out
.alias_handle
, r
->in
.alias_handle
, sizeof(r
->out
.alias_handle
));
5657 status
= access_check_samr_function(acc_granted
,
5658 STD_RIGHT_DELETE_ACCESS
,
5659 "_samr_DeleteDomAlias");
5660 if (!NT_STATUS_IS_OK(status
)) {
5664 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid
)));
5666 /* Don't let Windows delete builtin groups */
5668 if ( sid_check_is_in_builtin( &alias_sid
) ) {
5669 return NT_STATUS_SPECIAL_ACCOUNT
;
5672 if (!sid_check_is_in_our_domain(&alias_sid
))
5673 return NT_STATUS_NO_SUCH_ALIAS
;
5675 DEBUG(10, ("lookup on Local SID\n"));
5677 se_priv_copy( &se_rights
, &se_add_users
);
5678 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5680 /******** BEGIN SeAddUsers BLOCK *********/
5682 if ( can_add_accounts
)
5685 /* Have passdb delete the alias */
5686 status
= pdb_delete_alias(&alias_sid
);
5688 if ( can_add_accounts
)
5691 /******** END SeAddUsers BLOCK *********/
5693 if ( !NT_STATUS_IS_OK(status
))
5696 if (!close_policy_hnd(p
, r
->in
.alias_handle
))
5697 return NT_STATUS_OBJECT_NAME_INVALID
;
5699 force_flush_samr_cache(disp_info
);
5701 return NT_STATUS_OK
;
5704 /*********************************************************************
5705 _samr_CreateDomainGroup
5706 *********************************************************************/
5708 NTSTATUS
_samr_CreateDomainGroup(pipes_struct
*p
,
5709 struct samr_CreateDomainGroup
*r
)
5716 struct samr_info
*info
;
5719 bool can_add_accounts
;
5720 DISP_INFO
*disp_info
= NULL
;
5722 /* Find the policy handle. Open a policy on it. */
5723 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &dom_sid
, &acc_granted
, &disp_info
))
5724 return NT_STATUS_INVALID_HANDLE
;
5726 status
= access_check_samr_function(acc_granted
,
5727 SAMR_DOMAIN_ACCESS_CREATE_GROUP
,
5728 "_samr_CreateDomainGroup");
5729 if (!NT_STATUS_IS_OK(status
)) {
5733 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
5734 return NT_STATUS_ACCESS_DENIED
;
5736 name
= r
->in
.name
->string
;
5738 return NT_STATUS_NO_MEMORY
;
5741 status
= can_create(p
->mem_ctx
, name
);
5742 if (!NT_STATUS_IS_OK(status
)) {
5746 se_priv_copy( &se_rights
, &se_add_users
);
5747 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5749 /******** BEGIN SeAddUsers BLOCK *********/
5751 if ( can_add_accounts
)
5754 /* check that we successfully create the UNIX group */
5756 status
= pdb_create_dom_group(p
->mem_ctx
, name
, r
->out
.rid
);
5758 if ( can_add_accounts
)
5761 /******** END SeAddUsers BLOCK *********/
5763 /* check if we should bail out here */
5765 if ( !NT_STATUS_IS_OK(status
) )
5768 sid_compose(&info_sid
, get_global_sam_sid(), *r
->out
.rid
);
5770 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &info_sid
)) == NULL
)
5771 return NT_STATUS_NO_MEMORY
;
5773 /* they created it; let the user do what he wants with it */
5775 info
->acc_granted
= GENERIC_RIGHTS_GROUP_ALL_ACCESS
;
5777 /* get a (unique) handle. open a policy on it. */
5778 if (!create_policy_hnd(p
, r
->out
.group_handle
, info
))
5779 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5781 force_flush_samr_cache(disp_info
);
5783 return NT_STATUS_OK
;
5786 /*********************************************************************
5787 _samr_CreateDomAlias
5788 *********************************************************************/
5790 NTSTATUS
_samr_CreateDomAlias(pipes_struct
*p
,
5791 struct samr_CreateDomAlias
*r
)
5795 const char *name
= NULL
;
5796 struct samr_info
*info
;
5801 bool can_add_accounts
;
5802 DISP_INFO
*disp_info
= NULL
;
5804 /* Find the policy handle. Open a policy on it. */
5805 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &dom_sid
, &acc_granted
, &disp_info
))
5806 return NT_STATUS_INVALID_HANDLE
;
5808 result
= access_check_samr_function(acc_granted
,
5809 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
,
5810 "_samr_CreateDomAlias");
5811 if (!NT_STATUS_IS_OK(result
)) {
5815 if (!sid_equal(&dom_sid
, get_global_sam_sid()))
5816 return NT_STATUS_ACCESS_DENIED
;
5818 name
= r
->in
.alias_name
->string
;
5820 se_priv_copy( &se_rights
, &se_add_users
);
5821 can_add_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_rights
);
5823 result
= can_create(p
->mem_ctx
, name
);
5824 if (!NT_STATUS_IS_OK(result
)) {
5828 /******** BEGIN SeAddUsers BLOCK *********/
5830 if ( can_add_accounts
)
5833 /* Have passdb create the alias */
5834 result
= pdb_create_alias(name
, r
->out
.rid
);
5836 if ( can_add_accounts
)
5839 /******** END SeAddUsers BLOCK *********/
5841 if (!NT_STATUS_IS_OK(result
)) {
5842 DEBUG(10, ("pdb_create_alias failed: %s\n",
5843 nt_errstr(result
)));
5847 sid_copy(&info_sid
, get_global_sam_sid());
5848 sid_append_rid(&info_sid
, *r
->out
.rid
);
5850 if (!sid_to_gid(&info_sid
, &gid
)) {
5851 DEBUG(10, ("Could not find alias just created\n"));
5852 return NT_STATUS_ACCESS_DENIED
;
5855 /* check if the group has been successfully created */
5856 if ( getgrgid(gid
) == NULL
) {
5857 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5859 return NT_STATUS_ACCESS_DENIED
;
5862 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &info_sid
)) == NULL
)
5863 return NT_STATUS_NO_MEMORY
;
5865 /* they created it; let the user do what he wants with it */
5867 info
->acc_granted
= GENERIC_RIGHTS_ALIAS_ALL_ACCESS
;
5869 /* get a (unique) handle. open a policy on it. */
5870 if (!create_policy_hnd(p
, r
->out
.alias_handle
, info
))
5871 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5873 force_flush_samr_cache(disp_info
);
5875 return NT_STATUS_OK
;
5878 /*********************************************************************
5879 _samr_QueryGroupInfo
5880 *********************************************************************/
5882 NTSTATUS
_samr_QueryGroupInfo(pipes_struct
*p
,
5883 struct samr_QueryGroupInfo
*r
)
5888 union samr_GroupInfo
*info
= NULL
;
5891 uint32_t attributes
= SE_GROUP_MANDATORY
|
5892 SE_GROUP_ENABLED_BY_DEFAULT
|
5894 const char *group_name
= NULL
;
5895 const char *group_description
= NULL
;
5897 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, NULL
))
5898 return NT_STATUS_INVALID_HANDLE
;
5900 status
= access_check_samr_function(acc_granted
,
5901 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
5902 "_samr_QueryGroupInfo");
5903 if (!NT_STATUS_IS_OK(status
)) {
5908 ret
= get_domain_group_from_sid(group_sid
, &map
);
5911 return NT_STATUS_INVALID_HANDLE
;
5913 /* FIXME: map contains fstrings */
5914 group_name
= talloc_strdup(r
, map
.nt_name
);
5915 group_description
= talloc_strdup(r
, map
.comment
);
5917 info
= TALLOC_ZERO_P(p
->mem_ctx
, union samr_GroupInfo
);
5919 return NT_STATUS_NO_MEMORY
;
5922 switch (r
->in
.level
) {
5928 status
= pdb_enum_group_members(
5929 p
->mem_ctx
, &group_sid
, &members
, &num_members
);
5932 if (!NT_STATUS_IS_OK(status
)) {
5936 info
->all
.name
.string
= group_name
;
5937 info
->all
.attributes
= attributes
;
5938 info
->all
.num_members
= num_members
;
5939 info
->all
.description
.string
= group_description
;
5943 info
->name
.string
= group_name
;
5946 info
->attributes
.attributes
= attributes
;
5949 info
->description
.string
= group_description
;
5959 status = pdb_enum_group_members(
5960 p->mem_ctx, &group_sid, &members, &num_members);
5963 if (!NT_STATUS_IS_OK(status)) {
5967 info
->all2
.name
.string
= group_name
;
5968 info
->all2
.attributes
= attributes
;
5969 info
->all2
.num_members
= 0; /* num_members - in w2k3 this is always 0 */
5970 info
->all2
.description
.string
= group_description
;
5975 return NT_STATUS_INVALID_INFO_CLASS
;
5978 *r
->out
.info
= info
;
5980 return NT_STATUS_OK
;
5983 /*********************************************************************
5985 *********************************************************************/
5987 NTSTATUS
_samr_SetGroupInfo(pipes_struct
*p
,
5988 struct samr_SetGroupInfo
*r
)
5995 bool can_mod_accounts
;
5996 DISP_INFO
*disp_info
= NULL
;
5998 if (!get_lsa_policy_samr_sid(p
, r
->in
.group_handle
, &group_sid
, &acc_granted
, &disp_info
))
5999 return NT_STATUS_INVALID_HANDLE
;
6001 status
= access_check_samr_function(acc_granted
,
6002 SAMR_GROUP_ACCESS_SET_INFO
,
6003 "_samr_SetGroupInfo");
6004 if (!NT_STATUS_IS_OK(status
)) {
6009 ret
= get_domain_group_from_sid(group_sid
, &map
);
6012 return NT_STATUS_NO_SUCH_GROUP
;
6014 switch (r
->in
.level
) {
6016 fstrcpy(map
.comment
, r
->in
.info
->all
.description
.string
);
6019 /* group rename is not supported yet */
6020 return NT_STATUS_NOT_SUPPORTED
;
6022 fstrcpy(map
.comment
, r
->in
.info
->description
.string
);
6025 return NT_STATUS_INVALID_INFO_CLASS
;
6028 can_mod_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_add_users
);
6030 /******** BEGIN SeAddUsers BLOCK *********/
6032 if ( can_mod_accounts
)
6035 status
= pdb_update_group_mapping_entry(&map
);
6037 if ( can_mod_accounts
)
6040 /******** End SeAddUsers BLOCK *********/
6042 if (NT_STATUS_IS_OK(status
)) {
6043 force_flush_samr_cache(disp_info
);
6049 /*********************************************************************
6051 *********************************************************************/
6053 NTSTATUS
_samr_SetAliasInfo(pipes_struct
*p
,
6054 struct samr_SetAliasInfo
*r
)
6057 struct acct_info info
;
6059 bool can_mod_accounts
;
6061 DISP_INFO
*disp_info
= NULL
;
6063 if (!get_lsa_policy_samr_sid(p
, r
->in
.alias_handle
, &group_sid
, &acc_granted
, &disp_info
))
6064 return NT_STATUS_INVALID_HANDLE
;
6066 status
= access_check_samr_function(acc_granted
,
6067 SAMR_ALIAS_ACCESS_SET_INFO
,
6068 "_samr_SetAliasInfo");
6069 if (!NT_STATUS_IS_OK(status
)) {
6073 /* get the current group information */
6076 status
= pdb_get_aliasinfo( &group_sid
, &info
);
6079 if ( !NT_STATUS_IS_OK(status
))
6082 switch (r
->in
.level
) {
6087 /* We currently do not support renaming groups in the
6088 the BUILTIN domain. Refer to util_builtin.c to understand
6089 why. The eventually needs to be fixed to be like Windows
6090 where you can rename builtin groups, just not delete them */
6092 if ( sid_check_is_in_builtin( &group_sid
) ) {
6093 return NT_STATUS_SPECIAL_ACCOUNT
;
6096 /* There has to be a valid name (and it has to be different) */
6098 if ( !r
->in
.info
->name
.string
)
6099 return NT_STATUS_INVALID_PARAMETER
;
6101 /* If the name is the same just reply "ok". Yes this
6102 doesn't allow you to change the case of a group name. */
6104 if ( strequal( r
->in
.info
->name
.string
, info
.acct_name
) )
6105 return NT_STATUS_OK
;
6107 fstrcpy( info
.acct_name
, r
->in
.info
->name
.string
);
6109 /* make sure the name doesn't already exist as a user
6112 fstr_sprintf( group_name
, "%s\\%s", global_myname(), info
.acct_name
);
6113 status
= can_create( p
->mem_ctx
, group_name
);
6114 if ( !NT_STATUS_IS_OK( status
) )
6118 case ALIASINFODESCRIPTION
:
6119 if (r
->in
.info
->description
.string
) {
6120 fstrcpy(info
.acct_desc
,
6121 r
->in
.info
->description
.string
);
6123 fstrcpy( info
.acct_desc
, "" );
6127 return NT_STATUS_INVALID_INFO_CLASS
;
6130 can_mod_accounts
= user_has_privileges( p
->server_info
->ptok
, &se_add_users
);
6132 /******** BEGIN SeAddUsers BLOCK *********/
6134 if ( can_mod_accounts
)
6137 status
= pdb_set_aliasinfo( &group_sid
, &info
);
6139 if ( can_mod_accounts
)
6142 /******** End SeAddUsers BLOCK *********/
6144 if (NT_STATUS_IS_OK(status
))
6145 force_flush_samr_cache(disp_info
);
6150 /****************************************************************
6152 ****************************************************************/
6154 NTSTATUS
_samr_GetDomPwInfo(pipes_struct
*p
,
6155 struct samr_GetDomPwInfo
*r
)
6157 uint32_t min_password_length
= 0;
6158 uint32_t password_properties
= 0;
6160 /* Perform access check. Since this rpc does not require a
6161 policy handle it will not be caught by the access checks on
6162 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6164 if (!pipe_access_check(p
)) {
6165 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6166 return NT_STATUS_ACCESS_DENIED
;
6170 pdb_get_account_policy(AP_MIN_PASSWORD_LEN
,
6171 &min_password_length
);
6172 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
,
6173 &password_properties
);
6176 if (lp_check_password_script() && *lp_check_password_script()) {
6177 password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
6180 r
->out
.info
->min_password_length
= min_password_length
;
6181 r
->out
.info
->password_properties
= password_properties
;
6183 return NT_STATUS_OK
;
6186 /*********************************************************************
6188 *********************************************************************/
6190 NTSTATUS
_samr_OpenGroup(pipes_struct
*p
,
6191 struct samr_OpenGroup
*r
)
6197 struct samr_info
*info
;
6198 SEC_DESC
*psd
= NULL
;
6200 uint32 des_access
= r
->in
.access_mask
;
6207 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &sid
, &acc_granted
, NULL
))
6208 return NT_STATUS_INVALID_HANDLE
;
6210 status
= access_check_samr_function(acc_granted
,
6211 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
6214 if ( !NT_STATUS_IS_OK(status
) )
6217 /*check if access can be granted as requested by client. */
6218 map_max_allowed_access(p
->server_info
->ptok
, &des_access
);
6220 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &grp_generic_mapping
, NULL
, 0);
6221 se_map_generic(&des_access
,&grp_generic_mapping
);
6223 se_priv_copy( &se_rights
, &se_add_users
);
6225 status
= access_check_samr_object(psd
, p
->server_info
->ptok
,
6226 &se_rights
, GENERIC_RIGHTS_GROUP_WRITE
, des_access
,
6227 &acc_granted
, "_samr_OpenGroup");
6229 if ( !NT_STATUS_IS_OK(status
) )
6232 /* this should not be hard-coded like this */
6234 if (!sid_equal(&sid
, get_global_sam_sid()))
6235 return NT_STATUS_ACCESS_DENIED
;
6237 sid_copy(&info_sid
, get_global_sam_sid());
6238 sid_append_rid(&info_sid
, r
->in
.rid
);
6239 sid_to_fstring(sid_string
, &info_sid
);
6241 if ((info
= get_samr_info_by_sid(p
->mem_ctx
, &info_sid
)) == NULL
)
6242 return NT_STATUS_NO_MEMORY
;
6244 info
->acc_granted
= acc_granted
;
6246 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string
));
6248 /* check if that group really exists */
6250 ret
= get_domain_group_from_sid(info
->sid
, &map
);
6253 return NT_STATUS_NO_SUCH_GROUP
;
6255 /* get a (unique) handle. open a policy on it. */
6256 if (!create_policy_hnd(p
, r
->out
.group_handle
, info
))
6257 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6259 return NT_STATUS_OK
;
6262 /*********************************************************************
6263 _samr_RemoveMemberFromForeignDomain
6264 *********************************************************************/
6266 NTSTATUS
_samr_RemoveMemberFromForeignDomain(pipes_struct
*p
,
6267 struct samr_RemoveMemberFromForeignDomain
*r
)
6269 DOM_SID delete_sid
, domain_sid
;
6272 DISP_INFO
*disp_info
= NULL
;
6274 sid_copy( &delete_sid
, r
->in
.sid
);
6276 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6277 sid_string_dbg(&delete_sid
)));
6279 /* Find the policy handle. Open a policy on it. */
6281 if (!get_lsa_policy_samr_sid(p
, r
->in
.domain_handle
, &domain_sid
,
6282 &acc_granted
, &disp_info
))
6283 return NT_STATUS_INVALID_HANDLE
;
6285 result
= access_check_samr_function(acc_granted
,
6286 STD_RIGHT_DELETE_ACCESS
,
6287 "_samr_RemoveMemberFromForeignDomain");
6289 if (!NT_STATUS_IS_OK(result
))
6292 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6293 sid_string_dbg(&domain_sid
)));
6295 /* we can only delete a user from a group since we don't have
6296 nested groups anyways. So in the latter case, just say OK */
6298 /* TODO: The above comment nowadays is bogus. Since we have nested
6299 * groups now, and aliases members are never reported out of the unix
6300 * group membership, the "just say OK" makes this call a no-op. For
6301 * us. This needs fixing however. */
6303 /* I've only ever seen this in the wild when deleting a user from
6304 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6305 * is the user about to be deleted. I very much suspect this is the
6306 * only application of this call. To verify this, let people report
6309 if (!sid_check_is_builtin(&domain_sid
)) {
6310 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6311 "global_sam_sid() = %s\n",
6312 sid_string_dbg(&domain_sid
),
6313 sid_string_dbg(get_global_sam_sid())));
6314 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6315 return NT_STATUS_OK
;
6318 force_flush_samr_cache(disp_info
);
6320 result
= NT_STATUS_OK
;
6325 /*******************************************************************
6326 _samr_QueryDomainInfo2
6327 ********************************************************************/
6329 NTSTATUS
_samr_QueryDomainInfo2(pipes_struct
*p
,
6330 struct samr_QueryDomainInfo2
*r
)
6332 struct samr_QueryDomainInfo q
;
6334 q
.in
.domain_handle
= r
->in
.domain_handle
;
6335 q
.in
.level
= r
->in
.level
;
6337 q
.out
.info
= r
->out
.info
;
6339 return _samr_QueryDomainInfo(p
, &q
);
6342 /*******************************************************************
6344 ********************************************************************/
6346 NTSTATUS
_samr_SetDomainInfo(pipes_struct
*p
,
6347 struct samr_SetDomainInfo
*r
)
6349 struct samr_info
*info
= NULL
;
6350 time_t u_expire
, u_min_age
;
6352 time_t u_lock_duration
, u_reset_time
;
6355 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6357 /* find the policy handle. open a policy on it. */
6358 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
))
6359 return NT_STATUS_INVALID_HANDLE
;
6361 /* We do have different access bits for info
6362 * levels here, but we're really just looking for
6363 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
6364 * this maps to different specific bits. So
6365 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
6368 result
= access_check_samr_function(info
->acc_granted
,
6369 SAMR_DOMAIN_ACCESS_SET_INFO_1
,
6370 "_samr_SetDomainInfo");
6372 if (!NT_STATUS_IS_OK(result
))
6375 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r
->in
.level
));
6377 switch (r
->in
.level
) {
6379 u_expire
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info1
.max_password_age
);
6380 u_min_age
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info1
.min_password_age
);
6381 pdb_set_account_policy(AP_MIN_PASSWORD_LEN
, (uint32
)r
->in
.info
->info1
.min_password_length
);
6382 pdb_set_account_policy(AP_PASSWORD_HISTORY
, (uint32
)r
->in
.info
->info1
.password_history_length
);
6383 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS
, (uint32
)r
->in
.info
->info1
.password_properties
);
6384 pdb_set_account_policy(AP_MAX_PASSWORD_AGE
, (int)u_expire
);
6385 pdb_set_account_policy(AP_MIN_PASSWORD_AGE
, (int)u_min_age
);
6388 u_logout
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info3
.force_logoff_time
);
6389 pdb_set_account_policy(AP_TIME_TO_LOGOUT
, (int)u_logout
);
6400 u_lock_duration
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info12
.lockout_duration
);
6401 if (u_lock_duration
!= -1)
6402 u_lock_duration
/= 60;
6404 u_reset_time
=nt_time_to_unix_abs((NTTIME
*)&r
->in
.info
->info12
.lockout_window
)/60;
6406 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION
, (int)u_lock_duration
);
6407 pdb_set_account_policy(AP_RESET_COUNT_TIME
, (int)u_reset_time
);
6408 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, (uint32
)r
->in
.info
->info12
.lockout_threshold
);
6411 return NT_STATUS_INVALID_INFO_CLASS
;
6414 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6416 return NT_STATUS_OK
;
6419 /****************************************************************
6420 _samr_GetDisplayEnumerationIndex
6421 ****************************************************************/
6423 NTSTATUS
_samr_GetDisplayEnumerationIndex(pipes_struct
*p
,
6424 struct samr_GetDisplayEnumerationIndex
*r
)
6426 struct samr_info
*info
= NULL
;
6427 uint32_t max_entries
= (uint32_t) -1;
6428 uint32_t enum_context
= 0;
6430 uint32_t num_account
= 0;
6431 struct samr_displayentry
*entries
= NULL
;
6434 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__
));
6436 /* find the policy handle. open a policy on it. */
6437 if (!find_policy_by_hnd(p
, r
->in
.domain_handle
, (void **)(void *)&info
)) {
6438 return NT_STATUS_INVALID_HANDLE
;
6441 status
= access_check_samr_function(info
->acc_granted
,
6442 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
,
6443 "_samr_GetDisplayEnumerationIndex");
6444 if (!NT_STATUS_IS_OK(status
)) {
6448 if ((r
->in
.level
< 1) || (r
->in
.level
> 3)) {
6449 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6450 "Unknown info level (%u)\n",
6452 return NT_STATUS_INVALID_INFO_CLASS
;
6457 /* The following done as ROOT. Don't return without unbecome_root(). */
6459 switch (r
->in
.level
) {
6461 if (info
->disp_info
->users
== NULL
) {
6462 info
->disp_info
->users
= pdb_search_users(
6463 info
->disp_info
, ACB_NORMAL
);
6464 if (info
->disp_info
->users
== NULL
) {
6466 return NT_STATUS_ACCESS_DENIED
;
6468 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6469 "starting user enumeration at index %u\n",
6470 (unsigned int)enum_context
));
6472 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6473 "using cached user enumeration at index %u\n",
6474 (unsigned int)enum_context
));
6476 num_account
= pdb_search_entries(info
->disp_info
->users
,
6477 enum_context
, max_entries
,
6481 if (info
->disp_info
->machines
== NULL
) {
6482 info
->disp_info
->machines
= pdb_search_users(
6483 info
->disp_info
, ACB_WSTRUST
|ACB_SVRTRUST
);
6484 if (info
->disp_info
->machines
== NULL
) {
6486 return NT_STATUS_ACCESS_DENIED
;
6488 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6489 "starting machine enumeration at index %u\n",
6490 (unsigned int)enum_context
));
6492 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6493 "using cached machine enumeration at index %u\n",
6494 (unsigned int)enum_context
));
6496 num_account
= pdb_search_entries(info
->disp_info
->machines
,
6497 enum_context
, max_entries
,
6501 if (info
->disp_info
->groups
== NULL
) {
6502 info
->disp_info
->groups
= pdb_search_groups(
6504 if (info
->disp_info
->groups
== NULL
) {
6506 return NT_STATUS_ACCESS_DENIED
;
6508 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6509 "starting group enumeration at index %u\n",
6510 (unsigned int)enum_context
));
6512 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6513 "using cached group enumeration at index %u\n",
6514 (unsigned int)enum_context
));
6516 num_account
= pdb_search_entries(info
->disp_info
->groups
,
6517 enum_context
, max_entries
,
6522 smb_panic("info class changed");
6528 /* Ensure we cache this enumeration. */
6529 set_disp_info_cache_timeout(info
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
6531 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6532 r
->in
.name
->string
));
6534 for (i
=0; i
<num_account
; i
++) {
6535 if (strequal(entries
[i
].account_name
, r
->in
.name
->string
)) {
6536 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6537 "found %s at idx %d\n",
6538 r
->in
.name
->string
, i
));
6540 return NT_STATUS_OK
;
6544 /* assuming account_name lives at the very end */
6545 *r
->out
.idx
= num_account
;
6547 return NT_STATUS_NO_MORE_ENTRIES
;
6550 /****************************************************************
6551 _samr_GetDisplayEnumerationIndex2
6552 ****************************************************************/
6554 NTSTATUS
_samr_GetDisplayEnumerationIndex2(pipes_struct
*p
,
6555 struct samr_GetDisplayEnumerationIndex2
*r
)
6557 struct samr_GetDisplayEnumerationIndex q
;
6559 q
.in
.domain_handle
= r
->in
.domain_handle
;
6560 q
.in
.level
= r
->in
.level
;
6561 q
.in
.name
= r
->in
.name
;
6563 q
.out
.idx
= r
->out
.idx
;
6565 return _samr_GetDisplayEnumerationIndex(p
, &q
);
6568 /****************************************************************
6569 ****************************************************************/
6571 NTSTATUS
_samr_Shutdown(pipes_struct
*p
,
6572 struct samr_Shutdown
*r
)
6574 p
->rng_fault_state
= true;
6575 return NT_STATUS_NOT_IMPLEMENTED
;
6578 /****************************************************************
6579 ****************************************************************/
6581 NTSTATUS
_samr_SetMemberAttributesOfGroup(pipes_struct
*p
,
6582 struct samr_SetMemberAttributesOfGroup
*r
)
6584 p
->rng_fault_state
= true;
6585 return NT_STATUS_NOT_IMPLEMENTED
;
6588 /****************************************************************
6589 ****************************************************************/
6591 NTSTATUS
_samr_TestPrivateFunctionsDomain(pipes_struct
*p
,
6592 struct samr_TestPrivateFunctionsDomain
*r
)
6594 p
->rng_fault_state
= true;
6595 return NT_STATUS_NOT_IMPLEMENTED
;
6598 /****************************************************************
6599 ****************************************************************/
6601 NTSTATUS
_samr_TestPrivateFunctionsUser(pipes_struct
*p
,
6602 struct samr_TestPrivateFunctionsUser
*r
)
6604 return NT_STATUS_NOT_IMPLEMENTED
;
6607 /****************************************************************
6608 ****************************************************************/
6610 NTSTATUS
_samr_AddMultipleMembersToAlias(pipes_struct
*p
,
6611 struct samr_AddMultipleMembersToAlias
*r
)
6613 p
->rng_fault_state
= true;
6614 return NT_STATUS_NOT_IMPLEMENTED
;
6617 /****************************************************************
6618 ****************************************************************/
6620 NTSTATUS
_samr_RemoveMultipleMembersFromAlias(pipes_struct
*p
,
6621 struct samr_RemoveMultipleMembersFromAlias
*r
)
6623 p
->rng_fault_state
= true;
6624 return NT_STATUS_NOT_IMPLEMENTED
;
6627 /****************************************************************
6628 ****************************************************************/
6630 NTSTATUS
_samr_SetBootKeyInformation(pipes_struct
*p
,
6631 struct samr_SetBootKeyInformation
*r
)
6633 p
->rng_fault_state
= true;
6634 return NT_STATUS_NOT_IMPLEMENTED
;
6637 /****************************************************************
6638 ****************************************************************/
6640 NTSTATUS
_samr_GetBootKeyInformation(pipes_struct
*p
,
6641 struct samr_GetBootKeyInformation
*r
)
6643 p
->rng_fault_state
= true;
6644 return NT_STATUS_NOT_IMPLEMENTED
;
6647 /****************************************************************
6648 ****************************************************************/
6650 NTSTATUS
_samr_RidToSid(pipes_struct
*p
,
6651 struct samr_RidToSid
*r
)
6653 p
->rng_fault_state
= true;
6654 return NT_STATUS_NOT_IMPLEMENTED
;
6657 /****************************************************************
6658 ****************************************************************/
6660 NTSTATUS
_samr_SetDsrmPassword(pipes_struct
*p
,
6661 struct samr_SetDsrmPassword
*r
)
6663 p
->rng_fault_state
= true;
6664 return NT_STATUS_NOT_IMPLEMENTED
;
6667 /****************************************************************
6668 ****************************************************************/
6670 NTSTATUS
_samr_ValidatePassword(pipes_struct
*p
,
6671 struct samr_ValidatePassword
*r
)
6673 p
->rng_fault_state
= true;
6674 return NT_STATUS_NOT_IMPLEMENTED
;