2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
35 #include "../libcli/auth/libcli_auth.h"
38 #define DBGC_CLASS DBGC_RPC_SRV
40 #define SAMR_USR_RIGHTS_WRITE_PW \
41 ( READ_CONTROL_ACCESS | \
42 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
43 SAMR_USER_ACCESS_SET_LOC_COM)
44 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
45 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
47 #define DISP_INFO_CACHE_TIMEOUT 10
49 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
50 #define MAX_SAM_ENTRIES_W95 50
52 typedef struct disp_info {
53 DOM_SID sid; /* identify which domain this is. */
54 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
55 struct pdb_search *users; /* querydispinfo 1 and 4 */
56 struct pdb_search *machines; /* querydispinfo 2 */
57 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
58 struct pdb_search *aliases; /* enumaliases */
61 struct pdb_search *enum_users; /* enumusers with a mask */
63 struct timed_event *cache_timeout_event; /* cache idle timeout
67 /* We keep a static list of these by SID as modern clients close down
68 all resources between each request in a complete enumeration. */
71 /* for use by the \PIPE\samr policy */
73 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
74 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
79 static const struct generic_mapping sam_generic_mapping = {
80 GENERIC_RIGHTS_SAM_READ,
81 GENERIC_RIGHTS_SAM_WRITE,
82 GENERIC_RIGHTS_SAM_EXECUTE,
83 GENERIC_RIGHTS_SAM_ALL_ACCESS};
84 static const struct generic_mapping dom_generic_mapping = {
85 GENERIC_RIGHTS_DOMAIN_READ,
86 GENERIC_RIGHTS_DOMAIN_WRITE,
87 GENERIC_RIGHTS_DOMAIN_EXECUTE,
88 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
89 static const struct generic_mapping usr_generic_mapping = {
90 GENERIC_RIGHTS_USER_READ,
91 GENERIC_RIGHTS_USER_WRITE,
92 GENERIC_RIGHTS_USER_EXECUTE,
93 GENERIC_RIGHTS_USER_ALL_ACCESS};
94 static const struct generic_mapping usr_nopwchange_generic_mapping = {
95 GENERIC_RIGHTS_USER_READ,
96 GENERIC_RIGHTS_USER_WRITE,
97 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
98 GENERIC_RIGHTS_USER_ALL_ACCESS};
99 static const struct generic_mapping grp_generic_mapping = {
100 GENERIC_RIGHTS_GROUP_READ,
101 GENERIC_RIGHTS_GROUP_WRITE,
102 GENERIC_RIGHTS_GROUP_EXECUTE,
103 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
104 static const struct generic_mapping ali_generic_mapping = {
105 GENERIC_RIGHTS_ALIAS_READ,
106 GENERIC_RIGHTS_ALIAS_WRITE,
107 GENERIC_RIGHTS_ALIAS_EXECUTE,
108 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
110 /*******************************************************************
111 *******************************************************************/
113 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
114 const struct generic_mapping *map,
115 DOM_SID *sid, uint32 sid_access )
117 DOM_SID domadmin_sid;
118 SEC_ACE ace[5]; /* at most 5 entries */
123 /* basic access for Everyone */
125 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
126 map->generic_execute | map->generic_read, 0);
128 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
130 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
131 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
132 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
133 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
135 /* Add Full Access for Domain Admins if we are a DC */
138 sid_copy( &domadmin_sid, get_global_sam_sid() );
139 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
140 init_sec_ace(&ace[i++], &domadmin_sid,
141 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
144 /* if we have a sid, give it some special access */
147 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
150 /* create the security descriptor */
152 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
153 return NT_STATUS_NO_MEMORY;
155 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
156 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
157 psa, sd_size)) == NULL)
158 return NT_STATUS_NO_MEMORY;
163 /*******************************************************************
164 Checks if access to an object should be granted, and returns that
165 level of access for further checks.
166 ********************************************************************/
168 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
169 SE_PRIV *rights, uint32 rights_mask,
170 uint32 des_access, uint32 *acc_granted,
173 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
174 uint32 saved_mask = 0;
176 /* check privileges; certain SAM access bits should be overridden
177 by privileges (mostly having to do with creating/modifying/deleting
180 if ( rights && user_has_any_privilege( token, rights ) ) {
182 saved_mask = (des_access & rights_mask);
183 des_access &= ~saved_mask;
185 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
190 /* check the security descriptor first */
192 status = se_access_check(psd, token, des_access, acc_granted);
193 if (NT_STATUS_IS_OK(status)) {
197 /* give root a free pass */
199 if ( geteuid() == sec_initial_uid() ) {
201 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
202 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
204 *acc_granted = des_access;
206 status = NT_STATUS_OK;
212 /* add in any bits saved during the privilege check (only
213 matters is status is ok) */
215 *acc_granted |= rights_mask;
217 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
218 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
219 des_access, *acc_granted));
224 /*******************************************************************
225 Checks if access to a function can be granted
226 ********************************************************************/
228 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
230 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
231 debug, acc_granted, acc_required));
233 /* check the security descriptor first */
235 if ( (acc_granted&acc_required) == acc_required )
238 /* give root a free pass */
240 if (geteuid() == sec_initial_uid()) {
242 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
243 debug, acc_granted, acc_required));
244 DEBUGADD(4,("but overwritten by euid == 0\n"));
249 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
250 debug, acc_granted, acc_required));
252 return NT_STATUS_ACCESS_DENIED;
255 /*******************************************************************
256 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
257 ********************************************************************/
259 static void map_max_allowed_access(const NT_USER_TOKEN *token,
260 uint32_t *pacc_requested)
262 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
265 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
267 /* At least try for generic read. */
268 *pacc_requested = GENERIC_READ_ACCESS;
270 /* root gets anything. */
271 if (geteuid() == sec_initial_uid()) {
272 *pacc_requested |= GENERIC_ALL_ACCESS;
276 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
278 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
279 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
280 *pacc_requested |= GENERIC_ALL_ACCESS;
284 /* Full access for DOMAIN\Domain Admins. */
286 DOM_SID domadmin_sid;
287 sid_copy( &domadmin_sid, get_global_sam_sid() );
288 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
289 if (is_sid_in_token(token, &domadmin_sid)) {
290 *pacc_requested |= GENERIC_ALL_ACCESS;
294 /* TODO ! Check privileges. */
297 /*******************************************************************
298 Fetch or create a dispinfo struct.
299 ********************************************************************/
301 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
304 * We do a static cache for DISP_INFO's here. Explanation can be found
305 * in Jeremy's checkin message to r11793:
307 * Fix the SAMR cache so it works across completely insane
308 * client behaviour (ie.:
309 * open pipe/open SAMR handle/enumerate 0 - 1024
310 * close SAMR handle, close pipe.
311 * open pipe/open SAMR handle/enumerate 1024 - 2048...
312 * close SAMR handle, close pipe.
313 * And on ad-nausium. Amazing.... probably object-oriented
314 * client side programming in action yet again.
315 * This change should *massively* improve performance when
316 * enumerating users from an LDAP database.
319 * "Our" and the builtin domain are the only ones where we ever
320 * enumerate stuff, so just cache 2 entries.
323 static struct disp_info *builtin_dispinfo;
324 static struct disp_info *domain_dispinfo;
326 /* There are two cases to consider here:
327 1) The SID is a domain SID and we look for an equality match, or
328 2) This is an account SID and so we return the DISP_INFO* for our
335 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
337 * Necessary only once, but it does not really hurt.
339 if (builtin_dispinfo == NULL) {
340 builtin_dispinfo = talloc_zero(
341 talloc_autofree_context(), struct disp_info);
342 if (builtin_dispinfo == NULL) {
346 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
348 return builtin_dispinfo;
351 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
353 * Necessary only once, but it does not really hurt.
355 if (domain_dispinfo == NULL) {
356 domain_dispinfo = talloc_zero(
357 talloc_autofree_context(), struct disp_info);
358 if (domain_dispinfo == NULL) {
362 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
364 return domain_dispinfo;
370 /*******************************************************************
371 Create a samr_info struct.
372 ********************************************************************/
374 static int samr_info_destructor(struct samr_info *info);
376 static struct samr_info *get_samr_info_by_sid(TALLOC_CTX *mem_ctx,
379 struct samr_info *info;
383 sid_to_fstring(sid_str, psid);
385 fstrcpy(sid_str,"(NULL)");
388 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL) {
391 talloc_set_destructor(info, samr_info_destructor);
393 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
395 sid_copy( &info->sid, psid);
396 info->builtin_domain = sid_check_is_builtin(psid);
398 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
399 info->builtin_domain = False;
402 info->disp_info = get_samr_dispinfo_by_sid(psid);
407 /*******************************************************************
408 Function to free the per SID data.
409 ********************************************************************/
411 static void free_samr_cache(DISP_INFO *disp_info)
413 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
414 sid_string_dbg(&disp_info->sid)));
416 /* We need to become root here because the paged search might have to
417 * tell the LDAP server we're not interested in the rest anymore. */
421 TALLOC_FREE(disp_info->users);
422 TALLOC_FREE(disp_info->machines);
423 TALLOC_FREE(disp_info->groups);
424 TALLOC_FREE(disp_info->aliases);
425 TALLOC_FREE(disp_info->enum_users);
430 static int samr_info_destructor(struct samr_info *info)
432 /* Only free the dispinfo cache if no one bothered to set up
435 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
436 free_samr_cache(info->disp_info);
441 /*******************************************************************
442 Idle event handler. Throw away the disp info cache.
443 ********************************************************************/
445 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
446 struct timed_event *te,
450 DISP_INFO *disp_info = (DISP_INFO *)private_data;
452 TALLOC_FREE(disp_info->cache_timeout_event);
454 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
456 free_samr_cache(disp_info);
459 /*******************************************************************
460 Setup cache removal idle event handler.
461 ********************************************************************/
463 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
465 /* Remove any pending timeout and update. */
467 TALLOC_FREE(disp_info->cache_timeout_event);
469 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
470 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
471 (unsigned int)secs_fromnow ));
473 disp_info->cache_timeout_event = event_add_timed(
474 smbd_event_context(), NULL,
475 timeval_current_ofs(secs_fromnow, 0),
476 disp_info_cache_idle_timeout_handler, (void *)disp_info);
479 /*******************************************************************
480 Force flush any cache. We do this on any samr_set_xxx call.
481 We must also remove the timeout handler.
482 ********************************************************************/
484 static void force_flush_samr_cache(DISP_INFO *disp_info)
486 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
490 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
491 TALLOC_FREE(disp_info->cache_timeout_event);
492 free_samr_cache(disp_info);
495 /*******************************************************************
496 Ensure password info is never given out. Paranioa... JRA.
497 ********************************************************************/
499 static void samr_clear_sam_passwd(struct samu *sam_pass)
505 /* These now zero out the old password */
507 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
508 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
511 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
513 struct samr_displayentry *entry;
515 if (info->builtin_domain) {
516 /* No users in builtin. */
520 if (info->users == NULL) {
521 info->users = pdb_search_users(info, acct_flags);
522 if (info->users == NULL) {
526 /* Fetch the last possible entry, thus trigger an enumeration */
527 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
529 /* Ensure we cache this enumeration. */
530 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
532 return info->users->num_entries;
535 static uint32 count_sam_groups(struct disp_info *info)
537 struct samr_displayentry *entry;
539 if (info->builtin_domain) {
540 /* No groups in builtin. */
544 if (info->groups == NULL) {
545 info->groups = pdb_search_groups(info);
546 if (info->groups == NULL) {
550 /* Fetch the last possible entry, thus trigger an enumeration */
551 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
553 /* Ensure we cache this enumeration. */
554 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
556 return info->groups->num_entries;
559 static uint32 count_sam_aliases(struct disp_info *info)
561 struct samr_displayentry *entry;
563 if (info->aliases == NULL) {
564 info->aliases = pdb_search_aliases(info, &info->sid);
565 if (info->aliases == NULL) {
569 /* Fetch the last possible entry, thus trigger an enumeration */
570 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
572 /* Ensure we cache this enumeration. */
573 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
575 return info->aliases->num_entries;
578 /*******************************************************************
580 ********************************************************************/
582 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
584 if (!close_policy_hnd(p, r->in.handle)) {
585 return NT_STATUS_INVALID_HANDLE;
588 ZERO_STRUCTP(r->out.handle);
593 /*******************************************************************
595 ********************************************************************/
597 NTSTATUS _samr_OpenDomain(pipes_struct *p,
598 struct samr_OpenDomain *r)
600 struct samr_info *info;
601 SEC_DESC *psd = NULL;
603 uint32 des_access = r->in.access_mask;
608 /* find the connection policy handle. */
610 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
611 return NT_STATUS_INVALID_HANDLE;
613 status = access_check_samr_function(info->acc_granted,
614 SAMR_ACCESS_OPEN_DOMAIN,
615 "_samr_OpenDomain" );
617 if ( !NT_STATUS_IS_OK(status) )
620 /*check if access can be granted as requested by client. */
621 map_max_allowed_access(p->server_info->ptok, &des_access);
623 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
624 se_map_generic( &des_access, &dom_generic_mapping );
626 se_priv_copy( &se_rights, &se_machine_account );
627 se_priv_add( &se_rights, &se_add_users );
629 status = access_check_samr_object( psd, p->server_info->ptok,
630 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
631 &acc_granted, "_samr_OpenDomain" );
633 if ( !NT_STATUS_IS_OK(status) )
636 if (!sid_check_is_domain(r->in.sid) &&
637 !sid_check_is_builtin(r->in.sid)) {
638 return NT_STATUS_NO_SUCH_DOMAIN;
641 /* associate the domain SID with the (unique) handle. */
642 if ((info = get_samr_info_by_sid(p->mem_ctx, r->in.sid))==NULL)
643 return NT_STATUS_NO_MEMORY;
644 info->acc_granted = acc_granted;
646 /* get a (unique) handle. open a policy on it. */
647 if (!create_policy_hnd(p, r->out.domain_handle, info))
648 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
650 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
655 /*******************************************************************
657 ********************************************************************/
659 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
660 struct samr_GetUserPwInfo *r)
662 struct samr_info *info = NULL;
663 enum lsa_SidType sid_type;
664 uint32_t min_password_length = 0;
665 uint32_t password_properties = 0;
669 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
671 /* find the policy handle. open a policy on it. */
672 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
673 return NT_STATUS_INVALID_HANDLE;
676 status = access_check_samr_function(info->acc_granted,
677 SAMR_USER_ACCESS_GET_ATTRIBUTES,
678 "_samr_GetUserPwInfo" );
679 if (!NT_STATUS_IS_OK(status)) {
683 if (!sid_check_is_in_our_domain(&info->sid)) {
684 return NT_STATUS_OBJECT_TYPE_MISMATCH;
688 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
691 return NT_STATUS_NO_SUCH_USER;
697 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
698 &min_password_length);
699 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
700 &password_properties);
703 if (lp_check_password_script() && *lp_check_password_script()) {
704 password_properties |= DOMAIN_PASSWORD_COMPLEX;
712 r->out.info->min_password_length = min_password_length;
713 r->out.info->password_properties = password_properties;
715 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
720 /*******************************************************************
721 ********************************************************************/
723 static bool get_lsa_policy_samr_sid( pipes_struct *p, struct policy_handle *pol,
724 DOM_SID *sid, uint32 *acc_granted,
725 DISP_INFO **ppdisp_info)
727 struct samr_info *info = NULL;
729 /* find the policy handle. open a policy on it. */
730 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
737 *acc_granted = info->acc_granted;
739 *ppdisp_info = info->disp_info;
745 /*******************************************************************
747 ********************************************************************/
749 NTSTATUS _samr_SetSecurity(pipes_struct *p,
750 struct samr_SetSecurity *r)
753 uint32 acc_granted, i;
756 struct samu *sampass=NULL;
759 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
760 return NT_STATUS_INVALID_HANDLE;
762 if (!(sampass = samu_new( p->mem_ctx))) {
763 DEBUG(0,("No memory!\n"));
764 return NT_STATUS_NO_MEMORY;
767 /* get the user record */
769 ret = pdb_getsampwsid(sampass, &pol_sid);
773 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
774 TALLOC_FREE(sampass);
775 return NT_STATUS_INVALID_HANDLE;
778 dacl = r->in.sdbuf->sd->dacl;
779 for (i=0; i < dacl->num_aces; i++) {
780 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
781 ret = pdb_set_pass_can_change(sampass,
782 (dacl->aces[i].access_mask &
783 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
790 TALLOC_FREE(sampass);
791 return NT_STATUS_ACCESS_DENIED;
794 status = access_check_samr_function(acc_granted,
795 SAMR_USER_ACCESS_SET_ATTRIBUTES,
796 "_samr_SetSecurity");
797 if (NT_STATUS_IS_OK(status)) {
799 status = pdb_update_sam_account(sampass);
803 TALLOC_FREE(sampass);
808 /*******************************************************************
809 build correct perms based on policies and password times for _samr_query_sec_obj
810 *******************************************************************/
811 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
813 struct samu *sampass=NULL;
816 if ( !(sampass = samu_new( mem_ctx )) ) {
817 DEBUG(0,("No memory!\n"));
822 ret = pdb_getsampwsid(sampass, user_sid);
826 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
827 TALLOC_FREE(sampass);
831 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
833 if (pdb_get_pass_can_change(sampass)) {
834 TALLOC_FREE(sampass);
837 TALLOC_FREE(sampass);
842 /*******************************************************************
844 ********************************************************************/
846 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
847 struct samr_QuerySecurity *r)
851 SEC_DESC * psd = NULL;
856 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
857 return NT_STATUS_INVALID_HANDLE;
859 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
860 sid_string_dbg(&pol_sid)));
862 status = access_check_samr_function(acc_granted,
863 STD_RIGHT_READ_CONTROL_ACCESS,
864 "_samr_QuerySecurity");
865 if (!NT_STATUS_IS_OK(status)) {
869 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
871 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
872 if (pol_sid.sid_rev_num == 0) {
873 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
874 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
875 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
876 /* check if it is our domain SID */
877 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
878 "with SID: %s\n", sid_string_dbg(&pol_sid)));
879 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
880 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
881 /* check if it is the Builtin Domain */
882 /* TODO: Builtin probably needs a different SD with restricted write access*/
883 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
884 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
885 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
886 } else if (sid_check_is_in_our_domain(&pol_sid) ||
887 sid_check_is_in_builtin(&pol_sid)) {
888 /* TODO: different SDs have to be generated for aliases groups and users.
889 Currently all three get a default user SD */
890 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
891 "with SID: %s\n", sid_string_dbg(&pol_sid)));
892 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
893 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
894 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
896 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
897 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
900 return NT_STATUS_OBJECT_TYPE_MISMATCH;
903 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
904 return NT_STATUS_NO_MEMORY;
909 /*******************************************************************
910 makes a SAM_ENTRY / UNISTR2* structure from a user list.
911 ********************************************************************/
913 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
914 struct samr_SamEntry **sam_pp,
915 uint32_t num_entries,
917 struct samr_displayentry *entries)
920 struct samr_SamEntry *sam;
924 if (num_entries == 0) {
928 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
930 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
931 return NT_STATUS_NO_MEMORY;
934 for (i = 0; i < num_entries; i++) {
937 * usrmgr expects a non-NULL terminated string with
938 * trust relationships
940 if (entries[i].acct_flags & ACB_DOMTRUST) {
941 init_unistr2(&uni_temp_name, entries[i].account_name,
944 init_unistr2(&uni_temp_name, entries[i].account_name,
948 init_lsa_String(&sam[i].name, entries[i].account_name);
949 sam[i].idx = entries[i].rid;
957 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
959 /*******************************************************************
960 _samr_EnumDomainUsers
961 ********************************************************************/
963 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
964 struct samr_EnumDomainUsers *r)
967 struct samr_info *info = NULL;
969 uint32 enum_context = *r->in.resume_handle;
970 enum remote_arch_types ra_type = get_remote_arch();
971 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
972 uint32 max_entries = max_sam_entries;
973 struct samr_displayentry *entries = NULL;
974 struct samr_SamArray *samr_array = NULL;
975 struct samr_SamEntry *samr_entries = NULL;
977 /* find the policy handle. open a policy on it. */
978 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
979 return NT_STATUS_INVALID_HANDLE;
981 status = access_check_samr_function(info->acc_granted,
982 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
983 "_samr_EnumDomainUsers");
984 if (!NT_STATUS_IS_OK(status)) {
988 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
990 if (info->builtin_domain) {
991 /* No users in builtin. */
992 *r->out.resume_handle = *r->in.resume_handle;
993 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
997 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
999 return NT_STATUS_NO_MEMORY;
1001 *r->out.sam = samr_array;
1007 if ((info->disp_info->enum_users != NULL) &&
1008 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1009 TALLOC_FREE(info->disp_info->enum_users);
1012 if (info->disp_info->enum_users == NULL) {
1013 info->disp_info->enum_users = pdb_search_users(
1014 info->disp_info, r->in.acct_flags);
1015 info->disp_info->enum_acb_mask = r->in.acct_flags;
1018 if (info->disp_info->enum_users == NULL) {
1019 /* END AS ROOT !!!! */
1021 return NT_STATUS_ACCESS_DENIED;
1024 num_account = pdb_search_entries(info->disp_info->enum_users,
1025 enum_context, max_entries,
1028 /* END AS ROOT !!!! */
1032 if (num_account == 0) {
1033 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1034 "total entries\n"));
1035 *r->out.resume_handle = *r->in.resume_handle;
1036 return NT_STATUS_OK;
1039 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1040 num_account, enum_context,
1042 if (!NT_STATUS_IS_OK(status)) {
1046 if (max_entries <= num_account) {
1047 status = STATUS_MORE_ENTRIES;
1049 status = NT_STATUS_OK;
1052 /* Ensure we cache this enumeration. */
1053 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1055 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1057 samr_array->count = num_account;
1058 samr_array->entries = samr_entries;
1060 *r->out.resume_handle = *r->in.resume_handle + num_account;
1061 *r->out.num_entries = num_account;
1063 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1068 /*******************************************************************
1069 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1070 ********************************************************************/
1072 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1073 struct samr_SamEntry **sam_pp,
1074 uint32_t num_sam_entries,
1075 struct samr_displayentry *entries)
1077 struct samr_SamEntry *sam;
1082 if (num_sam_entries == 0) {
1086 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1091 for (i = 0; i < num_sam_entries; i++) {
1093 * JRA. I think this should include the null. TNG does not.
1095 init_lsa_String(&sam[i].name, entries[i].account_name);
1096 sam[i].idx = entries[i].rid;
1102 /*******************************************************************
1103 _samr_EnumDomainGroups
1104 ********************************************************************/
1106 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1107 struct samr_EnumDomainGroups *r)
1110 struct samr_info *info = NULL;
1111 struct samr_displayentry *groups;
1113 struct samr_SamArray *samr_array = NULL;
1114 struct samr_SamEntry *samr_entries = NULL;
1116 /* find the policy handle. open a policy on it. */
1117 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1118 return NT_STATUS_INVALID_HANDLE;
1120 status = access_check_samr_function(info->acc_granted,
1121 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1122 "_samr_EnumDomainGroups");
1123 if (!NT_STATUS_IS_OK(status)) {
1127 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1129 if (info->builtin_domain) {
1130 /* No groups in builtin. */
1131 *r->out.resume_handle = *r->in.resume_handle;
1132 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1136 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1138 return NT_STATUS_NO_MEMORY;
1141 /* the domain group array is being allocated in the function below */
1145 if (info->disp_info->groups == NULL) {
1146 info->disp_info->groups = pdb_search_groups(info->disp_info);
1148 if (info->disp_info->groups == NULL) {
1150 return NT_STATUS_ACCESS_DENIED;
1154 num_groups = pdb_search_entries(info->disp_info->groups,
1155 *r->in.resume_handle,
1156 MAX_SAM_ENTRIES, &groups);
1159 /* Ensure we cache this enumeration. */
1160 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1162 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1163 num_groups, groups);
1165 samr_array->count = num_groups;
1166 samr_array->entries = samr_entries;
1168 *r->out.sam = samr_array;
1169 *r->out.num_entries = num_groups;
1170 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1172 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1177 /*******************************************************************
1178 _samr_EnumDomainAliases
1179 ********************************************************************/
1181 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1182 struct samr_EnumDomainAliases *r)
1185 struct samr_info *info;
1186 struct samr_displayentry *aliases;
1187 uint32 num_aliases = 0;
1188 struct samr_SamArray *samr_array = NULL;
1189 struct samr_SamEntry *samr_entries = NULL;
1191 /* find the policy handle. open a policy on it. */
1192 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1193 return NT_STATUS_INVALID_HANDLE;
1195 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1196 sid_string_dbg(&info->sid)));
1198 status = access_check_samr_function(info->acc_granted,
1199 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1200 "_samr_EnumDomainAliases");
1201 if (!NT_STATUS_IS_OK(status)) {
1205 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1207 return NT_STATUS_NO_MEMORY;
1212 if (info->disp_info->aliases == NULL) {
1213 info->disp_info->aliases = pdb_search_aliases(
1214 info->disp_info, &info->sid);
1215 if (info->disp_info->aliases == NULL) {
1217 return NT_STATUS_ACCESS_DENIED;
1221 num_aliases = pdb_search_entries(info->disp_info->aliases,
1222 *r->in.resume_handle,
1223 MAX_SAM_ENTRIES, &aliases);
1226 /* Ensure we cache this enumeration. */
1227 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1229 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1230 num_aliases, aliases);
1232 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1234 samr_array->count = num_aliases;
1235 samr_array->entries = samr_entries;
1237 *r->out.sam = samr_array;
1238 *r->out.num_entries = num_aliases;
1239 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1244 /*******************************************************************
1245 inits a samr_DispInfoGeneral structure.
1246 ********************************************************************/
1248 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1249 struct samr_DispInfoGeneral *r,
1250 uint32_t num_entries,
1252 struct samr_displayentry *entries)
1256 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1258 if (num_entries == 0) {
1259 return NT_STATUS_OK;
1262 r->count = num_entries;
1264 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1266 return NT_STATUS_NO_MEMORY;
1269 for (i = 0; i < num_entries ; i++) {
1271 init_lsa_String(&r->entries[i].account_name,
1272 entries[i].account_name);
1274 init_lsa_String(&r->entries[i].description,
1275 entries[i].description);
1277 init_lsa_String(&r->entries[i].full_name,
1278 entries[i].fullname);
1280 r->entries[i].rid = entries[i].rid;
1281 r->entries[i].acct_flags = entries[i].acct_flags;
1282 r->entries[i].idx = start_idx+i+1;
1285 return NT_STATUS_OK;
1288 /*******************************************************************
1289 inits a samr_DispInfoFull structure.
1290 ********************************************************************/
1292 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1293 struct samr_DispInfoFull *r,
1294 uint32_t num_entries,
1296 struct samr_displayentry *entries)
1300 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1302 if (num_entries == 0) {
1303 return NT_STATUS_OK;
1306 r->count = num_entries;
1308 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1310 return NT_STATUS_NO_MEMORY;
1313 for (i = 0; i < num_entries ; i++) {
1315 init_lsa_String(&r->entries[i].account_name,
1316 entries[i].account_name);
1318 init_lsa_String(&r->entries[i].description,
1319 entries[i].description);
1321 r->entries[i].rid = entries[i].rid;
1322 r->entries[i].acct_flags = entries[i].acct_flags;
1323 r->entries[i].idx = start_idx+i+1;
1326 return NT_STATUS_OK;
1329 /*******************************************************************
1330 inits a samr_DispInfoFullGroups structure.
1331 ********************************************************************/
1333 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1334 struct samr_DispInfoFullGroups *r,
1335 uint32_t num_entries,
1337 struct samr_displayentry *entries)
1341 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1343 if (num_entries == 0) {
1344 return NT_STATUS_OK;
1347 r->count = num_entries;
1349 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1351 return NT_STATUS_NO_MEMORY;
1354 for (i = 0; i < num_entries ; i++) {
1356 init_lsa_String(&r->entries[i].account_name,
1357 entries[i].account_name);
1359 init_lsa_String(&r->entries[i].description,
1360 entries[i].description);
1362 r->entries[i].rid = entries[i].rid;
1363 r->entries[i].acct_flags = entries[i].acct_flags;
1364 r->entries[i].idx = start_idx+i+1;
1367 return NT_STATUS_OK;
1370 /*******************************************************************
1371 inits a samr_DispInfoAscii structure.
1372 ********************************************************************/
1374 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1375 struct samr_DispInfoAscii *r,
1376 uint32_t num_entries,
1378 struct samr_displayentry *entries)
1382 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1384 if (num_entries == 0) {
1385 return NT_STATUS_OK;
1388 r->count = num_entries;
1390 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1392 return NT_STATUS_NO_MEMORY;
1395 for (i = 0; i < num_entries ; i++) {
1397 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1398 entries[i].account_name);
1400 r->entries[i].idx = start_idx+i+1;
1403 return NT_STATUS_OK;
1406 /*******************************************************************
1407 inits a samr_DispInfoAscii structure.
1408 ********************************************************************/
1410 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1411 struct samr_DispInfoAscii *r,
1412 uint32_t num_entries,
1414 struct samr_displayentry *entries)
1418 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1420 if (num_entries == 0) {
1421 return NT_STATUS_OK;
1424 r->count = num_entries;
1426 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1428 return NT_STATUS_NO_MEMORY;
1431 for (i = 0; i < num_entries ; i++) {
1433 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1434 entries[i].account_name);
1436 r->entries[i].idx = start_idx+i+1;
1439 return NT_STATUS_OK;
1442 /*******************************************************************
1443 _samr_QueryDisplayInfo
1444 ********************************************************************/
1446 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1447 struct samr_QueryDisplayInfo *r)
1450 struct samr_info *info = NULL;
1451 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1453 uint32 max_entries = r->in.max_entries;
1454 uint32 enum_context = r->in.start_idx;
1455 uint32 max_size = r->in.buf_size;
1457 union samr_DispInfo *disp_info = r->out.info;
1459 uint32 temp_size=0, total_data_size=0;
1460 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1461 uint32 num_account = 0;
1462 enum remote_arch_types ra_type = get_remote_arch();
1463 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1464 struct samr_displayentry *entries = NULL;
1466 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1468 /* find the policy handle. open a policy on it. */
1469 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1470 return NT_STATUS_INVALID_HANDLE;
1472 if (info->builtin_domain) {
1473 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1474 return NT_STATUS_OK;
1477 status = access_check_samr_function(info->acc_granted,
1478 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1479 "_samr_QueryDisplayInfo");
1480 if (!NT_STATUS_IS_OK(status)) {
1485 * calculate how many entries we will return.
1487 * - the number of entries the client asked
1488 * - our limit on that
1489 * - the starting point (enumeration context)
1490 * - the buffer size the client will accept
1494 * We are a lot more like W2K. Instead of reading the SAM
1495 * each time to find the records we need to send back,
1496 * we read it once and link that copy to the sam handle.
1497 * For large user list (over the MAX_SAM_ENTRIES)
1498 * it's a definitive win.
1499 * second point to notice: between enumerations
1500 * our sam is now the same as it's a snapshoot.
1501 * third point: got rid of the static SAM_USER_21 struct
1502 * no more intermediate.
1503 * con: it uses much more memory, as a full copy is stored
1506 * If you want to change it, think twice and think
1507 * of the second point , that's really important.
1512 if ((r->in.level < 1) || (r->in.level > 5)) {
1513 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1514 (unsigned int)r->in.level ));
1515 return NT_STATUS_INVALID_INFO_CLASS;
1518 /* first limit the number of entries we will return */
1519 if(max_entries > max_sam_entries) {
1520 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1521 "entries, limiting to %d\n", max_entries,
1523 max_entries = max_sam_entries;
1526 /* calculate the size and limit on the number of entries we will
1529 temp_size=max_entries*struct_size;
1531 if (temp_size>max_size) {
1532 max_entries=MIN((max_size/struct_size),max_entries);;
1533 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1534 "only %d entries\n", max_entries));
1539 /* THe following done as ROOT. Don't return without unbecome_root(). */
1541 switch (r->in.level) {
1544 if (info->disp_info->users == NULL) {
1545 info->disp_info->users = pdb_search_users(
1546 info->disp_info, ACB_NORMAL);
1547 if (info->disp_info->users == NULL) {
1549 return NT_STATUS_ACCESS_DENIED;
1551 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1552 (unsigned int)enum_context ));
1554 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1555 (unsigned int)enum_context ));
1558 num_account = pdb_search_entries(info->disp_info->users,
1559 enum_context, max_entries,
1563 if (info->disp_info->machines == NULL) {
1564 info->disp_info->machines = pdb_search_users(
1565 info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1566 if (info->disp_info->machines == NULL) {
1568 return NT_STATUS_ACCESS_DENIED;
1570 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1571 (unsigned int)enum_context ));
1573 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1574 (unsigned int)enum_context ));
1577 num_account = pdb_search_entries(info->disp_info->machines,
1578 enum_context, max_entries,
1583 if (info->disp_info->groups == NULL) {
1584 info->disp_info->groups = pdb_search_groups(
1586 if (info->disp_info->groups == NULL) {
1588 return NT_STATUS_ACCESS_DENIED;
1590 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1591 (unsigned int)enum_context ));
1593 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1594 (unsigned int)enum_context ));
1597 num_account = pdb_search_entries(info->disp_info->groups,
1598 enum_context, max_entries,
1603 smb_panic("info class changed");
1609 /* Now create reply structure */
1610 switch (r->in.level) {
1612 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1613 num_account, enum_context,
1617 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1618 num_account, enum_context,
1622 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1623 num_account, enum_context,
1627 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1628 num_account, enum_context,
1632 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1633 num_account, enum_context,
1637 smb_panic("info class changed");
1641 if (!NT_STATUS_IS_OK(disp_ret))
1644 /* calculate the total size */
1645 total_data_size=num_account*struct_size;
1647 if (max_entries <= num_account) {
1648 status = STATUS_MORE_ENTRIES;
1650 status = NT_STATUS_OK;
1653 /* Ensure we cache this enumeration. */
1654 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1656 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1658 *r->out.total_size = total_data_size;
1659 *r->out.returned_size = temp_size;
1664 /****************************************************************
1665 _samr_QueryDisplayInfo2
1666 ****************************************************************/
1668 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1669 struct samr_QueryDisplayInfo2 *r)
1671 struct samr_QueryDisplayInfo q;
1673 q.in.domain_handle = r->in.domain_handle;
1674 q.in.level = r->in.level;
1675 q.in.start_idx = r->in.start_idx;
1676 q.in.max_entries = r->in.max_entries;
1677 q.in.buf_size = r->in.buf_size;
1679 q.out.total_size = r->out.total_size;
1680 q.out.returned_size = r->out.returned_size;
1681 q.out.info = r->out.info;
1683 return _samr_QueryDisplayInfo(p, &q);
1686 /****************************************************************
1687 _samr_QueryDisplayInfo3
1688 ****************************************************************/
1690 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1691 struct samr_QueryDisplayInfo3 *r)
1693 struct samr_QueryDisplayInfo q;
1695 q.in.domain_handle = r->in.domain_handle;
1696 q.in.level = r->in.level;
1697 q.in.start_idx = r->in.start_idx;
1698 q.in.max_entries = r->in.max_entries;
1699 q.in.buf_size = r->in.buf_size;
1701 q.out.total_size = r->out.total_size;
1702 q.out.returned_size = r->out.returned_size;
1703 q.out.info = r->out.info;
1705 return _samr_QueryDisplayInfo(p, &q);
1708 /*******************************************************************
1709 _samr_QueryAliasInfo
1710 ********************************************************************/
1712 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1713 struct samr_QueryAliasInfo *r)
1716 struct acct_info info;
1719 union samr_AliasInfo *alias_info = NULL;
1720 const char *alias_name = NULL;
1721 const char *alias_description = NULL;
1723 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1725 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1727 return NT_STATUS_NO_MEMORY;
1730 /* find the policy handle. open a policy on it. */
1731 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1732 return NT_STATUS_INVALID_HANDLE;
1734 status = access_check_samr_function(acc_granted,
1735 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1736 "_samr_QueryAliasInfo");
1737 if (!NT_STATUS_IS_OK(status)) {
1742 status = pdb_get_aliasinfo(&sid, &info);
1745 if ( !NT_STATUS_IS_OK(status))
1748 /* FIXME: info contains fstrings */
1749 alias_name = talloc_strdup(r, info.acct_name);
1750 alias_description = talloc_strdup(r, info.acct_desc);
1752 switch (r->in.level) {
1754 alias_info->all.name.string = alias_name;
1755 alias_info->all.num_members = 1; /* ??? */
1756 alias_info->all.description.string = alias_description;
1758 case ALIASINFODESCRIPTION:
1759 alias_info->description.string = alias_description;
1762 return NT_STATUS_INVALID_INFO_CLASS;
1765 *r->out.info = alias_info;
1767 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1769 return NT_STATUS_OK;
1772 /*******************************************************************
1774 ********************************************************************/
1776 NTSTATUS _samr_LookupNames(pipes_struct *p,
1777 struct samr_LookupNames *r)
1781 enum lsa_SidType *type;
1783 int num_rids = r->in.num_names;
1786 struct samr_Ids rids, types;
1787 uint32_t num_mapped = 0;
1789 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1791 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1792 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1795 status = access_check_samr_function(acc_granted,
1796 0, /* Don't know the acc_bits yet */
1797 "_samr_LookupNames");
1798 if (!NT_STATUS_IS_OK(status)) {
1802 if (num_rids > MAX_SAM_ENTRIES) {
1803 num_rids = MAX_SAM_ENTRIES;
1804 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1807 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1808 NT_STATUS_HAVE_NO_MEMORY(rid);
1810 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1811 NT_STATUS_HAVE_NO_MEMORY(type);
1813 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1814 sid_string_dbg(&pol_sid)));
1816 for (i = 0; i < num_rids; i++) {
1818 status = NT_STATUS_NONE_MAPPED;
1819 type[i] = SID_NAME_UNKNOWN;
1821 rid[i] = 0xffffffff;
1823 if (sid_check_is_builtin(&pol_sid)) {
1824 if (lookup_builtin_name(r->in.names[i].string,
1827 type[i] = SID_NAME_ALIAS;
1830 lookup_global_sam_name(r->in.names[i].string, 0,
1834 if (type[i] != SID_NAME_UNKNOWN) {
1839 if (num_mapped == num_rids) {
1840 status = NT_STATUS_OK;
1841 } else if (num_mapped == 0) {
1842 status = NT_STATUS_NONE_MAPPED;
1844 status = STATUS_SOME_UNMAPPED;
1847 rids.count = num_rids;
1850 types.count = num_rids;
1853 *r->out.rids = rids;
1854 *r->out.types = types;
1856 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1861 /*******************************************************************
1862 _samr_ChangePasswordUser2
1863 ********************************************************************/
1865 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1866 struct samr_ChangePasswordUser2 *r)
1872 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1874 fstrcpy(user_name, r->in.account->string);
1875 fstrcpy(wks, r->in.server->string);
1877 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1880 * Pass the user through the NT -> unix user mapping
1884 (void)map_username(user_name);
1887 * UNIX username case mangling not required, pass_oem_change
1888 * is case insensitive.
1891 status = pass_oem_change(user_name,
1892 r->in.lm_password->data,
1893 r->in.lm_verifier->hash,
1894 r->in.nt_password->data,
1895 r->in.nt_verifier->hash,
1898 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1903 /*******************************************************************
1904 _samr_ChangePasswordUser3
1905 ********************************************************************/
1907 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1908 struct samr_ChangePasswordUser3 *r)
1912 const char *wks = NULL;
1913 uint32 reject_reason;
1914 struct samr_DomInfo1 *dominfo = NULL;
1915 struct samr_ChangeReject *reject = NULL;
1918 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1920 fstrcpy(user_name, r->in.account->string);
1921 if (r->in.server && r->in.server->string) {
1922 wks = r->in.server->string;
1925 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1928 * Pass the user through the NT -> unix user mapping
1932 (void)map_username(user_name);
1935 * UNIX username case mangling not required, pass_oem_change
1936 * is case insensitive.
1939 status = pass_oem_change(user_name,
1940 r->in.lm_password->data,
1941 r->in.lm_verifier->hash,
1942 r->in.nt_password->data,
1943 r->in.nt_verifier->hash,
1946 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1947 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1949 time_t u_expire, u_min_age;
1950 uint32 account_policy_temp;
1952 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1954 return NT_STATUS_NO_MEMORY;
1957 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1959 return NT_STATUS_NO_MEMORY;
1966 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
1967 dominfo->min_password_length = tmp;
1969 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
1970 dominfo->password_history_length = tmp;
1972 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
1973 &dominfo->password_properties);
1975 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1976 u_expire = account_policy_temp;
1978 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1979 u_min_age = account_policy_temp;
1985 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
1986 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
1988 if (lp_check_password_script() && *lp_check_password_script()) {
1989 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
1992 reject->reason = reject_reason;
1994 *r->out.dominfo = dominfo;
1995 *r->out.reject = reject;
1998 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2003 /*******************************************************************
2004 makes a SAMR_R_LOOKUP_RIDS structure.
2005 ********************************************************************/
2007 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2009 struct lsa_String **lsa_name_array_p)
2011 struct lsa_String *lsa_name_array = NULL;
2014 *lsa_name_array_p = NULL;
2016 if (num_names != 0) {
2017 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2018 if (!lsa_name_array) {
2023 for (i = 0; i < num_names; i++) {
2024 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2025 init_lsa_String(&lsa_name_array[i], names[i]);
2028 *lsa_name_array_p = lsa_name_array;
2033 /*******************************************************************
2035 ********************************************************************/
2037 NTSTATUS _samr_LookupRids(pipes_struct *p,
2038 struct samr_LookupRids *r)
2042 enum lsa_SidType *attrs = NULL;
2043 uint32 *wire_attrs = NULL;
2045 int num_rids = (int)r->in.num_rids;
2048 struct lsa_Strings names_array;
2049 struct samr_Ids types_array;
2050 struct lsa_String *lsa_names = NULL;
2052 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2054 /* find the policy handle. open a policy on it. */
2055 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2056 return NT_STATUS_INVALID_HANDLE;
2058 status = access_check_samr_function(acc_granted,
2059 0, /* Don't know the acc_bits yet */
2060 "_samr_LookupRids");
2061 if (!NT_STATUS_IS_OK(status)) {
2065 if (num_rids > 1000) {
2066 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2067 "to samba4 idl this is not possible\n", num_rids));
2068 return NT_STATUS_UNSUCCESSFUL;
2072 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2073 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2074 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2076 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2077 return NT_STATUS_NO_MEMORY;
2084 become_root(); /* lookup_sid can require root privs */
2085 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2089 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2090 status = NT_STATUS_OK;
2093 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2095 return NT_STATUS_NO_MEMORY;
2098 /* Convert from enum lsa_SidType to uint32 for wire format. */
2099 for (i = 0; i < num_rids; i++) {
2100 wire_attrs[i] = (uint32)attrs[i];
2103 names_array.count = num_rids;
2104 names_array.names = lsa_names;
2106 types_array.count = num_rids;
2107 types_array.ids = wire_attrs;
2109 *r->out.names = names_array;
2110 *r->out.types = types_array;
2112 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2117 /*******************************************************************
2119 ********************************************************************/
2121 NTSTATUS _samr_OpenUser(pipes_struct *p,
2122 struct samr_OpenUser *r)
2124 struct samu *sampass=NULL;
2126 struct samr_info *info = NULL;
2127 SEC_DESC *psd = NULL;
2129 uint32 des_access = r->in.access_mask;
2135 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2137 if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
2138 return NT_STATUS_INVALID_HANDLE;
2140 nt_status = access_check_samr_function(acc_granted,
2141 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2144 if ( !NT_STATUS_IS_OK(nt_status) )
2147 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2148 return NT_STATUS_NO_MEMORY;
2151 /* append the user's RID to it */
2153 if (!sid_append_rid(&sid, r->in.rid))
2154 return NT_STATUS_NO_SUCH_USER;
2156 /* check if access can be granted as requested by client. */
2158 map_max_allowed_access(p->server_info->ptok, &des_access);
2160 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2161 se_map_generic(&des_access, &usr_generic_mapping);
2163 se_priv_copy( &se_rights, &se_machine_account );
2164 se_priv_add( &se_rights, &se_add_users );
2166 nt_status = access_check_samr_object(psd, p->server_info->ptok,
2167 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2168 &acc_granted, "_samr_OpenUser");
2170 if ( !NT_STATUS_IS_OK(nt_status) )
2174 ret=pdb_getsampwsid(sampass, &sid);
2177 /* check that the SID exists in our domain. */
2179 return NT_STATUS_NO_SUCH_USER;
2182 TALLOC_FREE(sampass);
2184 /* associate the user's SID and access bits with the new handle. */
2185 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
2186 return NT_STATUS_NO_MEMORY;
2187 info->acc_granted = acc_granted;
2189 /* get a (unique) handle. open a policy on it. */
2190 if (!create_policy_hnd(p, r->out.user_handle, info))
2191 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2193 return NT_STATUS_OK;
2196 /*************************************************************************
2197 *************************************************************************/
2199 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2201 struct lsa_BinaryString **_r)
2203 struct lsa_BinaryString *r;
2206 return NT_STATUS_INVALID_PARAMETER;
2209 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2211 return NT_STATUS_NO_MEMORY;
2214 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2216 return NT_STATUS_NO_MEMORY;
2218 memcpy(r->array, blob->data, blob->length);
2219 r->size = blob->length;
2220 r->length = blob->length;
2223 return NT_STATUS_NO_MEMORY;
2228 return NT_STATUS_OK;
2231 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2232 struct samr_UserInfo5 *r,
2234 DOM_SID *domain_sid)
2236 const DOM_SID *sid_user, *sid_group;
2237 uint32_t rid, primary_gid;
2239 sid_user = pdb_get_user_sid(pw);
2241 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2242 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2243 "the domain sid %s. Failing operation.\n",
2244 pdb_get_username(pw), sid_string_dbg(sid_user),
2245 sid_string_dbg(domain_sid)));
2246 return NT_STATUS_UNSUCCESSFUL;
2250 sid_group = pdb_get_group_sid(pw);
2253 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2254 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2255 "which conflicts with the domain sid %s. Failing operation.\n",
2256 pdb_get_username(pw), sid_string_dbg(sid_group),
2257 sid_string_dbg(domain_sid)));
2258 return NT_STATUS_UNSUCCESSFUL;
2261 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2262 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2263 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2264 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2266 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2267 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2268 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2269 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2270 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2271 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2272 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2273 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2275 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2277 r->primary_gid = primary_gid;
2278 r->acct_flags = pdb_get_acct_ctrl(pw);
2279 r->bad_password_count = pdb_get_bad_password_count(pw);
2280 r->logon_count = pdb_get_logon_count(pw);
2282 return NT_STATUS_OK;
2285 /*************************************************************************
2286 get_user_info_7. Safe. Only gives out account_name.
2287 *************************************************************************/
2289 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2290 struct samr_UserInfo7 *r,
2291 struct samu *smbpass)
2293 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2294 if (!r->account_name.string) {
2295 return NT_STATUS_NO_MEMORY;
2298 return NT_STATUS_OK;
2301 /*************************************************************************
2302 get_user_info_9. Only gives out primary group SID.
2303 *************************************************************************/
2305 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2306 struct samr_UserInfo9 *r,
2307 struct samu *smbpass)
2309 r->primary_gid = pdb_get_group_rid(smbpass);
2311 return NT_STATUS_OK;
2314 /*************************************************************************
2315 get_user_info_16. Safe. Only gives out acb bits.
2316 *************************************************************************/
2318 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2319 struct samr_UserInfo16 *r,
2320 struct samu *smbpass)
2322 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2324 return NT_STATUS_OK;
2327 /*************************************************************************
2328 get_user_info_18. OK - this is the killer as it gives out password info.
2329 Ensure that this is only allowed on an encrypted connection with a root
2331 *************************************************************************/
2333 static NTSTATUS get_user_info_18(pipes_struct *p,
2334 TALLOC_CTX *mem_ctx,
2335 struct samr_UserInfo18 *r,
2338 struct samu *smbpass=NULL;
2343 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2344 return NT_STATUS_ACCESS_DENIED;
2347 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2348 return NT_STATUS_ACCESS_DENIED;
2352 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2355 if ( !(smbpass = samu_new( mem_ctx )) ) {
2356 return NT_STATUS_NO_MEMORY;
2359 ret = pdb_getsampwsid(smbpass, user_sid);
2362 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2363 TALLOC_FREE(smbpass);
2364 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2367 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2369 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2370 TALLOC_FREE(smbpass);
2371 return NT_STATUS_ACCOUNT_DISABLED;
2374 r->lm_pwd_active = true;
2375 r->nt_pwd_active = true;
2376 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2377 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2378 r->password_expired = 0; /* FIXME */
2380 TALLOC_FREE(smbpass);
2382 return NT_STATUS_OK;
2385 /*************************************************************************
2387 *************************************************************************/
2389 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2390 struct samr_UserInfo20 *r,
2391 struct samu *sampass)
2393 const char *munged_dial = NULL;
2396 struct lsa_BinaryString *parameters = NULL;
2400 munged_dial = pdb_get_munged_dial(sampass);
2402 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2403 munged_dial, (int)strlen(munged_dial)));
2406 blob = base64_decode_data_blob(munged_dial);
2408 blob = data_blob_string_const_null("");
2411 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2412 data_blob_free(&blob);
2413 if (!NT_STATUS_IS_OK(status)) {
2417 r->parameters = *parameters;
2419 return NT_STATUS_OK;
2423 /*************************************************************************
2425 *************************************************************************/
2427 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2428 struct samr_UserInfo21 *r,
2430 DOM_SID *domain_sid)
2433 const DOM_SID *sid_user, *sid_group;
2434 uint32_t rid, primary_gid;
2435 NTTIME force_password_change;
2436 time_t must_change_time;
2437 struct lsa_BinaryString *parameters = NULL;
2438 const char *munged_dial = NULL;
2443 sid_user = pdb_get_user_sid(pw);
2445 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2446 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2447 "the domain sid %s. Failing operation.\n",
2448 pdb_get_username(pw), sid_string_dbg(sid_user),
2449 sid_string_dbg(domain_sid)));
2450 return NT_STATUS_UNSUCCESSFUL;
2454 sid_group = pdb_get_group_sid(pw);
2457 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2458 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2459 "which conflicts with the domain sid %s. Failing operation.\n",
2460 pdb_get_username(pw), sid_string_dbg(sid_group),
2461 sid_string_dbg(domain_sid)));
2462 return NT_STATUS_UNSUCCESSFUL;
2465 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2466 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2467 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2468 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2469 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2471 must_change_time = pdb_get_pass_must_change_time(pw);
2472 if (must_change_time == get_time_t_max()) {
2473 unix_to_nt_time_abs(&force_password_change, must_change_time);
2475 unix_to_nt_time(&force_password_change, must_change_time);
2478 munged_dial = pdb_get_munged_dial(pw);
2480 blob = base64_decode_data_blob(munged_dial);
2482 blob = data_blob_string_const_null("");
2485 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2486 data_blob_free(&blob);
2487 if (!NT_STATUS_IS_OK(status)) {
2491 r->force_password_change = force_password_change;
2493 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2494 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2495 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2496 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2497 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2498 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2499 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2500 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2501 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2503 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2504 r->parameters = *parameters;
2506 r->primary_gid = primary_gid;
2507 r->acct_flags = pdb_get_acct_ctrl(pw);
2508 r->bad_password_count = pdb_get_bad_password_count(pw);
2509 r->logon_count = pdb_get_logon_count(pw);
2510 r->fields_present = pdb_build_fields_present(pw);
2511 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2512 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2513 r->country_code = 0;
2515 r->lm_password_set = 0;
2516 r->nt_password_set = 0;
2521 Look at a user on a real NT4 PDC with usrmgr, press
2522 'ok'. Then you will see that fields_present is set to
2523 0x08f827fa. Look at the user immediately after that again,
2524 and you will see that 0x00fffff is returned. This solves
2525 the problem that you get access denied after having looked
2533 return NT_STATUS_OK;
2536 /*******************************************************************
2538 ********************************************************************/
2540 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2541 struct samr_QueryUserInfo *r)
2544 union samr_UserInfo *user_info = NULL;
2545 struct samr_info *info = NULL;
2549 struct samu *pwd = NULL;
2551 /* search for the handle */
2552 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2553 return NT_STATUS_INVALID_HANDLE;
2555 status = access_check_samr_function(info->acc_granted,
2556 SAMR_USER_ACCESS_GET_ATTRIBUTES,
2557 "_samr_QueryUserInfo");
2558 if (!NT_STATUS_IS_OK(status)) {
2562 domain_sid = info->sid;
2564 sid_split_rid(&domain_sid, &rid);
2566 if (!sid_check_is_in_our_domain(&info->sid))
2567 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2569 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2570 sid_string_dbg(&info->sid)));
2572 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2574 return NT_STATUS_NO_MEMORY;
2577 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2579 if (!(pwd = samu_new(p->mem_ctx))) {
2580 return NT_STATUS_NO_MEMORY;
2584 ret = pdb_getsampwsid(pwd, &info->sid);
2588 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2590 return NT_STATUS_NO_SUCH_USER;
2593 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2595 samr_clear_sam_passwd(pwd);
2597 switch (r->in.level) {
2599 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2602 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2605 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2608 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2611 /* level 18 is special */
2612 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2615 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
2618 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
2621 status = NT_STATUS_INVALID_INFO_CLASS;
2627 *r->out.info = user_info;
2629 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2634 /****************************************************************
2635 ****************************************************************/
2637 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2638 struct samr_QueryUserInfo2 *r)
2640 struct samr_QueryUserInfo u;
2642 u.in.user_handle = r->in.user_handle;
2643 u.in.level = r->in.level;
2644 u.out.info = r->out.info;
2646 return _samr_QueryUserInfo(p, &u);
2649 /*******************************************************************
2650 _samr_GetGroupsForUser
2651 ********************************************************************/
2653 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2654 struct samr_GetGroupsForUser *r)
2656 struct samu *sam_pass=NULL;
2659 struct samr_RidWithAttribute dom_gid;
2660 struct samr_RidWithAttribute *gids = NULL;
2661 uint32 primary_group_rid;
2662 size_t num_groups = 0;
2668 bool success = False;
2670 struct samr_RidWithAttributeArray *rids = NULL;
2673 * from the SID in the request:
2674 * we should send back the list of DOMAIN GROUPS
2675 * the user is a member of
2677 * and only the DOMAIN GROUPS
2678 * no ALIASES !!! neither aliases of the domain
2679 * nor aliases of the builtin SID
2684 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2686 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2688 return NT_STATUS_NO_MEMORY;
2691 /* find the policy handle. open a policy on it. */
2692 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2693 return NT_STATUS_INVALID_HANDLE;
2695 result = access_check_samr_function(acc_granted,
2696 SAMR_USER_ACCESS_GET_GROUPS,
2697 "_samr_GetGroupsForUser");
2698 if (!NT_STATUS_IS_OK(result)) {
2702 if (!sid_check_is_in_our_domain(&sid))
2703 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2705 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2706 return NT_STATUS_NO_MEMORY;
2710 ret = pdb_getsampwsid(sam_pass, &sid);
2714 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2715 sid_string_dbg(&sid)));
2716 return NT_STATUS_NO_SUCH_USER;
2721 /* make both calls inside the root block */
2723 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2724 &sids, &unix_gids, &num_groups);
2725 if ( NT_STATUS_IS_OK(result) ) {
2726 success = sid_peek_check_rid(get_global_sam_sid(),
2727 pdb_get_group_sid(sam_pass),
2728 &primary_group_rid);
2732 if (!NT_STATUS_IS_OK(result)) {
2733 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2734 sid_string_dbg(&sid)));
2739 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2740 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2741 pdb_get_username(sam_pass)));
2742 TALLOC_FREE(sam_pass);
2743 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2749 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2751 dom_gid.rid = primary_group_rid;
2752 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2754 for (i=0; i<num_groups; i++) {
2756 if (!sid_peek_check_rid(get_global_sam_sid(),
2757 &(sids[i]), &dom_gid.rid)) {
2758 DEBUG(10, ("Found sid %s not in our domain\n",
2759 sid_string_dbg(&sids[i])));
2763 if (dom_gid.rid == primary_group_rid) {
2764 /* We added the primary group directly from the
2765 * sam_account. The other SIDs are unique from
2766 * enum_group_memberships */
2770 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2773 rids->count = num_gids;
2776 *r->out.rids = rids;
2778 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2783 /*******************************************************************
2784 _samr_QueryDomainInfo
2785 ********************************************************************/
2787 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2788 struct samr_QueryDomainInfo *r)
2790 NTSTATUS status = NT_STATUS_OK;
2791 struct samr_info *info = NULL;
2792 union samr_DomainInfo *dom_info;
2793 time_t u_expire, u_min_age;
2795 time_t u_lock_duration, u_reset_time;
2798 uint32 account_policy_temp;
2803 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2805 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2807 return NT_STATUS_NO_MEMORY;
2810 /* find the policy handle. open a policy on it. */
2811 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
2812 return NT_STATUS_INVALID_HANDLE;
2815 status = access_check_samr_function(info->acc_granted,
2816 SAMR_ACCESS_OPEN_DOMAIN,
2817 "_samr_QueryDomainInfo" );
2819 if ( !NT_STATUS_IS_OK(status) )
2822 switch (r->in.level) {
2829 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
2830 &account_policy_temp);
2831 dom_info->info1.min_password_length = account_policy_temp;
2833 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2834 dom_info->info1.password_history_length = account_policy_temp;
2836 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2837 &dom_info->info1.password_properties);
2839 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2840 u_expire = account_policy_temp;
2842 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2843 u_min_age = account_policy_temp;
2849 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
2850 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
2852 if (lp_check_password_script() && *lp_check_password_script()) {
2853 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
2863 dom_info->general.num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2864 dom_info->general.num_groups = count_sam_groups(info->disp_info);
2865 dom_info->general.num_aliases = count_sam_aliases(info->disp_info);
2867 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
2869 unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
2871 if (!pdb_get_seq_num(&seq_num))
2872 seq_num = time(NULL);
2878 server_role = ROLE_DOMAIN_PDC;
2879 if (lp_server_role() == ROLE_DOMAIN_BDC)
2880 server_role = ROLE_DOMAIN_BDC;
2882 dom_info->general.oem_information.string = lp_serverstring();
2883 dom_info->general.domain_name.string = lp_workgroup();
2884 dom_info->general.primary.string = global_myname();
2885 dom_info->general.sequence_num = seq_num;
2886 dom_info->general.domain_server_state = DOMAIN_SERVER_ENABLED;
2887 dom_info->general.role = server_role;
2888 dom_info->general.unknown3 = 1;
2899 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2900 u_logout = (time_t)ul;
2907 unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
2911 dom_info->oem.oem_information.string = lp_serverstring();
2914 dom_info->info5.domain_name.string = get_global_sam_name();
2917 /* NT returns its own name when a PDC. win2k and later
2918 * only the name of the PDC if itself is a BDC (samba4
2920 dom_info->info6.primary.string = global_myname();
2923 server_role = ROLE_DOMAIN_PDC;
2924 if (lp_server_role() == ROLE_DOMAIN_BDC)
2925 server_role = ROLE_DOMAIN_BDC;
2927 dom_info->info7.role = server_role;
2935 if (!pdb_get_seq_num(&seq_num)) {
2936 seq_num = time(NULL);
2943 dom_info->info8.sequence_num = seq_num;
2944 dom_info->info8.domain_create_time = 0;
2953 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2954 u_lock_duration = account_policy_temp;
2955 if (u_lock_duration != -1) {
2956 u_lock_duration *= 60;
2959 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2960 u_reset_time = account_policy_temp * 60;
2962 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
2963 &account_policy_temp);
2964 dom_info->info12.lockout_threshold = account_policy_temp;
2970 unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
2972 unix_to_nt_time_abs(&dom_info->info12.lockout_window,
2977 return NT_STATUS_INVALID_INFO_CLASS;
2980 *r->out.info = dom_info;
2982 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2987 /* W2k3 seems to use the same check for all 3 objects that can be created via
2988 * SAMR, if you try to create for example "Dialup" as an alias it says
2989 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
2992 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
2994 enum lsa_SidType type;
2997 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3000 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3001 * whether the name already exists */
3002 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3003 NULL, NULL, NULL, &type);
3007 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3008 return NT_STATUS_OK;
3011 DEBUG(5, ("trying to create %s, exists as %s\n",
3012 new_name, sid_type_lookup(type)));
3014 if (type == SID_NAME_DOM_GRP) {
3015 return NT_STATUS_GROUP_EXISTS;
3017 if (type == SID_NAME_ALIAS) {
3018 return NT_STATUS_ALIAS_EXISTS;
3021 /* Yes, the default is NT_STATUS_USER_EXISTS */
3022 return NT_STATUS_USER_EXISTS;
3025 /*******************************************************************
3027 ********************************************************************/
3029 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3030 struct samr_CreateUser2 *r)
3032 const char *account = NULL;
3034 uint32_t acb_info = r->in.acct_flags;
3035 struct samr_info *info = NULL;
3040 /* check this, when giving away 'add computer to domain' privs */
3041 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3042 bool can_add_account = False;
3044 DISP_INFO *disp_info = NULL;
3046 /* Get the domain SID stored in the domain policy */
3047 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted,
3049 return NT_STATUS_INVALID_HANDLE;
3051 if (disp_info->builtin_domain) {
3052 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3053 return NT_STATUS_ACCESS_DENIED;
3056 nt_status = access_check_samr_function(acc_granted,
3057 SAMR_DOMAIN_ACCESS_CREATE_USER,
3058 "_samr_CreateUser2");
3059 if (!NT_STATUS_IS_OK(nt_status)) {
3063 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3064 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3065 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3066 this parameter is not an account type */
3067 return NT_STATUS_INVALID_PARAMETER;
3070 account = r->in.account_name->string;
3071 if (account == NULL) {
3072 return NT_STATUS_NO_MEMORY;
3075 nt_status = can_create(p->mem_ctx, account);
3076 if (!NT_STATUS_IS_OK(nt_status)) {
3080 /* determine which user right we need to check based on the acb_info */
3082 if ( acb_info & ACB_WSTRUST )
3084 se_priv_copy( &se_rights, &se_machine_account );
3085 can_add_account = user_has_privileges(
3086 p->server_info->ptok, &se_rights );
3088 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3089 account for domain trusts and changes the ACB flags later */
3090 else if ( acb_info & ACB_NORMAL &&
3091 (account[strlen(account)-1] != '$') )
3093 se_priv_copy( &se_rights, &se_add_users );
3094 can_add_account = user_has_privileges(
3095 p->server_info->ptok, &se_rights );
3097 else /* implicit assumption of a BDC or domain trust account here
3098 * (we already check the flags earlier) */
3100 if ( lp_enable_privileges() ) {
3101 /* only Domain Admins can add a BDC or domain trust */
3102 se_priv_copy( &se_rights, &se_priv_none );
3103 can_add_account = nt_token_check_domain_rid(
3104 p->server_info->ptok,
3105 DOMAIN_GROUP_RID_ADMINS );
3109 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3110 uidtoname(p->server_info->utok.uid),
3111 can_add_account ? "True":"False" ));
3113 /********** BEGIN Admin BLOCK **********/
3115 if ( can_add_account )
3118 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3121 if ( can_add_account )
3124 /********** END Admin BLOCK **********/
3126 /* now check for failure */
3128 if ( !NT_STATUS_IS_OK(nt_status) )
3131 /* Get the user's SID */
3133 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3135 map_max_allowed_access(p->server_info->ptok, &des_access);
3137 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3138 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3139 se_map_generic(&des_access, &usr_generic_mapping);
3141 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3142 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3143 &acc_granted, "_samr_CreateUser2");
3145 if ( !NT_STATUS_IS_OK(nt_status) ) {
3149 /* associate the user's SID with the new handle. */
3150 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL) {
3151 return NT_STATUS_NO_MEMORY;
3156 info->acc_granted = acc_granted;
3158 /* get a (unique) handle. open a policy on it. */
3159 if (!create_policy_hnd(p, r->out.user_handle, info)) {
3160 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3163 /* After a "set" ensure we have no cached display info. */
3164 force_flush_samr_cache(info->disp_info);
3166 *r->out.access_granted = acc_granted;
3168 return NT_STATUS_OK;
3171 /****************************************************************
3172 ****************************************************************/
3174 NTSTATUS _samr_CreateUser(pipes_struct *p,
3175 struct samr_CreateUser *r)
3177 struct samr_CreateUser2 c;
3178 uint32_t access_granted;
3180 c.in.domain_handle = r->in.domain_handle;
3181 c.in.account_name = r->in.account_name;
3182 c.in.acct_flags = ACB_NORMAL;
3183 c.in.access_mask = r->in.access_mask;
3184 c.out.user_handle = r->out.user_handle;
3185 c.out.access_granted = &access_granted;
3186 c.out.rid = r->out.rid;
3188 return _samr_CreateUser2(p, &c);
3191 /*******************************************************************
3193 ********************************************************************/
3195 NTSTATUS _samr_Connect(pipes_struct *p,
3196 struct samr_Connect *r)
3198 struct samr_info *info = NULL;
3199 uint32 des_access = r->in.access_mask;
3203 if (!pipe_access_check(p)) {
3204 DEBUG(3, ("access denied to _samr_Connect\n"));
3205 return NT_STATUS_ACCESS_DENIED;
3208 /* set up the SAMR connect_anon response */
3210 /* associate the user's SID with the new handle. */
3211 if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
3212 return NT_STATUS_NO_MEMORY;
3214 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3215 was observed from a win98 client trying to enumerate users (when configured
3216 user level access control on shares) --jerry */
3218 map_max_allowed_access(p->server_info->ptok, &des_access);
3220 se_map_generic( &des_access, &sam_generic_mapping );
3221 info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN);
3223 /* get a (unique) handle. open a policy on it. */
3224 if (!create_policy_hnd(p, r->out.connect_handle, info))
3225 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3227 return NT_STATUS_OK;
3230 /*******************************************************************
3232 ********************************************************************/
3234 NTSTATUS _samr_Connect2(pipes_struct *p,
3235 struct samr_Connect2 *r)
3237 struct samr_info *info = NULL;
3238 SEC_DESC *psd = NULL;
3240 uint32 des_access = r->in.access_mask;
3243 const char *fn = "_samr_Connect2";
3245 switch (p->hdr_req.opnum) {
3246 case NDR_SAMR_CONNECT2:
3247 fn = "_samr_Connect2";
3249 case NDR_SAMR_CONNECT3:
3250 fn = "_samr_Connect3";
3252 case NDR_SAMR_CONNECT4:
3253 fn = "_samr_Connect4";
3255 case NDR_SAMR_CONNECT5:
3256 fn = "_samr_Connect5";
3260 DEBUG(5,("%s: %d\n", fn, __LINE__));
3264 if (!pipe_access_check(p)) {
3265 DEBUG(3, ("access denied to %s\n", fn));
3266 return NT_STATUS_ACCESS_DENIED;
3269 map_max_allowed_access(p->server_info->ptok, &des_access);
3271 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3272 se_map_generic(&des_access, &sam_generic_mapping);
3274 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3275 NULL, 0, des_access, &acc_granted, fn);
3277 if ( !NT_STATUS_IS_OK(nt_status) )
3280 /* associate the user's SID and access granted with the new handle. */
3281 if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
3282 return NT_STATUS_NO_MEMORY;
3284 info->acc_granted = acc_granted;
3285 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3287 /* get a (unique) handle. open a policy on it. */
3288 if (!create_policy_hnd(p, r->out.connect_handle, info))
3289 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3291 DEBUG(5,("%s: %d\n", fn, __LINE__));
3296 /****************************************************************
3298 ****************************************************************/
3300 NTSTATUS _samr_Connect3(pipes_struct *p,
3301 struct samr_Connect3 *r)
3303 struct samr_Connect2 c;
3305 c.in.system_name = r->in.system_name;
3306 c.in.access_mask = r->in.access_mask;
3307 c.out.connect_handle = r->out.connect_handle;
3309 return _samr_Connect2(p, &c);
3312 /*******************************************************************
3314 ********************************************************************/
3316 NTSTATUS _samr_Connect4(pipes_struct *p,
3317 struct samr_Connect4 *r)
3319 struct samr_Connect2 c;
3321 c.in.system_name = r->in.system_name;
3322 c.in.access_mask = r->in.access_mask;
3323 c.out.connect_handle = r->out.connect_handle;
3325 return _samr_Connect2(p, &c);
3328 /*******************************************************************
3330 ********************************************************************/
3332 NTSTATUS _samr_Connect5(pipes_struct *p,
3333 struct samr_Connect5 *r)
3336 struct samr_Connect2 c;
3337 struct samr_ConnectInfo1 info1;
3339 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3342 c.in.system_name = r->in.system_name;
3343 c.in.access_mask = r->in.access_mask;
3344 c.out.connect_handle = r->out.connect_handle;
3346 status = _samr_Connect2(p, &c);
3347 if (!NT_STATUS_IS_OK(status)) {
3351 *r->out.level_out = 1;
3352 r->out.info_out->info1 = info1;
3354 return NT_STATUS_OK;
3357 /**********************************************************************
3359 **********************************************************************/
3361 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3362 struct samr_LookupDomain *r)
3364 NTSTATUS status = NT_STATUS_OK;
3365 struct samr_info *info;
3366 const char *domain_name;
3367 DOM_SID *sid = NULL;
3369 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3370 return NT_STATUS_INVALID_HANDLE;
3372 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3373 Reverted that change so we will work with RAS servers again */
3375 status = access_check_samr_function(info->acc_granted,
3376 SAMR_ACCESS_OPEN_DOMAIN,
3377 "_samr_LookupDomain");
3378 if (!NT_STATUS_IS_OK(status)) {
3382 domain_name = r->in.domain_name->string;
3384 return NT_STATUS_INVALID_PARAMETER;
3387 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3389 return NT_STATUS_NO_MEMORY;
3392 if (strequal(domain_name, builtin_domain_name())) {
3393 sid_copy(sid, &global_sid_Builtin);
3395 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3396 status = NT_STATUS_NO_SUCH_DOMAIN;
3400 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3401 sid_string_dbg(sid)));
3408 /**********************************************************************
3410 **********************************************************************/
3412 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3413 struct samr_EnumDomains *r)
3416 struct samr_info *info;
3417 uint32_t num_entries = 2;
3418 struct samr_SamEntry *entry_array = NULL;
3419 struct samr_SamArray *sam;
3421 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3422 return NT_STATUS_INVALID_HANDLE;
3424 status = access_check_samr_function(info->acc_granted,
3425 SAMR_ACCESS_ENUM_DOMAINS,
3426 "_samr_EnumDomains");
3427 if (!NT_STATUS_IS_OK(status)) {
3431 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3433 return NT_STATUS_NO_MEMORY;
3436 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3437 struct samr_SamEntry,
3440 return NT_STATUS_NO_MEMORY;
3443 entry_array[0].idx = 0;
3444 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3446 entry_array[1].idx = 1;
3447 init_lsa_String(&entry_array[1].name, "Builtin");
3449 sam->count = num_entries;
3450 sam->entries = entry_array;
3453 *r->out.num_entries = num_entries;
3458 /*******************************************************************
3460 ********************************************************************/
3462 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3463 struct samr_OpenAlias *r)
3466 uint32 alias_rid = r->in.rid;
3467 struct samr_info *info = NULL;
3468 SEC_DESC *psd = NULL;
3470 uint32 des_access = r->in.access_mask;
3475 /* find the domain policy and get the SID / access bits stored in the domain policy */
3477 if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
3478 return NT_STATUS_INVALID_HANDLE;
3480 status = access_check_samr_function(acc_granted,
3481 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3484 if ( !NT_STATUS_IS_OK(status) )
3487 /* append the alias' RID to it */
3489 if (!sid_append_rid(&sid, alias_rid))
3490 return NT_STATUS_NO_SUCH_ALIAS;
3492 /*check if access can be granted as requested by client. */
3494 map_max_allowed_access(p->server_info->ptok, &des_access);
3496 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3497 se_map_generic(&des_access,&ali_generic_mapping);
3499 se_priv_copy( &se_rights, &se_add_users );
3502 status = access_check_samr_object(psd, p->server_info->ptok,
3503 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3504 &acc_granted, "_samr_OpenAlias");
3506 if ( !NT_STATUS_IS_OK(status) )
3510 /* Check we actually have the requested alias */
3511 enum lsa_SidType type;
3516 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3519 if (!result || (type != SID_NAME_ALIAS)) {
3520 return NT_STATUS_NO_SUCH_ALIAS;
3523 /* make sure there is a mapping */
3525 if ( !sid_to_gid( &sid, &gid ) ) {
3526 return NT_STATUS_NO_SUCH_ALIAS;
3531 /* associate the alias SID with the new handle. */
3532 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
3533 return NT_STATUS_NO_MEMORY;
3535 info->acc_granted = acc_granted;
3537 /* get a (unique) handle. open a policy on it. */
3538 if (!create_policy_hnd(p, r->out.alias_handle, info))
3539 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3541 return NT_STATUS_OK;
3544 /*******************************************************************
3546 ********************************************************************/
3548 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3549 struct samr_UserInfo7 *id7,
3555 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3556 return NT_STATUS_ACCESS_DENIED;
3559 if (!id7->account_name.string) {
3560 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3561 return NT_STATUS_ACCESS_DENIED;
3564 /* check to see if the new username already exists. Note: we can't
3565 reliably lock all backends, so there is potentially the
3566 possibility that a user can be created in between this check and
3567 the rename. The rename should fail, but may not get the
3568 exact same failure status code. I think this is small enough
3569 of a window for this type of operation and the results are
3570 simply that the rename fails with a slightly different status
3571 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3573 rc = can_create(mem_ctx, id7->account_name.string);
3574 if (!NT_STATUS_IS_OK(rc)) {
3578 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3583 /*******************************************************************
3585 ********************************************************************/
3587 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3591 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3595 /* FIX ME: check if the value is really changed --metze */
3596 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3600 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3607 /*******************************************************************
3609 ********************************************************************/
3611 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
3612 TALLOC_CTX *mem_ctx,
3613 DATA_BLOB *session_key,
3617 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3618 return NT_STATUS_INVALID_PARAMETER;
3621 if (id18->nt_pwd_active || id18->lm_pwd_active) {
3622 if (!session_key->length) {
3623 return NT_STATUS_NO_USER_SESSION_KEY;
3627 if (id18->nt_pwd_active) {
3631 in = data_blob_const(id18->nt_pwd.hash, 16);
3632 out = data_blob_talloc_zero(mem_ctx, 16);
3634 sess_crypt_blob(&out, &in, session_key, false);
3636 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
3637 return NT_STATUS_ACCESS_DENIED;
3640 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3643 if (id18->lm_pwd_active) {
3647 in = data_blob_const(id18->lm_pwd.hash, 16);
3648 out = data_blob_talloc_zero(mem_ctx, 16);
3650 sess_crypt_blob(&out, &in, session_key, false);
3652 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
3653 return NT_STATUS_ACCESS_DENIED;
3656 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3659 copy_id18_to_sam_passwd(pwd, id18);
3661 return pdb_update_sam_account(pwd);
3664 /*******************************************************************
3666 ********************************************************************/
3668 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3672 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3676 copy_id20_to_sam_passwd(pwd, id20);
3678 /* write the change out */
3679 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3686 /*******************************************************************
3688 ********************************************************************/
3690 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
3691 TALLOC_CTX *mem_ctx,
3692 DATA_BLOB *session_key,
3698 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3699 return NT_STATUS_INVALID_PARAMETER;
3702 if (id21->fields_present == 0) {
3703 return NT_STATUS_INVALID_PARAMETER;
3706 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3707 return NT_STATUS_ACCESS_DENIED;
3710 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
3711 if (id21->nt_password_set) {
3714 if ((id21->nt_owf_password.length != 16) ||
3715 (id21->nt_owf_password.size != 16)) {
3716 return NT_STATUS_INVALID_PARAMETER;
3719 if (!session_key->length) {
3720 return NT_STATUS_NO_USER_SESSION_KEY;
3723 in = data_blob_const(id21->nt_owf_password.array, 16);
3724 out = data_blob_talloc_zero(mem_ctx, 16);
3726 sess_crypt_blob(&out, &in, session_key, false);
3728 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
3729 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3733 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
3734 if (id21->lm_password_set) {
3737 if ((id21->lm_owf_password.length != 16) ||
3738 (id21->lm_owf_password.size != 16)) {
3739 return NT_STATUS_INVALID_PARAMETER;
3742 if (!session_key->length) {
3743 return NT_STATUS_NO_USER_SESSION_KEY;
3746 in = data_blob_const(id21->lm_owf_password.array, 16);
3747 out = data_blob_talloc_zero(mem_ctx, 16);
3749 sess_crypt_blob(&out, &in, session_key, false);
3751 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
3752 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3756 /* we need to separately check for an account rename first */
3758 if (id21->account_name.string &&
3759 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3762 /* check to see if the new username already exists. Note: we can't
3763 reliably lock all backends, so there is potentially the
3764 possibility that a user can be created in between this check and
3765 the rename. The rename should fail, but may not get the
3766 exact same failure status code. I think this is small enough
3767 of a window for this type of operation and the results are
3768 simply that the rename fails with a slightly different status
3769 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3771 status = can_create(mem_ctx, id21->account_name.string);
3772 if (!NT_STATUS_IS_OK(status)) {
3776 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3778 if (!NT_STATUS_IS_OK(status)) {
3779 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3780 nt_errstr(status)));
3784 /* set the new username so that later
3785 functions can work on the new account */
3786 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3789 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3792 * The funny part about the previous two calls is
3793 * that pwd still has the password hashes from the
3794 * passdb entry. These have not been updated from
3795 * id21. I don't know if they need to be set. --jerry
3798 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3799 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3800 if ( !NT_STATUS_IS_OK(status) ) {
3805 /* Don't worry about writing out the user account since the
3806 primary group SID is generated solely from the user's Unix
3809 /* write the change out */
3810 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3814 return NT_STATUS_OK;
3817 /*******************************************************************
3819 ********************************************************************/
3821 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3822 struct samr_UserInfo23 *id23,
3825 char *plaintext_buf = NULL;
3831 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3832 return NT_STATUS_INVALID_PARAMETER;
3835 if (id23->info.fields_present == 0) {
3836 return NT_STATUS_INVALID_PARAMETER;
3839 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3840 return NT_STATUS_ACCESS_DENIED;
3843 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3844 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
3846 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3847 pdb_get_username(pwd)));
3849 if (!decode_pw_buffer(mem_ctx,
3850 id23->password.data,
3854 return NT_STATUS_WRONG_PASSWORD;
3857 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3858 return NT_STATUS_ACCESS_DENIED;
3862 copy_id23_to_sam_passwd(pwd, id23);
3864 acct_ctrl = pdb_get_acct_ctrl(pwd);
3866 /* if it's a trust account, don't update /etc/passwd */
3867 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3868 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3869 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3870 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3871 } else if (plaintext_buf) {
3872 /* update the UNIX password */
3873 if (lp_unix_password_sync() ) {
3874 struct passwd *passwd;
3875 if (pdb_get_username(pwd) == NULL) {
3876 DEBUG(1, ("chgpasswd: User without name???\n"));
3877 return NT_STATUS_ACCESS_DENIED;
3880 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3881 if (passwd == NULL) {
3882 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3885 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3886 return NT_STATUS_ACCESS_DENIED;
3888 TALLOC_FREE(passwd);
3892 if (plaintext_buf) {
3893 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3896 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3897 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3902 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3906 return NT_STATUS_OK;
3909 /*******************************************************************
3911 ********************************************************************/
3913 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
3916 char *plaintext_buf = NULL;
3919 DEBUG(5, ("Attempting administrator password change for user %s\n",
3920 pdb_get_username(pwd)));
3922 acct_ctrl = pdb_get_acct_ctrl(pwd);
3924 if (!decode_pw_buffer(talloc_tos(),
3932 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3936 /* if it's a trust account, don't update /etc/passwd */
3937 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3938 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3939 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3940 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3942 /* update the UNIX password */
3943 if (lp_unix_password_sync()) {
3944 struct passwd *passwd;
3946 if (pdb_get_username(pwd) == NULL) {
3947 DEBUG(1, ("chgpasswd: User without name???\n"));
3951 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3952 if (passwd == NULL) {
3953 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3956 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3959 TALLOC_FREE(passwd);
3963 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3965 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3970 /*******************************************************************
3972 ********************************************************************/
3974 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
3975 struct samr_UserInfo24 *id24,
3981 DEBUG(5, ("set_user_info_24: NULL id24\n"));
3982 return NT_STATUS_INVALID_PARAMETER;
3985 if (!set_user_info_pw(id24->password.data, pwd)) {
3986 return NT_STATUS_WRONG_PASSWORD;
3989 copy_id24_to_sam_passwd(pwd, id24);
3991 status = pdb_update_sam_account(pwd);
3992 if (!NT_STATUS_IS_OK(status)) {
3996 return NT_STATUS_OK;
3999 /*******************************************************************
4001 ********************************************************************/
4003 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4004 struct samr_UserInfo25 *id25,
4010 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4011 return NT_STATUS_INVALID_PARAMETER;
4014 if (id25->info.fields_present == 0) {
4015 return NT_STATUS_INVALID_PARAMETER;
4018 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4019 return NT_STATUS_ACCESS_DENIED;
4022 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4023 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4025 if (!set_user_info_pw(id25->password.data, pwd)) {
4026 return NT_STATUS_WRONG_PASSWORD;
4030 copy_id25_to_sam_passwd(pwd, id25);
4032 /* write the change out */
4033 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4038 * We need to "pdb_update_sam_account" before the unix primary group
4039 * is set, because the idealx scripts would also change the
4040 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4041 * the delete explicit / add explicit, which would then fail to find
4042 * the previous primaryGroupSid value.
4045 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4046 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4047 if ( !NT_STATUS_IS_OK(status) ) {
4052 return NT_STATUS_OK;
4055 /*******************************************************************
4057 ********************************************************************/
4059 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4060 struct samr_UserInfo26 *id26,
4066 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4067 return NT_STATUS_INVALID_PARAMETER;
4070 if (!set_user_info_pw(id26->password.data, pwd)) {
4071 return NT_STATUS_WRONG_PASSWORD;
4074 copy_id26_to_sam_passwd(pwd, id26);
4076 status = pdb_update_sam_account(pwd);
4077 if (!NT_STATUS_IS_OK(status)) {
4081 return NT_STATUS_OK;
4085 /*******************************************************************
4087 ********************************************************************/
4089 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4090 struct samr_SetUserInfo *r)
4093 struct samu *pwd = NULL;
4095 union samr_UserInfo *info = r->in.info;
4096 uint16_t switch_value = r->in.level;
4097 uint32_t acc_granted;
4098 uint32_t acc_required;
4100 bool has_enough_rights = False;
4102 DISP_INFO *disp_info = NULL;
4104 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4106 /* find the policy handle. open a policy on it. */
4107 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) {
4108 return NT_STATUS_INVALID_HANDLE;
4111 /* This is tricky. A WinXP domain join sets
4112 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4113 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4114 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4115 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4116 we'll use the set from the WinXP join as the basis. */
4118 switch (switch_value) {
4123 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4126 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4127 SAMR_USER_ACCESS_SET_ATTRIBUTES |
4128 SAMR_USER_ACCESS_GET_ATTRIBUTES;
4132 status = access_check_samr_function(acc_granted,
4134 "_samr_SetUserInfo");
4135 if (!NT_STATUS_IS_OK(status)) {
4139 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4140 sid_string_dbg(&sid), switch_value));
4143 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4144 return NT_STATUS_INVALID_INFO_CLASS;
4147 if (!(pwd = samu_new(NULL))) {
4148 return NT_STATUS_NO_MEMORY;
4152 ret = pdb_getsampwsid(pwd, &sid);
4157 return NT_STATUS_NO_SUCH_USER;
4160 /* deal with machine password changes differently from userinfo changes */
4161 /* check to see if we have the sufficient rights */
4163 acb_info = pdb_get_acct_ctrl(pwd);
4164 if (acb_info & ACB_WSTRUST)
4165 has_enough_rights = user_has_privileges(p->server_info->ptok,
4166 &se_machine_account);
4167 else if (acb_info & ACB_NORMAL)
4168 has_enough_rights = user_has_privileges(p->server_info->ptok,
4170 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4171 if (lp_enable_privileges()) {
4172 has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
4173 DOMAIN_GROUP_RID_ADMINS);
4177 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4178 uidtoname(p->server_info->utok.uid),
4179 has_enough_rights ? "" : " not"));
4181 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4183 if (has_enough_rights) {
4187 /* ok! user info levels (lots: see MSDEV help), off we go... */
4189 switch (switch_value) {
4192 status = set_user_info_7(p->mem_ctx,
4197 if (!set_user_info_16(&info->info16, pwd)) {
4198 status = NT_STATUS_ACCESS_DENIED;
4203 /* Used by AS/U JRA. */
4204 status = set_user_info_18(&info->info18,
4206 &p->server_info->user_session_key,
4211 if (!set_user_info_20(&info->info20, pwd)) {
4212 status = NT_STATUS_ACCESS_DENIED;
4217 status = set_user_info_21(&info->info21,
4219 &p->server_info->user_session_key,
4224 if (!p->server_info->user_session_key.length) {
4225 status = NT_STATUS_NO_USER_SESSION_KEY;
4227 arcfour_crypt_blob(info->info23.password.data, 516,
4228 &p->server_info->user_session_key);
4230 dump_data(100, info->info23.password.data, 516);
4232 status = set_user_info_23(p->mem_ctx,
4233 &info->info23, pwd);
4237 if (!p->server_info->user_session_key.length) {
4238 status = NT_STATUS_NO_USER_SESSION_KEY;
4240 arcfour_crypt_blob(info->info24.password.data,
4242 &p->server_info->user_session_key);
4244 dump_data(100, info->info24.password.data, 516);
4246 status = set_user_info_24(p->mem_ctx,
4247 &info->info24, pwd);
4251 if (!p->server_info->user_session_key.length) {
4252 status = NT_STATUS_NO_USER_SESSION_KEY;
4254 encode_or_decode_arc4_passwd_buffer(
4255 info->info25.password.data,
4256 &p->server_info->user_session_key);
4258 dump_data(100, info->info25.password.data, 532);
4260 status = set_user_info_25(p->mem_ctx,
4261 &info->info25, pwd);
4265 if (!p->server_info->user_session_key.length) {
4266 status = NT_STATUS_NO_USER_SESSION_KEY;
4268 encode_or_decode_arc4_passwd_buffer(
4269 info->info26.password.data,
4270 &p->server_info->user_session_key);
4272 dump_data(100, info->info26.password.data, 516);
4274 status = set_user_info_26(p->mem_ctx,
4275 &info->info26, pwd);
4279 status = NT_STATUS_INVALID_INFO_CLASS;
4284 if (has_enough_rights) {
4288 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4290 if (NT_STATUS_IS_OK(status)) {
4291 force_flush_samr_cache(disp_info);
4297 /*******************************************************************
4299 ********************************************************************/
4301 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4302 struct samr_SetUserInfo2 *r)
4304 struct samr_SetUserInfo q;
4306 q.in.user_handle = r->in.user_handle;
4307 q.in.level = r->in.level;
4308 q.in.info = r->in.info;
4310 return _samr_SetUserInfo(p, &q);
4313 /*********************************************************************
4314 _samr_GetAliasMembership
4315 *********************************************************************/
4317 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4318 struct samr_GetAliasMembership *r)
4320 size_t num_alias_rids;
4322 struct samr_info *info = NULL;
4330 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4332 /* find the policy handle. open a policy on it. */
4333 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4334 return NT_STATUS_INVALID_HANDLE;
4336 ntstatus1 = access_check_samr_function(info->acc_granted,
4337 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
4338 "_samr_GetAliasMembership");
4339 ntstatus2 = access_check_samr_function(info->acc_granted,
4340 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4341 "_samr_GetAliasMembership");
4343 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4344 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4345 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4346 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4350 if (!sid_check_is_domain(&info->sid) &&
4351 !sid_check_is_builtin(&info->sid))
4352 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4354 if (r->in.sids->num_sids) {
4355 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4357 if (members == NULL)
4358 return NT_STATUS_NO_MEMORY;
4363 for (i=0; i<r->in.sids->num_sids; i++)
4364 sid_copy(&members[i], r->in.sids->sids[i].sid);
4370 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4371 r->in.sids->num_sids,
4372 &alias_rids, &num_alias_rids);
4375 if (!NT_STATUS_IS_OK(ntstatus1)) {
4379 r->out.rids->count = num_alias_rids;
4380 r->out.rids->ids = alias_rids;
4382 return NT_STATUS_OK;
4385 /*********************************************************************
4386 _samr_GetMembersInAlias
4387 *********************************************************************/
4389 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4390 struct samr_GetMembersInAlias *r)
4394 size_t num_sids = 0;
4395 struct lsa_SidPtr *sids = NULL;
4396 DOM_SID *pdb_sids = NULL;
4402 /* find the policy handle. open a policy on it. */
4403 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4404 return NT_STATUS_INVALID_HANDLE;
4406 status = access_check_samr_function(acc_granted,
4407 SAMR_ALIAS_ACCESS_GET_MEMBERS,
4408 "_samr_GetMembersInAlias");
4409 if (!NT_STATUS_IS_OK(status)) {
4413 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4416 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4419 if (!NT_STATUS_IS_OK(status)) {
4424 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4426 TALLOC_FREE(pdb_sids);
4427 return NT_STATUS_NO_MEMORY;
4431 for (i = 0; i < num_sids; i++) {
4432 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4434 TALLOC_FREE(pdb_sids);
4435 return NT_STATUS_NO_MEMORY;
4439 r->out.sids->num_sids = num_sids;
4440 r->out.sids->sids = sids;
4442 TALLOC_FREE(pdb_sids);
4444 return NT_STATUS_OK;
4447 /*********************************************************************
4448 _samr_QueryGroupMember
4449 *********************************************************************/
4451 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4452 struct samr_QueryGroupMember *r)
4455 size_t i, num_members;
4463 struct samr_RidTypeArray *rids = NULL;
4465 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4467 return NT_STATUS_NO_MEMORY;
4470 /* find the policy handle. open a policy on it. */
4471 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4472 return NT_STATUS_INVALID_HANDLE;
4474 status = access_check_samr_function(acc_granted,
4475 SAMR_GROUP_ACCESS_GET_MEMBERS,
4476 "_samr_QueryGroupMember");
4477 if (!NT_STATUS_IS_OK(status)) {
4481 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4483 if (!sid_check_is_in_our_domain(&group_sid)) {
4484 DEBUG(3, ("sid %s is not in our domain\n",
4485 sid_string_dbg(&group_sid)));
4486 return NT_STATUS_NO_SUCH_GROUP;
4489 DEBUG(10, ("lookup on Domain SID\n"));
4492 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4493 &rid, &num_members);
4496 if (!NT_STATUS_IS_OK(status))
4500 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4502 return NT_STATUS_NO_MEMORY;
4508 for (i=0; i<num_members; i++)
4509 attr[i] = SID_NAME_USER;
4511 rids->count = num_members;
4515 *r->out.rids = rids;
4517 return NT_STATUS_OK;
4520 /*********************************************************************
4521 _samr_AddAliasMember
4522 *********************************************************************/
4524 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4525 struct samr_AddAliasMember *r)
4530 bool can_add_accounts;
4532 DISP_INFO *disp_info = NULL;
4534 /* Find the policy handle. Open a policy on it. */
4535 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4536 return NT_STATUS_INVALID_HANDLE;
4538 status = access_check_samr_function(acc_granted,
4539 SAMR_ALIAS_ACCESS_ADD_MEMBER,
4540 "_samr_AddAliasMember");
4541 if (!NT_STATUS_IS_OK(status)) {
4545 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4547 se_priv_copy( &se_rights, &se_add_users );
4548 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4550 /******** BEGIN SeAddUsers BLOCK *********/
4552 if ( can_add_accounts )
4555 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4557 if ( can_add_accounts )
4560 /******** END SeAddUsers BLOCK *********/
4562 if (NT_STATUS_IS_OK(status)) {
4563 force_flush_samr_cache(disp_info);
4569 /*********************************************************************
4570 _samr_DeleteAliasMember
4571 *********************************************************************/
4573 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4574 struct samr_DeleteAliasMember *r)
4579 bool can_add_accounts;
4581 DISP_INFO *disp_info = NULL;
4583 /* Find the policy handle. Open a policy on it. */
4584 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4585 return NT_STATUS_INVALID_HANDLE;
4587 status = access_check_samr_function(acc_granted,
4588 SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
4589 "_samr_DeleteAliasMember");
4590 if (!NT_STATUS_IS_OK(status)) {
4594 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4595 sid_string_dbg(&alias_sid)));
4597 se_priv_copy( &se_rights, &se_add_users );
4598 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4600 /******** BEGIN SeAddUsers BLOCK *********/
4602 if ( can_add_accounts )
4605 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4607 if ( can_add_accounts )
4610 /******** END SeAddUsers BLOCK *********/
4612 if (NT_STATUS_IS_OK(status)) {
4613 force_flush_samr_cache(disp_info);
4619 /*********************************************************************
4620 _samr_AddGroupMember
4621 *********************************************************************/
4623 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4624 struct samr_AddGroupMember *r)
4631 bool can_add_accounts;
4632 DISP_INFO *disp_info = NULL;
4634 /* Find the policy handle. Open a policy on it. */
4635 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4636 return NT_STATUS_INVALID_HANDLE;
4638 status = access_check_samr_function(acc_granted,
4639 SAMR_GROUP_ACCESS_ADD_MEMBER,
4640 "_samr_AddGroupMember");
4641 if (!NT_STATUS_IS_OK(status)) {
4645 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4647 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4649 return NT_STATUS_INVALID_HANDLE;
4652 se_priv_copy( &se_rights, &se_add_users );
4653 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4655 /******** BEGIN SeAddUsers BLOCK *********/
4657 if ( can_add_accounts )
4660 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4662 if ( can_add_accounts )
4665 /******** END SeAddUsers BLOCK *********/
4667 force_flush_samr_cache(disp_info);
4672 /*********************************************************************
4673 _samr_DeleteGroupMember
4674 *********************************************************************/
4676 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4677 struct samr_DeleteGroupMember *r)
4685 bool can_add_accounts;
4686 DISP_INFO *disp_info = NULL;
4689 * delete the group member named r->in.rid
4690 * who is a member of the sid associated with the handle
4691 * the rid is a user's rid as the group is a domain group.
4694 /* Find the policy handle. Open a policy on it. */
4695 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4696 return NT_STATUS_INVALID_HANDLE;
4698 status = access_check_samr_function(acc_granted,
4699 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
4700 "_samr_DeleteGroupMember");
4701 if (!NT_STATUS_IS_OK(status)) {
4705 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4707 return NT_STATUS_INVALID_HANDLE;
4710 se_priv_copy( &se_rights, &se_add_users );
4711 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4713 /******** BEGIN SeAddUsers BLOCK *********/
4715 if ( can_add_accounts )
4718 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4720 if ( can_add_accounts )
4723 /******** END SeAddUsers BLOCK *********/
4725 force_flush_samr_cache(disp_info);
4730 /*********************************************************************
4732 *********************************************************************/
4734 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4735 struct samr_DeleteUser *r)
4739 struct samu *sam_pass=NULL;
4741 bool can_add_accounts;
4743 DISP_INFO *disp_info = NULL;
4746 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4748 /* Find the policy handle. Open a policy on it. */
4749 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4750 return NT_STATUS_INVALID_HANDLE;
4752 status = access_check_samr_function(acc_granted,
4753 STD_RIGHT_DELETE_ACCESS,
4754 "_samr_DeleteUser");
4755 if (!NT_STATUS_IS_OK(status)) {
4759 if (!sid_check_is_in_our_domain(&user_sid))
4760 return NT_STATUS_CANNOT_DELETE;
4762 /* check if the user exists before trying to delete */
4763 if ( !(sam_pass = samu_new( NULL )) ) {
4764 return NT_STATUS_NO_MEMORY;
4768 ret = pdb_getsampwsid(sam_pass, &user_sid);
4772 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4773 sid_string_dbg(&user_sid)));
4774 TALLOC_FREE(sam_pass);
4775 return NT_STATUS_NO_SUCH_USER;
4778 acb_info = pdb_get_acct_ctrl(sam_pass);
4780 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4781 if ( acb_info & ACB_WSTRUST ) {
4782 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
4784 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
4787 /******** BEGIN SeAddUsers BLOCK *********/
4789 if ( can_add_accounts )
4792 status = pdb_delete_user(p->mem_ctx, sam_pass);
4794 if ( can_add_accounts )
4797 /******** END SeAddUsers BLOCK *********/
4799 if ( !NT_STATUS_IS_OK(status) ) {
4800 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4801 "user %s: %s.\n", pdb_get_username(sam_pass),
4802 nt_errstr(status)));
4803 TALLOC_FREE(sam_pass);
4808 TALLOC_FREE(sam_pass);
4810 if (!close_policy_hnd(p, r->in.user_handle))
4811 return NT_STATUS_OBJECT_NAME_INVALID;
4813 ZERO_STRUCTP(r->out.user_handle);
4815 force_flush_samr_cache(disp_info);
4817 return NT_STATUS_OK;
4820 /*********************************************************************
4821 _samr_DeleteDomainGroup
4822 *********************************************************************/
4824 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4825 struct samr_DeleteDomainGroup *r)
4832 bool can_add_accounts;
4833 DISP_INFO *disp_info = NULL;
4835 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4837 /* Find the policy handle. Open a policy on it. */
4838 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4839 return NT_STATUS_INVALID_HANDLE;
4841 status = access_check_samr_function(acc_granted,
4842 STD_RIGHT_DELETE_ACCESS,
4843 "_samr_DeleteDomainGroup");
4844 if (!NT_STATUS_IS_OK(status)) {
4848 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4850 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4852 return NT_STATUS_NO_SUCH_GROUP;
4855 se_priv_copy( &se_rights, &se_add_users );
4856 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4858 /******** BEGIN SeAddUsers BLOCK *********/
4860 if ( can_add_accounts )
4863 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4865 if ( can_add_accounts )
4868 /******** END SeAddUsers BLOCK *********/
4870 if ( !NT_STATUS_IS_OK(status) ) {
4871 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4872 "entry for group %s: %s\n",
4873 sid_string_dbg(&group_sid),
4874 nt_errstr(status)));
4878 if (!close_policy_hnd(p, r->in.group_handle))
4879 return NT_STATUS_OBJECT_NAME_INVALID;
4881 force_flush_samr_cache(disp_info);
4883 return NT_STATUS_OK;
4886 /*********************************************************************
4887 _samr_DeleteDomAlias
4888 *********************************************************************/
4890 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4891 struct samr_DeleteDomAlias *r)
4896 bool can_add_accounts;
4898 DISP_INFO *disp_info = NULL;
4900 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4902 /* Find the policy handle. Open a policy on it. */
4903 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4904 return NT_STATUS_INVALID_HANDLE;
4906 /* copy the handle to the outgoing reply */
4908 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4910 status = access_check_samr_function(acc_granted,
4911 STD_RIGHT_DELETE_ACCESS,
4912 "_samr_DeleteDomAlias");
4913 if (!NT_STATUS_IS_OK(status)) {
4917 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4919 /* Don't let Windows delete builtin groups */
4921 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4922 return NT_STATUS_SPECIAL_ACCOUNT;
4925 if (!sid_check_is_in_our_domain(&alias_sid))
4926 return NT_STATUS_NO_SUCH_ALIAS;
4928 DEBUG(10, ("lookup on Local SID\n"));
4930 se_priv_copy( &se_rights, &se_add_users );
4931 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4933 /******** BEGIN SeAddUsers BLOCK *********/
4935 if ( can_add_accounts )
4938 /* Have passdb delete the alias */
4939 status = pdb_delete_alias(&alias_sid);
4941 if ( can_add_accounts )
4944 /******** END SeAddUsers BLOCK *********/
4946 if ( !NT_STATUS_IS_OK(status))
4949 if (!close_policy_hnd(p, r->in.alias_handle))
4950 return NT_STATUS_OBJECT_NAME_INVALID;
4952 force_flush_samr_cache(disp_info);
4954 return NT_STATUS_OK;
4957 /*********************************************************************
4958 _samr_CreateDomainGroup
4959 *********************************************************************/
4961 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4962 struct samr_CreateDomainGroup *r)
4969 struct samr_info *info;
4972 bool can_add_accounts;
4973 DISP_INFO *disp_info = NULL;
4975 /* Find the policy handle. Open a policy on it. */
4976 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4977 return NT_STATUS_INVALID_HANDLE;
4979 status = access_check_samr_function(acc_granted,
4980 SAMR_DOMAIN_ACCESS_CREATE_GROUP,
4981 "_samr_CreateDomainGroup");
4982 if (!NT_STATUS_IS_OK(status)) {
4986 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4987 return NT_STATUS_ACCESS_DENIED;
4989 name = r->in.name->string;
4991 return NT_STATUS_NO_MEMORY;
4994 status = can_create(p->mem_ctx, name);
4995 if (!NT_STATUS_IS_OK(status)) {
4999 se_priv_copy( &se_rights, &se_add_users );
5000 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5002 /******** BEGIN SeAddUsers BLOCK *********/
5004 if ( can_add_accounts )
5007 /* check that we successfully create the UNIX group */
5009 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5011 if ( can_add_accounts )
5014 /******** END SeAddUsers BLOCK *********/
5016 /* check if we should bail out here */
5018 if ( !NT_STATUS_IS_OK(status) )
5021 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5023 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5024 return NT_STATUS_NO_MEMORY;
5026 /* they created it; let the user do what he wants with it */
5028 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5030 /* get a (unique) handle. open a policy on it. */
5031 if (!create_policy_hnd(p, r->out.group_handle, info))
5032 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5034 force_flush_samr_cache(disp_info);
5036 return NT_STATUS_OK;
5039 /*********************************************************************
5040 _samr_CreateDomAlias
5041 *********************************************************************/
5043 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5044 struct samr_CreateDomAlias *r)
5048 const char *name = NULL;
5049 struct samr_info *info;
5054 bool can_add_accounts;
5055 DISP_INFO *disp_info = NULL;
5057 /* Find the policy handle. Open a policy on it. */
5058 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5059 return NT_STATUS_INVALID_HANDLE;
5061 result = access_check_samr_function(acc_granted,
5062 SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
5063 "_samr_CreateDomAlias");
5064 if (!NT_STATUS_IS_OK(result)) {
5068 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5069 return NT_STATUS_ACCESS_DENIED;
5071 name = r->in.alias_name->string;
5073 se_priv_copy( &se_rights, &se_add_users );
5074 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5076 result = can_create(p->mem_ctx, name);
5077 if (!NT_STATUS_IS_OK(result)) {
5081 /******** BEGIN SeAddUsers BLOCK *********/
5083 if ( can_add_accounts )
5086 /* Have passdb create the alias */
5087 result = pdb_create_alias(name, r->out.rid);
5089 if ( can_add_accounts )
5092 /******** END SeAddUsers BLOCK *********/
5094 if (!NT_STATUS_IS_OK(result)) {
5095 DEBUG(10, ("pdb_create_alias failed: %s\n",
5096 nt_errstr(result)));
5100 sid_copy(&info_sid, get_global_sam_sid());
5101 sid_append_rid(&info_sid, *r->out.rid);
5103 if (!sid_to_gid(&info_sid, &gid)) {
5104 DEBUG(10, ("Could not find alias just created\n"));
5105 return NT_STATUS_ACCESS_DENIED;
5108 /* check if the group has been successfully created */
5109 if ( getgrgid(gid) == NULL ) {
5110 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5112 return NT_STATUS_ACCESS_DENIED;
5115 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5116 return NT_STATUS_NO_MEMORY;
5118 /* they created it; let the user do what he wants with it */
5120 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5122 /* get a (unique) handle. open a policy on it. */
5123 if (!create_policy_hnd(p, r->out.alias_handle, info))
5124 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5126 force_flush_samr_cache(disp_info);
5128 return NT_STATUS_OK;
5131 /*********************************************************************
5132 _samr_QueryGroupInfo
5133 *********************************************************************/
5135 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5136 struct samr_QueryGroupInfo *r)
5141 union samr_GroupInfo *info = NULL;
5144 uint32_t attributes = SE_GROUP_MANDATORY |
5145 SE_GROUP_ENABLED_BY_DEFAULT |
5147 const char *group_name = NULL;
5148 const char *group_description = NULL;
5150 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5151 return NT_STATUS_INVALID_HANDLE;
5153 status = access_check_samr_function(acc_granted,
5154 SAMR_GROUP_ACCESS_LOOKUP_INFO,
5155 "_samr_QueryGroupInfo");
5156 if (!NT_STATUS_IS_OK(status)) {
5161 ret = get_domain_group_from_sid(group_sid, &map);
5164 return NT_STATUS_INVALID_HANDLE;
5166 /* FIXME: map contains fstrings */
5167 group_name = talloc_strdup(r, map.nt_name);
5168 group_description = talloc_strdup(r, map.comment);
5170 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5172 return NT_STATUS_NO_MEMORY;
5175 switch (r->in.level) {
5181 status = pdb_enum_group_members(
5182 p->mem_ctx, &group_sid, &members, &num_members);
5185 if (!NT_STATUS_IS_OK(status)) {
5189 info->all.name.string = group_name;
5190 info->all.attributes = attributes;
5191 info->all.num_members = num_members;
5192 info->all.description.string = group_description;
5196 info->name.string = group_name;
5199 info->attributes.attributes = attributes;
5202 info->description.string = group_description;
5212 status = pdb_enum_group_members(
5213 p->mem_ctx, &group_sid, &members, &num_members);
5216 if (!NT_STATUS_IS_OK(status)) {
5220 info->all2.name.string = group_name;
5221 info->all2.attributes = attributes;
5222 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5223 info->all2.description.string = group_description;
5228 return NT_STATUS_INVALID_INFO_CLASS;
5231 *r->out.info = info;
5233 return NT_STATUS_OK;
5236 /*********************************************************************
5238 *********************************************************************/
5240 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5241 struct samr_SetGroupInfo *r)
5248 bool can_mod_accounts;
5249 DISP_INFO *disp_info = NULL;
5251 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5252 return NT_STATUS_INVALID_HANDLE;
5254 status = access_check_samr_function(acc_granted,
5255 SAMR_GROUP_ACCESS_SET_INFO,
5256 "_samr_SetGroupInfo");
5257 if (!NT_STATUS_IS_OK(status)) {
5262 ret = get_domain_group_from_sid(group_sid, &map);
5265 return NT_STATUS_NO_SUCH_GROUP;
5267 switch (r->in.level) {
5269 fstrcpy(map.comment, r->in.info->all.description.string);
5272 /* group rename is not supported yet */
5273 return NT_STATUS_NOT_SUPPORTED;
5275 fstrcpy(map.comment, r->in.info->description.string);
5278 return NT_STATUS_INVALID_INFO_CLASS;
5281 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5283 /******** BEGIN SeAddUsers BLOCK *********/
5285 if ( can_mod_accounts )
5288 status = pdb_update_group_mapping_entry(&map);
5290 if ( can_mod_accounts )
5293 /******** End SeAddUsers BLOCK *********/
5295 if (NT_STATUS_IS_OK(status)) {
5296 force_flush_samr_cache(disp_info);
5302 /*********************************************************************
5304 *********************************************************************/
5306 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5307 struct samr_SetAliasInfo *r)
5310 struct acct_info info;
5312 bool can_mod_accounts;
5314 DISP_INFO *disp_info = NULL;
5316 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5317 return NT_STATUS_INVALID_HANDLE;
5319 status = access_check_samr_function(acc_granted,
5320 SAMR_ALIAS_ACCESS_SET_INFO,
5321 "_samr_SetAliasInfo");
5322 if (!NT_STATUS_IS_OK(status)) {
5326 /* get the current group information */
5329 status = pdb_get_aliasinfo( &group_sid, &info );
5332 if ( !NT_STATUS_IS_OK(status))
5335 switch (r->in.level) {
5340 /* We currently do not support renaming groups in the
5341 the BUILTIN domain. Refer to util_builtin.c to understand
5342 why. The eventually needs to be fixed to be like Windows
5343 where you can rename builtin groups, just not delete them */
5345 if ( sid_check_is_in_builtin( &group_sid ) ) {
5346 return NT_STATUS_SPECIAL_ACCOUNT;
5349 /* There has to be a valid name (and it has to be different) */
5351 if ( !r->in.info->name.string )
5352 return NT_STATUS_INVALID_PARAMETER;
5354 /* If the name is the same just reply "ok". Yes this
5355 doesn't allow you to change the case of a group name. */
5357 if ( strequal( r->in.info->name.string, info.acct_name ) )
5358 return NT_STATUS_OK;
5360 fstrcpy( info.acct_name, r->in.info->name.string);
5362 /* make sure the name doesn't already exist as a user
5365 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5366 status = can_create( p->mem_ctx, group_name );
5367 if ( !NT_STATUS_IS_OK( status ) )
5371 case ALIASINFODESCRIPTION:
5372 if (r->in.info->description.string) {
5373 fstrcpy(info.acct_desc,
5374 r->in.info->description.string);
5376 fstrcpy( info.acct_desc, "" );
5380 return NT_STATUS_INVALID_INFO_CLASS;
5383 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5385 /******** BEGIN SeAddUsers BLOCK *********/
5387 if ( can_mod_accounts )
5390 status = pdb_set_aliasinfo( &group_sid, &info );
5392 if ( can_mod_accounts )
5395 /******** End SeAddUsers BLOCK *********/
5397 if (NT_STATUS_IS_OK(status))
5398 force_flush_samr_cache(disp_info);
5403 /****************************************************************
5405 ****************************************************************/
5407 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5408 struct samr_GetDomPwInfo *r)
5410 uint32_t min_password_length = 0;
5411 uint32_t password_properties = 0;
5413 /* Perform access check. Since this rpc does not require a
5414 policy handle it will not be caught by the access checks on
5415 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5417 if (!pipe_access_check(p)) {
5418 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5419 return NT_STATUS_ACCESS_DENIED;
5423 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5424 &min_password_length);
5425 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5426 &password_properties);
5429 if (lp_check_password_script() && *lp_check_password_script()) {
5430 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5433 r->out.info->min_password_length = min_password_length;
5434 r->out.info->password_properties = password_properties;
5436 return NT_STATUS_OK;
5439 /*********************************************************************
5441 *********************************************************************/
5443 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5444 struct samr_OpenGroup *r)
5450 struct samr_info *info;
5451 SEC_DESC *psd = NULL;
5453 uint32 des_access = r->in.access_mask;
5460 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5461 return NT_STATUS_INVALID_HANDLE;
5463 status = access_check_samr_function(acc_granted,
5464 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
5467 if ( !NT_STATUS_IS_OK(status) )
5470 /*check if access can be granted as requested by client. */
5471 map_max_allowed_access(p->server_info->ptok, &des_access);
5473 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5474 se_map_generic(&des_access,&grp_generic_mapping);
5476 se_priv_copy( &se_rights, &se_add_users );
5478 status = access_check_samr_object(psd, p->server_info->ptok,
5479 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5480 &acc_granted, "_samr_OpenGroup");
5482 if ( !NT_STATUS_IS_OK(status) )
5485 /* this should not be hard-coded like this */
5487 if (!sid_equal(&sid, get_global_sam_sid()))
5488 return NT_STATUS_ACCESS_DENIED;
5490 sid_copy(&info_sid, get_global_sam_sid());
5491 sid_append_rid(&info_sid, r->in.rid);
5492 sid_to_fstring(sid_string, &info_sid);
5494 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5495 return NT_STATUS_NO_MEMORY;
5497 info->acc_granted = acc_granted;
5499 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5501 /* check if that group really exists */
5503 ret = get_domain_group_from_sid(info->sid, &map);
5506 return NT_STATUS_NO_SUCH_GROUP;
5508 /* get a (unique) handle. open a policy on it. */
5509 if (!create_policy_hnd(p, r->out.group_handle, info))
5510 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5512 return NT_STATUS_OK;
5515 /*********************************************************************
5516 _samr_RemoveMemberFromForeignDomain
5517 *********************************************************************/
5519 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5520 struct samr_RemoveMemberFromForeignDomain *r)
5522 DOM_SID delete_sid, domain_sid;
5525 DISP_INFO *disp_info = NULL;
5527 sid_copy( &delete_sid, r->in.sid );
5529 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5530 sid_string_dbg(&delete_sid)));
5532 /* Find the policy handle. Open a policy on it. */
5534 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5535 &acc_granted, &disp_info))
5536 return NT_STATUS_INVALID_HANDLE;
5538 result = access_check_samr_function(acc_granted,
5539 STD_RIGHT_DELETE_ACCESS,
5540 "_samr_RemoveMemberFromForeignDomain");
5542 if (!NT_STATUS_IS_OK(result))
5545 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5546 sid_string_dbg(&domain_sid)));
5548 /* we can only delete a user from a group since we don't have
5549 nested groups anyways. So in the latter case, just say OK */
5551 /* TODO: The above comment nowadays is bogus. Since we have nested
5552 * groups now, and aliases members are never reported out of the unix
5553 * group membership, the "just say OK" makes this call a no-op. For
5554 * us. This needs fixing however. */
5556 /* I've only ever seen this in the wild when deleting a user from
5557 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5558 * is the user about to be deleted. I very much suspect this is the
5559 * only application of this call. To verify this, let people report
5562 if (!sid_check_is_builtin(&domain_sid)) {
5563 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5564 "global_sam_sid() = %s\n",
5565 sid_string_dbg(&domain_sid),
5566 sid_string_dbg(get_global_sam_sid())));
5567 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5568 return NT_STATUS_OK;
5571 force_flush_samr_cache(disp_info);
5573 result = NT_STATUS_OK;
5578 /*******************************************************************
5579 _samr_QueryDomainInfo2
5580 ********************************************************************/
5582 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5583 struct samr_QueryDomainInfo2 *r)
5585 struct samr_QueryDomainInfo q;
5587 q.in.domain_handle = r->in.domain_handle;
5588 q.in.level = r->in.level;
5590 q.out.info = r->out.info;
5592 return _samr_QueryDomainInfo(p, &q);
5595 /*******************************************************************
5597 ********************************************************************/
5599 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5600 struct samr_SetDomainInfo *r)
5602 struct samr_info *info = NULL;
5603 time_t u_expire, u_min_age;
5605 time_t u_lock_duration, u_reset_time;
5608 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5610 /* find the policy handle. open a policy on it. */
5611 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5612 return NT_STATUS_INVALID_HANDLE;
5614 /* We do have different access bits for info
5615 * levels here, but we're really just looking for
5616 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5617 * this maps to different specific bits. So
5618 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
5621 result = access_check_samr_function(info->acc_granted,
5622 SAMR_DOMAIN_ACCESS_SET_INFO_1,
5623 "_samr_SetDomainInfo");
5625 if (!NT_STATUS_IS_OK(result))
5628 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5630 switch (r->in.level) {
5632 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5633 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5634 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5635 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5636 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5637 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5638 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5643 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5644 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5653 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5654 if (u_lock_duration != -1)
5655 u_lock_duration /= 60;
5657 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5659 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5660 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5661 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5664 return NT_STATUS_INVALID_INFO_CLASS;
5667 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5669 return NT_STATUS_OK;
5672 /****************************************************************
5673 _samr_GetDisplayEnumerationIndex
5674 ****************************************************************/
5676 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5677 struct samr_GetDisplayEnumerationIndex *r)
5679 struct samr_info *info = NULL;
5680 uint32_t max_entries = (uint32_t) -1;
5681 uint32_t enum_context = 0;
5683 uint32_t num_account = 0;
5684 struct samr_displayentry *entries = NULL;
5687 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5689 /* find the policy handle. open a policy on it. */
5690 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5691 return NT_STATUS_INVALID_HANDLE;
5694 status = access_check_samr_function(info->acc_granted,
5695 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
5696 "_samr_GetDisplayEnumerationIndex");
5697 if (!NT_STATUS_IS_OK(status)) {
5701 if ((r->in.level < 1) || (r->in.level > 3)) {
5702 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5703 "Unknown info level (%u)\n",
5705 return NT_STATUS_INVALID_INFO_CLASS;
5710 /* The following done as ROOT. Don't return without unbecome_root(). */
5712 switch (r->in.level) {
5714 if (info->disp_info->users == NULL) {
5715 info->disp_info->users = pdb_search_users(
5716 info->disp_info, ACB_NORMAL);
5717 if (info->disp_info->users == NULL) {
5719 return NT_STATUS_ACCESS_DENIED;
5721 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5722 "starting user enumeration at index %u\n",
5723 (unsigned int)enum_context));
5725 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5726 "using cached user enumeration at index %u\n",
5727 (unsigned int)enum_context));
5729 num_account = pdb_search_entries(info->disp_info->users,
5730 enum_context, max_entries,
5734 if (info->disp_info->machines == NULL) {
5735 info->disp_info->machines = pdb_search_users(
5736 info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
5737 if (info->disp_info->machines == NULL) {
5739 return NT_STATUS_ACCESS_DENIED;
5741 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5742 "starting machine enumeration at index %u\n",
5743 (unsigned int)enum_context));
5745 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5746 "using cached machine enumeration at index %u\n",
5747 (unsigned int)enum_context));
5749 num_account = pdb_search_entries(info->disp_info->machines,
5750 enum_context, max_entries,
5754 if (info->disp_info->groups == NULL) {
5755 info->disp_info->groups = pdb_search_groups(
5757 if (info->disp_info->groups == NULL) {
5759 return NT_STATUS_ACCESS_DENIED;
5761 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5762 "starting group enumeration at index %u\n",
5763 (unsigned int)enum_context));
5765 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5766 "using cached group enumeration at index %u\n",
5767 (unsigned int)enum_context));
5769 num_account = pdb_search_entries(info->disp_info->groups,
5770 enum_context, max_entries,
5775 smb_panic("info class changed");
5781 /* Ensure we cache this enumeration. */
5782 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5784 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5785 r->in.name->string));
5787 for (i=0; i<num_account; i++) {
5788 if (strequal(entries[i].account_name, r->in.name->string)) {
5789 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5790 "found %s at idx %d\n",
5791 r->in.name->string, i));
5793 return NT_STATUS_OK;
5797 /* assuming account_name lives at the very end */
5798 *r->out.idx = num_account;
5800 return NT_STATUS_NO_MORE_ENTRIES;
5803 /****************************************************************
5804 _samr_GetDisplayEnumerationIndex2
5805 ****************************************************************/
5807 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5808 struct samr_GetDisplayEnumerationIndex2 *r)
5810 struct samr_GetDisplayEnumerationIndex q;
5812 q.in.domain_handle = r->in.domain_handle;
5813 q.in.level = r->in.level;
5814 q.in.name = r->in.name;
5816 q.out.idx = r->out.idx;
5818 return _samr_GetDisplayEnumerationIndex(p, &q);
5821 /****************************************************************
5822 ****************************************************************/
5824 NTSTATUS _samr_Shutdown(pipes_struct *p,
5825 struct samr_Shutdown *r)
5827 p->rng_fault_state = true;
5828 return NT_STATUS_NOT_IMPLEMENTED;
5831 /****************************************************************
5832 ****************************************************************/
5834 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5835 struct samr_SetMemberAttributesOfGroup *r)
5837 p->rng_fault_state = true;
5838 return NT_STATUS_NOT_IMPLEMENTED;
5841 /****************************************************************
5842 ****************************************************************/
5844 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5845 struct samr_ChangePasswordUser *r)
5847 p->rng_fault_state = true;
5848 return NT_STATUS_NOT_IMPLEMENTED;
5851 /****************************************************************
5852 ****************************************************************/
5854 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5855 struct samr_TestPrivateFunctionsDomain *r)
5857 p->rng_fault_state = true;
5858 return NT_STATUS_NOT_IMPLEMENTED;
5861 /****************************************************************
5862 ****************************************************************/
5864 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5865 struct samr_TestPrivateFunctionsUser *r)
5867 p->rng_fault_state = true;
5868 return NT_STATUS_NOT_IMPLEMENTED;
5871 /****************************************************************
5872 ****************************************************************/
5874 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5875 struct samr_AddMultipleMembersToAlias *r)
5877 p->rng_fault_state = true;
5878 return NT_STATUS_NOT_IMPLEMENTED;
5881 /****************************************************************
5882 ****************************************************************/
5884 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5885 struct samr_RemoveMultipleMembersFromAlias *r)
5887 p->rng_fault_state = true;
5888 return NT_STATUS_NOT_IMPLEMENTED;
5891 /****************************************************************
5892 ****************************************************************/
5894 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5895 struct samr_OemChangePasswordUser2 *r)
5897 p->rng_fault_state = true;
5898 return NT_STATUS_NOT_IMPLEMENTED;
5901 /****************************************************************
5902 ****************************************************************/
5904 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5905 struct samr_SetBootKeyInformation *r)
5907 p->rng_fault_state = true;
5908 return NT_STATUS_NOT_IMPLEMENTED;
5911 /****************************************************************
5912 ****************************************************************/
5914 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5915 struct samr_GetBootKeyInformation *r)
5917 p->rng_fault_state = true;
5918 return NT_STATUS_NOT_IMPLEMENTED;
5921 /****************************************************************
5922 ****************************************************************/
5924 NTSTATUS _samr_RidToSid(pipes_struct *p,
5925 struct samr_RidToSid *r)
5927 p->rng_fault_state = true;
5928 return NT_STATUS_NOT_IMPLEMENTED;
5931 /****************************************************************
5932 ****************************************************************/
5934 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5935 struct samr_SetDsrmPassword *r)
5937 p->rng_fault_state = true;
5938 return NT_STATUS_NOT_IMPLEMENTED;
5941 /****************************************************************
5942 ****************************************************************/
5944 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5945 struct samr_ValidatePassword *r)
5947 p->rng_fault_state = true;
5948 return NT_STATUS_NOT_IMPLEMENTED;