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 "smbd/globals.h"
36 #include "../libcli/auth/libcli_auth.h"
37 #include "../librpc/gen_ndr/srv_samr.h"
38 #include "rpc_server/srv_samr_util.h"
39 #include "../lib/crypto/arcfour.h"
41 #include "rpc_client/init_lsa.h"
42 #include "../libcli/security/dom_sid.h"
45 #define DBGC_CLASS DBGC_RPC_SRV
47 #define SAMR_USR_RIGHTS_WRITE_PW \
48 ( READ_CONTROL_ACCESS | \
49 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
50 SAMR_USER_ACCESS_SET_LOC_COM)
51 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
52 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
54 #define DISP_INFO_CACHE_TIMEOUT 10
56 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
57 #define MAX_SAM_ENTRIES_W95 50
59 struct samr_connect_info {
63 struct samr_domain_info {
65 struct disp_info *disp_info;
68 struct samr_user_info {
72 struct samr_group_info {
76 struct samr_alias_info {
80 typedef struct disp_info {
81 struct dom_sid sid; /* identify which domain this is. */
82 struct pdb_search *users; /* querydispinfo 1 and 4 */
83 struct pdb_search *machines; /* querydispinfo 2 */
84 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
85 struct pdb_search *aliases; /* enumaliases */
87 uint32_t enum_acb_mask;
88 struct pdb_search *enum_users; /* enumusers with a mask */
90 struct timed_event *cache_timeout_event; /* cache idle timeout
94 static const struct generic_mapping sam_generic_mapping = {
95 GENERIC_RIGHTS_SAM_READ,
96 GENERIC_RIGHTS_SAM_WRITE,
97 GENERIC_RIGHTS_SAM_EXECUTE,
98 GENERIC_RIGHTS_SAM_ALL_ACCESS};
99 static const struct generic_mapping dom_generic_mapping = {
100 GENERIC_RIGHTS_DOMAIN_READ,
101 GENERIC_RIGHTS_DOMAIN_WRITE,
102 GENERIC_RIGHTS_DOMAIN_EXECUTE,
103 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
104 static const struct generic_mapping usr_generic_mapping = {
105 GENERIC_RIGHTS_USER_READ,
106 GENERIC_RIGHTS_USER_WRITE,
107 GENERIC_RIGHTS_USER_EXECUTE,
108 GENERIC_RIGHTS_USER_ALL_ACCESS};
109 static const struct generic_mapping usr_nopwchange_generic_mapping = {
110 GENERIC_RIGHTS_USER_READ,
111 GENERIC_RIGHTS_USER_WRITE,
112 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
113 GENERIC_RIGHTS_USER_ALL_ACCESS};
114 static const struct generic_mapping grp_generic_mapping = {
115 GENERIC_RIGHTS_GROUP_READ,
116 GENERIC_RIGHTS_GROUP_WRITE,
117 GENERIC_RIGHTS_GROUP_EXECUTE,
118 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
119 static const struct generic_mapping ali_generic_mapping = {
120 GENERIC_RIGHTS_ALIAS_READ,
121 GENERIC_RIGHTS_ALIAS_WRITE,
122 GENERIC_RIGHTS_ALIAS_EXECUTE,
123 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
125 /*******************************************************************
126 *******************************************************************/
128 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
129 const struct generic_mapping *map,
130 struct dom_sid *sid, uint32 sid_access )
132 struct dom_sid domadmin_sid;
133 struct security_ace ace[5]; /* at most 5 entries */
136 struct security_acl *psa = NULL;
138 /* basic access for Everyone */
140 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
141 map->generic_execute | map->generic_read, 0);
143 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
145 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
146 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
147 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
148 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
150 /* Add Full Access for Domain Admins if we are a DC */
153 sid_compose(&domadmin_sid, get_global_sam_sid(),
155 init_sec_ace(&ace[i++], &domadmin_sid,
156 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
159 /* if we have a sid, give it some special access */
162 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
165 /* create the security descriptor */
167 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
168 return NT_STATUS_NO_MEMORY;
170 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
171 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
172 psa, sd_size)) == NULL)
173 return NT_STATUS_NO_MEMORY;
178 /*******************************************************************
179 Checks if access to an object should be granted, and returns that
180 level of access for further checks.
182 If the user has either of needed_priv_1 or needed_priv_2 then they
183 get the rights in rights_mask in addition to any calulated rights.
185 This handles the unusual case where we need to allow two different
186 privileges to obtain exactly the same rights, which occours only in
188 ********************************************************************/
190 NTSTATUS access_check_object( struct security_descriptor *psd, struct security_token *token,
191 enum sec_privilege needed_priv_1, enum sec_privilege needed_priv_2,
193 uint32 des_access, uint32 *acc_granted,
196 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
197 uint32 saved_mask = 0;
199 /* check privileges; certain SAM access bits should be overridden
200 by privileges (mostly having to do with creating/modifying/deleting
203 if ((needed_priv_1 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_1)) ||
204 (needed_priv_2 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_2))) {
205 saved_mask = (des_access & rights_mask);
206 des_access &= ~saved_mask;
208 DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
213 /* check the security descriptor first */
215 status = se_access_check(psd, token, des_access, acc_granted);
216 if (NT_STATUS_IS_OK(status)) {
220 /* give root a free pass */
222 if ( geteuid() == sec_initial_uid() ) {
224 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
225 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
227 *acc_granted = des_access;
229 status = NT_STATUS_OK;
235 /* add in any bits saved during the privilege check (only
236 matters is status is ok) */
238 *acc_granted |= rights_mask;
240 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
241 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
242 des_access, *acc_granted));
248 /*******************************************************************
249 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
250 ********************************************************************/
252 void map_max_allowed_access(const struct security_token *nt_token,
253 const struct unix_user_token *unix_token,
254 uint32_t *pacc_requested)
256 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
259 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
261 /* At least try for generic read|execute - Everyone gets that. */
262 *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
264 /* root gets anything. */
265 if (unix_token->uid == sec_initial_uid()) {
266 *pacc_requested |= GENERIC_ALL_ACCESS;
270 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
272 if (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) ||
273 is_sid_in_token(nt_token, &global_sid_Builtin_Account_Operators)) {
274 *pacc_requested |= GENERIC_ALL_ACCESS;
278 /* Full access for DOMAIN\Domain Admins. */
280 struct dom_sid domadmin_sid;
281 sid_compose(&domadmin_sid, get_global_sam_sid(),
283 if (is_sid_in_token(nt_token, &domadmin_sid)) {
284 *pacc_requested |= GENERIC_ALL_ACCESS;
288 /* TODO ! Check privileges. */
291 /*******************************************************************
292 Fetch or create a dispinfo struct.
293 ********************************************************************/
295 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
298 * We do a static cache for DISP_INFO's here. Explanation can be found
299 * in Jeremy's checkin message to r11793:
301 * Fix the SAMR cache so it works across completely insane
302 * client behaviour (ie.:
303 * open pipe/open SAMR handle/enumerate 0 - 1024
304 * close SAMR handle, close pipe.
305 * open pipe/open SAMR handle/enumerate 1024 - 2048...
306 * close SAMR handle, close pipe.
307 * And on ad-nausium. Amazing.... probably object-oriented
308 * client side programming in action yet again.
309 * This change should *massively* improve performance when
310 * enumerating users from an LDAP database.
313 * "Our" and the builtin domain are the only ones where we ever
314 * enumerate stuff, so just cache 2 entries.
317 static struct disp_info *builtin_dispinfo;
318 static struct disp_info *domain_dispinfo;
320 /* There are two cases to consider here:
321 1) The SID is a domain SID and we look for an equality match, or
322 2) This is an account SID and so we return the DISP_INFO* for our
329 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
331 * Necessary only once, but it does not really hurt.
333 if (builtin_dispinfo == NULL) {
334 builtin_dispinfo = talloc_zero(
335 talloc_autofree_context(), struct disp_info);
336 if (builtin_dispinfo == NULL) {
340 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
342 return builtin_dispinfo;
345 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
347 * Necessary only once, but it does not really hurt.
349 if (domain_dispinfo == NULL) {
350 domain_dispinfo = talloc_zero(
351 talloc_autofree_context(), struct disp_info);
352 if (domain_dispinfo == NULL) {
356 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
358 return domain_dispinfo;
364 /*******************************************************************
365 Function to free the per SID data.
366 ********************************************************************/
368 static void free_samr_cache(DISP_INFO *disp_info)
370 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
371 sid_string_dbg(&disp_info->sid)));
373 /* We need to become root here because the paged search might have to
374 * tell the LDAP server we're not interested in the rest anymore. */
378 TALLOC_FREE(disp_info->users);
379 TALLOC_FREE(disp_info->machines);
380 TALLOC_FREE(disp_info->groups);
381 TALLOC_FREE(disp_info->aliases);
382 TALLOC_FREE(disp_info->enum_users);
387 /*******************************************************************
388 Idle event handler. Throw away the disp info cache.
389 ********************************************************************/
391 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
392 struct timed_event *te,
396 DISP_INFO *disp_info = (DISP_INFO *)private_data;
398 TALLOC_FREE(disp_info->cache_timeout_event);
400 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
402 free_samr_cache(disp_info);
405 /*******************************************************************
406 Setup cache removal idle event handler.
407 ********************************************************************/
409 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
411 /* Remove any pending timeout and update. */
413 TALLOC_FREE(disp_info->cache_timeout_event);
415 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
416 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
417 (unsigned int)secs_fromnow ));
419 disp_info->cache_timeout_event = event_add_timed(
420 server_event_context(), NULL,
421 timeval_current_ofs(secs_fromnow, 0),
422 disp_info_cache_idle_timeout_handler, (void *)disp_info);
425 /*******************************************************************
426 Force flush any cache. We do this on any samr_set_xxx call.
427 We must also remove the timeout handler.
428 ********************************************************************/
430 static void force_flush_samr_cache(const struct dom_sid *sid)
432 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
434 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
438 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
439 TALLOC_FREE(disp_info->cache_timeout_event);
440 free_samr_cache(disp_info);
443 /*******************************************************************
444 Ensure password info is never given out. Paranioa... JRA.
445 ********************************************************************/
447 static void samr_clear_sam_passwd(struct samu *sam_pass)
453 /* These now zero out the old password */
455 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
456 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
459 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
461 struct samr_displayentry *entry;
463 if (sid_check_is_builtin(&info->sid)) {
464 /* No users in builtin. */
468 if (info->users == NULL) {
469 info->users = pdb_search_users(info, acct_flags);
470 if (info->users == NULL) {
474 /* Fetch the last possible entry, thus trigger an enumeration */
475 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
477 /* Ensure we cache this enumeration. */
478 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
480 return info->users->num_entries;
483 static uint32 count_sam_groups(struct disp_info *info)
485 struct samr_displayentry *entry;
487 if (sid_check_is_builtin(&info->sid)) {
488 /* No groups in builtin. */
492 if (info->groups == NULL) {
493 info->groups = pdb_search_groups(info);
494 if (info->groups == NULL) {
498 /* Fetch the last possible entry, thus trigger an enumeration */
499 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
501 /* Ensure we cache this enumeration. */
502 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
504 return info->groups->num_entries;
507 static uint32 count_sam_aliases(struct disp_info *info)
509 struct samr_displayentry *entry;
511 if (info->aliases == NULL) {
512 info->aliases = pdb_search_aliases(info, &info->sid);
513 if (info->aliases == NULL) {
517 /* Fetch the last possible entry, thus trigger an enumeration */
518 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
520 /* Ensure we cache this enumeration. */
521 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
523 return info->aliases->num_entries;
526 /*******************************************************************
528 ********************************************************************/
530 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
532 if (!close_policy_hnd(p, r->in.handle)) {
533 return NT_STATUS_INVALID_HANDLE;
536 ZERO_STRUCTP(r->out.handle);
541 /*******************************************************************
543 ********************************************************************/
545 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
546 struct samr_OpenDomain *r)
548 struct samr_connect_info *cinfo;
549 struct samr_domain_info *dinfo;
550 struct security_descriptor *psd = NULL;
552 uint32 des_access = r->in.access_mask;
555 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
557 /* find the connection policy handle. */
559 cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
560 struct samr_connect_info, &status);
561 if (!NT_STATUS_IS_OK(status)) {
565 /*check if access can be granted as requested by client. */
566 map_max_allowed_access(p->server_info->ptok,
567 &p->server_info->utok,
570 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
571 se_map_generic( &des_access, &dom_generic_mapping );
574 * Users with SeAddUser get the ability to manipulate groups
577 if (security_token_has_privilege(p->server_info->ptok, SEC_PRIV_ADD_USERS)) {
578 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
579 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
580 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
581 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
582 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
586 * Users with SeMachineAccount or SeAddUser get additional
587 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
590 status = access_check_object( psd, p->server_info->ptok,
591 SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
592 extra_access, des_access,
593 &acc_granted, "_samr_OpenDomain" );
595 if ( !NT_STATUS_IS_OK(status) )
598 if (!sid_check_is_domain(r->in.sid) &&
599 !sid_check_is_builtin(r->in.sid)) {
600 return NT_STATUS_NO_SUCH_DOMAIN;
603 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
604 struct samr_domain_info, &status);
605 if (!NT_STATUS_IS_OK(status)) {
608 dinfo->sid = *r->in.sid;
609 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
611 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
616 /*******************************************************************
618 ********************************************************************/
620 NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
621 struct samr_GetUserPwInfo *r)
623 struct samr_user_info *uinfo;
624 enum lsa_SidType sid_type;
625 uint32_t min_password_length = 0;
626 uint32_t password_properties = 0;
630 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
632 uinfo = policy_handle_find(p, r->in.user_handle,
633 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
634 struct samr_user_info, &status);
635 if (!NT_STATUS_IS_OK(status)) {
639 if (!sid_check_is_in_our_domain(&uinfo->sid)) {
640 return NT_STATUS_OBJECT_TYPE_MISMATCH;
644 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
647 return NT_STATUS_NO_SUCH_USER;
653 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
654 &min_password_length);
655 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
656 &password_properties);
659 if (lp_check_password_script() && *lp_check_password_script()) {
660 password_properties |= DOMAIN_PASSWORD_COMPLEX;
668 r->out.info->min_password_length = min_password_length;
669 r->out.info->password_properties = password_properties;
671 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
676 /*******************************************************************
678 ********************************************************************/
680 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
681 struct samr_SetSecurity *r)
683 struct samr_user_info *uinfo;
685 struct security_acl *dacl;
687 struct samu *sampass=NULL;
690 uinfo = policy_handle_find(p, r->in.handle,
691 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
692 struct samr_user_info, &status);
693 if (!NT_STATUS_IS_OK(status)) {
697 if (!(sampass = samu_new( p->mem_ctx))) {
698 DEBUG(0,("No memory!\n"));
699 return NT_STATUS_NO_MEMORY;
702 /* get the user record */
704 ret = pdb_getsampwsid(sampass, &uinfo->sid);
708 DEBUG(4, ("User %s not found\n",
709 sid_string_dbg(&uinfo->sid)));
710 TALLOC_FREE(sampass);
711 return NT_STATUS_INVALID_HANDLE;
714 dacl = r->in.sdbuf->sd->dacl;
715 for (i=0; i < dacl->num_aces; i++) {
716 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
717 ret = pdb_set_pass_can_change(sampass,
718 (dacl->aces[i].access_mask &
719 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
726 TALLOC_FREE(sampass);
727 return NT_STATUS_ACCESS_DENIED;
731 status = pdb_update_sam_account(sampass);
734 TALLOC_FREE(sampass);
739 /*******************************************************************
740 build correct perms based on policies and password times for _samr_query_sec_obj
741 *******************************************************************/
742 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
744 struct samu *sampass=NULL;
747 if ( !(sampass = samu_new( mem_ctx )) ) {
748 DEBUG(0,("No memory!\n"));
753 ret = pdb_getsampwsid(sampass, user_sid);
757 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
758 TALLOC_FREE(sampass);
762 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
764 if (pdb_get_pass_can_change(sampass)) {
765 TALLOC_FREE(sampass);
768 TALLOC_FREE(sampass);
773 /*******************************************************************
775 ********************************************************************/
777 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
778 struct samr_QuerySecurity *r)
780 struct samr_connect_info *cinfo;
781 struct samr_domain_info *dinfo;
782 struct samr_user_info *uinfo;
783 struct samr_group_info *ginfo;
784 struct samr_alias_info *ainfo;
786 struct security_descriptor * psd = NULL;
789 cinfo = policy_handle_find(p, r->in.handle,
790 SEC_STD_READ_CONTROL, NULL,
791 struct samr_connect_info, &status);
792 if (NT_STATUS_IS_OK(status)) {
793 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
794 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
795 &sam_generic_mapping, NULL, 0);
799 dinfo = policy_handle_find(p, r->in.handle,
800 SEC_STD_READ_CONTROL, NULL,
801 struct samr_domain_info, &status);
802 if (NT_STATUS_IS_OK(status)) {
803 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
804 "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
806 * TODO: Builtin probably needs a different SD with restricted
809 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
810 &dom_generic_mapping, NULL, 0);
814 uinfo = policy_handle_find(p, r->in.handle,
815 SEC_STD_READ_CONTROL, NULL,
816 struct samr_user_info, &status);
817 if (NT_STATUS_IS_OK(status)) {
818 DEBUG(10,("_samr_QuerySecurity: querying security on user "
819 "Object with SID: %s\n",
820 sid_string_dbg(&uinfo->sid)));
821 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
822 status = make_samr_object_sd(
823 p->mem_ctx, &psd, &sd_size,
824 &usr_generic_mapping,
825 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
827 status = make_samr_object_sd(
828 p->mem_ctx, &psd, &sd_size,
829 &usr_nopwchange_generic_mapping,
830 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
835 ginfo = policy_handle_find(p, r->in.handle,
836 SEC_STD_READ_CONTROL, NULL,
837 struct samr_group_info, &status);
838 if (NT_STATUS_IS_OK(status)) {
840 * TODO: different SDs have to be generated for aliases groups
841 * and users. Currently all three get a default user SD
843 DEBUG(10,("_samr_QuerySecurity: querying security on group "
844 "Object with SID: %s\n",
845 sid_string_dbg(&ginfo->sid)));
846 status = make_samr_object_sd(
847 p->mem_ctx, &psd, &sd_size,
848 &usr_nopwchange_generic_mapping,
849 &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
853 ainfo = policy_handle_find(p, r->in.handle,
854 SEC_STD_READ_CONTROL, NULL,
855 struct samr_alias_info, &status);
856 if (NT_STATUS_IS_OK(status)) {
858 * TODO: different SDs have to be generated for aliases groups
859 * and users. Currently all three get a default user SD
861 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
862 "Object with SID: %s\n",
863 sid_string_dbg(&ainfo->sid)));
864 status = make_samr_object_sd(
865 p->mem_ctx, &psd, &sd_size,
866 &usr_nopwchange_generic_mapping,
867 &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
871 return NT_STATUS_OBJECT_TYPE_MISMATCH;
873 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
874 return NT_STATUS_NO_MEMORY;
879 /*******************************************************************
880 makes a SAM_ENTRY / UNISTR2* structure from a user list.
881 ********************************************************************/
883 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
884 struct samr_SamEntry **sam_pp,
885 uint32_t num_entries,
887 struct samr_displayentry *entries)
890 struct samr_SamEntry *sam;
894 if (num_entries == 0) {
898 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
900 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
901 return NT_STATUS_NO_MEMORY;
904 for (i = 0; i < num_entries; i++) {
907 * usrmgr expects a non-NULL terminated string with
908 * trust relationships
910 if (entries[i].acct_flags & ACB_DOMTRUST) {
911 init_unistr2(&uni_temp_name, entries[i].account_name,
914 init_unistr2(&uni_temp_name, entries[i].account_name,
918 init_lsa_String(&sam[i].name, entries[i].account_name);
919 sam[i].idx = entries[i].rid;
927 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
929 /*******************************************************************
930 _samr_EnumDomainUsers
931 ********************************************************************/
933 NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
934 struct samr_EnumDomainUsers *r)
937 struct samr_domain_info *dinfo;
939 uint32 enum_context = *r->in.resume_handle;
940 enum remote_arch_types ra_type = get_remote_arch();
941 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
942 uint32 max_entries = max_sam_entries;
943 struct samr_displayentry *entries = NULL;
944 struct samr_SamArray *samr_array = NULL;
945 struct samr_SamEntry *samr_entries = NULL;
947 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
949 dinfo = policy_handle_find(p, r->in.domain_handle,
950 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
951 struct samr_domain_info, &status);
952 if (!NT_STATUS_IS_OK(status)) {
956 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
958 return NT_STATUS_NO_MEMORY;
960 *r->out.sam = samr_array;
962 if (sid_check_is_builtin(&dinfo->sid)) {
963 /* No users in builtin. */
964 *r->out.resume_handle = *r->in.resume_handle;
965 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
973 if ((dinfo->disp_info->enum_users != NULL) &&
974 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
975 TALLOC_FREE(dinfo->disp_info->enum_users);
978 if (dinfo->disp_info->enum_users == NULL) {
979 dinfo->disp_info->enum_users = pdb_search_users(
980 dinfo->disp_info, r->in.acct_flags);
981 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
984 if (dinfo->disp_info->enum_users == NULL) {
985 /* END AS ROOT !!!! */
987 return NT_STATUS_ACCESS_DENIED;
990 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
991 enum_context, max_entries,
994 /* END AS ROOT !!!! */
998 if (num_account == 0) {
999 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1000 "total entries\n"));
1001 *r->out.resume_handle = *r->in.resume_handle;
1002 return NT_STATUS_OK;
1005 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1006 num_account, enum_context,
1008 if (!NT_STATUS_IS_OK(status)) {
1012 if (max_entries <= num_account) {
1013 status = STATUS_MORE_ENTRIES;
1015 status = NT_STATUS_OK;
1018 /* Ensure we cache this enumeration. */
1019 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1021 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1023 samr_array->count = num_account;
1024 samr_array->entries = samr_entries;
1026 *r->out.resume_handle = *r->in.resume_handle + num_account;
1027 *r->out.num_entries = num_account;
1029 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1034 /*******************************************************************
1035 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1036 ********************************************************************/
1038 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1039 struct samr_SamEntry **sam_pp,
1040 uint32_t num_sam_entries,
1041 struct samr_displayentry *entries)
1043 struct samr_SamEntry *sam;
1048 if (num_sam_entries == 0) {
1052 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1057 for (i = 0; i < num_sam_entries; i++) {
1059 * JRA. I think this should include the null. TNG does not.
1061 init_lsa_String(&sam[i].name, entries[i].account_name);
1062 sam[i].idx = entries[i].rid;
1068 /*******************************************************************
1069 _samr_EnumDomainGroups
1070 ********************************************************************/
1072 NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
1073 struct samr_EnumDomainGroups *r)
1076 struct samr_domain_info *dinfo;
1077 struct samr_displayentry *groups;
1079 struct samr_SamArray *samr_array = NULL;
1080 struct samr_SamEntry *samr_entries = NULL;
1082 dinfo = policy_handle_find(p, r->in.domain_handle,
1083 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1084 struct samr_domain_info, &status);
1085 if (!NT_STATUS_IS_OK(status)) {
1089 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1091 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1093 return NT_STATUS_NO_MEMORY;
1095 *r->out.sam = samr_array;
1097 if (sid_check_is_builtin(&dinfo->sid)) {
1098 /* No groups in builtin. */
1099 *r->out.resume_handle = *r->in.resume_handle;
1100 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1104 /* the domain group array is being allocated in the function below */
1108 if (dinfo->disp_info->groups == NULL) {
1109 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1111 if (dinfo->disp_info->groups == NULL) {
1113 return NT_STATUS_ACCESS_DENIED;
1117 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1118 *r->in.resume_handle,
1119 MAX_SAM_ENTRIES, &groups);
1122 /* Ensure we cache this enumeration. */
1123 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1125 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1126 num_groups, groups);
1128 if (MAX_SAM_ENTRIES <= num_groups) {
1129 status = STATUS_MORE_ENTRIES;
1131 status = NT_STATUS_OK;
1134 samr_array->count = num_groups;
1135 samr_array->entries = samr_entries;
1137 *r->out.num_entries = num_groups;
1138 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1140 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1145 /*******************************************************************
1146 _samr_EnumDomainAliases
1147 ********************************************************************/
1149 NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1150 struct samr_EnumDomainAliases *r)
1153 struct samr_domain_info *dinfo;
1154 struct samr_displayentry *aliases;
1155 uint32 num_aliases = 0;
1156 struct samr_SamArray *samr_array = NULL;
1157 struct samr_SamEntry *samr_entries = NULL;
1159 dinfo = policy_handle_find(p, r->in.domain_handle,
1160 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1161 struct samr_domain_info, &status);
1162 if (!NT_STATUS_IS_OK(status)) {
1166 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1167 sid_string_dbg(&dinfo->sid)));
1169 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1171 return NT_STATUS_NO_MEMORY;
1176 if (dinfo->disp_info->aliases == NULL) {
1177 dinfo->disp_info->aliases = pdb_search_aliases(
1178 dinfo->disp_info, &dinfo->sid);
1179 if (dinfo->disp_info->aliases == NULL) {
1181 return NT_STATUS_ACCESS_DENIED;
1185 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1186 *r->in.resume_handle,
1187 MAX_SAM_ENTRIES, &aliases);
1190 /* Ensure we cache this enumeration. */
1191 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1193 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1194 num_aliases, aliases);
1196 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1198 if (MAX_SAM_ENTRIES <= num_aliases) {
1199 status = STATUS_MORE_ENTRIES;
1201 status = NT_STATUS_OK;
1204 samr_array->count = num_aliases;
1205 samr_array->entries = samr_entries;
1207 *r->out.sam = samr_array;
1208 *r->out.num_entries = num_aliases;
1209 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1214 /*******************************************************************
1215 inits a samr_DispInfoGeneral structure.
1216 ********************************************************************/
1218 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1219 struct samr_DispInfoGeneral *r,
1220 uint32_t num_entries,
1222 struct samr_displayentry *entries)
1226 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1228 if (num_entries == 0) {
1229 return NT_STATUS_OK;
1232 r->count = num_entries;
1234 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1236 return NT_STATUS_NO_MEMORY;
1239 for (i = 0; i < num_entries ; i++) {
1241 init_lsa_String(&r->entries[i].account_name,
1242 entries[i].account_name);
1244 init_lsa_String(&r->entries[i].description,
1245 entries[i].description);
1247 init_lsa_String(&r->entries[i].full_name,
1248 entries[i].fullname);
1250 r->entries[i].rid = entries[i].rid;
1251 r->entries[i].acct_flags = entries[i].acct_flags;
1252 r->entries[i].idx = start_idx+i+1;
1255 return NT_STATUS_OK;
1258 /*******************************************************************
1259 inits a samr_DispInfoFull structure.
1260 ********************************************************************/
1262 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1263 struct samr_DispInfoFull *r,
1264 uint32_t num_entries,
1266 struct samr_displayentry *entries)
1270 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1272 if (num_entries == 0) {
1273 return NT_STATUS_OK;
1276 r->count = num_entries;
1278 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1280 return NT_STATUS_NO_MEMORY;
1283 for (i = 0; i < num_entries ; i++) {
1285 init_lsa_String(&r->entries[i].account_name,
1286 entries[i].account_name);
1288 init_lsa_String(&r->entries[i].description,
1289 entries[i].description);
1291 r->entries[i].rid = entries[i].rid;
1292 r->entries[i].acct_flags = entries[i].acct_flags;
1293 r->entries[i].idx = start_idx+i+1;
1296 return NT_STATUS_OK;
1299 /*******************************************************************
1300 inits a samr_DispInfoFullGroups structure.
1301 ********************************************************************/
1303 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1304 struct samr_DispInfoFullGroups *r,
1305 uint32_t num_entries,
1307 struct samr_displayentry *entries)
1311 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1313 if (num_entries == 0) {
1314 return NT_STATUS_OK;
1317 r->count = num_entries;
1319 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1321 return NT_STATUS_NO_MEMORY;
1324 for (i = 0; i < num_entries ; i++) {
1326 init_lsa_String(&r->entries[i].account_name,
1327 entries[i].account_name);
1329 init_lsa_String(&r->entries[i].description,
1330 entries[i].description);
1332 r->entries[i].rid = entries[i].rid;
1333 r->entries[i].acct_flags = entries[i].acct_flags;
1334 r->entries[i].idx = start_idx+i+1;
1337 return NT_STATUS_OK;
1340 /*******************************************************************
1341 inits a samr_DispInfoAscii structure.
1342 ********************************************************************/
1344 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1345 struct samr_DispInfoAscii *r,
1346 uint32_t num_entries,
1348 struct samr_displayentry *entries)
1352 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1354 if (num_entries == 0) {
1355 return NT_STATUS_OK;
1358 r->count = num_entries;
1360 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1362 return NT_STATUS_NO_MEMORY;
1365 for (i = 0; i < num_entries ; i++) {
1367 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1368 entries[i].account_name);
1370 r->entries[i].idx = start_idx+i+1;
1373 return NT_STATUS_OK;
1376 /*******************************************************************
1377 inits a samr_DispInfoAscii structure.
1378 ********************************************************************/
1380 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1381 struct samr_DispInfoAscii *r,
1382 uint32_t num_entries,
1384 struct samr_displayentry *entries)
1388 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1390 if (num_entries == 0) {
1391 return NT_STATUS_OK;
1394 r->count = num_entries;
1396 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1398 return NT_STATUS_NO_MEMORY;
1401 for (i = 0; i < num_entries ; i++) {
1403 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1404 entries[i].account_name);
1406 r->entries[i].idx = start_idx+i+1;
1409 return NT_STATUS_OK;
1412 /*******************************************************************
1413 _samr_QueryDisplayInfo
1414 ********************************************************************/
1416 NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1417 struct samr_QueryDisplayInfo *r)
1420 struct samr_domain_info *dinfo;
1421 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1423 uint32 max_entries = r->in.max_entries;
1425 union samr_DispInfo *disp_info = r->out.info;
1428 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1429 uint32 num_account = 0;
1430 enum remote_arch_types ra_type = get_remote_arch();
1431 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1432 struct samr_displayentry *entries = NULL;
1434 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1436 dinfo = policy_handle_find(p, r->in.domain_handle,
1437 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1438 struct samr_domain_info, &status);
1439 if (!NT_STATUS_IS_OK(status)) {
1443 if (sid_check_is_builtin(&dinfo->sid)) {
1444 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1445 return NT_STATUS_OK;
1449 * calculate how many entries we will return.
1451 * - the number of entries the client asked
1452 * - our limit on that
1453 * - the starting point (enumeration context)
1454 * - the buffer size the client will accept
1458 * We are a lot more like W2K. Instead of reading the SAM
1459 * each time to find the records we need to send back,
1460 * we read it once and link that copy to the sam handle.
1461 * For large user list (over the MAX_SAM_ENTRIES)
1462 * it's a definitive win.
1463 * second point to notice: between enumerations
1464 * our sam is now the same as it's a snapshoot.
1465 * third point: got rid of the static SAM_USER_21 struct
1466 * no more intermediate.
1467 * con: it uses much more memory, as a full copy is stored
1470 * If you want to change it, think twice and think
1471 * of the second point , that's really important.
1476 if ((r->in.level < 1) || (r->in.level > 5)) {
1477 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1478 (unsigned int)r->in.level ));
1479 return NT_STATUS_INVALID_INFO_CLASS;
1482 /* first limit the number of entries we will return */
1483 if (r->in.max_entries > max_sam_entries) {
1484 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1485 "entries, limiting to %d\n", r->in.max_entries,
1487 max_entries = max_sam_entries;
1490 /* calculate the size and limit on the number of entries we will
1493 temp_size=max_entries*struct_size;
1495 if (temp_size > r->in.buf_size) {
1496 max_entries = MIN((r->in.buf_size / struct_size),max_entries);;
1497 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1498 "only %d entries\n", max_entries));
1503 /* THe following done as ROOT. Don't return without unbecome_root(). */
1505 switch (r->in.level) {
1508 if (dinfo->disp_info->users == NULL) {
1509 dinfo->disp_info->users = pdb_search_users(
1510 dinfo->disp_info, ACB_NORMAL);
1511 if (dinfo->disp_info->users == NULL) {
1513 return NT_STATUS_ACCESS_DENIED;
1515 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1516 (unsigned int)r->in.start_idx));
1518 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1519 (unsigned int)r->in.start_idx));
1522 num_account = pdb_search_entries(dinfo->disp_info->users,
1523 r->in.start_idx, max_entries,
1527 if (dinfo->disp_info->machines == NULL) {
1528 dinfo->disp_info->machines = pdb_search_users(
1529 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1530 if (dinfo->disp_info->machines == NULL) {
1532 return NT_STATUS_ACCESS_DENIED;
1534 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1535 (unsigned int)r->in.start_idx));
1537 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1538 (unsigned int)r->in.start_idx));
1541 num_account = pdb_search_entries(dinfo->disp_info->machines,
1542 r->in.start_idx, max_entries,
1547 if (dinfo->disp_info->groups == NULL) {
1548 dinfo->disp_info->groups = pdb_search_groups(
1550 if (dinfo->disp_info->groups == NULL) {
1552 return NT_STATUS_ACCESS_DENIED;
1554 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1555 (unsigned int)r->in.start_idx));
1557 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1558 (unsigned int)r->in.start_idx));
1561 num_account = pdb_search_entries(dinfo->disp_info->groups,
1562 r->in.start_idx, max_entries,
1567 smb_panic("info class changed");
1573 /* Now create reply structure */
1574 switch (r->in.level) {
1576 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1577 num_account, r->in.start_idx,
1581 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1582 num_account, r->in.start_idx,
1586 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1587 num_account, r->in.start_idx,
1591 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1592 num_account, r->in.start_idx,
1596 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1597 num_account, r->in.start_idx,
1601 smb_panic("info class changed");
1605 if (!NT_STATUS_IS_OK(disp_ret))
1608 if (max_entries <= num_account) {
1609 status = STATUS_MORE_ENTRIES;
1611 status = NT_STATUS_OK;
1614 /* Ensure we cache this enumeration. */
1615 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1617 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1619 *r->out.total_size = num_account * struct_size;
1620 *r->out.returned_size = num_account ? temp_size : 0;
1625 /****************************************************************
1626 _samr_QueryDisplayInfo2
1627 ****************************************************************/
1629 NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1630 struct samr_QueryDisplayInfo2 *r)
1632 struct samr_QueryDisplayInfo q;
1634 q.in.domain_handle = r->in.domain_handle;
1635 q.in.level = r->in.level;
1636 q.in.start_idx = r->in.start_idx;
1637 q.in.max_entries = r->in.max_entries;
1638 q.in.buf_size = r->in.buf_size;
1640 q.out.total_size = r->out.total_size;
1641 q.out.returned_size = r->out.returned_size;
1642 q.out.info = r->out.info;
1644 return _samr_QueryDisplayInfo(p, &q);
1647 /****************************************************************
1648 _samr_QueryDisplayInfo3
1649 ****************************************************************/
1651 NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1652 struct samr_QueryDisplayInfo3 *r)
1654 struct samr_QueryDisplayInfo q;
1656 q.in.domain_handle = r->in.domain_handle;
1657 q.in.level = r->in.level;
1658 q.in.start_idx = r->in.start_idx;
1659 q.in.max_entries = r->in.max_entries;
1660 q.in.buf_size = r->in.buf_size;
1662 q.out.total_size = r->out.total_size;
1663 q.out.returned_size = r->out.returned_size;
1664 q.out.info = r->out.info;
1666 return _samr_QueryDisplayInfo(p, &q);
1669 /*******************************************************************
1670 _samr_QueryAliasInfo
1671 ********************************************************************/
1673 NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1674 struct samr_QueryAliasInfo *r)
1676 struct samr_alias_info *ainfo;
1677 struct acct_info info;
1679 union samr_AliasInfo *alias_info = NULL;
1680 const char *alias_name = NULL;
1681 const char *alias_description = NULL;
1683 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1685 ainfo = policy_handle_find(p, r->in.alias_handle,
1686 SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1687 struct samr_alias_info, &status);
1688 if (!NT_STATUS_IS_OK(status)) {
1692 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1694 return NT_STATUS_NO_MEMORY;
1698 status = pdb_get_aliasinfo(&ainfo->sid, &info);
1701 if ( !NT_STATUS_IS_OK(status))
1704 /* FIXME: info contains fstrings */
1705 alias_name = talloc_strdup(r, info.acct_name);
1706 alias_description = talloc_strdup(r, info.acct_desc);
1708 switch (r->in.level) {
1710 alias_info->all.name.string = alias_name;
1711 alias_info->all.num_members = 1; /* ??? */
1712 alias_info->all.description.string = alias_description;
1715 alias_info->name.string = alias_name;
1717 case ALIASINFODESCRIPTION:
1718 alias_info->description.string = alias_description;
1721 return NT_STATUS_INVALID_INFO_CLASS;
1724 *r->out.info = alias_info;
1726 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1728 return NT_STATUS_OK;
1731 /*******************************************************************
1733 ********************************************************************/
1735 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1736 struct samr_LookupNames *r)
1738 struct samr_domain_info *dinfo;
1741 enum lsa_SidType *type;
1743 int num_rids = r->in.num_names;
1744 struct samr_Ids rids, types;
1745 uint32_t num_mapped = 0;
1747 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1749 dinfo = policy_handle_find(p, r->in.domain_handle,
1750 0 /* Don't know the acc_bits yet */, NULL,
1751 struct samr_domain_info, &status);
1752 if (!NT_STATUS_IS_OK(status)) {
1756 if (num_rids > MAX_SAM_ENTRIES) {
1757 num_rids = MAX_SAM_ENTRIES;
1758 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1761 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1762 NT_STATUS_HAVE_NO_MEMORY(rid);
1764 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1765 NT_STATUS_HAVE_NO_MEMORY(type);
1767 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1768 sid_string_dbg(&dinfo->sid)));
1770 for (i = 0; i < num_rids; i++) {
1772 status = NT_STATUS_NONE_MAPPED;
1773 type[i] = SID_NAME_UNKNOWN;
1775 rid[i] = 0xffffffff;
1777 if (sid_check_is_builtin(&dinfo->sid)) {
1778 if (lookup_builtin_name(r->in.names[i].string,
1781 type[i] = SID_NAME_ALIAS;
1784 lookup_global_sam_name(r->in.names[i].string, 0,
1788 if (type[i] != SID_NAME_UNKNOWN) {
1793 if (num_mapped == num_rids) {
1794 status = NT_STATUS_OK;
1795 } else if (num_mapped == 0) {
1796 status = NT_STATUS_NONE_MAPPED;
1798 status = STATUS_SOME_UNMAPPED;
1801 rids.count = num_rids;
1804 types.count = num_rids;
1805 types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1806 NT_STATUS_HAVE_NO_MEMORY(type);
1807 for (i = 0; i < num_rids; i++) {
1808 types.ids[i] = (type[i] & 0xffffffff);
1811 *r->out.rids = rids;
1812 *r->out.types = types;
1814 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1819 /****************************************************************
1820 _samr_ChangePasswordUser
1821 ****************************************************************/
1823 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1824 struct samr_ChangePasswordUser *r)
1828 struct samr_user_info *uinfo;
1830 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1831 struct samr_Password lm_pwd, nt_pwd;
1833 uinfo = policy_handle_find(p, r->in.user_handle,
1834 SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1835 struct samr_user_info, &status);
1836 if (!NT_STATUS_IS_OK(status)) {
1840 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1841 sid_string_dbg(&uinfo->sid)));
1843 if (!(pwd = samu_new(NULL))) {
1844 return NT_STATUS_NO_MEMORY;
1848 ret = pdb_getsampwsid(pwd, &uinfo->sid);
1853 return NT_STATUS_WRONG_PASSWORD;
1857 const uint8_t *lm_pass, *nt_pass;
1859 lm_pass = pdb_get_lanman_passwd(pwd);
1860 nt_pass = pdb_get_nt_passwd(pwd);
1862 if (!lm_pass || !nt_pass) {
1863 status = NT_STATUS_WRONG_PASSWORD;
1867 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1868 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1871 /* basic sanity checking on parameters. Do this before any database ops */
1872 if (!r->in.lm_present || !r->in.nt_present ||
1873 !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1874 !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1875 /* we should really handle a change with lm not
1877 status = NT_STATUS_INVALID_PARAMETER_MIX;
1881 /* decrypt and check the new lm hash */
1882 D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1883 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1884 if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1885 status = NT_STATUS_WRONG_PASSWORD;
1889 /* decrypt and check the new nt hash */
1890 D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1891 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1892 if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1893 status = NT_STATUS_WRONG_PASSWORD;
1897 /* The NT Cross is not required by Win2k3 R2, but if present
1898 check the nt cross hash */
1899 if (r->in.cross1_present && r->in.nt_cross) {
1900 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1901 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1902 status = NT_STATUS_WRONG_PASSWORD;
1907 /* The LM Cross is not required by Win2k3 R2, but if present
1908 check the lm cross hash */
1909 if (r->in.cross2_present && r->in.lm_cross) {
1910 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1911 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1912 status = NT_STATUS_WRONG_PASSWORD;
1917 if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1918 !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1919 status = NT_STATUS_ACCESS_DENIED;
1923 status = pdb_update_sam_account(pwd);
1930 /*******************************************************************
1931 _samr_ChangePasswordUser2
1932 ********************************************************************/
1934 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1935 struct samr_ChangePasswordUser2 *r)
1941 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1943 fstrcpy(user_name, r->in.account->string);
1944 fstrcpy(wks, r->in.server->string);
1946 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1949 * Pass the user through the NT -> unix user mapping
1953 (void)map_username(user_name);
1956 * UNIX username case mangling not required, pass_oem_change
1957 * is case insensitive.
1960 status = pass_oem_change(user_name,
1962 r->in.lm_password->data,
1963 r->in.lm_verifier->hash,
1964 r->in.nt_password->data,
1965 r->in.nt_verifier->hash,
1968 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1970 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1971 return NT_STATUS_WRONG_PASSWORD;
1977 /****************************************************************
1978 _samr_OemChangePasswordUser2
1979 ****************************************************************/
1981 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1982 struct samr_OemChangePasswordUser2 *r)
1986 const char *wks = NULL;
1988 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1990 fstrcpy(user_name, r->in.account->string);
1991 if (r->in.server && r->in.server->string) {
1992 wks = r->in.server->string;
1995 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1998 * Pass the user through the NT -> unix user mapping
2002 (void)map_username(user_name);
2005 * UNIX username case mangling not required, pass_oem_change
2006 * is case insensitive.
2009 if (!r->in.hash || !r->in.password) {
2010 return NT_STATUS_INVALID_PARAMETER;
2013 status = pass_oem_change(user_name,
2015 r->in.password->data,
2021 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2022 return NT_STATUS_WRONG_PASSWORD;
2025 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2030 /*******************************************************************
2031 _samr_ChangePasswordUser3
2032 ********************************************************************/
2034 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
2035 struct samr_ChangePasswordUser3 *r)
2039 const char *wks = NULL;
2040 enum samPwdChangeReason reject_reason;
2041 struct samr_DomInfo1 *dominfo = NULL;
2042 struct userPwdChangeFailureInformation *reject = NULL;
2045 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2047 fstrcpy(user_name, r->in.account->string);
2048 if (r->in.server && r->in.server->string) {
2049 wks = r->in.server->string;
2052 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2055 * Pass the user through the NT -> unix user mapping
2059 (void)map_username(user_name);
2062 * UNIX username case mangling not required, pass_oem_change
2063 * is case insensitive.
2066 status = pass_oem_change(user_name,
2068 r->in.lm_password->data,
2069 r->in.lm_verifier->hash,
2070 r->in.nt_password->data,
2071 r->in.nt_verifier->hash,
2073 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2074 return NT_STATUS_WRONG_PASSWORD;
2077 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2078 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2080 time_t u_expire, u_min_age;
2081 uint32 account_policy_temp;
2083 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2085 return NT_STATUS_NO_MEMORY;
2088 reject = TALLOC_ZERO_P(p->mem_ctx,
2089 struct userPwdChangeFailureInformation);
2091 return NT_STATUS_NO_MEMORY;
2098 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2099 dominfo->min_password_length = tmp;
2101 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2102 dominfo->password_history_length = tmp;
2104 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2105 &dominfo->password_properties);
2107 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2108 u_expire = account_policy_temp;
2110 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2111 u_min_age = account_policy_temp;
2117 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2118 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2120 if (lp_check_password_script() && *lp_check_password_script()) {
2121 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2124 reject->extendedFailureReason = reject_reason;
2126 *r->out.dominfo = dominfo;
2127 *r->out.reject = reject;
2130 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2135 /*******************************************************************
2136 makes a SAMR_R_LOOKUP_RIDS structure.
2137 ********************************************************************/
2139 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2141 struct lsa_String **lsa_name_array_p)
2143 struct lsa_String *lsa_name_array = NULL;
2146 *lsa_name_array_p = NULL;
2148 if (num_names != 0) {
2149 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2150 if (!lsa_name_array) {
2155 for (i = 0; i < num_names; i++) {
2156 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2157 init_lsa_String(&lsa_name_array[i], names[i]);
2160 *lsa_name_array_p = lsa_name_array;
2165 /*******************************************************************
2167 ********************************************************************/
2169 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2170 struct samr_LookupRids *r)
2172 struct samr_domain_info *dinfo;
2175 enum lsa_SidType *attrs = NULL;
2176 uint32 *wire_attrs = NULL;
2177 int num_rids = (int)r->in.num_rids;
2179 struct lsa_Strings names_array;
2180 struct samr_Ids types_array;
2181 struct lsa_String *lsa_names = NULL;
2183 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2185 dinfo = policy_handle_find(p, r->in.domain_handle,
2186 0 /* Don't know the acc_bits yet */, NULL,
2187 struct samr_domain_info, &status);
2188 if (!NT_STATUS_IS_OK(status)) {
2192 if (num_rids > 1000) {
2193 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2194 "to samba4 idl this is not possible\n", num_rids));
2195 return NT_STATUS_UNSUCCESSFUL;
2199 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2200 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2201 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2203 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2204 return NT_STATUS_NO_MEMORY;
2211 become_root(); /* lookup_sid can require root privs */
2212 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2216 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2217 status = NT_STATUS_OK;
2220 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2222 return NT_STATUS_NO_MEMORY;
2225 /* Convert from enum lsa_SidType to uint32 for wire format. */
2226 for (i = 0; i < num_rids; i++) {
2227 wire_attrs[i] = (uint32)attrs[i];
2230 names_array.count = num_rids;
2231 names_array.names = lsa_names;
2233 types_array.count = num_rids;
2234 types_array.ids = wire_attrs;
2236 *r->out.names = names_array;
2237 *r->out.types = types_array;
2239 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2244 /*******************************************************************
2246 ********************************************************************/
2248 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2249 struct samr_OpenUser *r)
2251 struct samu *sampass=NULL;
2253 struct samr_domain_info *dinfo;
2254 struct samr_user_info *uinfo;
2255 struct security_descriptor *psd = NULL;
2257 uint32 des_access = r->in.access_mask;
2258 uint32_t extra_access = 0;
2263 /* These two privileges, if != SEC_PRIV_INVALID, indicate
2264 * privileges that the user must have to complete this
2265 * operation in defience of the fixed ACL */
2266 enum sec_privilege needed_priv_1, needed_priv_2;
2269 dinfo = policy_handle_find(p, r->in.domain_handle,
2270 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2271 struct samr_domain_info, &status);
2272 if (!NT_STATUS_IS_OK(status)) {
2276 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2277 return NT_STATUS_NO_MEMORY;
2280 /* append the user's RID to it */
2282 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2283 return NT_STATUS_NO_SUCH_USER;
2285 /* check if access can be granted as requested by client. */
2286 map_max_allowed_access(p->server_info->ptok,
2287 &p->server_info->utok,
2290 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2291 se_map_generic(&des_access, &usr_generic_mapping);
2294 * Get the sampass first as we need to check privileges
2295 * based on what kind of user object this is.
2296 * But don't reveal info too early if it didn't exist.
2300 ret=pdb_getsampwsid(sampass, &sid);
2303 needed_priv_1 = SEC_PRIV_INVALID;
2304 needed_priv_2 = SEC_PRIV_INVALID;
2306 * We do the override access checks on *open*, not at
2310 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2312 if (acb_info & ACB_WSTRUST) {
2314 * SeMachineAccount is needed to add
2315 * GENERIC_RIGHTS_USER_WRITE to a machine
2318 needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2320 if (acb_info & ACB_NORMAL) {
2322 * SeAddUsers is needed to add
2323 * GENERIC_RIGHTS_USER_WRITE to a normal
2326 needed_priv_1 = SEC_PRIV_ADD_USERS;
2329 * Cheat - we have not set a specific privilege for
2330 * server (BDC) or domain trust account, so allow
2331 * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2332 * DOMAIN_RID_ADMINS.
2334 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2335 if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2336 DOMAIN_RID_ADMINS)) {
2337 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2338 extra_access = GENERIC_RIGHTS_USER_WRITE;
2339 DEBUG(4,("_samr_OpenUser: Allowing "
2340 "GENERIC_RIGHTS_USER_WRITE for "
2346 TALLOC_FREE(sampass);
2348 nt_status = access_check_object(psd, p->server_info->ptok,
2349 needed_priv_1, needed_priv_2,
2350 GENERIC_RIGHTS_USER_WRITE, des_access,
2351 &acc_granted, "_samr_OpenUser");
2353 if ( !NT_STATUS_IS_OK(nt_status) )
2356 /* check that the SID exists in our domain. */
2358 return NT_STATUS_NO_SUCH_USER;
2361 /* If we did the rid admins hack above, allow access. */
2362 acc_granted |= extra_access;
2364 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2365 struct samr_user_info, &nt_status);
2366 if (!NT_STATUS_IS_OK(nt_status)) {
2371 return NT_STATUS_OK;
2374 /*************************************************************************
2375 *************************************************************************/
2377 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2379 struct lsa_BinaryString **_r)
2381 struct lsa_BinaryString *r;
2384 return NT_STATUS_INVALID_PARAMETER;
2387 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2389 return NT_STATUS_NO_MEMORY;
2392 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2394 return NT_STATUS_NO_MEMORY;
2396 memcpy(r->array, blob->data, blob->length);
2397 r->size = blob->length;
2398 r->length = blob->length;
2401 return NT_STATUS_NO_MEMORY;
2406 return NT_STATUS_OK;
2409 /*************************************************************************
2410 *************************************************************************/
2412 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2415 struct samr_LogonHours hours;
2416 const int units_per_week = 168;
2419 hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2424 hours.units_per_week = units_per_week;
2425 memset(hours.bits, 0xFF, units_per_week);
2427 if (pdb_get_hours(pw)) {
2428 memcpy(hours.bits, pdb_get_hours(pw),
2429 MIN(pdb_get_hours_len(pw), units_per_week));
2435 /*************************************************************************
2437 *************************************************************************/
2439 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2440 struct samr_UserInfo1 *r,
2442 struct dom_sid *domain_sid)
2444 const struct dom_sid *sid_group;
2445 uint32_t primary_gid;
2448 sid_group = pdb_get_group_sid(pw);
2451 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2452 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2453 "which conflicts with the domain sid %s. Failing operation.\n",
2454 pdb_get_username(pw), sid_string_dbg(sid_group),
2455 sid_string_dbg(domain_sid)));
2456 return NT_STATUS_UNSUCCESSFUL;
2459 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2460 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2461 r->primary_gid = primary_gid;
2462 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2463 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2465 return NT_STATUS_OK;
2468 /*************************************************************************
2470 *************************************************************************/
2472 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2473 struct samr_UserInfo2 *r,
2476 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2477 r->reserved.string = NULL;
2478 r->country_code = 0;
2481 return NT_STATUS_OK;
2484 /*************************************************************************
2486 *************************************************************************/
2488 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2489 struct samr_UserInfo3 *r,
2491 struct dom_sid *domain_sid)
2493 const struct dom_sid *sid_user, *sid_group;
2494 uint32_t rid, primary_gid;
2496 sid_user = pdb_get_user_sid(pw);
2498 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2499 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2500 "the domain sid %s. Failing operation.\n",
2501 pdb_get_username(pw), sid_string_dbg(sid_user),
2502 sid_string_dbg(domain_sid)));
2503 return NT_STATUS_UNSUCCESSFUL;
2507 sid_group = pdb_get_group_sid(pw);
2510 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2511 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2512 "which conflicts with the domain sid %s. Failing operation.\n",
2513 pdb_get_username(pw), sid_string_dbg(sid_group),
2514 sid_string_dbg(domain_sid)));
2515 return NT_STATUS_UNSUCCESSFUL;
2518 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2519 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2520 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2521 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2522 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2524 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2525 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2526 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2527 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2528 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2529 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2530 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2532 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2534 r->primary_gid = primary_gid;
2535 r->acct_flags = pdb_get_acct_ctrl(pw);
2536 r->bad_password_count = pdb_get_bad_password_count(pw);
2537 r->logon_count = pdb_get_logon_count(pw);
2539 return NT_STATUS_OK;
2542 /*************************************************************************
2544 *************************************************************************/
2546 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2547 struct samr_UserInfo4 *r,
2550 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2552 return NT_STATUS_OK;
2555 /*************************************************************************
2557 *************************************************************************/
2559 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2560 struct samr_UserInfo5 *r,
2562 struct dom_sid *domain_sid)
2564 const struct dom_sid *sid_user, *sid_group;
2565 uint32_t rid, primary_gid;
2567 sid_user = pdb_get_user_sid(pw);
2569 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2570 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2571 "the domain sid %s. Failing operation.\n",
2572 pdb_get_username(pw), sid_string_dbg(sid_user),
2573 sid_string_dbg(domain_sid)));
2574 return NT_STATUS_UNSUCCESSFUL;
2578 sid_group = pdb_get_group_sid(pw);
2581 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2582 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2583 "which conflicts with the domain sid %s. Failing operation.\n",
2584 pdb_get_username(pw), sid_string_dbg(sid_group),
2585 sid_string_dbg(domain_sid)));
2586 return NT_STATUS_UNSUCCESSFUL;
2589 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2590 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2591 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2592 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2594 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2595 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2596 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2597 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2598 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2599 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2600 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2601 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2603 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2605 r->primary_gid = primary_gid;
2606 r->acct_flags = pdb_get_acct_ctrl(pw);
2607 r->bad_password_count = pdb_get_bad_password_count(pw);
2608 r->logon_count = pdb_get_logon_count(pw);
2610 return NT_STATUS_OK;
2613 /*************************************************************************
2615 *************************************************************************/
2617 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2618 struct samr_UserInfo6 *r,
2621 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2622 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2624 return NT_STATUS_OK;
2627 /*************************************************************************
2628 get_user_info_7. Safe. Only gives out account_name.
2629 *************************************************************************/
2631 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2632 struct samr_UserInfo7 *r,
2633 struct samu *smbpass)
2635 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2636 if (!r->account_name.string) {
2637 return NT_STATUS_NO_MEMORY;
2640 return NT_STATUS_OK;
2643 /*************************************************************************
2645 *************************************************************************/
2647 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2648 struct samr_UserInfo8 *r,
2651 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2653 return NT_STATUS_OK;
2656 /*************************************************************************
2657 get_user_info_9. Only gives out primary group SID.
2658 *************************************************************************/
2660 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2661 struct samr_UserInfo9 *r,
2662 struct samu *smbpass)
2664 r->primary_gid = pdb_get_group_rid(smbpass);
2666 return NT_STATUS_OK;
2669 /*************************************************************************
2671 *************************************************************************/
2673 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2674 struct samr_UserInfo10 *r,
2677 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2678 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2680 return NT_STATUS_OK;
2683 /*************************************************************************
2685 *************************************************************************/
2687 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2688 struct samr_UserInfo11 *r,
2691 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2693 return NT_STATUS_OK;
2696 /*************************************************************************
2698 *************************************************************************/
2700 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2701 struct samr_UserInfo12 *r,
2704 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2706 return NT_STATUS_OK;
2709 /*************************************************************************
2711 *************************************************************************/
2713 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2714 struct samr_UserInfo13 *r,
2717 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2719 return NT_STATUS_OK;
2722 /*************************************************************************
2724 *************************************************************************/
2726 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2727 struct samr_UserInfo14 *r,
2730 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2732 return NT_STATUS_OK;
2735 /*************************************************************************
2736 get_user_info_16. Safe. Only gives out acb bits.
2737 *************************************************************************/
2739 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2740 struct samr_UserInfo16 *r,
2741 struct samu *smbpass)
2743 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2745 return NT_STATUS_OK;
2748 /*************************************************************************
2750 *************************************************************************/
2752 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2753 struct samr_UserInfo17 *r,
2756 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2758 return NT_STATUS_OK;
2761 /*************************************************************************
2762 get_user_info_18. OK - this is the killer as it gives out password info.
2763 Ensure that this is only allowed on an encrypted connection with a root
2765 *************************************************************************/
2767 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2768 TALLOC_CTX *mem_ctx,
2769 struct samr_UserInfo18 *r,
2770 struct dom_sid *user_sid)
2772 struct samu *smbpass=NULL;
2774 const uint8_t *nt_pass = NULL;
2775 const uint8_t *lm_pass = NULL;
2779 if (p->server_info->system) {
2783 if ((p->auth.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) ||
2784 (p->auth.auth_type != DCERPC_AUTH_TYPE_KRB5) ||
2785 (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO)) {
2786 return NT_STATUS_ACCESS_DENIED;
2789 if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2790 return NT_STATUS_ACCESS_DENIED;
2795 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2798 if ( !(smbpass = samu_new( mem_ctx )) ) {
2799 return NT_STATUS_NO_MEMORY;
2802 ret = pdb_getsampwsid(smbpass, user_sid);
2805 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2806 TALLOC_FREE(smbpass);
2807 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2810 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2812 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2813 TALLOC_FREE(smbpass);
2814 return NT_STATUS_ACCOUNT_DISABLED;
2817 lm_pass = pdb_get_lanman_passwd(smbpass);
2818 if (lm_pass != NULL) {
2819 memcpy(r->lm_pwd.hash, lm_pass, 16);
2820 r->lm_pwd_active = true;
2823 nt_pass = pdb_get_nt_passwd(smbpass);
2824 if (nt_pass != NULL) {
2825 memcpy(r->nt_pwd.hash, nt_pass, 16);
2826 r->nt_pwd_active = true;
2828 r->password_expired = 0; /* FIXME */
2830 TALLOC_FREE(smbpass);
2832 return NT_STATUS_OK;
2835 /*************************************************************************
2837 *************************************************************************/
2839 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2840 struct samr_UserInfo20 *r,
2841 struct samu *sampass)
2843 const char *munged_dial = NULL;
2846 struct lsa_BinaryString *parameters = NULL;
2850 munged_dial = pdb_get_munged_dial(sampass);
2852 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2853 munged_dial, (int)strlen(munged_dial)));
2856 blob = base64_decode_data_blob(munged_dial);
2858 blob = data_blob_string_const_null("");
2861 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2862 data_blob_free(&blob);
2863 if (!NT_STATUS_IS_OK(status)) {
2867 r->parameters = *parameters;
2869 return NT_STATUS_OK;
2873 /*************************************************************************
2875 *************************************************************************/
2877 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2878 struct samr_UserInfo21 *r,
2880 struct dom_sid *domain_sid,
2881 uint32_t acc_granted)
2884 const struct dom_sid *sid_user, *sid_group;
2885 uint32_t rid, primary_gid;
2886 NTTIME force_password_change;
2887 time_t must_change_time;
2888 struct lsa_BinaryString *parameters = NULL;
2889 const char *munged_dial = NULL;
2894 sid_user = pdb_get_user_sid(pw);
2896 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2897 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2898 "the domain sid %s. Failing operation.\n",
2899 pdb_get_username(pw), sid_string_dbg(sid_user),
2900 sid_string_dbg(domain_sid)));
2901 return NT_STATUS_UNSUCCESSFUL;
2905 sid_group = pdb_get_group_sid(pw);
2908 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2909 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2910 "which conflicts with the domain sid %s. Failing operation.\n",
2911 pdb_get_username(pw), sid_string_dbg(sid_group),
2912 sid_string_dbg(domain_sid)));
2913 return NT_STATUS_UNSUCCESSFUL;
2916 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2917 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2918 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2919 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2920 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2922 must_change_time = pdb_get_pass_must_change_time(pw);
2923 if (must_change_time == get_time_t_max()) {
2924 unix_to_nt_time_abs(&force_password_change, must_change_time);
2926 unix_to_nt_time(&force_password_change, must_change_time);
2929 munged_dial = pdb_get_munged_dial(pw);
2931 blob = base64_decode_data_blob(munged_dial);
2933 blob = data_blob_string_const_null("");
2936 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2937 data_blob_free(&blob);
2938 if (!NT_STATUS_IS_OK(status)) {
2942 r->force_password_change = force_password_change;
2944 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2945 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2946 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2947 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2948 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2949 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2950 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2951 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2952 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2954 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2955 r->parameters = *parameters;
2957 r->primary_gid = primary_gid;
2958 r->acct_flags = pdb_get_acct_ctrl(pw);
2959 r->bad_password_count = pdb_get_bad_password_count(pw);
2960 r->logon_count = pdb_get_logon_count(pw);
2961 r->fields_present = pdb_build_fields_present(pw);
2962 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2963 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2964 r->country_code = 0;
2966 r->lm_password_set = 0;
2967 r->nt_password_set = 0;
2972 Look at a user on a real NT4 PDC with usrmgr, press
2973 'ok'. Then you will see that fields_present is set to
2974 0x08f827fa. Look at the user immediately after that again,
2975 and you will see that 0x00fffff is returned. This solves
2976 the problem that you get access denied after having looked
2984 return NT_STATUS_OK;
2987 /*******************************************************************
2989 ********************************************************************/
2991 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
2992 struct samr_QueryUserInfo *r)
2995 union samr_UserInfo *user_info = NULL;
2996 struct samr_user_info *uinfo;
2997 struct dom_sid domain_sid;
3000 struct samu *pwd = NULL;
3001 uint32_t acc_required, acc_granted;
3003 switch (r->in.level) {
3004 case 1: /* UserGeneralInformation */
3005 /* USER_READ_GENERAL */
3006 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3008 case 2: /* UserPreferencesInformation */
3009 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
3010 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
3011 SAMR_USER_ACCESS_GET_NAME_ETC;
3013 case 3: /* UserLogonInformation */
3014 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3015 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3016 SAMR_USER_ACCESS_GET_LOCALE |
3017 SAMR_USER_ACCESS_GET_LOGONINFO |
3018 SAMR_USER_ACCESS_GET_ATTRIBUTES;
3020 case 4: /* UserLogonHoursInformation */
3021 /* USER_READ_LOGON */
3022 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3024 case 5: /* UserAccountInformation */
3025 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3026 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3027 SAMR_USER_ACCESS_GET_LOCALE |
3028 SAMR_USER_ACCESS_GET_LOGONINFO |
3029 SAMR_USER_ACCESS_GET_ATTRIBUTES;
3031 case 6: /* UserNameInformation */
3032 case 7: /* UserAccountNameInformation */
3033 case 8: /* UserFullNameInformation */
3034 case 9: /* UserPrimaryGroupInformation */
3035 case 13: /* UserAdminCommentInformation */
3036 /* USER_READ_GENERAL */
3037 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3039 case 10: /* UserHomeInformation */
3040 case 11: /* UserScriptInformation */
3041 case 12: /* UserProfileInformation */
3042 case 14: /* UserWorkStationsInformation */
3043 /* USER_READ_LOGON */
3044 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3046 case 16: /* UserControlInformation */
3047 case 17: /* UserExpiresInformation */
3048 case 20: /* UserParametersInformation */
3049 /* USER_READ_ACCOUNT */
3050 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3052 case 21: /* UserAllInformation */
3054 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3056 case 18: /* UserInternal1Information */
3058 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3060 case 23: /* UserInternal4Information */
3061 case 24: /* UserInternal4InformationNew */
3062 case 25: /* UserInternal4InformationNew */
3063 case 26: /* UserInternal5InformationNew */
3065 return NT_STATUS_INVALID_INFO_CLASS;
3069 uinfo = policy_handle_find(p, r->in.user_handle,
3070 acc_required, &acc_granted,
3071 struct samr_user_info, &status);
3072 if (!NT_STATUS_IS_OK(status)) {
3076 domain_sid = uinfo->sid;
3078 sid_split_rid(&domain_sid, &rid);
3080 if (!sid_check_is_in_our_domain(&uinfo->sid))
3081 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3083 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3084 sid_string_dbg(&uinfo->sid)));
3086 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3088 return NT_STATUS_NO_MEMORY;
3091 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3093 if (!(pwd = samu_new(p->mem_ctx))) {
3094 return NT_STATUS_NO_MEMORY;
3098 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3102 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3104 return NT_STATUS_NO_SUCH_USER;
3107 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3109 samr_clear_sam_passwd(pwd);
3111 switch (r->in.level) {
3113 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3116 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3119 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3122 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3125 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3128 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3131 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3134 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3137 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3140 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3143 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3146 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3149 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3152 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3155 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3158 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3161 /* level 18 is special */
3162 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3166 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3169 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3172 status = NT_STATUS_INVALID_INFO_CLASS;
3176 if (!NT_STATUS_IS_OK(status)) {
3180 *r->out.info = user_info;
3185 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3190 /****************************************************************
3191 ****************************************************************/
3193 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3194 struct samr_QueryUserInfo2 *r)
3196 struct samr_QueryUserInfo u;
3198 u.in.user_handle = r->in.user_handle;
3199 u.in.level = r->in.level;
3200 u.out.info = r->out.info;
3202 return _samr_QueryUserInfo(p, &u);
3205 /*******************************************************************
3206 _samr_GetGroupsForUser
3207 ********************************************************************/
3209 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3210 struct samr_GetGroupsForUser *r)
3212 struct samr_user_info *uinfo;
3213 struct samu *sam_pass=NULL;
3214 struct dom_sid *sids;
3215 struct samr_RidWithAttribute dom_gid;
3216 struct samr_RidWithAttribute *gids = NULL;
3217 uint32 primary_group_rid;
3218 size_t num_groups = 0;
3223 bool success = False;
3225 struct samr_RidWithAttributeArray *rids = NULL;
3228 * from the SID in the request:
3229 * we should send back the list of DOMAIN GROUPS
3230 * the user is a member of
3232 * and only the DOMAIN GROUPS
3233 * no ALIASES !!! neither aliases of the domain
3234 * nor aliases of the builtin SID
3239 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3241 uinfo = policy_handle_find(p, r->in.user_handle,
3242 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3243 struct samr_user_info, &result);
3244 if (!NT_STATUS_IS_OK(result)) {
3248 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3250 return NT_STATUS_NO_MEMORY;
3253 if (!sid_check_is_in_our_domain(&uinfo->sid))
3254 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3256 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3257 return NT_STATUS_NO_MEMORY;
3261 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3265 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3266 sid_string_dbg(&uinfo->sid)));
3267 return NT_STATUS_NO_SUCH_USER;
3272 /* make both calls inside the root block */
3274 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3275 &sids, &unix_gids, &num_groups);
3276 if ( NT_STATUS_IS_OK(result) ) {
3277 success = sid_peek_check_rid(get_global_sam_sid(),
3278 pdb_get_group_sid(sam_pass),
3279 &primary_group_rid);
3283 if (!NT_STATUS_IS_OK(result)) {
3284 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3285 sid_string_dbg(&uinfo->sid)));
3290 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3291 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3292 pdb_get_username(sam_pass)));
3293 TALLOC_FREE(sam_pass);
3294 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3300 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3302 dom_gid.rid = primary_group_rid;
3303 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3305 for (i=0; i<num_groups; i++) {
3307 if (!sid_peek_check_rid(get_global_sam_sid(),
3308 &(sids[i]), &dom_gid.rid)) {
3309 DEBUG(10, ("Found sid %s not in our domain\n",
3310 sid_string_dbg(&sids[i])));
3314 if (dom_gid.rid == primary_group_rid) {
3315 /* We added the primary group directly from the
3316 * sam_account. The other SIDs are unique from
3317 * enum_group_memberships */
3321 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3324 rids->count = num_gids;
3327 *r->out.rids = rids;
3329 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3334 /*******************************************************************
3335 ********************************************************************/
3337 static uint32_t samr_get_server_role(void)
3339 uint32_t role = ROLE_DOMAIN_PDC;
3341 if (lp_server_role() == ROLE_DOMAIN_BDC) {
3342 role = ROLE_DOMAIN_BDC;
3348 /*******************************************************************
3349 ********************************************************************/
3351 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3352 struct samr_DomInfo1 *r)
3354 uint32_t account_policy_temp;
3355 time_t u_expire, u_min_age;
3361 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3362 r->min_password_length = account_policy_temp;
3364 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3365 r->password_history_length = account_policy_temp;
3367 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3368 &r->password_properties);
3370 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3371 u_expire = account_policy_temp;
3373 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3374 u_min_age = account_policy_temp;
3380 unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3381 unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3383 if (lp_check_password_script() && *lp_check_password_script()) {
3384 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3387 return NT_STATUS_OK;
3390 /*******************************************************************
3391 ********************************************************************/
3393 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3394 struct samr_DomGeneralInformation *r,
3395 struct samr_domain_info *dinfo)
3404 r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3405 r->num_groups = count_sam_groups(dinfo->disp_info);
3406 r->num_aliases = count_sam_aliases(dinfo->disp_info);
3408 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3410 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3412 if (!pdb_get_seq_num(&seq_num)) {
3413 seq_num = time(NULL);
3420 r->oem_information.string = lp_serverstring();
3421 r->domain_name.string = lp_workgroup();
3422 r->primary.string = global_myname();
3423 r->sequence_num = seq_num;
3424 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3425 r->role = (enum samr_Role) samr_get_server_role();
3428 return NT_STATUS_OK;
3431 /*******************************************************************
3432 ********************************************************************/
3434 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3435 struct samr_DomInfo3 *r)
3445 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3446 u_logout = (time_t)ul;
3453 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3455 return NT_STATUS_OK;
3458 /*******************************************************************
3459 ********************************************************************/
3461 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3462 struct samr_DomOEMInformation *r)
3464 r->oem_information.string = lp_serverstring();
3466 return NT_STATUS_OK;
3469 /*******************************************************************
3470 ********************************************************************/
3472 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3473 struct samr_DomInfo5 *r)
3475 r->domain_name.string = get_global_sam_name();
3477 return NT_STATUS_OK;
3480 /*******************************************************************
3481 ********************************************************************/
3483 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3484 struct samr_DomInfo6 *r)
3486 /* NT returns its own name when a PDC. win2k and later
3487 * only the name of the PDC if itself is a BDC (samba4
3489 r->primary.string = global_myname();
3491 return NT_STATUS_OK;
3494 /*******************************************************************
3495 ********************************************************************/
3497 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3498 struct samr_DomInfo7 *r)
3500 r->role = (enum samr_Role) samr_get_server_role();
3502 return NT_STATUS_OK;
3505 /*******************************************************************
3506 ********************************************************************/
3508 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3509 struct samr_DomInfo8 *r)
3517 if (!pdb_get_seq_num(&seq_num)) {
3518 seq_num = time(NULL);
3525 r->sequence_num = seq_num;
3526 r->domain_create_time = 0;
3528 return NT_STATUS_OK;
3531 /*******************************************************************
3532 ********************************************************************/
3534 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3535 struct samr_DomInfo9 *r)
3537 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3539 return NT_STATUS_OK;
3542 /*******************************************************************
3543 ********************************************************************/
3545 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3546 struct samr_DomGeneralInformation2 *r,
3547 struct samr_domain_info *dinfo)
3550 uint32_t account_policy_temp;
3551 time_t u_lock_duration, u_reset_time;
3553 status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3554 if (!NT_STATUS_IS_OK(status)) {
3562 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3563 u_lock_duration = account_policy_temp;
3564 if (u_lock_duration != -1) {
3565 u_lock_duration *= 60;
3568 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3569 u_reset_time = account_policy_temp * 60;
3571 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3572 r->lockout_threshold = account_policy_temp;
3578 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3579 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3581 return NT_STATUS_OK;
3584 /*******************************************************************
3585 ********************************************************************/
3587 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3588 struct samr_DomInfo12 *r)
3590 uint32_t account_policy_temp;
3591 time_t u_lock_duration, u_reset_time;
3597 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3598 u_lock_duration = account_policy_temp;
3599 if (u_lock_duration != -1) {
3600 u_lock_duration *= 60;
3603 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3604 u_reset_time = account_policy_temp * 60;
3606 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3607 r->lockout_threshold = account_policy_temp;
3613 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3614 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3616 return NT_STATUS_OK;
3619 /*******************************************************************
3620 ********************************************************************/
3622 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3623 struct samr_DomInfo13 *r)
3631 if (!pdb_get_seq_num(&seq_num)) {
3632 seq_num = time(NULL);
3639 r->sequence_num = seq_num;
3640 r->domain_create_time = 0;
3641 r->modified_count_at_last_promotion = 0;
3643 return NT_STATUS_OK;
3646 /*******************************************************************
3647 _samr_QueryDomainInfo
3648 ********************************************************************/
3650 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3651 struct samr_QueryDomainInfo *r)
3653 NTSTATUS status = NT_STATUS_OK;
3654 struct samr_domain_info *dinfo;
3655 union samr_DomainInfo *dom_info;
3657 uint32_t acc_required;
3659 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3661 switch (r->in.level) {
3662 case 1: /* DomainPasswordInformation */
3663 case 12: /* DomainLockoutInformation */
3664 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3665 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3667 case 11: /* DomainGeneralInformation2 */
3668 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3669 * DOMAIN_READ_OTHER_PARAMETERS */
3670 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3671 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3673 case 2: /* DomainGeneralInformation */
3674 case 3: /* DomainLogoffInformation */
3675 case 4: /* DomainOemInformation */
3676 case 5: /* DomainReplicationInformation */
3677 case 6: /* DomainReplicationInformation */
3678 case 7: /* DomainServerRoleInformation */
3679 case 8: /* DomainModifiedInformation */
3680 case 9: /* DomainStateInformation */
3681 case 10: /* DomainUasInformation */
3682 case 13: /* DomainModifiedInformation2 */
3683 /* DOMAIN_READ_OTHER_PARAMETERS */
3684 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3687 return NT_STATUS_INVALID_INFO_CLASS;
3690 dinfo = policy_handle_find(p, r->in.domain_handle,
3692 struct samr_domain_info, &status);
3693 if (!NT_STATUS_IS_OK(status)) {
3697 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3699 return NT_STATUS_NO_MEMORY;
3702 switch (r->in.level) {
3704 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3707 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3710 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3713 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3716 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3719 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3722 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3725 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3728 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3731 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3734 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3737 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3740 return NT_STATUS_INVALID_INFO_CLASS;
3743 if (!NT_STATUS_IS_OK(status)) {
3747 *r->out.info = dom_info;
3749 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3754 /* W2k3 seems to use the same check for all 3 objects that can be created via
3755 * SAMR, if you try to create for example "Dialup" as an alias it says
3756 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3759 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3761 enum lsa_SidType type;
3764 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3767 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3768 * whether the name already exists */
3769 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3770 NULL, NULL, NULL, &type);
3774 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3775 return NT_STATUS_OK;
3778 DEBUG(5, ("trying to create %s, exists as %s\n",
3779 new_name, sid_type_lookup(type)));
3781 if (type == SID_NAME_DOM_GRP) {
3782 return NT_STATUS_GROUP_EXISTS;
3784 if (type == SID_NAME_ALIAS) {
3785 return NT_STATUS_ALIAS_EXISTS;
3788 /* Yes, the default is NT_STATUS_USER_EXISTS */
3789 return NT_STATUS_USER_EXISTS;
3792 /*******************************************************************
3794 ********************************************************************/
3796 NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3797 struct samr_CreateUser2 *r)
3799 const char *account = NULL;
3801 uint32_t acb_info = r->in.acct_flags;
3802 struct samr_domain_info *dinfo;
3803 struct samr_user_info *uinfo;
3806 struct security_descriptor *psd;
3808 /* check this, when giving away 'add computer to domain' privs */
3809 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3810 bool can_add_account = False;
3812 /* Which privilege is needed to override the ACL? */
3813 enum sec_privilege needed_priv = SEC_PRIV_INVALID;
3815 dinfo = policy_handle_find(p, r->in.domain_handle,
3816 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3817 struct samr_domain_info, &nt_status);
3818 if (!NT_STATUS_IS_OK(nt_status)) {
3822 if (sid_check_is_builtin(&dinfo->sid)) {
3823 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3824 return NT_STATUS_ACCESS_DENIED;
3827 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3828 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3829 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3830 this parameter is not an account type */
3831 return NT_STATUS_INVALID_PARAMETER;
3834 account = r->in.account_name->string;
3835 if (account == NULL) {
3836 return NT_STATUS_NO_MEMORY;
3839 nt_status = can_create(p->mem_ctx, account);
3840 if (!NT_STATUS_IS_OK(nt_status)) {
3844 /* determine which user right we need to check based on the acb_info */
3846 if (geteuid() == sec_initial_uid()) {
3847 can_add_account = true;
3848 } else if (acb_info & ACB_WSTRUST) {
3849 needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
3850 can_add_account = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_MACHINE_ACCOUNT);
3851 } else if (acb_info & ACB_NORMAL &&
3852 (account[strlen(account)-1] != '$')) {
3853 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3854 account for domain trusts and changes the ACB flags later */
3855 needed_priv = SEC_PRIV_ADD_USERS;
3856 can_add_account = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_ADD_USERS);
3857 } else if (lp_enable_privileges()) {
3858 /* implicit assumption of a BDC or domain trust account here
3859 * (we already check the flags earlier) */
3860 /* only Domain Admins can add a BDC or domain trust */
3861 can_add_account = nt_token_check_domain_rid(
3862 p->server_info->ptok,
3863 DOMAIN_RID_ADMINS );
3866 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3867 uidtoname(p->server_info->utok.uid),
3868 can_add_account ? "True":"False" ));
3870 if (!can_add_account) {
3871 return NT_STATUS_ACCESS_DENIED;
3874 /********** BEGIN Admin BLOCK **********/
3877 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3881 /********** END Admin BLOCK **********/
3883 /* now check for failure */
3885 if ( !NT_STATUS_IS_OK(nt_status) )
3888 /* Get the user's SID */
3890 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3892 map_max_allowed_access(p->server_info->ptok,
3893 &p->server_info->utok,
3896 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3897 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3898 se_map_generic(&des_access, &usr_generic_mapping);
3901 * JRA - TESTME. We just created this user so we
3902 * had rights to create them. Do we need to check
3903 * any further access on this object ? Can't we
3904 * just assume we have all the rights we need ?
3907 nt_status = access_check_object(psd, p->server_info->ptok,
3908 needed_priv, SEC_PRIV_INVALID,
3909 GENERIC_RIGHTS_USER_WRITE, des_access,
3910 &acc_granted, "_samr_CreateUser2");
3912 if ( !NT_STATUS_IS_OK(nt_status) ) {
3916 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3917 struct samr_user_info, &nt_status);
3918 if (!NT_STATUS_IS_OK(nt_status)) {
3923 /* After a "set" ensure we have no cached display info. */
3924 force_flush_samr_cache(&sid);
3926 *r->out.access_granted = acc_granted;
3928 return NT_STATUS_OK;
3931 /****************************************************************
3932 ****************************************************************/
3934 NTSTATUS _samr_CreateUser(struct pipes_struct *p,
3935 struct samr_CreateUser *r)
3937 struct samr_CreateUser2 c;
3938 uint32_t access_granted;
3940 c.in.domain_handle = r->in.domain_handle;
3941 c.in.account_name = r->in.account_name;
3942 c.in.acct_flags = ACB_NORMAL;
3943 c.in.access_mask = r->in.access_mask;
3944 c.out.user_handle = r->out.user_handle;
3945 c.out.access_granted = &access_granted;
3946 c.out.rid = r->out.rid;
3948 return _samr_CreateUser2(p, &c);
3951 /*******************************************************************
3953 ********************************************************************/
3955 NTSTATUS _samr_Connect(struct pipes_struct *p,
3956 struct samr_Connect *r)
3958 struct samr_connect_info *info;
3959 uint32_t acc_granted;
3960 struct policy_handle hnd;
3961 uint32 des_access = r->in.access_mask;
3966 if (!pipe_access_check(p)) {
3967 DEBUG(3, ("access denied to _samr_Connect\n"));
3968 return NT_STATUS_ACCESS_DENIED;
3971 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3972 was observed from a win98 client trying to enumerate users (when configured
3973 user level access control on shares) --jerry */
3975 map_max_allowed_access(p->server_info->ptok,
3976 &p->server_info->utok,
3979 se_map_generic( &des_access, &sam_generic_mapping );
3981 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3982 |SAMR_ACCESS_LOOKUP_DOMAIN);
3984 /* set up the SAMR connect_anon response */
3986 info = policy_handle_create(p, &hnd, acc_granted,
3987 struct samr_connect_info,
3989 if (!NT_STATUS_IS_OK(status)) {
3993 *r->out.connect_handle = hnd;
3994 return NT_STATUS_OK;
3997 /*******************************************************************
3999 ********************************************************************/
4001 NTSTATUS _samr_Connect2(struct pipes_struct *p,
4002 struct samr_Connect2 *r)
4004 struct samr_connect_info *info = NULL;
4005 struct policy_handle hnd;
4006 struct security_descriptor *psd = NULL;
4008 uint32 des_access = r->in.access_mask;
4011 const char *fn = "_samr_Connect2";
4014 case NDR_SAMR_CONNECT2:
4015 fn = "_samr_Connect2";
4017 case NDR_SAMR_CONNECT3:
4018 fn = "_samr_Connect3";
4020 case NDR_SAMR_CONNECT4:
4021 fn = "_samr_Connect4";
4023 case NDR_SAMR_CONNECT5:
4024 fn = "_samr_Connect5";
4028 DEBUG(5,("%s: %d\n", fn, __LINE__));
4032 if (!pipe_access_check(p)) {
4033 DEBUG(3, ("access denied to %s\n", fn));
4034 return NT_STATUS_ACCESS_DENIED;
4037 map_max_allowed_access(p->server_info->ptok,
4038 &p->server_info->utok,
4041 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
4042 se_map_generic(&des_access, &sam_generic_mapping);
4044 nt_status = access_check_object(psd, p->server_info->ptok,
4045 SEC_PRIV_INVALID, SEC_PRIV_INVALID,
4046 0, des_access, &acc_granted, fn);
4048 if ( !NT_STATUS_IS_OK(nt_status) )
4051 info = policy_handle_create(p, &hnd, acc_granted,
4052 struct samr_connect_info, &nt_status);
4053 if (!NT_STATUS_IS_OK(nt_status)) {
4057 DEBUG(5,("%s: %d\n", fn, __LINE__));
4059 *r->out.connect_handle = hnd;
4060 return NT_STATUS_OK;
4063 /****************************************************************
4065 ****************************************************************/
4067 NTSTATUS _samr_Connect3(struct pipes_struct *p,
4068 struct samr_Connect3 *r)
4070 struct samr_Connect2 c;
4072 c.in.system_name = r->in.system_name;
4073 c.in.access_mask = r->in.access_mask;
4074 c.out.connect_handle = r->out.connect_handle;
4076 return _samr_Connect2(p, &c);
4079 /*******************************************************************
4081 ********************************************************************/
4083 NTSTATUS _samr_Connect4(struct pipes_struct *p,
4084 struct samr_Connect4 *r)
4086 struct samr_Connect2 c;
4088 c.in.system_name = r->in.system_name;
4089 c.in.access_mask = r->in.access_mask;
4090 c.out.connect_handle = r->out.connect_handle;
4092 return _samr_Connect2(p, &c);
4095 /*******************************************************************
4097 ********************************************************************/
4099 NTSTATUS _samr_Connect5(struct pipes_struct *p,
4100 struct samr_Connect5 *r)
4103 struct samr_Connect2 c;
4104 struct samr_ConnectInfo1 info1;
4106 info1.client_version = SAMR_CONNECT_AFTER_W2K;
4109 c.in.system_name = r->in.system_name;
4110 c.in.access_mask = r->in.access_mask;
4111 c.out.connect_handle = r->out.connect_handle;
4113 *r->out.level_out = 1;
4115 status = _samr_Connect2(p, &c);
4116 if (!NT_STATUS_IS_OK(status)) {
4120 r->out.info_out->info1 = info1;
4122 return NT_STATUS_OK;
4125 /**********************************************************************
4127 **********************************************************************/
4129 NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
4130 struct samr_LookupDomain *r)
4133 struct samr_connect_info *info;
4134 const char *domain_name;
4135 struct dom_sid *sid = NULL;
4137 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4138 Reverted that change so we will work with RAS servers again */
4140 info = policy_handle_find(p, r->in.connect_handle,
4141 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4142 struct samr_connect_info,
4144 if (!NT_STATUS_IS_OK(status)) {
4148 domain_name = r->in.domain_name->string;
4150 return NT_STATUS_INVALID_PARAMETER;
4153 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
4155 return NT_STATUS_NO_MEMORY;
4158 if (strequal(domain_name, builtin_domain_name())) {
4159 sid_copy(sid, &global_sid_Builtin);
4161 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4162 status = NT_STATUS_NO_SUCH_DOMAIN;
4166 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4167 sid_string_dbg(sid)));
4174 /**********************************************************************
4176 **********************************************************************/
4178 NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4179 struct samr_EnumDomains *r)
4182 struct samr_connect_info *info;
4183 uint32_t num_entries = 2;
4184 struct samr_SamEntry *entry_array = NULL;
4185 struct samr_SamArray *sam;
4187 info = policy_handle_find(p, r->in.connect_handle,
4188 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4189 struct samr_connect_info, &status);
4190 if (!NT_STATUS_IS_OK(status)) {
4194 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4196 return NT_STATUS_NO_MEMORY;
4199 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4200 struct samr_SamEntry,
4203 return NT_STATUS_NO_MEMORY;
4206 entry_array[0].idx = 0;
4207 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4209 entry_array[1].idx = 1;
4210 init_lsa_String(&entry_array[1].name, "Builtin");
4212 sam->count = num_entries;
4213 sam->entries = entry_array;
4216 *r->out.num_entries = num_entries;
4221 /*******************************************************************
4223 ********************************************************************/
4225 NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4226 struct samr_OpenAlias *r)
4229 uint32 alias_rid = r->in.rid;
4230 struct samr_alias_info *ainfo;
4231 struct samr_domain_info *dinfo;
4232 struct security_descriptor *psd = NULL;
4234 uint32 des_access = r->in.access_mask;
4238 dinfo = policy_handle_find(p, r->in.domain_handle,
4239 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4240 struct samr_domain_info, &status);
4241 if (!NT_STATUS_IS_OK(status)) {
4245 /* append the alias' RID to it */
4247 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4248 return NT_STATUS_NO_SUCH_ALIAS;
4250 /*check if access can be granted as requested by client. */
4252 map_max_allowed_access(p->server_info->ptok,
4253 &p->server_info->utok,
4256 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4257 se_map_generic(&des_access,&ali_generic_mapping);
4259 status = access_check_object(psd, p->server_info->ptok,
4260 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
4261 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4262 des_access, &acc_granted, "_samr_OpenAlias");
4264 if ( !NT_STATUS_IS_OK(status) )
4268 /* Check we actually have the requested alias */
4269 enum lsa_SidType type;
4274 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4277 if (!result || (type != SID_NAME_ALIAS)) {
4278 return NT_STATUS_NO_SUCH_ALIAS;
4281 /* make sure there is a mapping */
4283 if ( !sid_to_gid( &sid, &gid ) ) {
4284 return NT_STATUS_NO_SUCH_ALIAS;
4289 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4290 struct samr_alias_info, &status);
4291 if (!NT_STATUS_IS_OK(status)) {
4296 return NT_STATUS_OK;
4299 /*******************************************************************
4301 ********************************************************************/
4303 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4304 struct samr_UserInfo2 *id2,
4308 DEBUG(5,("set_user_info_2: NULL id2\n"));
4309 return NT_STATUS_ACCESS_DENIED;
4312 copy_id2_to_sam_passwd(pwd, id2);
4314 return pdb_update_sam_account(pwd);
4317 /*******************************************************************
4319 ********************************************************************/
4321 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4322 struct samr_UserInfo4 *id4,
4326 DEBUG(5,("set_user_info_2: NULL id4\n"));
4327 return NT_STATUS_ACCESS_DENIED;
4330 copy_id4_to_sam_passwd(pwd, id4);
4332 return pdb_update_sam_account(pwd);
4335 /*******************************************************************
4337 ********************************************************************/
4339 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4340 struct samr_UserInfo6 *id6,
4344 DEBUG(5,("set_user_info_6: NULL id6\n"));
4345 return NT_STATUS_ACCESS_DENIED;
4348 copy_id6_to_sam_passwd(pwd, id6);
4350 return pdb_update_sam_account(pwd);
4353 /*******************************************************************
4355 ********************************************************************/
4357 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4358 struct samr_UserInfo7 *id7,
4364 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4365 return NT_STATUS_ACCESS_DENIED;
4368 if (!id7->account_name.string) {
4369 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4370 return NT_STATUS_ACCESS_DENIED;
4373 /* check to see if the new username already exists. Note: we can't
4374 reliably lock all backends, so there is potentially the
4375 possibility that a user can be created in between this check and
4376 the rename. The rename should fail, but may not get the
4377 exact same failure status code. I think this is small enough
4378 of a window for this type of operation and the results are
4379 simply that the rename fails with a slightly different status
4380 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4382 rc = can_create(mem_ctx, id7->account_name.string);
4384 /* when there is nothing to change, we're done here */
4385 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4386 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4387 return NT_STATUS_OK;
4389 if (!NT_STATUS_IS_OK(rc)) {
4393 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4398 /*******************************************************************
4400 ********************************************************************/
4402 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4403 struct samr_UserInfo8 *id8,
4407 DEBUG(5,("set_user_info_8: NULL id8\n"));
4408 return NT_STATUS_ACCESS_DENIED;
4411 copy_id8_to_sam_passwd(pwd, id8);
4413 return pdb_update_sam_account(pwd);
4416 /*******************************************************************
4418 ********************************************************************/
4420 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4421 struct samr_UserInfo10 *id10,
4425 DEBUG(5,("set_user_info_8: NULL id10\n"));
4426 return NT_STATUS_ACCESS_DENIED;
4429 copy_id10_to_sam_passwd(pwd, id10);
4431 return pdb_update_sam_account(pwd);
4434 /*******************************************************************
4436 ********************************************************************/
4438 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4439 struct samr_UserInfo11 *id11,
4443 DEBUG(5,("set_user_info_11: NULL id11\n"));
4444 return NT_STATUS_ACCESS_DENIED;
4447 copy_id11_to_sam_passwd(pwd, id11);
4449 return pdb_update_sam_account(pwd);
4452 /*******************************************************************
4454 ********************************************************************/
4456 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4457 struct samr_UserInfo12 *id12,
4461 DEBUG(5,("set_user_info_12: NULL id12\n"));
4462 return NT_STATUS_ACCESS_DENIED;
4465 copy_id12_to_sam_passwd(pwd, id12);
4467 return pdb_update_sam_account(pwd);
4470 /*******************************************************************
4472 ********************************************************************/
4474 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4475 struct samr_UserInfo13 *id13,
4479 DEBUG(5,("set_user_info_13: NULL id13\n"));
4480 return NT_STATUS_ACCESS_DENIED;
4483 copy_id13_to_sam_passwd(pwd, id13);
4485 return pdb_update_sam_account(pwd);
4488 /*******************************************************************
4490 ********************************************************************/
4492 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4493 struct samr_UserInfo14 *id14,
4497 DEBUG(5,("set_user_info_14: NULL id14\n"));
4498 return NT_STATUS_ACCESS_DENIED;
4501 copy_id14_to_sam_passwd(pwd, id14);
4503 return pdb_update_sam_account(pwd);
4506 /*******************************************************************
4508 ********************************************************************/
4510 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4511 struct samr_UserInfo16 *id16,
4515 DEBUG(5,("set_user_info_16: NULL id16\n"));
4516 return NT_STATUS_ACCESS_DENIED;
4519 copy_id16_to_sam_passwd(pwd, id16);
4521 return pdb_update_sam_account(pwd);
4524 /*******************************************************************
4526 ********************************************************************/
4528 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4529 struct samr_UserInfo17 *id17,
4533 DEBUG(5,("set_user_info_17: NULL id17\n"));
4534 return NT_STATUS_ACCESS_DENIED;
4537 copy_id17_to_sam_passwd(pwd, id17);
4539 return pdb_update_sam_account(pwd);
4542 /*******************************************************************
4544 ********************************************************************/
4546 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4547 TALLOC_CTX *mem_ctx,
4548 DATA_BLOB *session_key,
4552 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4553 return NT_STATUS_INVALID_PARAMETER;
4556 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4557 if (!session_key->length) {
4558 return NT_STATUS_NO_USER_SESSION_KEY;
4562 if (id18->nt_pwd_active) {
4566 in = data_blob_const(id18->nt_pwd.hash, 16);
4567 out = data_blob_talloc_zero(mem_ctx, 16);
4569 sess_crypt_blob(&out, &in, session_key, false);
4571 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4572 return NT_STATUS_ACCESS_DENIED;
4575 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4578 if (id18->lm_pwd_active) {
4582 in = data_blob_const(id18->lm_pwd.hash, 16);
4583 out = data_blob_talloc_zero(mem_ctx, 16);
4585 sess_crypt_blob(&out, &in, session_key, false);
4587 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4588 return NT_STATUS_ACCESS_DENIED;
4591 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4594 copy_id18_to_sam_passwd(pwd, id18);
4596 return pdb_update_sam_account(pwd);
4599 /*******************************************************************
4601 ********************************************************************/
4603 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4604 struct samr_UserInfo20 *id20,
4608 DEBUG(5,("set_user_info_20: NULL id20\n"));
4609 return NT_STATUS_ACCESS_DENIED;
4612 copy_id20_to_sam_passwd(pwd, id20);
4614 return pdb_update_sam_account(pwd);
4617 /*******************************************************************
4619 ********************************************************************/
4621 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4622 TALLOC_CTX *mem_ctx,
4623 DATA_BLOB *session_key,
4629 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4630 return NT_STATUS_INVALID_PARAMETER;
4633 if (id21->fields_present == 0) {
4634 return NT_STATUS_INVALID_PARAMETER;
4637 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4638 return NT_STATUS_ACCESS_DENIED;
4641 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4642 if (id21->nt_password_set) {
4645 if ((id21->nt_owf_password.length != 16) ||
4646 (id21->nt_owf_password.size != 16)) {
4647 return NT_STATUS_INVALID_PARAMETER;
4650 if (!session_key->length) {
4651 return NT_STATUS_NO_USER_SESSION_KEY;
4654 in = data_blob_const(id21->nt_owf_password.array, 16);
4655 out = data_blob_talloc_zero(mem_ctx, 16);
4657 sess_crypt_blob(&out, &in, session_key, false);
4659 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4660 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4664 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4665 if (id21->lm_password_set) {
4668 if ((id21->lm_owf_password.length != 16) ||
4669 (id21->lm_owf_password.size != 16)) {
4670 return NT_STATUS_INVALID_PARAMETER;
4673 if (!session_key->length) {
4674 return NT_STATUS_NO_USER_SESSION_KEY;
4677 in = data_blob_const(id21->lm_owf_password.array, 16);
4678 out = data_blob_talloc_zero(mem_ctx, 16);
4680 sess_crypt_blob(&out, &in, session_key, false);
4682 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4683 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4687 /* we need to separately check for an account rename first */
4689 if (id21->account_name.string &&
4690 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4693 /* check to see if the new username already exists. Note: we can't
4694 reliably lock all backends, so there is potentially the
4695 possibility that a user can be created in between this check and
4696 the rename. The rename should fail, but may not get the
4697 exact same failure status code. I think this is small enough
4698 of a window for this type of operation and the results are
4699 simply that the rename fails with a slightly different status
4700 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4702 status = can_create(mem_ctx, id21->account_name.string);
4703 if (!NT_STATUS_IS_OK(status)) {
4707 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4709 if (!NT_STATUS_IS_OK(status)) {
4710 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4711 nt_errstr(status)));
4715 /* set the new username so that later
4716 functions can work on the new account */
4717 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4720 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4723 * The funny part about the previous two calls is
4724 * that pwd still has the password hashes from the
4725 * passdb entry. These have not been updated from
4726 * id21. I don't know if they need to be set. --jerry
4729 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4730 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4731 if ( !NT_STATUS_IS_OK(status) ) {
4736 /* Don't worry about writing out the user account since the
4737 primary group SID is generated solely from the user's Unix
4740 /* write the change out */
4741 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4745 return NT_STATUS_OK;
4748 /*******************************************************************
4750 ********************************************************************/
4752 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4753 struct samr_UserInfo23 *id23,
4757 char *plaintext_buf = NULL;
4763 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4764 return NT_STATUS_INVALID_PARAMETER;
4767 if (id23->info.fields_present == 0) {
4768 return NT_STATUS_INVALID_PARAMETER;
4771 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4772 return NT_STATUS_ACCESS_DENIED;
4775 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4776 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4778 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4779 pdb_get_username(pwd)));
4781 if (!decode_pw_buffer(mem_ctx,
4782 id23->password.data,
4786 return NT_STATUS_WRONG_PASSWORD;
4789 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4790 return NT_STATUS_ACCESS_DENIED;
4794 copy_id23_to_sam_passwd(pwd, id23);
4796 acct_ctrl = pdb_get_acct_ctrl(pwd);
4798 /* if it's a trust account, don't update /etc/passwd */
4799 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4800 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4801 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4802 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4803 } else if (plaintext_buf) {
4804 /* update the UNIX password */
4805 if (lp_unix_password_sync() ) {
4806 struct passwd *passwd;
4807 if (pdb_get_username(pwd) == NULL) {
4808 DEBUG(1, ("chgpasswd: User without name???\n"));
4809 return NT_STATUS_ACCESS_DENIED;
4812 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4813 if (passwd == NULL) {
4814 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4817 if(!chgpasswd(pdb_get_username(pwd), rhost,
4818 passwd, "", plaintext_buf, True)) {
4819 return NT_STATUS_ACCESS_DENIED;
4821 TALLOC_FREE(passwd);
4825 if (plaintext_buf) {
4826 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4829 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4830 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4835 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4839 return NT_STATUS_OK;
4842 /*******************************************************************
4844 ********************************************************************/
4846 static bool set_user_info_pw(uint8 *pass, const char *rhost, struct samu *pwd)
4849 char *plaintext_buf = NULL;
4852 DEBUG(5, ("Attempting administrator password change for user %s\n",
4853 pdb_get_username(pwd)));
4855 acct_ctrl = pdb_get_acct_ctrl(pwd);
4857 if (!decode_pw_buffer(talloc_tos(),
4865 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4869 /* if it's a trust account, don't update /etc/passwd */
4870 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4871 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4872 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4873 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4875 /* update the UNIX password */
4876 if (lp_unix_password_sync()) {
4877 struct passwd *passwd;
4879 if (pdb_get_username(pwd) == NULL) {
4880 DEBUG(1, ("chgpasswd: User without name???\n"));
4884 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4885 if (passwd == NULL) {
4886 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4889 if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
4890 "", plaintext_buf, True)) {
4893 TALLOC_FREE(passwd);
4897 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4899 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4904 /*******************************************************************
4906 ********************************************************************/
4908 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4910 struct samr_UserInfo24 *id24,
4916 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4917 return NT_STATUS_INVALID_PARAMETER;
4920 if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
4921 return NT_STATUS_WRONG_PASSWORD;
4924 copy_id24_to_sam_passwd(pwd, id24);
4926 status = pdb_update_sam_account(pwd);
4927 if (!NT_STATUS_IS_OK(status)) {
4931 return NT_STATUS_OK;
4934 /*******************************************************************
4936 ********************************************************************/
4938 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4940 struct samr_UserInfo25 *id25,
4946 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4947 return NT_STATUS_INVALID_PARAMETER;
4950 if (id25->info.fields_present == 0) {
4951 return NT_STATUS_INVALID_PARAMETER;
4954 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4955 return NT_STATUS_ACCESS_DENIED;
4958 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4959 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4961 if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
4962 return NT_STATUS_WRONG_PASSWORD;
4966 copy_id25_to_sam_passwd(pwd, id25);
4968 /* write the change out */
4969 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4974 * We need to "pdb_update_sam_account" before the unix primary group
4975 * is set, because the idealx scripts would also change the
4976 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4977 * the delete explicit / add explicit, which would then fail to find
4978 * the previous primaryGroupSid value.
4981 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4982 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4983 if ( !NT_STATUS_IS_OK(status) ) {
4988 return NT_STATUS_OK;
4991 /*******************************************************************
4993 ********************************************************************/
4995 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4997 struct samr_UserInfo26 *id26,
5003 DEBUG(5, ("set_user_info_26: NULL id26\n"));
5004 return NT_STATUS_INVALID_PARAMETER;
5007 if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
5008 return NT_STATUS_WRONG_PASSWORD;
5011 copy_id26_to_sam_passwd(pwd, id26);
5013 status = pdb_update_sam_account(pwd);
5014 if (!NT_STATUS_IS_OK(status)) {
5018 return NT_STATUS_OK;
5021 /*************************************************************
5022 **************************************************************/
5024 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
5026 uint32_t acc_required = 0;
5028 /* USER_ALL_USERNAME */
5029 if (fields & SAMR_FIELD_ACCOUNT_NAME)
5030 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5031 /* USER_ALL_FULLNAME */
5032 if (fields & SAMR_FIELD_FULL_NAME)
5033 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5034 /* USER_ALL_PRIMARYGROUPID */
5035 if (fields & SAMR_FIELD_PRIMARY_GID)
5036 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5037 /* USER_ALL_HOMEDIRECTORY */
5038 if (fields & SAMR_FIELD_HOME_DIRECTORY)
5039 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5040 /* USER_ALL_HOMEDIRECTORYDRIVE */
5041 if (fields & SAMR_FIELD_HOME_DRIVE)
5042 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5043 /* USER_ALL_SCRIPTPATH */
5044 if (fields & SAMR_FIELD_LOGON_SCRIPT)
5045 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5046 /* USER_ALL_PROFILEPATH */
5047 if (fields & SAMR_FIELD_PROFILE_PATH)
5048 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5049 /* USER_ALL_ADMINCOMMENT */
5050 if (fields & SAMR_FIELD_COMMENT)
5051 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5052 /* USER_ALL_WORKSTATIONS */
5053 if (fields & SAMR_FIELD_WORKSTATIONS)
5054 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5055 /* USER_ALL_LOGONHOURS */
5056 if (fields & SAMR_FIELD_LOGON_HOURS)
5057 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5058 /* USER_ALL_ACCOUNTEXPIRES */
5059 if (fields & SAMR_FIELD_ACCT_EXPIRY)
5060 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5061 /* USER_ALL_USERACCOUNTCONTROL */
5062 if (fields & SAMR_FIELD_ACCT_FLAGS)
5063 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5064 /* USER_ALL_PARAMETERS */
5065 if (fields & SAMR_FIELD_PARAMETERS)
5066 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5067 /* USER_ALL_USERCOMMENT */
5068 if (fields & SAMR_FIELD_COMMENT)
5069 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5070 /* USER_ALL_COUNTRYCODE */
5071 if (fields & SAMR_FIELD_COUNTRY_CODE)
5072 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5073 /* USER_ALL_CODEPAGE */
5074 if (fields & SAMR_FIELD_CODE_PAGE)
5075 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5076 /* USER_ALL_NTPASSWORDPRESENT */
5077 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
5078 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5079 /* USER_ALL_LMPASSWORDPRESENT */
5080 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
5081 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5082 /* USER_ALL_PASSWORDEXPIRED */
5083 if (fields & SAMR_FIELD_EXPIRED_FLAG)
5084 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5086 return acc_required;
5089 /*******************************************************************
5091 ********************************************************************/
5093 NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
5094 struct samr_SetUserInfo *r)
5096 struct samr_user_info *uinfo;
5098 struct samu *pwd = NULL;
5099 union samr_UserInfo *info = r->in.info;
5100 uint32_t acc_required = 0;
5101 uint32_t fields = 0;
5104 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
5106 /* This is tricky. A WinXP domain join sets
5107 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5108 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
5109 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5110 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
5111 we'll use the set from the WinXP join as the basis. */
5113 switch (r->in.level) {
5114 case 2: /* UserPreferencesInformation */
5115 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5116 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5118 case 4: /* UserLogonHoursInformation */
5119 case 6: /* UserNameInformation */
5120 case 7: /* UserAccountNameInformation */
5121 case 8: /* UserFullNameInformation */
5122 case 9: /* UserPrimaryGroupInformation */
5123 case 10: /* UserHomeInformation */
5124 case 11: /* UserScriptInformation */
5125 case 12: /* UserProfileInformation */
5126 case 13: /* UserAdminCommentInformation */
5127 case 14: /* UserWorkStationsInformation */
5128 case 16: /* UserControlInformation */
5129 case 17: /* UserExpiresInformation */
5130 case 20: /* UserParametersInformation */
5131 /* USER_WRITE_ACCOUNT */
5132 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5134 case 18: /* UserInternal1Information */
5135 /* FIXME: gd, this is a guess */
5136 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5138 case 21: /* UserAllInformation */
5139 fields = info->info21.fields_present;
5140 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5142 case 23: /* UserInternal4Information */
5143 fields = info->info23.info.fields_present;
5144 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5146 case 25: /* UserInternal4InformationNew */
5147 fields = info->info25.info.fields_present;
5148 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5150 case 24: /* UserInternal5Information */
5151 case 26: /* UserInternal5InformationNew */
5152 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5155 return NT_STATUS_INVALID_INFO_CLASS;
5158 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5159 struct samr_user_info, &status);
5160 if (!NT_STATUS_IS_OK(status)) {
5164 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5165 sid_string_dbg(&uinfo->sid), r->in.level));
5168 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5169 return NT_STATUS_INVALID_INFO_CLASS;
5172 if (!(pwd = samu_new(NULL))) {
5173 return NT_STATUS_NO_MEMORY;
5177 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5182 return NT_STATUS_NO_SUCH_USER;
5185 /* ================ BEGIN Privilege BLOCK ================ */
5189 /* ok! user info levels (lots: see MSDEV help), off we go... */
5191 switch (r->in.level) {
5194 status = set_user_info_2(p->mem_ctx,
5199 status = set_user_info_4(p->mem_ctx,
5204 status = set_user_info_6(p->mem_ctx,
5209 status = set_user_info_7(p->mem_ctx,
5214 status = set_user_info_8(p->mem_ctx,
5219 status = set_user_info_10(p->mem_ctx,
5220 &info->info10, pwd);
5224 status = set_user_info_11(p->mem_ctx,
5225 &info->info11, pwd);
5229 status = set_user_info_12(p->mem_ctx,
5230 &info->info12, pwd);
5234 status = set_user_info_13(p->mem_ctx,
5235 &info->info13, pwd);
5239 status = set_user_info_14(p->mem_ctx,
5240 &info->info14, pwd);
5244 status = set_user_info_16(p->mem_ctx,
5245 &info->info16, pwd);
5249 status = set_user_info_17(p->mem_ctx,
5250 &info->info17, pwd);
5254 /* Used by AS/U JRA. */
5255 status = set_user_info_18(&info->info18,
5257 &p->server_info->user_session_key,
5262 status = set_user_info_20(p->mem_ctx,
5263 &info->info20, pwd);
5267 status = set_user_info_21(&info->info21,
5269 &p->server_info->user_session_key,
5274 if (!p->server_info->user_session_key.length) {
5275 status = NT_STATUS_NO_USER_SESSION_KEY;
5277 arcfour_crypt_blob(info->info23.password.data, 516,
5278 &p->server_info->user_session_key);
5280 dump_data(100, info->info23.password.data, 516);
5282 status = set_user_info_23(p->mem_ctx,
5289 if (!p->server_info->user_session_key.length) {
5290 status = NT_STATUS_NO_USER_SESSION_KEY;
5292 arcfour_crypt_blob(info->info24.password.data,
5294 &p->server_info->user_session_key);
5296 dump_data(100, info->info24.password.data, 516);
5298 status = set_user_info_24(p->mem_ctx,
5300 &info->info24, pwd);
5304 if (!p->server_info->user_session_key.length) {
5305 status = NT_STATUS_NO_USER_SESSION_KEY;
5307 encode_or_decode_arc4_passwd_buffer(
5308 info->info25.password.data,
5309 &p->server_info->user_session_key);
5311 dump_data(100, info->info25.password.data, 532);
5313 status = set_user_info_25(p->mem_ctx,
5315 &info->info25, pwd);
5319 if (!p->server_info->user_session_key.length) {
5320 status = NT_STATUS_NO_USER_SESSION_KEY;
5322 encode_or_decode_arc4_passwd_buffer(
5323 info->info26.password.data,
5324 &p->server_info->user_session_key);
5326 dump_data(100, info->info26.password.data, 516);
5328 status = set_user_info_26(p->mem_ctx,
5330 &info->info26, pwd);
5334 status = NT_STATUS_INVALID_INFO_CLASS;
5341 /* ================ END Privilege BLOCK ================ */
5343 if (NT_STATUS_IS_OK(status)) {
5344 force_flush_samr_cache(&uinfo->sid);
5350 /*******************************************************************
5352 ********************************************************************/
5354 NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
5355 struct samr_SetUserInfo2 *r)
5357 struct samr_SetUserInfo q;
5359 q.in.user_handle = r->in.user_handle;
5360 q.in.level = r->in.level;
5361 q.in.info = r->in.info;
5363 return _samr_SetUserInfo(p, &q);
5366 /*********************************************************************
5367 _samr_GetAliasMembership
5368 *********************************************************************/
5370 NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
5371 struct samr_GetAliasMembership *r)
5373 size_t num_alias_rids;
5375 struct samr_domain_info *dinfo;
5380 struct dom_sid *members;
5382 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5384 dinfo = policy_handle_find(p, r->in.domain_handle,
5385 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5386 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5387 struct samr_domain_info, &status);
5388 if (!NT_STATUS_IS_OK(status)) {
5392 if (!sid_check_is_domain(&dinfo->sid) &&
5393 !sid_check_is_builtin(&dinfo->sid))
5394 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5396 if (r->in.sids->num_sids) {
5397 members = TALLOC_ARRAY(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
5399 if (members == NULL)
5400 return NT_STATUS_NO_MEMORY;
5405 for (i=0; i<r->in.sids->num_sids; i++)
5406 sid_copy(&members[i], r->in.sids->sids[i].sid);
5412 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5413 r->in.sids->num_sids,
5414 &alias_rids, &num_alias_rids);
5417 if (!NT_STATUS_IS_OK(status)) {
5421 r->out.rids->count = num_alias_rids;
5422 r->out.rids->ids = alias_rids;
5424 if (r->out.rids->ids == NULL) {
5425 /* Windows domain clients don't accept a NULL ptr here */
5426 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5428 if (r->out.rids->ids == NULL) {
5429 return NT_STATUS_NO_MEMORY;
5432 return NT_STATUS_OK;
5435 /*********************************************************************
5436 _samr_GetMembersInAlias
5437 *********************************************************************/
5439 NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
5440 struct samr_GetMembersInAlias *r)
5442 struct samr_alias_info *ainfo;
5445 size_t num_sids = 0;
5446 struct lsa_SidPtr *sids = NULL;
5447 struct dom_sid *pdb_sids = NULL;
5449 ainfo = policy_handle_find(p, r->in.alias_handle,
5450 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5451 struct samr_alias_info, &status);
5452 if (!NT_STATUS_IS_OK(status)) {
5456 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5459 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5463 if (!NT_STATUS_IS_OK(status)) {
5468 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5470 TALLOC_FREE(pdb_sids);
5471 return NT_STATUS_NO_MEMORY;
5475 for (i = 0; i < num_sids; i++) {
5476 sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
5478 TALLOC_FREE(pdb_sids);
5479 return NT_STATUS_NO_MEMORY;
5483 r->out.sids->num_sids = num_sids;
5484 r->out.sids->sids = sids;
5486 TALLOC_FREE(pdb_sids);
5488 return NT_STATUS_OK;
5491 /*********************************************************************
5492 _samr_QueryGroupMember
5493 *********************************************************************/
5495 NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
5496 struct samr_QueryGroupMember *r)
5498 struct samr_group_info *ginfo;
5499 size_t i, num_members;
5505 struct samr_RidTypeArray *rids = NULL;
5507 ginfo = policy_handle_find(p, r->in.group_handle,
5508 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5509 struct samr_group_info, &status);
5510 if (!NT_STATUS_IS_OK(status)) {
5514 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5516 return NT_STATUS_NO_MEMORY;
5519 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5521 if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5522 DEBUG(3, ("sid %s is not in our domain\n",
5523 sid_string_dbg(&ginfo->sid)));
5524 return NT_STATUS_NO_SUCH_GROUP;
5527 DEBUG(10, ("lookup on Domain SID\n"));
5530 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5531 &rid, &num_members);
5534 if (!NT_STATUS_IS_OK(status))
5538 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5540 return NT_STATUS_NO_MEMORY;
5546 for (i=0; i<num_members; i++)
5547 attr[i] = SID_NAME_USER;
5549 rids->count = num_members;
5553 *r->out.rids = rids;
5555 return NT_STATUS_OK;
5558 /*********************************************************************
5559 _samr_AddAliasMember
5560 *********************************************************************/
5562 NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
5563 struct samr_AddAliasMember *r)
5565 struct samr_alias_info *ainfo;
5568 ainfo = policy_handle_find(p, r->in.alias_handle,
5569 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5570 struct samr_alias_info, &status);
5571 if (!NT_STATUS_IS_OK(status)) {
5575 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5577 /******** BEGIN SeAddUsers BLOCK *********/
5580 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5583 /******** END SeAddUsers BLOCK *********/
5585 if (NT_STATUS_IS_OK(status)) {
5586 force_flush_samr_cache(&ainfo->sid);
5592 /*********************************************************************
5593 _samr_DeleteAliasMember
5594 *********************************************************************/
5596 NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
5597 struct samr_DeleteAliasMember *r)
5599 struct samr_alias_info *ainfo;
5602 ainfo = policy_handle_find(p, r->in.alias_handle,
5603 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5604 struct samr_alias_info, &status);
5605 if (!NT_STATUS_IS_OK(status)) {
5609 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5610 sid_string_dbg(&ainfo->sid)));
5612 /******** BEGIN SeAddUsers BLOCK *********/
5615 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5618 /******** END SeAddUsers BLOCK *********/
5620 if (NT_STATUS_IS_OK(status)) {
5621 force_flush_samr_cache(&ainfo->sid);
5627 /*********************************************************************
5628 _samr_AddGroupMember
5629 *********************************************************************/
5631 NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
5632 struct samr_AddGroupMember *r)
5634 struct samr_group_info *ginfo;
5638 ginfo = policy_handle_find(p, r->in.group_handle,
5639 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5640 struct samr_group_info, &status);
5641 if (!NT_STATUS_IS_OK(status)) {
5645 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5647 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5649 return NT_STATUS_INVALID_HANDLE;
5652 /******** BEGIN SeAddUsers BLOCK *********/
5655 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5658 /******** END SeAddUsers BLOCK *********/
5660 force_flush_samr_cache(&ginfo->sid);
5665 /*********************************************************************
5666 _samr_DeleteGroupMember
5667 *********************************************************************/
5669 NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
5670 struct samr_DeleteGroupMember *r)
5673 struct samr_group_info *ginfo;
5678 * delete the group member named r->in.rid
5679 * who is a member of the sid associated with the handle
5680 * the rid is a user's rid as the group is a domain group.
5683 ginfo = policy_handle_find(p, r->in.group_handle,
5684 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5685 struct samr_group_info, &status);
5686 if (!NT_STATUS_IS_OK(status)) {
5690 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5692 return NT_STATUS_INVALID_HANDLE;
5695 /******** BEGIN SeAddUsers BLOCK *********/
5698 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5701 /******** END SeAddUsers BLOCK *********/
5703 force_flush_samr_cache(&ginfo->sid);
5708 /*********************************************************************
5710 *********************************************************************/
5712 NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
5713 struct samr_DeleteUser *r)
5715 struct samr_user_info *uinfo;
5717 struct samu *sam_pass=NULL;
5720 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5722 uinfo = policy_handle_find(p, r->in.user_handle,
5723 SEC_STD_DELETE, NULL,
5724 struct samr_user_info, &status);
5725 if (!NT_STATUS_IS_OK(status)) {
5729 if (!sid_check_is_in_our_domain(&uinfo->sid))
5730 return NT_STATUS_CANNOT_DELETE;
5732 /* check if the user exists before trying to delete */
5733 if ( !(sam_pass = samu_new( NULL )) ) {
5734 return NT_STATUS_NO_MEMORY;
5738 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5742 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5743 sid_string_dbg(&uinfo->sid)));
5744 TALLOC_FREE(sam_pass);
5745 return NT_STATUS_NO_SUCH_USER;
5748 /******** BEGIN SeAddUsers BLOCK *********/
5751 status = pdb_delete_user(p->mem_ctx, sam_pass);
5754 /******** END SeAddUsers BLOCK *********/
5756 if ( !NT_STATUS_IS_OK(status) ) {
5757 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5758 "user %s: %s.\n", pdb_get_username(sam_pass),
5759 nt_errstr(status)));
5760 TALLOC_FREE(sam_pass);
5765 TALLOC_FREE(sam_pass);
5767 force_flush_samr_cache(&uinfo->sid);
5769 if (!close_policy_hnd(p, r->in.user_handle))
5770 return NT_STATUS_OBJECT_NAME_INVALID;
5772 ZERO_STRUCTP(r->out.user_handle);
5774 return NT_STATUS_OK;
5777 /*********************************************************************
5778 _samr_DeleteDomainGroup
5779 *********************************************************************/
5781 NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
5782 struct samr_DeleteDomainGroup *r)
5784 struct samr_group_info *ginfo;
5788 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5790 ginfo = policy_handle_find(p, r->in.group_handle,
5791 SEC_STD_DELETE, NULL,
5792 struct samr_group_info, &status);
5793 if (!NT_STATUS_IS_OK(status)) {
5797 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5799 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5801 return NT_STATUS_NO_SUCH_GROUP;
5804 /******** BEGIN SeAddUsers BLOCK *********/
5807 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5810 /******** END SeAddUsers BLOCK *********/
5812 if ( !NT_STATUS_IS_OK(status) ) {
5813 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5814 "entry for group %s: %s\n",
5815 sid_string_dbg(&ginfo->sid),
5816 nt_errstr(status)));
5820 force_flush_samr_cache(&ginfo->sid);
5822 if (!close_policy_hnd(p, r->in.group_handle))
5823 return NT_STATUS_OBJECT_NAME_INVALID;
5825 return NT_STATUS_OK;
5828 /*********************************************************************
5829 _samr_DeleteDomAlias
5830 *********************************************************************/
5832 NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
5833 struct samr_DeleteDomAlias *r)
5835 struct samr_alias_info *ainfo;
5838 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5840 ainfo = policy_handle_find(p, r->in.alias_handle,
5841 SEC_STD_DELETE, NULL,
5842 struct samr_alias_info, &status);
5843 if (!NT_STATUS_IS_OK(status)) {
5847 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5849 /* Don't let Windows delete builtin groups */
5851 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5852 return NT_STATUS_SPECIAL_ACCOUNT;
5855 if (!sid_check_is_in_our_domain(&ainfo->sid))
5856 return NT_STATUS_NO_SUCH_ALIAS;
5858 DEBUG(10, ("lookup on Local SID\n"));
5860 /******** BEGIN SeAddUsers BLOCK *********/
5863 /* Have passdb delete the alias */
5864 status = pdb_delete_alias(&ainfo->sid);
5867 /******** END SeAddUsers BLOCK *********/
5869 if ( !NT_STATUS_IS_OK(status))
5872 force_flush_samr_cache(&ainfo->sid);
5874 if (!close_policy_hnd(p, r->in.alias_handle))
5875 return NT_STATUS_OBJECT_NAME_INVALID;
5877 return NT_STATUS_OK;
5880 /*********************************************************************
5881 _samr_CreateDomainGroup
5882 *********************************************************************/
5884 NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
5885 struct samr_CreateDomainGroup *r)
5890 struct samr_domain_info *dinfo;
5891 struct samr_group_info *ginfo;
5893 dinfo = policy_handle_find(p, r->in.domain_handle,
5894 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5895 struct samr_domain_info, &status);
5896 if (!NT_STATUS_IS_OK(status)) {
5900 if (!sid_check_is_domain(&dinfo->sid)) {
5901 return NT_STATUS_ACCESS_DENIED;
5904 name = r->in.name->string;
5906 return NT_STATUS_NO_MEMORY;
5909 status = can_create(p->mem_ctx, name);
5910 if (!NT_STATUS_IS_OK(status)) {
5914 /******** BEGIN SeAddUsers BLOCK *********/
5917 /* check that we successfully create the UNIX group */
5918 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5921 /******** END SeAddUsers BLOCK *********/
5923 /* check if we should bail out here */
5925 if ( !NT_STATUS_IS_OK(status) )
5928 ginfo = policy_handle_create(p, r->out.group_handle,
5929 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5930 struct samr_group_info, &status);
5931 if (!NT_STATUS_IS_OK(status)) {
5934 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5936 force_flush_samr_cache(&dinfo->sid);
5938 return NT_STATUS_OK;
5941 /*********************************************************************
5942 _samr_CreateDomAlias
5943 *********************************************************************/
5945 NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
5946 struct samr_CreateDomAlias *r)
5948 struct dom_sid info_sid;
5949 const char *name = NULL;
5950 struct samr_domain_info *dinfo;
5951 struct samr_alias_info *ainfo;
5955 dinfo = policy_handle_find(p, r->in.domain_handle,
5956 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5957 struct samr_domain_info, &result);
5958 if (!NT_STATUS_IS_OK(result)) {
5962 if (!sid_check_is_domain(&dinfo->sid)) {
5963 return NT_STATUS_ACCESS_DENIED;
5966 name = r->in.alias_name->string;
5968 result = can_create(p->mem_ctx, name);
5969 if (!NT_STATUS_IS_OK(result)) {
5973 /******** BEGIN SeAddUsers BLOCK *********/
5976 /* Have passdb create the alias */
5977 result = pdb_create_alias(name, r->out.rid);
5980 /******** END SeAddUsers BLOCK *********/
5982 if (!NT_STATUS_IS_OK(result)) {
5983 DEBUG(10, ("pdb_create_alias failed: %s\n",
5984 nt_errstr(result)));
5988 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5990 if (!sid_to_gid(&info_sid, &gid)) {
5991 DEBUG(10, ("Could not find alias just created\n"));
5992 return NT_STATUS_ACCESS_DENIED;
5995 /* check if the group has been successfully created */
5996 if ( getgrgid(gid) == NULL ) {
5997 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5998 (unsigned int)gid));
5999 return NT_STATUS_ACCESS_DENIED;
6002 ainfo = policy_handle_create(p, r->out.alias_handle,
6003 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
6004 struct samr_alias_info, &result);
6005 if (!NT_STATUS_IS_OK(result)) {
6008 ainfo->sid = info_sid;
6010 force_flush_samr_cache(&info_sid);
6012 return NT_STATUS_OK;
6015 /*********************************************************************
6016 _samr_QueryGroupInfo
6017 *********************************************************************/
6019 NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
6020 struct samr_QueryGroupInfo *r)
6022 struct samr_group_info *ginfo;
6025 union samr_GroupInfo *info = NULL;
6027 uint32_t attributes = SE_GROUP_MANDATORY |
6028 SE_GROUP_ENABLED_BY_DEFAULT |
6030 const char *group_name = NULL;
6031 const char *group_description = NULL;
6033 ginfo = policy_handle_find(p, r->in.group_handle,
6034 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
6035 struct samr_group_info, &status);
6036 if (!NT_STATUS_IS_OK(status)) {
6041 ret = get_domain_group_from_sid(ginfo->sid, &map);
6044 return NT_STATUS_INVALID_HANDLE;
6046 /* FIXME: map contains fstrings */
6047 group_name = talloc_strdup(r, map.nt_name);
6048 group_description = talloc_strdup(r, map.comment);
6050 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
6052 return NT_STATUS_NO_MEMORY;
6055 switch (r->in.level) {
6061 status = pdb_enum_group_members(
6062 p->mem_ctx, &ginfo->sid, &members,
6066 if (!NT_STATUS_IS_OK(status)) {
6070 info->all.name.string = group_name;
6071 info->all.attributes = attributes;
6072 info->all.num_members = num_members;
6073 info->all.description.string = group_description;
6077 info->name.string = group_name;
6080 info->attributes.attributes = attributes;
6083 info->description.string = group_description;
6093 status = pdb_enum_group_members(
6094 p->mem_ctx, &ginfo->sid, &members,
6098 if (!NT_STATUS_IS_OK(status)) {
6102 info->all2.name.string = group_name;
6103 info->all2.attributes = attributes;
6104 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
6105 info->all2.description.string = group_description;
6110 return NT_STATUS_INVALID_INFO_CLASS;
6113 *r->out.info = info;
6115 return NT_STATUS_OK;
6118 /*********************************************************************
6120 *********************************************************************/
6122 NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
6123 struct samr_SetGroupInfo *r)
6125 struct samr_group_info *ginfo;
6130 ginfo = policy_handle_find(p, r->in.group_handle,
6131 SAMR_GROUP_ACCESS_SET_INFO, NULL,
6132 struct samr_group_info, &status);
6133 if (!NT_STATUS_IS_OK(status)) {
6138 ret = get_domain_group_from_sid(ginfo->sid, &map);
6141 return NT_STATUS_NO_SUCH_GROUP;
6143 switch (r->in.level) {
6145 fstrcpy(map.nt_name, r->in.info->name.string);
6150 fstrcpy(map.comment, r->in.info->description.string);
6153 return NT_STATUS_INVALID_INFO_CLASS;
6156 /******** BEGIN SeAddUsers BLOCK *********/
6159 status = pdb_update_group_mapping_entry(&map);
6162 /******** End SeAddUsers BLOCK *********/
6164 if (NT_STATUS_IS_OK(status)) {
6165 force_flush_samr_cache(&ginfo->sid);
6171 /*********************************************************************
6173 *********************************************************************/
6175 NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
6176 struct samr_SetAliasInfo *r)
6178 struct samr_alias_info *ainfo;
6179 struct acct_info info;
6182 ainfo = policy_handle_find(p, r->in.alias_handle,
6183 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6184 struct samr_alias_info, &status);
6185 if (!NT_STATUS_IS_OK(status)) {
6189 /* get the current group information */
6192 status = pdb_get_aliasinfo( &ainfo->sid, &info );
6195 if ( !NT_STATUS_IS_OK(status))
6198 switch (r->in.level) {
6203 /* We currently do not support renaming groups in the
6204 the BUILTIN domain. Refer to util_builtin.c to understand
6205 why. The eventually needs to be fixed to be like Windows
6206 where you can rename builtin groups, just not delete them */
6208 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6209 return NT_STATUS_SPECIAL_ACCOUNT;
6212 /* There has to be a valid name (and it has to be different) */
6214 if ( !r->in.info->name.string )
6215 return NT_STATUS_INVALID_PARAMETER;
6217 /* If the name is the same just reply "ok". Yes this
6218 doesn't allow you to change the case of a group name. */
6220 if ( strequal( r->in.info->name.string, info.acct_name ) )
6221 return NT_STATUS_OK;
6223 fstrcpy( info.acct_name, r->in.info->name.string);
6225 /* make sure the name doesn't already exist as a user
6228 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6229 status = can_create( p->mem_ctx, group_name );
6230 if ( !NT_STATUS_IS_OK( status ) )
6234 case ALIASINFODESCRIPTION:
6235 if (r->in.info->description.string) {
6236 fstrcpy(info.acct_desc,
6237 r->in.info->description.string);
6239 fstrcpy( info.acct_desc, "" );
6243 return NT_STATUS_INVALID_INFO_CLASS;
6246 /******** BEGIN SeAddUsers BLOCK *********/
6249 status = pdb_set_aliasinfo( &ainfo->sid, &info );
6252 /******** End SeAddUsers BLOCK *********/
6254 if (NT_STATUS_IS_OK(status))
6255 force_flush_samr_cache(&ainfo->sid);
6260 /****************************************************************
6262 ****************************************************************/
6264 NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
6265 struct samr_GetDomPwInfo *r)
6267 uint32_t min_password_length = 0;
6268 uint32_t password_properties = 0;
6270 /* Perform access check. Since this rpc does not require a
6271 policy handle it will not be caught by the access checks on
6272 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6274 if (!pipe_access_check(p)) {
6275 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6276 return NT_STATUS_ACCESS_DENIED;
6280 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6281 &min_password_length);
6282 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6283 &password_properties);
6286 if (lp_check_password_script() && *lp_check_password_script()) {
6287 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6290 r->out.info->min_password_length = min_password_length;
6291 r->out.info->password_properties = password_properties;
6293 return NT_STATUS_OK;
6296 /*********************************************************************
6298 *********************************************************************/
6300 NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
6301 struct samr_OpenGroup *r)
6304 struct dom_sid info_sid;
6306 struct samr_domain_info *dinfo;
6307 struct samr_group_info *ginfo;
6308 struct security_descriptor *psd = NULL;
6310 uint32 des_access = r->in.access_mask;
6315 dinfo = policy_handle_find(p, r->in.domain_handle,
6316 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6317 struct samr_domain_info, &status);
6318 if (!NT_STATUS_IS_OK(status)) {
6322 /*check if access can be granted as requested by client. */
6323 map_max_allowed_access(p->server_info->ptok,
6324 &p->server_info->utok,
6327 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6328 se_map_generic(&des_access,&grp_generic_mapping);
6330 status = access_check_object(psd, p->server_info->ptok,
6331 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6332 des_access, &acc_granted, "_samr_OpenGroup");
6334 if ( !NT_STATUS_IS_OK(status) )
6337 /* this should not be hard-coded like this */
6339 if (!sid_check_is_domain(&dinfo->sid)) {
6340 return NT_STATUS_ACCESS_DENIED;
6343 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6345 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6346 sid_string_dbg(&info_sid)));
6348 /* check if that group really exists */
6350 ret = get_domain_group_from_sid(info_sid, &map);
6353 return NT_STATUS_NO_SUCH_GROUP;
6355 ginfo = policy_handle_create(p, r->out.group_handle,
6357 struct samr_group_info, &status);
6358 if (!NT_STATUS_IS_OK(status)) {
6361 ginfo->sid = info_sid;
6363 return NT_STATUS_OK;
6366 /*********************************************************************
6367 _samr_RemoveMemberFromForeignDomain
6368 *********************************************************************/
6370 NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
6371 struct samr_RemoveMemberFromForeignDomain *r)
6373 struct samr_domain_info *dinfo;
6376 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6377 sid_string_dbg(r->in.sid)));
6379 /* Find the policy handle. Open a policy on it. */
6381 dinfo = policy_handle_find(p, r->in.domain_handle,
6382 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6383 struct samr_domain_info, &result);
6384 if (!NT_STATUS_IS_OK(result)) {
6388 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6389 sid_string_dbg(&dinfo->sid)));
6391 /* we can only delete a user from a group since we don't have
6392 nested groups anyways. So in the latter case, just say OK */
6394 /* TODO: The above comment nowadays is bogus. Since we have nested
6395 * groups now, and aliases members are never reported out of the unix
6396 * group membership, the "just say OK" makes this call a no-op. For
6397 * us. This needs fixing however. */
6399 /* I've only ever seen this in the wild when deleting a user from
6400 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6401 * is the user about to be deleted. I very much suspect this is the
6402 * only application of this call. To verify this, let people report
6405 if (!sid_check_is_builtin(&dinfo->sid)) {
6406 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6407 "global_sam_sid() = %s\n",
6408 sid_string_dbg(&dinfo->sid),
6409 sid_string_dbg(get_global_sam_sid())));
6410 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6411 return NT_STATUS_OK;
6414 force_flush_samr_cache(&dinfo->sid);
6416 result = NT_STATUS_OK;
6421 /*******************************************************************
6422 _samr_QueryDomainInfo2
6423 ********************************************************************/
6425 NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
6426 struct samr_QueryDomainInfo2 *r)
6428 struct samr_QueryDomainInfo q;
6430 q.in.domain_handle = r->in.domain_handle;
6431 q.in.level = r->in.level;
6433 q.out.info = r->out.info;
6435 return _samr_QueryDomainInfo(p, &q);
6438 /*******************************************************************
6439 ********************************************************************/
6441 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6442 struct samr_DomInfo1 *r)
6444 time_t u_expire, u_min_age;
6446 u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6447 u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6449 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6450 (uint32_t)r->min_password_length);
6451 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6452 (uint32_t)r->password_history_length);
6453 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6454 (uint32_t)r->password_properties);
6455 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6456 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6458 return NT_STATUS_OK;
6461 /*******************************************************************
6462 ********************************************************************/
6464 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6465 struct samr_DomInfo3 *r)
6469 u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6471 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6473 return NT_STATUS_OK;
6476 /*******************************************************************
6477 ********************************************************************/
6479 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6480 struct samr_DomInfo12 *r)
6482 time_t u_lock_duration, u_reset_time;
6484 u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6485 if (u_lock_duration != -1) {
6486 u_lock_duration /= 60;
6489 u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6491 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6492 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6493 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6494 (uint32_t)r->lockout_threshold);
6496 return NT_STATUS_OK;
6499 /*******************************************************************
6501 ********************************************************************/
6503 NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
6504 struct samr_SetDomainInfo *r)
6506 struct samr_domain_info *dinfo;
6508 uint32_t acc_required = 0;
6510 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6512 switch (r->in.level) {
6513 case 1: /* DomainPasswordInformation */
6514 case 12: /* DomainLockoutInformation */
6515 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6516 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6518 case 3: /* DomainLogoffInformation */
6519 case 4: /* DomainOemInformation */
6520 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6521 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6523 case 6: /* DomainReplicationInformation */
6524 case 9: /* DomainStateInformation */
6525 case 7: /* DomainServerRoleInformation */
6526 /* DOMAIN_ADMINISTER_SERVER */
6527 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6530 return NT_STATUS_INVALID_INFO_CLASS;
6533 dinfo = policy_handle_find(p, r->in.domain_handle,
6535 struct samr_domain_info, &status);
6536 if (!NT_STATUS_IS_OK(status)) {
6540 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6542 switch (r->in.level) {
6544 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6547 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6558 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6561 return NT_STATUS_INVALID_INFO_CLASS;
6564 if (!NT_STATUS_IS_OK(status)) {
6568 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6570 return NT_STATUS_OK;
6573 /****************************************************************
6574 _samr_GetDisplayEnumerationIndex
6575 ****************************************************************/
6577 NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
6578 struct samr_GetDisplayEnumerationIndex *r)
6580 struct samr_domain_info *dinfo;
6581 uint32_t max_entries = (uint32_t) -1;
6582 uint32_t enum_context = 0;
6584 uint32_t num_account = 0;
6585 struct samr_displayentry *entries = NULL;
6588 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6590 dinfo = policy_handle_find(p, r->in.domain_handle,
6591 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6592 struct samr_domain_info, &status);
6593 if (!NT_STATUS_IS_OK(status)) {
6597 if ((r->in.level < 1) || (r->in.level > 3)) {
6598 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6599 "Unknown info level (%u)\n",
6601 return NT_STATUS_INVALID_INFO_CLASS;
6606 /* The following done as ROOT. Don't return without unbecome_root(). */
6608 switch (r->in.level) {
6610 if (dinfo->disp_info->users == NULL) {
6611 dinfo->disp_info->users = pdb_search_users(
6612 dinfo->disp_info, ACB_NORMAL);
6613 if (dinfo->disp_info->users == NULL) {
6615 return NT_STATUS_ACCESS_DENIED;
6617 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6618 "starting user enumeration at index %u\n",
6619 (unsigned int)enum_context));
6621 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6622 "using cached user enumeration at index %u\n",
6623 (unsigned int)enum_context));
6625 num_account = pdb_search_entries(dinfo->disp_info->users,
6626 enum_context, max_entries,
6630 if (dinfo->disp_info->machines == NULL) {
6631 dinfo->disp_info->machines = pdb_search_users(
6632 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6633 if (dinfo->disp_info->machines == NULL) {
6635 return NT_STATUS_ACCESS_DENIED;
6637 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6638 "starting machine enumeration at index %u\n",
6639 (unsigned int)enum_context));
6641 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6642 "using cached machine enumeration at index %u\n",
6643 (unsigned int)enum_context));
6645 num_account = pdb_search_entries(dinfo->disp_info->machines,
6646 enum_context, max_entries,
6650 if (dinfo->disp_info->groups == NULL) {
6651 dinfo->disp_info->groups = pdb_search_groups(
6653 if (dinfo->disp_info->groups == NULL) {
6655 return NT_STATUS_ACCESS_DENIED;
6657 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6658 "starting group enumeration at index %u\n",
6659 (unsigned int)enum_context));
6661 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6662 "using cached group enumeration at index %u\n",
6663 (unsigned int)enum_context));
6665 num_account = pdb_search_entries(dinfo->disp_info->groups,
6666 enum_context, max_entries,
6671 smb_panic("info class changed");
6677 /* Ensure we cache this enumeration. */
6678 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6680 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6681 r->in.name->string));
6683 for (i=0; i<num_account; i++) {
6684 if (strequal(entries[i].account_name, r->in.name->string)) {
6685 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6686 "found %s at idx %d\n",
6687 r->in.name->string, i));
6689 return NT_STATUS_OK;
6693 /* assuming account_name lives at the very end */
6694 *r->out.idx = num_account;
6696 return NT_STATUS_NO_MORE_ENTRIES;
6699 /****************************************************************
6700 _samr_GetDisplayEnumerationIndex2
6701 ****************************************************************/
6703 NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
6704 struct samr_GetDisplayEnumerationIndex2 *r)
6706 struct samr_GetDisplayEnumerationIndex q;
6708 q.in.domain_handle = r->in.domain_handle;
6709 q.in.level = r->in.level;
6710 q.in.name = r->in.name;
6712 q.out.idx = r->out.idx;
6714 return _samr_GetDisplayEnumerationIndex(p, &q);
6717 /****************************************************************
6719 ****************************************************************/
6721 NTSTATUS _samr_RidToSid(struct pipes_struct *p,
6722 struct samr_RidToSid *r)
6724 struct samr_domain_info *dinfo;
6728 dinfo = policy_handle_find(p, r->in.domain_handle,
6730 struct samr_domain_info, &status);
6731 if (!NT_STATUS_IS_OK(status)) {
6735 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6736 return NT_STATUS_NO_MEMORY;
6739 *r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
6741 return NT_STATUS_NO_MEMORY;
6744 return NT_STATUS_OK;
6747 /****************************************************************
6748 ****************************************************************/
6750 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
6751 const struct samr_PwInfo *dom_pw_info,
6752 const struct samr_ValidatePasswordReq2 *req,
6753 struct samr_ValidatePasswordRepCtr *rep)
6757 if (req->password.string == NULL) {
6758 return SAMR_VALIDATION_STATUS_SUCCESS;
6760 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6761 ZERO_STRUCT(rep->info);
6762 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6764 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6765 status = check_password_complexity(req->account.string,
6766 req->password.string,
6768 if (!NT_STATUS_IS_OK(status)) {
6769 ZERO_STRUCT(rep->info);
6770 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6774 return SAMR_VALIDATION_STATUS_SUCCESS;
6777 /****************************************************************
6778 ****************************************************************/
6780 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
6781 const struct samr_PwInfo *dom_pw_info,
6782 const struct samr_ValidatePasswordReq3 *req,
6783 struct samr_ValidatePasswordRepCtr *rep)
6787 if (req->password.string == NULL) {
6788 return SAMR_VALIDATION_STATUS_SUCCESS;
6790 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6791 ZERO_STRUCT(rep->info);
6792 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6794 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6795 status = check_password_complexity(req->account.string,
6796 req->password.string,
6798 if (!NT_STATUS_IS_OK(status)) {
6799 ZERO_STRUCT(rep->info);
6800 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6804 return SAMR_VALIDATION_STATUS_SUCCESS;
6807 /****************************************************************
6808 _samr_ValidatePassword
6809 ****************************************************************/
6811 NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
6812 struct samr_ValidatePassword *r)
6814 union samr_ValidatePasswordRep *rep;
6816 struct samr_GetDomPwInfo pw;
6817 struct samr_PwInfo dom_pw_info;
6819 if (r->in.level < 1 || r->in.level > 3) {
6820 return NT_STATUS_INVALID_INFO_CLASS;
6823 pw.in.domain_name = NULL;
6824 pw.out.info = &dom_pw_info;
6826 status = _samr_GetDomPwInfo(p, &pw);
6827 if (!NT_STATUS_IS_OK(status)) {
6831 rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
6833 return NT_STATUS_NO_MEMORY;
6836 switch (r->in.level) {
6838 status = NT_STATUS_NOT_SUPPORTED;
6841 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
6847 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
6853 status = NT_STATUS_INVALID_INFO_CLASS;
6857 if (!NT_STATUS_IS_OK(status)) {
6864 return NT_STATUS_OK;
6867 /****************************************************************
6868 ****************************************************************/
6870 NTSTATUS _samr_Shutdown(struct pipes_struct *p,
6871 struct samr_Shutdown *r)
6873 p->rng_fault_state = true;
6874 return NT_STATUS_NOT_IMPLEMENTED;
6877 /****************************************************************
6878 ****************************************************************/
6880 NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
6881 struct samr_SetMemberAttributesOfGroup *r)
6883 p->rng_fault_state = true;
6884 return NT_STATUS_NOT_IMPLEMENTED;
6887 /****************************************************************
6888 ****************************************************************/
6890 NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
6891 struct samr_TestPrivateFunctionsDomain *r)
6893 return NT_STATUS_NOT_IMPLEMENTED;
6896 /****************************************************************
6897 ****************************************************************/
6899 NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
6900 struct samr_TestPrivateFunctionsUser *r)
6902 return NT_STATUS_NOT_IMPLEMENTED;
6905 /****************************************************************
6906 ****************************************************************/
6908 NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
6909 struct samr_AddMultipleMembersToAlias *r)
6911 p->rng_fault_state = true;
6912 return NT_STATUS_NOT_IMPLEMENTED;
6915 /****************************************************************
6916 ****************************************************************/
6918 NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
6919 struct samr_RemoveMultipleMembersFromAlias *r)
6921 p->rng_fault_state = true;
6922 return NT_STATUS_NOT_IMPLEMENTED;
6925 /****************************************************************
6926 ****************************************************************/
6928 NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
6929 struct samr_SetBootKeyInformation *r)
6931 p->rng_fault_state = true;
6932 return NT_STATUS_NOT_IMPLEMENTED;
6935 /****************************************************************
6936 ****************************************************************/
6938 NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
6939 struct samr_GetBootKeyInformation *r)
6941 p->rng_fault_state = true;
6942 return NT_STATUS_NOT_IMPLEMENTED;
6945 /****************************************************************
6946 ****************************************************************/
6948 NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
6949 struct samr_SetDsrmPassword *r)
6951 p->rng_fault_state = true;
6952 return NT_STATUS_NOT_IMPLEMENTED;