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"
50 #define DBGC_CLASS DBGC_RPC_SRV
52 #define SAMR_USR_RIGHTS_WRITE_PW \
53 ( READ_CONTROL_ACCESS | \
54 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
55 SAMR_USER_ACCESS_SET_LOC_COM)
56 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
57 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
59 #define DISP_INFO_CACHE_TIMEOUT 10
61 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
62 #define MAX_SAM_ENTRIES_W95 50
64 struct samr_connect_info
{
68 struct samr_domain_info
{
70 struct disp_info
*disp_info
;
73 struct samr_user_info
{
77 struct samr_group_info
{
81 struct samr_alias_info
{
85 typedef struct disp_info
{
86 struct dom_sid sid
; /* identify which domain this is. */
87 struct pdb_search
*users
; /* querydispinfo 1 and 4 */
88 struct pdb_search
*machines
; /* querydispinfo 2 */
89 struct pdb_search
*groups
; /* querydispinfo 3 and 5, enumgroups */
90 struct pdb_search
*aliases
; /* enumaliases */
92 uint32_t enum_acb_mask
;
93 struct pdb_search
*enum_users
; /* enumusers with a mask */
95 struct tevent_timer
*cache_timeout_event
; /* cache idle timeout
99 static const struct generic_mapping sam_generic_mapping
= {
100 GENERIC_RIGHTS_SAM_READ
,
101 GENERIC_RIGHTS_SAM_WRITE
,
102 GENERIC_RIGHTS_SAM_EXECUTE
,
103 GENERIC_RIGHTS_SAM_ALL_ACCESS
};
104 static const struct generic_mapping dom_generic_mapping
= {
105 GENERIC_RIGHTS_DOMAIN_READ
,
106 GENERIC_RIGHTS_DOMAIN_WRITE
,
107 GENERIC_RIGHTS_DOMAIN_EXECUTE
,
108 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS
};
109 static const struct generic_mapping usr_generic_mapping
= {
110 GENERIC_RIGHTS_USER_READ
,
111 GENERIC_RIGHTS_USER_WRITE
,
112 GENERIC_RIGHTS_USER_EXECUTE
,
113 GENERIC_RIGHTS_USER_ALL_ACCESS
};
114 static const struct generic_mapping usr_nopwchange_generic_mapping
= {
115 GENERIC_RIGHTS_USER_READ
,
116 GENERIC_RIGHTS_USER_WRITE
,
117 GENERIC_RIGHTS_USER_EXECUTE
& ~SAMR_USER_ACCESS_CHANGE_PASSWORD
,
118 GENERIC_RIGHTS_USER_ALL_ACCESS
};
119 static const struct generic_mapping grp_generic_mapping
= {
120 GENERIC_RIGHTS_GROUP_READ
,
121 GENERIC_RIGHTS_GROUP_WRITE
,
122 GENERIC_RIGHTS_GROUP_EXECUTE
,
123 GENERIC_RIGHTS_GROUP_ALL_ACCESS
};
124 static const struct generic_mapping ali_generic_mapping
= {
125 GENERIC_RIGHTS_ALIAS_READ
,
126 GENERIC_RIGHTS_ALIAS_WRITE
,
127 GENERIC_RIGHTS_ALIAS_EXECUTE
,
128 GENERIC_RIGHTS_ALIAS_ALL_ACCESS
};
130 /*******************************************************************
131 *******************************************************************/
133 static NTSTATUS
make_samr_object_sd( TALLOC_CTX
*ctx
, struct security_descriptor
**psd
, size_t *sd_size
,
134 const struct generic_mapping
*map
,
135 struct dom_sid
*sid
, uint32 sid_access
)
137 struct dom_sid domadmin_sid
;
138 struct security_ace ace
[5]; /* at most 5 entries */
141 struct security_acl
*psa
= NULL
;
143 /* basic access for Everyone */
145 init_sec_ace(&ace
[i
++], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
146 map
->generic_execute
| map
->generic_read
, 0);
148 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
150 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Administrators
,
151 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
152 init_sec_ace(&ace
[i
++], &global_sid_Builtin_Account_Operators
,
153 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
155 /* Add Full Access for Domain Admins if we are a DC */
158 sid_compose(&domadmin_sid
, get_global_sam_sid(),
160 init_sec_ace(&ace
[i
++], &domadmin_sid
,
161 SEC_ACE_TYPE_ACCESS_ALLOWED
, map
->generic_all
, 0);
164 /* if we have a sid, give it some special access */
167 init_sec_ace(&ace
[i
++], sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
, sid_access
, 0);
170 /* create the security descriptor */
172 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, i
, ace
)) == NULL
)
173 return NT_STATUS_NO_MEMORY
;
175 if ((*psd
= make_sec_desc(ctx
, SECURITY_DESCRIPTOR_REVISION_1
,
176 SEC_DESC_SELF_RELATIVE
, NULL
, NULL
, NULL
,
177 psa
, sd_size
)) == NULL
)
178 return NT_STATUS_NO_MEMORY
;
183 /*******************************************************************
184 Fetch or create a dispinfo struct.
185 ********************************************************************/
187 static DISP_INFO
*get_samr_dispinfo_by_sid(const struct dom_sid
*psid
)
190 * We do a static cache for DISP_INFO's here. Explanation can be found
191 * in Jeremy's checkin message to r11793:
193 * Fix the SAMR cache so it works across completely insane
194 * client behaviour (ie.:
195 * open pipe/open SAMR handle/enumerate 0 - 1024
196 * close SAMR handle, close pipe.
197 * open pipe/open SAMR handle/enumerate 1024 - 2048...
198 * close SAMR handle, close pipe.
199 * And on ad-nausium. Amazing.... probably object-oriented
200 * client side programming in action yet again.
201 * This change should *massively* improve performance when
202 * enumerating users from an LDAP database.
205 * "Our" and the builtin domain are the only ones where we ever
206 * enumerate stuff, so just cache 2 entries.
209 static struct disp_info
*builtin_dispinfo
;
210 static struct disp_info
*domain_dispinfo
;
212 /* There are two cases to consider here:
213 1) The SID is a domain SID and we look for an equality match, or
214 2) This is an account SID and so we return the DISP_INFO* for our
221 if (sid_check_is_builtin(psid
) || sid_check_is_in_builtin(psid
)) {
223 * Necessary only once, but it does not really hurt.
225 if (builtin_dispinfo
== NULL
) {
226 builtin_dispinfo
= talloc_zero(NULL
, struct disp_info
);
227 if (builtin_dispinfo
== NULL
) {
231 sid_copy(&builtin_dispinfo
->sid
, &global_sid_Builtin
);
233 return builtin_dispinfo
;
236 if (sid_check_is_our_sam(psid
) || sid_check_is_in_our_sam(psid
)) {
238 * Necessary only once, but it does not really hurt.
240 if (domain_dispinfo
== NULL
) {
241 domain_dispinfo
= talloc_zero(NULL
, struct disp_info
);
242 if (domain_dispinfo
== NULL
) {
246 sid_copy(&domain_dispinfo
->sid
, get_global_sam_sid());
248 return domain_dispinfo
;
254 /*******************************************************************
255 Function to free the per SID data.
256 ********************************************************************/
258 static void free_samr_cache(DISP_INFO
*disp_info
)
260 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
261 sid_string_dbg(&disp_info
->sid
)));
263 /* We need to become root here because the paged search might have to
264 * tell the LDAP server we're not interested in the rest anymore. */
268 TALLOC_FREE(disp_info
->users
);
269 TALLOC_FREE(disp_info
->machines
);
270 TALLOC_FREE(disp_info
->groups
);
271 TALLOC_FREE(disp_info
->aliases
);
272 TALLOC_FREE(disp_info
->enum_users
);
277 /*******************************************************************
278 Idle event handler. Throw away the disp info cache.
279 ********************************************************************/
281 static void disp_info_cache_idle_timeout_handler(struct tevent_context
*ev_ctx
,
282 struct tevent_timer
*te
,
286 DISP_INFO
*disp_info
= (DISP_INFO
*)private_data
;
288 TALLOC_FREE(disp_info
->cache_timeout_event
);
290 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
292 free_samr_cache(disp_info
);
295 /*******************************************************************
296 Setup cache removal idle event handler.
297 ********************************************************************/
299 static void set_disp_info_cache_timeout(DISP_INFO
*disp_info
, time_t secs_fromnow
)
301 /* Remove any pending timeout and update. */
303 TALLOC_FREE(disp_info
->cache_timeout_event
);
305 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
306 "SID %s for %u seconds\n", sid_string_dbg(&disp_info
->sid
),
307 (unsigned int)secs_fromnow
));
309 disp_info
->cache_timeout_event
= tevent_add_timer(
310 server_event_context(), NULL
,
311 timeval_current_ofs(secs_fromnow
, 0),
312 disp_info_cache_idle_timeout_handler
, (void *)disp_info
);
315 /*******************************************************************
316 Force flush any cache. We do this on any samr_set_xxx call.
317 We must also remove the timeout handler.
318 ********************************************************************/
320 static void force_flush_samr_cache(const struct dom_sid
*sid
)
322 struct disp_info
*disp_info
= get_samr_dispinfo_by_sid(sid
);
324 if ((disp_info
== NULL
) || (disp_info
->cache_timeout_event
== NULL
)) {
328 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
329 TALLOC_FREE(disp_info
->cache_timeout_event
);
330 free_samr_cache(disp_info
);
333 /*******************************************************************
334 Ensure password info is never given out. Paranioa... JRA.
335 ********************************************************************/
337 static void samr_clear_sam_passwd(struct samu
*sam_pass
)
343 /* These now zero out the old password */
345 pdb_set_lanman_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
346 pdb_set_nt_passwd(sam_pass
, NULL
, PDB_DEFAULT
);
349 static uint32
count_sam_users(struct disp_info
*info
, uint32 acct_flags
)
351 struct samr_displayentry
*entry
;
353 if (sid_check_is_builtin(&info
->sid
)) {
354 /* No users in builtin. */
358 if (info
->users
== NULL
) {
359 info
->users
= pdb_search_users(info
, acct_flags
);
360 if (info
->users
== NULL
) {
364 /* Fetch the last possible entry, thus trigger an enumeration */
365 pdb_search_entries(info
->users
, 0xffffffff, 1, &entry
);
367 /* Ensure we cache this enumeration. */
368 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
370 return info
->users
->num_entries
;
373 static uint32
count_sam_groups(struct disp_info
*info
)
375 struct samr_displayentry
*entry
;
377 if (sid_check_is_builtin(&info
->sid
)) {
378 /* No groups in builtin. */
382 if (info
->groups
== NULL
) {
383 info
->groups
= pdb_search_groups(info
);
384 if (info
->groups
== NULL
) {
388 /* Fetch the last possible entry, thus trigger an enumeration */
389 pdb_search_entries(info
->groups
, 0xffffffff, 1, &entry
);
391 /* Ensure we cache this enumeration. */
392 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
394 return info
->groups
->num_entries
;
397 static uint32
count_sam_aliases(struct disp_info
*info
)
399 struct samr_displayentry
*entry
;
401 if (info
->aliases
== NULL
) {
402 info
->aliases
= pdb_search_aliases(info
, &info
->sid
);
403 if (info
->aliases
== NULL
) {
407 /* Fetch the last possible entry, thus trigger an enumeration */
408 pdb_search_entries(info
->aliases
, 0xffffffff, 1, &entry
);
410 /* Ensure we cache this enumeration. */
411 set_disp_info_cache_timeout(info
, DISP_INFO_CACHE_TIMEOUT
);
413 return info
->aliases
->num_entries
;
416 /*******************************************************************
418 ********************************************************************/
420 NTSTATUS
_samr_Close(struct pipes_struct
*p
, struct samr_Close
*r
)
422 if (!close_policy_hnd(p
, r
->in
.handle
)) {
423 return NT_STATUS_INVALID_HANDLE
;
426 ZERO_STRUCTP(r
->out
.handle
);
431 /*******************************************************************
433 ********************************************************************/
435 NTSTATUS
_samr_OpenDomain(struct pipes_struct
*p
,
436 struct samr_OpenDomain
*r
)
438 struct samr_domain_info
*dinfo
;
439 struct security_descriptor
*psd
= NULL
;
441 uint32 des_access
= r
->in
.access_mask
;
444 uint32_t extra_access
= SAMR_DOMAIN_ACCESS_CREATE_USER
;
446 /* find the connection policy handle. */
448 (void)policy_handle_find(p
, r
->in
.connect_handle
, 0, NULL
,
449 struct samr_connect_info
, &status
);
450 if (!NT_STATUS_IS_OK(status
)) {
454 /*check if access can be granted as requested by client. */
455 map_max_allowed_access(p
->session_info
->security_token
,
456 p
->session_info
->unix_token
,
459 make_samr_object_sd( p
->mem_ctx
, &psd
, &sd_size
, &dom_generic_mapping
, NULL
, 0 );
460 se_map_generic( &des_access
, &dom_generic_mapping
);
463 * Users with SeAddUser get the ability to manipulate groups
466 if (security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_ADD_USERS
)) {
467 extra_access
|= (SAMR_DOMAIN_ACCESS_CREATE_GROUP
|
468 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
469 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
470 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
|
471 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
);
475 * Users with SeMachineAccount or SeAddUser get additional
476 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
479 status
= access_check_object( psd
, p
->session_info
->security_token
,
480 SEC_PRIV_MACHINE_ACCOUNT
, SEC_PRIV_ADD_USERS
,
481 extra_access
, des_access
,
482 &acc_granted
, "_samr_OpenDomain" );
484 if ( !NT_STATUS_IS_OK(status
) )
487 if (!sid_check_is_our_sam(r
->in
.sid
) &&
488 !sid_check_is_builtin(r
->in
.sid
)) {
489 return NT_STATUS_NO_SUCH_DOMAIN
;
492 dinfo
= policy_handle_create(p
, r
->out
.domain_handle
, acc_granted
,
493 struct samr_domain_info
, &status
);
494 if (!NT_STATUS_IS_OK(status
)) {
497 dinfo
->sid
= *r
->in
.sid
;
498 dinfo
->disp_info
= get_samr_dispinfo_by_sid(r
->in
.sid
);
500 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__
));
505 /*******************************************************************
507 ********************************************************************/
509 NTSTATUS
_samr_GetUserPwInfo(struct pipes_struct
*p
,
510 struct samr_GetUserPwInfo
*r
)
512 struct samr_user_info
*uinfo
;
513 enum lsa_SidType sid_type
;
514 uint32_t min_password_length
= 0;
515 uint32_t password_properties
= 0;
519 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__
));
521 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
522 SAMR_USER_ACCESS_GET_ATTRIBUTES
, NULL
,
523 struct samr_user_info
, &status
);
524 if (!NT_STATUS_IS_OK(status
)) {
528 if (!sid_check_is_in_our_sam(&uinfo
->sid
)) {
529 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
533 ret
= lookup_sid(p
->mem_ctx
, &uinfo
->sid
, NULL
, NULL
, &sid_type
);
536 return NT_STATUS_NO_SUCH_USER
;
542 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN
,
543 &min_password_length
);
544 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS
,
545 &password_properties
);
548 if (lp_check_password_script(talloc_tos())
549 && *lp_check_password_script(talloc_tos())) {
550 password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
558 r
->out
.info
->min_password_length
= min_password_length
;
559 r
->out
.info
->password_properties
= password_properties
;
561 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__
));
566 /*******************************************************************
568 ********************************************************************/
570 NTSTATUS
_samr_SetSecurity(struct pipes_struct
*p
,
571 struct samr_SetSecurity
*r
)
573 struct samr_user_info
*uinfo
;
575 struct security_acl
*dacl
;
577 struct samu
*sampass
=NULL
;
580 uinfo
= policy_handle_find(p
, r
->in
.handle
,
581 SAMR_USER_ACCESS_SET_ATTRIBUTES
, NULL
,
582 struct samr_user_info
, &status
);
583 if (!NT_STATUS_IS_OK(status
)) {
587 if (!(sampass
= samu_new( p
->mem_ctx
))) {
588 DEBUG(0,("No memory!\n"));
589 return NT_STATUS_NO_MEMORY
;
592 /* get the user record */
594 ret
= pdb_getsampwsid(sampass
, &uinfo
->sid
);
598 DEBUG(4, ("User %s not found\n",
599 sid_string_dbg(&uinfo
->sid
)));
600 TALLOC_FREE(sampass
);
601 return NT_STATUS_INVALID_HANDLE
;
604 dacl
= r
->in
.sdbuf
->sd
->dacl
;
605 for (i
=0; i
< dacl
->num_aces
; i
++) {
606 if (dom_sid_equal(&uinfo
->sid
, &dacl
->aces
[i
].trustee
)) {
607 ret
= pdb_set_pass_can_change(sampass
,
608 (dacl
->aces
[i
].access_mask
&
609 SAMR_USER_ACCESS_CHANGE_PASSWORD
) ?
616 TALLOC_FREE(sampass
);
617 return NT_STATUS_ACCESS_DENIED
;
621 status
= pdb_update_sam_account(sampass
);
624 TALLOC_FREE(sampass
);
629 /*******************************************************************
630 build correct perms based on policies and password times for _samr_query_sec_obj
631 *******************************************************************/
632 static bool check_change_pw_access(TALLOC_CTX
*mem_ctx
, struct dom_sid
*user_sid
)
634 struct samu
*sampass
=NULL
;
637 if ( !(sampass
= samu_new( mem_ctx
)) ) {
638 DEBUG(0,("No memory!\n"));
643 ret
= pdb_getsampwsid(sampass
, user_sid
);
647 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid
)));
648 TALLOC_FREE(sampass
);
652 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass
) ));
654 if (pdb_get_pass_can_change(sampass
)) {
655 TALLOC_FREE(sampass
);
658 TALLOC_FREE(sampass
);
663 /*******************************************************************
665 ********************************************************************/
667 NTSTATUS
_samr_QuerySecurity(struct pipes_struct
*p
,
668 struct samr_QuerySecurity
*r
)
670 struct samr_domain_info
*dinfo
;
671 struct samr_user_info
*uinfo
;
672 struct samr_group_info
*ginfo
;
673 struct samr_alias_info
*ainfo
;
675 struct security_descriptor
* psd
= NULL
;
678 (void)policy_handle_find(p
, r
->in
.handle
,
679 SEC_STD_READ_CONTROL
, NULL
,
680 struct samr_connect_info
, &status
);
681 if (NT_STATUS_IS_OK(status
)) {
682 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
683 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
684 &sam_generic_mapping
, NULL
, 0);
688 dinfo
= policy_handle_find(p
, r
->in
.handle
,
689 SEC_STD_READ_CONTROL
, NULL
,
690 struct samr_domain_info
, &status
);
691 if (NT_STATUS_IS_OK(status
)) {
692 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
693 "with SID: %s\n", sid_string_dbg(&dinfo
->sid
)));
695 * TODO: Builtin probably needs a different SD with restricted
698 status
= make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
,
699 &dom_generic_mapping
, NULL
, 0);
703 uinfo
= policy_handle_find(p
, r
->in
.handle
,
704 SEC_STD_READ_CONTROL
, NULL
,
705 struct samr_user_info
, &status
);
706 if (NT_STATUS_IS_OK(status
)) {
707 DEBUG(10,("_samr_QuerySecurity: querying security on user "
708 "Object with SID: %s\n",
709 sid_string_dbg(&uinfo
->sid
)));
710 if (check_change_pw_access(p
->mem_ctx
, &uinfo
->sid
)) {
711 status
= make_samr_object_sd(
712 p
->mem_ctx
, &psd
, &sd_size
,
713 &usr_generic_mapping
,
714 &uinfo
->sid
, SAMR_USR_RIGHTS_WRITE_PW
);
716 status
= make_samr_object_sd(
717 p
->mem_ctx
, &psd
, &sd_size
,
718 &usr_nopwchange_generic_mapping
,
719 &uinfo
->sid
, SAMR_USR_RIGHTS_CANT_WRITE_PW
);
724 ginfo
= policy_handle_find(p
, r
->in
.handle
,
725 SEC_STD_READ_CONTROL
, NULL
,
726 struct samr_group_info
, &status
);
727 if (NT_STATUS_IS_OK(status
)) {
729 * TODO: different SDs have to be generated for aliases groups
730 * and users. Currently all three get a default user SD
732 DEBUG(10,("_samr_QuerySecurity: querying security on group "
733 "Object with SID: %s\n",
734 sid_string_dbg(&ginfo
->sid
)));
735 status
= make_samr_object_sd(
736 p
->mem_ctx
, &psd
, &sd_size
,
737 &usr_nopwchange_generic_mapping
,
738 &ginfo
->sid
, SAMR_USR_RIGHTS_CANT_WRITE_PW
);
742 ainfo
= policy_handle_find(p
, r
->in
.handle
,
743 SEC_STD_READ_CONTROL
, NULL
,
744 struct samr_alias_info
, &status
);
745 if (NT_STATUS_IS_OK(status
)) {
747 * TODO: different SDs have to be generated for aliases groups
748 * and users. Currently all three get a default user SD
750 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
751 "Object with SID: %s\n",
752 sid_string_dbg(&ainfo
->sid
)));
753 status
= make_samr_object_sd(
754 p
->mem_ctx
, &psd
, &sd_size
,
755 &usr_nopwchange_generic_mapping
,
756 &ainfo
->sid
, SAMR_USR_RIGHTS_CANT_WRITE_PW
);
760 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
762 if ((*r
->out
.sdbuf
= make_sec_desc_buf(p
->mem_ctx
, sd_size
, psd
)) == NULL
)
763 return NT_STATUS_NO_MEMORY
;
768 /*******************************************************************
769 makes a SAM_ENTRY / UNISTR2* structure from a user list.
770 ********************************************************************/
772 static NTSTATUS
make_user_sam_entry_list(TALLOC_CTX
*ctx
,
773 struct samr_SamEntry
**sam_pp
,
774 uint32_t num_entries
,
776 struct samr_displayentry
*entries
)
779 struct samr_SamEntry
*sam
;
783 if (num_entries
== 0) {
787 sam
= talloc_zero_array(ctx
, struct samr_SamEntry
, num_entries
);
789 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
790 return NT_STATUS_NO_MEMORY
;
793 for (i
= 0; i
< num_entries
; i
++) {
796 * usrmgr expects a non-NULL terminated string with
797 * trust relationships
799 if (entries
[i
].acct_flags
& ACB_DOMTRUST
) {
800 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
803 init_unistr2(&uni_temp_name
, entries
[i
].account_name
,
807 init_lsa_String(&sam
[i
].name
, entries
[i
].account_name
);
808 sam
[i
].idx
= entries
[i
].rid
;
816 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
818 /*******************************************************************
819 _samr_EnumDomainUsers
820 ********************************************************************/
822 NTSTATUS
_samr_EnumDomainUsers(struct pipes_struct
*p
,
823 struct samr_EnumDomainUsers
*r
)
826 struct samr_domain_info
*dinfo
;
828 uint32 enum_context
= *r
->in
.resume_handle
;
829 enum remote_arch_types ra_type
= get_remote_arch();
830 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
831 uint32 max_entries
= max_sam_entries
;
832 struct samr_displayentry
*entries
= NULL
;
833 struct samr_SamArray
*samr_array
= NULL
;
834 struct samr_SamEntry
*samr_entries
= NULL
;
836 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__
));
838 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
839 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
840 struct samr_domain_info
, &status
);
841 if (!NT_STATUS_IS_OK(status
)) {
845 samr_array
= talloc_zero(p
->mem_ctx
, struct samr_SamArray
);
847 return NT_STATUS_NO_MEMORY
;
849 *r
->out
.sam
= samr_array
;
851 if (sid_check_is_builtin(&dinfo
->sid
)) {
852 /* No users in builtin. */
853 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
854 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
862 if ((dinfo
->disp_info
->enum_users
!= NULL
) &&
863 (dinfo
->disp_info
->enum_acb_mask
!= r
->in
.acct_flags
)) {
864 TALLOC_FREE(dinfo
->disp_info
->enum_users
);
867 if (dinfo
->disp_info
->enum_users
== NULL
) {
868 dinfo
->disp_info
->enum_users
= pdb_search_users(
869 dinfo
->disp_info
, r
->in
.acct_flags
);
870 dinfo
->disp_info
->enum_acb_mask
= r
->in
.acct_flags
;
873 if (dinfo
->disp_info
->enum_users
== NULL
) {
874 /* END AS ROOT !!!! */
876 return NT_STATUS_ACCESS_DENIED
;
879 num_account
= pdb_search_entries(dinfo
->disp_info
->enum_users
,
880 enum_context
, max_entries
,
883 /* END AS ROOT !!!! */
887 if (num_account
== 0) {
888 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
890 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
894 status
= make_user_sam_entry_list(p
->mem_ctx
, &samr_entries
,
895 num_account
, enum_context
,
897 if (!NT_STATUS_IS_OK(status
)) {
901 if (max_entries
<= num_account
) {
902 status
= STATUS_MORE_ENTRIES
;
904 status
= NT_STATUS_OK
;
907 /* Ensure we cache this enumeration. */
908 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
910 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__
));
912 samr_array
->count
= num_account
;
913 samr_array
->entries
= samr_entries
;
915 *r
->out
.resume_handle
= *r
->in
.resume_handle
+ num_account
;
916 *r
->out
.num_entries
= num_account
;
918 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__
));
923 /*******************************************************************
924 makes a SAM_ENTRY / UNISTR2* structure from a group list.
925 ********************************************************************/
927 static void make_group_sam_entry_list(TALLOC_CTX
*ctx
,
928 struct samr_SamEntry
**sam_pp
,
929 uint32_t num_sam_entries
,
930 struct samr_displayentry
*entries
)
932 struct samr_SamEntry
*sam
;
937 if (num_sam_entries
== 0) {
941 sam
= talloc_zero_array(ctx
, struct samr_SamEntry
, num_sam_entries
);
946 for (i
= 0; i
< num_sam_entries
; i
++) {
948 * JRA. I think this should include the null. TNG does not.
950 init_lsa_String(&sam
[i
].name
, entries
[i
].account_name
);
951 sam
[i
].idx
= entries
[i
].rid
;
957 /*******************************************************************
958 _samr_EnumDomainGroups
959 ********************************************************************/
961 NTSTATUS
_samr_EnumDomainGroups(struct pipes_struct
*p
,
962 struct samr_EnumDomainGroups
*r
)
965 struct samr_domain_info
*dinfo
;
966 struct samr_displayentry
*groups
;
968 struct samr_SamArray
*samr_array
= NULL
;
969 struct samr_SamEntry
*samr_entries
= NULL
;
971 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
972 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
973 struct samr_domain_info
, &status
);
974 if (!NT_STATUS_IS_OK(status
)) {
978 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__
));
980 samr_array
= talloc_zero(p
->mem_ctx
, struct samr_SamArray
);
982 return NT_STATUS_NO_MEMORY
;
984 *r
->out
.sam
= samr_array
;
986 if (sid_check_is_builtin(&dinfo
->sid
)) {
987 /* No groups in builtin. */
988 *r
->out
.resume_handle
= *r
->in
.resume_handle
;
989 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
993 /* the domain group array is being allocated in the function below */
997 if (dinfo
->disp_info
->groups
== NULL
) {
998 dinfo
->disp_info
->groups
= pdb_search_groups(dinfo
->disp_info
);
1000 if (dinfo
->disp_info
->groups
== NULL
) {
1002 return NT_STATUS_ACCESS_DENIED
;
1006 num_groups
= pdb_search_entries(dinfo
->disp_info
->groups
,
1007 *r
->in
.resume_handle
,
1008 MAX_SAM_ENTRIES
, &groups
);
1011 /* Ensure we cache this enumeration. */
1012 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1014 make_group_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1015 num_groups
, groups
);
1017 if (MAX_SAM_ENTRIES
<= num_groups
) {
1018 status
= STATUS_MORE_ENTRIES
;
1020 status
= NT_STATUS_OK
;
1023 samr_array
->count
= num_groups
;
1024 samr_array
->entries
= samr_entries
;
1026 *r
->out
.num_entries
= num_groups
;
1027 *r
->out
.resume_handle
= num_groups
+ *r
->in
.resume_handle
;
1029 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__
));
1034 /*******************************************************************
1035 _samr_EnumDomainAliases
1036 ********************************************************************/
1038 NTSTATUS
_samr_EnumDomainAliases(struct pipes_struct
*p
,
1039 struct samr_EnumDomainAliases
*r
)
1042 struct samr_domain_info
*dinfo
;
1043 struct samr_displayentry
*aliases
;
1044 uint32 num_aliases
= 0;
1045 struct samr_SamArray
*samr_array
= NULL
;
1046 struct samr_SamEntry
*samr_entries
= NULL
;
1048 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
1049 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
1050 struct samr_domain_info
, &status
);
1051 if (!NT_STATUS_IS_OK(status
)) {
1055 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1056 sid_string_dbg(&dinfo
->sid
)));
1058 samr_array
= talloc_zero(p
->mem_ctx
, struct samr_SamArray
);
1060 return NT_STATUS_NO_MEMORY
;
1065 if (dinfo
->disp_info
->aliases
== NULL
) {
1066 dinfo
->disp_info
->aliases
= pdb_search_aliases(
1067 dinfo
->disp_info
, &dinfo
->sid
);
1068 if (dinfo
->disp_info
->aliases
== NULL
) {
1070 return NT_STATUS_ACCESS_DENIED
;
1074 num_aliases
= pdb_search_entries(dinfo
->disp_info
->aliases
,
1075 *r
->in
.resume_handle
,
1076 MAX_SAM_ENTRIES
, &aliases
);
1079 /* Ensure we cache this enumeration. */
1080 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1082 make_group_sam_entry_list(p
->mem_ctx
, &samr_entries
,
1083 num_aliases
, aliases
);
1085 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__
));
1087 if (MAX_SAM_ENTRIES
<= num_aliases
) {
1088 status
= STATUS_MORE_ENTRIES
;
1090 status
= NT_STATUS_OK
;
1093 samr_array
->count
= num_aliases
;
1094 samr_array
->entries
= samr_entries
;
1096 *r
->out
.sam
= samr_array
;
1097 *r
->out
.num_entries
= num_aliases
;
1098 *r
->out
.resume_handle
= num_aliases
+ *r
->in
.resume_handle
;
1103 /*******************************************************************
1104 inits a samr_DispInfoGeneral structure.
1105 ********************************************************************/
1107 static NTSTATUS
init_samr_dispinfo_1(TALLOC_CTX
*ctx
,
1108 struct samr_DispInfoGeneral
*r
,
1109 uint32_t num_entries
,
1111 struct samr_displayentry
*entries
)
1115 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries
));
1117 if (num_entries
== 0) {
1118 return NT_STATUS_OK
;
1121 r
->count
= num_entries
;
1123 r
->entries
= talloc_zero_array(ctx
, struct samr_DispEntryGeneral
, num_entries
);
1125 return NT_STATUS_NO_MEMORY
;
1128 for (i
= 0; i
< num_entries
; i
++) {
1130 init_lsa_String(&r
->entries
[i
].account_name
,
1131 entries
[i
].account_name
);
1133 init_lsa_String(&r
->entries
[i
].description
,
1134 entries
[i
].description
);
1136 init_lsa_String(&r
->entries
[i
].full_name
,
1137 entries
[i
].fullname
);
1139 r
->entries
[i
].rid
= entries
[i
].rid
;
1140 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1141 r
->entries
[i
].idx
= start_idx
+i
+1;
1144 return NT_STATUS_OK
;
1147 /*******************************************************************
1148 inits a samr_DispInfoFull structure.
1149 ********************************************************************/
1151 static NTSTATUS
init_samr_dispinfo_2(TALLOC_CTX
*ctx
,
1152 struct samr_DispInfoFull
*r
,
1153 uint32_t num_entries
,
1155 struct samr_displayentry
*entries
)
1159 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries
));
1161 if (num_entries
== 0) {
1162 return NT_STATUS_OK
;
1165 r
->count
= num_entries
;
1167 r
->entries
= talloc_zero_array(ctx
, struct samr_DispEntryFull
, num_entries
);
1169 return NT_STATUS_NO_MEMORY
;
1172 for (i
= 0; i
< num_entries
; i
++) {
1174 init_lsa_String(&r
->entries
[i
].account_name
,
1175 entries
[i
].account_name
);
1177 init_lsa_String(&r
->entries
[i
].description
,
1178 entries
[i
].description
);
1180 r
->entries
[i
].rid
= entries
[i
].rid
;
1181 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1182 r
->entries
[i
].idx
= start_idx
+i
+1;
1185 return NT_STATUS_OK
;
1188 /*******************************************************************
1189 inits a samr_DispInfoFullGroups structure.
1190 ********************************************************************/
1192 static NTSTATUS
init_samr_dispinfo_3(TALLOC_CTX
*ctx
,
1193 struct samr_DispInfoFullGroups
*r
,
1194 uint32_t num_entries
,
1196 struct samr_displayentry
*entries
)
1200 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries
));
1202 if (num_entries
== 0) {
1203 return NT_STATUS_OK
;
1206 r
->count
= num_entries
;
1208 r
->entries
= talloc_zero_array(ctx
, struct samr_DispEntryFullGroup
, num_entries
);
1210 return NT_STATUS_NO_MEMORY
;
1213 for (i
= 0; i
< num_entries
; i
++) {
1215 init_lsa_String(&r
->entries
[i
].account_name
,
1216 entries
[i
].account_name
);
1218 init_lsa_String(&r
->entries
[i
].description
,
1219 entries
[i
].description
);
1221 r
->entries
[i
].rid
= entries
[i
].rid
;
1222 r
->entries
[i
].acct_flags
= entries
[i
].acct_flags
;
1223 r
->entries
[i
].idx
= start_idx
+i
+1;
1226 return NT_STATUS_OK
;
1229 /*******************************************************************
1230 inits a samr_DispInfoAscii structure.
1231 ********************************************************************/
1233 static NTSTATUS
init_samr_dispinfo_4(TALLOC_CTX
*ctx
,
1234 struct samr_DispInfoAscii
*r
,
1235 uint32_t num_entries
,
1237 struct samr_displayentry
*entries
)
1241 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries
));
1243 if (num_entries
== 0) {
1244 return NT_STATUS_OK
;
1247 r
->count
= num_entries
;
1249 r
->entries
= talloc_zero_array(ctx
, struct samr_DispEntryAscii
, num_entries
);
1251 return NT_STATUS_NO_MEMORY
;
1254 for (i
= 0; i
< num_entries
; i
++) {
1256 init_lsa_AsciiStringLarge(&r
->entries
[i
].account_name
,
1257 entries
[i
].account_name
);
1259 r
->entries
[i
].idx
= start_idx
+i
+1;
1262 return NT_STATUS_OK
;
1265 /*******************************************************************
1266 inits a samr_DispInfoAscii structure.
1267 ********************************************************************/
1269 static NTSTATUS
init_samr_dispinfo_5(TALLOC_CTX
*ctx
,
1270 struct samr_DispInfoAscii
*r
,
1271 uint32_t num_entries
,
1273 struct samr_displayentry
*entries
)
1277 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries
));
1279 if (num_entries
== 0) {
1280 return NT_STATUS_OK
;
1283 r
->count
= num_entries
;
1285 r
->entries
= talloc_zero_array(ctx
, struct samr_DispEntryAscii
, num_entries
);
1287 return NT_STATUS_NO_MEMORY
;
1290 for (i
= 0; i
< num_entries
; i
++) {
1292 init_lsa_AsciiStringLarge(&r
->entries
[i
].account_name
,
1293 entries
[i
].account_name
);
1295 r
->entries
[i
].idx
= start_idx
+i
+1;
1298 return NT_STATUS_OK
;
1301 /*******************************************************************
1302 _samr_QueryDisplayInfo
1303 ********************************************************************/
1305 NTSTATUS
_samr_QueryDisplayInfo(struct pipes_struct
*p
,
1306 struct samr_QueryDisplayInfo
*r
)
1309 struct samr_domain_info
*dinfo
;
1310 uint32 struct_size
=0x20; /* W2K always reply that, client doesn't care */
1312 uint32 max_entries
= r
->in
.max_entries
;
1314 union samr_DispInfo
*disp_info
= r
->out
.info
;
1317 NTSTATUS disp_ret
= NT_STATUS_UNSUCCESSFUL
;
1318 uint32 num_account
= 0;
1319 enum remote_arch_types ra_type
= get_remote_arch();
1320 int max_sam_entries
= (ra_type
== RA_WIN95
) ? MAX_SAM_ENTRIES_W95
: MAX_SAM_ENTRIES_W2K
;
1321 struct samr_displayentry
*entries
= NULL
;
1323 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__
));
1325 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
1326 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
1327 struct samr_domain_info
, &status
);
1328 if (!NT_STATUS_IS_OK(status
)) {
1332 if (sid_check_is_builtin(&dinfo
->sid
)) {
1333 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1334 return NT_STATUS_OK
;
1338 * calculate how many entries we will return.
1340 * - the number of entries the client asked
1341 * - our limit on that
1342 * - the starting point (enumeration context)
1343 * - the buffer size the client will accept
1347 * We are a lot more like W2K. Instead of reading the SAM
1348 * each time to find the records we need to send back,
1349 * we read it once and link that copy to the sam handle.
1350 * For large user list (over the MAX_SAM_ENTRIES)
1351 * it's a definitive win.
1352 * second point to notice: between enumerations
1353 * our sam is now the same as it's a snapshoot.
1354 * third point: got rid of the static SAM_USER_21 struct
1355 * no more intermediate.
1356 * con: it uses much more memory, as a full copy is stored
1359 * If you want to change it, think twice and think
1360 * of the second point , that's really important.
1365 if ((r
->in
.level
< 1) || (r
->in
.level
> 5)) {
1366 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1367 (unsigned int)r
->in
.level
));
1368 return NT_STATUS_INVALID_INFO_CLASS
;
1371 /* first limit the number of entries we will return */
1372 if (r
->in
.max_entries
> max_sam_entries
) {
1373 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1374 "entries, limiting to %d\n", r
->in
.max_entries
,
1376 max_entries
= max_sam_entries
;
1379 /* calculate the size and limit on the number of entries we will
1382 temp_size
=max_entries
*struct_size
;
1384 if (temp_size
> r
->in
.buf_size
) {
1385 max_entries
= MIN((r
->in
.buf_size
/ struct_size
),max_entries
);
1386 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1387 "only %d entries\n", max_entries
));
1392 /* THe following done as ROOT. Don't return without unbecome_root(). */
1394 switch (r
->in
.level
) {
1397 if (dinfo
->disp_info
->users
== NULL
) {
1398 dinfo
->disp_info
->users
= pdb_search_users(
1399 dinfo
->disp_info
, ACB_NORMAL
);
1400 if (dinfo
->disp_info
->users
== NULL
) {
1402 return NT_STATUS_ACCESS_DENIED
;
1404 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1405 (unsigned int)r
->in
.start_idx
));
1407 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1408 (unsigned int)r
->in
.start_idx
));
1411 num_account
= pdb_search_entries(dinfo
->disp_info
->users
,
1412 r
->in
.start_idx
, max_entries
,
1416 if (dinfo
->disp_info
->machines
== NULL
) {
1417 dinfo
->disp_info
->machines
= pdb_search_users(
1418 dinfo
->disp_info
, ACB_WSTRUST
|ACB_SVRTRUST
);
1419 if (dinfo
->disp_info
->machines
== NULL
) {
1421 return NT_STATUS_ACCESS_DENIED
;
1423 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1424 (unsigned int)r
->in
.start_idx
));
1426 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1427 (unsigned int)r
->in
.start_idx
));
1430 num_account
= pdb_search_entries(dinfo
->disp_info
->machines
,
1431 r
->in
.start_idx
, max_entries
,
1436 if (dinfo
->disp_info
->groups
== NULL
) {
1437 dinfo
->disp_info
->groups
= pdb_search_groups(
1439 if (dinfo
->disp_info
->groups
== NULL
) {
1441 return NT_STATUS_ACCESS_DENIED
;
1443 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1444 (unsigned int)r
->in
.start_idx
));
1446 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1447 (unsigned int)r
->in
.start_idx
));
1450 num_account
= pdb_search_entries(dinfo
->disp_info
->groups
,
1451 r
->in
.start_idx
, max_entries
,
1456 smb_panic("info class changed");
1462 /* Now create reply structure */
1463 switch (r
->in
.level
) {
1465 disp_ret
= init_samr_dispinfo_1(p
->mem_ctx
, &disp_info
->info1
,
1466 num_account
, r
->in
.start_idx
,
1470 disp_ret
= init_samr_dispinfo_2(p
->mem_ctx
, &disp_info
->info2
,
1471 num_account
, r
->in
.start_idx
,
1475 disp_ret
= init_samr_dispinfo_3(p
->mem_ctx
, &disp_info
->info3
,
1476 num_account
, r
->in
.start_idx
,
1480 disp_ret
= init_samr_dispinfo_4(p
->mem_ctx
, &disp_info
->info4
,
1481 num_account
, r
->in
.start_idx
,
1485 disp_ret
= init_samr_dispinfo_5(p
->mem_ctx
, &disp_info
->info5
,
1486 num_account
, r
->in
.start_idx
,
1490 smb_panic("info class changed");
1494 if (!NT_STATUS_IS_OK(disp_ret
))
1497 if (max_entries
<= num_account
) {
1498 status
= STATUS_MORE_ENTRIES
;
1500 status
= NT_STATUS_OK
;
1503 /* Ensure we cache this enumeration. */
1504 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
1506 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__
));
1508 *r
->out
.total_size
= num_account
* struct_size
;
1509 *r
->out
.returned_size
= num_account
? temp_size
: 0;
1514 /****************************************************************
1515 _samr_QueryDisplayInfo2
1516 ****************************************************************/
1518 NTSTATUS
_samr_QueryDisplayInfo2(struct pipes_struct
*p
,
1519 struct samr_QueryDisplayInfo2
*r
)
1521 struct samr_QueryDisplayInfo q
;
1523 q
.in
.domain_handle
= r
->in
.domain_handle
;
1524 q
.in
.level
= r
->in
.level
;
1525 q
.in
.start_idx
= r
->in
.start_idx
;
1526 q
.in
.max_entries
= r
->in
.max_entries
;
1527 q
.in
.buf_size
= r
->in
.buf_size
;
1529 q
.out
.total_size
= r
->out
.total_size
;
1530 q
.out
.returned_size
= r
->out
.returned_size
;
1531 q
.out
.info
= r
->out
.info
;
1533 return _samr_QueryDisplayInfo(p
, &q
);
1536 /****************************************************************
1537 _samr_QueryDisplayInfo3
1538 ****************************************************************/
1540 NTSTATUS
_samr_QueryDisplayInfo3(struct pipes_struct
*p
,
1541 struct samr_QueryDisplayInfo3
*r
)
1543 struct samr_QueryDisplayInfo q
;
1545 q
.in
.domain_handle
= r
->in
.domain_handle
;
1546 q
.in
.level
= r
->in
.level
;
1547 q
.in
.start_idx
= r
->in
.start_idx
;
1548 q
.in
.max_entries
= r
->in
.max_entries
;
1549 q
.in
.buf_size
= r
->in
.buf_size
;
1551 q
.out
.total_size
= r
->out
.total_size
;
1552 q
.out
.returned_size
= r
->out
.returned_size
;
1553 q
.out
.info
= r
->out
.info
;
1555 return _samr_QueryDisplayInfo(p
, &q
);
1558 /*******************************************************************
1559 _samr_QueryAliasInfo
1560 ********************************************************************/
1562 NTSTATUS
_samr_QueryAliasInfo(struct pipes_struct
*p
,
1563 struct samr_QueryAliasInfo
*r
)
1565 struct samr_alias_info
*ainfo
;
1566 struct acct_info
*info
;
1568 union samr_AliasInfo
*alias_info
= NULL
;
1569 const char *alias_name
= NULL
;
1570 const char *alias_description
= NULL
;
1572 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__
));
1574 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
1575 SAMR_ALIAS_ACCESS_LOOKUP_INFO
, NULL
,
1576 struct samr_alias_info
, &status
);
1577 if (!NT_STATUS_IS_OK(status
)) {
1581 alias_info
= talloc_zero(p
->mem_ctx
, union samr_AliasInfo
);
1583 return NT_STATUS_NO_MEMORY
;
1586 info
= talloc_zero(p
->mem_ctx
, struct acct_info
);
1588 return NT_STATUS_NO_MEMORY
;
1592 status
= pdb_get_aliasinfo(&ainfo
->sid
, info
);
1595 if (!NT_STATUS_IS_OK(status
)) {
1600 alias_name
= talloc_steal(r
, info
->acct_name
);
1601 alias_description
= talloc_steal(r
, info
->acct_desc
);
1604 switch (r
->in
.level
) {
1606 alias_info
->all
.name
.string
= alias_name
;
1607 alias_info
->all
.num_members
= 1; /* ??? */
1608 alias_info
->all
.description
.string
= alias_description
;
1611 alias_info
->name
.string
= alias_name
;
1613 case ALIASINFODESCRIPTION
:
1614 alias_info
->description
.string
= alias_description
;
1617 return NT_STATUS_INVALID_INFO_CLASS
;
1620 *r
->out
.info
= alias_info
;
1622 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__
));
1624 return NT_STATUS_OK
;
1627 /*******************************************************************
1629 ********************************************************************/
1631 NTSTATUS
_samr_LookupNames(struct pipes_struct
*p
,
1632 struct samr_LookupNames
*r
)
1634 struct samr_domain_info
*dinfo
;
1637 enum lsa_SidType
*type
;
1639 int num_rids
= r
->in
.num_names
;
1640 struct samr_Ids rids
, types
;
1641 uint32_t num_mapped
= 0;
1643 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1645 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
1646 0 /* Don't know the acc_bits yet */, NULL
,
1647 struct samr_domain_info
, &status
);
1648 if (!NT_STATUS_IS_OK(status
)) {
1652 if (num_rids
> MAX_SAM_ENTRIES
) {
1653 num_rids
= MAX_SAM_ENTRIES
;
1654 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids
));
1657 rid
= talloc_array(p
->mem_ctx
, uint32
, num_rids
);
1658 NT_STATUS_HAVE_NO_MEMORY(rid
);
1660 type
= talloc_array(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
1661 NT_STATUS_HAVE_NO_MEMORY(type
);
1663 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1664 sid_string_dbg(&dinfo
->sid
)));
1666 for (i
= 0; i
< num_rids
; i
++) {
1668 status
= NT_STATUS_NONE_MAPPED
;
1669 type
[i
] = SID_NAME_UNKNOWN
;
1671 rid
[i
] = 0xffffffff;
1673 if (sid_check_is_builtin(&dinfo
->sid
)) {
1674 if (lookup_builtin_name(r
->in
.names
[i
].string
,
1677 type
[i
] = SID_NAME_ALIAS
;
1680 lookup_global_sam_name(r
->in
.names
[i
].string
, 0,
1684 if (type
[i
] != SID_NAME_UNKNOWN
) {
1689 if (num_mapped
== num_rids
) {
1690 status
= NT_STATUS_OK
;
1691 } else if (num_mapped
== 0) {
1692 status
= NT_STATUS_NONE_MAPPED
;
1694 status
= STATUS_SOME_UNMAPPED
;
1697 rids
.count
= num_rids
;
1700 types
.count
= num_rids
;
1701 types
.ids
= talloc_array(p
->mem_ctx
, uint32_t, num_rids
);
1702 NT_STATUS_HAVE_NO_MEMORY(type
);
1703 for (i
= 0; i
< num_rids
; i
++) {
1704 types
.ids
[i
] = (type
[i
] & 0xffffffff);
1707 *r
->out
.rids
= rids
;
1708 *r
->out
.types
= types
;
1710 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__
));
1715 /****************************************************************
1716 _samr_ChangePasswordUser.
1718 So old it is just not worth implementing
1719 because it does not supply a plaintext and so we can't do password
1720 complexity checking and cannot update other services that use a
1721 plaintext password via passwd chat/pam password change/ldap password
1723 ****************************************************************/
1725 NTSTATUS
_samr_ChangePasswordUser(struct pipes_struct
*p
,
1726 struct samr_ChangePasswordUser
*r
)
1728 return NT_STATUS_NOT_IMPLEMENTED
;
1731 /*******************************************************************
1732 _samr_ChangePasswordUser2
1733 ********************************************************************/
1735 NTSTATUS
_samr_ChangePasswordUser2(struct pipes_struct
*p
,
1736 struct samr_ChangePasswordUser2
*r
)
1739 char *user_name
= NULL
;
1741 const char *wks
= NULL
;
1743 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
1745 if (!r
->in
.account
->string
) {
1746 return NT_STATUS_INVALID_PARAMETER
;
1748 if (r
->in
.server
&& r
->in
.server
->string
) {
1749 wks
= r
->in
.server
->string
;
1752 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
1755 * Pass the user through the NT -> unix user mapping
1759 (void)map_username(talloc_tos(), r
->in
.account
->string
, &user_name
);
1761 return NT_STATUS_NO_MEMORY
;
1764 rhost
= tsocket_address_inet_addr_string(p
->remote_address
,
1766 if (rhost
== NULL
) {
1767 return NT_STATUS_NO_MEMORY
;
1771 * UNIX username case mangling not required, pass_oem_change
1772 * is case insensitive.
1775 status
= pass_oem_change(user_name
,
1777 r
->in
.lm_password
->data
,
1778 r
->in
.lm_verifier
->hash
,
1779 r
->in
.nt_password
->data
,
1780 r
->in
.nt_verifier
->hash
,
1783 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__
));
1785 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
1786 return NT_STATUS_WRONG_PASSWORD
;
1792 /****************************************************************
1793 _samr_OemChangePasswordUser2
1794 ****************************************************************/
1796 NTSTATUS
_samr_OemChangePasswordUser2(struct pipes_struct
*p
,
1797 struct samr_OemChangePasswordUser2
*r
)
1800 char *user_name
= NULL
;
1801 const char *wks
= NULL
;
1804 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
1806 if (!r
->in
.account
->string
) {
1807 return NT_STATUS_INVALID_PARAMETER
;
1809 if (r
->in
.server
&& r
->in
.server
->string
) {
1810 wks
= r
->in
.server
->string
;
1813 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name
, wks
));
1816 * Pass the user through the NT -> unix user mapping
1820 (void)map_username(talloc_tos(), r
->in
.account
->string
, &user_name
);
1822 return NT_STATUS_NO_MEMORY
;
1826 * UNIX username case mangling not required, pass_oem_change
1827 * is case insensitive.
1830 if (!r
->in
.hash
|| !r
->in
.password
) {
1831 return NT_STATUS_INVALID_PARAMETER
;
1834 rhost
= tsocket_address_inet_addr_string(p
->remote_address
,
1836 if (rhost
== NULL
) {
1837 return NT_STATUS_NO_MEMORY
;
1840 status
= pass_oem_change(user_name
,
1842 r
->in
.password
->data
,
1848 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
1849 return NT_STATUS_WRONG_PASSWORD
;
1852 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__
));
1857 /*******************************************************************
1858 _samr_ChangePasswordUser3
1859 ********************************************************************/
1861 NTSTATUS
_samr_ChangePasswordUser3(struct pipes_struct
*p
,
1862 struct samr_ChangePasswordUser3
*r
)
1865 char *user_name
= NULL
;
1866 const char *wks
= NULL
;
1867 enum samPwdChangeReason reject_reason
;
1868 struct samr_DomInfo1
*dominfo
= NULL
;
1869 struct userPwdChangeFailureInformation
*reject
= NULL
;
1873 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
1875 if (!r
->in
.account
->string
) {
1876 return NT_STATUS_INVALID_PARAMETER
;
1878 if (r
->in
.server
&& r
->in
.server
->string
) {
1879 wks
= r
->in
.server
->string
;
1882 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name
, wks
));
1885 * Pass the user through the NT -> unix user mapping
1889 (void)map_username(talloc_tos(), r
->in
.account
->string
, &user_name
);
1891 return NT_STATUS_NO_MEMORY
;
1894 rhost
= tsocket_address_inet_addr_string(p
->remote_address
,
1896 if (rhost
== NULL
) {
1897 return NT_STATUS_NO_MEMORY
;
1901 * UNIX username case mangling not required, pass_oem_change
1902 * is case insensitive.
1905 status
= pass_oem_change(user_name
,
1907 r
->in
.lm_password
->data
,
1908 r
->in
.lm_verifier
->hash
,
1909 r
->in
.nt_password
->data
,
1910 r
->in
.nt_verifier
->hash
,
1912 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
1913 return NT_STATUS_WRONG_PASSWORD
;
1916 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) ||
1917 NT_STATUS_EQUAL(status
, NT_STATUS_ACCOUNT_RESTRICTION
)) {
1919 time_t u_expire
, u_min_age
;
1920 uint32 account_policy_temp
;
1922 dominfo
= talloc_zero(p
->mem_ctx
, struct samr_DomInfo1
);
1924 return NT_STATUS_NO_MEMORY
;
1927 reject
= talloc_zero(p
->mem_ctx
,
1928 struct userPwdChangeFailureInformation
);
1930 return NT_STATUS_NO_MEMORY
;
1937 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN
, &tmp
);
1938 dominfo
->min_password_length
= tmp
;
1940 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &tmp
);
1941 dominfo
->password_history_length
= tmp
;
1943 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS
,
1944 &dominfo
->password_properties
);
1946 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE
, &account_policy_temp
);
1947 u_expire
= account_policy_temp
;
1949 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE
, &account_policy_temp
);
1950 u_min_age
= account_policy_temp
;
1956 unix_to_nt_time_abs((NTTIME
*)&dominfo
->max_password_age
, u_expire
);
1957 unix_to_nt_time_abs((NTTIME
*)&dominfo
->min_password_age
, u_min_age
);
1959 if (lp_check_password_script(talloc_tos())
1960 && *lp_check_password_script(talloc_tos())) {
1961 dominfo
->password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
1964 reject
->extendedFailureReason
= reject_reason
;
1966 *r
->out
.dominfo
= dominfo
;
1967 *r
->out
.reject
= reject
;
1970 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__
));
1975 /*******************************************************************
1976 makes a SAMR_R_LOOKUP_RIDS structure.
1977 ********************************************************************/
1979 static bool make_samr_lookup_rids(TALLOC_CTX
*ctx
, uint32 num_names
,
1981 struct lsa_String
**lsa_name_array_p
)
1983 struct lsa_String
*lsa_name_array
= NULL
;
1986 *lsa_name_array_p
= NULL
;
1988 if (num_names
!= 0) {
1989 lsa_name_array
= talloc_zero_array(ctx
, struct lsa_String
, num_names
);
1990 if (!lsa_name_array
) {
1995 for (i
= 0; i
< num_names
; i
++) {
1996 DEBUG(10, ("names[%d]:%s\n", i
, names
[i
] && *names
[i
] ? names
[i
] : ""));
1997 init_lsa_String(&lsa_name_array
[i
], names
[i
]);
2000 *lsa_name_array_p
= lsa_name_array
;
2005 /*******************************************************************
2007 ********************************************************************/
2009 NTSTATUS
_samr_LookupRids(struct pipes_struct
*p
,
2010 struct samr_LookupRids
*r
)
2012 struct samr_domain_info
*dinfo
;
2015 enum lsa_SidType
*attrs
= NULL
;
2016 uint32
*wire_attrs
= NULL
;
2017 int num_rids
= (int)r
->in
.num_rids
;
2019 struct lsa_Strings names_array
;
2020 struct samr_Ids types_array
;
2021 struct lsa_String
*lsa_names
= NULL
;
2023 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2025 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
2026 0 /* Don't know the acc_bits yet */, NULL
,
2027 struct samr_domain_info
, &status
);
2028 if (!NT_STATUS_IS_OK(status
)) {
2032 if (num_rids
> 1000) {
2033 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2034 "to samba4 idl this is not possible\n", num_rids
));
2035 return NT_STATUS_UNSUCCESSFUL
;
2039 names
= talloc_zero_array(p
->mem_ctx
, const char *, num_rids
);
2040 attrs
= talloc_zero_array(p
->mem_ctx
, enum lsa_SidType
, num_rids
);
2041 wire_attrs
= talloc_zero_array(p
->mem_ctx
, uint32
, num_rids
);
2043 if ((names
== NULL
) || (attrs
== NULL
) || (wire_attrs
==NULL
))
2044 return NT_STATUS_NO_MEMORY
;
2051 become_root(); /* lookup_sid can require root privs */
2052 status
= pdb_lookup_rids(&dinfo
->sid
, num_rids
, r
->in
.rids
,
2056 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
) && (num_rids
== 0)) {
2057 status
= NT_STATUS_OK
;
2060 if (!make_samr_lookup_rids(p
->mem_ctx
, num_rids
, names
,
2062 return NT_STATUS_NO_MEMORY
;
2065 /* Convert from enum lsa_SidType to uint32 for wire format. */
2066 for (i
= 0; i
< num_rids
; i
++) {
2067 wire_attrs
[i
] = (uint32
)attrs
[i
];
2070 names_array
.count
= num_rids
;
2071 names_array
.names
= lsa_names
;
2073 types_array
.count
= num_rids
;
2074 types_array
.ids
= wire_attrs
;
2076 *r
->out
.names
= names_array
;
2077 *r
->out
.types
= types_array
;
2079 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__
));
2084 /*******************************************************************
2086 ********************************************************************/
2088 NTSTATUS
_samr_OpenUser(struct pipes_struct
*p
,
2089 struct samr_OpenUser
*r
)
2091 struct samu
*sampass
=NULL
;
2093 struct samr_domain_info
*dinfo
;
2094 struct samr_user_info
*uinfo
;
2095 struct security_descriptor
*psd
= NULL
;
2097 uint32 des_access
= r
->in
.access_mask
;
2098 uint32_t extra_access
= 0;
2103 /* These two privileges, if != SEC_PRIV_INVALID, indicate
2104 * privileges that the user must have to complete this
2105 * operation in defience of the fixed ACL */
2106 enum sec_privilege needed_priv_1
, needed_priv_2
;
2109 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
2110 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
2111 struct samr_domain_info
, &status
);
2112 if (!NT_STATUS_IS_OK(status
)) {
2116 if ( !(sampass
= samu_new( p
->mem_ctx
)) ) {
2117 return NT_STATUS_NO_MEMORY
;
2120 /* append the user's RID to it */
2122 if (!sid_compose(&sid
, &dinfo
->sid
, r
->in
.rid
))
2123 return NT_STATUS_NO_SUCH_USER
;
2125 /* check if access can be granted as requested by client. */
2126 map_max_allowed_access(p
->session_info
->security_token
,
2127 p
->session_info
->unix_token
,
2130 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
, &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
2131 se_map_generic(&des_access
, &usr_generic_mapping
);
2134 * Get the sampass first as we need to check privileges
2135 * based on what kind of user object this is.
2136 * But don't reveal info too early if it didn't exist.
2140 ret
=pdb_getsampwsid(sampass
, &sid
);
2143 needed_priv_1
= SEC_PRIV_INVALID
;
2144 needed_priv_2
= SEC_PRIV_INVALID
;
2146 * We do the override access checks on *open*, not at
2150 uint32_t acb_info
= pdb_get_acct_ctrl(sampass
);
2152 if (acb_info
& ACB_WSTRUST
) {
2154 * SeMachineAccount is needed to add
2155 * GENERIC_RIGHTS_USER_WRITE to a machine
2158 needed_priv_1
= SEC_PRIV_MACHINE_ACCOUNT
;
2160 if (acb_info
& ACB_NORMAL
) {
2162 * SeAddUsers is needed to add
2163 * GENERIC_RIGHTS_USER_WRITE to a normal
2166 needed_priv_1
= SEC_PRIV_ADD_USERS
;
2169 * Cheat - we have not set a specific privilege for
2170 * server (BDC) or domain trust account, so allow
2171 * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2172 * DOMAIN_RID_ADMINS.
2174 if (acb_info
& (ACB_SVRTRUST
|ACB_DOMTRUST
)) {
2175 if (lp_enable_privileges() && nt_token_check_domain_rid(p
->session_info
->security_token
,
2176 DOMAIN_RID_ADMINS
)) {
2177 des_access
&= ~GENERIC_RIGHTS_USER_WRITE
;
2178 extra_access
= GENERIC_RIGHTS_USER_WRITE
;
2179 DEBUG(4,("_samr_OpenUser: Allowing "
2180 "GENERIC_RIGHTS_USER_WRITE for "
2186 TALLOC_FREE(sampass
);
2188 nt_status
= access_check_object(psd
, p
->session_info
->security_token
,
2189 needed_priv_1
, needed_priv_2
,
2190 GENERIC_RIGHTS_USER_WRITE
, des_access
,
2191 &acc_granted
, "_samr_OpenUser");
2193 if ( !NT_STATUS_IS_OK(nt_status
) )
2196 /* check that the SID exists in our domain. */
2198 return NT_STATUS_NO_SUCH_USER
;
2201 /* If we did the rid admins hack above, allow access. */
2202 acc_granted
|= extra_access
;
2204 uinfo
= policy_handle_create(p
, r
->out
.user_handle
, acc_granted
,
2205 struct samr_user_info
, &nt_status
);
2206 if (!NT_STATUS_IS_OK(nt_status
)) {
2211 return NT_STATUS_OK
;
2214 /*************************************************************************
2215 *************************************************************************/
2217 static NTSTATUS
init_samr_parameters_string(TALLOC_CTX
*mem_ctx
,
2219 struct lsa_BinaryString
**_r
)
2221 struct lsa_BinaryString
*r
;
2224 return NT_STATUS_INVALID_PARAMETER
;
2227 r
= talloc_zero(mem_ctx
, struct lsa_BinaryString
);
2229 return NT_STATUS_NO_MEMORY
;
2232 r
->array
= talloc_zero_array(mem_ctx
, uint16_t, blob
->length
/2);
2234 return NT_STATUS_NO_MEMORY
;
2236 memcpy(r
->array
, blob
->data
, blob
->length
);
2237 r
->size
= blob
->length
;
2238 r
->length
= blob
->length
;
2241 return NT_STATUS_NO_MEMORY
;
2246 return NT_STATUS_OK
;
2249 /*************************************************************************
2250 *************************************************************************/
2252 static struct samr_LogonHours
get_logon_hours_from_pdb(TALLOC_CTX
*mem_ctx
,
2255 struct samr_LogonHours hours
;
2256 const int units_per_week
= 168;
2259 hours
.bits
= talloc_array(mem_ctx
, uint8_t, units_per_week
);
2264 hours
.units_per_week
= units_per_week
;
2265 memset(hours
.bits
, 0xFF, units_per_week
);
2267 if (pdb_get_hours(pw
)) {
2268 memcpy(hours
.bits
, pdb_get_hours(pw
),
2269 MIN(pdb_get_hours_len(pw
), units_per_week
));
2275 /*************************************************************************
2277 *************************************************************************/
2279 static NTSTATUS
get_user_info_1(TALLOC_CTX
*mem_ctx
,
2280 struct samr_UserInfo1
*r
,
2282 struct dom_sid
*domain_sid
)
2284 const struct dom_sid
*sid_group
;
2285 uint32_t primary_gid
;
2288 sid_group
= pdb_get_group_sid(pw
);
2291 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2292 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2293 "which conflicts with the domain sid %s. Failing operation.\n",
2294 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2295 sid_string_dbg(domain_sid
)));
2296 return NT_STATUS_UNSUCCESSFUL
;
2299 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2300 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2301 r
->primary_gid
= primary_gid
;
2302 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2303 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2305 return NT_STATUS_OK
;
2308 /*************************************************************************
2310 *************************************************************************/
2312 static NTSTATUS
get_user_info_2(TALLOC_CTX
*mem_ctx
,
2313 struct samr_UserInfo2
*r
,
2316 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2317 r
->reserved
.string
= NULL
;
2318 r
->country_code
= pdb_get_country_code(pw
);
2319 r
->code_page
= pdb_get_code_page(pw
);
2321 return NT_STATUS_OK
;
2324 /*************************************************************************
2326 *************************************************************************/
2328 static NTSTATUS
get_user_info_3(TALLOC_CTX
*mem_ctx
,
2329 struct samr_UserInfo3
*r
,
2331 struct dom_sid
*domain_sid
)
2333 const struct dom_sid
*sid_user
, *sid_group
;
2334 uint32_t rid
, primary_gid
;
2336 sid_user
= pdb_get_user_sid(pw
);
2338 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2339 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2340 "the domain sid %s. Failing operation.\n",
2341 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2342 sid_string_dbg(domain_sid
)));
2343 return NT_STATUS_UNSUCCESSFUL
;
2347 sid_group
= pdb_get_group_sid(pw
);
2350 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2351 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2352 "which conflicts with the domain sid %s. Failing operation.\n",
2353 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2354 sid_string_dbg(domain_sid
)));
2355 return NT_STATUS_UNSUCCESSFUL
;
2358 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2359 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2360 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2361 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2362 unix_to_nt_time(&r
->force_password_change
, pdb_get_pass_must_change_time(pw
));
2364 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2365 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2366 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2367 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2368 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2369 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2370 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2372 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2374 r
->primary_gid
= primary_gid
;
2375 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2376 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2377 r
->logon_count
= pdb_get_logon_count(pw
);
2379 return NT_STATUS_OK
;
2382 /*************************************************************************
2384 *************************************************************************/
2386 static NTSTATUS
get_user_info_4(TALLOC_CTX
*mem_ctx
,
2387 struct samr_UserInfo4
*r
,
2390 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2392 return NT_STATUS_OK
;
2395 /*************************************************************************
2397 *************************************************************************/
2399 static NTSTATUS
get_user_info_5(TALLOC_CTX
*mem_ctx
,
2400 struct samr_UserInfo5
*r
,
2402 struct dom_sid
*domain_sid
)
2404 const struct dom_sid
*sid_user
, *sid_group
;
2405 uint32_t rid
, primary_gid
;
2407 sid_user
= pdb_get_user_sid(pw
);
2409 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2410 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2411 "the domain sid %s. Failing operation.\n",
2412 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2413 sid_string_dbg(domain_sid
)));
2414 return NT_STATUS_UNSUCCESSFUL
;
2418 sid_group
= pdb_get_group_sid(pw
);
2421 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2422 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2423 "which conflicts with the domain sid %s. Failing operation.\n",
2424 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2425 sid_string_dbg(domain_sid
)));
2426 return NT_STATUS_UNSUCCESSFUL
;
2429 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2430 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2431 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2432 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2434 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2435 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2436 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2437 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2438 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2439 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2440 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2441 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2443 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2445 r
->primary_gid
= primary_gid
;
2446 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2447 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2448 r
->logon_count
= pdb_get_logon_count(pw
);
2450 return NT_STATUS_OK
;
2453 /*************************************************************************
2455 *************************************************************************/
2457 static NTSTATUS
get_user_info_6(TALLOC_CTX
*mem_ctx
,
2458 struct samr_UserInfo6
*r
,
2461 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2462 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2464 return NT_STATUS_OK
;
2467 /*************************************************************************
2468 get_user_info_7. Safe. Only gives out account_name.
2469 *************************************************************************/
2471 static NTSTATUS
get_user_info_7(TALLOC_CTX
*mem_ctx
,
2472 struct samr_UserInfo7
*r
,
2473 struct samu
*smbpass
)
2475 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(smbpass
));
2476 if (!r
->account_name
.string
) {
2477 return NT_STATUS_NO_MEMORY
;
2480 return NT_STATUS_OK
;
2483 /*************************************************************************
2485 *************************************************************************/
2487 static NTSTATUS
get_user_info_8(TALLOC_CTX
*mem_ctx
,
2488 struct samr_UserInfo8
*r
,
2491 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2493 return NT_STATUS_OK
;
2496 /*************************************************************************
2497 get_user_info_9. Only gives out primary group SID.
2498 *************************************************************************/
2500 static NTSTATUS
get_user_info_9(TALLOC_CTX
*mem_ctx
,
2501 struct samr_UserInfo9
*r
,
2502 struct samu
*smbpass
)
2504 r
->primary_gid
= pdb_get_group_rid(smbpass
);
2506 return NT_STATUS_OK
;
2509 /*************************************************************************
2511 *************************************************************************/
2513 static NTSTATUS
get_user_info_10(TALLOC_CTX
*mem_ctx
,
2514 struct samr_UserInfo10
*r
,
2517 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2518 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2520 return NT_STATUS_OK
;
2523 /*************************************************************************
2525 *************************************************************************/
2527 static NTSTATUS
get_user_info_11(TALLOC_CTX
*mem_ctx
,
2528 struct samr_UserInfo11
*r
,
2531 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2533 return NT_STATUS_OK
;
2536 /*************************************************************************
2538 *************************************************************************/
2540 static NTSTATUS
get_user_info_12(TALLOC_CTX
*mem_ctx
,
2541 struct samr_UserInfo12
*r
,
2544 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2546 return NT_STATUS_OK
;
2549 /*************************************************************************
2551 *************************************************************************/
2553 static NTSTATUS
get_user_info_13(TALLOC_CTX
*mem_ctx
,
2554 struct samr_UserInfo13
*r
,
2557 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2559 return NT_STATUS_OK
;
2562 /*************************************************************************
2564 *************************************************************************/
2566 static NTSTATUS
get_user_info_14(TALLOC_CTX
*mem_ctx
,
2567 struct samr_UserInfo14
*r
,
2570 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2572 return NT_STATUS_OK
;
2575 /*************************************************************************
2576 get_user_info_16. Safe. Only gives out acb bits.
2577 *************************************************************************/
2579 static NTSTATUS
get_user_info_16(TALLOC_CTX
*mem_ctx
,
2580 struct samr_UserInfo16
*r
,
2581 struct samu
*smbpass
)
2583 r
->acct_flags
= pdb_get_acct_ctrl(smbpass
);
2585 return NT_STATUS_OK
;
2588 /*************************************************************************
2590 *************************************************************************/
2592 static NTSTATUS
get_user_info_17(TALLOC_CTX
*mem_ctx
,
2593 struct samr_UserInfo17
*r
,
2596 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2598 return NT_STATUS_OK
;
2601 /*************************************************************************
2602 get_user_info_18. OK - this is the killer as it gives out password info.
2603 Ensure that this is only allowed on an encrypted connection with a root
2605 *************************************************************************/
2607 static NTSTATUS
get_user_info_18(struct pipes_struct
*p
,
2608 TALLOC_CTX
*mem_ctx
,
2609 struct samr_UserInfo18
*r
,
2610 struct dom_sid
*user_sid
)
2612 struct samu
*smbpass
=NULL
;
2614 const uint8_t *nt_pass
= NULL
;
2615 const uint8_t *lm_pass
= NULL
;
2619 if (security_token_is_system(p
->session_info
->security_token
)) {
2623 if ((p
->auth
.auth_type
!= DCERPC_AUTH_TYPE_NTLMSSP
) ||
2624 (p
->auth
.auth_type
!= DCERPC_AUTH_TYPE_KRB5
) ||
2625 (p
->auth
.auth_type
!= DCERPC_AUTH_TYPE_SPNEGO
)) {
2626 return NT_STATUS_ACCESS_DENIED
;
2629 if (p
->auth
.auth_level
!= DCERPC_AUTH_LEVEL_PRIVACY
) {
2630 return NT_STATUS_ACCESS_DENIED
;
2635 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2638 if ( !(smbpass
= samu_new( mem_ctx
)) ) {
2639 return NT_STATUS_NO_MEMORY
;
2642 ret
= pdb_getsampwsid(smbpass
, user_sid
);
2645 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid
)));
2646 TALLOC_FREE(smbpass
);
2647 return root_mode() ? NT_STATUS_NO_SUCH_USER
: NT_STATUS_ACCESS_DENIED
;
2650 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass
), pdb_get_acct_ctrl(smbpass
) ));
2652 if ( pdb_get_acct_ctrl(smbpass
) & ACB_DISABLED
) {
2653 TALLOC_FREE(smbpass
);
2654 return NT_STATUS_ACCOUNT_DISABLED
;
2657 lm_pass
= pdb_get_lanman_passwd(smbpass
);
2658 if (lm_pass
!= NULL
) {
2659 memcpy(r
->lm_pwd
.hash
, lm_pass
, 16);
2660 r
->lm_pwd_active
= true;
2663 nt_pass
= pdb_get_nt_passwd(smbpass
);
2664 if (nt_pass
!= NULL
) {
2665 memcpy(r
->nt_pwd
.hash
, nt_pass
, 16);
2666 r
->nt_pwd_active
= true;
2668 r
->password_expired
= 0; /* FIXME */
2670 TALLOC_FREE(smbpass
);
2672 return NT_STATUS_OK
;
2675 /*************************************************************************
2677 *************************************************************************/
2679 static NTSTATUS
get_user_info_20(TALLOC_CTX
*mem_ctx
,
2680 struct samr_UserInfo20
*r
,
2681 struct samu
*sampass
)
2683 const char *munged_dial
= NULL
;
2686 struct lsa_BinaryString
*parameters
= NULL
;
2690 munged_dial
= pdb_get_munged_dial(sampass
);
2692 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass
),
2693 munged_dial
, (int)strlen(munged_dial
)));
2696 blob
= base64_decode_data_blob(munged_dial
);
2698 blob
= data_blob_string_const_null("");
2701 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2702 data_blob_free(&blob
);
2703 if (!NT_STATUS_IS_OK(status
)) {
2707 r
->parameters
= *parameters
;
2709 return NT_STATUS_OK
;
2713 /*************************************************************************
2715 *************************************************************************/
2717 static NTSTATUS
get_user_info_21(TALLOC_CTX
*mem_ctx
,
2718 struct samr_UserInfo21
*r
,
2720 struct dom_sid
*domain_sid
,
2721 uint32_t acc_granted
)
2724 const struct dom_sid
*sid_user
, *sid_group
;
2725 uint32_t rid
, primary_gid
;
2726 NTTIME force_password_change
;
2727 time_t must_change_time
;
2728 struct lsa_BinaryString
*parameters
= NULL
;
2729 const char *munged_dial
= NULL
;
2734 sid_user
= pdb_get_user_sid(pw
);
2736 if (!sid_peek_check_rid(domain_sid
, sid_user
, &rid
)) {
2737 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2738 "the domain sid %s. Failing operation.\n",
2739 pdb_get_username(pw
), sid_string_dbg(sid_user
),
2740 sid_string_dbg(domain_sid
)));
2741 return NT_STATUS_UNSUCCESSFUL
;
2745 sid_group
= pdb_get_group_sid(pw
);
2748 if (!sid_peek_check_rid(domain_sid
, sid_group
, &primary_gid
)) {
2749 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2750 "which conflicts with the domain sid %s. Failing operation.\n",
2751 pdb_get_username(pw
), sid_string_dbg(sid_group
),
2752 sid_string_dbg(domain_sid
)));
2753 return NT_STATUS_UNSUCCESSFUL
;
2756 unix_to_nt_time(&r
->last_logon
, pdb_get_logon_time(pw
));
2757 unix_to_nt_time(&r
->last_logoff
, pdb_get_logoff_time(pw
));
2758 unix_to_nt_time(&r
->acct_expiry
, pdb_get_kickoff_time(pw
));
2759 unix_to_nt_time(&r
->last_password_change
, pdb_get_pass_last_set_time(pw
));
2760 unix_to_nt_time(&r
->allow_password_change
, pdb_get_pass_can_change_time(pw
));
2762 must_change_time
= pdb_get_pass_must_change_time(pw
);
2763 if (pdb_is_password_change_time_max(must_change_time
)) {
2764 unix_to_nt_time_abs(&force_password_change
, must_change_time
);
2766 unix_to_nt_time(&force_password_change
, must_change_time
);
2769 munged_dial
= pdb_get_munged_dial(pw
);
2771 blob
= base64_decode_data_blob(munged_dial
);
2773 blob
= data_blob_string_const_null("");
2776 status
= init_samr_parameters_string(mem_ctx
, &blob
, ¶meters
);
2777 data_blob_free(&blob
);
2778 if (!NT_STATUS_IS_OK(status
)) {
2782 r
->force_password_change
= force_password_change
;
2784 r
->account_name
.string
= talloc_strdup(mem_ctx
, pdb_get_username(pw
));
2785 r
->full_name
.string
= talloc_strdup(mem_ctx
, pdb_get_fullname(pw
));
2786 r
->home_directory
.string
= talloc_strdup(mem_ctx
, pdb_get_homedir(pw
));
2787 r
->home_drive
.string
= talloc_strdup(mem_ctx
, pdb_get_dir_drive(pw
));
2788 r
->logon_script
.string
= talloc_strdup(mem_ctx
, pdb_get_logon_script(pw
));
2789 r
->profile_path
.string
= talloc_strdup(mem_ctx
, pdb_get_profile_path(pw
));
2790 r
->description
.string
= talloc_strdup(mem_ctx
, pdb_get_acct_desc(pw
));
2791 r
->workstations
.string
= talloc_strdup(mem_ctx
, pdb_get_workstations(pw
));
2792 r
->comment
.string
= talloc_strdup(mem_ctx
, pdb_get_comment(pw
));
2794 r
->logon_hours
= get_logon_hours_from_pdb(mem_ctx
, pw
);
2795 r
->parameters
= *parameters
;
2797 r
->primary_gid
= primary_gid
;
2798 r
->acct_flags
= pdb_get_acct_ctrl(pw
);
2799 r
->bad_password_count
= pdb_get_bad_password_count(pw
);
2800 r
->logon_count
= pdb_get_logon_count(pw
);
2801 r
->fields_present
= pdb_build_fields_present(pw
);
2802 r
->password_expired
= (pdb_get_pass_must_change_time(pw
) == 0) ?
2803 PASS_MUST_CHANGE_AT_NEXT_LOGON
: 0;
2804 r
->country_code
= pdb_get_country_code(pw
);
2805 r
->code_page
= pdb_get_code_page(pw
);
2806 r
->lm_password_set
= 0;
2807 r
->nt_password_set
= 0;
2812 Look at a user on a real NT4 PDC with usrmgr, press
2813 'ok'. Then you will see that fields_present is set to
2814 0x08f827fa. Look at the user immediately after that again,
2815 and you will see that 0x00fffff is returned. This solves
2816 the problem that you get access denied after having looked
2824 return NT_STATUS_OK
;
2827 /*******************************************************************
2829 ********************************************************************/
2831 NTSTATUS
_samr_QueryUserInfo(struct pipes_struct
*p
,
2832 struct samr_QueryUserInfo
*r
)
2835 union samr_UserInfo
*user_info
= NULL
;
2836 struct samr_user_info
*uinfo
;
2837 struct dom_sid domain_sid
;
2840 struct samu
*pwd
= NULL
;
2841 uint32_t acc_required
, acc_granted
;
2843 switch (r
->in
.level
) {
2844 case 1: /* UserGeneralInformation */
2845 /* USER_READ_GENERAL */
2846 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
;
2848 case 2: /* UserPreferencesInformation */
2849 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2850 acc_required
= SAMR_USER_ACCESS_GET_LOCALE
|
2851 SAMR_USER_ACCESS_GET_NAME_ETC
;
2853 case 3: /* UserLogonInformation */
2854 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2855 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
|
2856 SAMR_USER_ACCESS_GET_LOCALE
|
2857 SAMR_USER_ACCESS_GET_LOGONINFO
|
2858 SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2860 case 4: /* UserLogonHoursInformation */
2861 /* USER_READ_LOGON */
2862 acc_required
= SAMR_USER_ACCESS_GET_LOGONINFO
;
2864 case 5: /* UserAccountInformation */
2865 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2866 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
|
2867 SAMR_USER_ACCESS_GET_LOCALE
|
2868 SAMR_USER_ACCESS_GET_LOGONINFO
|
2869 SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2871 case 6: /* UserNameInformation */
2872 case 7: /* UserAccountNameInformation */
2873 case 8: /* UserFullNameInformation */
2874 case 9: /* UserPrimaryGroupInformation */
2875 case 13: /* UserAdminCommentInformation */
2876 /* USER_READ_GENERAL */
2877 acc_required
= SAMR_USER_ACCESS_GET_NAME_ETC
;
2879 case 10: /* UserHomeInformation */
2880 case 11: /* UserScriptInformation */
2881 case 12: /* UserProfileInformation */
2882 case 14: /* UserWorkStationsInformation */
2883 /* USER_READ_LOGON */
2884 acc_required
= SAMR_USER_ACCESS_GET_LOGONINFO
;
2886 case 16: /* UserControlInformation */
2887 case 17: /* UserExpiresInformation */
2888 case 20: /* UserParametersInformation */
2889 /* USER_READ_ACCOUNT */
2890 acc_required
= SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2892 case 21: /* UserAllInformation */
2894 acc_required
= SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2896 case 18: /* UserInternal1Information */
2898 acc_required
= SAMR_USER_ACCESS_GET_ATTRIBUTES
;
2900 case 23: /* UserInternal4Information */
2901 case 24: /* UserInternal4InformationNew */
2902 case 25: /* UserInternal4InformationNew */
2903 case 26: /* UserInternal5InformationNew */
2905 return NT_STATUS_INVALID_INFO_CLASS
;
2909 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
2910 acc_required
, &acc_granted
,
2911 struct samr_user_info
, &status
);
2912 if (!NT_STATUS_IS_OK(status
)) {
2916 domain_sid
= uinfo
->sid
;
2918 sid_split_rid(&domain_sid
, &rid
);
2920 if (!sid_check_is_in_our_sam(&uinfo
->sid
))
2921 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
2923 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2924 sid_string_dbg(&uinfo
->sid
)));
2926 user_info
= talloc_zero(p
->mem_ctx
, union samr_UserInfo
);
2928 return NT_STATUS_NO_MEMORY
;
2931 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r
->in
.level
));
2933 if (!(pwd
= samu_new(p
->mem_ctx
))) {
2934 return NT_STATUS_NO_MEMORY
;
2938 ret
= pdb_getsampwsid(pwd
, &uinfo
->sid
);
2942 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo
->sid
)));
2944 return NT_STATUS_NO_SUCH_USER
;
2947 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd
)));
2949 samr_clear_sam_passwd(pwd
);
2951 switch (r
->in
.level
) {
2953 status
= get_user_info_1(p
->mem_ctx
, &user_info
->info1
, pwd
, &domain_sid
);
2956 status
= get_user_info_2(p
->mem_ctx
, &user_info
->info2
, pwd
);
2959 status
= get_user_info_3(p
->mem_ctx
, &user_info
->info3
, pwd
, &domain_sid
);
2962 status
= get_user_info_4(p
->mem_ctx
, &user_info
->info4
, pwd
);
2965 status
= get_user_info_5(p
->mem_ctx
, &user_info
->info5
, pwd
, &domain_sid
);
2968 status
= get_user_info_6(p
->mem_ctx
, &user_info
->info6
, pwd
);
2971 status
= get_user_info_7(p
->mem_ctx
, &user_info
->info7
, pwd
);
2974 status
= get_user_info_8(p
->mem_ctx
, &user_info
->info8
, pwd
);
2977 status
= get_user_info_9(p
->mem_ctx
, &user_info
->info9
, pwd
);
2980 status
= get_user_info_10(p
->mem_ctx
, &user_info
->info10
, pwd
);
2983 status
= get_user_info_11(p
->mem_ctx
, &user_info
->info11
, pwd
);
2986 status
= get_user_info_12(p
->mem_ctx
, &user_info
->info12
, pwd
);
2989 status
= get_user_info_13(p
->mem_ctx
, &user_info
->info13
, pwd
);
2992 status
= get_user_info_14(p
->mem_ctx
, &user_info
->info14
, pwd
);
2995 status
= get_user_info_16(p
->mem_ctx
, &user_info
->info16
, pwd
);
2998 status
= get_user_info_17(p
->mem_ctx
, &user_info
->info17
, pwd
);
3001 /* level 18 is special */
3002 status
= get_user_info_18(p
, p
->mem_ctx
, &user_info
->info18
,
3006 status
= get_user_info_20(p
->mem_ctx
, &user_info
->info20
, pwd
);
3009 status
= get_user_info_21(p
->mem_ctx
, &user_info
->info21
, pwd
, &domain_sid
, acc_granted
);
3012 status
= NT_STATUS_INVALID_INFO_CLASS
;
3016 if (!NT_STATUS_IS_OK(status
)) {
3020 *r
->out
.info
= user_info
;
3025 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__
));
3030 /****************************************************************
3031 ****************************************************************/
3033 NTSTATUS
_samr_QueryUserInfo2(struct pipes_struct
*p
,
3034 struct samr_QueryUserInfo2
*r
)
3036 struct samr_QueryUserInfo u
;
3038 u
.in
.user_handle
= r
->in
.user_handle
;
3039 u
.in
.level
= r
->in
.level
;
3040 u
.out
.info
= r
->out
.info
;
3042 return _samr_QueryUserInfo(p
, &u
);
3045 /*******************************************************************
3046 _samr_GetGroupsForUser
3047 ********************************************************************/
3049 NTSTATUS
_samr_GetGroupsForUser(struct pipes_struct
*p
,
3050 struct samr_GetGroupsForUser
*r
)
3052 struct samr_user_info
*uinfo
;
3053 struct samu
*sam_pass
=NULL
;
3054 struct dom_sid
*sids
;
3055 struct samr_RidWithAttribute dom_gid
;
3056 struct samr_RidWithAttribute
*gids
= NULL
;
3057 uint32 primary_group_rid
;
3058 uint32_t num_groups
= 0;
3060 uint32_t i
, num_gids
;
3063 bool success
= False
;
3065 struct samr_RidWithAttributeArray
*rids
= NULL
;
3068 * from the SID in the request:
3069 * we should send back the list of DOMAIN GROUPS
3070 * the user is a member of
3072 * and only the DOMAIN GROUPS
3073 * no ALIASES !!! neither aliases of the domain
3074 * nor aliases of the builtin SID
3079 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3081 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
3082 SAMR_USER_ACCESS_GET_GROUPS
, NULL
,
3083 struct samr_user_info
, &result
);
3084 if (!NT_STATUS_IS_OK(result
)) {
3088 rids
= talloc_zero(p
->mem_ctx
, struct samr_RidWithAttributeArray
);
3090 return NT_STATUS_NO_MEMORY
;
3093 if (!sid_check_is_in_our_sam(&uinfo
->sid
))
3094 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
3096 if ( !(sam_pass
= samu_new( p
->mem_ctx
)) ) {
3097 return NT_STATUS_NO_MEMORY
;
3101 ret
= pdb_getsampwsid(sam_pass
, &uinfo
->sid
);
3105 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3106 sid_string_dbg(&uinfo
->sid
)));
3107 return NT_STATUS_NO_SUCH_USER
;
3112 /* make both calls inside the root block */
3114 result
= pdb_enum_group_memberships(p
->mem_ctx
, sam_pass
,
3115 &sids
, &unix_gids
, &num_groups
);
3116 if ( NT_STATUS_IS_OK(result
) ) {
3117 success
= sid_peek_check_rid(get_global_sam_sid(),
3118 pdb_get_group_sid(sam_pass
),
3119 &primary_group_rid
);
3123 if (!NT_STATUS_IS_OK(result
)) {
3124 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3125 sid_string_dbg(&uinfo
->sid
)));
3130 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3131 sid_string_dbg(pdb_get_group_sid(sam_pass
)),
3132 pdb_get_username(sam_pass
)));
3133 TALLOC_FREE(sam_pass
);
3134 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
3140 dom_gid
.attributes
= (SE_GROUP_MANDATORY
|SE_GROUP_ENABLED_BY_DEFAULT
|
3142 dom_gid
.rid
= primary_group_rid
;
3143 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3145 for (i
=0; i
<num_groups
; i
++) {
3147 if (!sid_peek_check_rid(get_global_sam_sid(),
3148 &(sids
[i
]), &dom_gid
.rid
)) {
3149 DEBUG(10, ("Found sid %s not in our domain\n",
3150 sid_string_dbg(&sids
[i
])));
3154 if (dom_gid
.rid
== primary_group_rid
) {
3155 /* We added the primary group directly from the
3156 * sam_account. The other SIDs are unique from
3157 * enum_group_memberships */
3161 ADD_TO_ARRAY(p
->mem_ctx
, struct samr_RidWithAttribute
, dom_gid
, &gids
, &num_gids
);
3164 rids
->count
= num_gids
;
3167 *r
->out
.rids
= rids
;
3169 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__
));
3174 /*******************************************************************
3175 ********************************************************************/
3177 static uint32_t samr_get_server_role(void)
3179 uint32_t role
= ROLE_DOMAIN_PDC
;
3181 if (lp_server_role() == ROLE_DOMAIN_BDC
) {
3182 role
= ROLE_DOMAIN_BDC
;
3188 /*******************************************************************
3189 ********************************************************************/
3191 static NTSTATUS
query_dom_info_1(TALLOC_CTX
*mem_ctx
,
3192 struct samr_DomInfo1
*r
)
3194 uint32_t account_policy_temp
;
3195 time_t u_expire
, u_min_age
;
3201 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN
, &account_policy_temp
);
3202 r
->min_password_length
= account_policy_temp
;
3204 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &account_policy_temp
);
3205 r
->password_history_length
= account_policy_temp
;
3207 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS
,
3208 &r
->password_properties
);
3210 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE
, &account_policy_temp
);
3211 u_expire
= account_policy_temp
;
3213 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE
, &account_policy_temp
);
3214 u_min_age
= account_policy_temp
;
3220 unix_to_nt_time_abs((NTTIME
*)&r
->max_password_age
, u_expire
);
3221 unix_to_nt_time_abs((NTTIME
*)&r
->min_password_age
, u_min_age
);
3223 if (lp_check_password_script(talloc_tos()) && *lp_check_password_script(talloc_tos())) {
3224 r
->password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
3227 return NT_STATUS_OK
;
3230 /*******************************************************************
3231 ********************************************************************/
3233 static NTSTATUS
query_dom_info_2(TALLOC_CTX
*mem_ctx
,
3234 struct samr_DomGeneralInformation
*r
,
3235 struct samr_domain_info
*dinfo
)
3244 r
->num_users
= count_sam_users(dinfo
->disp_info
, ACB_NORMAL
);
3245 r
->num_groups
= count_sam_groups(dinfo
->disp_info
);
3246 r
->num_aliases
= count_sam_aliases(dinfo
->disp_info
);
3248 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT
, &u_logout
);
3250 unix_to_nt_time_abs(&r
->force_logoff_time
, u_logout
);
3252 if (!pdb_get_seq_num(&seq_num
)) {
3253 seq_num
= time(NULL
);
3260 r
->oem_information
.string
= lp_server_string(r
);
3261 r
->domain_name
.string
= lp_workgroup();
3262 r
->primary
.string
= lp_netbios_name();
3263 r
->sequence_num
= seq_num
;
3264 r
->domain_server_state
= DOMAIN_SERVER_ENABLED
;
3265 r
->role
= (enum samr_Role
) samr_get_server_role();
3268 return NT_STATUS_OK
;
3271 /*******************************************************************
3272 ********************************************************************/
3274 static NTSTATUS
query_dom_info_3(TALLOC_CTX
*mem_ctx
,
3275 struct samr_DomInfo3
*r
)
3285 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT
, &ul
);
3286 u_logout
= (time_t)ul
;
3293 unix_to_nt_time_abs(&r
->force_logoff_time
, u_logout
);
3295 return NT_STATUS_OK
;
3298 /*******************************************************************
3299 ********************************************************************/
3301 static NTSTATUS
query_dom_info_4(TALLOC_CTX
*mem_ctx
,
3302 struct samr_DomOEMInformation
*r
)
3304 r
->oem_information
.string
= lp_server_string(r
);
3306 return NT_STATUS_OK
;
3309 /*******************************************************************
3310 ********************************************************************/
3312 static NTSTATUS
query_dom_info_5(TALLOC_CTX
*mem_ctx
,
3313 struct samr_DomInfo5
*r
)
3315 r
->domain_name
.string
= get_global_sam_name();
3317 return NT_STATUS_OK
;
3320 /*******************************************************************
3321 ********************************************************************/
3323 static NTSTATUS
query_dom_info_6(TALLOC_CTX
*mem_ctx
,
3324 struct samr_DomInfo6
*r
)
3326 /* NT returns its own name when a PDC. win2k and later
3327 * only the name of the PDC if itself is a BDC (samba4
3329 r
->primary
.string
= lp_netbios_name();
3331 return NT_STATUS_OK
;
3334 /*******************************************************************
3335 ********************************************************************/
3337 static NTSTATUS
query_dom_info_7(TALLOC_CTX
*mem_ctx
,
3338 struct samr_DomInfo7
*r
)
3340 r
->role
= (enum samr_Role
) samr_get_server_role();
3342 return NT_STATUS_OK
;
3345 /*******************************************************************
3346 ********************************************************************/
3348 static NTSTATUS
query_dom_info_8(TALLOC_CTX
*mem_ctx
,
3349 struct samr_DomInfo8
*r
)
3357 if (!pdb_get_seq_num(&seq_num
)) {
3358 seq_num
= time(NULL
);
3365 r
->sequence_num
= seq_num
;
3366 r
->domain_create_time
= 0;
3368 return NT_STATUS_OK
;
3371 /*******************************************************************
3372 ********************************************************************/
3374 static NTSTATUS
query_dom_info_9(TALLOC_CTX
*mem_ctx
,
3375 struct samr_DomInfo9
*r
)
3377 r
->domain_server_state
= DOMAIN_SERVER_ENABLED
;
3379 return NT_STATUS_OK
;
3382 /*******************************************************************
3383 ********************************************************************/
3385 static NTSTATUS
query_dom_info_11(TALLOC_CTX
*mem_ctx
,
3386 struct samr_DomGeneralInformation2
*r
,
3387 struct samr_domain_info
*dinfo
)
3390 uint32_t account_policy_temp
;
3391 time_t u_lock_duration
, u_reset_time
;
3393 status
= query_dom_info_2(mem_ctx
, &r
->general
, dinfo
);
3394 if (!NT_STATUS_IS_OK(status
)) {
3402 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
3403 u_lock_duration
= account_policy_temp
;
3404 if (u_lock_duration
!= -1) {
3405 u_lock_duration
*= 60;
3408 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME
, &account_policy_temp
);
3409 u_reset_time
= account_policy_temp
* 60;
3411 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
3412 r
->lockout_threshold
= account_policy_temp
;
3418 unix_to_nt_time_abs(&r
->lockout_duration
, u_lock_duration
);
3419 unix_to_nt_time_abs(&r
->lockout_window
, u_reset_time
);
3421 return NT_STATUS_OK
;
3424 /*******************************************************************
3425 ********************************************************************/
3427 static NTSTATUS
query_dom_info_12(TALLOC_CTX
*mem_ctx
,
3428 struct samr_DomInfo12
*r
)
3430 uint32_t account_policy_temp
;
3431 time_t u_lock_duration
, u_reset_time
;
3437 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, &account_policy_temp
);
3438 u_lock_duration
= account_policy_temp
;
3439 if (u_lock_duration
!= -1) {
3440 u_lock_duration
*= 60;
3443 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME
, &account_policy_temp
);
3444 u_reset_time
= account_policy_temp
* 60;
3446 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
, &account_policy_temp
);
3447 r
->lockout_threshold
= account_policy_temp
;
3453 unix_to_nt_time_abs(&r
->lockout_duration
, u_lock_duration
);
3454 unix_to_nt_time_abs(&r
->lockout_window
, u_reset_time
);
3456 return NT_STATUS_OK
;
3459 /*******************************************************************
3460 ********************************************************************/
3462 static NTSTATUS
query_dom_info_13(TALLOC_CTX
*mem_ctx
,
3463 struct samr_DomInfo13
*r
)
3471 if (!pdb_get_seq_num(&seq_num
)) {
3472 seq_num
= time(NULL
);
3479 r
->sequence_num
= seq_num
;
3480 r
->domain_create_time
= 0;
3481 r
->modified_count_at_last_promotion
= 0;
3483 return NT_STATUS_OK
;
3486 /*******************************************************************
3487 _samr_QueryDomainInfo
3488 ********************************************************************/
3490 NTSTATUS
_samr_QueryDomainInfo(struct pipes_struct
*p
,
3491 struct samr_QueryDomainInfo
*r
)
3493 NTSTATUS status
= NT_STATUS_OK
;
3494 struct samr_domain_info
*dinfo
;
3495 union samr_DomainInfo
*dom_info
;
3497 uint32_t acc_required
;
3499 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3501 switch (r
->in
.level
) {
3502 case 1: /* DomainPasswordInformation */
3503 case 12: /* DomainLockoutInformation */
3504 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3505 acc_required
= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
;
3507 case 11: /* DomainGeneralInformation2 */
3508 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3509 * DOMAIN_READ_OTHER_PARAMETERS */
3510 acc_required
= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
3511 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
3513 case 2: /* DomainGeneralInformation */
3514 case 3: /* DomainLogoffInformation */
3515 case 4: /* DomainOemInformation */
3516 case 5: /* DomainReplicationInformation */
3517 case 6: /* DomainReplicationInformation */
3518 case 7: /* DomainServerRoleInformation */
3519 case 8: /* DomainModifiedInformation */
3520 case 9: /* DomainStateInformation */
3521 case 10: /* DomainUasInformation */
3522 case 13: /* DomainModifiedInformation2 */
3523 /* DOMAIN_READ_OTHER_PARAMETERS */
3524 acc_required
= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
3527 return NT_STATUS_INVALID_INFO_CLASS
;
3530 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
3532 struct samr_domain_info
, &status
);
3533 if (!NT_STATUS_IS_OK(status
)) {
3537 dom_info
= talloc_zero(p
->mem_ctx
, union samr_DomainInfo
);
3539 return NT_STATUS_NO_MEMORY
;
3542 switch (r
->in
.level
) {
3544 status
= query_dom_info_1(p
->mem_ctx
, &dom_info
->info1
);
3547 status
= query_dom_info_2(p
->mem_ctx
, &dom_info
->general
, dinfo
);
3550 status
= query_dom_info_3(p
->mem_ctx
, &dom_info
->info3
);
3553 status
= query_dom_info_4(p
->mem_ctx
, &dom_info
->oem
);
3556 status
= query_dom_info_5(p
->mem_ctx
, &dom_info
->info5
);
3559 status
= query_dom_info_6(p
->mem_ctx
, &dom_info
->info6
);
3562 status
= query_dom_info_7(p
->mem_ctx
, &dom_info
->info7
);
3565 status
= query_dom_info_8(p
->mem_ctx
, &dom_info
->info8
);
3568 status
= query_dom_info_9(p
->mem_ctx
, &dom_info
->info9
);
3571 status
= query_dom_info_11(p
->mem_ctx
, &dom_info
->general2
, dinfo
);
3574 status
= query_dom_info_12(p
->mem_ctx
, &dom_info
->info12
);
3577 status
= query_dom_info_13(p
->mem_ctx
, &dom_info
->info13
);
3580 return NT_STATUS_INVALID_INFO_CLASS
;
3583 if (!NT_STATUS_IS_OK(status
)) {
3587 *r
->out
.info
= dom_info
;
3589 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__
));
3594 /* W2k3 seems to use the same check for all 3 objects that can be created via
3595 * SAMR, if you try to create for example "Dialup" as an alias it says
3596 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3599 static NTSTATUS
can_create(TALLOC_CTX
*mem_ctx
, const char *new_name
)
3601 enum lsa_SidType type
;
3604 DEBUG(10, ("Checking whether [%s] can be created\n", new_name
));
3607 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3608 * whether the name already exists */
3609 result
= lookup_name(mem_ctx
, new_name
, LOOKUP_NAME_LOCAL
,
3610 NULL
, NULL
, NULL
, &type
);
3614 DEBUG(10, ("%s does not exist, can create it\n", new_name
));
3615 return NT_STATUS_OK
;
3618 DEBUG(5, ("trying to create %s, exists as %s\n",
3619 new_name
, sid_type_lookup(type
)));
3621 if (type
== SID_NAME_DOM_GRP
) {
3622 return NT_STATUS_GROUP_EXISTS
;
3624 if (type
== SID_NAME_ALIAS
) {
3625 return NT_STATUS_ALIAS_EXISTS
;
3628 /* Yes, the default is NT_STATUS_USER_EXISTS */
3629 return NT_STATUS_USER_EXISTS
;
3632 /*******************************************************************
3634 ********************************************************************/
3636 NTSTATUS
_samr_CreateUser2(struct pipes_struct
*p
,
3637 struct samr_CreateUser2
*r
)
3639 const char *account
= NULL
;
3641 uint32_t acb_info
= r
->in
.acct_flags
;
3642 struct samr_domain_info
*dinfo
;
3643 struct samr_user_info
*uinfo
;
3646 struct security_descriptor
*psd
;
3648 /* check this, when giving away 'add computer to domain' privs */
3649 uint32 des_access
= GENERIC_RIGHTS_USER_ALL_ACCESS
;
3650 bool can_add_account
= False
;
3652 /* Which privilege is needed to override the ACL? */
3653 enum sec_privilege needed_priv
= SEC_PRIV_INVALID
;
3655 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
3656 SAMR_DOMAIN_ACCESS_CREATE_USER
, NULL
,
3657 struct samr_domain_info
, &nt_status
);
3658 if (!NT_STATUS_IS_OK(nt_status
)) {
3662 if (sid_check_is_builtin(&dinfo
->sid
)) {
3663 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3664 return NT_STATUS_ACCESS_DENIED
;
3667 if (!(acb_info
== ACB_NORMAL
|| acb_info
== ACB_DOMTRUST
||
3668 acb_info
== ACB_WSTRUST
|| acb_info
== ACB_SVRTRUST
)) {
3669 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3670 this parameter is not an account type */
3671 return NT_STATUS_INVALID_PARAMETER
;
3674 account
= r
->in
.account_name
->string
;
3675 if (account
== NULL
) {
3676 return NT_STATUS_NO_MEMORY
;
3679 nt_status
= can_create(p
->mem_ctx
, account
);
3680 if (!NT_STATUS_IS_OK(nt_status
)) {
3684 /* determine which user right we need to check based on the acb_info */
3687 can_add_account
= true;
3688 } else if (acb_info
& ACB_WSTRUST
) {
3689 needed_priv
= SEC_PRIV_MACHINE_ACCOUNT
;
3690 can_add_account
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_MACHINE_ACCOUNT
);
3691 } else if (acb_info
& ACB_NORMAL
&&
3692 (account
[strlen(account
)-1] != '$')) {
3693 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3694 account for domain trusts and changes the ACB flags later */
3695 needed_priv
= SEC_PRIV_ADD_USERS
;
3696 can_add_account
= security_token_has_privilege(p
->session_info
->security_token
, SEC_PRIV_ADD_USERS
);
3697 } else if (lp_enable_privileges()) {
3698 /* implicit assumption of a BDC or domain trust account here
3699 * (we already check the flags earlier) */
3700 /* only Domain Admins can add a BDC or domain trust */
3701 can_add_account
= nt_token_check_domain_rid(
3702 p
->session_info
->security_token
,
3703 DOMAIN_RID_ADMINS
);
3706 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3707 uidtoname(p
->session_info
->unix_token
->uid
),
3708 can_add_account
? "True":"False" ));
3710 if (!can_add_account
) {
3711 return NT_STATUS_ACCESS_DENIED
;
3714 /********** BEGIN Admin BLOCK **********/
3717 nt_status
= pdb_create_user(p
->mem_ctx
, account
, acb_info
,
3721 /********** END Admin BLOCK **********/
3723 /* now check for failure */
3725 if ( !NT_STATUS_IS_OK(nt_status
) )
3728 /* Get the user's SID */
3730 sid_compose(&sid
, get_global_sam_sid(), *r
->out
.rid
);
3732 map_max_allowed_access(p
->session_info
->security_token
,
3733 p
->session_info
->unix_token
,
3736 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &usr_generic_mapping
,
3737 &sid
, SAMR_USR_RIGHTS_WRITE_PW
);
3738 se_map_generic(&des_access
, &usr_generic_mapping
);
3741 * JRA - TESTME. We just created this user so we
3742 * had rights to create them. Do we need to check
3743 * any further access on this object ? Can't we
3744 * just assume we have all the rights we need ?
3747 nt_status
= access_check_object(psd
, p
->session_info
->security_token
,
3748 needed_priv
, SEC_PRIV_INVALID
,
3749 GENERIC_RIGHTS_USER_WRITE
, des_access
,
3750 &acc_granted
, "_samr_CreateUser2");
3752 if ( !NT_STATUS_IS_OK(nt_status
) ) {
3756 uinfo
= policy_handle_create(p
, r
->out
.user_handle
, acc_granted
,
3757 struct samr_user_info
, &nt_status
);
3758 if (!NT_STATUS_IS_OK(nt_status
)) {
3763 /* After a "set" ensure we have no cached display info. */
3764 force_flush_samr_cache(&sid
);
3766 *r
->out
.access_granted
= acc_granted
;
3768 return NT_STATUS_OK
;
3771 /****************************************************************
3772 ****************************************************************/
3774 NTSTATUS
_samr_CreateUser(struct pipes_struct
*p
,
3775 struct samr_CreateUser
*r
)
3777 struct samr_CreateUser2 c
;
3778 uint32_t access_granted
;
3780 c
.in
.domain_handle
= r
->in
.domain_handle
;
3781 c
.in
.account_name
= r
->in
.account_name
;
3782 c
.in
.acct_flags
= ACB_NORMAL
;
3783 c
.in
.access_mask
= r
->in
.access_mask
;
3784 c
.out
.user_handle
= r
->out
.user_handle
;
3785 c
.out
.access_granted
= &access_granted
;
3786 c
.out
.rid
= r
->out
.rid
;
3788 return _samr_CreateUser2(p
, &c
);
3791 /*******************************************************************
3793 ********************************************************************/
3795 NTSTATUS
_samr_Connect(struct pipes_struct
*p
,
3796 struct samr_Connect
*r
)
3798 uint32_t acc_granted
;
3799 struct policy_handle hnd
;
3800 uint32 des_access
= r
->in
.access_mask
;
3805 if (!pipe_access_check(p
)) {
3806 DEBUG(3, ("access denied to _samr_Connect\n"));
3807 return NT_STATUS_ACCESS_DENIED
;
3810 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3811 was observed from a win98 client trying to enumerate users (when configured
3812 user level access control on shares) --jerry */
3814 map_max_allowed_access(p
->session_info
->security_token
,
3815 p
->session_info
->unix_token
,
3818 se_map_generic( &des_access
, &sam_generic_mapping
);
3820 acc_granted
= des_access
& (SAMR_ACCESS_ENUM_DOMAINS
3821 |SAMR_ACCESS_LOOKUP_DOMAIN
);
3823 /* set up the SAMR connect_anon response */
3825 (void)policy_handle_create(p
, &hnd
, acc_granted
,
3826 struct samr_connect_info
,
3828 if (!NT_STATUS_IS_OK(status
)) {
3832 *r
->out
.connect_handle
= hnd
;
3833 return NT_STATUS_OK
;
3836 /*******************************************************************
3838 ********************************************************************/
3840 NTSTATUS
_samr_Connect2(struct pipes_struct
*p
,
3841 struct samr_Connect2
*r
)
3843 struct policy_handle hnd
;
3844 struct security_descriptor
*psd
= NULL
;
3846 uint32 des_access
= r
->in
.access_mask
;
3849 const char *fn
= "_samr_Connect2";
3852 case NDR_SAMR_CONNECT2
:
3853 fn
= "_samr_Connect2";
3855 case NDR_SAMR_CONNECT3
:
3856 fn
= "_samr_Connect3";
3858 case NDR_SAMR_CONNECT4
:
3859 fn
= "_samr_Connect4";
3861 case NDR_SAMR_CONNECT5
:
3862 fn
= "_samr_Connect5";
3866 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3870 if (!pipe_access_check(p
)) {
3871 DEBUG(3, ("access denied to %s\n", fn
));
3872 return NT_STATUS_ACCESS_DENIED
;
3875 map_max_allowed_access(p
->session_info
->security_token
,
3876 p
->session_info
->unix_token
,
3879 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &sam_generic_mapping
, NULL
, 0);
3880 se_map_generic(&des_access
, &sam_generic_mapping
);
3882 nt_status
= access_check_object(psd
, p
->session_info
->security_token
,
3883 SEC_PRIV_INVALID
, SEC_PRIV_INVALID
,
3884 0, des_access
, &acc_granted
, fn
);
3886 if ( !NT_STATUS_IS_OK(nt_status
) )
3889 (void)policy_handle_create(p
, &hnd
, acc_granted
,
3890 struct samr_connect_info
, &nt_status
);
3891 if (!NT_STATUS_IS_OK(nt_status
)) {
3895 DEBUG(5,("%s: %d\n", fn
, __LINE__
));
3897 *r
->out
.connect_handle
= hnd
;
3898 return NT_STATUS_OK
;
3901 /****************************************************************
3903 ****************************************************************/
3905 NTSTATUS
_samr_Connect3(struct pipes_struct
*p
,
3906 struct samr_Connect3
*r
)
3908 struct samr_Connect2 c
;
3910 c
.in
.system_name
= r
->in
.system_name
;
3911 c
.in
.access_mask
= r
->in
.access_mask
;
3912 c
.out
.connect_handle
= r
->out
.connect_handle
;
3914 return _samr_Connect2(p
, &c
);
3917 /*******************************************************************
3919 ********************************************************************/
3921 NTSTATUS
_samr_Connect4(struct pipes_struct
*p
,
3922 struct samr_Connect4
*r
)
3924 struct samr_Connect2 c
;
3926 c
.in
.system_name
= r
->in
.system_name
;
3927 c
.in
.access_mask
= r
->in
.access_mask
;
3928 c
.out
.connect_handle
= r
->out
.connect_handle
;
3930 return _samr_Connect2(p
, &c
);
3933 /*******************************************************************
3935 ********************************************************************/
3937 NTSTATUS
_samr_Connect5(struct pipes_struct
*p
,
3938 struct samr_Connect5
*r
)
3941 struct samr_Connect2 c
;
3942 struct samr_ConnectInfo1 info1
;
3944 info1
.client_version
= SAMR_CONNECT_AFTER_W2K
;
3947 c
.in
.system_name
= r
->in
.system_name
;
3948 c
.in
.access_mask
= r
->in
.access_mask
;
3949 c
.out
.connect_handle
= r
->out
.connect_handle
;
3951 *r
->out
.level_out
= 1;
3953 status
= _samr_Connect2(p
, &c
);
3954 if (!NT_STATUS_IS_OK(status
)) {
3958 r
->out
.info_out
->info1
= info1
;
3960 return NT_STATUS_OK
;
3963 /**********************************************************************
3965 **********************************************************************/
3967 NTSTATUS
_samr_LookupDomain(struct pipes_struct
*p
,
3968 struct samr_LookupDomain
*r
)
3971 const char *domain_name
;
3972 struct dom_sid
*sid
= NULL
;
3974 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3975 Reverted that change so we will work with RAS servers again */
3977 (void)policy_handle_find(p
, r
->in
.connect_handle
,
3978 SAMR_ACCESS_LOOKUP_DOMAIN
, NULL
,
3979 struct samr_connect_info
,
3981 if (!NT_STATUS_IS_OK(status
)) {
3985 domain_name
= r
->in
.domain_name
->string
;
3987 return NT_STATUS_INVALID_PARAMETER
;
3990 sid
= talloc_zero(p
->mem_ctx
, struct dom_sid2
);
3992 return NT_STATUS_NO_MEMORY
;
3995 if (strequal(domain_name
, builtin_domain_name())) {
3996 sid_copy(sid
, &global_sid_Builtin
);
3998 if (!secrets_fetch_domain_sid(domain_name
, sid
)) {
3999 status
= NT_STATUS_NO_SUCH_DOMAIN
;
4003 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name
,
4004 sid_string_dbg(sid
)));
4011 /**********************************************************************
4013 **********************************************************************/
4015 NTSTATUS
_samr_EnumDomains(struct pipes_struct
*p
,
4016 struct samr_EnumDomains
*r
)
4019 uint32_t num_entries
= 2;
4020 struct samr_SamEntry
*entry_array
= NULL
;
4021 struct samr_SamArray
*sam
;
4023 (void)policy_handle_find(p
, r
->in
.connect_handle
,
4024 SAMR_ACCESS_ENUM_DOMAINS
, NULL
,
4025 struct samr_connect_info
, &status
);
4026 if (!NT_STATUS_IS_OK(status
)) {
4030 sam
= talloc_zero(p
->mem_ctx
, struct samr_SamArray
);
4032 return NT_STATUS_NO_MEMORY
;
4035 entry_array
= talloc_zero_array(p
->mem_ctx
,
4036 struct samr_SamEntry
,
4039 return NT_STATUS_NO_MEMORY
;
4042 entry_array
[0].idx
= 0;
4043 init_lsa_String(&entry_array
[0].name
, get_global_sam_name());
4045 entry_array
[1].idx
= 1;
4046 init_lsa_String(&entry_array
[1].name
, "Builtin");
4048 sam
->count
= num_entries
;
4049 sam
->entries
= entry_array
;
4052 *r
->out
.num_entries
= num_entries
;
4057 /*******************************************************************
4059 ********************************************************************/
4061 NTSTATUS
_samr_OpenAlias(struct pipes_struct
*p
,
4062 struct samr_OpenAlias
*r
)
4065 uint32 alias_rid
= r
->in
.rid
;
4066 struct samr_alias_info
*ainfo
;
4067 struct samr_domain_info
*dinfo
;
4068 struct security_descriptor
*psd
= NULL
;
4070 uint32 des_access
= r
->in
.access_mask
;
4074 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
4075 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
4076 struct samr_domain_info
, &status
);
4077 if (!NT_STATUS_IS_OK(status
)) {
4081 /* append the alias' RID to it */
4083 if (!sid_compose(&sid
, &dinfo
->sid
, alias_rid
))
4084 return NT_STATUS_NO_SUCH_ALIAS
;
4086 /*check if access can be granted as requested by client. */
4088 map_max_allowed_access(p
->session_info
->security_token
,
4089 p
->session_info
->unix_token
,
4092 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &ali_generic_mapping
, NULL
, 0);
4093 se_map_generic(&des_access
,&ali_generic_mapping
);
4095 status
= access_check_object(psd
, p
->session_info
->security_token
,
4096 SEC_PRIV_ADD_USERS
, SEC_PRIV_INVALID
,
4097 GENERIC_RIGHTS_ALIAS_ALL_ACCESS
,
4098 des_access
, &acc_granted
, "_samr_OpenAlias");
4100 if ( !NT_STATUS_IS_OK(status
) )
4104 /* Check we actually have the requested alias */
4105 enum lsa_SidType type
;
4110 result
= lookup_sid(NULL
, &sid
, NULL
, NULL
, &type
);
4113 if (!result
|| (type
!= SID_NAME_ALIAS
)) {
4114 return NT_STATUS_NO_SUCH_ALIAS
;
4117 /* make sure there is a mapping */
4119 if ( !sid_to_gid( &sid
, &gid
) ) {
4120 return NT_STATUS_NO_SUCH_ALIAS
;
4125 ainfo
= policy_handle_create(p
, r
->out
.alias_handle
, acc_granted
,
4126 struct samr_alias_info
, &status
);
4127 if (!NT_STATUS_IS_OK(status
)) {
4132 return NT_STATUS_OK
;
4135 /*******************************************************************
4137 ********************************************************************/
4139 static NTSTATUS
set_user_info_2(TALLOC_CTX
*mem_ctx
,
4140 struct samr_UserInfo2
*id2
,
4144 DEBUG(5,("set_user_info_2: NULL id2\n"));
4145 return NT_STATUS_ACCESS_DENIED
;
4148 copy_id2_to_sam_passwd(pwd
, id2
);
4150 return pdb_update_sam_account(pwd
);
4153 /*******************************************************************
4155 ********************************************************************/
4157 static NTSTATUS
set_user_info_4(TALLOC_CTX
*mem_ctx
,
4158 struct samr_UserInfo4
*id4
,
4162 DEBUG(5,("set_user_info_2: NULL id4\n"));
4163 return NT_STATUS_ACCESS_DENIED
;
4166 copy_id4_to_sam_passwd(pwd
, id4
);
4168 return pdb_update_sam_account(pwd
);
4171 /*******************************************************************
4173 ********************************************************************/
4175 static NTSTATUS
set_user_info_6(TALLOC_CTX
*mem_ctx
,
4176 struct samr_UserInfo6
*id6
,
4180 DEBUG(5,("set_user_info_6: NULL id6\n"));
4181 return NT_STATUS_ACCESS_DENIED
;
4184 copy_id6_to_sam_passwd(pwd
, id6
);
4186 return pdb_update_sam_account(pwd
);
4189 /*******************************************************************
4191 ********************************************************************/
4193 static NTSTATUS
set_user_info_7(TALLOC_CTX
*mem_ctx
,
4194 struct samr_UserInfo7
*id7
,
4200 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4201 return NT_STATUS_ACCESS_DENIED
;
4204 if (!id7
->account_name
.string
) {
4205 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4206 return NT_STATUS_ACCESS_DENIED
;
4209 /* check to see if the new username already exists. Note: we can't
4210 reliably lock all backends, so there is potentially the
4211 possibility that a user can be created in between this check and
4212 the rename. The rename should fail, but may not get the
4213 exact same failure status code. I think this is small enough
4214 of a window for this type of operation and the results are
4215 simply that the rename fails with a slightly different status
4216 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4218 rc
= can_create(mem_ctx
, id7
->account_name
.string
);
4220 /* when there is nothing to change, we're done here */
4221 if (NT_STATUS_EQUAL(rc
, NT_STATUS_USER_EXISTS
) &&
4222 strequal(id7
->account_name
.string
, pdb_get_username(pwd
))) {
4223 return NT_STATUS_OK
;
4225 if (!NT_STATUS_IS_OK(rc
)) {
4229 rc
= pdb_rename_sam_account(pwd
, id7
->account_name
.string
);
4234 /*******************************************************************
4236 ********************************************************************/
4238 static NTSTATUS
set_user_info_8(TALLOC_CTX
*mem_ctx
,
4239 struct samr_UserInfo8
*id8
,
4243 DEBUG(5,("set_user_info_8: NULL id8\n"));
4244 return NT_STATUS_ACCESS_DENIED
;
4247 copy_id8_to_sam_passwd(pwd
, id8
);
4249 return pdb_update_sam_account(pwd
);
4252 /*******************************************************************
4254 ********************************************************************/
4256 static NTSTATUS
set_user_info_10(TALLOC_CTX
*mem_ctx
,
4257 struct samr_UserInfo10
*id10
,
4261 DEBUG(5,("set_user_info_8: NULL id10\n"));
4262 return NT_STATUS_ACCESS_DENIED
;
4265 copy_id10_to_sam_passwd(pwd
, id10
);
4267 return pdb_update_sam_account(pwd
);
4270 /*******************************************************************
4272 ********************************************************************/
4274 static NTSTATUS
set_user_info_11(TALLOC_CTX
*mem_ctx
,
4275 struct samr_UserInfo11
*id11
,
4279 DEBUG(5,("set_user_info_11: NULL id11\n"));
4280 return NT_STATUS_ACCESS_DENIED
;
4283 copy_id11_to_sam_passwd(pwd
, id11
);
4285 return pdb_update_sam_account(pwd
);
4288 /*******************************************************************
4290 ********************************************************************/
4292 static NTSTATUS
set_user_info_12(TALLOC_CTX
*mem_ctx
,
4293 struct samr_UserInfo12
*id12
,
4297 DEBUG(5,("set_user_info_12: NULL id12\n"));
4298 return NT_STATUS_ACCESS_DENIED
;
4301 copy_id12_to_sam_passwd(pwd
, id12
);
4303 return pdb_update_sam_account(pwd
);
4306 /*******************************************************************
4308 ********************************************************************/
4310 static NTSTATUS
set_user_info_13(TALLOC_CTX
*mem_ctx
,
4311 struct samr_UserInfo13
*id13
,
4315 DEBUG(5,("set_user_info_13: NULL id13\n"));
4316 return NT_STATUS_ACCESS_DENIED
;
4319 copy_id13_to_sam_passwd(pwd
, id13
);
4321 return pdb_update_sam_account(pwd
);
4324 /*******************************************************************
4326 ********************************************************************/
4328 static NTSTATUS
set_user_info_14(TALLOC_CTX
*mem_ctx
,
4329 struct samr_UserInfo14
*id14
,
4333 DEBUG(5,("set_user_info_14: NULL id14\n"));
4334 return NT_STATUS_ACCESS_DENIED
;
4337 copy_id14_to_sam_passwd(pwd
, id14
);
4339 return pdb_update_sam_account(pwd
);
4342 /*******************************************************************
4344 ********************************************************************/
4346 static NTSTATUS
set_user_info_16(TALLOC_CTX
*mem_ctx
,
4347 struct samr_UserInfo16
*id16
,
4351 DEBUG(5,("set_user_info_16: NULL id16\n"));
4352 return NT_STATUS_ACCESS_DENIED
;
4355 copy_id16_to_sam_passwd(pwd
, id16
);
4357 return pdb_update_sam_account(pwd
);
4360 /*******************************************************************
4362 ********************************************************************/
4364 static NTSTATUS
set_user_info_17(TALLOC_CTX
*mem_ctx
,
4365 struct samr_UserInfo17
*id17
,
4369 DEBUG(5,("set_user_info_17: NULL id17\n"));
4370 return NT_STATUS_ACCESS_DENIED
;
4373 copy_id17_to_sam_passwd(pwd
, id17
);
4375 return pdb_update_sam_account(pwd
);
4378 /*******************************************************************
4380 ********************************************************************/
4382 static NTSTATUS
set_user_info_18(struct samr_UserInfo18
*id18
,
4383 TALLOC_CTX
*mem_ctx
,
4384 DATA_BLOB
*session_key
,
4388 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4389 return NT_STATUS_INVALID_PARAMETER
;
4392 if (id18
->nt_pwd_active
|| id18
->lm_pwd_active
) {
4393 if (!session_key
->length
) {
4394 return NT_STATUS_NO_USER_SESSION_KEY
;
4398 if (id18
->nt_pwd_active
) {
4402 in
= data_blob_const(id18
->nt_pwd
.hash
, 16);
4403 out
= data_blob_talloc_zero(mem_ctx
, 16);
4405 sess_crypt_blob(&out
, &in
, session_key
, false);
4407 if (!pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4408 return NT_STATUS_ACCESS_DENIED
;
4411 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4414 if (id18
->lm_pwd_active
) {
4418 in
= data_blob_const(id18
->lm_pwd
.hash
, 16);
4419 out
= data_blob_talloc_zero(mem_ctx
, 16);
4421 sess_crypt_blob(&out
, &in
, session_key
, false);
4423 if (!pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
)) {
4424 return NT_STATUS_ACCESS_DENIED
;
4427 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4430 copy_id18_to_sam_passwd(pwd
, id18
);
4432 return pdb_update_sam_account(pwd
);
4435 /*******************************************************************
4437 ********************************************************************/
4439 static NTSTATUS
set_user_info_20(TALLOC_CTX
*mem_ctx
,
4440 struct samr_UserInfo20
*id20
,
4444 DEBUG(5,("set_user_info_20: NULL id20\n"));
4445 return NT_STATUS_ACCESS_DENIED
;
4448 copy_id20_to_sam_passwd(pwd
, id20
);
4450 return pdb_update_sam_account(pwd
);
4453 /*******************************************************************
4455 ********************************************************************/
4457 static NTSTATUS
set_user_info_21(struct samr_UserInfo21
*id21
,
4458 TALLOC_CTX
*mem_ctx
,
4459 DATA_BLOB
*session_key
,
4465 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4466 return NT_STATUS_INVALID_PARAMETER
;
4469 if (id21
->fields_present
== 0) {
4470 return NT_STATUS_INVALID_PARAMETER
;
4473 if (id21
->fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4474 return NT_STATUS_ACCESS_DENIED
;
4477 if (id21
->fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
4478 if (id21
->nt_password_set
) {
4481 if ((id21
->nt_owf_password
.length
!= 16) ||
4482 (id21
->nt_owf_password
.size
!= 16)) {
4483 return NT_STATUS_INVALID_PARAMETER
;
4486 if (!session_key
->length
) {
4487 return NT_STATUS_NO_USER_SESSION_KEY
;
4490 in
= data_blob_const(id21
->nt_owf_password
.array
, 16);
4491 out
= data_blob_talloc_zero(mem_ctx
, 16);
4493 sess_crypt_blob(&out
, &in
, session_key
, false);
4495 pdb_set_nt_passwd(pwd
, out
.data
, PDB_CHANGED
);
4496 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4500 if (id21
->fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4501 if (id21
->lm_password_set
) {
4504 if ((id21
->lm_owf_password
.length
!= 16) ||
4505 (id21
->lm_owf_password
.size
!= 16)) {
4506 return NT_STATUS_INVALID_PARAMETER
;
4509 if (!session_key
->length
) {
4510 return NT_STATUS_NO_USER_SESSION_KEY
;
4513 in
= data_blob_const(id21
->lm_owf_password
.array
, 16);
4514 out
= data_blob_talloc_zero(mem_ctx
, 16);
4516 sess_crypt_blob(&out
, &in
, session_key
, false);
4518 pdb_set_lanman_passwd(pwd
, out
.data
, PDB_CHANGED
);
4519 pdb_set_pass_last_set_time(pwd
, time(NULL
), PDB_CHANGED
);
4523 /* we need to separately check for an account rename first */
4525 if (id21
->account_name
.string
&&
4526 (!strequal(id21
->account_name
.string
, pdb_get_username(pwd
))))
4529 /* check to see if the new username already exists. Note: we can't
4530 reliably lock all backends, so there is potentially the
4531 possibility that a user can be created in between this check and
4532 the rename. The rename should fail, but may not get the
4533 exact same failure status code. I think this is small enough
4534 of a window for this type of operation and the results are
4535 simply that the rename fails with a slightly different status
4536 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4538 status
= can_create(mem_ctx
, id21
->account_name
.string
);
4539 if (!NT_STATUS_IS_OK(status
)) {
4543 status
= pdb_rename_sam_account(pwd
, id21
->account_name
.string
);
4545 if (!NT_STATUS_IS_OK(status
)) {
4546 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4547 nt_errstr(status
)));
4551 /* set the new username so that later
4552 functions can work on the new account */
4553 pdb_set_username(pwd
, id21
->account_name
.string
, PDB_SET
);
4556 copy_id21_to_sam_passwd("INFO_21", pwd
, id21
);
4559 * The funny part about the previous two calls is
4560 * that pwd still has the password hashes from the
4561 * passdb entry. These have not been updated from
4562 * id21. I don't know if they need to be set. --jerry
4565 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4566 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4567 if ( !NT_STATUS_IS_OK(status
) ) {
4572 /* Don't worry about writing out the user account since the
4573 primary group SID is generated solely from the user's Unix
4576 /* write the change out */
4577 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4581 return NT_STATUS_OK
;
4584 /*******************************************************************
4586 ********************************************************************/
4588 static NTSTATUS
set_user_info_23(TALLOC_CTX
*mem_ctx
,
4589 struct samr_UserInfo23
*id23
,
4593 char *plaintext_buf
= NULL
;
4599 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4600 return NT_STATUS_INVALID_PARAMETER
;
4603 if (id23
->info
.fields_present
== 0) {
4604 return NT_STATUS_INVALID_PARAMETER
;
4607 if (id23
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4608 return NT_STATUS_ACCESS_DENIED
;
4611 if ((id23
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4612 (id23
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4614 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4615 pdb_get_username(pwd
)));
4617 if (!decode_pw_buffer(mem_ctx
,
4618 id23
->password
.data
,
4622 return NT_STATUS_WRONG_PASSWORD
;
4625 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4626 return NT_STATUS_ACCESS_DENIED
;
4630 copy_id23_to_sam_passwd(pwd
, id23
);
4632 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4634 /* if it's a trust account, don't update /etc/passwd */
4635 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4636 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4637 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4638 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4639 } else if (plaintext_buf
) {
4640 /* update the UNIX password */
4641 if (lp_unix_password_sync() ) {
4642 struct passwd
*passwd
;
4643 if (pdb_get_username(pwd
) == NULL
) {
4644 DEBUG(1, ("chgpasswd: User without name???\n"));
4645 return NT_STATUS_ACCESS_DENIED
;
4648 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4649 if (passwd
== NULL
) {
4650 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4653 if(!chgpasswd(pdb_get_username(pwd
), rhost
,
4654 passwd
, "", plaintext_buf
, True
)) {
4655 return NT_STATUS_ACCESS_DENIED
;
4657 TALLOC_FREE(passwd
);
4661 if (plaintext_buf
) {
4662 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4665 if (IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) &&
4666 (!NT_STATUS_IS_OK(status
= pdb_set_unix_primary_group(mem_ctx
,
4671 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4675 return NT_STATUS_OK
;
4678 /*******************************************************************
4680 ********************************************************************/
4682 static bool set_user_info_pw(uint8
*pass
, const char *rhost
, struct samu
*pwd
)
4685 char *plaintext_buf
= NULL
;
4688 DEBUG(5, ("Attempting administrator password change for user %s\n",
4689 pdb_get_username(pwd
)));
4691 acct_ctrl
= pdb_get_acct_ctrl(pwd
);
4693 if (!decode_pw_buffer(talloc_tos(),
4701 if (!pdb_set_plaintext_passwd (pwd
, plaintext_buf
)) {
4705 /* if it's a trust account, don't update /etc/passwd */
4706 if ( ( (acct_ctrl
& ACB_DOMTRUST
) == ACB_DOMTRUST
) ||
4707 ( (acct_ctrl
& ACB_WSTRUST
) == ACB_WSTRUST
) ||
4708 ( (acct_ctrl
& ACB_SVRTRUST
) == ACB_SVRTRUST
) ) {
4709 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4711 /* update the UNIX password */
4712 if (lp_unix_password_sync()) {
4713 struct passwd
*passwd
;
4715 if (pdb_get_username(pwd
) == NULL
) {
4716 DEBUG(1, ("chgpasswd: User without name???\n"));
4720 passwd
= Get_Pwnam_alloc(pwd
, pdb_get_username(pwd
));
4721 if (passwd
== NULL
) {
4722 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4725 if(!chgpasswd(pdb_get_username(pwd
), rhost
, passwd
,
4726 "", plaintext_buf
, True
)) {
4729 TALLOC_FREE(passwd
);
4733 memset(plaintext_buf
, '\0', strlen(plaintext_buf
));
4735 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4740 /*******************************************************************
4742 ********************************************************************/
4744 static NTSTATUS
set_user_info_24(TALLOC_CTX
*mem_ctx
,
4746 struct samr_UserInfo24
*id24
,
4752 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4753 return NT_STATUS_INVALID_PARAMETER
;
4756 if (!set_user_info_pw(id24
->password
.data
, rhost
, pwd
)) {
4757 return NT_STATUS_WRONG_PASSWORD
;
4760 copy_id24_to_sam_passwd(pwd
, id24
);
4762 status
= pdb_update_sam_account(pwd
);
4763 if (!NT_STATUS_IS_OK(status
)) {
4767 return NT_STATUS_OK
;
4770 /*******************************************************************
4772 ********************************************************************/
4774 static NTSTATUS
set_user_info_25(TALLOC_CTX
*mem_ctx
,
4776 struct samr_UserInfo25
*id25
,
4782 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4783 return NT_STATUS_INVALID_PARAMETER
;
4786 if (id25
->info
.fields_present
== 0) {
4787 return NT_STATUS_INVALID_PARAMETER
;
4790 if (id25
->info
.fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
4791 return NT_STATUS_ACCESS_DENIED
;
4794 if ((id25
->info
.fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4795 (id25
->info
.fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
)) {
4797 if (!set_user_info_pw(id25
->password
.data
, rhost
, pwd
)) {
4798 return NT_STATUS_WRONG_PASSWORD
;
4802 copy_id25_to_sam_passwd(pwd
, id25
);
4804 /* write the change out */
4805 if(!NT_STATUS_IS_OK(status
= pdb_update_sam_account(pwd
))) {
4810 * We need to "pdb_update_sam_account" before the unix primary group
4811 * is set, because the idealx scripts would also change the
4812 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4813 * the delete explicit / add explicit, which would then fail to find
4814 * the previous primaryGroupSid value.
4817 if ( IS_SAM_CHANGED(pwd
, PDB_GROUPSID
) ) {
4818 status
= pdb_set_unix_primary_group(mem_ctx
, pwd
);
4819 if ( !NT_STATUS_IS_OK(status
) ) {
4824 return NT_STATUS_OK
;
4827 /*******************************************************************
4829 ********************************************************************/
4831 static NTSTATUS
set_user_info_26(TALLOC_CTX
*mem_ctx
,
4833 struct samr_UserInfo26
*id26
,
4839 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4840 return NT_STATUS_INVALID_PARAMETER
;
4843 if (!set_user_info_pw(id26
->password
.data
, rhost
, pwd
)) {
4844 return NT_STATUS_WRONG_PASSWORD
;
4847 copy_id26_to_sam_passwd(pwd
, id26
);
4849 status
= pdb_update_sam_account(pwd
);
4850 if (!NT_STATUS_IS_OK(status
)) {
4854 return NT_STATUS_OK
;
4857 /*************************************************************
4858 **************************************************************/
4860 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields
)
4862 uint32_t acc_required
= 0;
4864 /* USER_ALL_USERNAME */
4865 if (fields
& SAMR_FIELD_ACCOUNT_NAME
)
4866 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4867 /* USER_ALL_FULLNAME */
4868 if (fields
& SAMR_FIELD_FULL_NAME
)
4869 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4870 /* USER_ALL_PRIMARYGROUPID */
4871 if (fields
& SAMR_FIELD_PRIMARY_GID
)
4872 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4873 /* USER_ALL_HOMEDIRECTORY */
4874 if (fields
& SAMR_FIELD_HOME_DIRECTORY
)
4875 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4876 /* USER_ALL_HOMEDIRECTORYDRIVE */
4877 if (fields
& SAMR_FIELD_HOME_DRIVE
)
4878 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4879 /* USER_ALL_SCRIPTPATH */
4880 if (fields
& SAMR_FIELD_LOGON_SCRIPT
)
4881 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4882 /* USER_ALL_PROFILEPATH */
4883 if (fields
& SAMR_FIELD_PROFILE_PATH
)
4884 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4885 /* USER_ALL_ADMINCOMMENT */
4886 if (fields
& SAMR_FIELD_COMMENT
)
4887 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4888 /* USER_ALL_WORKSTATIONS */
4889 if (fields
& SAMR_FIELD_WORKSTATIONS
)
4890 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4891 /* USER_ALL_LOGONHOURS */
4892 if (fields
& SAMR_FIELD_LOGON_HOURS
)
4893 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4894 /* USER_ALL_ACCOUNTEXPIRES */
4895 if (fields
& SAMR_FIELD_ACCT_EXPIRY
)
4896 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4897 /* USER_ALL_USERACCOUNTCONTROL */
4898 if (fields
& SAMR_FIELD_ACCT_FLAGS
)
4899 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4900 /* USER_ALL_PARAMETERS */
4901 if (fields
& SAMR_FIELD_PARAMETERS
)
4902 acc_required
|= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4903 /* USER_ALL_USERCOMMENT */
4904 if (fields
& SAMR_FIELD_COMMENT
)
4905 acc_required
|= SAMR_USER_ACCESS_SET_LOC_COM
;
4906 /* USER_ALL_COUNTRYCODE */
4907 if (fields
& SAMR_FIELD_COUNTRY_CODE
)
4908 acc_required
|= SAMR_USER_ACCESS_SET_LOC_COM
;
4909 /* USER_ALL_CODEPAGE */
4910 if (fields
& SAMR_FIELD_CODE_PAGE
)
4911 acc_required
|= SAMR_USER_ACCESS_SET_LOC_COM
;
4912 /* USER_ALL_NTPASSWORDPRESENT */
4913 if (fields
& SAMR_FIELD_NT_PASSWORD_PRESENT
)
4914 acc_required
|= SAMR_USER_ACCESS_SET_PASSWORD
;
4915 /* USER_ALL_LMPASSWORDPRESENT */
4916 if (fields
& SAMR_FIELD_LM_PASSWORD_PRESENT
)
4917 acc_required
|= SAMR_USER_ACCESS_SET_PASSWORD
;
4918 /* USER_ALL_PASSWORDEXPIRED */
4919 if (fields
& SAMR_FIELD_EXPIRED_FLAG
)
4920 acc_required
|= SAMR_USER_ACCESS_SET_PASSWORD
;
4922 return acc_required
;
4925 /*******************************************************************
4927 ********************************************************************/
4929 NTSTATUS
_samr_SetUserInfo(struct pipes_struct
*p
,
4930 struct samr_SetUserInfo
*r
)
4932 struct samr_user_info
*uinfo
;
4934 struct samu
*pwd
= NULL
;
4935 union samr_UserInfo
*info
= r
->in
.info
;
4936 uint32_t acc_required
= 0;
4937 uint32_t fields
= 0;
4940 DATA_BLOB session_key
;
4942 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__
));
4944 /* This is tricky. A WinXP domain join sets
4945 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4946 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4947 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4948 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4949 we'll use the set from the WinXP join as the basis. */
4951 switch (r
->in
.level
) {
4952 case 2: /* UserPreferencesInformation */
4953 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
4954 acc_required
= SAMR_USER_ACCESS_SET_ATTRIBUTES
| SAMR_USER_ACCESS_SET_LOC_COM
;
4956 case 4: /* UserLogonHoursInformation */
4957 case 6: /* UserNameInformation */
4958 case 7: /* UserAccountNameInformation */
4959 case 8: /* UserFullNameInformation */
4960 case 9: /* UserPrimaryGroupInformation */
4961 case 10: /* UserHomeInformation */
4962 case 11: /* UserScriptInformation */
4963 case 12: /* UserProfileInformation */
4964 case 13: /* UserAdminCommentInformation */
4965 case 14: /* UserWorkStationsInformation */
4966 case 16: /* UserControlInformation */
4967 case 17: /* UserExpiresInformation */
4968 case 20: /* UserParametersInformation */
4969 /* USER_WRITE_ACCOUNT */
4970 acc_required
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
4972 case 18: /* UserInternal1Information */
4973 /* FIXME: gd, this is a guess */
4974 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
;
4976 case 21: /* UserAllInformation */
4977 fields
= info
->info21
.fields_present
;
4978 acc_required
= samr_set_user_info_map_fields_to_access_mask(fields
);
4980 case 23: /* UserInternal4Information */
4981 fields
= info
->info23
.info
.fields_present
;
4982 acc_required
= samr_set_user_info_map_fields_to_access_mask(fields
);
4984 case 25: /* UserInternal4InformationNew */
4985 fields
= info
->info25
.info
.fields_present
;
4986 acc_required
= samr_set_user_info_map_fields_to_access_mask(fields
);
4988 case 24: /* UserInternal5Information */
4989 case 26: /* UserInternal5InformationNew */
4990 acc_required
= SAMR_USER_ACCESS_SET_PASSWORD
;
4993 return NT_STATUS_INVALID_INFO_CLASS
;
4996 uinfo
= policy_handle_find(p
, r
->in
.user_handle
, acc_required
, NULL
,
4997 struct samr_user_info
, &status
);
4998 if (!NT_STATUS_IS_OK(status
)) {
5002 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5003 sid_string_dbg(&uinfo
->sid
), r
->in
.level
));
5006 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5007 return NT_STATUS_INVALID_INFO_CLASS
;
5010 if (!(pwd
= samu_new(NULL
))) {
5011 return NT_STATUS_NO_MEMORY
;
5015 ret
= pdb_getsampwsid(pwd
, &uinfo
->sid
);
5020 return NT_STATUS_NO_SUCH_USER
;
5023 rhost
= tsocket_address_inet_addr_string(p
->remote_address
,
5025 if (rhost
== NULL
) {
5026 return NT_STATUS_NO_MEMORY
;
5029 /* ================ BEGIN Privilege BLOCK ================ */
5033 /* ok! user info levels (lots: see MSDEV help), off we go... */
5035 switch (r
->in
.level
) {
5038 status
= set_user_info_2(p
->mem_ctx
,
5043 status
= set_user_info_4(p
->mem_ctx
,
5048 status
= set_user_info_6(p
->mem_ctx
,
5053 status
= set_user_info_7(p
->mem_ctx
,
5058 status
= set_user_info_8(p
->mem_ctx
,
5063 status
= set_user_info_10(p
->mem_ctx
,
5064 &info
->info10
, pwd
);
5068 status
= set_user_info_11(p
->mem_ctx
,
5069 &info
->info11
, pwd
);
5073 status
= set_user_info_12(p
->mem_ctx
,
5074 &info
->info12
, pwd
);
5078 status
= set_user_info_13(p
->mem_ctx
,
5079 &info
->info13
, pwd
);
5083 status
= set_user_info_14(p
->mem_ctx
,
5084 &info
->info14
, pwd
);
5088 status
= set_user_info_16(p
->mem_ctx
,
5089 &info
->info16
, pwd
);
5093 status
= set_user_info_17(p
->mem_ctx
,
5094 &info
->info17
, pwd
);
5098 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5099 if(!NT_STATUS_IS_OK(status
)) {
5102 /* Used by AS/U JRA. */
5103 status
= set_user_info_18(&info
->info18
,
5110 status
= set_user_info_20(p
->mem_ctx
,
5111 &info
->info20
, pwd
);
5115 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5116 if(!NT_STATUS_IS_OK(status
)) {
5119 status
= set_user_info_21(&info
->info21
,
5126 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5127 arcfour_crypt_blob(info
->info23
.password
.data
, 516,
5130 dump_data(100, info
->info23
.password
.data
, 516);
5132 status
= set_user_info_23(p
->mem_ctx
,
5139 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5140 arcfour_crypt_blob(info
->info24
.password
.data
,
5144 dump_data(100, info
->info24
.password
.data
, 516);
5146 status
= set_user_info_24(p
->mem_ctx
,
5148 &info
->info24
, pwd
);
5152 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5153 encode_or_decode_arc4_passwd_buffer(
5154 info
->info25
.password
.data
,
5157 dump_data(100, info
->info25
.password
.data
, 532);
5159 status
= set_user_info_25(p
->mem_ctx
,
5161 &info
->info25
, pwd
);
5165 status
= session_extract_session_key(p
->session_info
, &session_key
, KEY_USE_16BYTES
);
5166 encode_or_decode_arc4_passwd_buffer(
5167 info
->info26
.password
.data
,
5170 dump_data(100, info
->info26
.password
.data
, 516);
5172 status
= set_user_info_26(p
->mem_ctx
,
5174 &info
->info26
, pwd
);
5178 status
= NT_STATUS_INVALID_INFO_CLASS
;
5185 /* ================ END Privilege BLOCK ================ */
5187 if (NT_STATUS_IS_OK(status
)) {
5188 force_flush_samr_cache(&uinfo
->sid
);
5194 /*******************************************************************
5196 ********************************************************************/
5198 NTSTATUS
_samr_SetUserInfo2(struct pipes_struct
*p
,
5199 struct samr_SetUserInfo2
*r
)
5201 struct samr_SetUserInfo q
;
5203 q
.in
.user_handle
= r
->in
.user_handle
;
5204 q
.in
.level
= r
->in
.level
;
5205 q
.in
.info
= r
->in
.info
;
5207 return _samr_SetUserInfo(p
, &q
);
5210 /*********************************************************************
5211 _samr_GetAliasMembership
5212 *********************************************************************/
5214 NTSTATUS
_samr_GetAliasMembership(struct pipes_struct
*p
,
5215 struct samr_GetAliasMembership
*r
)
5217 size_t num_alias_rids
;
5219 struct samr_domain_info
*dinfo
;
5224 struct dom_sid
*members
;
5226 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__
));
5228 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
5229 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5230 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
5231 struct samr_domain_info
, &status
);
5232 if (!NT_STATUS_IS_OK(status
)) {
5236 if (!sid_check_is_our_sam(&dinfo
->sid
) &&
5237 !sid_check_is_builtin(&dinfo
->sid
))
5238 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
5240 if (r
->in
.sids
->num_sids
) {
5241 members
= talloc_array(p
->mem_ctx
, struct dom_sid
, r
->in
.sids
->num_sids
);
5243 if (members
== NULL
)
5244 return NT_STATUS_NO_MEMORY
;
5249 for (i
=0; i
<r
->in
.sids
->num_sids
; i
++)
5250 sid_copy(&members
[i
], r
->in
.sids
->sids
[i
].sid
);
5256 status
= pdb_enum_alias_memberships(p
->mem_ctx
, &dinfo
->sid
, members
,
5257 r
->in
.sids
->num_sids
,
5258 &alias_rids
, &num_alias_rids
);
5261 if (!NT_STATUS_IS_OK(status
)) {
5265 r
->out
.rids
->count
= num_alias_rids
;
5266 r
->out
.rids
->ids
= alias_rids
;
5268 if (r
->out
.rids
->ids
== NULL
) {
5269 /* Windows domain clients don't accept a NULL ptr here */
5270 r
->out
.rids
->ids
= talloc_zero(p
->mem_ctx
, uint32_t);
5272 if (r
->out
.rids
->ids
== NULL
) {
5273 return NT_STATUS_NO_MEMORY
;
5276 return NT_STATUS_OK
;
5279 /*********************************************************************
5280 _samr_GetMembersInAlias
5281 *********************************************************************/
5283 NTSTATUS
_samr_GetMembersInAlias(struct pipes_struct
*p
,
5284 struct samr_GetMembersInAlias
*r
)
5286 struct samr_alias_info
*ainfo
;
5289 size_t num_sids
= 0;
5290 struct lsa_SidPtr
*sids
= NULL
;
5291 struct dom_sid
*pdb_sids
= NULL
;
5293 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5294 SAMR_ALIAS_ACCESS_GET_MEMBERS
, NULL
,
5295 struct samr_alias_info
, &status
);
5296 if (!NT_STATUS_IS_OK(status
)) {
5300 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo
->sid
)));
5303 status
= pdb_enum_aliasmem(&ainfo
->sid
, talloc_tos(), &pdb_sids
,
5307 if (!NT_STATUS_IS_OK(status
)) {
5312 sids
= talloc_zero_array(p
->mem_ctx
, struct lsa_SidPtr
, num_sids
);
5314 TALLOC_FREE(pdb_sids
);
5315 return NT_STATUS_NO_MEMORY
;
5319 for (i
= 0; i
< num_sids
; i
++) {
5320 sids
[i
].sid
= dom_sid_dup(p
->mem_ctx
, &pdb_sids
[i
]);
5322 TALLOC_FREE(pdb_sids
);
5323 return NT_STATUS_NO_MEMORY
;
5327 r
->out
.sids
->num_sids
= num_sids
;
5328 r
->out
.sids
->sids
= sids
;
5330 TALLOC_FREE(pdb_sids
);
5332 return NT_STATUS_OK
;
5335 /*********************************************************************
5336 _samr_QueryGroupMember
5337 *********************************************************************/
5339 NTSTATUS
_samr_QueryGroupMember(struct pipes_struct
*p
,
5340 struct samr_QueryGroupMember
*r
)
5342 struct samr_group_info
*ginfo
;
5343 size_t i
, num_members
;
5349 struct samr_RidAttrArray
*rids
= NULL
;
5351 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5352 SAMR_GROUP_ACCESS_GET_MEMBERS
, NULL
,
5353 struct samr_group_info
, &status
);
5354 if (!NT_STATUS_IS_OK(status
)) {
5358 rids
= talloc_zero(p
->mem_ctx
, struct samr_RidAttrArray
);
5360 return NT_STATUS_NO_MEMORY
;
5363 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo
->sid
)));
5365 if (!sid_check_is_in_our_sam(&ginfo
->sid
)) {
5366 DEBUG(3, ("sid %s is not in our domain\n",
5367 sid_string_dbg(&ginfo
->sid
)));
5368 return NT_STATUS_NO_SUCH_GROUP
;
5371 DEBUG(10, ("lookup on Domain SID\n"));
5374 status
= pdb_enum_group_members(p
->mem_ctx
, &ginfo
->sid
,
5375 &rid
, &num_members
);
5378 if (!NT_STATUS_IS_OK(status
))
5382 attr
=talloc_zero_array(p
->mem_ctx
, uint32
, num_members
);
5384 return NT_STATUS_NO_MEMORY
;
5390 for (i
=0; i
<num_members
; i
++) {
5391 attr
[i
] = SE_GROUP_MANDATORY
|
5392 SE_GROUP_ENABLED_BY_DEFAULT
|
5396 rids
->count
= num_members
;
5397 rids
->attributes
= attr
;
5400 *r
->out
.rids
= rids
;
5402 return NT_STATUS_OK
;
5405 /*********************************************************************
5406 _samr_AddAliasMember
5407 *********************************************************************/
5409 NTSTATUS
_samr_AddAliasMember(struct pipes_struct
*p
,
5410 struct samr_AddAliasMember
*r
)
5412 struct samr_alias_info
*ainfo
;
5415 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5416 SAMR_ALIAS_ACCESS_ADD_MEMBER
, NULL
,
5417 struct samr_alias_info
, &status
);
5418 if (!NT_STATUS_IS_OK(status
)) {
5422 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo
->sid
)));
5424 /******** BEGIN SeAddUsers BLOCK *********/
5427 status
= pdb_add_aliasmem(&ainfo
->sid
, r
->in
.sid
);
5430 /******** END SeAddUsers BLOCK *********/
5432 if (NT_STATUS_IS_OK(status
)) {
5433 force_flush_samr_cache(&ainfo
->sid
);
5439 /*********************************************************************
5440 _samr_DeleteAliasMember
5441 *********************************************************************/
5443 NTSTATUS
_samr_DeleteAliasMember(struct pipes_struct
*p
,
5444 struct samr_DeleteAliasMember
*r
)
5446 struct samr_alias_info
*ainfo
;
5449 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5450 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
, NULL
,
5451 struct samr_alias_info
, &status
);
5452 if (!NT_STATUS_IS_OK(status
)) {
5456 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5457 sid_string_dbg(&ainfo
->sid
)));
5459 /******** BEGIN SeAddUsers BLOCK *********/
5462 status
= pdb_del_aliasmem(&ainfo
->sid
, r
->in
.sid
);
5465 /******** END SeAddUsers BLOCK *********/
5467 if (NT_STATUS_IS_OK(status
)) {
5468 force_flush_samr_cache(&ainfo
->sid
);
5474 /*********************************************************************
5475 _samr_AddGroupMember
5476 *********************************************************************/
5478 NTSTATUS
_samr_AddGroupMember(struct pipes_struct
*p
,
5479 struct samr_AddGroupMember
*r
)
5481 struct samr_group_info
*ginfo
;
5485 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5486 SAMR_GROUP_ACCESS_ADD_MEMBER
, NULL
,
5487 struct samr_group_info
, &status
);
5488 if (!NT_STATUS_IS_OK(status
)) {
5492 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo
->sid
)));
5494 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo
->sid
,
5496 return NT_STATUS_INVALID_HANDLE
;
5499 /******** BEGIN SeAddUsers BLOCK *********/
5502 status
= pdb_add_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5505 /******** END SeAddUsers BLOCK *********/
5507 force_flush_samr_cache(&ginfo
->sid
);
5512 /*********************************************************************
5513 _samr_DeleteGroupMember
5514 *********************************************************************/
5516 NTSTATUS
_samr_DeleteGroupMember(struct pipes_struct
*p
,
5517 struct samr_DeleteGroupMember
*r
)
5520 struct samr_group_info
*ginfo
;
5525 * delete the group member named r->in.rid
5526 * who is a member of the sid associated with the handle
5527 * the rid is a user's rid as the group is a domain group.
5530 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5531 SAMR_GROUP_ACCESS_REMOVE_MEMBER
, NULL
,
5532 struct samr_group_info
, &status
);
5533 if (!NT_STATUS_IS_OK(status
)) {
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_del_groupmem(p
->mem_ctx
, group_rid
, r
->in
.rid
);
5548 /******** END SeAddUsers BLOCK *********/
5550 force_flush_samr_cache(&ginfo
->sid
);
5555 /*********************************************************************
5557 *********************************************************************/
5559 NTSTATUS
_samr_DeleteUser(struct pipes_struct
*p
,
5560 struct samr_DeleteUser
*r
)
5562 struct samr_user_info
*uinfo
;
5564 struct samu
*sam_pass
=NULL
;
5567 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__
));
5569 uinfo
= policy_handle_find(p
, r
->in
.user_handle
,
5570 SEC_STD_DELETE
, NULL
,
5571 struct samr_user_info
, &status
);
5572 if (!NT_STATUS_IS_OK(status
)) {
5576 if (!sid_check_is_in_our_sam(&uinfo
->sid
))
5577 return NT_STATUS_CANNOT_DELETE
;
5579 /* check if the user exists before trying to delete */
5580 if ( !(sam_pass
= samu_new( NULL
)) ) {
5581 return NT_STATUS_NO_MEMORY
;
5585 ret
= pdb_getsampwsid(sam_pass
, &uinfo
->sid
);
5589 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5590 sid_string_dbg(&uinfo
->sid
)));
5591 TALLOC_FREE(sam_pass
);
5592 return NT_STATUS_NO_SUCH_USER
;
5595 /******** BEGIN SeAddUsers BLOCK *********/
5598 status
= pdb_delete_user(p
->mem_ctx
, sam_pass
);
5601 /******** END SeAddUsers BLOCK *********/
5603 if ( !NT_STATUS_IS_OK(status
) ) {
5604 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5605 "user %s: %s.\n", pdb_get_username(sam_pass
),
5606 nt_errstr(status
)));
5607 TALLOC_FREE(sam_pass
);
5612 TALLOC_FREE(sam_pass
);
5614 force_flush_samr_cache(&uinfo
->sid
);
5616 if (!close_policy_hnd(p
, r
->in
.user_handle
))
5617 return NT_STATUS_OBJECT_NAME_INVALID
;
5619 ZERO_STRUCTP(r
->out
.user_handle
);
5621 return NT_STATUS_OK
;
5624 /*********************************************************************
5625 _samr_DeleteDomainGroup
5626 *********************************************************************/
5628 NTSTATUS
_samr_DeleteDomainGroup(struct pipes_struct
*p
,
5629 struct samr_DeleteDomainGroup
*r
)
5631 struct samr_group_info
*ginfo
;
5635 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__
));
5637 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5638 SEC_STD_DELETE
, NULL
,
5639 struct samr_group_info
, &status
);
5640 if (!NT_STATUS_IS_OK(status
)) {
5644 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo
->sid
)));
5646 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo
->sid
,
5648 return NT_STATUS_NO_SUCH_GROUP
;
5651 /******** BEGIN SeAddUsers BLOCK *********/
5654 status
= pdb_delete_dom_group(p
->mem_ctx
, group_rid
);
5657 /******** END SeAddUsers BLOCK *********/
5659 if ( !NT_STATUS_IS_OK(status
) ) {
5660 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5661 "entry for group %s: %s\n",
5662 sid_string_dbg(&ginfo
->sid
),
5663 nt_errstr(status
)));
5667 force_flush_samr_cache(&ginfo
->sid
);
5669 if (!close_policy_hnd(p
, r
->in
.group_handle
))
5670 return NT_STATUS_OBJECT_NAME_INVALID
;
5672 return NT_STATUS_OK
;
5675 /*********************************************************************
5676 _samr_DeleteDomAlias
5677 *********************************************************************/
5679 NTSTATUS
_samr_DeleteDomAlias(struct pipes_struct
*p
,
5680 struct samr_DeleteDomAlias
*r
)
5682 struct samr_alias_info
*ainfo
;
5685 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__
));
5687 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
5688 SEC_STD_DELETE
, NULL
,
5689 struct samr_alias_info
, &status
);
5690 if (!NT_STATUS_IS_OK(status
)) {
5694 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo
->sid
)));
5696 /* Don't let Windows delete builtin groups */
5698 if ( sid_check_is_in_builtin( &ainfo
->sid
) ) {
5699 return NT_STATUS_SPECIAL_ACCOUNT
;
5702 if (!sid_check_is_in_our_sam(&ainfo
->sid
))
5703 return NT_STATUS_NO_SUCH_ALIAS
;
5705 DEBUG(10, ("lookup on Local SID\n"));
5707 /******** BEGIN SeAddUsers BLOCK *********/
5710 /* Have passdb delete the alias */
5711 status
= pdb_delete_alias(&ainfo
->sid
);
5714 /******** END SeAddUsers BLOCK *********/
5716 if ( !NT_STATUS_IS_OK(status
))
5719 force_flush_samr_cache(&ainfo
->sid
);
5721 if (!close_policy_hnd(p
, r
->in
.alias_handle
))
5722 return NT_STATUS_OBJECT_NAME_INVALID
;
5724 return NT_STATUS_OK
;
5727 /*********************************************************************
5728 _samr_CreateDomainGroup
5729 *********************************************************************/
5731 NTSTATUS
_samr_CreateDomainGroup(struct pipes_struct
*p
,
5732 struct samr_CreateDomainGroup
*r
)
5737 struct samr_domain_info
*dinfo
;
5738 struct samr_group_info
*ginfo
;
5740 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
5741 SAMR_DOMAIN_ACCESS_CREATE_GROUP
, NULL
,
5742 struct samr_domain_info
, &status
);
5743 if (!NT_STATUS_IS_OK(status
)) {
5747 if (!sid_check_is_our_sam(&dinfo
->sid
)) {
5748 return NT_STATUS_ACCESS_DENIED
;
5751 name
= r
->in
.name
->string
;
5753 return NT_STATUS_NO_MEMORY
;
5756 status
= can_create(p
->mem_ctx
, name
);
5757 if (!NT_STATUS_IS_OK(status
)) {
5761 /******** BEGIN SeAddUsers BLOCK *********/
5764 /* check that we successfully create the UNIX group */
5765 status
= pdb_create_dom_group(p
->mem_ctx
, name
, r
->out
.rid
);
5768 /******** END SeAddUsers BLOCK *********/
5770 /* check if we should bail out here */
5772 if ( !NT_STATUS_IS_OK(status
) )
5775 ginfo
= policy_handle_create(p
, r
->out
.group_handle
,
5776 GENERIC_RIGHTS_GROUP_ALL_ACCESS
,
5777 struct samr_group_info
, &status
);
5778 if (!NT_STATUS_IS_OK(status
)) {
5781 sid_compose(&ginfo
->sid
, &dinfo
->sid
, *r
->out
.rid
);
5783 force_flush_samr_cache(&dinfo
->sid
);
5785 return NT_STATUS_OK
;
5788 /*********************************************************************
5789 _samr_CreateDomAlias
5790 *********************************************************************/
5792 NTSTATUS
_samr_CreateDomAlias(struct pipes_struct
*p
,
5793 struct samr_CreateDomAlias
*r
)
5795 struct dom_sid info_sid
;
5796 const char *name
= NULL
;
5797 struct samr_domain_info
*dinfo
;
5798 struct samr_alias_info
*ainfo
;
5802 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
5803 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
, NULL
,
5804 struct samr_domain_info
, &result
);
5805 if (!NT_STATUS_IS_OK(result
)) {
5809 if (!sid_check_is_our_sam(&dinfo
->sid
)) {
5810 return NT_STATUS_ACCESS_DENIED
;
5813 name
= r
->in
.alias_name
->string
;
5815 result
= can_create(p
->mem_ctx
, name
);
5816 if (!NT_STATUS_IS_OK(result
)) {
5820 /******** BEGIN SeAddUsers BLOCK *********/
5823 /* Have passdb create the alias */
5824 result
= pdb_create_alias(name
, r
->out
.rid
);
5827 /******** END SeAddUsers BLOCK *********/
5829 if (!NT_STATUS_IS_OK(result
)) {
5830 DEBUG(10, ("pdb_create_alias failed: %s\n",
5831 nt_errstr(result
)));
5835 sid_compose(&info_sid
, &dinfo
->sid
, *r
->out
.rid
);
5837 if (!sid_to_gid(&info_sid
, &gid
)) {
5838 DEBUG(10, ("Could not find alias just created\n"));
5839 return NT_STATUS_ACCESS_DENIED
;
5842 /* check if the group has been successfully created */
5843 if ( getgrgid(gid
) == NULL
) {
5844 DEBUG(1, ("getgrgid(%u) of just created alias failed\n",
5845 (unsigned int)gid
));
5846 return NT_STATUS_ACCESS_DENIED
;
5849 ainfo
= policy_handle_create(p
, r
->out
.alias_handle
,
5850 GENERIC_RIGHTS_ALIAS_ALL_ACCESS
,
5851 struct samr_alias_info
, &result
);
5852 if (!NT_STATUS_IS_OK(result
)) {
5855 ainfo
->sid
= info_sid
;
5857 force_flush_samr_cache(&info_sid
);
5859 return NT_STATUS_OK
;
5862 /*********************************************************************
5863 _samr_QueryGroupInfo
5864 *********************************************************************/
5866 NTSTATUS
_samr_QueryGroupInfo(struct pipes_struct
*p
,
5867 struct samr_QueryGroupInfo
*r
)
5869 struct samr_group_info
*ginfo
;
5872 union samr_GroupInfo
*info
= NULL
;
5874 uint32_t attributes
= SE_GROUP_MANDATORY
|
5875 SE_GROUP_ENABLED_BY_DEFAULT
|
5877 const char *group_name
= NULL
;
5878 const char *group_description
= NULL
;
5880 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5881 SAMR_GROUP_ACCESS_LOOKUP_INFO
, NULL
,
5882 struct samr_group_info
, &status
);
5883 if (!NT_STATUS_IS_OK(status
)) {
5887 map
= talloc_zero(p
->mem_ctx
, GROUP_MAP
);
5889 return NT_STATUS_NO_MEMORY
;
5893 ret
= get_domain_group_from_sid(ginfo
->sid
, map
);
5896 return NT_STATUS_INVALID_HANDLE
;
5898 group_name
= talloc_move(r
, &map
->nt_name
);
5899 group_description
= talloc_move(r
, &map
->comment
);
5903 info
= talloc_zero(p
->mem_ctx
, union samr_GroupInfo
);
5905 return NT_STATUS_NO_MEMORY
;
5908 switch (r
->in
.level
) {
5914 status
= pdb_enum_group_members(
5915 p
->mem_ctx
, &ginfo
->sid
, &members
,
5919 if (!NT_STATUS_IS_OK(status
)) {
5923 info
->all
.name
.string
= group_name
;
5924 info
->all
.attributes
= attributes
;
5925 info
->all
.num_members
= num_members
;
5926 info
->all
.description
.string
= group_description
;
5930 info
->name
.string
= group_name
;
5933 info
->attributes
.attributes
= attributes
;
5936 info
->description
.string
= group_description
;
5946 status = pdb_enum_group_members(
5947 p->mem_ctx, &ginfo->sid, &members,
5951 if (!NT_STATUS_IS_OK(status)) {
5955 info
->all2
.name
.string
= group_name
;
5956 info
->all2
.attributes
= attributes
;
5957 info
->all2
.num_members
= 0; /* num_members - in w2k3 this is always 0 */
5958 info
->all2
.description
.string
= group_description
;
5963 return NT_STATUS_INVALID_INFO_CLASS
;
5966 *r
->out
.info
= info
;
5968 return NT_STATUS_OK
;
5971 /*********************************************************************
5973 *********************************************************************/
5975 NTSTATUS
_samr_SetGroupInfo(struct pipes_struct
*p
,
5976 struct samr_SetGroupInfo
*r
)
5978 struct samr_group_info
*ginfo
;
5983 ginfo
= policy_handle_find(p
, r
->in
.group_handle
,
5984 SAMR_GROUP_ACCESS_SET_INFO
, NULL
,
5985 struct samr_group_info
, &status
);
5986 if (!NT_STATUS_IS_OK(status
)) {
5990 map
= talloc_zero(p
->mem_ctx
, GROUP_MAP
);
5992 return NT_STATUS_NO_MEMORY
;
5996 ret
= get_domain_group_from_sid(ginfo
->sid
, map
);
5999 return NT_STATUS_NO_SUCH_GROUP
;
6001 switch (r
->in
.level
) {
6003 map
->nt_name
= talloc_strdup(map
,
6004 r
->in
.info
->name
.string
);
6005 if (!map
->nt_name
) {
6006 return NT_STATUS_NO_MEMORY
;
6012 map
->comment
= talloc_strdup(map
,
6013 r
->in
.info
->description
.string
);
6014 if (!map
->comment
) {
6015 return NT_STATUS_NO_MEMORY
;
6019 return NT_STATUS_INVALID_INFO_CLASS
;
6022 /******** BEGIN SeAddUsers BLOCK *********/
6025 status
= pdb_update_group_mapping_entry(map
);
6028 /******** End SeAddUsers BLOCK *********/
6032 if (NT_STATUS_IS_OK(status
)) {
6033 force_flush_samr_cache(&ginfo
->sid
);
6039 /*********************************************************************
6041 *********************************************************************/
6043 NTSTATUS
_samr_SetAliasInfo(struct pipes_struct
*p
,
6044 struct samr_SetAliasInfo
*r
)
6046 struct samr_alias_info
*ainfo
;
6047 struct acct_info
*info
;
6050 ainfo
= policy_handle_find(p
, r
->in
.alias_handle
,
6051 SAMR_ALIAS_ACCESS_SET_INFO
, NULL
,
6052 struct samr_alias_info
, &status
);
6053 if (!NT_STATUS_IS_OK(status
)) {
6057 info
= talloc_zero(p
->mem_ctx
, struct acct_info
);
6059 return NT_STATUS_NO_MEMORY
;
6062 /* get the current group information */
6065 status
= pdb_get_aliasinfo(&ainfo
->sid
, info
);
6068 if ( !NT_STATUS_IS_OK(status
))
6071 switch (r
->in
.level
) {
6076 /* We currently do not support renaming groups in the
6077 the BUILTIN domain. Refer to util_builtin.c to understand
6078 why. The eventually needs to be fixed to be like Windows
6079 where you can rename builtin groups, just not delete them */
6081 if ( sid_check_is_in_builtin( &ainfo
->sid
) ) {
6082 return NT_STATUS_SPECIAL_ACCOUNT
;
6085 /* There has to be a valid name (and it has to be different) */
6087 if ( !r
->in
.info
->name
.string
)
6088 return NT_STATUS_INVALID_PARAMETER
;
6090 /* If the name is the same just reply "ok". Yes this
6091 doesn't allow you to change the case of a group name. */
6093 if (strequal(r
->in
.info
->name
.string
, info
->acct_name
)) {
6094 return NT_STATUS_OK
;
6097 talloc_free(info
->acct_name
);
6098 info
->acct_name
= talloc_strdup(info
, r
->in
.info
->name
.string
);
6099 if (!info
->acct_name
) {
6100 return NT_STATUS_NO_MEMORY
;
6103 /* make sure the name doesn't already exist as a user
6106 group_name
= talloc_asprintf(p
->mem_ctx
,
6110 if (group_name
== NULL
) {
6111 return NT_STATUS_NO_MEMORY
;
6114 status
= can_create( p
->mem_ctx
, group_name
);
6115 talloc_free(group_name
);
6116 if ( !NT_STATUS_IS_OK( status
) )
6120 case ALIASINFODESCRIPTION
:
6121 TALLOC_FREE(info
->acct_desc
);
6122 if (r
->in
.info
->description
.string
) {
6123 info
->acct_desc
= talloc_strdup(info
,
6124 r
->in
.info
->description
.string
);
6126 info
->acct_desc
= talloc_strdup(info
, "");
6128 if (!info
->acct_desc
) {
6129 return NT_STATUS_NO_MEMORY
;
6133 return NT_STATUS_INVALID_INFO_CLASS
;
6136 /******** BEGIN SeAddUsers BLOCK *********/
6139 status
= pdb_set_aliasinfo(&ainfo
->sid
, info
);
6142 /******** End SeAddUsers BLOCK *********/
6144 if (NT_STATUS_IS_OK(status
))
6145 force_flush_samr_cache(&ainfo
->sid
);
6150 /****************************************************************
6152 ****************************************************************/
6154 NTSTATUS
_samr_GetDomPwInfo(struct pipes_struct
*p
,
6155 struct samr_GetDomPwInfo
*r
)
6157 uint32_t min_password_length
= 0;
6158 uint32_t password_properties
= 0;
6160 /* Perform access check. Since this rpc does not require a
6161 policy handle it will not be caught by the access checks on
6162 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6164 if (!pipe_access_check(p
)) {
6165 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6166 return NT_STATUS_ACCESS_DENIED
;
6170 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN
,
6171 &min_password_length
);
6172 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS
,
6173 &password_properties
);
6176 if (lp_check_password_script(talloc_tos()) && *lp_check_password_script(talloc_tos())) {
6177 password_properties
|= DOMAIN_PASSWORD_COMPLEX
;
6180 r
->out
.info
->min_password_length
= min_password_length
;
6181 r
->out
.info
->password_properties
= password_properties
;
6183 return NT_STATUS_OK
;
6186 /*********************************************************************
6188 *********************************************************************/
6190 NTSTATUS
_samr_OpenGroup(struct pipes_struct
*p
,
6191 struct samr_OpenGroup
*r
)
6194 struct dom_sid info_sid
;
6196 struct samr_domain_info
*dinfo
;
6197 struct samr_group_info
*ginfo
;
6198 struct security_descriptor
*psd
= NULL
;
6200 uint32 des_access
= r
->in
.access_mask
;
6205 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6206 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
6207 struct samr_domain_info
, &status
);
6208 if (!NT_STATUS_IS_OK(status
)) {
6212 /*check if access can be granted as requested by client. */
6213 map_max_allowed_access(p
->session_info
->security_token
,
6214 p
->session_info
->unix_token
,
6217 make_samr_object_sd(p
->mem_ctx
, &psd
, &sd_size
, &grp_generic_mapping
, NULL
, 0);
6218 se_map_generic(&des_access
,&grp_generic_mapping
);
6220 status
= access_check_object(psd
, p
->session_info
->security_token
,
6221 SEC_PRIV_ADD_USERS
, SEC_PRIV_INVALID
, GENERIC_RIGHTS_GROUP_ALL_ACCESS
,
6222 des_access
, &acc_granted
, "_samr_OpenGroup");
6224 if ( !NT_STATUS_IS_OK(status
) )
6227 /* this should not be hard-coded like this */
6229 if (!sid_check_is_our_sam(&dinfo
->sid
)) {
6230 return NT_STATUS_ACCESS_DENIED
;
6233 sid_compose(&info_sid
, &dinfo
->sid
, r
->in
.rid
);
6235 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6236 sid_string_dbg(&info_sid
)));
6238 map
= talloc_zero(p
->mem_ctx
, GROUP_MAP
);
6240 return NT_STATUS_NO_MEMORY
;
6243 /* check if that group really exists */
6245 ret
= get_domain_group_from_sid(info_sid
, map
);
6248 return NT_STATUS_NO_SUCH_GROUP
;
6252 ginfo
= policy_handle_create(p
, r
->out
.group_handle
,
6254 struct samr_group_info
, &status
);
6255 if (!NT_STATUS_IS_OK(status
)) {
6258 ginfo
->sid
= info_sid
;
6260 return NT_STATUS_OK
;
6263 /*********************************************************************
6264 _samr_RemoveMemberFromForeignDomain
6265 *********************************************************************/
6267 NTSTATUS
_samr_RemoveMemberFromForeignDomain(struct pipes_struct
*p
,
6268 struct samr_RemoveMemberFromForeignDomain
*r
)
6270 struct samr_domain_info
*dinfo
;
6273 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6274 sid_string_dbg(r
->in
.sid
)));
6276 /* Find the policy handle. Open a policy on it. */
6278 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6279 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
, NULL
,
6280 struct samr_domain_info
, &result
);
6281 if (!NT_STATUS_IS_OK(result
)) {
6285 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6286 sid_string_dbg(&dinfo
->sid
)));
6288 /* we can only delete a user from a group since we don't have
6289 nested groups anyways. So in the latter case, just say OK */
6291 /* TODO: The above comment nowadays is bogus. Since we have nested
6292 * groups now, and aliases members are never reported out of the unix
6293 * group membership, the "just say OK" makes this call a no-op. For
6294 * us. This needs fixing however. */
6296 /* I've only ever seen this in the wild when deleting a user from
6297 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6298 * is the user about to be deleted. I very much suspect this is the
6299 * only application of this call. To verify this, let people report
6302 if (!sid_check_is_builtin(&dinfo
->sid
)) {
6303 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6304 "global_sam_sid() = %s\n",
6305 sid_string_dbg(&dinfo
->sid
),
6306 sid_string_dbg(get_global_sam_sid())));
6307 DEBUGADD(1,("please report to samba-technical@lists.samba.org!\n"));
6308 return NT_STATUS_OK
;
6311 force_flush_samr_cache(&dinfo
->sid
);
6313 result
= NT_STATUS_OK
;
6318 /*******************************************************************
6319 _samr_QueryDomainInfo2
6320 ********************************************************************/
6322 NTSTATUS
_samr_QueryDomainInfo2(struct pipes_struct
*p
,
6323 struct samr_QueryDomainInfo2
*r
)
6325 struct samr_QueryDomainInfo q
;
6327 q
.in
.domain_handle
= r
->in
.domain_handle
;
6328 q
.in
.level
= r
->in
.level
;
6330 q
.out
.info
= r
->out
.info
;
6332 return _samr_QueryDomainInfo(p
, &q
);
6335 /*******************************************************************
6336 ********************************************************************/
6338 static NTSTATUS
set_dom_info_1(TALLOC_CTX
*mem_ctx
,
6339 struct samr_DomInfo1
*r
)
6341 time_t u_expire
, u_min_age
;
6343 u_expire
= nt_time_to_unix_abs((NTTIME
*)&r
->max_password_age
);
6344 u_min_age
= nt_time_to_unix_abs((NTTIME
*)&r
->min_password_age
);
6346 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN
,
6347 (uint32_t)r
->min_password_length
);
6348 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY
,
6349 (uint32_t)r
->password_history_length
);
6350 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS
,
6351 (uint32_t)r
->password_properties
);
6352 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE
, (int)u_expire
);
6353 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE
, (int)u_min_age
);
6355 return NT_STATUS_OK
;
6358 /*******************************************************************
6359 ********************************************************************/
6361 static NTSTATUS
set_dom_info_3(TALLOC_CTX
*mem_ctx
,
6362 struct samr_DomInfo3
*r
)
6366 u_logout
= nt_time_to_unix_abs((NTTIME
*)&r
->force_logoff_time
);
6368 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT
, (int)u_logout
);
6370 return NT_STATUS_OK
;
6373 /*******************************************************************
6374 ********************************************************************/
6376 static NTSTATUS
set_dom_info_12(TALLOC_CTX
*mem_ctx
,
6377 struct samr_DomInfo12
*r
)
6379 time_t u_lock_duration
, u_reset_time
;
6382 * It is not possible to set lockout_duration < lockout_window.
6383 * (The test is the other way around since the negative numbers
6386 * This constraint is documented here for the samr rpc service:
6387 * MS-SAMR 3.1.1.6 Attribute Constraints for Originating Updates
6388 * http://msdn.microsoft.com/en-us/library/cc245667%28PROT.10%29.aspx
6390 * And here for the ldap backend:
6391 * MS-ADTS 3.1.1.5.3.2 Constraints
6392 * http://msdn.microsoft.com/en-us/library/cc223462(PROT.10).aspx
6394 if (r
->lockout_duration
> r
->lockout_window
) {
6395 return NT_STATUS_INVALID_PARAMETER
;
6398 u_lock_duration
= nt_time_to_unix_abs((NTTIME
*)&r
->lockout_duration
);
6399 if (u_lock_duration
!= -1) {
6400 u_lock_duration
/= 60;
6403 u_reset_time
= nt_time_to_unix_abs((NTTIME
*)&r
->lockout_window
)/60;
6405 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, (int)u_lock_duration
);
6406 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME
, (int)u_reset_time
);
6407 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
,
6408 (uint32_t)r
->lockout_threshold
);
6410 return NT_STATUS_OK
;
6413 /*******************************************************************
6415 ********************************************************************/
6417 NTSTATUS
_samr_SetDomainInfo(struct pipes_struct
*p
,
6418 struct samr_SetDomainInfo
*r
)
6421 uint32_t acc_required
= 0;
6423 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6425 switch (r
->in
.level
) {
6426 case 1: /* DomainPasswordInformation */
6427 case 12: /* DomainLockoutInformation */
6428 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6429 acc_required
= SAMR_DOMAIN_ACCESS_SET_INFO_1
;
6431 case 3: /* DomainLogoffInformation */
6432 case 4: /* DomainOemInformation */
6433 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6434 acc_required
= SAMR_DOMAIN_ACCESS_SET_INFO_2
;
6436 case 6: /* DomainReplicationInformation */
6437 case 9: /* DomainStateInformation */
6438 case 7: /* DomainServerRoleInformation */
6439 /* DOMAIN_ADMINISTER_SERVER */
6440 acc_required
= SAMR_DOMAIN_ACCESS_SET_INFO_3
;
6443 return NT_STATUS_INVALID_INFO_CLASS
;
6446 (void)policy_handle_find(p
, r
->in
.domain_handle
,
6448 struct samr_domain_info
, &status
);
6449 if (!NT_STATUS_IS_OK(status
)) {
6453 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r
->in
.level
));
6455 switch (r
->in
.level
) {
6457 status
= set_dom_info_1(p
->mem_ctx
, &r
->in
.info
->info1
);
6460 status
= set_dom_info_3(p
->mem_ctx
, &r
->in
.info
->info3
);
6471 status
= set_dom_info_12(p
->mem_ctx
, &r
->in
.info
->info12
);
6474 return NT_STATUS_INVALID_INFO_CLASS
;
6477 if (!NT_STATUS_IS_OK(status
)) {
6481 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__
));
6483 return NT_STATUS_OK
;
6486 /****************************************************************
6487 _samr_GetDisplayEnumerationIndex
6488 ****************************************************************/
6490 NTSTATUS
_samr_GetDisplayEnumerationIndex(struct pipes_struct
*p
,
6491 struct samr_GetDisplayEnumerationIndex
*r
)
6493 struct samr_domain_info
*dinfo
;
6494 uint32_t max_entries
= (uint32_t) -1;
6495 uint32_t enum_context
= 0;
6497 uint32_t num_account
= 0;
6498 struct samr_displayentry
*entries
= NULL
;
6501 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__
));
6503 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6504 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
, NULL
,
6505 struct samr_domain_info
, &status
);
6506 if (!NT_STATUS_IS_OK(status
)) {
6510 if ((r
->in
.level
< 1) || (r
->in
.level
> 3)) {
6511 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6512 "Unknown info level (%u)\n",
6514 return NT_STATUS_INVALID_INFO_CLASS
;
6519 /* The following done as ROOT. Don't return without unbecome_root(). */
6521 switch (r
->in
.level
) {
6523 if (dinfo
->disp_info
->users
== NULL
) {
6524 dinfo
->disp_info
->users
= pdb_search_users(
6525 dinfo
->disp_info
, ACB_NORMAL
);
6526 if (dinfo
->disp_info
->users
== NULL
) {
6528 return NT_STATUS_ACCESS_DENIED
;
6530 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6531 "starting user enumeration at index %u\n",
6532 (unsigned int)enum_context
));
6534 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6535 "using cached user enumeration at index %u\n",
6536 (unsigned int)enum_context
));
6538 num_account
= pdb_search_entries(dinfo
->disp_info
->users
,
6539 enum_context
, max_entries
,
6543 if (dinfo
->disp_info
->machines
== NULL
) {
6544 dinfo
->disp_info
->machines
= pdb_search_users(
6545 dinfo
->disp_info
, ACB_WSTRUST
|ACB_SVRTRUST
);
6546 if (dinfo
->disp_info
->machines
== NULL
) {
6548 return NT_STATUS_ACCESS_DENIED
;
6550 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6551 "starting machine enumeration at index %u\n",
6552 (unsigned int)enum_context
));
6554 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6555 "using cached machine enumeration at index %u\n",
6556 (unsigned int)enum_context
));
6558 num_account
= pdb_search_entries(dinfo
->disp_info
->machines
,
6559 enum_context
, max_entries
,
6563 if (dinfo
->disp_info
->groups
== NULL
) {
6564 dinfo
->disp_info
->groups
= pdb_search_groups(
6566 if (dinfo
->disp_info
->groups
== NULL
) {
6568 return NT_STATUS_ACCESS_DENIED
;
6570 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6571 "starting group enumeration at index %u\n",
6572 (unsigned int)enum_context
));
6574 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6575 "using cached group enumeration at index %u\n",
6576 (unsigned int)enum_context
));
6578 num_account
= pdb_search_entries(dinfo
->disp_info
->groups
,
6579 enum_context
, max_entries
,
6584 smb_panic("info class changed");
6590 /* Ensure we cache this enumeration. */
6591 set_disp_info_cache_timeout(dinfo
->disp_info
, DISP_INFO_CACHE_TIMEOUT
);
6593 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6594 r
->in
.name
->string
));
6596 for (i
=0; i
<num_account
; i
++) {
6597 if (strequal(entries
[i
].account_name
, r
->in
.name
->string
)) {
6598 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6599 "found %s at idx %d\n",
6600 r
->in
.name
->string
, i
));
6602 return NT_STATUS_OK
;
6606 /* assuming account_name lives at the very end */
6607 *r
->out
.idx
= num_account
;
6609 return NT_STATUS_NO_MORE_ENTRIES
;
6612 /****************************************************************
6613 _samr_GetDisplayEnumerationIndex2
6614 ****************************************************************/
6616 NTSTATUS
_samr_GetDisplayEnumerationIndex2(struct pipes_struct
*p
,
6617 struct samr_GetDisplayEnumerationIndex2
*r
)
6619 struct samr_GetDisplayEnumerationIndex q
;
6621 q
.in
.domain_handle
= r
->in
.domain_handle
;
6622 q
.in
.level
= r
->in
.level
;
6623 q
.in
.name
= r
->in
.name
;
6625 q
.out
.idx
= r
->out
.idx
;
6627 return _samr_GetDisplayEnumerationIndex(p
, &q
);
6630 /****************************************************************
6632 ****************************************************************/
6634 NTSTATUS
_samr_RidToSid(struct pipes_struct
*p
,
6635 struct samr_RidToSid
*r
)
6637 struct samr_domain_info
*dinfo
;
6641 dinfo
= policy_handle_find(p
, r
->in
.domain_handle
,
6643 struct samr_domain_info
, &status
);
6644 if (!NT_STATUS_IS_OK(status
)) {
6648 if (!sid_compose(&sid
, &dinfo
->sid
, r
->in
.rid
)) {
6649 return NT_STATUS_NO_MEMORY
;
6652 *r
->out
.sid
= dom_sid_dup(p
->mem_ctx
, &sid
);
6654 return NT_STATUS_NO_MEMORY
;
6657 return NT_STATUS_OK
;
6660 /****************************************************************
6661 ****************************************************************/
6663 static enum samr_ValidationStatus
samr_ValidatePassword_Change(TALLOC_CTX
*mem_ctx
,
6664 const struct samr_PwInfo
*dom_pw_info
,
6665 const struct samr_ValidatePasswordReq2
*req
,
6666 struct samr_ValidatePasswordRepCtr
*rep
)
6670 if (req
->password
.string
== NULL
) {
6671 return SAMR_VALIDATION_STATUS_SUCCESS
;
6673 if (strlen(req
->password
.string
) < dom_pw_info
->min_password_length
) {
6674 ZERO_STRUCT(rep
->info
);
6675 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT
;
6677 if (dom_pw_info
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
6678 status
= check_password_complexity(req
->account
.string
,
6679 req
->password
.string
,
6681 if (!NT_STATUS_IS_OK(status
)) {
6682 ZERO_STRUCT(rep
->info
);
6683 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH
;
6687 return SAMR_VALIDATION_STATUS_SUCCESS
;
6690 /****************************************************************
6691 ****************************************************************/
6693 static enum samr_ValidationStatus
samr_ValidatePassword_Reset(TALLOC_CTX
*mem_ctx
,
6694 const struct samr_PwInfo
*dom_pw_info
,
6695 const struct samr_ValidatePasswordReq3
*req
,
6696 struct samr_ValidatePasswordRepCtr
*rep
)
6700 if (req
->password
.string
== NULL
) {
6701 return SAMR_VALIDATION_STATUS_SUCCESS
;
6703 if (strlen(req
->password
.string
) < dom_pw_info
->min_password_length
) {
6704 ZERO_STRUCT(rep
->info
);
6705 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT
;
6707 if (dom_pw_info
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
6708 status
= check_password_complexity(req
->account
.string
,
6709 req
->password
.string
,
6711 if (!NT_STATUS_IS_OK(status
)) {
6712 ZERO_STRUCT(rep
->info
);
6713 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH
;
6717 return SAMR_VALIDATION_STATUS_SUCCESS
;
6720 /****************************************************************
6721 _samr_ValidatePassword
6722 ****************************************************************/
6724 NTSTATUS
_samr_ValidatePassword(struct pipes_struct
*p
,
6725 struct samr_ValidatePassword
*r
)
6727 union samr_ValidatePasswordRep
*rep
;
6729 struct samr_GetDomPwInfo pw
;
6730 struct samr_PwInfo dom_pw_info
;
6732 if (p
->transport
!= NCACN_IP_TCP
&& p
->transport
!= NCALRPC
) {
6733 p
->fault_state
= DCERPC_FAULT_ACCESS_DENIED
;
6734 return NT_STATUS_ACCESS_DENIED
;
6737 if (r
->in
.level
< 1 || r
->in
.level
> 3) {
6738 return NT_STATUS_INVALID_INFO_CLASS
;
6741 pw
.in
.domain_name
= NULL
;
6742 pw
.out
.info
= &dom_pw_info
;
6744 status
= _samr_GetDomPwInfo(p
, &pw
);
6745 if (!NT_STATUS_IS_OK(status
)) {
6749 rep
= talloc_zero(p
->mem_ctx
, union samr_ValidatePasswordRep
);
6751 return NT_STATUS_NO_MEMORY
;
6754 switch (r
->in
.level
) {
6756 status
= NT_STATUS_NOT_SUPPORTED
;
6759 rep
->ctr2
.status
= samr_ValidatePassword_Change(p
->mem_ctx
,
6765 rep
->ctr3
.status
= samr_ValidatePassword_Reset(p
->mem_ctx
,
6771 status
= NT_STATUS_INVALID_INFO_CLASS
;
6775 if (!NT_STATUS_IS_OK(status
)) {
6782 return NT_STATUS_OK
;
6785 /****************************************************************
6786 ****************************************************************/
6788 NTSTATUS
_samr_Shutdown(struct pipes_struct
*p
,
6789 struct samr_Shutdown
*r
)
6791 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6792 return NT_STATUS_NOT_IMPLEMENTED
;
6795 /****************************************************************
6796 ****************************************************************/
6798 NTSTATUS
_samr_SetMemberAttributesOfGroup(struct pipes_struct
*p
,
6799 struct samr_SetMemberAttributesOfGroup
*r
)
6801 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6802 return NT_STATUS_NOT_IMPLEMENTED
;
6805 /****************************************************************
6806 ****************************************************************/
6808 NTSTATUS
_samr_TestPrivateFunctionsDomain(struct pipes_struct
*p
,
6809 struct samr_TestPrivateFunctionsDomain
*r
)
6811 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6812 return NT_STATUS_NOT_IMPLEMENTED
;
6815 /****************************************************************
6816 ****************************************************************/
6818 NTSTATUS
_samr_TestPrivateFunctionsUser(struct pipes_struct
*p
,
6819 struct samr_TestPrivateFunctionsUser
*r
)
6821 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6822 return NT_STATUS_NOT_IMPLEMENTED
;
6825 /****************************************************************
6826 ****************************************************************/
6828 NTSTATUS
_samr_AddMultipleMembersToAlias(struct pipes_struct
*p
,
6829 struct samr_AddMultipleMembersToAlias
*r
)
6831 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6832 return NT_STATUS_NOT_IMPLEMENTED
;
6835 /****************************************************************
6836 ****************************************************************/
6838 NTSTATUS
_samr_RemoveMultipleMembersFromAlias(struct pipes_struct
*p
,
6839 struct samr_RemoveMultipleMembersFromAlias
*r
)
6841 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6842 return NT_STATUS_NOT_IMPLEMENTED
;
6845 /****************************************************************
6846 ****************************************************************/
6848 NTSTATUS
_samr_SetBootKeyInformation(struct pipes_struct
*p
,
6849 struct samr_SetBootKeyInformation
*r
)
6851 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6852 return NT_STATUS_NOT_IMPLEMENTED
;
6855 /****************************************************************
6856 ****************************************************************/
6858 NTSTATUS
_samr_GetBootKeyInformation(struct pipes_struct
*p
,
6859 struct samr_GetBootKeyInformation
*r
)
6861 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6862 return NT_STATUS_NOT_IMPLEMENTED
;
6865 /****************************************************************
6866 ****************************************************************/
6868 NTSTATUS
_samr_SetDsrmPassword(struct pipes_struct
*p
,
6869 struct samr_SetDsrmPassword
*r
)
6871 p
->fault_state
= DCERPC_FAULT_OP_RNG_ERROR
;
6872 return NT_STATUS_NOT_IMPLEMENTED
;