2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
35 #include "system/passwd.h"
36 #include "../libcli/auth/libcli_auth.h"
38 #include "../librpc/gen_ndr/srv_samr.h"
39 #include "rpc_server/samr/srv_samr_util.h"
40 #include "../lib/crypto/arcfour.h"
42 #include "rpc_client/init_lsa.h"
43 #include "../libcli/security/security.h"
46 #include "rpc_server/srv_access_check.h"
47 #include "../lib/tsocket/tsocket.h"
48 #include "lib/util/base64.h"
51 #define DBGC_CLASS DBGC_RPC_SRV
53 #define SAMR_USR_RIGHTS_WRITE_PW \
54 ( READ_CONTROL_ACCESS | \
55 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
56 SAMR_USER_ACCESS_SET_LOC_COM)
57 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
58 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
60 #define DISP_INFO_CACHE_TIMEOUT 10
62 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
63 #define MAX_SAM_ENTRIES_W95 50
65 struct samr_connect_info
{
69 struct samr_domain_info
{
71 struct disp_info
*disp_info
;
74 struct samr_user_info
{
78 struct samr_group_info
{
82 struct samr_alias_info
{
86 typedef struct disp_info
{
87 struct dom_sid sid
; /* identify which domain this is. */
88 struct pdb_search
*users
; /* querydispinfo 1 and 4 */
89 struct pdb_search
*machines
; /* querydispinfo 2 */
90 struct pdb_search
*groups
; /* querydispinfo 3 and 5, enumgroups */
91 struct pdb_search
*aliases
; /* enumaliases */
93 uint32_t enum_acb_mask
;
94 struct pdb_search
*enum_users
; /* enumusers with a mask */
96 struct tevent_timer
*cache_timeout_event
; /* cache idle timeout
100 static const struct generic_mapping sam_generic_mapping
= {
101 GENERIC_RIGHTS_SAM_READ
,
102 GENERIC_RIGHTS_SAM_WRITE
,
103 GENERIC_RIGHTS_SAM_EXECUTE
,
104 GENERIC_RIGHTS_SAM_ALL_ACCESS
};
105 static const struct generic_mapping dom_generic_mapping
= {
106 GENERIC_RIGHTS_DOMAIN_READ
,
107 GENERIC_RIGHTS_DOMAIN_WRITE
,
108 GENERIC_RIGHTS_DOMAIN_EXECUTE
,
109 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS
};
110 static const struct generic_mapping usr_generic_mapping
= {
111 GENERIC_RIGHTS_USER_READ
,
112 GENERIC_RIGHTS_USER_WRITE
,
113 GENERIC_RIGHTS_USER_EXECUTE
,
114 GENERIC_RIGHTS_USER_ALL_ACCESS
};
115 static const struct generic_mapping usr_nopwchange_generic_mapping
= {
116 GENERIC_RIGHTS_USER_READ
,
117 GENERIC_RIGHTS_USER_WRITE
,
118 GENERIC_RIGHTS_USER_EXECUTE
& ~SAMR_USER_ACCESS_CHANGE_PASSWORD
,
119 GENERIC_RIGHTS_USER_ALL_ACCESS
};
120 static const struct generic_mapping grp_generic_mapping
= {
121 GENERIC_RIGHTS_GROUP_READ
,
122 GENERIC_RIGHTS_GROUP_WRITE
,
123 GENERIC_RIGHTS_GROUP_EXECUTE
,
124 GENERIC_RIGHTS_GROUP_ALL_ACCESS
};
125 static const struct generic_mapping ali_generic_mapping
= {
126 GENERIC_RIGHTS_ALIAS_READ
,
127 GENERIC_RIGHTS_ALIAS_WRITE
,
128 GENERIC_RIGHTS_ALIAS_EXECUTE
,
129 GENERIC_RIGHTS_ALIAS_ALL_ACCESS
};
131 /*******************************************************************
132 *******************************************************************/
134 static NTSTATUS
make_samr_object_sd( TALLOC_CTX
*ctx
, struct security_descriptor
**psd
, size_t *sd_size
,
135 const struct generic_mapping
*map
,
136 struct dom_sid
*sid
, uint32_t sid_access
)
138 struct dom_sid domadmin_sid
;
139 struct security_ace ace
[5]; /* at most 5 entries */
142 struct security_acl
*psa
= NULL
;
144 /* basic access for Everyone */
146 init_sec_ace(&ace
[i
++], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
147 map
->generic_execute
| map
->generic_read
, 0);
149 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
151 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Administrators
,
152 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
153 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Account_Operators
,
154 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
156 /* Add Full Access for Domain Admins if we are a DC */
159 sid_compose(&domadmin_sid
, get_global_sam_sid(),
161 init_sec_ace(&ace
[i
++], &domadmin_sid
,
162 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
165 /* if we have a sid, give it some special access */
168 init_sec_ace(&ace
[i
++], sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, sid_access
, 0);
171 /* create the security descriptor */
173 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, i
, ace
)) == NULL
)
174 return NT_STATUS_NO_MEMORY
;
176 if ((*psd
= make_sec_desc(ctx
, SECURITY_DESCRIPTOR_REVISION_1
,
177 SEC_DESC_SELF_RELATIVE
, NULL
, NULL
, NULL
,
178 psa
, sd_size
)) == NULL
)
179 return NT_STATUS_NO_MEMORY
;
184 /*******************************************************************
185 Fetch or create a dispinfo struct.
186 ********************************************************************/
188 static DISP_INFO
*get_samr_dispinfo_by_sid(const struct dom_sid
*psid
)
191 * We do a static cache for DISP_INFO's here. Explanation can be found
192 * in Jeremy's checkin message to r11793:
194 * Fix the SAMR cache so it works across completely insane
195 * client behaviour (ie.:
196 * open pipe/open SAMR handle/enumerate 0 - 1024
197 * close SAMR handle, close pipe.
198 * open pipe/open SAMR handle/enumerate 1024 - 2048...
199 * close SAMR handle, close pipe.
200 * And on ad-nausium. Amazing.... probably object-oriented
201 * client side programming in action yet again.
202 * This change should *massively* improve performance when
203 * enumerating users from an LDAP database.
206 * "Our" and the builtin domain are the only ones where we ever
207 * enumerate stuff, so just cache 2 entries.
210 static struct disp_info
*builtin_dispinfo
;
211 static struct disp_info
*domain_dispinfo
;
213 /* There are two cases to consider here:
214 1) The SID is a domain SID and we look for an equality match, or
215 2) This is an account SID and so we return the DISP_INFO* for our
222 if (sid_check_is_builtin(psid
) || sid_check_is_in_builtin(psid
)) {
224 * Necessary only once, but it does not really hurt.
226 if (builtin_dispinfo
== NULL
) {
227 builtin_dispinfo
= talloc_zero(NULL
, struct disp_info
);
228 if (builtin_dispinfo
== NULL
) {
232 sid_copy(&builtin_dispinfo
->sid
, &global_sid_Builtin
);
234 return builtin_dispinfo
;
237 if (sid_check_is_our_sam(psid
) || sid_check_is_in_our_sam(psid
)) {
239 * Necessary only once, but it does not really hurt.
241 if (domain_dispinfo
== NULL
) {
242 domain_dispinfo
= talloc_zero(NULL
, struct disp_info
);
243 if (domain_dispinfo
== NULL
) {
247 sid_copy(&domain_dispinfo
->sid
, get_global_sam_sid());
249 return domain_dispinfo
;
255 /*******************************************************************
256 Function to free the per SID data.
257 ********************************************************************/
259 static void free_samr_cache(DISP_INFO
*disp_info
)
261 struct dom_sid_buf buf
;
263 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
264 dom_sid_str_buf(&disp_info
->sid
, &buf
)));
266 /* We need to become root here because the paged search might have to
267 * tell the LDAP server we're not interested in the rest anymore. */
271 TALLOC_FREE(disp_info
->users
);
272 TALLOC_FREE(disp_info
->machines
);
273 TALLOC_FREE(disp_info
->groups
);
274 TALLOC_FREE(disp_info
->aliases
);
275 TALLOC_FREE(disp_info
->enum_users
);
280 /*******************************************************************
281 Idle event handler. Throw away the disp info cache.
282 ********************************************************************/
284 static void disp_info_cache_idle_timeout_handler(struct tevent_context
*ev_ctx
,
285 struct tevent_timer
*te
,
289 DISP_INFO
*disp_info
= (DISP_INFO
*)private_data
;
291 TALLOC_FREE(disp_info
->cache_timeout_event
);
293 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
295 free_samr_cache(disp_info
);
298 /*******************************************************************
299 Setup cache removal idle event handler.
300 ********************************************************************/
302 static void set_disp_info_cache_timeout(DISP_INFO
*disp_info
, time_t secs_fromnow
)
304 struct dom_sid_buf buf
;
306 /* Remove any pending timeout and update. */
308 TALLOC_FREE(disp_info
->cache_timeout_event
);
310 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
311 "SID %s for %u seconds\n",
312 dom_sid_str_buf(&disp_info
->sid
, &buf
),
313 (unsigned int)secs_fromnow
));
315 disp_info
->cache_timeout_event
= tevent_add_timer(
316 global_event_context(), NULL
,
317 timeval_current_ofs(secs_fromnow
, 0),
318 disp_info_cache_idle_timeout_handler
, (void *)disp_info
);
321 /*******************************************************************
322 Force flush any cache. We do this on any samr_set_xxx call.
323 We must also remove the timeout handler.
324 ********************************************************************/
326 static void force_flush_samr_cache(const struct dom_sid
*sid
)
328 struct disp_info
*disp_info
= get_samr_dispinfo_by_sid(sid
);
330 if ((disp_info
== NULL
) || (disp_info
->cache_timeout_event
== NULL
)) {
334 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
335 TALLOC_FREE(disp_info
->cache_timeout_event
);
336 free_samr_cache(disp_info
);
339 /*******************************************************************
340 Ensure password info is never given out. Paranioa... JRA.
341 ********************************************************************/
343 static void samr_clear_sam_passwd(struct samu
*sam_pass
)
349 /* These now zero out the old password */
351 pdb_set_lanman_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
352 pdb_set_nt_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
355 static uint32_t count_sam_users(struct disp_info
*info
, uint32_t acct_flags
)
357 struct samr_displayentry
*entry
;
359 if (sid_check_is_builtin(&info
->sid
)) {
360 /* No users in builtin. */
364 if (info
->users
== NULL
) {
365 info
->users
= pdb_search_users(info
, acct_flags
);
366 if (info
->users
== NULL
) {
370 /* Fetch the last possible entry, thus trigger an enumeration */
371 pdb_search_entries(info
->users
, 0xffffffff, 1, &entry
);
373 /* Ensure we cache this enumeration. */
374 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
376 return info
->users
->num_entries
;
379 static uint32_t count_sam_groups(struct disp_info
*info
)
381 struct samr_displayentry
*entry
;
383 if (sid_check_is_builtin(&info
->sid
)) {
384 /* No groups in builtin. */
388 if (info
->groups
== NULL
) {
389 info
->groups
= pdb_search_groups(info
);
390 if (info
->groups
== NULL
) {
394 /* Fetch the last possible entry, thus trigger an enumeration */
395 pdb_search_entries(info
->groups
, 0xffffffff, 1, &entry
);
397 /* Ensure we cache this enumeration. */
398 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
400 return info
->groups
->num_entries
;
403 static uint32_t count_sam_aliases(struct disp_info
*info
)
405 struct samr_displayentry
*entry
;
407 if (info
->aliases
== NULL
) {
408 info
->aliases
= pdb_search_aliases(info
, &info
->sid
);
409 if (info
->aliases
== NULL
) {
413 /* Fetch the last possible entry, thus trigger an enumeration */
414 pdb_search_entries(info
->aliases
, 0xffffffff, 1, &entry
);
416 /* Ensure we cache this enumeration. */
417 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
419 return info
->aliases
->num_entries
;
422 /*******************************************************************
424 ********************************************************************/
426 NTSTATUS
_samr_Close(struct pipes_struct
*p
, struct samr_Close
*r
)
428 if (!close_policy_hnd(p
, r
->in
.handle
)) {
429 return NT_STATUS_INVALID_HANDLE
;
432 ZERO_STRUCTP(r
->out
.handle
);
437 /*******************************************************************
439 ********************************************************************/
441 NTSTATUS
_samr_OpenDomain(struct pipes_struct
*p
,
442 struct samr_OpenDomain
*r
)
444 struct samr_domain_info
*dinfo
;
445 struct security_descriptor
*psd
= NULL
;
446 uint32_t acc_granted
;
447 uint32_t des_access
= r
->in
.access_mask
;
450 uint32_t extra_access
= SAMR_DOMAIN_ACCESS_CREATE_USER
;
452 /* find the connection policy handle. */
454 (void)policy_handle_find(p
, r
->in
.connect_handle
, 0, NULL
,
455 struct samr_connect_info
, &status
);
456 if (!NT_STATUS_IS_OK(status
)) {
460 /*check if access can be granted as requested by client. */
461 map_max_allowed_access(p
->session_info
->security_token
,
462 p
->session_info
->unix_token
,
465 make_samr_object_sd( p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0 );
466 se_map_generic( &des_access
, &dom_generic_mapping
);
469 * Users with SeAddUser get the ability to manipulate groups
472 if (security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_ADD_USERS
)) {
473 extra_access
|= (SAMR_DOMAIN_ACCESS_CREATE_GROUP
|
474 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
475 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
476 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
|
477 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
);
481 * Users with SeMachineAccount or SeAddUser get additional
482 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
485 status
= access_check_object( psd
, p
->session_info
->security_token
,
486 SEC_PRIV_MACHINE_ACCOUNT
, SEC_PRIV_ADD_USERS
,
487 extra_access
, des_access
,
488 &acc_granted
, "_samr_OpenDomain" );
490 if ( !NT_STATUS_IS_OK(status
) )
493 if (!sid_check_is_our_sam(r
->in
.sid
) &&
494 !sid_check_is_builtin(r
->in
.sid
)) {
495 return NT_STATUS_NO_SUCH_DOMAIN
;
498 dinfo
= policy_handle_create(p
, r
->out
.domain_handle
, acc_granted
,
499 struct samr_domain_info
, &status
);
500 if (!NT_STATUS_IS_OK(status
)) {
503 dinfo
->sid
= *r
->in
.sid
;
504 dinfo
->disp_info
= get_samr_dispinfo_by_sid(r
->in
.sid
);
506 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__
));
511 /*******************************************************************
513 ********************************************************************/
515 NTSTATUS
_samr_GetUserPwInfo(struct pipes_struct
*p
,
516 struct samr_GetUserPwInfo
*r
)
518 struct samr_user_info
*uinfo
;
519 enum lsa_SidType sid_type
;
520 uint32_t min_password_length
= 0;
521 uint32_t password_properties
= 0;
525 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__
));
527 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
528 SAMR_USER_ACCESS_GET_ATTRIBUTES
, NULL
,
529 struct samr_user_info
, &status
);
530 if (!NT_STATUS_IS_OK(status
)) {
534 if (!sid_check_is_in_our_sam(&uinfo
->sid
)) {
535 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
539 ret
= lookup_sid(p
->mem_ctx
, &uinfo
->sid
, NULL
, NULL
, &sid_type
);
542 return NT_STATUS_NO_SUCH_USER
;
548 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN
,
549 &min_password_length
);
550 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS
,
551 &password_properties
);
554 if (lp_check_password_script(talloc_tos())
555 && *lp_check_password_script(talloc_tos())) {
556 password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
564 r
->out
.info
->min_password_length
= min_password_length
;
565 r
->out
.info
->password_properties
= password_properties
;
567 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__
));
572 /*******************************************************************
574 ********************************************************************/
576 NTSTATUS
_samr_SetSecurity(struct pipes_struct
*p
,
577 struct samr_SetSecurity
*r
)
579 struct samr_user_info
*uinfo
;
581 struct security_acl
*dacl
;
583 struct samu
*sampass
=NULL
;
586 uinfo
= policy_handle_find(p
, r
->in
.handle
,
587 SAMR_USER_ACCESS_SET_ATTRIBUTES
, NULL
,
588 struct samr_user_info
, &status
);
589 if (!NT_STATUS_IS_OK(status
)) {
593 if (!(sampass
= samu_new( p
->mem_ctx
))) {
594 DEBUG(0,("No memory!\n"));
595 return NT_STATUS_NO_MEMORY
;
598 /* get the user record */
600 ret
= pdb_getsampwsid(sampass
, &uinfo
->sid
);
604 struct dom_sid_buf buf
;
605 DEBUG(4, ("User %s not found\n",
606 dom_sid_str_buf(&uinfo
->sid
, &buf
)));
607 TALLOC_FREE(sampass
);
608 return NT_STATUS_INVALID_HANDLE
;
611 dacl
= r
->in
.sdbuf
->sd
->dacl
;
612 for (i
=0; i
< dacl
->num_aces
; i
++) {
613 if (dom_sid_equal(&uinfo
->sid
, &dacl
->aces
[i
].trustee
)) {
614 ret
= pdb_set_pass_can_change(sampass
,
615 (dacl
->aces
[i
].access_mask
&
616 SAMR_USER_ACCESS_CHANGE_PASSWORD
) ?
623 TALLOC_FREE(sampass
);
624 return NT_STATUS_ACCESS_DENIED
;
628 status
= pdb_update_sam_account(sampass
);
631 TALLOC_FREE(sampass
);
636 /*******************************************************************
637 build correct perms based on policies and password times for _samr_query_sec_obj
638 *******************************************************************/
639 static bool check_change_pw_access(TALLOC_CTX
*mem_ctx
, struct dom_sid
*user_sid
)
641 struct samu
*sampass
=NULL
;
644 if ( !(sampass
= samu_new( mem_ctx
)) ) {
645 DEBUG(0,("No memory!\n"));
650 ret
= pdb_getsampwsid(sampass
, user_sid
);
654 struct dom_sid_buf buf
;
655 DEBUG(4,("User %s not found\n",
656 dom_sid_str_buf(user_sid
, &buf
)));
657 TALLOC_FREE(sampass
);
661 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
663 if (pdb_get_pass_can_change(sampass
)) {
664 TALLOC_FREE(sampass
);
667 TALLOC_FREE(sampass
);
672 /*******************************************************************
674 ********************************************************************/
676 NTSTATUS
_samr_QuerySecurity(struct pipes_struct
*p
,
677 struct samr_QuerySecurity
*r
)
679 struct samr_domain_info
*dinfo
;
680 struct samr_user_info
*uinfo
;
681 struct samr_group_info
*ginfo
;
682 struct samr_alias_info
*ainfo
;
684 struct security_descriptor
* psd
= NULL
;
686 struct dom_sid_buf buf
;
688 (void)policy_handle_find(p
, r
->in
.handle
,
689 SEC_STD_READ_CONTROL
, NULL
,
690 struct samr_connect_info
, &status
);
691 if (NT_STATUS_IS_OK(status
)) {
692 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
693 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
694 &sam_generic_mapping
, NULL
, 0);
698 dinfo
= policy_handle_find(p
, r
->in
.handle
,
699 SEC_STD_READ_CONTROL
, NULL
,
700 struct samr_domain_info
, &status
);
701 if (NT_STATUS_IS_OK(status
)) {
702 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
704 dom_sid_str_buf(&dinfo
->sid
, &buf
)));
706 * TODO: Builtin probably needs a different SD with restricted
709 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
710 &dom_generic_mapping
, NULL
, 0);
714 uinfo
= policy_handle_find(p
, r
->in
.handle
,
715 SEC_STD_READ_CONTROL
, NULL
,
716 struct samr_user_info
, &status
);
717 if (NT_STATUS_IS_OK(status
)) {
718 DEBUG(10,("_samr_QuerySecurity: querying security on user "
719 "Object with SID: %s\n",
720 dom_sid_str_buf(&uinfo
->sid
, &buf
)));
721 if (check_change_pw_access(p
->mem_ctx
, &uinfo
->sid
)) {
722 status
= make_samr_object_sd(
723 p
->mem_ctx
, &psd
, &sd_size
,
724 &usr_generic_mapping
,
725 &uinfo
->sid
, SAMR_USR_RIGHTS_WRITE_PW
);
727 status
= make_samr_object_sd(
728 p
->mem_ctx
, &psd
, &sd_size
,
729 &usr_nopwchange_generic_mapping
,
730 &uinfo
->sid
, SAMR_USR_RIGHTS_CANT_WRITE_PW
);
735 ginfo
= policy_handle_find(p
, r
->in
.handle
,
736 SEC_STD_READ_CONTROL
, NULL
,
737 struct samr_group_info
, &status
);
738 if (NT_STATUS_IS_OK(status
)) {
740 * TODO: different SDs have to be generated for aliases groups
741 * and users. Currently all three get a default user SD
743 DEBUG(10,("_samr_QuerySecurity: querying security on group "
744 "Object with SID: %s\n",
745 dom_sid_str_buf(&ginfo
->sid
, &buf
)));
746 status
= make_samr_object_sd(
747 p
->mem_ctx
, &psd
, &sd_size
,
748 &usr_nopwchange_generic_mapping
,
749 &ginfo
->sid
, SAMR_USR_RIGHTS_CANT_WRITE_PW
);
753 ainfo
= policy_handle_find(p
, r
->in
.handle
,
754 SEC_STD_READ_CONTROL
, NULL
,
755 struct samr_alias_info
, &status
);
756 if (NT_STATUS_IS_OK(status
)) {
758 * TODO: different SDs have to be generated for aliases groups
759 * and users. Currently all three get a default user SD
761 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
762 "Object with SID: %s\n",
763 dom_sid_str_buf(&ainfo
->sid
, &buf
)));
764 status
= make_samr_object_sd(
765 p
->mem_ctx
, &psd
, &sd_size
,
766 &usr_nopwchange_generic_mapping
,
767 &ainfo
->sid
, SAMR_USR_RIGHTS_CANT_WRITE_PW
);
771 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
773 if ((*r
->out
.sdbuf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
774 return NT_STATUS_NO_MEMORY
;
779 /*******************************************************************
780 makes a SAM_ENTRY / UNISTR2* structure from a user list.
781 ********************************************************************/
783 static NTSTATUS
make_user_sam_entry_list(TALLOC_CTX
*ctx
,
784 struct samr_SamEntry
**sam_pp
,
785 uint32_t num_entries
,
787 struct samr_displayentry
*entries
)
790 struct samr_SamEntry
*sam
;
794 if (num_entries
== 0) {
798 sam
= talloc_zero_array(ctx
, struct samr_SamEntry
, num_entries
);
800 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
801 return NT_STATUS_NO_MEMORY
;
804 for (i
= 0; i
< num_entries
; i
++) {
807 * usrmgr expects a non-NULL terminated string with
808 * trust relationships
810 if (entries
[i
].acct_flags
& ACB_DOMTRUST
) {
811 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
814 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
818 init_lsa_String(&sam
[i
].name
, entries
[i
].account_name
);
819 sam
[i
].idx
= entries
[i
].rid
;
827 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
829 /*******************************************************************
830 _samr_EnumDomainUsers
831 ********************************************************************/
833 NTSTATUS
_samr_EnumDomainUsers(struct pipes_struct
*p
,
834 struct samr_EnumDomainUsers
*r
)
837 struct samr_domain_info
*dinfo
;
839 uint32_t enum_context
= *r
->in
.resume_handle
;
840 enum remote_arch_types ra_type
= get_remote_arch();
841 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
842 uint32_t max_entries
= max_sam_entries
;
843 struct samr_displayentry
*entries
= NULL
;
844 struct samr_SamArray
*samr_array
= NULL
;
845 struct samr_SamEntry
*samr_entries
= NULL
;
847 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__
));
849 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
850 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
851 struct samr_domain_info
, &status
);
852 if (!NT_STATUS_IS_OK(status
)) {
856 samr_array
= talloc_zero(p
->mem_ctx
, struct samr_SamArray
);
858 return NT_STATUS_NO_MEMORY
;
860 *r
->out
.sam
= samr_array
;
862 if (sid_check_is_builtin(&dinfo
->sid
)) {
863 /* No users in builtin. */
864 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
865 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
873 if ((dinfo
->disp_info
->enum_users
!= NULL
) &&
874 (dinfo
->disp_info
->enum_acb_mask
!= r
->in
.acct_flags
)) {
875 TALLOC_FREE(dinfo
->disp_info
->enum_users
);
878 if (dinfo
->disp_info
->enum_users
== NULL
) {
879 dinfo
->disp_info
->enum_users
= pdb_search_users(
880 dinfo
->disp_info
, r
->in
.acct_flags
);
881 dinfo
->disp_info
->enum_acb_mask
= r
->in
.acct_flags
;
884 if (dinfo
->disp_info
->enum_users
== NULL
) {
885 /* END AS ROOT !!!! */
887 return NT_STATUS_ACCESS_DENIED
;
890 num_account
= pdb_search_entries(dinfo
->disp_info
->enum_users
,
891 enum_context
, max_entries
,
894 /* END AS ROOT !!!! */
898 if (num_account
== 0) {
899 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
901 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
905 status
= make_user_sam_entry_list(p
->mem_ctx
, &samr_entries
,
906 num_account
, enum_context
,
908 if (!NT_STATUS_IS_OK(status
)) {
912 if (max_entries
<= num_account
) {
913 status
= STATUS_MORE_ENTRIES
;
915 status
= NT_STATUS_OK
;
918 /* Ensure we cache this enumeration. */
919 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
921 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__
));
923 samr_array
->count
= num_account
;
924 samr_array
->entries
= samr_entries
;
926 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ num_account
;
927 *r
->out
.num_entries
= num_account
;
929 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__
));
934 /*******************************************************************
935 makes a SAM_ENTRY / UNISTR2* structure from a group list.
936 ********************************************************************/
938 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
,
939 struct samr_SamEntry
**sam_pp
,
940 uint32_t num_sam_entries
,
941 struct samr_displayentry
*entries
)
943 struct samr_SamEntry
*sam
;
948 if (num_sam_entries
== 0) {
952 sam
= talloc_zero_array(ctx
, struct samr_SamEntry
, num_sam_entries
);
957 for (i
= 0; i
< num_sam_entries
; i
++) {
959 * JRA. I think this should include the null. TNG does not.
961 init_lsa_String(&sam
[i
].name
, entries
[i
].account_name
);
962 sam
[i
].idx
= entries
[i
].rid
;
968 /*******************************************************************
969 _samr_EnumDomainGroups
970 ********************************************************************/
972 NTSTATUS
_samr_EnumDomainGroups(struct pipes_struct
*p
,
973 struct samr_EnumDomainGroups
*r
)
976 struct samr_domain_info
*dinfo
;
977 struct samr_displayentry
*groups
;
979 struct samr_SamArray
*samr_array
= NULL
;
980 struct samr_SamEntry
*samr_entries
= NULL
;
982 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
983 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
984 struct samr_domain_info
, &status
);
985 if (!NT_STATUS_IS_OK(status
)) {
989 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__
));
991 samr_array
= talloc_zero(p
->mem_ctx
, struct samr_SamArray
);
993 return NT_STATUS_NO_MEMORY
;
995 *r
->out
.sam
= samr_array
;
997 if (sid_check_is_builtin(&dinfo
->sid
)) {
998 /* No groups in builtin. */
999 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
1000 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1004 /* the domain group array is being allocated in the function below */
1008 if (dinfo
->disp_info
->groups
== NULL
) {
1009 dinfo
->disp_info
->groups
= pdb_search_groups(dinfo
->disp_info
);
1011 if (dinfo
->disp_info
->groups
== NULL
) {
1013 return NT_STATUS_ACCESS_DENIED
;
1017 num_groups
= pdb_search_entries(dinfo
->disp_info
->groups
,
1018 *r
->in
.resume_handle
,
1019 MAX_SAM_ENTRIES
, &groups
);
1022 /* Ensure we cache this enumeration. */
1023 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1025 make_group_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1026 num_groups
, groups
);
1028 if (MAX_SAM_ENTRIES
<= num_groups
) {
1029 status
= STATUS_MORE_ENTRIES
;
1031 status
= NT_STATUS_OK
;
1034 samr_array
->count
= num_groups
;
1035 samr_array
->entries
= samr_entries
;
1037 *r
->out
.num_entries
= num_groups
;
1038 *r
->out
.resume_handle
= num_groups
+ *r
->in
.resume_handle
;
1040 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__
));
1045 /*******************************************************************
1046 _samr_EnumDomainAliases
1047 ********************************************************************/
1049 NTSTATUS
_samr_EnumDomainAliases(struct pipes_struct
*p
,
1050 struct samr_EnumDomainAliases
*r
)
1053 struct samr_domain_info
*dinfo
;
1054 struct samr_displayentry
*aliases
;
1055 uint32_t num_aliases
= 0;
1056 struct samr_SamArray
*samr_array
= NULL
;
1057 struct samr_SamEntry
*samr_entries
= NULL
;
1058 struct dom_sid_buf buf
;
1060 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
1061 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
1062 struct samr_domain_info
, &status
);
1063 if (!NT_STATUS_IS_OK(status
)) {
1067 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1068 dom_sid_str_buf(&dinfo
->sid
, &buf
)));
1070 samr_array
= talloc_zero(p
->mem_ctx
, struct samr_SamArray
);
1072 return NT_STATUS_NO_MEMORY
;
1077 if (dinfo
->disp_info
->aliases
== NULL
) {
1078 dinfo
->disp_info
->aliases
= pdb_search_aliases(
1079 dinfo
->disp_info
, &dinfo
->sid
);
1080 if (dinfo
->disp_info
->aliases
== NULL
) {
1082 return NT_STATUS_ACCESS_DENIED
;
1086 num_aliases
= pdb_search_entries(dinfo
->disp_info
->aliases
,
1087 *r
->in
.resume_handle
,
1088 MAX_SAM_ENTRIES
, &aliases
);
1091 /* Ensure we cache this enumeration. */
1092 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1094 make_group_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1095 num_aliases
, aliases
);
1097 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__
));
1099 if (MAX_SAM_ENTRIES
<= num_aliases
) {
1100 status
= STATUS_MORE_ENTRIES
;
1102 status
= NT_STATUS_OK
;
1105 samr_array
->count
= num_aliases
;
1106 samr_array
->entries
= samr_entries
;
1108 *r
->out
.sam
= samr_array
;
1109 *r
->out
.num_entries
= num_aliases
;
1110 *r
->out
.resume_handle
= num_aliases
+ *r
->in
.resume_handle
;
1115 /*******************************************************************
1116 inits a samr_DispInfoGeneral structure.
1117 ********************************************************************/
1119 static NTSTATUS
init_samr_dispinfo_1(TALLOC_CTX
*ctx
,
1120 struct samr_DispInfoGeneral
*r
,
1121 uint32_t num_entries
,
1123 struct samr_displayentry
*entries
)
1127 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries
));
1129 if (num_entries
== 0) {
1130 return NT_STATUS_OK
;
1133 r
->count
= num_entries
;
1135 r
->entries
= talloc_zero_array(ctx
, struct samr_DispEntryGeneral
, num_entries
);
1137 return NT_STATUS_NO_MEMORY
;
1140 for (i
= 0; i
< num_entries
; i
++) {
1142 init_lsa_String(&r
->entries
[i
].account_name
,
1143 entries
[i
].account_name
);
1145 init_lsa_String(&r
->entries
[i
].description
,
1146 entries
[i
].description
);
1148 init_lsa_String(&r
->entries
[i
].full_name
,
1149 entries
[i
].fullname
);
1151 r
->entries
[i
].rid
= entries
[i
].rid
;
1152 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1153 r
->entries
[i
].idx
= start_idx
+i
+1;
1156 return NT_STATUS_OK
;
1159 /*******************************************************************
1160 inits a samr_DispInfoFull structure.
1161 ********************************************************************/
1163 static NTSTATUS
init_samr_dispinfo_2(TALLOC_CTX
*ctx
,
1164 struct samr_DispInfoFull
*r
,
1165 uint32_t num_entries
,
1167 struct samr_displayentry
*entries
)
1171 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries
));
1173 if (num_entries
== 0) {
1174 return NT_STATUS_OK
;
1177 r
->count
= num_entries
;
1179 r
->entries
= talloc_zero_array(ctx
, struct samr_DispEntryFull
, num_entries
);
1181 return NT_STATUS_NO_MEMORY
;
1184 for (i
= 0; i
< num_entries
; i
++) {
1186 init_lsa_String(&r
->entries
[i
].account_name
,
1187 entries
[i
].account_name
);
1189 init_lsa_String(&r
->entries
[i
].description
,
1190 entries
[i
].description
);
1192 r
->entries
[i
].rid
= entries
[i
].rid
;
1193 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1194 r
->entries
[i
].idx
= start_idx
+i
+1;
1197 return NT_STATUS_OK
;
1200 /*******************************************************************
1201 inits a samr_DispInfoFullGroups structure.
1202 ********************************************************************/
1204 static NTSTATUS
init_samr_dispinfo_3(TALLOC_CTX
*ctx
,
1205 struct samr_DispInfoFullGroups
*r
,
1206 uint32_t num_entries
,
1208 struct samr_displayentry
*entries
)
1212 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries
));
1214 if (num_entries
== 0) {
1215 return NT_STATUS_OK
;
1218 r
->count
= num_entries
;
1220 r
->entries
= talloc_zero_array(ctx
, struct samr_DispEntryFullGroup
, num_entries
);
1222 return NT_STATUS_NO_MEMORY
;
1225 for (i
= 0; i
< num_entries
; i
++) {
1227 init_lsa_String(&r
->entries
[i
].account_name
,
1228 entries
[i
].account_name
);
1230 init_lsa_String(&r
->entries
[i
].description
,
1231 entries
[i
].description
);
1233 r
->entries
[i
].rid
= entries
[i
].rid
;
1234 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1235 r
->entries
[i
].idx
= start_idx
+i
+1;
1238 return NT_STATUS_OK
;
1241 /*******************************************************************
1242 inits a samr_DispInfoAscii structure.
1243 ********************************************************************/
1245 static NTSTATUS
init_samr_dispinfo_4(TALLOC_CTX
*ctx
,
1246 struct samr_DispInfoAscii
*r
,
1247 uint32_t num_entries
,
1249 struct samr_displayentry
*entries
)
1253 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries
));
1255 if (num_entries
== 0) {
1256 return NT_STATUS_OK
;
1259 r
->count
= num_entries
;
1261 r
->entries
= talloc_zero_array(ctx
, struct samr_DispEntryAscii
, num_entries
);
1263 return NT_STATUS_NO_MEMORY
;
1266 for (i
= 0; i
< num_entries
; i
++) {
1268 init_lsa_AsciiStringLarge(&r
->entries
[i
].account_name
,
1269 entries
[i
].account_name
);
1271 r
->entries
[i
].idx
= start_idx
+i
+1;
1274 return NT_STATUS_OK
;
1277 /*******************************************************************
1278 inits a samr_DispInfoAscii structure.
1279 ********************************************************************/
1281 static NTSTATUS
init_samr_dispinfo_5(TALLOC_CTX
*ctx
,
1282 struct samr_DispInfoAscii
*r
,
1283 uint32_t num_entries
,
1285 struct samr_displayentry
*entries
)
1289 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries
));
1291 if (num_entries
== 0) {
1292 return NT_STATUS_OK
;
1295 r
->count
= num_entries
;
1297 r
->entries
= talloc_zero_array(ctx
, struct samr_DispEntryAscii
, num_entries
);
1299 return NT_STATUS_NO_MEMORY
;
1302 for (i
= 0; i
< num_entries
; i
++) {
1304 init_lsa_AsciiStringLarge(&r
->entries
[i
].account_name
,
1305 entries
[i
].account_name
);
1307 r
->entries
[i
].idx
= start_idx
+i
+1;
1310 return NT_STATUS_OK
;
1313 /*******************************************************************
1314 _samr_QueryDisplayInfo
1315 ********************************************************************/
1317 NTSTATUS
_samr_QueryDisplayInfo(struct pipes_struct
*p
,
1318 struct samr_QueryDisplayInfo
*r
)
1321 struct samr_domain_info
*dinfo
;
1322 uint32_t struct_size
=0x20; /* W2K always reply that, client doesn't care */
1324 uint32_t max_entries
= r
->in
.max_entries
;
1326 union samr_DispInfo
*disp_info
= r
->out
.info
;
1328 uint32_t temp_size
=0;
1329 NTSTATUS disp_ret
= NT_STATUS_UNSUCCESSFUL
;
1330 uint32_t num_account
= 0;
1331 enum remote_arch_types ra_type
= get_remote_arch();
1332 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
1333 struct samr_displayentry
*entries
= NULL
;
1335 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__
));
1337 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
1338 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
1339 struct samr_domain_info
, &status
);
1340 if (!NT_STATUS_IS_OK(status
)) {
1344 if (sid_check_is_builtin(&dinfo
->sid
)) {
1345 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1346 return NT_STATUS_OK
;
1350 * calculate how many entries we will return.
1352 * - the number of entries the client asked
1353 * - our limit on that
1354 * - the starting point (enumeration context)
1355 * - the buffer size the client will accept
1359 * We are a lot more like W2K. Instead of reading the SAM
1360 * each time to find the records we need to send back,
1361 * we read it once and link that copy to the sam handle.
1362 * For large user list (over the MAX_SAM_ENTRIES)
1363 * it's a definitive win.
1364 * second point to notice: between enumerations
1365 * our sam is now the same as it's a snapshoot.
1366 * third point: got rid of the static SAM_USER_21 struct
1367 * no more intermediate.
1368 * con: it uses much more memory, as a full copy is stored
1371 * If you want to change it, think twice and think
1372 * of the second point , that's really important.
1377 if ((r
->in
.level
< 1) || (r
->in
.level
> 5)) {
1378 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1379 (unsigned int)r
->in
.level
));
1380 return NT_STATUS_INVALID_INFO_CLASS
;
1383 /* first limit the number of entries we will return */
1384 if (r
->in
.max_entries
> max_sam_entries
) {
1385 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1386 "entries, limiting to %d\n", r
->in
.max_entries
,
1388 max_entries
= max_sam_entries
;
1391 /* calculate the size and limit on the number of entries we will
1394 temp_size
=max_entries
*struct_size
;
1396 if (temp_size
> r
->in
.buf_size
) {
1397 max_entries
= MIN((r
->in
.buf_size
/ struct_size
),max_entries
);
1398 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1399 "only %d entries\n", max_entries
));
1404 /* THe following done as ROOT. Don't return without unbecome_root(). */
1406 switch (r
->in
.level
) {
1409 if (dinfo
->disp_info
->users
== NULL
) {
1410 dinfo
->disp_info
->users
= pdb_search_users(
1411 dinfo
->disp_info
, ACB_NORMAL
);
1412 if (dinfo
->disp_info
->users
== NULL
) {
1414 return NT_STATUS_ACCESS_DENIED
;
1416 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1417 (unsigned int)r
->in
.start_idx
));
1419 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1420 (unsigned int)r
->in
.start_idx
));
1423 num_account
= pdb_search_entries(dinfo
->disp_info
->users
,
1424 r
->in
.start_idx
, max_entries
,
1428 if (dinfo
->disp_info
->machines
== NULL
) {
1429 dinfo
->disp_info
->machines
= pdb_search_users(
1430 dinfo
->disp_info
, ACB_WSTRUST
|ACB_SVRTRUST
);
1431 if (dinfo
->disp_info
->machines
== NULL
) {
1433 return NT_STATUS_ACCESS_DENIED
;
1435 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1436 (unsigned int)r
->in
.start_idx
));
1438 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1439 (unsigned int)r
->in
.start_idx
));
1442 num_account
= pdb_search_entries(dinfo
->disp_info
->machines
,
1443 r
->in
.start_idx
, max_entries
,
1448 if (dinfo
->disp_info
->groups
== NULL
) {
1449 dinfo
->disp_info
->groups
= pdb_search_groups(
1451 if (dinfo
->disp_info
->groups
== NULL
) {
1453 return NT_STATUS_ACCESS_DENIED
;
1455 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1456 (unsigned int)r
->in
.start_idx
));
1458 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1459 (unsigned int)r
->in
.start_idx
));
1462 num_account
= pdb_search_entries(dinfo
->disp_info
->groups
,
1463 r
->in
.start_idx
, max_entries
,
1468 smb_panic("info class changed");
1474 /* Now create reply structure */
1475 switch (r
->in
.level
) {
1477 disp_ret
= init_samr_dispinfo_1(p
->mem_ctx
, &disp_info
->info1
,
1478 num_account
, r
->in
.start_idx
,
1482 disp_ret
= init_samr_dispinfo_2(p
->mem_ctx
, &disp_info
->info2
,
1483 num_account
, r
->in
.start_idx
,
1487 disp_ret
= init_samr_dispinfo_3(p
->mem_ctx
, &disp_info
->info3
,
1488 num_account
, r
->in
.start_idx
,
1492 disp_ret
= init_samr_dispinfo_4(p
->mem_ctx
, &disp_info
->info4
,
1493 num_account
, r
->in
.start_idx
,
1497 disp_ret
= init_samr_dispinfo_5(p
->mem_ctx
, &disp_info
->info5
,
1498 num_account
, r
->in
.start_idx
,
1502 smb_panic("info class changed");
1506 if (!NT_STATUS_IS_OK(disp_ret
))
1509 if (max_entries
<= num_account
) {
1510 status
= STATUS_MORE_ENTRIES
;
1512 status
= NT_STATUS_OK
;
1515 /* Ensure we cache this enumeration. */
1516 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1518 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__
));
1520 *r
->out
.total_size
= num_account
* struct_size
;
1521 *r
->out
.returned_size
= num_account
? temp_size
: 0;
1526 /****************************************************************
1527 _samr_QueryDisplayInfo2
1528 ****************************************************************/
1530 NTSTATUS
_samr_QueryDisplayInfo2(struct pipes_struct
*p
,
1531 struct samr_QueryDisplayInfo2
*r
)
1533 struct samr_QueryDisplayInfo q
;
1535 q
.in
.domain_handle
= r
->in
.domain_handle
;
1536 q
.in
.level
= r
->in
.level
;
1537 q
.in
.start_idx
= r
->in
.start_idx
;
1538 q
.in
.max_entries
= r
->in
.max_entries
;
1539 q
.in
.buf_size
= r
->in
.buf_size
;
1541 q
.out
.total_size
= r
->out
.total_size
;
1542 q
.out
.returned_size
= r
->out
.returned_size
;
1543 q
.out
.info
= r
->out
.info
;
1545 return _samr_QueryDisplayInfo(p
, &q
);
1548 /****************************************************************
1549 _samr_QueryDisplayInfo3
1550 ****************************************************************/
1552 NTSTATUS
_samr_QueryDisplayInfo3(struct pipes_struct
*p
,
1553 struct samr_QueryDisplayInfo3
*r
)
1555 struct samr_QueryDisplayInfo q
;
1557 q
.in
.domain_handle
= r
->in
.domain_handle
;
1558 q
.in
.level
= r
->in
.level
;
1559 q
.in
.start_idx
= r
->in
.start_idx
;
1560 q
.in
.max_entries
= r
->in
.max_entries
;
1561 q
.in
.buf_size
= r
->in
.buf_size
;
1563 q
.out
.total_size
= r
->out
.total_size
;
1564 q
.out
.returned_size
= r
->out
.returned_size
;
1565 q
.out
.info
= r
->out
.info
;
1567 return _samr_QueryDisplayInfo(p
, &q
);
1570 /*******************************************************************
1571 _samr_QueryAliasInfo
1572 ********************************************************************/
1574 NTSTATUS
_samr_QueryAliasInfo(struct pipes_struct
*p
,
1575 struct samr_QueryAliasInfo
*r
)
1577 struct samr_alias_info
*ainfo
;
1578 struct acct_info
*info
;
1580 union samr_AliasInfo
*alias_info
= NULL
;
1581 const char *alias_name
= NULL
;
1582 const char *alias_description
= NULL
;
1584 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__
));
1586 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
1587 SAMR_ALIAS_ACCESS_LOOKUP_INFO
, NULL
,
1588 struct samr_alias_info
, &status
);
1589 if (!NT_STATUS_IS_OK(status
)) {
1593 alias_info
= talloc_zero(p
->mem_ctx
, union samr_AliasInfo
);
1595 return NT_STATUS_NO_MEMORY
;
1598 info
= talloc_zero(p
->mem_ctx
, struct acct_info
);
1600 return NT_STATUS_NO_MEMORY
;
1604 status
= pdb_get_aliasinfo(&ainfo
->sid
, info
);
1607 if (!NT_STATUS_IS_OK(status
)) {
1612 alias_name
= talloc_steal(r
, info
->acct_name
);
1613 alias_description
= talloc_steal(r
, info
->acct_desc
);
1616 switch (r
->in
.level
) {
1618 alias_info
->all
.name
.string
= alias_name
;
1619 alias_info
->all
.num_members
= 1; /* ??? */
1620 alias_info
->all
.description
.string
= alias_description
;
1623 alias_info
->name
.string
= alias_name
;
1625 case ALIASINFODESCRIPTION
:
1626 alias_info
->description
.string
= alias_description
;
1629 return NT_STATUS_INVALID_INFO_CLASS
;
1632 *r
->out
.info
= alias_info
;
1634 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__
));
1636 return NT_STATUS_OK
;
1639 /*******************************************************************
1641 ********************************************************************/
1643 NTSTATUS
_samr_LookupNames(struct pipes_struct
*p
,
1644 struct samr_LookupNames
*r
)
1646 struct samr_domain_info
*dinfo
;
1649 enum lsa_SidType
*type
;
1651 int num_rids
= r
->in
.num_names
;
1652 struct samr_Ids rids
, types
;
1653 uint32_t num_mapped
= 0;
1654 struct dom_sid_buf buf
;
1656 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1658 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
1659 0 /* Don't know the acc_bits yet */, NULL
,
1660 struct samr_domain_info
, &status
);
1661 if (!NT_STATUS_IS_OK(status
)) {
1665 if (num_rids
> MAX_SAM_ENTRIES
) {
1666 num_rids
= MAX_SAM_ENTRIES
;
1667 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids
));
1670 rid
= talloc_array(p
->mem_ctx
, uint32_t, num_rids
);
1671 NT_STATUS_HAVE_NO_MEMORY(rid
);
1673 type
= talloc_array(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
1674 NT_STATUS_HAVE_NO_MEMORY(type
);
1676 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1677 dom_sid_str_buf(&dinfo
->sid
, &buf
)));
1679 for (i
= 0; i
< num_rids
; i
++) {
1681 status
= NT_STATUS_NONE_MAPPED
;
1682 type
[i
] = SID_NAME_UNKNOWN
;
1684 rid
[i
] = 0xffffffff;
1686 if (sid_check_is_builtin(&dinfo
->sid
)) {
1687 if (lookup_builtin_name(r
->in
.names
[i
].string
,
1690 type
[i
] = SID_NAME_ALIAS
;
1693 lookup_global_sam_name(r
->in
.names
[i
].string
, 0,
1697 if (type
[i
] != SID_NAME_UNKNOWN
) {
1702 if (num_mapped
== num_rids
) {
1703 status
= NT_STATUS_OK
;
1704 } else if (num_mapped
== 0) {
1705 status
= NT_STATUS_NONE_MAPPED
;
1707 status
= STATUS_SOME_UNMAPPED
;
1710 rids
.count
= num_rids
;
1713 types
.count
= num_rids
;
1714 types
.ids
= talloc_array(p
->mem_ctx
, uint32_t, num_rids
);
1715 NT_STATUS_HAVE_NO_MEMORY(type
);
1716 for (i
= 0; i
< num_rids
; i
++) {
1717 types
.ids
[i
] = (type
[i
] & 0xffffffff);
1720 *r
->out
.rids
= rids
;
1721 *r
->out
.types
= types
;
1723 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1728 /****************************************************************
1729 _samr_ChangePasswordUser.
1731 So old it is just not worth implementing
1732 because it does not supply a plaintext and so we can't do password
1733 complexity checking and cannot update other services that use a
1734 plaintext password via passwd chat/pam password change/ldap password
1736 ****************************************************************/
1738 NTSTATUS
_samr_ChangePasswordUser(struct pipes_struct
*p
,
1739 struct samr_ChangePasswordUser
*r
)
1741 return NT_STATUS_NOT_IMPLEMENTED
;
1744 /*******************************************************************
1745 _samr_ChangePasswordUser2
1746 ********************************************************************/
1748 NTSTATUS
_samr_ChangePasswordUser2(struct pipes_struct
*p
,
1749 struct samr_ChangePasswordUser2
*r
)
1752 char *user_name
= NULL
;
1754 const char *wks
= NULL
;
1756 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
1758 if (!r
->in
.account
->string
) {
1759 return NT_STATUS_INVALID_PARAMETER
;
1761 if (r
->in
.server
&& r
->in
.server
->string
) {
1762 wks
= r
->in
.server
->string
;
1765 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
1768 * Pass the user through the NT -> unix user mapping
1772 (void)map_username(talloc_tos(), r
->in
.account
->string
, &user_name
);
1774 return NT_STATUS_NO_MEMORY
;
1777 rhost
= tsocket_address_inet_addr_string(p
->remote_address
,
1779 if (rhost
== NULL
) {
1780 return NT_STATUS_NO_MEMORY
;
1784 * UNIX username case mangling not required, pass_oem_change
1785 * is case insensitive.
1788 status
= pass_oem_change(user_name
,
1790 r
->in
.lm_password
->data
,
1791 r
->in
.lm_verifier
->hash
,
1792 r
->in
.nt_password
->data
,
1793 r
->in
.nt_verifier
->hash
,
1796 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
1798 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
1799 return NT_STATUS_WRONG_PASSWORD
;
1805 /****************************************************************
1806 _samr_OemChangePasswordUser2
1807 ****************************************************************/
1809 NTSTATUS
_samr_OemChangePasswordUser2(struct pipes_struct
*p
,
1810 struct samr_OemChangePasswordUser2
*r
)
1813 char *user_name
= NULL
;
1814 const char *wks
= NULL
;
1817 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
1819 if (!r
->in
.account
->string
) {
1820 return NT_STATUS_INVALID_PARAMETER
;
1822 if (r
->in
.server
&& r
->in
.server
->string
) {
1823 wks
= r
->in
.server
->string
;
1826 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
1829 * Pass the user through the NT -> unix user mapping
1833 (void)map_username(talloc_tos(), r
->in
.account
->string
, &user_name
);
1835 return NT_STATUS_NO_MEMORY
;
1839 * UNIX username case mangling not required, pass_oem_change
1840 * is case insensitive.
1843 if (!r
->in
.hash
|| !r
->in
.password
) {
1844 return NT_STATUS_INVALID_PARAMETER
;
1847 rhost
= tsocket_address_inet_addr_string(p
->remote_address
,
1849 if (rhost
== NULL
) {
1850 return NT_STATUS_NO_MEMORY
;
1853 status
= pass_oem_change(user_name
,
1855 r
->in
.password
->data
,
1861 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
1862 return NT_STATUS_WRONG_PASSWORD
;
1865 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
1870 /*******************************************************************
1871 _samr_ChangePasswordUser3
1872 ********************************************************************/
1874 NTSTATUS
_samr_ChangePasswordUser3(struct pipes_struct
*p
,
1875 struct samr_ChangePasswordUser3
*r
)
1878 char *user_name
= NULL
;
1879 const char *wks
= NULL
;
1880 enum samPwdChangeReason reject_reason
;
1881 struct samr_DomInfo1
*dominfo
= NULL
;
1882 struct userPwdChangeFailureInformation
*reject
= NULL
;
1886 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
1888 if (!r
->in
.account
->string
) {
1889 return NT_STATUS_INVALID_PARAMETER
;
1891 if (r
->in
.server
&& r
->in
.server
->string
) {
1892 wks
= r
->in
.server
->string
;
1895 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name
, wks
));
1898 * Pass the user through the NT -> unix user mapping
1902 (void)map_username(talloc_tos(), r
->in
.account
->string
, &user_name
);
1904 return NT_STATUS_NO_MEMORY
;
1907 rhost
= tsocket_address_inet_addr_string(p
->remote_address
,
1909 if (rhost
== NULL
) {
1910 return NT_STATUS_NO_MEMORY
;
1914 * UNIX username case mangling not required, pass_oem_change
1915 * is case insensitive.
1918 status
= pass_oem_change(user_name
,
1920 r
->in
.lm_password
->data
,
1921 r
->in
.lm_verifier
->hash
,
1922 r
->in
.nt_password
->data
,
1923 r
->in
.nt_verifier
->hash
,
1925 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
1926 return NT_STATUS_WRONG_PASSWORD
;
1929 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) ||
1930 NT_STATUS_EQUAL(status
, NT_STATUS_ACCOUNT_RESTRICTION
)) {
1932 time_t u_expire
, u_min_age
;
1933 uint32_t account_policy_temp
;
1935 dominfo
= talloc_zero(p
->mem_ctx
, struct samr_DomInfo1
);
1937 return NT_STATUS_NO_MEMORY
;
1940 reject
= talloc_zero(p
->mem_ctx
,
1941 struct userPwdChangeFailureInformation
);
1943 return NT_STATUS_NO_MEMORY
;
1950 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN
, &tmp
);
1951 dominfo
->min_password_length
= tmp
;
1953 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &tmp
);
1954 dominfo
->password_history_length
= tmp
;
1956 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS
,
1957 &dominfo
->password_properties
);
1959 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE
, &account_policy_temp
);
1960 u_expire
= account_policy_temp
;
1962 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE
, &account_policy_temp
);
1963 u_min_age
= account_policy_temp
;
1969 unix_to_nt_time_abs((NTTIME
*)&dominfo
->max_password_age
, u_expire
);
1970 unix_to_nt_time_abs((NTTIME
*)&dominfo
->min_password_age
, u_min_age
);
1972 if (lp_check_password_script(talloc_tos())
1973 && *lp_check_password_script(talloc_tos())) {
1974 dominfo
->password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
1977 reject
->extendedFailureReason
= reject_reason
;
1979 *r
->out
.dominfo
= dominfo
;
1980 *r
->out
.reject
= reject
;
1983 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
1988 /*******************************************************************
1989 makes a SAMR_R_LOOKUP_RIDS structure.
1990 ********************************************************************/
1992 static bool make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32_t num_names
,
1994 struct lsa_String
**lsa_name_array_p
)
1996 struct lsa_String
*lsa_name_array
= NULL
;
1999 *lsa_name_array_p
= NULL
;
2001 if (num_names
!= 0) {
2002 lsa_name_array
= talloc_zero_array(ctx
, struct lsa_String
, num_names
);
2003 if (!lsa_name_array
) {
2008 for (i
= 0; i
< num_names
; i
++) {
2009 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
] && *names
[i
] ? names
[i
] : ""));
2010 init_lsa_String(&lsa_name_array
[i
], names
[i
]);
2013 *lsa_name_array_p
= lsa_name_array
;
2018 /*******************************************************************
2020 ********************************************************************/
2022 NTSTATUS
_samr_LookupRids(struct pipes_struct
*p
,
2023 struct samr_LookupRids
*r
)
2025 struct samr_domain_info
*dinfo
;
2028 enum lsa_SidType
*attrs
= NULL
;
2029 uint32_t *wire_attrs
= NULL
;
2030 int num_rids
= (int)r
->in
.num_rids
;
2032 struct lsa_Strings names_array
;
2033 struct samr_Ids types_array
;
2034 struct lsa_String
*lsa_names
= NULL
;
2036 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2038 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
2039 0 /* Don't know the acc_bits yet */, NULL
,
2040 struct samr_domain_info
, &status
);
2041 if (!NT_STATUS_IS_OK(status
)) {
2045 if (num_rids
> 1000) {
2046 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2047 "to samba4 idl this is not possible\n", num_rids
));
2048 return NT_STATUS_UNSUCCESSFUL
;
2052 names
= talloc_zero_array(p
->mem_ctx
, const char *, num_rids
);
2053 attrs
= talloc_zero_array(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
2054 wire_attrs
= talloc_zero_array(p
->mem_ctx
, uint32_t, num_rids
);
2056 if ((names
== NULL
) || (attrs
== NULL
) || (wire_attrs
==NULL
))
2057 return NT_STATUS_NO_MEMORY
;
2064 become_root(); /* lookup_sid can require root privs */
2065 status
= pdb_lookup_rids(&dinfo
->sid
, num_rids
, r
->in
.rids
,
2069 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
) && (num_rids
== 0)) {
2070 status
= NT_STATUS_OK
;
2073 if (!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, names
,
2075 return NT_STATUS_NO_MEMORY
;
2078 /* Convert from enum lsa_SidType to uint32_t for wire format. */
2079 for (i
= 0; i
< num_rids
; i
++) {
2080 wire_attrs
[i
] = (uint32_t)attrs
[i
];
2083 names_array
.count
= num_rids
;
2084 names_array
.names
= lsa_names
;
2086 types_array
.count
= num_rids
;
2087 types_array
.ids
= wire_attrs
;
2089 *r
->out
.names
= names_array
;
2090 *r
->out
.types
= types_array
;
2092 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2097 /*******************************************************************
2099 ********************************************************************/
2101 NTSTATUS
_samr_OpenUser(struct pipes_struct
*p
,
2102 struct samr_OpenUser
*r
)
2104 struct samu
*sampass
=NULL
;
2106 struct samr_domain_info
*dinfo
;
2107 struct samr_user_info
*uinfo
;
2108 struct security_descriptor
*psd
= NULL
;
2109 uint32_t acc_granted
;
2110 uint32_t des_access
= r
->in
.access_mask
;
2111 uint32_t extra_access
= 0;
2116 /* These two privileges, if != SEC_PRIV_INVALID, indicate
2117 * privileges that the user must have to complete this
2118 * operation in defience of the fixed ACL */
2119 enum sec_privilege needed_priv_1
, needed_priv_2
;
2122 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
2123 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
2124 struct samr_domain_info
, &status
);
2125 if (!NT_STATUS_IS_OK(status
)) {
2129 if ( !(sampass
= samu_new( p
->mem_ctx
)) ) {
2130 return NT_STATUS_NO_MEMORY
;
2133 /* append the user's RID to it */
2135 if (!sid_compose(&sid
, &dinfo
->sid
, r
->in
.rid
))
2136 return NT_STATUS_NO_SUCH_USER
;
2138 /* check if access can be granted as requested by client. */
2139 map_max_allowed_access(p
->session_info
->security_token
,
2140 p
->session_info
->unix_token
,
2143 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
, &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
2144 se_map_generic(&des_access
, &usr_generic_mapping
);
2147 * Get the sampass first as we need to check privileges
2148 * based on what kind of user object this is.
2149 * But don't reveal info too early if it didn't exist.
2153 ret
=pdb_getsampwsid(sampass
, &sid
);
2156 needed_priv_1
= SEC_PRIV_INVALID
;
2157 needed_priv_2
= SEC_PRIV_INVALID
;
2159 * We do the override access checks on *open*, not at
2163 uint32_t acb_info
= pdb_get_acct_ctrl(sampass
);
2165 if (acb_info
& ACB_WSTRUST
) {
2167 * SeMachineAccount is needed to add
2168 * GENERIC_RIGHTS_USER_WRITE to a machine
2171 needed_priv_1
= SEC_PRIV_MACHINE_ACCOUNT
;
2173 if (acb_info
& ACB_NORMAL
) {
2175 * SeAddUsers is needed to add
2176 * GENERIC_RIGHTS_USER_WRITE to a normal
2179 needed_priv_1
= SEC_PRIV_ADD_USERS
;
2182 * Cheat - we have not set a specific privilege for
2183 * server (BDC) or domain trust account, so allow
2184 * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2185 * DOMAIN_RID_ADMINS.
2187 if (acb_info
& (ACB_SVRTRUST
|ACB_DOMTRUST
)) {
2188 if (lp_enable_privileges() && nt_token_check_domain_rid(p
->session_info
->security_token
,
2189 DOMAIN_RID_ADMINS
)) {
2190 des_access
&= ~GENERIC_RIGHTS_USER_WRITE
;
2191 extra_access
= GENERIC_RIGHTS_USER_WRITE
;
2192 DEBUG(4,("_samr_OpenUser: Allowing "
2193 "GENERIC_RIGHTS_USER_WRITE for "
2199 TALLOC_FREE(sampass
);
2201 nt_status
= access_check_object(psd
, p
->session_info
->security_token
,
2202 needed_priv_1
, needed_priv_2
,
2203 GENERIC_RIGHTS_USER_WRITE
, des_access
,
2204 &acc_granted
, "_samr_OpenUser");
2206 if ( !NT_STATUS_IS_OK(nt_status
) )
2209 /* check that the SID exists in our domain. */
2211 return NT_STATUS_NO_SUCH_USER
;
2214 /* If we did the rid admins hack above, allow access. */
2215 acc_granted
|= extra_access
;
2217 uinfo
= policy_handle_create(p
, r
->out
.user_handle
, acc_granted
,
2218 struct samr_user_info
, &nt_status
);
2219 if (!NT_STATUS_IS_OK(nt_status
)) {
2224 return NT_STATUS_OK
;
2227 /*************************************************************************
2228 *************************************************************************/
2230 static NTSTATUS
init_samr_parameters_string(TALLOC_CTX
*mem_ctx
,
2232 struct lsa_BinaryString
**_r
)
2234 struct lsa_BinaryString
*r
;
2237 return NT_STATUS_INVALID_PARAMETER
;
2240 r
= talloc_zero(mem_ctx
, struct lsa_BinaryString
);
2242 return NT_STATUS_NO_MEMORY
;
2245 r
->array
= talloc_zero_array(mem_ctx
, uint16_t, blob
->length
/2);
2247 return NT_STATUS_NO_MEMORY
;
2249 memcpy(r
->array
, blob
->data
, blob
->length
);
2250 r
->size
= blob
->length
;
2251 r
->length
= blob
->length
;
2254 return NT_STATUS_NO_MEMORY
;
2259 return NT_STATUS_OK
;
2262 /*************************************************************************
2263 *************************************************************************/
2265 static struct samr_LogonHours
get_logon_hours_from_pdb(TALLOC_CTX
*mem_ctx
,
2268 struct samr_LogonHours hours
;
2269 const int units_per_week
= 168;
2272 hours
.bits
= talloc_array(mem_ctx
, uint8_t, units_per_week
);
2277 hours
.units_per_week
= units_per_week
;
2278 memset(hours
.bits
, 0xFF, units_per_week
);
2280 if (pdb_get_hours(pw
)) {
2281 memcpy(hours
.bits
, pdb_get_hours(pw
),
2282 MIN(pdb_get_hours_len(pw
), units_per_week
));
2288 /*************************************************************************
2290 *************************************************************************/
2292 static NTSTATUS
get_user_info_1(TALLOC_CTX
*mem_ctx
,
2293 struct samr_UserInfo1
*r
,
2295 struct dom_sid
*domain_sid
)
2297 const struct dom_sid
*sid_group
;
2298 uint32_t primary_gid
;
2301 sid_group
= pdb_get_group_sid(pw
);
2304 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2305 struct dom_sid_buf buf1
, buf2
;
2307 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2308 "which conflicts with the domain sid %s. Failing operation.\n",
2309 pdb_get_username(pw
),
2310 dom_sid_str_buf(sid_group
, &buf1
),
2311 dom_sid_str_buf(domain_sid
, &buf2
)));
2312 return NT_STATUS_UNSUCCESSFUL
;
2315 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2316 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2317 r
->primary_gid
= primary_gid
;
2318 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2319 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2321 return NT_STATUS_OK
;
2324 /*************************************************************************
2326 *************************************************************************/
2328 static NTSTATUS
get_user_info_2(TALLOC_CTX
*mem_ctx
,
2329 struct samr_UserInfo2
*r
,
2332 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2333 r
->reserved
.string
= NULL
;
2334 r
->country_code
= pdb_get_country_code(pw
);
2335 r
->code_page
= pdb_get_code_page(pw
);
2337 return NT_STATUS_OK
;
2340 /*************************************************************************
2342 *************************************************************************/
2344 static NTSTATUS
get_user_info_3(TALLOC_CTX
*mem_ctx
,
2345 struct samr_UserInfo3
*r
,
2347 struct dom_sid
*domain_sid
)
2349 const struct dom_sid
*sid_user
, *sid_group
;
2350 uint32_t rid
, primary_gid
;
2351 struct dom_sid_buf buf1
, buf2
;
2353 sid_user
= pdb_get_user_sid(pw
);
2355 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2356 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2357 "the domain sid %s. Failing operation.\n",
2358 pdb_get_username(pw
),
2359 dom_sid_str_buf(sid_user
, &buf1
),
2360 dom_sid_str_buf(domain_sid
, &buf2
)));
2361 return NT_STATUS_UNSUCCESSFUL
;
2365 sid_group
= pdb_get_group_sid(pw
);
2368 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2369 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2370 "which conflicts with the domain sid %s. Failing operation.\n",
2371 pdb_get_username(pw
),
2372 dom_sid_str_buf(sid_group
, &buf1
),
2373 dom_sid_str_buf(domain_sid
, &buf2
)));
2374 return NT_STATUS_UNSUCCESSFUL
;
2377 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2378 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2379 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2380 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2381 unix_to_nt_time(&r
->force_password_change
, pdb_get_pass_must_change_time(pw
));
2383 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2384 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2385 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2386 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2387 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2388 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2389 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2391 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2393 r
->primary_gid
= primary_gid
;
2394 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2395 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2396 r
->logon_count
= pdb_get_logon_count(pw
);
2398 return NT_STATUS_OK
;
2401 /*************************************************************************
2403 *************************************************************************/
2405 static NTSTATUS
get_user_info_4(TALLOC_CTX
*mem_ctx
,
2406 struct samr_UserInfo4
*r
,
2409 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2411 return NT_STATUS_OK
;
2414 /*************************************************************************
2416 *************************************************************************/
2418 static NTSTATUS
get_user_info_5(TALLOC_CTX
*mem_ctx
,
2419 struct samr_UserInfo5
*r
,
2421 struct dom_sid
*domain_sid
)
2423 const struct dom_sid
*sid_user
, *sid_group
;
2424 uint32_t rid
, primary_gid
;
2425 struct dom_sid_buf buf1
, buf2
;
2427 sid_user
= pdb_get_user_sid(pw
);
2429 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2430 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2431 "the domain sid %s. Failing operation.\n",
2432 pdb_get_username(pw
),
2433 dom_sid_str_buf(sid_user
, &buf1
),
2434 dom_sid_str_buf(domain_sid
, &buf2
)));
2435 return NT_STATUS_UNSUCCESSFUL
;
2439 sid_group
= pdb_get_group_sid(pw
);
2442 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2443 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2444 "which conflicts with the domain sid %s. Failing operation.\n",
2445 pdb_get_username(pw
),
2446 dom_sid_str_buf(sid_group
, &buf1
),
2447 dom_sid_str_buf(domain_sid
, &buf2
)));
2448 return NT_STATUS_UNSUCCESSFUL
;
2451 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2452 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2453 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2454 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2456 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2457 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2458 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2459 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2460 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2461 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2462 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2463 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2465 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2467 r
->primary_gid
= primary_gid
;
2468 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2469 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2470 r
->logon_count
= pdb_get_logon_count(pw
);
2472 return NT_STATUS_OK
;
2475 /*************************************************************************
2477 *************************************************************************/
2479 static NTSTATUS
get_user_info_6(TALLOC_CTX
*mem_ctx
,
2480 struct samr_UserInfo6
*r
,
2483 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2484 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2486 return NT_STATUS_OK
;
2489 /*************************************************************************
2490 get_user_info_7. Safe. Only gives out account_name.
2491 *************************************************************************/
2493 static NTSTATUS
get_user_info_7(TALLOC_CTX
*mem_ctx
,
2494 struct samr_UserInfo7
*r
,
2495 struct samu
*smbpass
)
2497 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(smbpass
));
2498 if (!r
->account_name
.string
) {
2499 return NT_STATUS_NO_MEMORY
;
2502 return NT_STATUS_OK
;
2505 /*************************************************************************
2507 *************************************************************************/
2509 static NTSTATUS
get_user_info_8(TALLOC_CTX
*mem_ctx
,
2510 struct samr_UserInfo8
*r
,
2513 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2515 return NT_STATUS_OK
;
2518 /*************************************************************************
2519 get_user_info_9. Only gives out primary group SID.
2520 *************************************************************************/
2522 static NTSTATUS
get_user_info_9(TALLOC_CTX
*mem_ctx
,
2523 struct samr_UserInfo9
*r
,
2524 struct samu
*smbpass
)
2526 r
->primary_gid
= pdb_get_group_rid(smbpass
);
2528 return NT_STATUS_OK
;
2531 /*************************************************************************
2533 *************************************************************************/
2535 static NTSTATUS
get_user_info_10(TALLOC_CTX
*mem_ctx
,
2536 struct samr_UserInfo10
*r
,
2539 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2540 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2542 return NT_STATUS_OK
;
2545 /*************************************************************************
2547 *************************************************************************/
2549 static NTSTATUS
get_user_info_11(TALLOC_CTX
*mem_ctx
,
2550 struct samr_UserInfo11
*r
,
2553 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2555 return NT_STATUS_OK
;
2558 /*************************************************************************
2560 *************************************************************************/
2562 static NTSTATUS
get_user_info_12(TALLOC_CTX
*mem_ctx
,
2563 struct samr_UserInfo12
*r
,
2566 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2568 return NT_STATUS_OK
;
2571 /*************************************************************************
2573 *************************************************************************/
2575 static NTSTATUS
get_user_info_13(TALLOC_CTX
*mem_ctx
,
2576 struct samr_UserInfo13
*r
,
2579 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2581 return NT_STATUS_OK
;
2584 /*************************************************************************
2586 *************************************************************************/
2588 static NTSTATUS
get_user_info_14(TALLOC_CTX
*mem_ctx
,
2589 struct samr_UserInfo14
*r
,
2592 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2594 return NT_STATUS_OK
;
2597 /*************************************************************************
2598 get_user_info_16. Safe. Only gives out acb bits.
2599 *************************************************************************/
2601 static NTSTATUS
get_user_info_16(TALLOC_CTX
*mem_ctx
,
2602 struct samr_UserInfo16
*r
,
2603 struct samu
*smbpass
)
2605 r
->acct_flags
= pdb_get_acct_ctrl(smbpass
);
2607 return NT_STATUS_OK
;
2610 /*************************************************************************
2612 *************************************************************************/
2614 static NTSTATUS
get_user_info_17(TALLOC_CTX
*mem_ctx
,
2615 struct samr_UserInfo17
*r
,
2618 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2620 return NT_STATUS_OK
;
2623 /*************************************************************************
2624 get_user_info_18. OK - this is the killer as it gives out password info.
2625 Ensure that this is only allowed on an encrypted connection with a root
2627 *************************************************************************/
2629 static NTSTATUS
get_user_info_18(struct pipes_struct
*p
,
2630 TALLOC_CTX
*mem_ctx
,
2631 struct samr_UserInfo18
*r
,
2632 struct dom_sid
*user_sid
)
2634 struct samu
*smbpass
=NULL
;
2636 const uint8_t *nt_pass
= NULL
;
2637 const uint8_t *lm_pass
= NULL
;
2641 if (p
->transport
!= NCALRPC
) {
2642 return NT_STATUS_INVALID_INFO_CLASS
;
2645 if (!security_token_is_system(p
->session_info
->security_token
)) {
2646 return NT_STATUS_ACCESS_DENIED
;
2650 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2653 if ( !(smbpass
= samu_new( mem_ctx
)) ) {
2654 return NT_STATUS_NO_MEMORY
;
2657 ret
= pdb_getsampwsid(smbpass
, user_sid
);
2660 struct dom_sid_buf buf
;
2661 DEBUG(4, ("User %s not found\n",
2662 dom_sid_str_buf(user_sid
, &buf
)));
2663 TALLOC_FREE(smbpass
);
2664 return root_mode() ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
2667 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
2669 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
2670 TALLOC_FREE(smbpass
);
2671 return NT_STATUS_ACCOUNT_DISABLED
;
2674 lm_pass
= pdb_get_lanman_passwd(smbpass
);
2675 if (lm_pass
!= NULL
) {
2676 memcpy(r
->lm_pwd
.hash
, lm_pass
, 16);
2677 r
->lm_pwd_active
= true;
2680 nt_pass
= pdb_get_nt_passwd(smbpass
);
2681 if (nt_pass
!= NULL
) {
2682 memcpy(r
->nt_pwd
.hash
, nt_pass
, 16);
2683 r
->nt_pwd_active
= true;
2685 r
->password_expired
= 0; /* FIXME */
2687 TALLOC_FREE(smbpass
);
2689 return NT_STATUS_OK
;
2692 /*************************************************************************
2694 *************************************************************************/
2696 static NTSTATUS
get_user_info_20(TALLOC_CTX
*mem_ctx
,
2697 struct samr_UserInfo20
*r
,
2698 struct samu
*sampass
)
2700 const char *munged_dial
= NULL
;
2703 struct lsa_BinaryString
*parameters
= NULL
;
2707 munged_dial
= pdb_get_munged_dial(sampass
);
2709 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass
),
2710 munged_dial
, (int)strlen(munged_dial
)));
2713 blob
= base64_decode_data_blob(munged_dial
);
2715 blob
= data_blob_string_const_null("");
2718 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2719 data_blob_free(&blob
);
2720 if (!NT_STATUS_IS_OK(status
)) {
2724 r
->parameters
= *parameters
;
2726 return NT_STATUS_OK
;
2730 /*************************************************************************
2732 *************************************************************************/
2734 static NTSTATUS
get_user_info_21(TALLOC_CTX
*mem_ctx
,
2735 struct samr_UserInfo21
*r
,
2737 struct dom_sid
*domain_sid
,
2738 uint32_t acc_granted
)
2741 const struct dom_sid
*sid_user
, *sid_group
;
2742 uint32_t rid
, primary_gid
;
2743 NTTIME force_password_change
;
2744 time_t must_change_time
;
2745 struct lsa_BinaryString
*parameters
= NULL
;
2746 const char *munged_dial
= NULL
;
2748 struct dom_sid_buf buf1
, buf2
;
2752 sid_user
= pdb_get_user_sid(pw
);
2754 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2755 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2756 "the domain sid %s. Failing operation.\n",
2757 pdb_get_username(pw
),
2758 dom_sid_str_buf(sid_user
, &buf1
),
2759 dom_sid_str_buf(domain_sid
, &buf2
)));
2760 return NT_STATUS_UNSUCCESSFUL
;
2764 sid_group
= pdb_get_group_sid(pw
);
2767 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2768 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2769 "which conflicts with the domain sid %s. Failing operation.\n",
2770 pdb_get_username(pw
),
2771 dom_sid_str_buf(sid_group
, &buf1
),
2772 dom_sid_str_buf(domain_sid
, &buf2
)));
2773 return NT_STATUS_UNSUCCESSFUL
;
2776 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2777 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2778 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2779 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2780 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2782 must_change_time
= pdb_get_pass_must_change_time(pw
);
2783 if (pdb_is_password_change_time_max(must_change_time
)) {
2784 unix_to_nt_time_abs(&force_password_change
, must_change_time
);
2786 unix_to_nt_time(&force_password_change
, must_change_time
);
2789 munged_dial
= pdb_get_munged_dial(pw
);
2791 blob
= base64_decode_data_blob(munged_dial
);
2793 blob
= data_blob_string_const_null("");
2796 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2797 data_blob_free(&blob
);
2798 if (!NT_STATUS_IS_OK(status
)) {
2802 r
->force_password_change
= force_password_change
;
2804 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2805 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2806 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2807 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2808 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2809 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2810 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2811 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2812 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2814 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2815 r
->parameters
= *parameters
;
2817 r
->primary_gid
= primary_gid
;
2818 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2819 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2820 r
->logon_count
= pdb_get_logon_count(pw
);
2821 r
->fields_present
= pdb_build_fields_present(pw
);
2822 r
->password_expired
= (pdb_get_pass_must_change_time(pw
) == 0) ?
2823 PASS_MUST_CHANGE_AT_NEXT_LOGON
: 0;
2824 r
->country_code
= pdb_get_country_code(pw
);
2825 r
->code_page
= pdb_get_code_page(pw
);
2826 r
->lm_password_set
= 0;
2827 r
->nt_password_set
= 0;
2832 Look at a user on a real NT4 PDC with usrmgr, press
2833 'ok'. Then you will see that fields_present is set to
2834 0x08f827fa. Look at the user immediately after that again,
2835 and you will see that 0x00fffff is returned. This solves
2836 the problem that you get access denied after having looked
2844 return NT_STATUS_OK
;
2847 /*******************************************************************
2849 ********************************************************************/
2851 NTSTATUS
_samr_QueryUserInfo(struct pipes_struct
*p
,
2852 struct samr_QueryUserInfo
*r
)
2855 union samr_UserInfo
*user_info
= NULL
;
2856 struct samr_user_info
*uinfo
;
2857 struct dom_sid domain_sid
;
2860 struct samu
*pwd
= NULL
;
2861 uint32_t acc_required
, acc_granted
;
2862 struct dom_sid_buf buf
;
2864 switch (r
->in
.level
) {
2865 case 1: /* UserGeneralInformation */
2866 /* USER_READ_GENERAL */
2867 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
;
2869 case 2: /* UserPreferencesInformation */
2870 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2871 acc_required
= SAMR_USER_ACCESS_GET_LOCALE
|
2872 SAMR_USER_ACCESS_GET_NAME_ETC
;
2874 case 3: /* UserLogonInformation */
2875 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2876 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
|
2877 SAMR_USER_ACCESS_GET_LOCALE
|
2878 SAMR_USER_ACCESS_GET_LOGONINFO
|
2879 SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2881 case 4: /* UserLogonHoursInformation */
2882 /* USER_READ_LOGON */
2883 acc_required
= SAMR_USER_ACCESS_GET_LOGONINFO
;
2885 case 5: /* UserAccountInformation */
2886 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2887 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
|
2888 SAMR_USER_ACCESS_GET_LOCALE
|
2889 SAMR_USER_ACCESS_GET_LOGONINFO
|
2890 SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2892 case 6: /* UserNameInformation */
2893 case 7: /* UserAccountNameInformation */
2894 case 8: /* UserFullNameInformation */
2895 case 9: /* UserPrimaryGroupInformation */
2896 case 13: /* UserAdminCommentInformation */
2897 /* USER_READ_GENERAL */
2898 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
;
2900 case 10: /* UserHomeInformation */
2901 case 11: /* UserScriptInformation */
2902 case 12: /* UserProfileInformation */
2903 case 14: /* UserWorkStationsInformation */
2904 /* USER_READ_LOGON */
2905 acc_required
= SAMR_USER_ACCESS_GET_LOGONINFO
;
2907 case 16: /* UserControlInformation */
2908 case 17: /* UserExpiresInformation */
2909 case 20: /* UserParametersInformation */
2910 /* USER_READ_ACCOUNT */
2911 acc_required
= SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2913 case 21: /* UserAllInformation */
2915 acc_required
= SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2917 case 18: /* UserInternal1Information */
2919 acc_required
= SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2921 case 23: /* UserInternal4Information */
2922 case 24: /* UserInternal4InformationNew */
2923 case 25: /* UserInternal4InformationNew */
2924 case 26: /* UserInternal5InformationNew */
2926 return NT_STATUS_INVALID_INFO_CLASS
;
2930 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
2931 acc_required
, &acc_granted
,
2932 struct samr_user_info
, &status
);
2933 if (!NT_STATUS_IS_OK(status
)) {
2937 domain_sid
= uinfo
->sid
;
2939 sid_split_rid(&domain_sid
, &rid
);
2941 if (!sid_check_is_in_our_sam(&uinfo
->sid
))
2942 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
2944 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2945 dom_sid_str_buf(&uinfo
->sid
, &buf
)));
2947 user_info
= talloc_zero(p
->mem_ctx
, union samr_UserInfo
);
2949 return NT_STATUS_NO_MEMORY
;
2952 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r
->in
.level
));
2954 if (!(pwd
= samu_new(p
->mem_ctx
))) {
2955 return NT_STATUS_NO_MEMORY
;
2959 ret
= pdb_getsampwsid(pwd
, &uinfo
->sid
);
2963 DEBUG(4,("User %s not found\n",
2964 dom_sid_str_buf(&uinfo
->sid
, &buf
)));
2966 return NT_STATUS_NO_SUCH_USER
;
2969 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd
)));
2971 samr_clear_sam_passwd(pwd
);
2973 switch (r
->in
.level
) {
2975 status
= get_user_info_1(p
->mem_ctx
, &user_info
->info1
, pwd
, &domain_sid
);
2978 status
= get_user_info_2(p
->mem_ctx
, &user_info
->info2
, pwd
);
2981 status
= get_user_info_3(p
->mem_ctx
, &user_info
->info3
, pwd
, &domain_sid
);
2984 status
= get_user_info_4(p
->mem_ctx
, &user_info
->info4
, pwd
);
2987 status
= get_user_info_5(p
->mem_ctx
, &user_info
->info5
, pwd
, &domain_sid
);
2990 status
= get_user_info_6(p
->mem_ctx
, &user_info
->info6
, pwd
);
2993 status
= get_user_info_7(p
->mem_ctx
, &user_info
->info7
, pwd
);
2996 status
= get_user_info_8(p
->mem_ctx
, &user_info
->info8
, pwd
);
2999 status
= get_user_info_9(p
->mem_ctx
, &user_info
->info9
, pwd
);
3002 status
= get_user_info_10(p
->mem_ctx
, &user_info
->info10
, pwd
);
3005 status
= get_user_info_11(p
->mem_ctx
, &user_info
->info11
, pwd
);
3008 status
= get_user_info_12(p
->mem_ctx
, &user_info
->info12
, pwd
);
3011 status
= get_user_info_13(p
->mem_ctx
, &user_info
->info13
, pwd
);
3014 status
= get_user_info_14(p
->mem_ctx
, &user_info
->info14
, pwd
);
3017 status
= get_user_info_16(p
->mem_ctx
, &user_info
->info16
, pwd
);
3020 status
= get_user_info_17(p
->mem_ctx
, &user_info
->info17
, pwd
);
3023 /* level 18 is special */
3024 status
= get_user_info_18(p
, p
->mem_ctx
, &user_info
->info18
,
3028 status
= get_user_info_20(p
->mem_ctx
, &user_info
->info20
, pwd
);
3031 status
= get_user_info_21(p
->mem_ctx
, &user_info
->info21
, pwd
, &domain_sid
, acc_granted
);
3034 status
= NT_STATUS_INVALID_INFO_CLASS
;
3038 if (!NT_STATUS_IS_OK(status
)) {
3042 *r
->out
.info
= user_info
;
3047 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__
));
3052 /****************************************************************
3053 ****************************************************************/
3055 NTSTATUS
_samr_QueryUserInfo2(struct pipes_struct
*p
,
3056 struct samr_QueryUserInfo2
*r
)
3058 struct samr_QueryUserInfo u
;
3060 u
.in
.user_handle
= r
->in
.user_handle
;
3061 u
.in
.level
= r
->in
.level
;
3062 u
.out
.info
= r
->out
.info
;
3064 return _samr_QueryUserInfo(p
, &u
);
3067 /*******************************************************************
3068 _samr_GetGroupsForUser
3069 ********************************************************************/
3071 NTSTATUS
_samr_GetGroupsForUser(struct pipes_struct
*p
,
3072 struct samr_GetGroupsForUser
*r
)
3074 struct samr_user_info
*uinfo
;
3075 struct samu
*sam_pass
=NULL
;
3076 struct dom_sid
*sids
;
3077 struct samr_RidWithAttribute dom_gid
;
3078 struct samr_RidWithAttribute
*gids
= NULL
;
3079 uint32_t primary_group_rid
;
3080 uint32_t num_groups
= 0;
3082 uint32_t i
, num_gids
;
3085 bool success
= False
;
3086 struct dom_sid_buf buf
;
3088 struct samr_RidWithAttributeArray
*rids
= NULL
;
3091 * from the SID in the request:
3092 * we should send back the list of DOMAIN GROUPS
3093 * the user is a member of
3095 * and only the DOMAIN GROUPS
3096 * no ALIASES !!! neither aliases of the domain
3097 * nor aliases of the builtin SID
3102 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3104 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
3105 SAMR_USER_ACCESS_GET_GROUPS
, NULL
,
3106 struct samr_user_info
, &result
);
3107 if (!NT_STATUS_IS_OK(result
)) {
3111 rids
= talloc_zero(p
->mem_ctx
, struct samr_RidWithAttributeArray
);
3113 return NT_STATUS_NO_MEMORY
;
3116 if (!sid_check_is_in_our_sam(&uinfo
->sid
))
3117 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3119 if ( !(sam_pass
= samu_new( p
->mem_ctx
)) ) {
3120 return NT_STATUS_NO_MEMORY
;
3124 ret
= pdb_getsampwsid(sam_pass
, &uinfo
->sid
);
3128 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3129 dom_sid_str_buf(&uinfo
->sid
, &buf
)));
3130 return NT_STATUS_NO_SUCH_USER
;
3135 /* make both calls inside the root block */
3137 result
= pdb_enum_group_memberships(p
->mem_ctx
, sam_pass
,
3138 &sids
, &unix_gids
, &num_groups
);
3139 if ( NT_STATUS_IS_OK(result
) ) {
3140 success
= sid_peek_check_rid(get_global_sam_sid(),
3141 pdb_get_group_sid(sam_pass
),
3142 &primary_group_rid
);
3146 if (!NT_STATUS_IS_OK(result
)) {
3147 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3148 dom_sid_str_buf(&uinfo
->sid
, &buf
)));
3153 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3154 dom_sid_str_buf(pdb_get_group_sid(sam_pass
), &buf
),
3155 pdb_get_username(sam_pass
)));
3156 TALLOC_FREE(sam_pass
);
3157 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
3163 dom_gid
.attributes
= (SE_GROUP_MANDATORY
|SE_GROUP_ENABLED_BY_DEFAULT
|
3165 dom_gid
.rid
= primary_group_rid
;
3166 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3168 for (i
=0; i
<num_groups
; i
++) {
3170 if (!sid_peek_check_rid(get_global_sam_sid(),
3171 &(sids
[i
]), &dom_gid
.rid
)) {
3172 DEBUG(10, ("Found sid %s not in our domain\n",
3173 dom_sid_str_buf(&sids
[i
], &buf
)));
3177 if (dom_gid
.rid
== primary_group_rid
) {
3178 /* We added the primary group directly from the
3179 * sam_account. The other SIDs are unique from
3180 * enum_group_memberships */
3184 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3187 rids
->count
= num_gids
;
3190 *r
->out
.rids
= rids
;
3192 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3197 /*******************************************************************
3198 ********************************************************************/
3200 static uint32_t samr_get_server_role(void)
3202 uint32_t role
= ROLE_DOMAIN_PDC
;
3204 if (lp_server_role() == ROLE_DOMAIN_BDC
) {
3205 role
= ROLE_DOMAIN_BDC
;
3211 /*******************************************************************
3212 ********************************************************************/
3214 static NTSTATUS
query_dom_info_1(TALLOC_CTX
*mem_ctx
,
3215 struct samr_DomInfo1
*r
)
3217 uint32_t account_policy_temp
;
3218 time_t u_expire
, u_min_age
;
3224 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN
, &account_policy_temp
);
3225 r
->min_password_length
= account_policy_temp
;
3227 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &account_policy_temp
);
3228 r
->password_history_length
= account_policy_temp
;
3230 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS
,
3231 &r
->password_properties
);
3233 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE
, &account_policy_temp
);
3234 u_expire
= account_policy_temp
;
3236 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE
, &account_policy_temp
);
3237 u_min_age
= account_policy_temp
;
3243 unix_to_nt_time_abs((NTTIME
*)&r
->max_password_age
, u_expire
);
3244 unix_to_nt_time_abs((NTTIME
*)&r
->min_password_age
, u_min_age
);
3246 if (lp_check_password_script(talloc_tos()) && *lp_check_password_script(talloc_tos())) {
3247 r
->password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
3250 return NT_STATUS_OK
;
3253 /*******************************************************************
3254 ********************************************************************/
3256 static NTSTATUS
query_dom_info_2(TALLOC_CTX
*mem_ctx
,
3257 struct samr_DomGeneralInformation
*r
,
3258 struct samr_domain_info
*dinfo
)
3267 r
->num_users
= count_sam_users(dinfo
->disp_info
, ACB_NORMAL
);
3268 r
->num_groups
= count_sam_groups(dinfo
->disp_info
);
3269 r
->num_aliases
= count_sam_aliases(dinfo
->disp_info
);
3271 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT
, &u_logout
);
3273 unix_to_nt_time_abs(&r
->force_logoff_time
, u_logout
);
3275 if (!pdb_get_seq_num(&seq_num
)) {
3276 seq_num
= time(NULL
);
3283 r
->oem_information
.string
= lp_server_string(r
);
3284 r
->domain_name
.string
= lp_workgroup();
3285 r
->primary
.string
= lp_netbios_name();
3286 r
->sequence_num
= seq_num
;
3287 r
->domain_server_state
= DOMAIN_SERVER_ENABLED
;
3288 r
->role
= (enum samr_Role
) samr_get_server_role();
3291 return NT_STATUS_OK
;
3294 /*******************************************************************
3295 ********************************************************************/
3297 static NTSTATUS
query_dom_info_3(TALLOC_CTX
*mem_ctx
,
3298 struct samr_DomInfo3
*r
)
3308 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT
, &ul
);
3309 u_logout
= (time_t)ul
;
3316 unix_to_nt_time_abs(&r
->force_logoff_time
, u_logout
);
3318 return NT_STATUS_OK
;
3321 /*******************************************************************
3322 ********************************************************************/
3324 static NTSTATUS
query_dom_info_4(TALLOC_CTX
*mem_ctx
,
3325 struct samr_DomOEMInformation
*r
)
3327 r
->oem_information
.string
= lp_server_string(r
);
3329 return NT_STATUS_OK
;
3332 /*******************************************************************
3333 ********************************************************************/
3335 static NTSTATUS
query_dom_info_5(TALLOC_CTX
*mem_ctx
,
3336 struct samr_DomInfo5
*r
)
3338 r
->domain_name
.string
= get_global_sam_name();
3340 return NT_STATUS_OK
;
3343 /*******************************************************************
3344 ********************************************************************/
3346 static NTSTATUS
query_dom_info_6(TALLOC_CTX
*mem_ctx
,
3347 struct samr_DomInfo6
*r
)
3349 /* NT returns its own name when a PDC. win2k and later
3350 * only the name of the PDC if itself is a BDC (samba4
3352 r
->primary
.string
= lp_netbios_name();
3354 return NT_STATUS_OK
;
3357 /*******************************************************************
3358 ********************************************************************/
3360 static NTSTATUS
query_dom_info_7(TALLOC_CTX
*mem_ctx
,
3361 struct samr_DomInfo7
*r
)
3363 r
->role
= (enum samr_Role
) samr_get_server_role();
3365 return NT_STATUS_OK
;
3368 /*******************************************************************
3369 ********************************************************************/
3371 static NTSTATUS
query_dom_info_8(TALLOC_CTX
*mem_ctx
,
3372 struct samr_DomInfo8
*r
)
3380 if (!pdb_get_seq_num(&seq_num
)) {
3381 seq_num
= time(NULL
);
3388 r
->sequence_num
= seq_num
;
3389 r
->domain_create_time
= 0;
3391 return NT_STATUS_OK
;
3394 /*******************************************************************
3395 ********************************************************************/
3397 static NTSTATUS
query_dom_info_9(TALLOC_CTX
*mem_ctx
,
3398 struct samr_DomInfo9
*r
)
3400 r
->domain_server_state
= DOMAIN_SERVER_ENABLED
;
3402 return NT_STATUS_OK
;
3405 /*******************************************************************
3406 ********************************************************************/
3408 static NTSTATUS
query_dom_info_11(TALLOC_CTX
*mem_ctx
,
3409 struct samr_DomGeneralInformation2
*r
,
3410 struct samr_domain_info
*dinfo
)
3413 uint32_t account_policy_temp
;
3414 time_t u_lock_duration
, u_reset_time
;
3416 status
= query_dom_info_2(mem_ctx
, &r
->general
, dinfo
);
3417 if (!NT_STATUS_IS_OK(status
)) {
3425 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
3426 u_lock_duration
= account_policy_temp
;
3427 if (u_lock_duration
!= -1) {
3428 u_lock_duration
*= 60;
3431 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME
, &account_policy_temp
);
3432 u_reset_time
= account_policy_temp
* 60;
3434 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
3435 r
->lockout_threshold
= account_policy_temp
;
3441 unix_to_nt_time_abs(&r
->lockout_duration
, u_lock_duration
);
3442 unix_to_nt_time_abs(&r
->lockout_window
, u_reset_time
);
3444 return NT_STATUS_OK
;
3447 /*******************************************************************
3448 ********************************************************************/
3450 static NTSTATUS
query_dom_info_12(TALLOC_CTX
*mem_ctx
,
3451 struct samr_DomInfo12
*r
)
3453 uint32_t account_policy_temp
;
3454 time_t u_lock_duration
, u_reset_time
;
3460 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
3461 u_lock_duration
= account_policy_temp
;
3462 if (u_lock_duration
!= -1) {
3463 u_lock_duration
*= 60;
3466 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME
, &account_policy_temp
);
3467 u_reset_time
= account_policy_temp
* 60;
3469 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
3470 r
->lockout_threshold
= account_policy_temp
;
3476 unix_to_nt_time_abs(&r
->lockout_duration
, u_lock_duration
);
3477 unix_to_nt_time_abs(&r
->lockout_window
, u_reset_time
);
3479 return NT_STATUS_OK
;
3482 /*******************************************************************
3483 ********************************************************************/
3485 static NTSTATUS
query_dom_info_13(TALLOC_CTX
*mem_ctx
,
3486 struct samr_DomInfo13
*r
)
3494 if (!pdb_get_seq_num(&seq_num
)) {
3495 seq_num
= time(NULL
);
3502 r
->sequence_num
= seq_num
;
3503 r
->domain_create_time
= 0;
3504 r
->modified_count_at_last_promotion
= 0;
3506 return NT_STATUS_OK
;
3509 /*******************************************************************
3510 _samr_QueryDomainInfo
3511 ********************************************************************/
3513 NTSTATUS
_samr_QueryDomainInfo(struct pipes_struct
*p
,
3514 struct samr_QueryDomainInfo
*r
)
3516 NTSTATUS status
= NT_STATUS_OK
;
3517 struct samr_domain_info
*dinfo
;
3518 union samr_DomainInfo
*dom_info
;
3520 uint32_t acc_required
;
3522 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3524 switch (r
->in
.level
) {
3525 case 1: /* DomainPasswordInformation */
3526 case 12: /* DomainLockoutInformation */
3527 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3528 acc_required
= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
;
3530 case 11: /* DomainGeneralInformation2 */
3531 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3532 * DOMAIN_READ_OTHER_PARAMETERS */
3533 acc_required
= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
3534 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
3536 case 2: /* DomainGeneralInformation */
3537 case 3: /* DomainLogoffInformation */
3538 case 4: /* DomainOemInformation */
3539 case 5: /* DomainReplicationInformation */
3540 case 6: /* DomainReplicationInformation */
3541 case 7: /* DomainServerRoleInformation */
3542 case 8: /* DomainModifiedInformation */
3543 case 9: /* DomainStateInformation */
3544 case 10: /* DomainUasInformation */
3545 case 13: /* DomainModifiedInformation2 */
3546 /* DOMAIN_READ_OTHER_PARAMETERS */
3547 acc_required
= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
3550 return NT_STATUS_INVALID_INFO_CLASS
;
3553 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
3555 struct samr_domain_info
, &status
);
3556 if (!NT_STATUS_IS_OK(status
)) {
3560 dom_info
= talloc_zero(p
->mem_ctx
, union samr_DomainInfo
);
3562 return NT_STATUS_NO_MEMORY
;
3565 switch (r
->in
.level
) {
3567 status
= query_dom_info_1(p
->mem_ctx
, &dom_info
->info1
);
3570 status
= query_dom_info_2(p
->mem_ctx
, &dom_info
->general
, dinfo
);
3573 status
= query_dom_info_3(p
->mem_ctx
, &dom_info
->info3
);
3576 status
= query_dom_info_4(p
->mem_ctx
, &dom_info
->oem
);
3579 status
= query_dom_info_5(p
->mem_ctx
, &dom_info
->info5
);
3582 status
= query_dom_info_6(p
->mem_ctx
, &dom_info
->info6
);
3585 status
= query_dom_info_7(p
->mem_ctx
, &dom_info
->info7
);
3588 status
= query_dom_info_8(p
->mem_ctx
, &dom_info
->info8
);
3591 status
= query_dom_info_9(p
->mem_ctx
, &dom_info
->info9
);
3594 status
= query_dom_info_11(p
->mem_ctx
, &dom_info
->general2
, dinfo
);
3597 status
= query_dom_info_12(p
->mem_ctx
, &dom_info
->info12
);
3600 status
= query_dom_info_13(p
->mem_ctx
, &dom_info
->info13
);
3603 return NT_STATUS_INVALID_INFO_CLASS
;
3606 if (!NT_STATUS_IS_OK(status
)) {
3610 *r
->out
.info
= dom_info
;
3612 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3617 /* W2k3 seems to use the same check for all 3 objects that can be created via
3618 * SAMR, if you try to create for example "Dialup" as an alias it says
3619 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3622 static NTSTATUS
can_create(TALLOC_CTX
*mem_ctx
, const char *new_name
)
3624 enum lsa_SidType type
;
3627 DEBUG(10, ("Checking whether [%s] can be created\n", new_name
));
3630 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3631 * whether the name already exists */
3632 result
= lookup_name(mem_ctx
, new_name
, LOOKUP_NAME_LOCAL
,
3633 NULL
, NULL
, NULL
, &type
);
3637 DEBUG(10, ("%s does not exist, can create it\n", new_name
));
3638 return NT_STATUS_OK
;
3641 DEBUG(5, ("trying to create %s, exists as %s\n",
3642 new_name
, sid_type_lookup(type
)));
3644 if (type
== SID_NAME_DOM_GRP
) {
3645 return NT_STATUS_GROUP_EXISTS
;
3647 if (type
== SID_NAME_ALIAS
) {
3648 return NT_STATUS_ALIAS_EXISTS
;
3651 /* Yes, the default is NT_STATUS_USER_EXISTS */
3652 return NT_STATUS_USER_EXISTS
;
3655 /*******************************************************************
3657 ********************************************************************/
3659 NTSTATUS
_samr_CreateUser2(struct pipes_struct
*p
,
3660 struct samr_CreateUser2
*r
)
3662 const char *account
= NULL
;
3664 uint32_t acb_info
= r
->in
.acct_flags
;
3665 struct samr_domain_info
*dinfo
;
3666 struct samr_user_info
*uinfo
;
3668 uint32_t acc_granted
;
3669 struct security_descriptor
*psd
;
3671 /* check this, when giving away 'add computer to domain' privs */
3672 uint32_t des_access
= GENERIC_RIGHTS_USER_ALL_ACCESS
;
3673 bool can_add_account
= False
;
3675 /* Which privilege is needed to override the ACL? */
3676 enum sec_privilege needed_priv
= SEC_PRIV_INVALID
;
3678 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
3679 SAMR_DOMAIN_ACCESS_CREATE_USER
, NULL
,
3680 struct samr_domain_info
, &nt_status
);
3681 if (!NT_STATUS_IS_OK(nt_status
)) {
3685 if (sid_check_is_builtin(&dinfo
->sid
)) {
3686 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3687 return NT_STATUS_ACCESS_DENIED
;
3690 if (!(acb_info
== ACB_NORMAL
|| acb_info
== ACB_DOMTRUST
||
3691 acb_info
== ACB_WSTRUST
|| acb_info
== ACB_SVRTRUST
)) {
3692 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3693 this parameter is not an account type */
3694 return NT_STATUS_INVALID_PARAMETER
;
3697 account
= r
->in
.account_name
->string
;
3698 if (account
== NULL
) {
3699 return NT_STATUS_NO_MEMORY
;
3702 nt_status
= can_create(p
->mem_ctx
, account
);
3703 if (!NT_STATUS_IS_OK(nt_status
)) {
3707 /* determine which user right we need to check based on the acb_info */
3710 can_add_account
= true;
3711 } else if (acb_info
& ACB_WSTRUST
) {
3712 needed_priv
= SEC_PRIV_MACHINE_ACCOUNT
;
3713 can_add_account
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_MACHINE_ACCOUNT
);
3714 } else if (acb_info
& ACB_NORMAL
&&
3715 (account
[strlen(account
)-1] != '$')) {
3716 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3717 account for domain trusts and changes the ACB flags later */
3718 needed_priv
= SEC_PRIV_ADD_USERS
;
3719 can_add_account
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_ADD_USERS
);
3720 } else if (lp_enable_privileges()) {
3721 /* implicit assumption of a BDC or domain trust account here
3722 * (we already check the flags earlier) */
3723 /* only Domain Admins can add a BDC or domain trust */
3724 can_add_account
= nt_token_check_domain_rid(
3725 p
->session_info
->security_token
,
3726 DOMAIN_RID_ADMINS
);
3729 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3730 uidtoname(p
->session_info
->unix_token
->uid
),
3731 can_add_account
? "True":"False" ));
3733 if (!can_add_account
) {
3734 return NT_STATUS_ACCESS_DENIED
;
3737 /********** BEGIN Admin BLOCK **********/
3740 nt_status
= pdb_create_user(p
->mem_ctx
, account
, acb_info
,
3744 /********** END Admin BLOCK **********/
3746 /* now check for failure */
3748 if ( !NT_STATUS_IS_OK(nt_status
) )
3751 /* Get the user's SID */
3753 sid_compose(&sid
, get_global_sam_sid(), *r
->out
.rid
);
3755 map_max_allowed_access(p
->session_info
->security_token
,
3756 p
->session_info
->unix_token
,
3759 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
,
3760 &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
3761 se_map_generic(&des_access
, &usr_generic_mapping
);
3764 * JRA - TESTME. We just created this user so we
3765 * had rights to create them. Do we need to check
3766 * any further access on this object ? Can't we
3767 * just assume we have all the rights we need ?
3770 nt_status
= access_check_object(psd
, p
->session_info
->security_token
,
3771 needed_priv
, SEC_PRIV_INVALID
,
3772 GENERIC_RIGHTS_USER_WRITE
, des_access
,
3773 &acc_granted
, "_samr_CreateUser2");
3775 if ( !NT_STATUS_IS_OK(nt_status
) ) {
3779 uinfo
= policy_handle_create(p
, r
->out
.user_handle
, acc_granted
,
3780 struct samr_user_info
, &nt_status
);
3781 if (!NT_STATUS_IS_OK(nt_status
)) {
3786 /* After a "set" ensure we have no cached display info. */
3787 force_flush_samr_cache(&sid
);
3789 *r
->out
.access_granted
= acc_granted
;
3791 return NT_STATUS_OK
;
3794 /****************************************************************
3795 ****************************************************************/
3797 NTSTATUS
_samr_CreateUser(struct pipes_struct
*p
,
3798 struct samr_CreateUser
*r
)
3800 struct samr_CreateUser2 c
;
3801 uint32_t access_granted
;
3803 c
.in
.domain_handle
= r
->in
.domain_handle
;
3804 c
.in
.account_name
= r
->in
.account_name
;
3805 c
.in
.acct_flags
= ACB_NORMAL
;
3806 c
.in
.access_mask
= r
->in
.access_mask
;
3807 c
.out
.user_handle
= r
->out
.user_handle
;
3808 c
.out
.access_granted
= &access_granted
;
3809 c
.out
.rid
= r
->out
.rid
;
3811 return _samr_CreateUser2(p
, &c
);
3814 /*******************************************************************
3816 ********************************************************************/
3818 NTSTATUS
_samr_Connect(struct pipes_struct
*p
,
3819 struct samr_Connect
*r
)
3821 uint32_t acc_granted
;
3822 struct policy_handle hnd
;
3823 uint32_t des_access
= r
->in
.access_mask
;
3828 if (!pipe_access_check(p
)) {
3829 DEBUG(3, ("access denied to _samr_Connect\n"));
3830 return NT_STATUS_ACCESS_DENIED
;
3833 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3834 was observed from a win98 client trying to enumerate users (when configured
3835 user level access control on shares) --jerry */
3837 map_max_allowed_access(p
->session_info
->security_token
,
3838 p
->session_info
->unix_token
,
3841 se_map_generic( &des_access
, &sam_generic_mapping
);
3843 acc_granted
= des_access
& (SAMR_ACCESS_ENUM_DOMAINS
3844 |SAMR_ACCESS_LOOKUP_DOMAIN
);
3846 /* set up the SAMR connect_anon response */
3848 (void)policy_handle_create(p
, &hnd
, acc_granted
,
3849 struct samr_connect_info
,
3851 if (!NT_STATUS_IS_OK(status
)) {
3855 *r
->out
.connect_handle
= hnd
;
3856 return NT_STATUS_OK
;
3859 /*******************************************************************
3861 ********************************************************************/
3863 NTSTATUS
_samr_Connect2(struct pipes_struct
*p
,
3864 struct samr_Connect2
*r
)
3866 struct policy_handle hnd
;
3867 struct security_descriptor
*psd
= NULL
;
3868 uint32_t acc_granted
;
3869 uint32_t des_access
= r
->in
.access_mask
;
3872 const char *fn
= "_samr_Connect2";
3875 case NDR_SAMR_CONNECT2
:
3876 fn
= "_samr_Connect2";
3878 case NDR_SAMR_CONNECT3
:
3879 fn
= "_samr_Connect3";
3881 case NDR_SAMR_CONNECT4
:
3882 fn
= "_samr_Connect4";
3884 case NDR_SAMR_CONNECT5
:
3885 fn
= "_samr_Connect5";
3889 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3893 if (!pipe_access_check(p
)) {
3894 DEBUG(3, ("access denied to %s\n", fn
));
3895 return NT_STATUS_ACCESS_DENIED
;
3898 map_max_allowed_access(p
->session_info
->security_token
,
3899 p
->session_info
->unix_token
,
3902 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
3903 se_map_generic(&des_access
, &sam_generic_mapping
);
3905 nt_status
= access_check_object(psd
, p
->session_info
->security_token
,
3906 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
,
3907 0, des_access
, &acc_granted
, fn
);
3909 if ( !NT_STATUS_IS_OK(nt_status
) )
3912 (void)policy_handle_create(p
, &hnd
, acc_granted
,
3913 struct samr_connect_info
, &nt_status
);
3914 if (!NT_STATUS_IS_OK(nt_status
)) {
3918 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3920 *r
->out
.connect_handle
= hnd
;
3921 return NT_STATUS_OK
;
3924 /****************************************************************
3926 ****************************************************************/
3928 NTSTATUS
_samr_Connect3(struct pipes_struct
*p
,
3929 struct samr_Connect3
*r
)
3931 struct samr_Connect2 c
;
3933 c
.in
.system_name
= r
->in
.system_name
;
3934 c
.in
.access_mask
= r
->in
.access_mask
;
3935 c
.out
.connect_handle
= r
->out
.connect_handle
;
3937 return _samr_Connect2(p
, &c
);
3940 /*******************************************************************
3942 ********************************************************************/
3944 NTSTATUS
_samr_Connect4(struct pipes_struct
*p
,
3945 struct samr_Connect4
*r
)
3947 struct samr_Connect2 c
;
3949 c
.in
.system_name
= r
->in
.system_name
;
3950 c
.in
.access_mask
= r
->in
.access_mask
;
3951 c
.out
.connect_handle
= r
->out
.connect_handle
;
3953 return _samr_Connect2(p
, &c
);
3956 /*******************************************************************
3958 ********************************************************************/
3960 NTSTATUS
_samr_Connect5(struct pipes_struct
*p
,
3961 struct samr_Connect5
*r
)
3964 struct samr_Connect2 c
;
3965 struct samr_ConnectInfo1 info1
;
3967 info1
.client_version
= SAMR_CONNECT_AFTER_W2K
;
3970 c
.in
.system_name
= r
->in
.system_name
;
3971 c
.in
.access_mask
= r
->in
.access_mask
;
3972 c
.out
.connect_handle
= r
->out
.connect_handle
;
3974 *r
->out
.level_out
= 1;
3976 status
= _samr_Connect2(p
, &c
);
3977 if (!NT_STATUS_IS_OK(status
)) {
3981 r
->out
.info_out
->info1
= info1
;
3983 return NT_STATUS_OK
;
3986 /**********************************************************************
3988 **********************************************************************/
3990 NTSTATUS
_samr_LookupDomain(struct pipes_struct
*p
,
3991 struct samr_LookupDomain
*r
)
3994 const char *domain_name
;
3995 struct dom_sid
*sid
= NULL
;
3996 struct dom_sid_buf buf
;
3998 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3999 Reverted that change so we will work with RAS servers again */
4001 (void)policy_handle_find(p
, r
->in
.connect_handle
,
4002 SAMR_ACCESS_LOOKUP_DOMAIN
, NULL
,
4003 struct samr_connect_info
,
4005 if (!NT_STATUS_IS_OK(status
)) {
4009 domain_name
= r
->in
.domain_name
->string
;
4011 return NT_STATUS_INVALID_PARAMETER
;
4014 sid
= talloc_zero(p
->mem_ctx
, struct dom_sid2
);
4016 return NT_STATUS_NO_MEMORY
;
4019 if (strequal(domain_name
, builtin_domain_name())) {
4020 sid_copy(sid
, &global_sid_Builtin
);
4022 if (!secrets_fetch_domain_sid(domain_name
, sid
)) {
4023 status
= NT_STATUS_NO_SUCH_DOMAIN
;
4027 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
,
4028 dom_sid_str_buf(sid
, &buf
)));
4035 /**********************************************************************
4037 **********************************************************************/
4039 NTSTATUS
_samr_EnumDomains(struct pipes_struct
*p
,
4040 struct samr_EnumDomains
*r
)
4043 uint32_t num_entries
= 2;
4044 struct samr_SamEntry
*entry_array
= NULL
;
4045 struct samr_SamArray
*sam
;
4047 (void)policy_handle_find(p
, r
->in
.connect_handle
,
4048 SAMR_ACCESS_ENUM_DOMAINS
, NULL
,
4049 struct samr_connect_info
, &status
);
4050 if (!NT_STATUS_IS_OK(status
)) {
4054 sam
= talloc_zero(p
->mem_ctx
, struct samr_SamArray
);
4056 return NT_STATUS_NO_MEMORY
;
4059 entry_array
= talloc_zero_array(p
->mem_ctx
,
4060 struct samr_SamEntry
,
4063 return NT_STATUS_NO_MEMORY
;
4066 entry_array
[0].idx
= 0;
4067 init_lsa_String(&entry_array
[0].name
, get_global_sam_name());
4069 entry_array
[1].idx
= 1;
4070 init_lsa_String(&entry_array
[1].name
, "Builtin");
4072 sam
->count
= num_entries
;
4073 sam
->entries
= entry_array
;
4076 *r
->out
.num_entries
= num_entries
;
4081 /*******************************************************************
4083 ********************************************************************/
4085 NTSTATUS
_samr_OpenAlias(struct pipes_struct
*p
,
4086 struct samr_OpenAlias
*r
)
4089 uint32_t alias_rid
= r
->in
.rid
;
4090 struct samr_alias_info
*ainfo
;
4091 struct samr_domain_info
*dinfo
;
4092 struct security_descriptor
*psd
= NULL
;
4093 uint32_t acc_granted
;
4094 uint32_t des_access
= r
->in
.access_mask
;
4098 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
4099 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
4100 struct samr_domain_info
, &status
);
4101 if (!NT_STATUS_IS_OK(status
)) {
4105 /* append the alias' RID to it */
4107 if (!sid_compose(&sid
, &dinfo
->sid
, alias_rid
))
4108 return NT_STATUS_NO_SUCH_ALIAS
;
4110 /*check if access can be granted as requested by client. */
4112 map_max_allowed_access(p
->session_info
->security_token
,
4113 p
->session_info
->unix_token
,
4116 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &ali_generic_mapping
, NULL
, 0);
4117 se_map_generic(&des_access
,&ali_generic_mapping
);
4119 status
= access_check_object(psd
, p
->session_info
->security_token
,
4120 SEC_PRIV_ADD_USERS
, SEC_PRIV_INVALID
,
4121 GENERIC_RIGHTS_ALIAS_ALL_ACCESS
,
4122 des_access
, &acc_granted
, "_samr_OpenAlias");
4124 if ( !NT_STATUS_IS_OK(status
) )
4128 /* Check we actually have the requested alias */
4129 enum lsa_SidType type
;
4134 result
= lookup_sid(NULL
, &sid
, NULL
, NULL
, &type
);
4137 if (!result
|| (type
!= SID_NAME_ALIAS
)) {
4138 return NT_STATUS_NO_SUCH_ALIAS
;
4141 /* make sure there is a mapping */
4143 if ( !sid_to_gid( &sid
, &gid
) ) {
4144 return NT_STATUS_NO_SUCH_ALIAS
;
4149 ainfo
= policy_handle_create(p
, r
->out
.alias_handle
, acc_granted
,
4150 struct samr_alias_info
, &status
);
4151 if (!NT_STATUS_IS_OK(status
)) {
4156 return NT_STATUS_OK
;
4159 /*******************************************************************
4161 ********************************************************************/
4163 static NTSTATUS
set_user_info_2(TALLOC_CTX
*mem_ctx
,
4164 struct samr_UserInfo2
*id2
,
4168 DEBUG(5,("set_user_info_2: NULL id2\n"));
4169 return NT_STATUS_ACCESS_DENIED
;
4172 copy_id2_to_sam_passwd(pwd
, id2
);
4174 return pdb_update_sam_account(pwd
);
4177 /*******************************************************************
4179 ********************************************************************/
4181 static NTSTATUS
set_user_info_4(TALLOC_CTX
*mem_ctx
,
4182 struct samr_UserInfo4
*id4
,
4186 DEBUG(5,("set_user_info_2: NULL id4\n"));
4187 return NT_STATUS_ACCESS_DENIED
;
4190 copy_id4_to_sam_passwd(pwd
, id4
);
4192 return pdb_update_sam_account(pwd
);
4195 /*******************************************************************
4197 ********************************************************************/
4199 static NTSTATUS
set_user_info_6(TALLOC_CTX
*mem_ctx
,
4200 struct samr_UserInfo6
*id6
,
4204 DEBUG(5,("set_user_info_6: NULL id6\n"));
4205 return NT_STATUS_ACCESS_DENIED
;
4208 copy_id6_to_sam_passwd(pwd
, id6
);
4210 return pdb_update_sam_account(pwd
);
4213 /*******************************************************************
4215 ********************************************************************/
4217 static NTSTATUS
set_user_info_7(TALLOC_CTX
*mem_ctx
,
4218 struct samr_UserInfo7
*id7
,
4224 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4225 return NT_STATUS_ACCESS_DENIED
;
4228 if (!id7
->account_name
.string
) {
4229 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4230 return NT_STATUS_ACCESS_DENIED
;
4233 /* check to see if the new username already exists. Note: we can't
4234 reliably lock all backends, so there is potentially the
4235 possibility that a user can be created in between this check and
4236 the rename. The rename should fail, but may not get the
4237 exact same failure status code. I think this is small enough
4238 of a window for this type of operation and the results are
4239 simply that the rename fails with a slightly different status
4240 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4242 rc
= can_create(mem_ctx
, id7
->account_name
.string
);
4244 /* when there is nothing to change, we're done here */
4245 if (NT_STATUS_EQUAL(rc
, NT_STATUS_USER_EXISTS
) &&
4246 strequal(id7
->account_name
.string
, pdb_get_username(pwd
))) {
4247 return NT_STATUS_OK
;
4249 if (!NT_STATUS_IS_OK(rc
)) {
4253 rc
= pdb_rename_sam_account(pwd
, id7
->account_name
.string
);
4258 /*******************************************************************
4260 ********************************************************************/
4262 static NTSTATUS
set_user_info_8(TALLOC_CTX
*mem_ctx
,
4263 struct samr_UserInfo8
*id8
,
4267 DEBUG(5,("set_user_info_8: NULL id8\n"));
4268 return NT_STATUS_ACCESS_DENIED
;
4271 copy_id8_to_sam_passwd(pwd
, id8
);
4273 return pdb_update_sam_account(pwd
);
4276 /*******************************************************************
4278 ********************************************************************/
4280 static NTSTATUS
set_user_info_10(TALLOC_CTX
*mem_ctx
,
4281 struct samr_UserInfo10
*id10
,
4285 DEBUG(5,("set_user_info_8: NULL id10\n"));
4286 return NT_STATUS_ACCESS_DENIED
;
4289 copy_id10_to_sam_passwd(pwd
, id10
);
4291 return pdb_update_sam_account(pwd
);
4294 /*******************************************************************
4296 ********************************************************************/
4298 static NTSTATUS
set_user_info_11(TALLOC_CTX
*mem_ctx
,
4299 struct samr_UserInfo11
*id11
,
4303 DEBUG(5,("set_user_info_11: NULL id11\n"));
4304 return NT_STATUS_ACCESS_DENIED
;
4307 copy_id11_to_sam_passwd(pwd
, id11
);
4309 return pdb_update_sam_account(pwd
);
4312 /*******************************************************************
4314 ********************************************************************/
4316 static NTSTATUS
set_user_info_12(TALLOC_CTX
*mem_ctx
,
4317 struct samr_UserInfo12
*id12
,
4321 DEBUG(5,("set_user_info_12: NULL id12\n"));
4322 return NT_STATUS_ACCESS_DENIED
;
4325 copy_id12_to_sam_passwd(pwd
, id12
);
4327 return pdb_update_sam_account(pwd
);
4330 /*******************************************************************
4332 ********************************************************************/
4334 static NTSTATUS
set_user_info_13(TALLOC_CTX
*mem_ctx
,
4335 struct samr_UserInfo13
*id13
,
4339 DEBUG(5,("set_user_info_13: NULL id13\n"));
4340 return NT_STATUS_ACCESS_DENIED
;
4343 copy_id13_to_sam_passwd(pwd
, id13
);
4345 return pdb_update_sam_account(pwd
);
4348 /*******************************************************************
4350 ********************************************************************/
4352 static NTSTATUS
set_user_info_14(TALLOC_CTX
*mem_ctx
,
4353 struct samr_UserInfo14
*id14
,
4357 DEBUG(5,("set_user_info_14: NULL id14\n"));
4358 return NT_STATUS_ACCESS_DENIED
;
4361 copy_id14_to_sam_passwd(pwd
, id14
);
4363 return pdb_update_sam_account(pwd
);
4366 /*******************************************************************
4368 ********************************************************************/
4370 static NTSTATUS
set_user_info_16(TALLOC_CTX
*mem_ctx
,
4371 struct samr_UserInfo16
*id16
,
4375 DEBUG(5,("set_user_info_16: NULL id16\n"));
4376 return NT_STATUS_ACCESS_DENIED
;
4379 copy_id16_to_sam_passwd(pwd
, id16
);
4381 return pdb_update_sam_account(pwd
);
4384 /*******************************************************************
4386 ********************************************************************/
4388 static NTSTATUS
set_user_info_17(TALLOC_CTX
*mem_ctx
,
4389 struct samr_UserInfo17
*id17
,
4393 DEBUG(5,("set_user_info_17: NULL id17\n"));
4394 return NT_STATUS_ACCESS_DENIED
;
4397 copy_id17_to_sam_passwd(pwd
, id17
);
4399 return pdb_update_sam_account(pwd
);
4402 /*******************************************************************
4404 ********************************************************************/
4406 static NTSTATUS
set_user_info_18(struct samr_UserInfo18
*id18
,
4407 TALLOC_CTX
*mem_ctx
,
4408 DATA_BLOB
*session_key
,
4412 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4413 return NT_STATUS_INVALID_PARAMETER
;
4416 if (id18
->nt_pwd_active
|| id18
->lm_pwd_active
) {
4417 if (!session_key
->length
) {
4418 return NT_STATUS_NO_USER_SESSION_KEY
;
4422 if (id18
->nt_pwd_active
) {
4426 in
= data_blob_const(id18
->nt_pwd
.hash
, 16);
4427 out
= data_blob_talloc_zero(mem_ctx
, 16);
4429 sess_crypt_blob(&out
, &in
, session_key
, false);
4431 if (!pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4432 return NT_STATUS_ACCESS_DENIED
;
4435 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4438 if (id18
->lm_pwd_active
) {
4442 in
= data_blob_const(id18
->lm_pwd
.hash
, 16);
4443 out
= data_blob_talloc_zero(mem_ctx
, 16);
4445 sess_crypt_blob(&out
, &in
, session_key
, false);
4447 if (!pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4448 return NT_STATUS_ACCESS_DENIED
;
4451 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4454 copy_id18_to_sam_passwd(pwd
, id18
);
4456 return pdb_update_sam_account(pwd
);
4459 /*******************************************************************
4461 ********************************************************************/
4463 static NTSTATUS
set_user_info_20(TALLOC_CTX
*mem_ctx
,
4464 struct samr_UserInfo20
*id20
,
4468 DEBUG(5,("set_user_info_20: NULL id20\n"));
4469 return NT_STATUS_ACCESS_DENIED
;
4472 copy_id20_to_sam_passwd(pwd
, id20
);
4474 return pdb_update_sam_account(pwd
);
4477 /*******************************************************************
4479 ********************************************************************/
4481 static NTSTATUS
set_user_info_21(struct samr_UserInfo21
*id21
,
4482 TALLOC_CTX
*mem_ctx
,
4483 DATA_BLOB
*session_key
,
4489 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4490 return NT_STATUS_INVALID_PARAMETER
;
4493 if (id21
->fields_present
== 0) {
4494 return NT_STATUS_INVALID_PARAMETER
;
4497 if (id21
->fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4498 return NT_STATUS_ACCESS_DENIED
;
4501 if (id21
->fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
4502 if (id21
->nt_password_set
) {
4505 if ((id21
->nt_owf_password
.length
!= 16) ||
4506 (id21
->nt_owf_password
.size
!= 16)) {
4507 return NT_STATUS_INVALID_PARAMETER
;
4510 if (!session_key
->length
) {
4511 return NT_STATUS_NO_USER_SESSION_KEY
;
4514 in
= data_blob_const(id21
->nt_owf_password
.array
, 16);
4515 out
= data_blob_talloc_zero(mem_ctx
, 16);
4517 sess_crypt_blob(&out
, &in
, session_key
, false);
4519 pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
);
4520 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4524 if (id21
->fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4525 if (id21
->lm_password_set
) {
4528 if ((id21
->lm_owf_password
.length
!= 16) ||
4529 (id21
->lm_owf_password
.size
!= 16)) {
4530 return NT_STATUS_INVALID_PARAMETER
;
4533 if (!session_key
->length
) {
4534 return NT_STATUS_NO_USER_SESSION_KEY
;
4537 in
= data_blob_const(id21
->lm_owf_password
.array
, 16);
4538 out
= data_blob_talloc_zero(mem_ctx
, 16);
4540 sess_crypt_blob(&out
, &in
, session_key
, false);
4542 pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
);
4543 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4547 /* we need to separately check for an account rename first */
4549 if (id21
->account_name
.string
&&
4550 (!strequal(id21
->account_name
.string
, pdb_get_username(pwd
))))
4553 /* check to see if the new username already exists. Note: we can't
4554 reliably lock all backends, so there is potentially the
4555 possibility that a user can be created in between this check and
4556 the rename. The rename should fail, but may not get the
4557 exact same failure status code. I think this is small enough
4558 of a window for this type of operation and the results are
4559 simply that the rename fails with a slightly different status
4560 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4562 status
= can_create(mem_ctx
, id21
->account_name
.string
);
4563 if (!NT_STATUS_IS_OK(status
)) {
4567 status
= pdb_rename_sam_account(pwd
, id21
->account_name
.string
);
4569 if (!NT_STATUS_IS_OK(status
)) {
4570 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4571 nt_errstr(status
)));
4575 /* set the new username so that later
4576 functions can work on the new account */
4577 pdb_set_username(pwd
, id21
->account_name
.string
, PDB_SET
);
4580 copy_id21_to_sam_passwd("INFO_21", pwd
, id21
);
4583 * The funny part about the previous two calls is
4584 * that pwd still has the password hashes from the
4585 * passdb entry. These have not been updated from
4586 * id21. I don't know if they need to be set. --jerry
4589 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4590 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4591 if ( !NT_STATUS_IS_OK(status
) ) {
4596 /* Don't worry about writing out the user account since the
4597 primary group SID is generated solely from the user's Unix
4600 /* write the change out */
4601 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4605 return NT_STATUS_OK
;
4608 /*******************************************************************
4610 ********************************************************************/
4612 static NTSTATUS
set_user_info_23(TALLOC_CTX
*mem_ctx
,
4613 struct samr_UserInfo23
*id23
,
4617 char *plaintext_buf
= NULL
;
4623 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4624 return NT_STATUS_INVALID_PARAMETER
;
4627 if (id23
->info
.fields_present
== 0) {
4628 return NT_STATUS_INVALID_PARAMETER
;
4631 if (id23
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4632 return NT_STATUS_ACCESS_DENIED
;
4635 if ((id23
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4636 (id23
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4638 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4639 pdb_get_username(pwd
)));
4641 if (!decode_pw_buffer(mem_ctx
,
4642 id23
->password
.data
,
4646 return NT_STATUS_WRONG_PASSWORD
;
4649 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4650 return NT_STATUS_ACCESS_DENIED
;
4654 copy_id23_to_sam_passwd(pwd
, id23
);
4656 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4658 /* if it's a trust account, don't update /etc/passwd */
4659 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4660 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4661 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4662 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4663 } else if (plaintext_buf
) {
4664 /* update the UNIX password */
4665 if (lp_unix_password_sync() ) {
4666 struct passwd
*passwd
;
4667 if (pdb_get_username(pwd
) == NULL
) {
4668 DEBUG(1, ("chgpasswd: User without name???\n"));
4669 return NT_STATUS_ACCESS_DENIED
;
4672 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4673 if (passwd
== NULL
) {
4674 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4677 if(!chgpasswd(pdb_get_username(pwd
), rhost
,
4678 passwd
, "", plaintext_buf
, True
)) {
4679 return NT_STATUS_ACCESS_DENIED
;
4681 TALLOC_FREE(passwd
);
4685 if (plaintext_buf
) {
4686 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4689 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) &&
4690 (!NT_STATUS_IS_OK(status
= pdb_set_unix_primary_group(mem_ctx
,
4695 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4699 return NT_STATUS_OK
;
4702 /*******************************************************************
4704 ********************************************************************/
4706 static bool set_user_info_pw(uint8_t *pass
, const char *rhost
, struct samu
*pwd
)
4709 char *plaintext_buf
= NULL
;
4712 DEBUG(5, ("Attempting administrator password change for user %s\n",
4713 pdb_get_username(pwd
)));
4715 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4717 if (!decode_pw_buffer(talloc_tos(),
4725 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4729 /* if it's a trust account, don't update /etc/passwd */
4730 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4731 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4732 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4733 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4735 /* update the UNIX password */
4736 if (lp_unix_password_sync()) {
4737 struct passwd
*passwd
;
4739 if (pdb_get_username(pwd
) == NULL
) {
4740 DEBUG(1, ("chgpasswd: User without name???\n"));
4744 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4745 if (passwd
== NULL
) {
4746 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4749 if(!chgpasswd(pdb_get_username(pwd
), rhost
, passwd
,
4750 "", plaintext_buf
, True
)) {
4753 TALLOC_FREE(passwd
);
4757 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4759 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4764 /*******************************************************************
4766 ********************************************************************/
4768 static NTSTATUS
set_user_info_24(TALLOC_CTX
*mem_ctx
,
4770 struct samr_UserInfo24
*id24
,
4776 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4777 return NT_STATUS_INVALID_PARAMETER
;
4780 if (!set_user_info_pw(id24
->password
.data
, rhost
, pwd
)) {
4781 return NT_STATUS_WRONG_PASSWORD
;
4784 copy_id24_to_sam_passwd(pwd
, id24
);
4786 status
= pdb_update_sam_account(pwd
);
4787 if (!NT_STATUS_IS_OK(status
)) {
4791 return NT_STATUS_OK
;
4794 /*******************************************************************
4796 ********************************************************************/
4798 static NTSTATUS
set_user_info_25(TALLOC_CTX
*mem_ctx
,
4800 struct samr_UserInfo25
*id25
,
4806 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4807 return NT_STATUS_INVALID_PARAMETER
;
4810 if (id25
->info
.fields_present
== 0) {
4811 return NT_STATUS_INVALID_PARAMETER
;
4814 if (id25
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4815 return NT_STATUS_ACCESS_DENIED
;
4818 if ((id25
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4819 (id25
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4821 if (!set_user_info_pw(id25
->password
.data
, rhost
, pwd
)) {
4822 return NT_STATUS_WRONG_PASSWORD
;
4826 copy_id25_to_sam_passwd(pwd
, id25
);
4828 /* write the change out */
4829 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4834 * We need to "pdb_update_sam_account" before the unix primary group
4835 * is set, because the idealx scripts would also change the
4836 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4837 * the delete explicit / add explicit, which would then fail to find
4838 * the previous primaryGroupSid value.
4841 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4842 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4843 if ( !NT_STATUS_IS_OK(status
) ) {
4848 return NT_STATUS_OK
;
4851 /*******************************************************************
4853 ********************************************************************/
4855 static NTSTATUS
set_user_info_26(TALLOC_CTX
*mem_ctx
,
4857 struct samr_UserInfo26
*id26
,
4863 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4864 return NT_STATUS_INVALID_PARAMETER
;
4867 if (!set_user_info_pw(id26
->password
.data
, rhost
, pwd
)) {
4868 return NT_STATUS_WRONG_PASSWORD
;
4871 copy_id26_to_sam_passwd(pwd
, id26
);
4873 status
= pdb_update_sam_account(pwd
);
4874 if (!NT_STATUS_IS_OK(status
)) {
4878 return NT_STATUS_OK
;
4881 /*************************************************************
4882 **************************************************************/
4884 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields
)
4886 uint32_t acc_required
= 0;
4888 /* USER_ALL_USERNAME */
4889 if (fields
& SAMR_FIELD_ACCOUNT_NAME
)
4890 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4891 /* USER_ALL_FULLNAME */
4892 if (fields
& SAMR_FIELD_FULL_NAME
)
4893 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4894 /* USER_ALL_PRIMARYGROUPID */
4895 if (fields
& SAMR_FIELD_PRIMARY_GID
)
4896 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4897 /* USER_ALL_HOMEDIRECTORY */
4898 if (fields
& SAMR_FIELD_HOME_DIRECTORY
)
4899 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4900 /* USER_ALL_HOMEDIRECTORYDRIVE */
4901 if (fields
& SAMR_FIELD_HOME_DRIVE
)
4902 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4903 /* USER_ALL_SCRIPTPATH */
4904 if (fields
& SAMR_FIELD_LOGON_SCRIPT
)
4905 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4906 /* USER_ALL_PROFILEPATH */
4907 if (fields
& SAMR_FIELD_PROFILE_PATH
)
4908 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4909 /* USER_ALL_ADMINCOMMENT */
4910 if (fields
& SAMR_FIELD_COMMENT
)
4911 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4912 /* USER_ALL_WORKSTATIONS */
4913 if (fields
& SAMR_FIELD_WORKSTATIONS
)
4914 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4915 /* USER_ALL_LOGONHOURS */
4916 if (fields
& SAMR_FIELD_LOGON_HOURS
)
4917 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4918 /* USER_ALL_ACCOUNTEXPIRES */
4919 if (fields
& SAMR_FIELD_ACCT_EXPIRY
)
4920 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4921 /* USER_ALL_USERACCOUNTCONTROL */
4922 if (fields
& SAMR_FIELD_ACCT_FLAGS
)
4923 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4924 /* USER_ALL_PARAMETERS */
4925 if (fields
& SAMR_FIELD_PARAMETERS
)
4926 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4927 /* USER_ALL_USERCOMMENT */
4928 if (fields
& SAMR_FIELD_COMMENT
)
4929 acc_required
|= SAMR_USER_ACCESS_SET_LOC_COM
;
4930 /* USER_ALL_COUNTRYCODE */
4931 if (fields
& SAMR_FIELD_COUNTRY_CODE
)
4932 acc_required
|= SAMR_USER_ACCESS_SET_LOC_COM
;
4933 /* USER_ALL_CODEPAGE */
4934 if (fields
& SAMR_FIELD_CODE_PAGE
)
4935 acc_required
|= SAMR_USER_ACCESS_SET_LOC_COM
;
4936 /* USER_ALL_NTPASSWORDPRESENT */
4937 if (fields
& SAMR_FIELD_NT_PASSWORD_PRESENT
)
4938 acc_required
|= SAMR_USER_ACCESS_SET_PASSWORD
;
4939 /* USER_ALL_LMPASSWORDPRESENT */
4940 if (fields
& SAMR_FIELD_LM_PASSWORD_PRESENT
)
4941 acc_required
|= SAMR_USER_ACCESS_SET_PASSWORD
;
4942 /* USER_ALL_PASSWORDEXPIRED */
4943 if (fields
& SAMR_FIELD_EXPIRED_FLAG
)
4944 acc_required
|= SAMR_USER_ACCESS_SET_PASSWORD
;
4946 return acc_required
;
4949 /*******************************************************************
4951 ********************************************************************/
4953 NTSTATUS
_samr_SetUserInfo(struct pipes_struct
*p
,
4954 struct samr_SetUserInfo
*r
)
4956 struct samr_user_info
*uinfo
;
4958 struct samu
*pwd
= NULL
;
4959 union samr_UserInfo
*info
= r
->in
.info
;
4960 uint32_t acc_required
= 0;
4961 uint32_t fields
= 0;
4964 DATA_BLOB session_key
;
4965 struct dom_sid_buf buf
;
4967 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__
));
4969 /* This is tricky. A WinXP domain join sets
4970 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4971 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4972 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4973 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4974 we'll use the set from the WinXP join as the basis. */
4976 switch (r
->in
.level
) {
4977 case 2: /* UserPreferencesInformation */
4978 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
4979 acc_required
= SAMR_USER_ACCESS_SET_ATTRIBUTES
| SAMR_USER_ACCESS_SET_LOC_COM
;
4981 case 4: /* UserLogonHoursInformation */
4982 case 6: /* UserNameInformation */
4983 case 7: /* UserAccountNameInformation */
4984 case 8: /* UserFullNameInformation */
4985 case 9: /* UserPrimaryGroupInformation */
4986 case 10: /* UserHomeInformation */
4987 case 11: /* UserScriptInformation */
4988 case 12: /* UserProfileInformation */
4989 case 13: /* UserAdminCommentInformation */
4990 case 14: /* UserWorkStationsInformation */
4991 case 16: /* UserControlInformation */
4992 case 17: /* UserExpiresInformation */
4993 case 20: /* UserParametersInformation */
4994 /* USER_WRITE_ACCOUNT */
4995 acc_required
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4997 case 18: /* UserInternal1Information */
4998 /* FIXME: gd, this is a guess */
4999 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
;
5001 case 21: /* UserAllInformation */
5002 fields
= info
->info21
.fields_present
;
5003 acc_required
= samr_set_user_info_map_fields_to_access_mask(fields
);
5005 case 23: /* UserInternal4Information */
5006 fields
= info
->info23
.info
.fields_present
;
5007 acc_required
= samr_set_user_info_map_fields_to_access_mask(fields
);
5009 case 25: /* UserInternal4InformationNew */
5010 fields
= info
->info25
.info
.fields_present
;
5011 acc_required
= samr_set_user_info_map_fields_to_access_mask(fields
);
5013 case 24: /* UserInternal5Information */
5014 case 26: /* UserInternal5InformationNew */
5015 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
;
5018 return NT_STATUS_INVALID_INFO_CLASS
;
5021 uinfo
= policy_handle_find(p
, r
->in
.user_handle
, acc_required
, NULL
,
5022 struct samr_user_info
, &status
);
5023 if (!NT_STATUS_IS_OK(status
)) {
5027 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5028 dom_sid_str_buf(&uinfo
->sid
, &buf
),
5032 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5033 return NT_STATUS_INVALID_INFO_CLASS
;
5036 if (!(pwd
= samu_new(NULL
))) {
5037 return NT_STATUS_NO_MEMORY
;
5041 ret
= pdb_getsampwsid(pwd
, &uinfo
->sid
);
5046 return NT_STATUS_NO_SUCH_USER
;
5049 rhost
= tsocket_address_inet_addr_string(p
->remote_address
,
5051 if (rhost
== NULL
) {
5052 return NT_STATUS_NO_MEMORY
;
5055 /* ================ BEGIN Privilege BLOCK ================ */
5059 /* ok! user info levels (lots: see MSDEV help), off we go... */
5061 switch (r
->in
.level
) {
5064 status
= set_user_info_2(p
->mem_ctx
,
5069 status
= set_user_info_4(p
->mem_ctx
,
5074 status
= set_user_info_6(p
->mem_ctx
,
5079 status
= set_user_info_7(p
->mem_ctx
,
5084 status
= set_user_info_8(p
->mem_ctx
,
5089 status
= set_user_info_10(p
->mem_ctx
,
5090 &info
->info10
, pwd
);
5094 status
= set_user_info_11(p
->mem_ctx
,
5095 &info
->info11
, pwd
);
5099 status
= set_user_info_12(p
->mem_ctx
,
5100 &info
->info12
, pwd
);
5104 status
= set_user_info_13(p
->mem_ctx
,
5105 &info
->info13
, pwd
);
5109 status
= set_user_info_14(p
->mem_ctx
,
5110 &info
->info14
, pwd
);
5114 status
= set_user_info_16(p
->mem_ctx
,
5115 &info
->info16
, pwd
);
5119 status
= set_user_info_17(p
->mem_ctx
,
5120 &info
->info17
, pwd
);
5124 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5125 if(!NT_STATUS_IS_OK(status
)) {
5128 /* Used by AS/U JRA. */
5129 status
= set_user_info_18(&info
->info18
,
5136 status
= set_user_info_20(p
->mem_ctx
,
5137 &info
->info20
, pwd
);
5141 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5142 if(!NT_STATUS_IS_OK(status
)) {
5145 status
= set_user_info_21(&info
->info21
,
5152 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5153 if(!NT_STATUS_IS_OK(status
)) {
5156 arcfour_crypt_blob(info
->info23
.password
.data
, 516,
5159 dump_data(100, info
->info23
.password
.data
, 516);
5161 status
= set_user_info_23(p
->mem_ctx
,
5168 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5169 if(!NT_STATUS_IS_OK(status
)) {
5172 arcfour_crypt_blob(info
->info24
.password
.data
,
5176 dump_data(100, info
->info24
.password
.data
, 516);
5178 status
= set_user_info_24(p
->mem_ctx
,
5180 &info
->info24
, pwd
);
5184 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5185 if(!NT_STATUS_IS_OK(status
)) {
5188 encode_or_decode_arc4_passwd_buffer(
5189 info
->info25
.password
.data
,
5192 dump_data(100, info
->info25
.password
.data
, 532);
5194 status
= set_user_info_25(p
->mem_ctx
,
5196 &info
->info25
, pwd
);
5200 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5201 if(!NT_STATUS_IS_OK(status
)) {
5204 encode_or_decode_arc4_passwd_buffer(
5205 info
->info26
.password
.data
,
5208 dump_data(100, info
->info26
.password
.data
, 516);
5210 status
= set_user_info_26(p
->mem_ctx
,
5212 &info
->info26
, pwd
);
5216 status
= NT_STATUS_INVALID_INFO_CLASS
;
5223 /* ================ END Privilege BLOCK ================ */
5225 if (NT_STATUS_IS_OK(status
)) {
5226 force_flush_samr_cache(&uinfo
->sid
);
5232 /*******************************************************************
5234 ********************************************************************/
5236 NTSTATUS
_samr_SetUserInfo2(struct pipes_struct
*p
,
5237 struct samr_SetUserInfo2
*r
)
5239 struct samr_SetUserInfo q
;
5241 q
.in
.user_handle
= r
->in
.user_handle
;
5242 q
.in
.level
= r
->in
.level
;
5243 q
.in
.info
= r
->in
.info
;
5245 return _samr_SetUserInfo(p
, &q
);
5248 /*********************************************************************
5249 _samr_GetAliasMembership
5250 *********************************************************************/
5252 NTSTATUS
_samr_GetAliasMembership(struct pipes_struct
*p
,
5253 struct samr_GetAliasMembership
*r
)
5255 size_t num_alias_rids
;
5256 uint32_t *alias_rids
;
5257 struct samr_domain_info
*dinfo
;
5262 struct dom_sid
*members
;
5264 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__
));
5266 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
5267 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5268 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
5269 struct samr_domain_info
, &status
);
5270 if (!NT_STATUS_IS_OK(status
)) {
5274 if (!sid_check_is_our_sam(&dinfo
->sid
) &&
5275 !sid_check_is_builtin(&dinfo
->sid
))
5276 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
5278 if (r
->in
.sids
->num_sids
) {
5279 members
= talloc_array(p
->mem_ctx
, struct dom_sid
, r
->in
.sids
->num_sids
);
5281 if (members
== NULL
)
5282 return NT_STATUS_NO_MEMORY
;
5287 for (i
=0; i
<r
->in
.sids
->num_sids
; i
++)
5288 sid_copy(&members
[i
], r
->in
.sids
->sids
[i
].sid
);
5294 status
= pdb_enum_alias_memberships(p
->mem_ctx
, &dinfo
->sid
, members
,
5295 r
->in
.sids
->num_sids
,
5296 &alias_rids
, &num_alias_rids
);
5299 if (!NT_STATUS_IS_OK(status
)) {
5303 r
->out
.rids
->count
= num_alias_rids
;
5304 r
->out
.rids
->ids
= alias_rids
;
5306 if (r
->out
.rids
->ids
== NULL
) {
5307 /* Windows domain clients don't accept a NULL ptr here */
5308 r
->out
.rids
->ids
= talloc_zero(p
->mem_ctx
, uint32_t);
5310 if (r
->out
.rids
->ids
== NULL
) {
5311 return NT_STATUS_NO_MEMORY
;
5314 return NT_STATUS_OK
;
5317 /*********************************************************************
5318 _samr_GetMembersInAlias
5319 *********************************************************************/
5321 NTSTATUS
_samr_GetMembersInAlias(struct pipes_struct
*p
,
5322 struct samr_GetMembersInAlias
*r
)
5324 struct samr_alias_info
*ainfo
;
5327 size_t num_sids
= 0;
5328 struct lsa_SidPtr
*sids
= NULL
;
5329 struct dom_sid
*pdb_sids
= NULL
;
5330 struct dom_sid_buf buf
;
5332 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5333 SAMR_ALIAS_ACCESS_GET_MEMBERS
, NULL
,
5334 struct samr_alias_info
, &status
);
5335 if (!NT_STATUS_IS_OK(status
)) {
5339 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo
->sid
, &buf
)));
5342 status
= pdb_enum_aliasmem(&ainfo
->sid
, talloc_tos(), &pdb_sids
,
5346 if (!NT_STATUS_IS_OK(status
)) {
5351 sids
= talloc_zero_array(p
->mem_ctx
, struct lsa_SidPtr
, num_sids
);
5353 TALLOC_FREE(pdb_sids
);
5354 return NT_STATUS_NO_MEMORY
;
5358 for (i
= 0; i
< num_sids
; i
++) {
5359 sids
[i
].sid
= dom_sid_dup(p
->mem_ctx
, &pdb_sids
[i
]);
5361 TALLOC_FREE(pdb_sids
);
5362 return NT_STATUS_NO_MEMORY
;
5366 r
->out
.sids
->num_sids
= num_sids
;
5367 r
->out
.sids
->sids
= sids
;
5369 TALLOC_FREE(pdb_sids
);
5371 return NT_STATUS_OK
;
5374 /*********************************************************************
5375 _samr_QueryGroupMember
5376 *********************************************************************/
5378 NTSTATUS
_samr_QueryGroupMember(struct pipes_struct
*p
,
5379 struct samr_QueryGroupMember
*r
)
5381 struct samr_group_info
*ginfo
;
5382 size_t i
, num_members
;
5385 uint32_t *attr
=NULL
;
5388 struct samr_RidAttrArray
*rids
= NULL
;
5389 struct dom_sid_buf buf
;
5391 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5392 SAMR_GROUP_ACCESS_GET_MEMBERS
, NULL
,
5393 struct samr_group_info
, &status
);
5394 if (!NT_STATUS_IS_OK(status
)) {
5398 rids
= talloc_zero(p
->mem_ctx
, struct samr_RidAttrArray
);
5400 return NT_STATUS_NO_MEMORY
;
5403 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo
->sid
, &buf
)));
5405 if (!sid_check_is_in_our_sam(&ginfo
->sid
)) {
5406 DEBUG(3, ("sid %s is not in our domain\n",
5407 dom_sid_str_buf(&ginfo
->sid
, &buf
)));
5408 return NT_STATUS_NO_SUCH_GROUP
;
5411 DEBUG(10, ("lookup on Domain SID\n"));
5414 status
= pdb_enum_group_members(p
->mem_ctx
, &ginfo
->sid
,
5415 &rid
, &num_members
);
5418 if (!NT_STATUS_IS_OK(status
))
5422 attr
=talloc_zero_array(p
->mem_ctx
, uint32_t, num_members
);
5424 return NT_STATUS_NO_MEMORY
;
5430 for (i
=0; i
<num_members
; i
++) {
5431 attr
[i
] = SE_GROUP_MANDATORY
|
5432 SE_GROUP_ENABLED_BY_DEFAULT
|
5436 rids
->count
= num_members
;
5437 rids
->attributes
= attr
;
5440 *r
->out
.rids
= rids
;
5442 return NT_STATUS_OK
;
5445 /*********************************************************************
5446 _samr_AddAliasMember
5447 *********************************************************************/
5449 NTSTATUS
_samr_AddAliasMember(struct pipes_struct
*p
,
5450 struct samr_AddAliasMember
*r
)
5452 struct samr_alias_info
*ainfo
;
5453 struct dom_sid_buf buf
;
5456 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5457 SAMR_ALIAS_ACCESS_ADD_MEMBER
, NULL
,
5458 struct samr_alias_info
, &status
);
5459 if (!NT_STATUS_IS_OK(status
)) {
5463 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo
->sid
, &buf
)));
5465 /******** BEGIN SeAddUsers BLOCK *********/
5468 status
= pdb_add_aliasmem(&ainfo
->sid
, r
->in
.sid
);
5471 /******** END SeAddUsers BLOCK *********/
5473 if (NT_STATUS_IS_OK(status
)) {
5474 force_flush_samr_cache(&ainfo
->sid
);
5480 /*********************************************************************
5481 _samr_DeleteAliasMember
5482 *********************************************************************/
5484 NTSTATUS
_samr_DeleteAliasMember(struct pipes_struct
*p
,
5485 struct samr_DeleteAliasMember
*r
)
5487 struct samr_alias_info
*ainfo
;
5488 struct dom_sid_buf buf
;
5491 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5492 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
, NULL
,
5493 struct samr_alias_info
, &status
);
5494 if (!NT_STATUS_IS_OK(status
)) {
5498 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5499 dom_sid_str_buf(&ainfo
->sid
, &buf
)));
5501 /******** BEGIN SeAddUsers BLOCK *********/
5504 status
= pdb_del_aliasmem(&ainfo
->sid
, r
->in
.sid
);
5507 /******** END SeAddUsers BLOCK *********/
5509 if (NT_STATUS_IS_OK(status
)) {
5510 force_flush_samr_cache(&ainfo
->sid
);
5516 /*********************************************************************
5517 _samr_AddGroupMember
5518 *********************************************************************/
5520 NTSTATUS
_samr_AddGroupMember(struct pipes_struct
*p
,
5521 struct samr_AddGroupMember
*r
)
5523 struct samr_group_info
*ginfo
;
5524 struct dom_sid_buf buf
;
5528 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5529 SAMR_GROUP_ACCESS_ADD_MEMBER
, NULL
,
5530 struct samr_group_info
, &status
);
5531 if (!NT_STATUS_IS_OK(status
)) {
5535 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo
->sid
, &buf
)));
5537 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo
->sid
,
5539 return NT_STATUS_INVALID_HANDLE
;
5542 /******** BEGIN SeAddUsers BLOCK *********/
5545 status
= pdb_add_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5548 /******** END SeAddUsers BLOCK *********/
5550 force_flush_samr_cache(&ginfo
->sid
);
5555 /*********************************************************************
5556 _samr_DeleteGroupMember
5557 *********************************************************************/
5559 NTSTATUS
_samr_DeleteGroupMember(struct pipes_struct
*p
,
5560 struct samr_DeleteGroupMember
*r
)
5563 struct samr_group_info
*ginfo
;
5568 * delete the group member named r->in.rid
5569 * who is a member of the sid associated with the handle
5570 * the rid is a user's rid as the group is a domain group.
5573 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5574 SAMR_GROUP_ACCESS_REMOVE_MEMBER
, NULL
,
5575 struct samr_group_info
, &status
);
5576 if (!NT_STATUS_IS_OK(status
)) {
5580 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo
->sid
,
5582 return NT_STATUS_INVALID_HANDLE
;
5585 /******** BEGIN SeAddUsers BLOCK *********/
5588 status
= pdb_del_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5591 /******** END SeAddUsers BLOCK *********/
5593 force_flush_samr_cache(&ginfo
->sid
);
5598 /*********************************************************************
5600 *********************************************************************/
5602 NTSTATUS
_samr_DeleteUser(struct pipes_struct
*p
,
5603 struct samr_DeleteUser
*r
)
5605 struct samr_user_info
*uinfo
;
5607 struct samu
*sam_pass
=NULL
;
5610 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__
));
5612 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
5613 SEC_STD_DELETE
, NULL
,
5614 struct samr_user_info
, &status
);
5615 if (!NT_STATUS_IS_OK(status
)) {
5619 if (!sid_check_is_in_our_sam(&uinfo
->sid
))
5620 return NT_STATUS_CANNOT_DELETE
;
5622 /* check if the user exists before trying to delete */
5623 if ( !(sam_pass
= samu_new( NULL
)) ) {
5624 return NT_STATUS_NO_MEMORY
;
5628 ret
= pdb_getsampwsid(sam_pass
, &uinfo
->sid
);
5632 struct dom_sid_buf buf
;
5633 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5634 dom_sid_str_buf(&uinfo
->sid
, &buf
)));
5635 TALLOC_FREE(sam_pass
);
5636 return NT_STATUS_NO_SUCH_USER
;
5639 /******** BEGIN SeAddUsers BLOCK *********/
5642 status
= pdb_delete_user(p
->mem_ctx
, sam_pass
);
5645 /******** END SeAddUsers BLOCK *********/
5647 if ( !NT_STATUS_IS_OK(status
) ) {
5648 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5649 "user %s: %s.\n", pdb_get_username(sam_pass
),
5650 nt_errstr(status
)));
5651 TALLOC_FREE(sam_pass
);
5656 TALLOC_FREE(sam_pass
);
5658 force_flush_samr_cache(&uinfo
->sid
);
5660 if (!close_policy_hnd(p
, r
->in
.user_handle
))
5661 return NT_STATUS_OBJECT_NAME_INVALID
;
5663 ZERO_STRUCTP(r
->out
.user_handle
);
5665 return NT_STATUS_OK
;
5668 /*********************************************************************
5669 _samr_DeleteDomainGroup
5670 *********************************************************************/
5672 NTSTATUS
_samr_DeleteDomainGroup(struct pipes_struct
*p
,
5673 struct samr_DeleteDomainGroup
*r
)
5675 struct samr_group_info
*ginfo
;
5676 struct dom_sid_buf buf
;
5680 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__
));
5682 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5683 SEC_STD_DELETE
, NULL
,
5684 struct samr_group_info
, &status
);
5685 if (!NT_STATUS_IS_OK(status
)) {
5689 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo
->sid
, &buf
)));
5691 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo
->sid
,
5693 return NT_STATUS_NO_SUCH_GROUP
;
5696 /******** BEGIN SeAddUsers BLOCK *********/
5699 status
= pdb_delete_dom_group(p
->mem_ctx
, group_rid
);
5702 /******** END SeAddUsers BLOCK *********/
5704 if ( !NT_STATUS_IS_OK(status
) ) {
5705 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5706 "entry for group %s: %s\n",
5707 dom_sid_str_buf(&ginfo
->sid
, &buf
),
5708 nt_errstr(status
)));
5712 force_flush_samr_cache(&ginfo
->sid
);
5714 if (!close_policy_hnd(p
, r
->in
.group_handle
))
5715 return NT_STATUS_OBJECT_NAME_INVALID
;
5717 return NT_STATUS_OK
;
5720 /*********************************************************************
5721 _samr_DeleteDomAlias
5722 *********************************************************************/
5724 NTSTATUS
_samr_DeleteDomAlias(struct pipes_struct
*p
,
5725 struct samr_DeleteDomAlias
*r
)
5727 struct samr_alias_info
*ainfo
;
5728 struct dom_sid_buf buf
;
5731 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__
));
5733 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5734 SEC_STD_DELETE
, NULL
,
5735 struct samr_alias_info
, &status
);
5736 if (!NT_STATUS_IS_OK(status
)) {
5740 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo
->sid
, &buf
)));
5742 /* Don't let Windows delete builtin groups */
5744 if ( sid_check_is_in_builtin( &ainfo
->sid
) ) {
5745 return NT_STATUS_SPECIAL_ACCOUNT
;
5748 if (!sid_check_is_in_our_sam(&ainfo
->sid
))
5749 return NT_STATUS_NO_SUCH_ALIAS
;
5751 DEBUG(10, ("lookup on Local SID\n"));
5753 /******** BEGIN SeAddUsers BLOCK *********/
5756 /* Have passdb delete the alias */
5757 status
= pdb_delete_alias(&ainfo
->sid
);
5760 /******** END SeAddUsers BLOCK *********/
5762 if ( !NT_STATUS_IS_OK(status
))
5765 force_flush_samr_cache(&ainfo
->sid
);
5767 if (!close_policy_hnd(p
, r
->in
.alias_handle
))
5768 return NT_STATUS_OBJECT_NAME_INVALID
;
5770 return NT_STATUS_OK
;
5773 /*********************************************************************
5774 _samr_CreateDomainGroup
5775 *********************************************************************/
5777 NTSTATUS
_samr_CreateDomainGroup(struct pipes_struct
*p
,
5778 struct samr_CreateDomainGroup
*r
)
5783 struct samr_domain_info
*dinfo
;
5784 struct samr_group_info
*ginfo
;
5786 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
5787 SAMR_DOMAIN_ACCESS_CREATE_GROUP
, NULL
,
5788 struct samr_domain_info
, &status
);
5789 if (!NT_STATUS_IS_OK(status
)) {
5793 if (!sid_check_is_our_sam(&dinfo
->sid
)) {
5794 return NT_STATUS_ACCESS_DENIED
;
5797 name
= r
->in
.name
->string
;
5799 return NT_STATUS_NO_MEMORY
;
5802 status
= can_create(p
->mem_ctx
, name
);
5803 if (!NT_STATUS_IS_OK(status
)) {
5807 /******** BEGIN SeAddUsers BLOCK *********/
5810 /* check that we successfully create the UNIX group */
5811 status
= pdb_create_dom_group(p
->mem_ctx
, name
, r
->out
.rid
);
5814 /******** END SeAddUsers BLOCK *********/
5816 /* check if we should bail out here */
5818 if ( !NT_STATUS_IS_OK(status
) )
5821 ginfo
= policy_handle_create(p
, r
->out
.group_handle
,
5822 GENERIC_RIGHTS_GROUP_ALL_ACCESS
,
5823 struct samr_group_info
, &status
);
5824 if (!NT_STATUS_IS_OK(status
)) {
5827 sid_compose(&ginfo
->sid
, &dinfo
->sid
, *r
->out
.rid
);
5829 force_flush_samr_cache(&dinfo
->sid
);
5831 return NT_STATUS_OK
;
5834 /*********************************************************************
5835 _samr_CreateDomAlias
5836 *********************************************************************/
5838 NTSTATUS
_samr_CreateDomAlias(struct pipes_struct
*p
,
5839 struct samr_CreateDomAlias
*r
)
5841 struct dom_sid info_sid
;
5842 const char *name
= NULL
;
5843 struct samr_domain_info
*dinfo
;
5844 struct samr_alias_info
*ainfo
;
5848 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
5849 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
, NULL
,
5850 struct samr_domain_info
, &result
);
5851 if (!NT_STATUS_IS_OK(result
)) {
5855 if (!sid_check_is_our_sam(&dinfo
->sid
)) {
5856 return NT_STATUS_ACCESS_DENIED
;
5859 name
= r
->in
.alias_name
->string
;
5861 result
= can_create(p
->mem_ctx
, name
);
5862 if (!NT_STATUS_IS_OK(result
)) {
5866 /******** BEGIN SeAddUsers BLOCK *********/
5869 /* Have passdb create the alias */
5870 result
= pdb_create_alias(name
, r
->out
.rid
);
5873 /******** END SeAddUsers BLOCK *********/
5875 if (!NT_STATUS_IS_OK(result
)) {
5876 DEBUG(10, ("pdb_create_alias failed: %s\n",
5877 nt_errstr(result
)));
5881 sid_compose(&info_sid
, &dinfo
->sid
, *r
->out
.rid
);
5883 if (!sid_to_gid(&info_sid
, &gid
)) {
5884 DEBUG(10, ("Could not find alias just created\n"));
5885 return NT_STATUS_ACCESS_DENIED
;
5888 /* check if the group has been successfully created */
5889 if ( getgrgid(gid
) == NULL
) {
5890 DEBUG(1, ("getgrgid(%u) of just created alias failed\n",
5891 (unsigned int)gid
));
5892 return NT_STATUS_ACCESS_DENIED
;
5895 ainfo
= policy_handle_create(p
, r
->out
.alias_handle
,
5896 GENERIC_RIGHTS_ALIAS_ALL_ACCESS
,
5897 struct samr_alias_info
, &result
);
5898 if (!NT_STATUS_IS_OK(result
)) {
5901 ainfo
->sid
= info_sid
;
5903 force_flush_samr_cache(&info_sid
);
5905 return NT_STATUS_OK
;
5908 /*********************************************************************
5909 _samr_QueryGroupInfo
5910 *********************************************************************/
5912 NTSTATUS
_samr_QueryGroupInfo(struct pipes_struct
*p
,
5913 struct samr_QueryGroupInfo
*r
)
5915 struct samr_group_info
*ginfo
;
5918 union samr_GroupInfo
*info
= NULL
;
5920 uint32_t attributes
= SE_GROUP_MANDATORY
|
5921 SE_GROUP_ENABLED_BY_DEFAULT
|
5923 const char *group_name
= NULL
;
5924 const char *group_description
= NULL
;
5926 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5927 SAMR_GROUP_ACCESS_LOOKUP_INFO
, NULL
,
5928 struct samr_group_info
, &status
);
5929 if (!NT_STATUS_IS_OK(status
)) {
5933 map
= talloc_zero(p
->mem_ctx
, GROUP_MAP
);
5935 return NT_STATUS_NO_MEMORY
;
5939 ret
= get_domain_group_from_sid(ginfo
->sid
, map
);
5942 return NT_STATUS_INVALID_HANDLE
;
5944 group_name
= talloc_move(r
, &map
->nt_name
);
5945 group_description
= talloc_move(r
, &map
->comment
);
5949 info
= talloc_zero(p
->mem_ctx
, union samr_GroupInfo
);
5951 return NT_STATUS_NO_MEMORY
;
5954 switch (r
->in
.level
) {
5960 status
= pdb_enum_group_members(
5961 p
->mem_ctx
, &ginfo
->sid
, &members
,
5965 if (!NT_STATUS_IS_OK(status
)) {
5969 info
->all
.name
.string
= group_name
;
5970 info
->all
.attributes
= attributes
;
5971 info
->all
.num_members
= num_members
;
5972 info
->all
.description
.string
= group_description
;
5976 info
->name
.string
= group_name
;
5979 info
->attributes
.attributes
= attributes
;
5982 info
->description
.string
= group_description
;
5992 status = pdb_enum_group_members(
5993 p->mem_ctx, &ginfo->sid, &members,
5997 if (!NT_STATUS_IS_OK(status)) {
6001 info
->all2
.name
.string
= group_name
;
6002 info
->all2
.attributes
= attributes
;
6003 info
->all2
.num_members
= 0; /* num_members - in w2k3 this is always 0 */
6004 info
->all2
.description
.string
= group_description
;
6009 return NT_STATUS_INVALID_INFO_CLASS
;
6012 *r
->out
.info
= info
;
6014 return NT_STATUS_OK
;
6017 /*********************************************************************
6019 *********************************************************************/
6021 NTSTATUS
_samr_SetGroupInfo(struct pipes_struct
*p
,
6022 struct samr_SetGroupInfo
*r
)
6024 struct samr_group_info
*ginfo
;
6029 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
6030 SAMR_GROUP_ACCESS_SET_INFO
, NULL
,
6031 struct samr_group_info
, &status
);
6032 if (!NT_STATUS_IS_OK(status
)) {
6036 map
= talloc_zero(p
->mem_ctx
, GROUP_MAP
);
6038 return NT_STATUS_NO_MEMORY
;
6042 ret
= get_domain_group_from_sid(ginfo
->sid
, map
);
6045 return NT_STATUS_NO_SUCH_GROUP
;
6047 switch (r
->in
.level
) {
6049 map
->nt_name
= talloc_strdup(map
,
6050 r
->in
.info
->name
.string
);
6051 if (!map
->nt_name
) {
6052 return NT_STATUS_NO_MEMORY
;
6058 map
->comment
= talloc_strdup(map
,
6059 r
->in
.info
->description
.string
);
6060 if (!map
->comment
) {
6061 return NT_STATUS_NO_MEMORY
;
6065 return NT_STATUS_INVALID_INFO_CLASS
;
6068 /******** BEGIN SeAddUsers BLOCK *********/
6071 status
= pdb_update_group_mapping_entry(map
);
6074 /******** End SeAddUsers BLOCK *********/
6078 if (NT_STATUS_IS_OK(status
)) {
6079 force_flush_samr_cache(&ginfo
->sid
);
6085 /*********************************************************************
6087 *********************************************************************/
6089 NTSTATUS
_samr_SetAliasInfo(struct pipes_struct
*p
,
6090 struct samr_SetAliasInfo
*r
)
6092 struct samr_alias_info
*ainfo
;
6093 struct acct_info
*info
;
6096 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
6097 SAMR_ALIAS_ACCESS_SET_INFO
, NULL
,
6098 struct samr_alias_info
, &status
);
6099 if (!NT_STATUS_IS_OK(status
)) {
6103 info
= talloc_zero(p
->mem_ctx
, struct acct_info
);
6105 return NT_STATUS_NO_MEMORY
;
6108 /* get the current group information */
6111 status
= pdb_get_aliasinfo(&ainfo
->sid
, info
);
6114 if ( !NT_STATUS_IS_OK(status
))
6117 switch (r
->in
.level
) {
6122 /* We currently do not support renaming groups in the
6123 the BUILTIN domain. Refer to util_builtin.c to understand
6124 why. The eventually needs to be fixed to be like Windows
6125 where you can rename builtin groups, just not delete them */
6127 if ( sid_check_is_in_builtin( &ainfo
->sid
) ) {
6128 return NT_STATUS_SPECIAL_ACCOUNT
;
6131 /* There has to be a valid name (and it has to be different) */
6133 if ( !r
->in
.info
->name
.string
)
6134 return NT_STATUS_INVALID_PARAMETER
;
6136 /* If the name is the same just reply "ok". Yes this
6137 doesn't allow you to change the case of a group name. */
6139 if (strequal(r
->in
.info
->name
.string
, info
->acct_name
)) {
6140 return NT_STATUS_OK
;
6143 talloc_free(info
->acct_name
);
6144 info
->acct_name
= talloc_strdup(info
, r
->in
.info
->name
.string
);
6145 if (!info
->acct_name
) {
6146 return NT_STATUS_NO_MEMORY
;
6149 /* make sure the name doesn't already exist as a user
6152 group_name
= talloc_asprintf(p
->mem_ctx
,
6156 if (group_name
== NULL
) {
6157 return NT_STATUS_NO_MEMORY
;
6160 status
= can_create( p
->mem_ctx
, group_name
);
6161 talloc_free(group_name
);
6162 if ( !NT_STATUS_IS_OK( status
) )
6166 case ALIASINFODESCRIPTION
:
6167 TALLOC_FREE(info
->acct_desc
);
6168 if (r
->in
.info
->description
.string
) {
6169 info
->acct_desc
= talloc_strdup(info
,
6170 r
->in
.info
->description
.string
);
6172 info
->acct_desc
= talloc_strdup(info
, "");
6174 if (!info
->acct_desc
) {
6175 return NT_STATUS_NO_MEMORY
;
6179 return NT_STATUS_INVALID_INFO_CLASS
;
6182 /******** BEGIN SeAddUsers BLOCK *********/
6185 status
= pdb_set_aliasinfo(&ainfo
->sid
, info
);
6188 /******** End SeAddUsers BLOCK *********/
6190 if (NT_STATUS_IS_OK(status
))
6191 force_flush_samr_cache(&ainfo
->sid
);
6196 /****************************************************************
6198 ****************************************************************/
6200 NTSTATUS
_samr_GetDomPwInfo(struct pipes_struct
*p
,
6201 struct samr_GetDomPwInfo
*r
)
6203 uint32_t min_password_length
= 0;
6204 uint32_t password_properties
= 0;
6206 /* Perform access check. Since this rpc does not require a
6207 policy handle it will not be caught by the access checks on
6208 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6210 if (!pipe_access_check(p
)) {
6211 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6212 return NT_STATUS_ACCESS_DENIED
;
6216 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN
,
6217 &min_password_length
);
6218 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS
,
6219 &password_properties
);
6222 if (lp_check_password_script(talloc_tos()) && *lp_check_password_script(talloc_tos())) {
6223 password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
6226 r
->out
.info
->min_password_length
= min_password_length
;
6227 r
->out
.info
->password_properties
= password_properties
;
6229 return NT_STATUS_OK
;
6232 /*********************************************************************
6234 *********************************************************************/
6236 NTSTATUS
_samr_OpenGroup(struct pipes_struct
*p
,
6237 struct samr_OpenGroup
*r
)
6240 struct dom_sid info_sid
;
6241 struct dom_sid_buf buf
;
6243 struct samr_domain_info
*dinfo
;
6244 struct samr_group_info
*ginfo
;
6245 struct security_descriptor
*psd
= NULL
;
6246 uint32_t acc_granted
;
6247 uint32_t des_access
= r
->in
.access_mask
;
6252 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6253 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
6254 struct samr_domain_info
, &status
);
6255 if (!NT_STATUS_IS_OK(status
)) {
6259 /*check if access can be granted as requested by client. */
6260 map_max_allowed_access(p
->session_info
->security_token
,
6261 p
->session_info
->unix_token
,
6264 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &grp_generic_mapping
, NULL
, 0);
6265 se_map_generic(&des_access
,&grp_generic_mapping
);
6267 status
= access_check_object(psd
, p
->session_info
->security_token
,
6268 SEC_PRIV_ADD_USERS
, SEC_PRIV_INVALID
, GENERIC_RIGHTS_GROUP_ALL_ACCESS
,
6269 des_access
, &acc_granted
, "_samr_OpenGroup");
6271 if ( !NT_STATUS_IS_OK(status
) )
6274 /* this should not be hard-coded like this */
6276 if (!sid_check_is_our_sam(&dinfo
->sid
)) {
6277 return NT_STATUS_ACCESS_DENIED
;
6280 sid_compose(&info_sid
, &dinfo
->sid
, r
->in
.rid
);
6282 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6283 dom_sid_str_buf(&info_sid
, &buf
)));
6285 map
= talloc_zero(p
->mem_ctx
, GROUP_MAP
);
6287 return NT_STATUS_NO_MEMORY
;
6290 /* check if that group really exists */
6292 ret
= get_domain_group_from_sid(info_sid
, map
);
6295 return NT_STATUS_NO_SUCH_GROUP
;
6299 ginfo
= policy_handle_create(p
, r
->out
.group_handle
,
6301 struct samr_group_info
, &status
);
6302 if (!NT_STATUS_IS_OK(status
)) {
6305 ginfo
->sid
= info_sid
;
6307 return NT_STATUS_OK
;
6310 /*********************************************************************
6311 _samr_RemoveMemberFromForeignDomain
6312 *********************************************************************/
6314 NTSTATUS
_samr_RemoveMemberFromForeignDomain(struct pipes_struct
*p
,
6315 struct samr_RemoveMemberFromForeignDomain
*r
)
6317 struct samr_domain_info
*dinfo
;
6318 struct dom_sid_buf buf
;
6321 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6322 dom_sid_str_buf(r
->in
.sid
, &buf
)));
6324 /* Find the policy handle. Open a policy on it. */
6326 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6327 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
6328 struct samr_domain_info
, &result
);
6329 if (!NT_STATUS_IS_OK(result
)) {
6333 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6334 dom_sid_str_buf(&dinfo
->sid
, &buf
)));
6336 /* we can only delete a user from a group since we don't have
6337 nested groups anyways. So in the latter case, just say OK */
6339 /* TODO: The above comment nowadays is bogus. Since we have nested
6340 * groups now, and aliases members are never reported out of the unix
6341 * group membership, the "just say OK" makes this call a no-op. For
6342 * us. This needs fixing however. */
6344 /* I've only ever seen this in the wild when deleting a user from
6345 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6346 * is the user about to be deleted. I very much suspect this is the
6347 * only application of this call. To verify this, let people report
6350 if (!sid_check_is_builtin(&dinfo
->sid
)) {
6351 struct dom_sid_buf buf2
;
6352 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6353 "global_sam_sid() = %s\n",
6354 dom_sid_str_buf(&dinfo
->sid
, &buf
),
6355 dom_sid_str_buf(get_global_sam_sid(), &buf2
)));
6356 DEBUGADD(1,("please report to samba-technical@lists.samba.org!\n"));
6357 return NT_STATUS_OK
;
6360 force_flush_samr_cache(&dinfo
->sid
);
6362 result
= NT_STATUS_OK
;
6367 /*******************************************************************
6368 _samr_QueryDomainInfo2
6369 ********************************************************************/
6371 NTSTATUS
_samr_QueryDomainInfo2(struct pipes_struct
*p
,
6372 struct samr_QueryDomainInfo2
*r
)
6374 struct samr_QueryDomainInfo q
;
6376 q
.in
.domain_handle
= r
->in
.domain_handle
;
6377 q
.in
.level
= r
->in
.level
;
6379 q
.out
.info
= r
->out
.info
;
6381 return _samr_QueryDomainInfo(p
, &q
);
6384 /*******************************************************************
6385 ********************************************************************/
6387 static NTSTATUS
set_dom_info_1(TALLOC_CTX
*mem_ctx
,
6388 struct samr_DomInfo1
*r
)
6390 time_t u_expire
, u_min_age
;
6392 u_expire
= nt_time_to_unix_abs((NTTIME
*)&r
->max_password_age
);
6393 u_min_age
= nt_time_to_unix_abs((NTTIME
*)&r
->min_password_age
);
6395 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN
,
6396 (uint32_t)r
->min_password_length
);
6397 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY
,
6398 (uint32_t)r
->password_history_length
);
6399 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS
,
6400 (uint32_t)r
->password_properties
);
6401 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE
, (int)u_expire
);
6402 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE
, (int)u_min_age
);
6404 return NT_STATUS_OK
;
6407 /*******************************************************************
6408 ********************************************************************/
6410 static NTSTATUS
set_dom_info_3(TALLOC_CTX
*mem_ctx
,
6411 struct samr_DomInfo3
*r
)
6415 u_logout
= nt_time_to_unix_abs((NTTIME
*)&r
->force_logoff_time
);
6417 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT
, (int)u_logout
);
6419 return NT_STATUS_OK
;
6422 /*******************************************************************
6423 ********************************************************************/
6425 static NTSTATUS
set_dom_info_12(TALLOC_CTX
*mem_ctx
,
6426 struct samr_DomInfo12
*r
)
6428 time_t u_lock_duration
, u_reset_time
;
6431 * It is not possible to set lockout_duration < lockout_window.
6432 * (The test is the other way around since the negative numbers
6435 * This constraint is documented here for the samr rpc service:
6436 * MS-SAMR 3.1.1.6 Attribute Constraints for Originating Updates
6437 * http://msdn.microsoft.com/en-us/library/cc245667%28PROT.10%29.aspx
6439 * And here for the ldap backend:
6440 * MS-ADTS 3.1.1.5.3.2 Constraints
6441 * http://msdn.microsoft.com/en-us/library/cc223462(PROT.10).aspx
6443 if (r
->lockout_duration
> r
->lockout_window
) {
6444 return NT_STATUS_INVALID_PARAMETER
;
6447 u_lock_duration
= nt_time_to_unix_abs((NTTIME
*)&r
->lockout_duration
);
6448 if (u_lock_duration
!= -1) {
6449 u_lock_duration
/= 60;
6452 u_reset_time
= nt_time_to_unix_abs((NTTIME
*)&r
->lockout_window
)/60;
6454 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, (int)u_lock_duration
);
6455 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME
, (int)u_reset_time
);
6456 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
,
6457 (uint32_t)r
->lockout_threshold
);
6459 return NT_STATUS_OK
;
6462 /*******************************************************************
6464 ********************************************************************/
6466 NTSTATUS
_samr_SetDomainInfo(struct pipes_struct
*p
,
6467 struct samr_SetDomainInfo
*r
)
6470 uint32_t acc_required
= 0;
6472 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6474 switch (r
->in
.level
) {
6475 case 1: /* DomainPasswordInformation */
6476 case 12: /* DomainLockoutInformation */
6477 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6478 acc_required
= SAMR_DOMAIN_ACCESS_SET_INFO_1
;
6480 case 3: /* DomainLogoffInformation */
6481 case 4: /* DomainOemInformation */
6482 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6483 acc_required
= SAMR_DOMAIN_ACCESS_SET_INFO_2
;
6485 case 6: /* DomainReplicationInformation */
6486 case 9: /* DomainStateInformation */
6487 case 7: /* DomainServerRoleInformation */
6488 /* DOMAIN_ADMINISTER_SERVER */
6489 acc_required
= SAMR_DOMAIN_ACCESS_SET_INFO_3
;
6492 return NT_STATUS_INVALID_INFO_CLASS
;
6495 (void)policy_handle_find(p
, r
->in
.domain_handle
,
6497 struct samr_domain_info
, &status
);
6498 if (!NT_STATUS_IS_OK(status
)) {
6502 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r
->in
.level
));
6504 switch (r
->in
.level
) {
6506 status
= set_dom_info_1(p
->mem_ctx
, &r
->in
.info
->info1
);
6509 status
= set_dom_info_3(p
->mem_ctx
, &r
->in
.info
->info3
);
6520 status
= set_dom_info_12(p
->mem_ctx
, &r
->in
.info
->info12
);
6523 return NT_STATUS_INVALID_INFO_CLASS
;
6526 if (!NT_STATUS_IS_OK(status
)) {
6530 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6532 return NT_STATUS_OK
;
6535 /****************************************************************
6536 _samr_GetDisplayEnumerationIndex
6537 ****************************************************************/
6539 NTSTATUS
_samr_GetDisplayEnumerationIndex(struct pipes_struct
*p
,
6540 struct samr_GetDisplayEnumerationIndex
*r
)
6542 struct samr_domain_info
*dinfo
;
6543 uint32_t max_entries
= (uint32_t) -1;
6544 uint32_t enum_context
= 0;
6546 uint32_t num_account
= 0;
6547 struct samr_displayentry
*entries
= NULL
;
6550 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__
));
6552 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6553 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
6554 struct samr_domain_info
, &status
);
6555 if (!NT_STATUS_IS_OK(status
)) {
6559 if ((r
->in
.level
< 1) || (r
->in
.level
> 3)) {
6560 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6561 "Unknown info level (%u)\n",
6563 return NT_STATUS_INVALID_INFO_CLASS
;
6568 /* The following done as ROOT. Don't return without unbecome_root(). */
6570 switch (r
->in
.level
) {
6572 if (dinfo
->disp_info
->users
== NULL
) {
6573 dinfo
->disp_info
->users
= pdb_search_users(
6574 dinfo
->disp_info
, ACB_NORMAL
);
6575 if (dinfo
->disp_info
->users
== NULL
) {
6577 return NT_STATUS_ACCESS_DENIED
;
6579 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6580 "starting user enumeration at index %u\n",
6581 (unsigned int)enum_context
));
6583 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6584 "using cached user enumeration at index %u\n",
6585 (unsigned int)enum_context
));
6587 num_account
= pdb_search_entries(dinfo
->disp_info
->users
,
6588 enum_context
, max_entries
,
6592 if (dinfo
->disp_info
->machines
== NULL
) {
6593 dinfo
->disp_info
->machines
= pdb_search_users(
6594 dinfo
->disp_info
, ACB_WSTRUST
|ACB_SVRTRUST
);
6595 if (dinfo
->disp_info
->machines
== NULL
) {
6597 return NT_STATUS_ACCESS_DENIED
;
6599 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6600 "starting machine enumeration at index %u\n",
6601 (unsigned int)enum_context
));
6603 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6604 "using cached machine enumeration at index %u\n",
6605 (unsigned int)enum_context
));
6607 num_account
= pdb_search_entries(dinfo
->disp_info
->machines
,
6608 enum_context
, max_entries
,
6612 if (dinfo
->disp_info
->groups
== NULL
) {
6613 dinfo
->disp_info
->groups
= pdb_search_groups(
6615 if (dinfo
->disp_info
->groups
== NULL
) {
6617 return NT_STATUS_ACCESS_DENIED
;
6619 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6620 "starting group enumeration at index %u\n",
6621 (unsigned int)enum_context
));
6623 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6624 "using cached group enumeration at index %u\n",
6625 (unsigned int)enum_context
));
6627 num_account
= pdb_search_entries(dinfo
->disp_info
->groups
,
6628 enum_context
, max_entries
,
6633 smb_panic("info class changed");
6639 /* Ensure we cache this enumeration. */
6640 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
6642 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6643 r
->in
.name
->string
));
6645 for (i
=0; i
<num_account
; i
++) {
6646 if (strequal(entries
[i
].account_name
, r
->in
.name
->string
)) {
6647 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6648 "found %s at idx %d\n",
6649 r
->in
.name
->string
, i
));
6651 return NT_STATUS_OK
;
6655 /* assuming account_name lives at the very end */
6656 *r
->out
.idx
= num_account
;
6658 return NT_STATUS_NO_MORE_ENTRIES
;
6661 /****************************************************************
6662 _samr_GetDisplayEnumerationIndex2
6663 ****************************************************************/
6665 NTSTATUS
_samr_GetDisplayEnumerationIndex2(struct pipes_struct
*p
,
6666 struct samr_GetDisplayEnumerationIndex2
*r
)
6668 struct samr_GetDisplayEnumerationIndex q
;
6670 q
.in
.domain_handle
= r
->in
.domain_handle
;
6671 q
.in
.level
= r
->in
.level
;
6672 q
.in
.name
= r
->in
.name
;
6674 q
.out
.idx
= r
->out
.idx
;
6676 return _samr_GetDisplayEnumerationIndex(p
, &q
);
6679 /****************************************************************
6681 ****************************************************************/
6683 NTSTATUS
_samr_RidToSid(struct pipes_struct
*p
,
6684 struct samr_RidToSid
*r
)
6686 struct samr_domain_info
*dinfo
;
6690 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6692 struct samr_domain_info
, &status
);
6693 if (!NT_STATUS_IS_OK(status
)) {
6697 if (!sid_compose(&sid
, &dinfo
->sid
, r
->in
.rid
)) {
6698 return NT_STATUS_NO_MEMORY
;
6701 *r
->out
.sid
= dom_sid_dup(p
->mem_ctx
, &sid
);
6703 return NT_STATUS_NO_MEMORY
;
6706 return NT_STATUS_OK
;
6709 /****************************************************************
6710 ****************************************************************/
6712 static enum samr_ValidationStatus
samr_ValidatePassword_Change(TALLOC_CTX
*mem_ctx
,
6713 const struct samr_PwInfo
*dom_pw_info
,
6714 const struct samr_ValidatePasswordReq2
*req
,
6715 struct samr_ValidatePasswordRepCtr
*rep
)
6719 if (req
->password
.string
== NULL
) {
6720 return SAMR_VALIDATION_STATUS_SUCCESS
;
6722 if (strlen(req
->password
.string
) < dom_pw_info
->min_password_length
) {
6723 ZERO_STRUCT(rep
->info
);
6724 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT
;
6726 if (dom_pw_info
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
6727 status
= check_password_complexity(req
->account
.string
,
6728 NULL
, /* full_name */
6729 req
->password
.string
,
6731 if (!NT_STATUS_IS_OK(status
)) {
6732 ZERO_STRUCT(rep
->info
);
6733 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH
;
6737 return SAMR_VALIDATION_STATUS_SUCCESS
;
6740 /****************************************************************
6741 ****************************************************************/
6743 static enum samr_ValidationStatus
samr_ValidatePassword_Reset(TALLOC_CTX
*mem_ctx
,
6744 const struct samr_PwInfo
*dom_pw_info
,
6745 const struct samr_ValidatePasswordReq3
*req
,
6746 struct samr_ValidatePasswordRepCtr
*rep
)
6750 if (req
->password
.string
== NULL
) {
6751 return SAMR_VALIDATION_STATUS_SUCCESS
;
6753 if (strlen(req
->password
.string
) < dom_pw_info
->min_password_length
) {
6754 ZERO_STRUCT(rep
->info
);
6755 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT
;
6757 if (dom_pw_info
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
6758 status
= check_password_complexity(req
->account
.string
,
6759 NULL
, /* full_name */
6760 req
->password
.string
,
6762 if (!NT_STATUS_IS_OK(status
)) {
6763 ZERO_STRUCT(rep
->info
);
6764 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH
;
6768 return SAMR_VALIDATION_STATUS_SUCCESS
;
6771 /****************************************************************
6772 _samr_ValidatePassword
6773 ****************************************************************/
6775 NTSTATUS
_samr_ValidatePassword(struct pipes_struct
*p
,
6776 struct samr_ValidatePassword
*r
)
6778 union samr_ValidatePasswordRep
*rep
;
6780 struct samr_GetDomPwInfo pw
;
6781 struct samr_PwInfo dom_pw_info
;
6783 if (p
->transport
!= NCACN_IP_TCP
&& p
->transport
!= NCALRPC
) {
6784 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
6785 return NT_STATUS_ACCESS_DENIED
;
6788 if (p
->auth
.auth_level
!= DCERPC_AUTH_LEVEL_PRIVACY
) {
6789 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
6790 return NT_STATUS_ACCESS_DENIED
;
6793 if (r
->in
.level
< 1 || r
->in
.level
> 3) {
6794 return NT_STATUS_INVALID_INFO_CLASS
;
6797 pw
.in
.domain_name
= NULL
;
6798 pw
.out
.info
= &dom_pw_info
;
6800 status
= _samr_GetDomPwInfo(p
, &pw
);
6801 if (!NT_STATUS_IS_OK(status
)) {
6805 rep
= talloc_zero(p
->mem_ctx
, union samr_ValidatePasswordRep
);
6807 return NT_STATUS_NO_MEMORY
;
6810 switch (r
->in
.level
) {
6812 status
= NT_STATUS_NOT_SUPPORTED
;
6815 rep
->ctr2
.status
= samr_ValidatePassword_Change(p
->mem_ctx
,
6821 rep
->ctr3
.status
= samr_ValidatePassword_Reset(p
->mem_ctx
,
6827 status
= NT_STATUS_INVALID_INFO_CLASS
;
6831 if (!NT_STATUS_IS_OK(status
)) {
6838 return NT_STATUS_OK
;
6841 /****************************************************************
6842 ****************************************************************/
6844 NTSTATUS
_samr_Shutdown(struct pipes_struct
*p
,
6845 struct samr_Shutdown
*r
)
6847 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6848 return NT_STATUS_NOT_IMPLEMENTED
;
6851 /****************************************************************
6852 ****************************************************************/
6854 NTSTATUS
_samr_SetMemberAttributesOfGroup(struct pipes_struct
*p
,
6855 struct samr_SetMemberAttributesOfGroup
*r
)
6857 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6858 return NT_STATUS_NOT_IMPLEMENTED
;
6861 /****************************************************************
6862 ****************************************************************/
6864 NTSTATUS
_samr_TestPrivateFunctionsDomain(struct pipes_struct
*p
,
6865 struct samr_TestPrivateFunctionsDomain
*r
)
6867 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6868 return NT_STATUS_NOT_IMPLEMENTED
;
6871 /****************************************************************
6872 ****************************************************************/
6874 NTSTATUS
_samr_TestPrivateFunctionsUser(struct pipes_struct
*p
,
6875 struct samr_TestPrivateFunctionsUser
*r
)
6877 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6878 return NT_STATUS_NOT_IMPLEMENTED
;
6881 /****************************************************************
6882 ****************************************************************/
6884 NTSTATUS
_samr_AddMultipleMembersToAlias(struct pipes_struct
*p
,
6885 struct samr_AddMultipleMembersToAlias
*r
)
6887 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6888 return NT_STATUS_NOT_IMPLEMENTED
;
6891 /****************************************************************
6892 ****************************************************************/
6894 NTSTATUS
_samr_RemoveMultipleMembersFromAlias(struct pipes_struct
*p
,
6895 struct samr_RemoveMultipleMembersFromAlias
*r
)
6897 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6898 return NT_STATUS_NOT_IMPLEMENTED
;
6901 /****************************************************************
6902 ****************************************************************/
6904 NTSTATUS
_samr_SetBootKeyInformation(struct pipes_struct
*p
,
6905 struct samr_SetBootKeyInformation
*r
)
6907 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6908 return NT_STATUS_NOT_IMPLEMENTED
;
6911 /****************************************************************
6912 ****************************************************************/
6914 NTSTATUS
_samr_GetBootKeyInformation(struct pipes_struct
*p
,
6915 struct samr_GetBootKeyInformation
*r
)
6917 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6918 return NT_STATUS_NOT_IMPLEMENTED
;
6921 /****************************************************************
6922 ****************************************************************/
6924 NTSTATUS
_samr_SetDsrmPassword(struct pipes_struct
*p
,
6925 struct samr_SetDsrmPassword
*r
)
6927 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6928 return NT_STATUS_NOT_IMPLEMENTED
;