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-2005,
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.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 * This is the implementation of the SAMR code.
36 #define DBGC_CLASS DBGC_RPC_SRV
38 #define SAMR_USR_RIGHTS_WRITE_PW \
39 ( READ_CONTROL_ACCESS | \
40 SA_RIGHT_USER_CHANGE_PASSWORD | \
41 SA_RIGHT_USER_SET_LOC_COM )
42 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
43 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
45 #define DISP_INFO_CACHE_TIMEOUT 10
47 typedef struct disp_info {
48 DOM_SID sid; /* identify which domain this is. */
49 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
50 struct pdb_search *users; /* querydispinfo 1 and 4 */
51 struct pdb_search *machines; /* querydispinfo 2 */
52 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
53 struct pdb_search *aliases; /* enumaliases */
56 struct pdb_search *enum_users; /* enumusers with a mask */
58 struct timed_event *cache_timeout_event; /* cache idle timeout
62 /* We keep a static list of these by SID as modern clients close down
63 all resources between each request in a complete enumeration. */
66 /* for use by the \PIPE\samr policy */
68 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
69 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
75 static const struct generic_mapping sam_generic_mapping = {
76 GENERIC_RIGHTS_SAM_READ,
77 GENERIC_RIGHTS_SAM_WRITE,
78 GENERIC_RIGHTS_SAM_EXECUTE,
79 GENERIC_RIGHTS_SAM_ALL_ACCESS};
80 static const struct generic_mapping dom_generic_mapping = {
81 GENERIC_RIGHTS_DOMAIN_READ,
82 GENERIC_RIGHTS_DOMAIN_WRITE,
83 GENERIC_RIGHTS_DOMAIN_EXECUTE,
84 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
85 static const struct generic_mapping usr_generic_mapping = {
86 GENERIC_RIGHTS_USER_READ,
87 GENERIC_RIGHTS_USER_WRITE,
88 GENERIC_RIGHTS_USER_EXECUTE,
89 GENERIC_RIGHTS_USER_ALL_ACCESS};
90 static const struct generic_mapping usr_nopwchange_generic_mapping = {
91 GENERIC_RIGHTS_USER_READ,
92 GENERIC_RIGHTS_USER_WRITE,
93 GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
94 GENERIC_RIGHTS_USER_ALL_ACCESS};
95 static const struct generic_mapping grp_generic_mapping = {
96 GENERIC_RIGHTS_GROUP_READ,
97 GENERIC_RIGHTS_GROUP_WRITE,
98 GENERIC_RIGHTS_GROUP_EXECUTE,
99 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
100 static const struct generic_mapping ali_generic_mapping = {
101 GENERIC_RIGHTS_ALIAS_READ,
102 GENERIC_RIGHTS_ALIAS_WRITE,
103 GENERIC_RIGHTS_ALIAS_EXECUTE,
104 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
106 /*******************************************************************
108 ********************************************************************/
110 static void init_lsa_String(struct lsa_String *name, const char *s)
115 /*******************************************************************
116 *******************************************************************/
118 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
119 const struct generic_mapping *map,
120 DOM_SID *sid, uint32 sid_access )
122 DOM_SID domadmin_sid;
123 SEC_ACE ace[5]; /* at most 5 entries */
129 /* basic access for Everyone */
131 init_sec_access(&mask, map->generic_execute | map->generic_read );
132 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
134 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
136 init_sec_access(&mask, map->generic_all);
138 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
139 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
141 /* Add Full Access for Domain Admins if we are a DC */
144 sid_copy( &domadmin_sid, get_global_sam_sid() );
145 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
146 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
149 /* if we have a sid, give it some special access */
152 init_sec_access( &mask, sid_access );
153 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
156 /* create the security descriptor */
158 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
159 return NT_STATUS_NO_MEMORY;
161 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
162 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
163 psa, sd_size)) == NULL)
164 return NT_STATUS_NO_MEMORY;
169 /*******************************************************************
170 Checks if access to an object should be granted, and returns that
171 level of access for further checks.
172 ********************************************************************/
174 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
175 SE_PRIV *rights, uint32 rights_mask,
176 uint32 des_access, uint32 *acc_granted,
179 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
180 uint32 saved_mask = 0;
182 /* check privileges; certain SAM access bits should be overridden
183 by privileges (mostly having to do with creating/modifying/deleting
186 if ( rights && user_has_any_privilege( token, rights ) ) {
188 saved_mask = (des_access & rights_mask);
189 des_access &= ~saved_mask;
191 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
196 /* check the security descriptor first */
198 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
201 /* give root a free pass */
203 if ( geteuid() == sec_initial_uid() ) {
205 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
206 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
208 *acc_granted = des_access;
210 status = NT_STATUS_OK;
216 /* add in any bits saved during the privilege check (only
217 matters is status is ok) */
219 *acc_granted |= rights_mask;
221 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
222 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
223 des_access, *acc_granted));
228 /*******************************************************************
229 Checks if access to a function can be granted
230 ********************************************************************/
232 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
234 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
235 debug, acc_granted, acc_required));
237 /* check the security descriptor first */
239 if ( (acc_granted&acc_required) == acc_required )
242 /* give root a free pass */
244 if (geteuid() == sec_initial_uid()) {
246 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
247 debug, acc_granted, acc_required));
248 DEBUGADD(4,("but overwritten by euid == 0\n"));
253 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
254 debug, acc_granted, acc_required));
256 return NT_STATUS_ACCESS_DENIED;
259 /*******************************************************************
260 Fetch or create a dispinfo struct.
261 ********************************************************************/
263 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
266 * We do a static cache for DISP_INFO's here. Explanation can be found
267 * in Jeremy's checkin message to r11793:
269 * Fix the SAMR cache so it works across completely insane
270 * client behaviour (ie.:
271 * open pipe/open SAMR handle/enumerate 0 - 1024
272 * close SAMR handle, close pipe.
273 * open pipe/open SAMR handle/enumerate 1024 - 2048...
274 * close SAMR handle, close pipe.
275 * And on ad-nausium. Amazing.... probably object-oriented
276 * client side programming in action yet again.
277 * This change should *massively* improve performance when
278 * enumerating users from an LDAP database.
281 * "Our" and the builtin domain are the only ones where we ever
282 * enumerate stuff, so just cache 2 entries.
285 static struct disp_info builtin_dispinfo;
286 static struct disp_info domain_dispinfo;
288 /* There are two cases to consider here:
289 1) The SID is a domain SID and we look for an equality match, or
290 2) This is an account SID and so we return the DISP_INFO* for our
297 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
299 * Necessary only once, but it does not really hurt.
301 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
303 return &builtin_dispinfo;
306 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
308 * Necessary only once, but it does not really hurt.
310 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
312 return &domain_dispinfo;
318 /*******************************************************************
319 Create a samr_info struct.
320 ********************************************************************/
322 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
324 struct samr_info *info;
329 sid_to_fstring(sid_str, psid);
331 fstrcpy(sid_str,"(NULL)");
334 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
336 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
339 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
341 sid_copy( &info->sid, psid);
342 info->builtin_domain = sid_check_is_builtin(psid);
344 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
345 info->builtin_domain = False;
347 info->mem_ctx = mem_ctx;
349 info->disp_info = get_samr_dispinfo_by_sid(psid);
354 /*******************************************************************
355 Function to free the per SID data.
356 ********************************************************************/
358 static void free_samr_cache(DISP_INFO *disp_info)
360 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
361 sid_string_dbg(&disp_info->sid)));
363 /* We need to become root here because the paged search might have to
364 * tell the LDAP server we're not interested in the rest anymore. */
368 if (disp_info->users) {
369 DEBUG(10,("free_samr_cache: deleting users cache\n"));
370 pdb_search_destroy(disp_info->users);
371 disp_info->users = NULL;
373 if (disp_info->machines) {
374 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
375 pdb_search_destroy(disp_info->machines);
376 disp_info->machines = NULL;
378 if (disp_info->groups) {
379 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
380 pdb_search_destroy(disp_info->groups);
381 disp_info->groups = NULL;
383 if (disp_info->aliases) {
384 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
385 pdb_search_destroy(disp_info->aliases);
386 disp_info->aliases = NULL;
388 if (disp_info->enum_users) {
389 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
390 pdb_search_destroy(disp_info->enum_users);
391 disp_info->enum_users = NULL;
393 disp_info->enum_acb_mask = 0;
398 /*******************************************************************
399 Function to free the per handle data.
400 ********************************************************************/
402 static void free_samr_info(void *ptr)
404 struct samr_info *info=(struct samr_info *) ptr;
406 /* Only free the dispinfo cache if no one bothered to set up
409 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
410 free_samr_cache(info->disp_info);
413 talloc_destroy(info->mem_ctx);
416 /*******************************************************************
417 Idle event handler. Throw away the disp info cache.
418 ********************************************************************/
420 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
421 struct timed_event *te,
422 const struct timeval *now,
425 DISP_INFO *disp_info = (DISP_INFO *)private_data;
427 TALLOC_FREE(disp_info->cache_timeout_event);
429 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
431 free_samr_cache(disp_info);
434 /*******************************************************************
435 Setup cache removal idle event handler.
436 ********************************************************************/
438 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
440 /* Remove any pending timeout and update. */
442 TALLOC_FREE(disp_info->cache_timeout_event);
444 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
445 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
446 (unsigned int)secs_fromnow ));
448 disp_info->cache_timeout_event = event_add_timed(
449 smbd_event_context(), NULL,
450 timeval_current_ofs(secs_fromnow, 0),
451 "disp_info_cache_idle_timeout_handler",
452 disp_info_cache_idle_timeout_handler, (void *)disp_info);
455 /*******************************************************************
456 Force flush any cache. We do this on any samr_set_xxx call.
457 We must also remove the timeout handler.
458 ********************************************************************/
460 static void force_flush_samr_cache(DISP_INFO *disp_info)
462 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
466 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
467 TALLOC_FREE(disp_info->cache_timeout_event);
468 free_samr_cache(disp_info);
471 /*******************************************************************
472 Ensure password info is never given out. Paranioa... JRA.
473 ********************************************************************/
475 static void samr_clear_sam_passwd(struct samu *sam_pass)
481 /* These now zero out the old password */
483 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
484 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
487 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
489 struct samr_displayentry *entry;
491 if (info->builtin_domain) {
492 /* No users in builtin. */
496 if (info->users == NULL) {
497 info->users = pdb_search_users(acct_flags);
498 if (info->users == NULL) {
502 /* Fetch the last possible entry, thus trigger an enumeration */
503 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
505 /* Ensure we cache this enumeration. */
506 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
508 return info->users->num_entries;
511 static uint32 count_sam_groups(struct disp_info *info)
513 struct samr_displayentry *entry;
515 if (info->builtin_domain) {
516 /* No groups in builtin. */
520 if (info->groups == NULL) {
521 info->groups = pdb_search_groups();
522 if (info->groups == NULL) {
526 /* Fetch the last possible entry, thus trigger an enumeration */
527 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
529 /* Ensure we cache this enumeration. */
530 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
532 return info->groups->num_entries;
535 static uint32 count_sam_aliases(struct disp_info *info)
537 struct samr_displayentry *entry;
539 if (info->aliases == NULL) {
540 info->aliases = pdb_search_aliases(&info->sid);
541 if (info->aliases == NULL) {
545 /* Fetch the last possible entry, thus trigger an enumeration */
546 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
548 /* Ensure we cache this enumeration. */
549 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
551 return info->aliases->num_entries;
554 /*******************************************************************
556 ********************************************************************/
558 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
560 if (!close_policy_hnd(p, r->in.handle)) {
561 return NT_STATUS_INVALID_HANDLE;
564 ZERO_STRUCTP(r->out.handle);
569 /*******************************************************************
571 ********************************************************************/
573 NTSTATUS _samr_OpenDomain(pipes_struct *p,
574 struct samr_OpenDomain *r)
576 struct samr_info *info;
577 SEC_DESC *psd = NULL;
579 uint32 des_access = r->in.access_mask;
584 /* find the connection policy handle. */
586 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
587 return NT_STATUS_INVALID_HANDLE;
589 status = access_check_samr_function(info->acc_granted,
590 SA_RIGHT_SAM_OPEN_DOMAIN,
591 "_samr_OpenDomain" );
593 if ( !NT_STATUS_IS_OK(status) )
596 /*check if access can be granted as requested by client. */
598 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
599 se_map_generic( &des_access, &dom_generic_mapping );
601 se_priv_copy( &se_rights, &se_machine_account );
602 se_priv_add( &se_rights, &se_add_users );
604 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
605 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
606 &acc_granted, "_samr_OpenDomain" );
608 if ( !NT_STATUS_IS_OK(status) )
611 if (!sid_check_is_domain(r->in.sid) &&
612 !sid_check_is_builtin(r->in.sid)) {
613 return NT_STATUS_NO_SUCH_DOMAIN;
616 /* associate the domain SID with the (unique) handle. */
617 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
618 return NT_STATUS_NO_MEMORY;
619 info->acc_granted = acc_granted;
621 /* get a (unique) handle. open a policy on it. */
622 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
623 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
625 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
630 /*******************************************************************
632 ********************************************************************/
634 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
635 struct samr_GetUserPwInfo *r)
637 struct samr_info *info = NULL;
639 /* find the policy handle. open a policy on it. */
640 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
641 return NT_STATUS_INVALID_HANDLE;
643 if (!sid_check_is_in_our_domain(&info->sid))
644 return NT_STATUS_OBJECT_TYPE_MISMATCH;
646 ZERO_STRUCTP(r->out.info);
648 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
651 * NT sometimes return NT_STATUS_ACCESS_DENIED
652 * I don't know yet why.
658 /*******************************************************************
659 ********************************************************************/
661 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
662 DOM_SID *sid, uint32 *acc_granted,
663 DISP_INFO **ppdisp_info)
665 struct samr_info *info = NULL;
667 /* find the policy handle. open a policy on it. */
668 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
675 *acc_granted = info->acc_granted;
677 *ppdisp_info = info->disp_info;
683 /*******************************************************************
685 ********************************************************************/
687 NTSTATUS _samr_SetSecurity(pipes_struct *p,
688 struct samr_SetSecurity *r)
691 uint32 acc_granted, i;
694 struct samu *sampass=NULL;
697 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
698 return NT_STATUS_INVALID_HANDLE;
700 if (!(sampass = samu_new( p->mem_ctx))) {
701 DEBUG(0,("No memory!\n"));
702 return NT_STATUS_NO_MEMORY;
705 /* get the user record */
707 ret = pdb_getsampwsid(sampass, &pol_sid);
711 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
712 TALLOC_FREE(sampass);
713 return NT_STATUS_INVALID_HANDLE;
716 dacl = r->in.sdbuf->sd->dacl;
717 for (i=0; i < dacl->num_aces; i++) {
718 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
719 ret = pdb_set_pass_can_change(sampass,
720 (dacl->aces[i].access_mask &
721 SA_RIGHT_USER_CHANGE_PASSWORD) ?
728 TALLOC_FREE(sampass);
729 return NT_STATUS_ACCESS_DENIED;
732 status = access_check_samr_function(acc_granted,
733 SA_RIGHT_USER_SET_ATTRIBUTES,
734 "_samr_SetSecurity");
735 if (NT_STATUS_IS_OK(status)) {
737 status = pdb_update_sam_account(sampass);
741 TALLOC_FREE(sampass);
746 /*******************************************************************
747 build correct perms based on policies and password times for _samr_query_sec_obj
748 *******************************************************************/
749 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
751 struct samu *sampass=NULL;
754 if ( !(sampass = samu_new( mem_ctx )) ) {
755 DEBUG(0,("No memory!\n"));
760 ret = pdb_getsampwsid(sampass, user_sid);
764 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
765 TALLOC_FREE(sampass);
769 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
771 if (pdb_get_pass_can_change(sampass)) {
772 TALLOC_FREE(sampass);
775 TALLOC_FREE(sampass);
780 /*******************************************************************
782 ********************************************************************/
784 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
785 struct samr_QuerySecurity *r)
789 SEC_DESC * psd = NULL;
794 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
795 return NT_STATUS_INVALID_HANDLE;
797 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
798 sid_string_dbg(&pol_sid)));
800 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
802 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
803 if (pol_sid.sid_rev_num == 0) {
804 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
805 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
806 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
807 /* check if it is our domain SID */
808 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
809 "with SID: %s\n", sid_string_dbg(&pol_sid)));
810 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
811 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
812 /* check if it is the Builtin Domain */
813 /* TODO: Builtin probably needs a different SD with restricted write access*/
814 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
815 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
816 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
817 } else if (sid_check_is_in_our_domain(&pol_sid) ||
818 sid_check_is_in_builtin(&pol_sid)) {
819 /* TODO: different SDs have to be generated for aliases groups and users.
820 Currently all three get a default user SD */
821 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
822 "with SID: %s\n", sid_string_dbg(&pol_sid)));
823 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
824 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
825 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
827 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
828 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
831 return NT_STATUS_OBJECT_TYPE_MISMATCH;
834 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
835 return NT_STATUS_NO_MEMORY;
840 /*******************************************************************
841 makes a SAM_ENTRY / UNISTR2* structure from a user list.
842 ********************************************************************/
844 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
845 struct samr_SamEntry **sam_pp,
846 uint32_t num_entries,
848 struct samr_displayentry *entries)
851 struct samr_SamEntry *sam;
855 if (num_entries == 0) {
859 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
861 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
862 return NT_STATUS_NO_MEMORY;
865 for (i = 0; i < num_entries; i++) {
868 * usrmgr expects a non-NULL terminated string with
869 * trust relationships
871 if (entries[i].acct_flags & ACB_DOMTRUST) {
872 init_unistr2(&uni_temp_name, entries[i].account_name,
875 init_unistr2(&uni_temp_name, entries[i].account_name,
879 init_lsa_String(&sam[i].name, entries[i].account_name);
880 sam[i].idx = entries[i].rid;
888 /*******************************************************************
889 _samr_EnumDomainUsers
890 ********************************************************************/
892 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
893 struct samr_EnumDomainUsers *r)
896 struct samr_info *info = NULL;
898 uint32 enum_context = *r->in.resume_handle;
899 enum remote_arch_types ra_type = get_remote_arch();
900 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
901 uint32 max_entries = max_sam_entries;
902 struct samr_displayentry *entries = NULL;
903 struct samr_SamArray *samr_array = NULL;
904 struct samr_SamEntry *samr_entries = NULL;
906 /* find the policy handle. open a policy on it. */
907 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
908 return NT_STATUS_INVALID_HANDLE;
910 status = access_check_samr_function(info->acc_granted,
911 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
912 "_samr_EnumDomainUsers");
913 if (!NT_STATUS_IS_OK(status)) {
917 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
919 if (info->builtin_domain) {
920 /* No users in builtin. */
921 *r->out.resume_handle = *r->in.resume_handle;
922 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
926 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
928 return NT_STATUS_NO_MEMORY;
935 if ((info->disp_info->enum_users != NULL) &&
936 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
937 pdb_search_destroy(info->disp_info->enum_users);
938 info->disp_info->enum_users = NULL;
941 if (info->disp_info->enum_users == NULL) {
942 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
943 info->disp_info->enum_acb_mask = r->in.acct_flags;
946 if (info->disp_info->enum_users == NULL) {
947 /* END AS ROOT !!!! */
949 return NT_STATUS_ACCESS_DENIED;
952 num_account = pdb_search_entries(info->disp_info->enum_users,
953 enum_context, max_entries,
956 /* END AS ROOT !!!! */
960 if (num_account == 0) {
961 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
963 *r->out.resume_handle = *r->in.resume_handle;
967 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
968 num_account, enum_context,
970 if (!NT_STATUS_IS_OK(status)) {
974 if (max_entries <= num_account) {
975 status = STATUS_MORE_ENTRIES;
977 status = NT_STATUS_OK;
980 /* Ensure we cache this enumeration. */
981 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
983 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
985 samr_array->count = num_account;
986 samr_array->entries = samr_entries;
988 *r->out.resume_handle = *r->in.resume_handle + num_account;
989 *r->out.sam = samr_array;
990 *r->out.num_entries = num_account;
992 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
997 /*******************************************************************
998 makes a SAM_ENTRY / UNISTR2* structure from a group list.
999 ********************************************************************/
1001 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1002 struct samr_SamEntry **sam_pp,
1003 uint32_t num_sam_entries,
1004 struct samr_displayentry *entries)
1006 struct samr_SamEntry *sam;
1011 if (num_sam_entries == 0) {
1015 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1020 for (i = 0; i < num_sam_entries; i++) {
1022 * JRA. I think this should include the null. TNG does not.
1024 init_lsa_String(&sam[i].name, entries[i].account_name);
1025 sam[i].idx = entries[i].rid;
1031 /*******************************************************************
1032 _samr_EnumDomainGroups
1033 ********************************************************************/
1035 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1036 struct samr_EnumDomainGroups *r)
1039 struct samr_info *info = NULL;
1040 struct samr_displayentry *groups;
1042 struct samr_SamArray *samr_array = NULL;
1043 struct samr_SamEntry *samr_entries = NULL;
1045 /* find the policy handle. open a policy on it. */
1046 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1047 return NT_STATUS_INVALID_HANDLE;
1049 status = access_check_samr_function(info->acc_granted,
1050 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1051 "_samr_EnumDomainGroups");
1052 if (!NT_STATUS_IS_OK(status)) {
1056 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1058 if (info->builtin_domain) {
1059 /* No groups in builtin. */
1060 *r->out.resume_handle = *r->in.resume_handle;
1061 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1065 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1067 return NT_STATUS_NO_MEMORY;
1070 /* the domain group array is being allocated in the function below */
1074 if (info->disp_info->groups == NULL) {
1075 info->disp_info->groups = pdb_search_groups();
1077 if (info->disp_info->groups == NULL) {
1079 return NT_STATUS_ACCESS_DENIED;
1083 num_groups = pdb_search_entries(info->disp_info->groups,
1084 *r->in.resume_handle,
1085 MAX_SAM_ENTRIES, &groups);
1088 /* Ensure we cache this enumeration. */
1089 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1091 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1092 num_groups, groups);
1094 samr_array->count = num_groups;
1095 samr_array->entries = samr_entries;
1097 *r->out.sam = samr_array;
1098 *r->out.num_entries = num_groups;
1099 /* this was missing, IMHO:
1100 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1103 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1108 /*******************************************************************
1109 _samr_EnumDomainAliases
1110 ********************************************************************/
1112 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1113 struct samr_EnumDomainAliases *r)
1116 struct samr_info *info;
1117 struct samr_displayentry *aliases;
1118 uint32 num_aliases = 0;
1119 struct samr_SamArray *samr_array = NULL;
1120 struct samr_SamEntry *samr_entries = NULL;
1122 /* find the policy handle. open a policy on it. */
1123 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1124 return NT_STATUS_INVALID_HANDLE;
1126 status = access_check_samr_function(info->acc_granted,
1127 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1128 "_samr_EnumDomainAliases");
1129 if (!NT_STATUS_IS_OK(status)) {
1133 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1134 sid_string_dbg(&info->sid)));
1136 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1138 return NT_STATUS_NO_MEMORY;
1143 if (info->disp_info->aliases == NULL) {
1144 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1145 if (info->disp_info->aliases == NULL) {
1147 return NT_STATUS_ACCESS_DENIED;
1151 num_aliases = pdb_search_entries(info->disp_info->aliases,
1152 *r->in.resume_handle,
1153 MAX_SAM_ENTRIES, &aliases);
1156 /* Ensure we cache this enumeration. */
1157 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1159 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1160 num_aliases, aliases);
1162 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1164 samr_array->count = num_aliases;
1165 samr_array->entries = samr_entries;
1167 *r->out.sam = samr_array;
1168 *r->out.num_entries = num_aliases;
1169 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1174 /*******************************************************************
1176 ********************************************************************/
1178 static void init_lsa_AsciiString(struct lsa_AsciiString *name, const char *s)
1183 /*******************************************************************
1184 inits a samr_DispInfoGeneral structure.
1185 ********************************************************************/
1187 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1188 struct samr_DispInfoGeneral *r,
1189 uint32_t num_entries,
1191 struct samr_displayentry *entries)
1195 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1197 if (num_entries == 0) {
1198 return NT_STATUS_OK;
1201 r->count = num_entries;
1203 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1205 return NT_STATUS_NO_MEMORY;
1208 for (i = 0; i < num_entries ; i++) {
1210 init_lsa_String(&r->entries[i].account_name,
1211 entries[i].account_name);
1213 init_lsa_String(&r->entries[i].description,
1214 entries[i].description);
1216 init_lsa_String(&r->entries[i].full_name,
1217 entries[i].fullname);
1219 r->entries[i].rid = entries[i].rid;
1220 r->entries[i].acct_flags = entries[i].acct_flags;
1221 r->entries[i].idx = start_idx+i+1;
1224 return NT_STATUS_OK;
1227 /*******************************************************************
1228 inits a samr_DispInfoFull structure.
1229 ********************************************************************/
1231 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1232 struct samr_DispInfoFull *r,
1233 uint32_t num_entries,
1235 struct samr_displayentry *entries)
1239 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1241 if (num_entries == 0) {
1242 return NT_STATUS_OK;
1245 r->count = num_entries;
1247 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1249 return NT_STATUS_NO_MEMORY;
1252 for (i = 0; i < num_entries ; i++) {
1254 init_lsa_String(&r->entries[i].account_name,
1255 entries[i].account_name);
1257 init_lsa_String(&r->entries[i].description,
1258 entries[i].description);
1260 r->entries[i].rid = entries[i].rid;
1261 r->entries[i].acct_flags = entries[i].acct_flags;
1262 r->entries[i].idx = start_idx+i+1;
1265 return NT_STATUS_OK;
1268 /*******************************************************************
1269 inits a samr_DispInfoFullGroups structure.
1270 ********************************************************************/
1272 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1273 struct samr_DispInfoFullGroups *r,
1274 uint32_t num_entries,
1276 struct samr_displayentry *entries)
1280 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1282 if (num_entries == 0) {
1283 return NT_STATUS_OK;
1286 r->count = num_entries;
1288 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1290 return NT_STATUS_NO_MEMORY;
1293 for (i = 0; i < num_entries ; i++) {
1295 init_lsa_String(&r->entries[i].account_name,
1296 entries[i].account_name);
1298 init_lsa_String(&r->entries[i].description,
1299 entries[i].description);
1301 r->entries[i].rid = entries[i].rid;
1302 r->entries[i].acct_flags = entries[i].acct_flags;
1303 r->entries[i].idx = start_idx+i+1;
1306 return NT_STATUS_OK;
1309 /*******************************************************************
1310 inits a samr_DispInfoAscii structure.
1311 ********************************************************************/
1313 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1314 struct samr_DispInfoAscii *r,
1315 uint32_t num_entries,
1317 struct samr_displayentry *entries)
1321 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1323 if (num_entries == 0) {
1324 return NT_STATUS_OK;
1327 r->count = num_entries;
1329 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1331 return NT_STATUS_NO_MEMORY;
1334 for (i = 0; i < num_entries ; i++) {
1336 init_lsa_AsciiString(&r->entries[i].account_name,
1337 entries[i].account_name);
1339 r->entries[i].idx = start_idx+i+1;
1342 return NT_STATUS_OK;
1345 /*******************************************************************
1346 inits a samr_DispInfoAscii structure.
1347 ********************************************************************/
1349 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1350 struct samr_DispInfoAscii *r,
1351 uint32_t num_entries,
1353 struct samr_displayentry *entries)
1357 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1359 if (num_entries == 0) {
1360 return NT_STATUS_OK;
1363 r->count = num_entries;
1365 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1367 return NT_STATUS_NO_MEMORY;
1370 for (i = 0; i < num_entries ; i++) {
1372 init_lsa_AsciiString(&r->entries[i].account_name,
1373 entries[i].account_name);
1375 r->entries[i].idx = start_idx+i+1;
1378 return NT_STATUS_OK;
1381 /*******************************************************************
1382 _samr_QueryDisplayInfo
1383 ********************************************************************/
1385 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1386 struct samr_QueryDisplayInfo *r)
1389 struct samr_info *info = NULL;
1390 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1392 uint32 max_entries = r->in.max_entries;
1393 uint32 enum_context = r->in.start_idx;
1394 uint32 max_size = r->in.buf_size;
1396 union samr_DispInfo *disp_info = r->out.info;
1398 uint32 temp_size=0, total_data_size=0;
1399 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1400 uint32 num_account = 0;
1401 enum remote_arch_types ra_type = get_remote_arch();
1402 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1403 struct samr_displayentry *entries = NULL;
1405 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1407 /* find the policy handle. open a policy on it. */
1408 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1409 return NT_STATUS_INVALID_HANDLE;
1412 * calculate how many entries we will return.
1414 * - the number of entries the client asked
1415 * - our limit on that
1416 * - the starting point (enumeration context)
1417 * - the buffer size the client will accept
1421 * We are a lot more like W2K. Instead of reading the SAM
1422 * each time to find the records we need to send back,
1423 * we read it once and link that copy to the sam handle.
1424 * For large user list (over the MAX_SAM_ENTRIES)
1425 * it's a definitive win.
1426 * second point to notice: between enumerations
1427 * our sam is now the same as it's a snapshoot.
1428 * third point: got rid of the static SAM_USER_21 struct
1429 * no more intermediate.
1430 * con: it uses much more memory, as a full copy is stored
1433 * If you want to change it, think twice and think
1434 * of the second point , that's really important.
1439 if ((r->in.level < 1) || (r->in.level > 5)) {
1440 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1441 (unsigned int)r->in.level ));
1442 return NT_STATUS_INVALID_INFO_CLASS;
1445 /* first limit the number of entries we will return */
1446 if(max_entries > max_sam_entries) {
1447 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1448 "entries, limiting to %d\n", max_entries,
1450 max_entries = max_sam_entries;
1453 /* calculate the size and limit on the number of entries we will
1456 temp_size=max_entries*struct_size;
1458 if (temp_size>max_size) {
1459 max_entries=MIN((max_size/struct_size),max_entries);;
1460 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1461 "only %d entries\n", max_entries));
1466 /* THe following done as ROOT. Don't return without unbecome_root(). */
1468 switch (r->in.level) {
1471 if (info->disp_info->users == NULL) {
1472 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1473 if (info->disp_info->users == NULL) {
1475 return NT_STATUS_ACCESS_DENIED;
1477 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1478 (unsigned int)enum_context ));
1480 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1481 (unsigned int)enum_context ));
1484 num_account = pdb_search_entries(info->disp_info->users,
1485 enum_context, max_entries,
1489 if (info->disp_info->machines == NULL) {
1490 info->disp_info->machines =
1491 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1492 if (info->disp_info->machines == NULL) {
1494 return NT_STATUS_ACCESS_DENIED;
1496 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1497 (unsigned int)enum_context ));
1499 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1500 (unsigned int)enum_context ));
1503 num_account = pdb_search_entries(info->disp_info->machines,
1504 enum_context, max_entries,
1509 if (info->disp_info->groups == NULL) {
1510 info->disp_info->groups = pdb_search_groups();
1511 if (info->disp_info->groups == NULL) {
1513 return NT_STATUS_ACCESS_DENIED;
1515 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1516 (unsigned int)enum_context ));
1518 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1519 (unsigned int)enum_context ));
1522 num_account = pdb_search_entries(info->disp_info->groups,
1523 enum_context, max_entries,
1528 smb_panic("info class changed");
1534 /* Now create reply structure */
1535 switch (r->in.level) {
1537 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1538 num_account, enum_context,
1542 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1543 num_account, enum_context,
1547 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1548 num_account, enum_context,
1552 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1553 num_account, enum_context,
1557 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1558 num_account, enum_context,
1562 smb_panic("info class changed");
1566 if (!NT_STATUS_IS_OK(disp_ret))
1569 /* calculate the total size */
1570 total_data_size=num_account*struct_size;
1573 status = STATUS_MORE_ENTRIES;
1575 status = NT_STATUS_OK;
1578 /* Ensure we cache this enumeration. */
1579 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1581 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1583 *r->out.total_size = total_data_size;
1584 *r->out.returned_size = temp_size;
1589 /****************************************************************
1590 _samr_QueryDisplayInfo2
1591 ****************************************************************/
1593 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1594 struct samr_QueryDisplayInfo2 *r)
1596 struct samr_QueryDisplayInfo q;
1598 q.in.domain_handle = r->in.domain_handle;
1599 q.in.level = r->in.level;
1600 q.in.start_idx = r->in.start_idx;
1601 q.in.max_entries = r->in.max_entries;
1602 q.in.buf_size = r->in.buf_size;
1604 q.out.total_size = r->out.total_size;
1605 q.out.returned_size = r->out.returned_size;
1606 q.out.info = r->out.info;
1608 return _samr_QueryDisplayInfo(p, &q);
1611 /****************************************************************
1612 _samr_QueryDisplayInfo3
1613 ****************************************************************/
1615 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1616 struct samr_QueryDisplayInfo3 *r)
1618 struct samr_QueryDisplayInfo q;
1620 q.in.domain_handle = r->in.domain_handle;
1621 q.in.level = r->in.level;
1622 q.in.start_idx = r->in.start_idx;
1623 q.in.max_entries = r->in.max_entries;
1624 q.in.buf_size = r->in.buf_size;
1626 q.out.total_size = r->out.total_size;
1627 q.out.returned_size = r->out.returned_size;
1628 q.out.info = r->out.info;
1630 return _samr_QueryDisplayInfo(p, &q);
1633 /*******************************************************************
1634 _samr_QueryAliasInfo
1635 ********************************************************************/
1637 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1638 struct samr_QueryAliasInfo *r)
1641 struct acct_info info;
1644 union samr_AliasInfo *alias_info = NULL;
1645 const char *alias_name = NULL;
1646 const char *alias_description = NULL;
1648 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1650 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1652 return NT_STATUS_NO_MEMORY;
1655 /* find the policy handle. open a policy on it. */
1656 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1657 return NT_STATUS_INVALID_HANDLE;
1659 status = access_check_samr_function(acc_granted,
1660 SA_RIGHT_ALIAS_LOOKUP_INFO,
1661 "_samr_QueryAliasInfo");
1662 if (!NT_STATUS_IS_OK(status)) {
1667 status = pdb_get_aliasinfo(&sid, &info);
1670 if ( !NT_STATUS_IS_OK(status))
1673 /* FIXME: info contains fstrings */
1674 alias_name = talloc_strdup(r, info.acct_name);
1675 alias_description = talloc_strdup(r, info.acct_desc);
1677 switch (r->in.level) {
1679 init_samr_alias_info1(&alias_info->all,
1684 case ALIASINFODESCRIPTION:
1685 init_samr_alias_info3(&alias_info->description,
1689 return NT_STATUS_INVALID_INFO_CLASS;
1692 *r->out.info = alias_info;
1694 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1696 return NT_STATUS_OK;
1700 /*******************************************************************
1701 samr_reply_lookup_ids
1702 ********************************************************************/
1704 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1706 uint32 rid[MAX_SAM_ENTRIES];
1707 int num_rids = q_u->num_sids1;
1709 r_u->status = NT_STATUS_OK;
1711 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1713 if (num_rids > MAX_SAM_ENTRIES) {
1714 num_rids = MAX_SAM_ENTRIES;
1715 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1720 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1722 for (i = 0; i < num_rids && status == 0; i++)
1724 struct sam_passwd *sam_pass;
1728 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1729 q_u->uni_user_name[i].uni_str_len));
1731 /* find the user account */
1733 sam_pass = get_smb21pwd_entry(user_name, 0);
1736 if (sam_pass == NULL)
1738 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1743 rid[i] = sam_pass->user_rid;
1749 rid[0] = BUILTIN_ALIAS_RID_USERS;
1751 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1753 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1759 /*******************************************************************
1761 ********************************************************************/
1763 NTSTATUS _samr_LookupNames(pipes_struct *p,
1764 struct samr_LookupNames *r)
1767 uint32 rid[MAX_SAM_ENTRIES];
1768 enum lsa_SidType type[MAX_SAM_ENTRIES];
1770 int num_rids = r->in.num_names;
1773 struct samr_Ids rids, types;
1775 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1780 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1781 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1784 status = access_check_samr_function(acc_granted,
1785 0, /* Don't know the acc_bits yet */
1786 "_samr_LookupNames");
1787 if (!NT_STATUS_IS_OK(status)) {
1791 if (num_rids > MAX_SAM_ENTRIES) {
1792 num_rids = MAX_SAM_ENTRIES;
1793 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1796 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1797 sid_string_dbg(&pol_sid)));
1799 for (i = 0; i < num_rids; i++) {
1801 status = NT_STATUS_NONE_MAPPED;
1802 type[i] = SID_NAME_UNKNOWN;
1804 rid[i] = 0xffffffff;
1806 if (sid_check_is_builtin(&pol_sid)) {
1807 if (lookup_builtin_name(r->in.names[i].string,
1810 type[i] = SID_NAME_ALIAS;
1813 lookup_global_sam_name(r->in.names[i].string, 0,
1817 if (type[i] != SID_NAME_UNKNOWN) {
1818 status = NT_STATUS_OK;
1822 rids.count = num_rids;
1825 types.count = num_rids;
1828 *r->out.rids = rids;
1829 *r->out.types = types;
1831 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1836 /*******************************************************************
1837 _samr_ChangePasswordUser2
1838 ********************************************************************/
1840 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1841 struct samr_ChangePasswordUser2 *r)
1847 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1849 fstrcpy(user_name, r->in.account->string);
1850 fstrcpy(wks, r->in.server->string);
1852 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1855 * Pass the user through the NT -> unix user mapping
1859 (void)map_username(user_name);
1862 * UNIX username case mangling not required, pass_oem_change
1863 * is case insensitive.
1866 status = pass_oem_change(user_name,
1867 r->in.lm_password->data,
1868 r->in.lm_verifier->hash,
1869 r->in.nt_password->data,
1870 r->in.nt_verifier->hash,
1873 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1878 /*******************************************************************
1879 _samr_ChangePasswordUser3
1880 ********************************************************************/
1882 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1883 struct samr_ChangePasswordUser3 *r)
1887 const char *wks = NULL;
1888 uint32 reject_reason;
1889 struct samr_DomInfo1 *dominfo = NULL;
1890 struct samr_ChangeReject *reject = NULL;
1892 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1894 fstrcpy(user_name, r->in.account->string);
1895 if (r->in.server && r->in.server->string) {
1896 wks = r->in.server->string;
1899 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1902 * Pass the user through the NT -> unix user mapping
1906 (void)map_username(user_name);
1909 * UNIX username case mangling not required, pass_oem_change
1910 * is case insensitive.
1913 status = pass_oem_change(user_name,
1914 r->in.lm_password->data,
1915 r->in.lm_verifier->hash,
1916 r->in.nt_password->data,
1917 r->in.nt_verifier->hash,
1920 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1921 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1923 uint32 min_pass_len,pass_hist,password_properties;
1924 time_t u_expire, u_min_age;
1925 NTTIME nt_expire, nt_min_age;
1926 uint32 account_policy_temp;
1928 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1930 return NT_STATUS_NO_MEMORY;
1933 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1935 return NT_STATUS_NO_MEMORY;
1942 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1943 min_pass_len = account_policy_temp;
1945 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1946 pass_hist = account_policy_temp;
1948 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1949 password_properties = account_policy_temp;
1951 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1952 u_expire = account_policy_temp;
1954 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1955 u_min_age = account_policy_temp;
1961 unix_to_nt_time_abs(&nt_expire, u_expire);
1962 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1964 if (lp_check_password_script() && *lp_check_password_script()) {
1965 password_properties |= DOMAIN_PASSWORD_COMPLEX;
1968 init_samr_DomInfo1(dominfo,
1971 password_properties,
1975 reject->reason = reject_reason;
1977 *r->out.dominfo = dominfo;
1978 *r->out.reject = reject;
1981 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1986 /*******************************************************************
1987 makes a SAMR_R_LOOKUP_RIDS structure.
1988 ********************************************************************/
1990 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1992 struct lsa_String **lsa_name_array_p)
1994 struct lsa_String *lsa_name_array = NULL;
1997 *lsa_name_array_p = NULL;
1999 if (num_names != 0) {
2000 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2001 if (!lsa_name_array) {
2006 for (i = 0; i < num_names; i++) {
2007 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2008 init_lsa_String(&lsa_name_array[i], names[i]);
2011 *lsa_name_array_p = lsa_name_array;
2016 /*******************************************************************
2018 ********************************************************************/
2020 NTSTATUS _samr_LookupRids(pipes_struct *p,
2021 struct samr_LookupRids *r)
2025 enum lsa_SidType *attrs = NULL;
2026 uint32 *wire_attrs = NULL;
2028 int num_rids = (int)r->in.num_rids;
2031 struct lsa_Strings names_array;
2032 struct samr_Ids types_array;
2033 struct lsa_String *lsa_names = NULL;
2035 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2037 /* find the policy handle. open a policy on it. */
2038 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2039 return NT_STATUS_INVALID_HANDLE;
2041 if (num_rids > 1000) {
2042 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2043 "to samba4 idl this is not possible\n", num_rids));
2044 return NT_STATUS_UNSUCCESSFUL;
2048 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2049 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2050 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2052 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2053 return NT_STATUS_NO_MEMORY;
2060 become_root(); /* lookup_sid can require root privs */
2061 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2065 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2066 status = NT_STATUS_OK;
2069 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2071 return NT_STATUS_NO_MEMORY;
2074 /* Convert from enum lsa_SidType to uint32 for wire format. */
2075 for (i = 0; i < num_rids; i++) {
2076 wire_attrs[i] = (uint32)attrs[i];
2079 names_array.count = num_rids;
2080 names_array.names = lsa_names;
2082 types_array.count = num_rids;
2083 types_array.ids = wire_attrs;
2085 *r->out.names = names_array;
2086 *r->out.types = types_array;
2088 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2093 /*******************************************************************
2095 ********************************************************************/
2097 NTSTATUS _samr_OpenUser(pipes_struct *p,
2098 struct samr_OpenUser *r)
2100 struct samu *sampass=NULL;
2102 POLICY_HND domain_pol = *r->in.domain_handle;
2103 POLICY_HND *user_pol = r->out.user_handle;
2104 struct samr_info *info = NULL;
2105 SEC_DESC *psd = NULL;
2107 uint32 des_access = r->in.access_mask;
2113 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2115 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2116 return NT_STATUS_INVALID_HANDLE;
2118 nt_status = access_check_samr_function(acc_granted,
2119 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2122 if ( !NT_STATUS_IS_OK(nt_status) )
2125 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2126 return NT_STATUS_NO_MEMORY;
2129 /* append the user's RID to it */
2131 if (!sid_append_rid(&sid, r->in.rid))
2132 return NT_STATUS_NO_SUCH_USER;
2134 /* check if access can be granted as requested by client. */
2136 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2137 se_map_generic(&des_access, &usr_generic_mapping);
2139 se_priv_copy( &se_rights, &se_machine_account );
2140 se_priv_add( &se_rights, &se_add_users );
2142 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2143 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2144 &acc_granted, "_samr_OpenUser");
2146 if ( !NT_STATUS_IS_OK(nt_status) )
2150 ret=pdb_getsampwsid(sampass, &sid);
2153 /* check that the SID exists in our domain. */
2155 return NT_STATUS_NO_SUCH_USER;
2158 TALLOC_FREE(sampass);
2160 /* associate the user's SID and access bits with the new handle. */
2161 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2162 return NT_STATUS_NO_MEMORY;
2163 info->acc_granted = acc_granted;
2165 /* get a (unique) handle. open a policy on it. */
2166 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2167 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2169 return NT_STATUS_OK;
2172 /*************************************************************************
2173 get_user_info_7. Safe. Only gives out account_name.
2174 *************************************************************************/
2176 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2177 struct samr_UserInfo7 *r,
2180 struct samu *smbpass=NULL;
2182 const char *account_name = NULL;
2186 if ( !(smbpass = samu_new( mem_ctx )) ) {
2187 return NT_STATUS_NO_MEMORY;
2191 ret = pdb_getsampwsid(smbpass, user_sid);
2195 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2196 return NT_STATUS_NO_SUCH_USER;
2199 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2200 if (!account_name) {
2201 TALLOC_FREE(smbpass);
2202 return NT_STATUS_NO_MEMORY;
2204 TALLOC_FREE(smbpass);
2206 DEBUG(3,("User:[%s]\n", account_name));
2208 init_samr_user_info7(r, account_name);
2210 return NT_STATUS_OK;
2213 /*************************************************************************
2214 get_user_info_9. Only gives out primary group SID.
2215 *************************************************************************/
2217 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2218 struct samr_UserInfo9 *r,
2221 struct samu *smbpass=NULL;
2226 if ( !(smbpass = samu_new( mem_ctx )) ) {
2227 return NT_STATUS_NO_MEMORY;
2231 ret = pdb_getsampwsid(smbpass, user_sid);
2235 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2236 TALLOC_FREE(smbpass);
2237 return NT_STATUS_NO_SUCH_USER;
2240 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2242 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2244 TALLOC_FREE(smbpass);
2246 return NT_STATUS_OK;
2249 /*************************************************************************
2250 get_user_info_16. Safe. Only gives out acb bits.
2251 *************************************************************************/
2253 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2254 struct samr_UserInfo16 *r,
2257 struct samu *smbpass=NULL;
2262 if ( !(smbpass = samu_new( mem_ctx )) ) {
2263 return NT_STATUS_NO_MEMORY;
2267 ret = pdb_getsampwsid(smbpass, user_sid);
2271 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2272 TALLOC_FREE(smbpass);
2273 return NT_STATUS_NO_SUCH_USER;
2276 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2278 init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2280 TALLOC_FREE(smbpass);
2282 return NT_STATUS_OK;
2285 /*************************************************************************
2286 get_user_info_18. OK - this is the killer as it gives out password info.
2287 Ensure that this is only allowed on an encrypted connection with a root
2289 *************************************************************************/
2291 static NTSTATUS get_user_info_18(pipes_struct *p,
2292 TALLOC_CTX *mem_ctx,
2293 struct samr_UserInfo18 *r,
2296 struct samu *smbpass=NULL;
2301 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2302 return NT_STATUS_ACCESS_DENIED;
2305 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2306 return NT_STATUS_ACCESS_DENIED;
2310 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2313 if ( !(smbpass = samu_new( mem_ctx )) ) {
2314 return NT_STATUS_NO_MEMORY;
2317 ret = pdb_getsampwsid(smbpass, user_sid);
2320 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2321 TALLOC_FREE(smbpass);
2322 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2325 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2327 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2328 TALLOC_FREE(smbpass);
2329 return NT_STATUS_ACCOUNT_DISABLED;
2332 init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2333 pdb_get_nt_passwd(smbpass));
2335 TALLOC_FREE(smbpass);
2337 return NT_STATUS_OK;
2340 /*************************************************************************
2342 *************************************************************************/
2344 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2345 struct samr_UserInfo20 *r,
2348 struct samu *sampass=NULL;
2350 const char *munged_dial = NULL;
2351 const char *munged_dial_decoded = NULL;
2356 if ( !(sampass = samu_new( mem_ctx )) ) {
2357 return NT_STATUS_NO_MEMORY;
2361 ret = pdb_getsampwsid(sampass, user_sid);
2365 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2366 TALLOC_FREE(sampass);
2367 return NT_STATUS_NO_SUCH_USER;
2370 munged_dial = pdb_get_munged_dial(sampass);
2372 samr_clear_sam_passwd(sampass);
2374 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
2377 blob = base64_decode_data_blob(munged_dial);
2378 munged_dial_decoded = talloc_strndup(mem_ctx,
2379 (const char *)blob.data,
2381 data_blob_free(&blob);
2382 if (!munged_dial_decoded) {
2383 TALLOC_FREE(sampass);
2384 return NT_STATUS_NO_MEMORY;
2389 init_unistr2_from_datablob(&usr->uni_munged_dial, &blob);
2390 init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
2391 data_blob_free(&blob);
2393 init_samr_user_info20(r, munged_dial_decoded);
2395 TALLOC_FREE(sampass);
2397 return NT_STATUS_OK;
2401 /*************************************************************************
2403 *************************************************************************/
2405 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2406 struct samr_UserInfo21 *r,
2408 DOM_SID *domain_sid)
2410 struct samu *pw = NULL;
2412 const DOM_SID *sid_user, *sid_group;
2413 uint32_t rid, primary_gid;
2414 NTTIME last_logon, last_logoff, last_password_change,
2415 acct_expiry, allow_password_change, force_password_change;
2416 time_t must_change_time;
2417 uint8_t password_expired;
2418 const char *account_name, *full_name, *home_directory, *home_drive,
2419 *logon_script, *profile_path, *description,
2420 *workstations, *comment, *parameters;
2421 struct samr_LogonHours logon_hours;
2422 const char *munged_dial = NULL;
2427 if (!(pw = samu_new(mem_ctx))) {
2428 return NT_STATUS_NO_MEMORY;
2432 ret = pdb_getsampwsid(pw, user_sid);
2436 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2438 return NT_STATUS_NO_SUCH_USER;
2441 samr_clear_sam_passwd(pw);
2443 DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2445 sid_user = pdb_get_user_sid(pw);
2447 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2448 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2449 "the domain sid %s. Failing operation.\n",
2450 pdb_get_username(pw), sid_string_dbg(sid_user),
2451 sid_string_dbg(domain_sid)));
2453 return NT_STATUS_UNSUCCESSFUL;
2457 sid_group = pdb_get_group_sid(pw);
2460 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2461 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2462 "which conflicts with the domain sid %s. Failing operation.\n",
2463 pdb_get_username(pw), sid_string_dbg(sid_group),
2464 sid_string_dbg(domain_sid)));
2466 return NT_STATUS_UNSUCCESSFUL;
2469 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2470 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2471 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2472 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2473 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2475 must_change_time = pdb_get_pass_must_change_time(pw);
2476 if (must_change_time == get_time_t_max()) {
2477 unix_to_nt_time_abs(&force_password_change, must_change_time);
2479 unix_to_nt_time(&force_password_change, must_change_time);
2482 if (pdb_get_pass_must_change_time(pw) == 0) {
2483 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2485 password_expired = 0;
2488 munged_dial = pdb_get_munged_dial(pw);
2490 blob = base64_decode_data_blob(munged_dial);
2491 parameters = talloc_strndup(mem_ctx, (const char *)blob.data, blob.length);
2492 data_blob_free(&blob);
2495 return NT_STATUS_NO_MEMORY;
2500 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2501 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2502 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2503 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2504 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2505 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2506 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2507 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2508 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2510 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2514 Look at a user on a real NT4 PDC with usrmgr, press
2515 'ok'. Then you will see that fields_present is set to
2516 0x08f827fa. Look at the user immediately after that again,
2517 and you will see that 0x00fffff is returned. This solves
2518 the problem that you get access denied after having looked
2524 init_unistr2_from_datablob(&usr->uni_munged_dial, &munged_dial_blob);
2525 init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
2526 data_blob_free(&munged_dial_blob);
2530 init_samr_user_info21(r,
2533 last_password_change,
2535 allow_password_change,
2536 force_password_change,
2549 pdb_get_acct_ctrl(pw),
2550 pdb_build_fields_present(pw),
2552 pdb_get_bad_password_count(pw),
2553 pdb_get_logon_count(pw),
2556 0, //nt_password_set,
2557 0, //lm_password_set,
2561 return NT_STATUS_OK;
2564 /*******************************************************************
2566 ********************************************************************/
2568 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2569 struct samr_QueryUserInfo *r)
2572 union samr_UserInfo *user_info = NULL;
2573 struct samr_info *info = NULL;
2577 /* search for the handle */
2578 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2579 return NT_STATUS_INVALID_HANDLE;
2581 domain_sid = info->sid;
2583 sid_split_rid(&domain_sid, &rid);
2585 if (!sid_check_is_in_our_domain(&info->sid))
2586 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2588 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2589 sid_string_dbg(&info->sid)));
2591 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2593 return NT_STATUS_NO_MEMORY;
2596 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2598 switch (r->in.level) {
2600 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2601 if (!NT_STATUS_IS_OK(status)) {
2606 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2607 if (!NT_STATUS_IS_OK(status)) {
2612 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2613 if (!NT_STATUS_IS_OK(status)) {
2619 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2620 if (!NT_STATUS_IS_OK(status)) {
2626 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2627 if (!NT_STATUS_IS_OK(status)) {
2633 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2634 &info->sid, &domain_sid);
2635 if (!NT_STATUS_IS_OK(status)) {
2641 return NT_STATUS_INVALID_INFO_CLASS;
2644 *r->out.info = user_info;
2646 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2651 /*******************************************************************
2652 _samr_GetGroupsForUser
2653 ********************************************************************/
2655 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2656 struct samr_GetGroupsForUser *r)
2658 struct samu *sam_pass=NULL;
2661 struct samr_RidWithAttribute dom_gid;
2662 struct samr_RidWithAttribute *gids = NULL;
2663 uint32 primary_group_rid;
2664 size_t num_groups = 0;
2670 bool success = False;
2672 struct samr_RidWithAttributeArray *rids = NULL;
2675 * from the SID in the request:
2676 * we should send back the list of DOMAIN GROUPS
2677 * the user is a member of
2679 * and only the DOMAIN GROUPS
2680 * no ALIASES !!! neither aliases of the domain
2681 * nor aliases of the builtin SID
2686 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2688 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2690 return NT_STATUS_NO_MEMORY;
2693 /* find the policy handle. open a policy on it. */
2694 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2695 return NT_STATUS_INVALID_HANDLE;
2697 result = access_check_samr_function(acc_granted,
2698 SA_RIGHT_USER_GET_GROUPS,
2699 "_samr_GetGroupsForUser");
2700 if (!NT_STATUS_IS_OK(result)) {
2704 if (!sid_check_is_in_our_domain(&sid))
2705 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2707 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2708 return NT_STATUS_NO_MEMORY;
2712 ret = pdb_getsampwsid(sam_pass, &sid);
2716 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2717 sid_string_dbg(&sid)));
2718 return NT_STATUS_NO_SUCH_USER;
2723 /* make both calls inside the root block */
2725 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2726 &sids, &unix_gids, &num_groups);
2727 if ( NT_STATUS_IS_OK(result) ) {
2728 success = sid_peek_check_rid(get_global_sam_sid(),
2729 pdb_get_group_sid(sam_pass),
2730 &primary_group_rid);
2734 if (!NT_STATUS_IS_OK(result)) {
2735 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2736 sid_string_dbg(&sid)));
2741 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2742 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2743 pdb_get_username(sam_pass)));
2744 TALLOC_FREE(sam_pass);
2745 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2751 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2753 dom_gid.rid = primary_group_rid;
2754 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2756 for (i=0; i<num_groups; i++) {
2758 if (!sid_peek_check_rid(get_global_sam_sid(),
2759 &(sids[i]), &dom_gid.rid)) {
2760 DEBUG(10, ("Found sid %s not in our domain\n",
2761 sid_string_dbg(&sids[i])));
2765 if (dom_gid.rid == primary_group_rid) {
2766 /* We added the primary group directly from the
2767 * sam_account. The other SIDs are unique from
2768 * enum_group_memberships */
2772 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2775 rids->count = num_gids;
2778 *r->out.rids = rids;
2780 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2785 /*******************************************************************
2786 samr_QueryDomainInfo_internal
2787 ********************************************************************/
2789 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2791 struct policy_handle *handle,
2793 union samr_DomainInfo **dom_info_ptr)
2795 NTSTATUS status = NT_STATUS_OK;
2796 struct samr_info *info = NULL;
2797 union samr_DomainInfo *dom_info;
2798 uint32 min_pass_len,pass_hist,password_properties;
2799 time_t u_expire, u_min_age;
2800 NTTIME nt_expire, nt_min_age;
2802 time_t u_lock_duration, u_reset_time;
2803 NTTIME nt_lock_duration, nt_reset_time;
2808 uint32 account_policy_temp;
2813 uint32 num_users=0, num_groups=0, num_aliases=0;
2815 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2817 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2819 return NT_STATUS_NO_MEMORY;
2822 *dom_info_ptr = dom_info;
2824 /* find the policy handle. open a policy on it. */
2825 if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2826 return NT_STATUS_INVALID_HANDLE;
2836 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2837 min_pass_len = account_policy_temp;
2839 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2840 pass_hist = account_policy_temp;
2842 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2843 password_properties = account_policy_temp;
2845 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2846 u_expire = account_policy_temp;
2848 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2849 u_min_age = account_policy_temp;
2855 unix_to_nt_time_abs(&nt_expire, u_expire);
2856 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2858 init_samr_DomInfo1(&dom_info->info1,
2859 (uint16)min_pass_len,
2861 password_properties,
2871 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2872 num_groups = count_sam_groups(info->disp_info);
2873 num_aliases = count_sam_aliases(info->disp_info);
2875 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2876 u_logout = account_policy_temp;
2878 unix_to_nt_time_abs(&nt_logout, u_logout);
2880 if (!pdb_get_seq_num(&seq_num))
2881 seq_num = time(NULL);
2887 server_role = ROLE_DOMAIN_PDC;
2888 if (lp_server_role() == ROLE_DOMAIN_BDC)
2889 server_role = ROLE_DOMAIN_BDC;
2891 init_samr_DomInfo2(&dom_info->info2,
2912 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2913 u_logout = (time_t)ul;
2920 unix_to_nt_time_abs(&nt_logout, u_logout);
2922 init_samr_DomInfo3(&dom_info->info3,
2927 init_samr_DomInfo4(&dom_info->info4,
2931 init_samr_DomInfo5(&dom_info->info5,
2932 get_global_sam_name());
2935 /* NT returns its own name when a PDC. win2k and later
2936 * only the name of the PDC if itself is a BDC (samba4
2938 init_samr_DomInfo6(&dom_info->info6,
2942 server_role = ROLE_DOMAIN_PDC;
2943 if (lp_server_role() == ROLE_DOMAIN_BDC)
2944 server_role = ROLE_DOMAIN_BDC;
2946 init_samr_DomInfo7(&dom_info->info7,
2955 if (!pdb_get_seq_num(&seq_num)) {
2956 seq_num = time(NULL);
2963 init_samr_DomInfo8(&dom_info->info8,
2973 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2974 u_lock_duration = account_policy_temp;
2975 if (u_lock_duration != -1) {
2976 u_lock_duration *= 60;
2979 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2980 u_reset_time = account_policy_temp * 60;
2982 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2983 lockout = account_policy_temp;
2989 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2990 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2992 init_samr_DomInfo12(&dom_info->info12,
2998 return NT_STATUS_INVALID_INFO_CLASS;
3001 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
3006 /*******************************************************************
3007 _samr_QueryDomainInfo
3008 ********************************************************************/
3010 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3011 struct samr_QueryDomainInfo *r)
3013 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
3015 r->in.domain_handle,
3020 /* W2k3 seems to use the same check for all 3 objects that can be created via
3021 * SAMR, if you try to create for example "Dialup" as an alias it says
3022 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3025 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3027 enum lsa_SidType type;
3030 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3033 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3034 * whether the name already exists */
3035 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3036 NULL, NULL, NULL, &type);
3040 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3041 return NT_STATUS_OK;
3044 DEBUG(5, ("trying to create %s, exists as %s\n",
3045 new_name, sid_type_lookup(type)));
3047 if (type == SID_NAME_DOM_GRP) {
3048 return NT_STATUS_GROUP_EXISTS;
3050 if (type == SID_NAME_ALIAS) {
3051 return NT_STATUS_ALIAS_EXISTS;
3054 /* Yes, the default is NT_STATUS_USER_EXISTS */
3055 return NT_STATUS_USER_EXISTS;
3058 /*******************************************************************
3060 ********************************************************************/
3062 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3063 struct samr_CreateUser2 *r)
3065 const char *account = NULL;
3067 POLICY_HND dom_pol = *r->in.domain_handle;
3068 uint32_t acb_info = r->in.acct_flags;
3069 POLICY_HND *user_pol = r->out.user_handle;
3070 struct samr_info *info = NULL;
3075 /* check this, when giving away 'add computer to domain' privs */
3076 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3077 bool can_add_account = False;
3079 DISP_INFO *disp_info = NULL;
3081 /* Get the domain SID stored in the domain policy */
3082 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3084 return NT_STATUS_INVALID_HANDLE;
3086 nt_status = access_check_samr_function(acc_granted,
3087 SA_RIGHT_DOMAIN_CREATE_USER,
3088 "_samr_CreateUser2");
3089 if (!NT_STATUS_IS_OK(nt_status)) {
3093 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3094 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3095 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3096 this parameter is not an account type */
3097 return NT_STATUS_INVALID_PARAMETER;
3100 account = r->in.account_name->string;
3101 if (account == NULL) {
3102 return NT_STATUS_NO_MEMORY;
3105 nt_status = can_create(p->mem_ctx, account);
3106 if (!NT_STATUS_IS_OK(nt_status)) {
3110 /* determine which user right we need to check based on the acb_info */
3112 if ( acb_info & ACB_WSTRUST )
3114 se_priv_copy( &se_rights, &se_machine_account );
3115 can_add_account = user_has_privileges(
3116 p->pipe_user.nt_user_token, &se_rights );
3118 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3119 account for domain trusts and changes the ACB flags later */
3120 else if ( acb_info & ACB_NORMAL &&
3121 (account[strlen(account)-1] != '$') )
3123 se_priv_copy( &se_rights, &se_add_users );
3124 can_add_account = user_has_privileges(
3125 p->pipe_user.nt_user_token, &se_rights );
3127 else /* implicit assumption of a BDC or domain trust account here
3128 * (we already check the flags earlier) */
3130 if ( lp_enable_privileges() ) {
3131 /* only Domain Admins can add a BDC or domain trust */
3132 se_priv_copy( &se_rights, &se_priv_none );
3133 can_add_account = nt_token_check_domain_rid(
3134 p->pipe_user.nt_user_token,
3135 DOMAIN_GROUP_RID_ADMINS );
3139 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3140 uidtoname(p->pipe_user.ut.uid),
3141 can_add_account ? "True":"False" ));
3143 /********** BEGIN Admin BLOCK **********/
3145 if ( can_add_account )
3148 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3151 if ( can_add_account )
3154 /********** END Admin BLOCK **********/
3156 /* now check for failure */
3158 if ( !NT_STATUS_IS_OK(nt_status) )
3161 /* Get the user's SID */
3163 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3165 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3166 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3167 se_map_generic(&des_access, &usr_generic_mapping);
3169 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3170 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3171 &acc_granted, "_samr_CreateUser2");
3173 if ( !NT_STATUS_IS_OK(nt_status) ) {
3177 /* associate the user's SID with the new handle. */
3178 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3179 return NT_STATUS_NO_MEMORY;
3184 info->acc_granted = acc_granted;
3186 /* get a (unique) handle. open a policy on it. */
3187 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3188 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3191 /* After a "set" ensure we have no cached display info. */
3192 force_flush_samr_cache(info->disp_info);
3194 *r->out.access_granted = acc_granted;
3196 return NT_STATUS_OK;
3199 /*******************************************************************
3201 ********************************************************************/
3203 NTSTATUS _samr_Connect(pipes_struct *p,
3204 struct samr_Connect *r)
3206 struct samr_info *info = NULL;
3207 uint32 des_access = r->in.access_mask;
3211 if (!pipe_access_check(p)) {
3212 DEBUG(3, ("access denied to _samr_Connect\n"));
3213 return NT_STATUS_ACCESS_DENIED;
3216 /* set up the SAMR connect_anon response */
3218 /* associate the user's SID with the new handle. */
3219 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3220 return NT_STATUS_NO_MEMORY;
3222 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3223 was observed from a win98 client trying to enumerate users (when configured
3224 user level access control on shares) --jerry */
3226 if (des_access == MAXIMUM_ALLOWED_ACCESS) {
3227 /* Map to max possible knowing we're filtered below. */
3228 des_access = GENERIC_ALL_ACCESS;
3231 se_map_generic( &des_access, &sam_generic_mapping );
3232 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3234 /* get a (unique) handle. open a policy on it. */
3235 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3236 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3238 return NT_STATUS_OK;
3241 /*******************************************************************
3243 ********************************************************************/
3245 NTSTATUS _samr_Connect2(pipes_struct *p,
3246 struct samr_Connect2 *r)
3248 struct samr_info *info = NULL;
3249 SEC_DESC *psd = NULL;
3251 uint32 des_access = r->in.access_mask;
3256 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3260 if (!pipe_access_check(p)) {
3261 DEBUG(3, ("access denied to _samr_Connect2\n"));
3262 return NT_STATUS_ACCESS_DENIED;
3265 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3266 se_map_generic(&des_access, &sam_generic_mapping);
3268 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3269 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3271 if ( !NT_STATUS_IS_OK(nt_status) )
3274 /* associate the user's SID and access granted with the new handle. */
3275 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3276 return NT_STATUS_NO_MEMORY;
3278 info->acc_granted = acc_granted;
3279 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3281 /* get a (unique) handle. open a policy on it. */
3282 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3283 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3285 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3290 /*******************************************************************
3292 ********************************************************************/
3294 NTSTATUS _samr_Connect4(pipes_struct *p,
3295 struct samr_Connect4 *r)
3297 struct samr_info *info = NULL;
3298 SEC_DESC *psd = NULL;
3300 uint32 des_access = r->in.access_mask;
3305 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3309 if (!pipe_access_check(p)) {
3310 DEBUG(3, ("access denied to samr_Connect4\n"));
3311 return NT_STATUS_ACCESS_DENIED;
3314 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3315 se_map_generic(&des_access, &sam_generic_mapping);
3317 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3318 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3320 if ( !NT_STATUS_IS_OK(nt_status) )
3323 /* associate the user's SID and access granted with the new handle. */
3324 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3325 return NT_STATUS_NO_MEMORY;
3327 info->acc_granted = acc_granted;
3328 info->status = r->in.access_mask; /* ??? */
3330 /* get a (unique) handle. open a policy on it. */
3331 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3332 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3334 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3336 return NT_STATUS_OK;
3339 /*******************************************************************
3341 ********************************************************************/
3343 NTSTATUS _samr_Connect5(pipes_struct *p,
3344 struct samr_Connect5 *r)
3346 struct samr_info *info = NULL;
3347 SEC_DESC *psd = NULL;
3349 uint32 des_access = r->in.access_mask;
3352 struct samr_ConnectInfo1 info1;
3354 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3358 if (!pipe_access_check(p)) {
3359 DEBUG(3, ("access denied to samr_Connect5\n"));
3360 return NT_STATUS_ACCESS_DENIED;
3363 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3364 se_map_generic(&des_access, &sam_generic_mapping);
3366 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3367 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3369 if ( !NT_STATUS_IS_OK(nt_status) )
3372 /* associate the user's SID and access granted with the new handle. */
3373 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3374 return NT_STATUS_NO_MEMORY;
3376 info->acc_granted = acc_granted;
3377 info->status = r->in.access_mask; /* ??? */
3379 /* get a (unique) handle. open a policy on it. */
3380 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3381 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3383 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3385 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3388 *r->out.level_out = 1;
3389 r->out.info_out->info1 = info1;
3391 return NT_STATUS_OK;
3394 /**********************************************************************
3396 **********************************************************************/
3398 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3399 struct samr_LookupDomain *r)
3401 NTSTATUS status = NT_STATUS_OK;
3402 struct samr_info *info;
3403 const char *domain_name;
3404 DOM_SID *sid = NULL;
3406 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3407 return NT_STATUS_INVALID_HANDLE;
3409 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3410 Reverted that change so we will work with RAS servers again */
3412 status = access_check_samr_function(info->acc_granted,
3413 SA_RIGHT_SAM_OPEN_DOMAIN,
3414 "_samr_LookupDomain");
3415 if (!NT_STATUS_IS_OK(status)) {
3419 domain_name = r->in.domain_name->string;
3421 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3423 return NT_STATUS_NO_MEMORY;
3426 if (strequal(domain_name, builtin_domain_name())) {
3427 sid_copy(sid, &global_sid_Builtin);
3429 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3430 status = NT_STATUS_NO_SUCH_DOMAIN;
3434 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3435 sid_string_dbg(sid)));
3442 /**********************************************************************
3444 **********************************************************************/
3446 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3447 struct samr_EnumDomains *r)
3450 struct samr_info *info;
3451 uint32_t num_entries = 2;
3452 struct samr_SamEntry *entry_array = NULL;
3453 struct samr_SamArray *sam;
3455 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3456 return NT_STATUS_INVALID_HANDLE;
3458 status = access_check_samr_function(info->acc_granted,
3459 SA_RIGHT_SAM_ENUM_DOMAINS,
3460 "_samr_EnumDomains");
3461 if (!NT_STATUS_IS_OK(status)) {
3465 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3467 return NT_STATUS_NO_MEMORY;
3470 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3471 struct samr_SamEntry,
3474 return NT_STATUS_NO_MEMORY;
3477 entry_array[0].idx = 0;
3478 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3480 entry_array[1].idx = 1;
3481 init_lsa_String(&entry_array[1].name, "Builtin");
3483 sam->count = num_entries;
3484 sam->entries = entry_array;
3487 *r->out.num_entries = num_entries;
3492 /*******************************************************************
3494 ********************************************************************/
3496 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3497 struct samr_OpenAlias *r)
3500 POLICY_HND domain_pol = *r->in.domain_handle;
3501 uint32 alias_rid = r->in.rid;
3502 POLICY_HND *alias_pol = r->out.alias_handle;
3503 struct samr_info *info = NULL;
3504 SEC_DESC *psd = NULL;
3506 uint32 des_access = r->in.access_mask;
3511 /* find the domain policy and get the SID / access bits stored in the domain policy */
3513 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3514 return NT_STATUS_INVALID_HANDLE;
3516 status = access_check_samr_function(acc_granted,
3517 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3520 if ( !NT_STATUS_IS_OK(status) )
3523 /* append the alias' RID to it */
3525 if (!sid_append_rid(&sid, alias_rid))
3526 return NT_STATUS_NO_SUCH_ALIAS;
3528 /*check if access can be granted as requested by client. */
3530 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3531 se_map_generic(&des_access,&ali_generic_mapping);
3533 se_priv_copy( &se_rights, &se_add_users );
3536 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3537 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3538 &acc_granted, "_samr_OpenAlias");
3540 if ( !NT_STATUS_IS_OK(status) )
3544 /* Check we actually have the requested alias */
3545 enum lsa_SidType type;
3550 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3553 if (!result || (type != SID_NAME_ALIAS)) {
3554 return NT_STATUS_NO_SUCH_ALIAS;
3557 /* make sure there is a mapping */
3559 if ( !sid_to_gid( &sid, &gid ) ) {
3560 return NT_STATUS_NO_SUCH_ALIAS;
3565 /* associate the alias SID with the new handle. */
3566 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3567 return NT_STATUS_NO_MEMORY;
3569 info->acc_granted = acc_granted;
3571 /* get a (unique) handle. open a policy on it. */
3572 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3573 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3575 return NT_STATUS_OK;
3578 /*******************************************************************
3580 ********************************************************************/
3582 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3583 struct samr_UserInfo7 *id7,
3589 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3591 return NT_STATUS_ACCESS_DENIED;
3594 if (!id7->account_name.string) {
3595 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3597 return NT_STATUS_ACCESS_DENIED;
3600 /* check to see if the new username already exists. Note: we can't
3601 reliably lock all backends, so there is potentially the
3602 possibility that a user can be created in between this check and
3603 the rename. The rename should fail, but may not get the
3604 exact same failure status code. I think this is small enough
3605 of a window for this type of operation and the results are
3606 simply that the rename fails with a slightly different status
3607 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3609 rc = can_create(mem_ctx, id7->account_name.string);
3610 if (!NT_STATUS_IS_OK(rc)) {
3614 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3620 /*******************************************************************
3622 ********************************************************************/
3624 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3628 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3633 /* FIX ME: check if the value is really changed --metze */
3634 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3639 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3649 /*******************************************************************
3651 ********************************************************************/
3653 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3657 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3662 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3666 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3670 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3675 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3684 /*******************************************************************
3686 ********************************************************************/
3688 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3692 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3696 copy_id20_to_sam_passwd(pwd, id20);
3698 /* write the change out */
3699 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3709 /*******************************************************************
3711 ********************************************************************/
3713 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3714 struct samr_UserInfo21 *id21,
3720 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3721 return NT_STATUS_INVALID_PARAMETER;
3724 /* we need to separately check for an account rename first */
3726 if (id21->account_name.string &&
3727 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3730 /* check to see if the new username already exists. Note: we can't
3731 reliably lock all backends, so there is potentially the
3732 possibility that a user can be created in between this check and
3733 the rename. The rename should fail, but may not get the
3734 exact same failure status code. I think this is small enough
3735 of a window for this type of operation and the results are
3736 simply that the rename fails with a slightly different status
3737 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3739 status = can_create(mem_ctx, id21->account_name.string);
3740 if (!NT_STATUS_IS_OK(status)) {
3744 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3746 if (!NT_STATUS_IS_OK(status)) {
3747 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3748 nt_errstr(status)));
3753 /* set the new username so that later
3754 functions can work on the new account */
3755 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3758 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3761 * The funny part about the previous two calls is
3762 * that pwd still has the password hashes from the
3763 * passdb entry. These have not been updated from
3764 * id21. I don't know if they need to be set. --jerry
3767 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3768 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3769 if ( !NT_STATUS_IS_OK(status) ) {
3774 /* Don't worry about writing out the user account since the
3775 primary group SID is generated solely from the user's Unix
3778 /* write the change out */
3779 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3786 return NT_STATUS_OK;
3789 /*******************************************************************
3791 ********************************************************************/
3793 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3794 struct samr_UserInfo23 *id23,
3797 char *plaintext_buf = NULL;
3803 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3804 return NT_STATUS_INVALID_PARAMETER;
3807 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3808 pdb_get_username(pwd)));
3810 acct_ctrl = pdb_get_acct_ctrl(pwd);
3812 if (!decode_pw_buffer(mem_ctx,
3813 id23->password.data,
3818 return NT_STATUS_INVALID_PARAMETER;
3821 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3823 return NT_STATUS_ACCESS_DENIED;
3826 copy_id23_to_sam_passwd(pwd, id23);
3828 /* if it's a trust account, don't update /etc/passwd */
3829 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3830 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3831 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3832 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3834 /* update the UNIX password */
3835 if (lp_unix_password_sync() ) {
3836 struct passwd *passwd;
3837 if (pdb_get_username(pwd) == NULL) {
3838 DEBUG(1, ("chgpasswd: User without name???\n"));
3840 return NT_STATUS_ACCESS_DENIED;
3843 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3844 if (passwd == NULL) {
3845 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3848 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3850 return NT_STATUS_ACCESS_DENIED;
3852 TALLOC_FREE(passwd);
3856 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3858 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3859 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3865 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3872 return NT_STATUS_OK;
3875 /*******************************************************************
3877 ********************************************************************/
3879 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
3882 char *plaintext_buf = NULL;
3884 time_t last_set_time;
3885 enum pdb_value_state last_set_state;
3887 DEBUG(5, ("Attempting administrator password change for user %s\n",
3888 pdb_get_username(pwd)));
3890 acct_ctrl = pdb_get_acct_ctrl(pwd);
3891 /* we need to know if it's expired, because this is an admin change, not a
3892 user change, so it's still expired when we're done */
3893 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3894 last_set_time = pdb_get_pass_last_set_time(pwd);
3896 if (!decode_pw_buffer(talloc_tos(),
3905 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3910 /* if it's a trust account, don't update /etc/passwd */
3911 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3912 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3913 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3914 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3916 /* update the UNIX password */
3917 if (lp_unix_password_sync()) {
3918 struct passwd *passwd;
3920 if (pdb_get_username(pwd) == NULL) {
3921 DEBUG(1, ("chgpasswd: User without name???\n"));
3926 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3927 if (passwd == NULL) {
3928 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3931 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3935 TALLOC_FREE(passwd);
3939 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3941 /* restore last set time as this is an admin change, not a user pw change */
3942 pdb_set_pass_last_set_time (pwd, last_set_time, last_set_state);
3944 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3946 /* update the SAMBA password */
3947 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3957 /*******************************************************************
3959 ********************************************************************/
3961 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
3962 struct samr_UserInfo25 *id25,
3968 DEBUG(5, ("set_user_info_25: NULL id25\n"));
3969 return NT_STATUS_INVALID_PARAMETER;
3972 copy_id25_to_sam_passwd(pwd, id25);
3974 /* write the change out */
3975 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3981 * We need to "pdb_update_sam_account" before the unix primary group
3982 * is set, because the idealx scripts would also change the
3983 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
3984 * the delete explicit / add explicit, which would then fail to find
3985 * the previous primaryGroupSid value.
3988 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3989 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3990 if ( !NT_STATUS_IS_OK(status) ) {
3995 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
3998 return NT_STATUS_OK;
4001 /*******************************************************************
4002 samr_SetUserInfo_internal
4003 ********************************************************************/
4005 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
4007 struct policy_handle *user_handle,
4009 union samr_UserInfo *info)
4012 struct samu *pwd = NULL;
4014 POLICY_HND *pol = user_handle;
4015 uint16_t switch_value = level;
4016 uint32_t acc_granted;
4017 uint32_t acc_required;
4019 bool has_enough_rights = False;
4021 DISP_INFO *disp_info = NULL;
4023 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4025 /* find the policy handle. open a policy on it. */
4026 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4027 return NT_STATUS_INVALID_HANDLE;
4030 /* This is tricky. A WinXP domain join sets
4031 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4032 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4033 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4034 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4035 we'll use the set from the WinXP join as the basis. */
4037 switch (switch_value) {
4042 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4045 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4046 SA_RIGHT_USER_SET_ATTRIBUTES |
4047 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4051 status = access_check_samr_function(acc_granted,
4054 if (!NT_STATUS_IS_OK(status)) {
4058 DEBUG(5, ("%s: sid:%s, level:%d\n",
4059 fn_name, sid_string_dbg(&sid), switch_value));
4062 DEBUG(5, ("%s: NULL info level\n", fn_name));
4063 return NT_STATUS_INVALID_INFO_CLASS;
4066 if (!(pwd = samu_new(NULL))) {
4067 return NT_STATUS_NO_MEMORY;
4071 ret = pdb_getsampwsid(pwd, &sid);
4076 return NT_STATUS_NO_SUCH_USER;
4079 /* deal with machine password changes differently from userinfo changes */
4080 /* check to see if we have the sufficient rights */
4082 acb_info = pdb_get_acct_ctrl(pwd);
4083 if (acb_info & ACB_WSTRUST)
4084 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4085 &se_machine_account);
4086 else if (acb_info & ACB_NORMAL)
4087 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4089 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4090 if (lp_enable_privileges()) {
4091 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4092 DOMAIN_GROUP_RID_ADMINS);
4096 DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4098 uidtoname(p->pipe_user.ut.uid),
4099 has_enough_rights ? "" : " not"));
4101 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4103 if (has_enough_rights) {
4107 /* ok! user info levels (lots: see MSDEV help), off we go... */
4109 switch (switch_value) {
4112 status = set_user_info_7(p->mem_ctx,
4117 if (!set_user_info_16(&info->info16, pwd)) {
4118 status = NT_STATUS_ACCESS_DENIED;
4123 /* Used by AS/U JRA. */
4124 if (!set_user_info_18(&info->info18, pwd)) {
4125 status = NT_STATUS_ACCESS_DENIED;
4130 if (!set_user_info_20(&info->info20, pwd)) {
4131 status = NT_STATUS_ACCESS_DENIED;
4136 status = set_user_info_21(p->mem_ctx,
4137 &info->info21, pwd);
4141 if (!p->session_key.length) {
4142 status = NT_STATUS_NO_USER_SESSION_KEY;
4144 SamOEMhashBlob(info->info23.password.data, 516,
4147 dump_data(100, info->info23.password.data, 516);
4149 status = set_user_info_23(p->mem_ctx,
4150 &info->info23, pwd);
4154 if (!p->session_key.length) {
4155 status = NT_STATUS_NO_USER_SESSION_KEY;
4157 SamOEMhashBlob(info->info24.password.data,
4161 dump_data(100, info->info24.password.data, 516);
4163 if (!set_user_info_pw(info->info24.password.data, pwd)) {
4164 status = NT_STATUS_ACCESS_DENIED;
4169 if (!p->session_key.length) {
4170 status = NT_STATUS_NO_USER_SESSION_KEY;
4172 encode_or_decode_arc4_passwd_buffer(info->info25.password.data,
4175 dump_data(100, info->info25.password.data, 532);
4177 status = set_user_info_25(p->mem_ctx,
4178 &info->info25, pwd);
4179 if (!NT_STATUS_IS_OK(status)) {
4182 if (!set_user_info_pw(info->info25.password.data, pwd)) {
4183 status = NT_STATUS_ACCESS_DENIED;
4188 if (!p->session_key.length) {
4189 status = NT_STATUS_NO_USER_SESSION_KEY;
4191 encode_or_decode_arc4_passwd_buffer(info->info26.password.data,
4194 dump_data(100, info->info26.password.data, 516);
4196 if (!set_user_info_pw(info->info26.password.data, pwd)) {
4197 status = NT_STATUS_ACCESS_DENIED;
4202 status = NT_STATUS_INVALID_INFO_CLASS;
4207 if (has_enough_rights) {
4211 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4213 if (NT_STATUS_IS_OK(status)) {
4214 force_flush_samr_cache(disp_info);
4220 /*******************************************************************
4222 ********************************************************************/
4224 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4225 struct samr_SetUserInfo *r)
4227 return samr_SetUserInfo_internal("_samr_SetUserInfo",
4234 /*******************************************************************
4236 ********************************************************************/
4238 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4239 struct samr_SetUserInfo2 *r)
4241 return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4248 /*********************************************************************
4249 _samr_GetAliasMembership
4250 *********************************************************************/
4252 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4253 struct samr_GetAliasMembership *r)
4255 size_t num_alias_rids;
4257 struct samr_info *info = NULL;
4265 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4267 /* find the policy handle. open a policy on it. */
4268 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4269 return NT_STATUS_INVALID_HANDLE;
4271 ntstatus1 = access_check_samr_function(info->acc_granted,
4272 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4273 "_samr_GetAliasMembership");
4274 ntstatus2 = access_check_samr_function(info->acc_granted,
4275 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4276 "_samr_GetAliasMembership");
4278 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4279 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4280 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4281 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4285 if (!sid_check_is_domain(&info->sid) &&
4286 !sid_check_is_builtin(&info->sid))
4287 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4289 if (r->in.sids->num_sids) {
4290 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4292 if (members == NULL)
4293 return NT_STATUS_NO_MEMORY;
4298 for (i=0; i<r->in.sids->num_sids; i++)
4299 sid_copy(&members[i], r->in.sids->sids[i].sid);
4305 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4306 r->in.sids->num_sids,
4307 &alias_rids, &num_alias_rids);
4310 if (!NT_STATUS_IS_OK(ntstatus1)) {
4314 r->out.rids->count = num_alias_rids;
4315 r->out.rids->ids = alias_rids;
4317 return NT_STATUS_OK;
4320 /*********************************************************************
4321 _samr_GetMembersInAlias
4322 *********************************************************************/
4324 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4325 struct samr_GetMembersInAlias *r)
4329 size_t num_sids = 0;
4330 struct lsa_SidPtr *sids = NULL;
4331 DOM_SID *pdb_sids = NULL;
4337 /* find the policy handle. open a policy on it. */
4338 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4339 return NT_STATUS_INVALID_HANDLE;
4341 status = access_check_samr_function(acc_granted,
4342 SA_RIGHT_ALIAS_GET_MEMBERS,
4343 "_samr_GetMembersInAlias");
4344 if (!NT_STATUS_IS_OK(status)) {
4348 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4351 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4354 if (!NT_STATUS_IS_OK(status)) {
4359 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4361 TALLOC_FREE(pdb_sids);
4362 return NT_STATUS_NO_MEMORY;
4366 for (i = 0; i < num_sids; i++) {
4367 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4369 TALLOC_FREE(pdb_sids);
4370 return NT_STATUS_NO_MEMORY;
4374 r->out.sids->num_sids = num_sids;
4375 r->out.sids->sids = sids;
4377 TALLOC_FREE(pdb_sids);
4379 return NT_STATUS_OK;
4382 /*********************************************************************
4383 _samr_QueryGroupMember
4384 *********************************************************************/
4386 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4387 struct samr_QueryGroupMember *r)
4390 size_t i, num_members;
4398 struct samr_RidTypeArray *rids = NULL;
4400 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4402 return NT_STATUS_NO_MEMORY;
4405 /* find the policy handle. open a policy on it. */
4406 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4407 return NT_STATUS_INVALID_HANDLE;
4409 status = access_check_samr_function(acc_granted,
4410 SA_RIGHT_GROUP_GET_MEMBERS,
4411 "_samr_QueryGroupMember");
4412 if (!NT_STATUS_IS_OK(status)) {
4416 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4418 if (!sid_check_is_in_our_domain(&group_sid)) {
4419 DEBUG(3, ("sid %s is not in our domain\n",
4420 sid_string_dbg(&group_sid)));
4421 return NT_STATUS_NO_SUCH_GROUP;
4424 DEBUG(10, ("lookup on Domain SID\n"));
4427 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4428 &rid, &num_members);
4431 if (!NT_STATUS_IS_OK(status))
4435 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4437 return NT_STATUS_NO_MEMORY;
4443 for (i=0; i<num_members; i++)
4444 attr[i] = SID_NAME_USER;
4446 rids->count = num_members;
4450 *r->out.rids = rids;
4452 return NT_STATUS_OK;
4455 /*********************************************************************
4456 _samr_AddAliasMember
4457 *********************************************************************/
4459 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4460 struct samr_AddAliasMember *r)
4465 bool can_add_accounts;
4467 DISP_INFO *disp_info = NULL;
4469 /* Find the policy handle. Open a policy on it. */
4470 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4471 return NT_STATUS_INVALID_HANDLE;
4473 status = access_check_samr_function(acc_granted,
4474 SA_RIGHT_ALIAS_ADD_MEMBER,
4475 "_samr_AddAliasMember");
4476 if (!NT_STATUS_IS_OK(status)) {
4480 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4482 se_priv_copy( &se_rights, &se_add_users );
4483 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4485 /******** BEGIN SeAddUsers BLOCK *********/
4487 if ( can_add_accounts )
4490 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4492 if ( can_add_accounts )
4495 /******** END SeAddUsers BLOCK *********/
4497 if (NT_STATUS_IS_OK(status)) {
4498 force_flush_samr_cache(disp_info);
4504 /*********************************************************************
4505 _samr_DeleteAliasMember
4506 *********************************************************************/
4508 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4509 struct samr_DeleteAliasMember *r)
4514 bool can_add_accounts;
4516 DISP_INFO *disp_info = NULL;
4518 /* Find the policy handle. Open a policy on it. */
4519 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4520 return NT_STATUS_INVALID_HANDLE;
4522 status = access_check_samr_function(acc_granted,
4523 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4524 "_samr_DeleteAliasMember");
4525 if (!NT_STATUS_IS_OK(status)) {
4529 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4530 sid_string_dbg(&alias_sid)));
4532 se_priv_copy( &se_rights, &se_add_users );
4533 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4535 /******** BEGIN SeAddUsers BLOCK *********/
4537 if ( can_add_accounts )
4540 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4542 if ( can_add_accounts )
4545 /******** END SeAddUsers BLOCK *********/
4547 if (NT_STATUS_IS_OK(status)) {
4548 force_flush_samr_cache(disp_info);
4554 /*********************************************************************
4555 _samr_AddGroupMember
4556 *********************************************************************/
4558 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4559 struct samr_AddGroupMember *r)
4566 bool can_add_accounts;
4567 DISP_INFO *disp_info = NULL;
4569 /* Find the policy handle. Open a policy on it. */
4570 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4571 return NT_STATUS_INVALID_HANDLE;
4573 status = access_check_samr_function(acc_granted,
4574 SA_RIGHT_GROUP_ADD_MEMBER,
4575 "_samr_AddGroupMember");
4576 if (!NT_STATUS_IS_OK(status)) {
4580 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4582 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4584 return NT_STATUS_INVALID_HANDLE;
4587 se_priv_copy( &se_rights, &se_add_users );
4588 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4590 /******** BEGIN SeAddUsers BLOCK *********/
4592 if ( can_add_accounts )
4595 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4597 if ( can_add_accounts )
4600 /******** END SeAddUsers BLOCK *********/
4602 force_flush_samr_cache(disp_info);
4607 /*********************************************************************
4608 _samr_DeleteGroupMember
4609 *********************************************************************/
4611 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4612 struct samr_DeleteGroupMember *r)
4620 bool can_add_accounts;
4621 DISP_INFO *disp_info = NULL;
4624 * delete the group member named r->in.rid
4625 * who is a member of the sid associated with the handle
4626 * the rid is a user's rid as the group is a domain group.
4629 /* Find the policy handle. Open a policy on it. */
4630 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4631 return NT_STATUS_INVALID_HANDLE;
4633 status = access_check_samr_function(acc_granted,
4634 SA_RIGHT_GROUP_REMOVE_MEMBER,
4635 "_samr_DeleteGroupMember");
4636 if (!NT_STATUS_IS_OK(status)) {
4640 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4642 return NT_STATUS_INVALID_HANDLE;
4645 se_priv_copy( &se_rights, &se_add_users );
4646 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4648 /******** BEGIN SeAddUsers BLOCK *********/
4650 if ( can_add_accounts )
4653 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4655 if ( can_add_accounts )
4658 /******** END SeAddUsers BLOCK *********/
4660 force_flush_samr_cache(disp_info);
4665 /*********************************************************************
4667 *********************************************************************/
4669 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4670 struct samr_DeleteUser *r)
4674 struct samu *sam_pass=NULL;
4676 bool can_add_accounts;
4678 DISP_INFO *disp_info = NULL;
4681 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4683 /* Find the policy handle. Open a policy on it. */
4684 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4685 return NT_STATUS_INVALID_HANDLE;
4687 status = access_check_samr_function(acc_granted,
4688 STD_RIGHT_DELETE_ACCESS,
4689 "_samr_DeleteUser");
4690 if (!NT_STATUS_IS_OK(status)) {
4694 if (!sid_check_is_in_our_domain(&user_sid))
4695 return NT_STATUS_CANNOT_DELETE;
4697 /* check if the user exists before trying to delete */
4698 if ( !(sam_pass = samu_new( NULL )) ) {
4699 return NT_STATUS_NO_MEMORY;
4703 ret = pdb_getsampwsid(sam_pass, &user_sid);
4707 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4708 sid_string_dbg(&user_sid)));
4709 TALLOC_FREE(sam_pass);
4710 return NT_STATUS_NO_SUCH_USER;
4713 acb_info = pdb_get_acct_ctrl(sam_pass);
4715 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4716 if ( acb_info & ACB_WSTRUST ) {
4717 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4719 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4722 /******** BEGIN SeAddUsers BLOCK *********/
4724 if ( can_add_accounts )
4727 status = pdb_delete_user(p->mem_ctx, sam_pass);
4729 if ( can_add_accounts )
4732 /******** END SeAddUsers BLOCK *********/
4734 if ( !NT_STATUS_IS_OK(status) ) {
4735 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4736 "user %s: %s.\n", pdb_get_username(sam_pass),
4737 nt_errstr(status)));
4738 TALLOC_FREE(sam_pass);
4743 TALLOC_FREE(sam_pass);
4745 if (!close_policy_hnd(p, r->in.user_handle))
4746 return NT_STATUS_OBJECT_NAME_INVALID;
4748 force_flush_samr_cache(disp_info);
4750 return NT_STATUS_OK;
4753 /*********************************************************************
4754 _samr_DeleteDomainGroup
4755 *********************************************************************/
4757 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4758 struct samr_DeleteDomainGroup *r)
4765 bool can_add_accounts;
4766 DISP_INFO *disp_info = NULL;
4768 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4770 /* Find the policy handle. Open a policy on it. */
4771 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4772 return NT_STATUS_INVALID_HANDLE;
4774 status = access_check_samr_function(acc_granted,
4775 STD_RIGHT_DELETE_ACCESS,
4776 "_samr_DeleteDomainGroup");
4777 if (!NT_STATUS_IS_OK(status)) {
4781 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4783 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4785 return NT_STATUS_NO_SUCH_GROUP;
4788 se_priv_copy( &se_rights, &se_add_users );
4789 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4791 /******** BEGIN SeAddUsers BLOCK *********/
4793 if ( can_add_accounts )
4796 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4798 if ( can_add_accounts )
4801 /******** END SeAddUsers BLOCK *********/
4803 if ( !NT_STATUS_IS_OK(status) ) {
4804 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4805 "entry for group %s: %s\n",
4806 sid_string_dbg(&group_sid),
4807 nt_errstr(status)));
4811 if (!close_policy_hnd(p, r->in.group_handle))
4812 return NT_STATUS_OBJECT_NAME_INVALID;
4814 force_flush_samr_cache(disp_info);
4816 return NT_STATUS_OK;
4819 /*********************************************************************
4820 _samr_DeleteDomAlias
4821 *********************************************************************/
4823 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4824 struct samr_DeleteDomAlias *r)
4829 bool can_add_accounts;
4831 DISP_INFO *disp_info = NULL;
4833 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4835 /* Find the policy handle. Open a policy on it. */
4836 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4837 return NT_STATUS_INVALID_HANDLE;
4839 /* copy the handle to the outgoing reply */
4841 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4843 status = access_check_samr_function(acc_granted,
4844 STD_RIGHT_DELETE_ACCESS,
4845 "_samr_DeleteDomAlias");
4846 if (!NT_STATUS_IS_OK(status)) {
4850 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4852 /* Don't let Windows delete builtin groups */
4854 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4855 return NT_STATUS_SPECIAL_ACCOUNT;
4858 if (!sid_check_is_in_our_domain(&alias_sid))
4859 return NT_STATUS_NO_SUCH_ALIAS;
4861 DEBUG(10, ("lookup on Local SID\n"));
4863 se_priv_copy( &se_rights, &se_add_users );
4864 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4866 /******** BEGIN SeAddUsers BLOCK *********/
4868 if ( can_add_accounts )
4871 /* Have passdb delete the alias */
4872 status = pdb_delete_alias(&alias_sid);
4874 if ( can_add_accounts )
4877 /******** END SeAddUsers BLOCK *********/
4879 if ( !NT_STATUS_IS_OK(status))
4882 if (!close_policy_hnd(p, r->in.alias_handle))
4883 return NT_STATUS_OBJECT_NAME_INVALID;
4885 force_flush_samr_cache(disp_info);
4887 return NT_STATUS_OK;
4890 /*********************************************************************
4891 _samr_CreateDomainGroup
4892 *********************************************************************/
4894 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4895 struct samr_CreateDomainGroup *r)
4902 struct samr_info *info;
4905 bool can_add_accounts;
4906 DISP_INFO *disp_info = NULL;
4908 /* Find the policy handle. Open a policy on it. */
4909 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4910 return NT_STATUS_INVALID_HANDLE;
4912 status = access_check_samr_function(acc_granted,
4913 SA_RIGHT_DOMAIN_CREATE_GROUP,
4914 "_samr_CreateDomainGroup");
4915 if (!NT_STATUS_IS_OK(status)) {
4919 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4920 return NT_STATUS_ACCESS_DENIED;
4922 name = r->in.name->string;
4924 return NT_STATUS_NO_MEMORY;
4927 status = can_create(p->mem_ctx, name);
4928 if (!NT_STATUS_IS_OK(status)) {
4932 se_priv_copy( &se_rights, &se_add_users );
4933 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4935 /******** BEGIN SeAddUsers BLOCK *********/
4937 if ( can_add_accounts )
4940 /* check that we successfully create the UNIX group */
4942 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
4944 if ( can_add_accounts )
4947 /******** END SeAddUsers BLOCK *********/
4949 /* check if we should bail out here */
4951 if ( !NT_STATUS_IS_OK(status) )
4954 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
4956 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4957 return NT_STATUS_NO_MEMORY;
4959 /* they created it; let the user do what he wants with it */
4961 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
4963 /* get a (unique) handle. open a policy on it. */
4964 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
4965 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4967 force_flush_samr_cache(disp_info);
4969 return NT_STATUS_OK;
4972 /*********************************************************************
4973 _samr_CreateDomAlias
4974 *********************************************************************/
4976 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
4977 struct samr_CreateDomAlias *r)
4981 const char *name = NULL;
4982 struct samr_info *info;
4987 bool can_add_accounts;
4988 DISP_INFO *disp_info = NULL;
4990 /* Find the policy handle. Open a policy on it. */
4991 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4992 return NT_STATUS_INVALID_HANDLE;
4994 result = access_check_samr_function(acc_granted,
4995 SA_RIGHT_DOMAIN_CREATE_ALIAS,
4996 "_samr_CreateDomAlias");
4997 if (!NT_STATUS_IS_OK(result)) {
5001 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5002 return NT_STATUS_ACCESS_DENIED;
5004 name = r->in.alias_name->string;
5006 se_priv_copy( &se_rights, &se_add_users );
5007 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5009 result = can_create(p->mem_ctx, name);
5010 if (!NT_STATUS_IS_OK(result)) {
5014 /******** BEGIN SeAddUsers BLOCK *********/
5016 if ( can_add_accounts )
5019 /* Have passdb create the alias */
5020 result = pdb_create_alias(name, r->out.rid);
5022 if ( can_add_accounts )
5025 /******** END SeAddUsers BLOCK *********/
5027 if (!NT_STATUS_IS_OK(result)) {
5028 DEBUG(10, ("pdb_create_alias failed: %s\n",
5029 nt_errstr(result)));
5033 sid_copy(&info_sid, get_global_sam_sid());
5034 sid_append_rid(&info_sid, *r->out.rid);
5036 if (!sid_to_gid(&info_sid, &gid)) {
5037 DEBUG(10, ("Could not find alias just created\n"));
5038 return NT_STATUS_ACCESS_DENIED;
5041 /* check if the group has been successfully created */
5042 if ( getgrgid(gid) == NULL ) {
5043 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5045 return NT_STATUS_ACCESS_DENIED;
5048 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5049 return NT_STATUS_NO_MEMORY;
5051 /* they created it; let the user do what he wants with it */
5053 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5055 /* get a (unique) handle. open a policy on it. */
5056 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5057 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5059 force_flush_samr_cache(disp_info);
5061 return NT_STATUS_OK;
5064 /*********************************************************************
5065 _samr_QueryGroupInfo
5066 *********************************************************************/
5068 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5069 struct samr_QueryGroupInfo *r)
5074 union samr_GroupInfo *info = NULL;
5077 uint32_t attributes = SE_GROUP_MANDATORY |
5078 SE_GROUP_ENABLED_BY_DEFAULT |
5080 const char *group_name = NULL;
5081 const char *group_description = NULL;
5083 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5084 return NT_STATUS_INVALID_HANDLE;
5086 status = access_check_samr_function(acc_granted,
5087 SA_RIGHT_GROUP_LOOKUP_INFO,
5088 "_samr_QueryGroupInfo");
5089 if (!NT_STATUS_IS_OK(status)) {
5094 ret = get_domain_group_from_sid(group_sid, &map);
5097 return NT_STATUS_INVALID_HANDLE;
5099 /* FIXME: map contains fstrings */
5100 group_name = talloc_strdup(r, map.nt_name);
5101 group_description = talloc_strdup(r, map.comment);
5103 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5105 return NT_STATUS_NO_MEMORY;
5108 switch (r->in.level) {
5114 status = pdb_enum_group_members(
5115 p->mem_ctx, &group_sid, &members, &num_members);
5118 if (!NT_STATUS_IS_OK(status)) {
5122 init_samr_group_info1(&info->all,
5130 init_samr_group_info2(&info->name,
5134 init_samr_group_info3(&info->attributes,
5138 init_samr_group_info4(&info->description,
5149 status = pdb_enum_group_members(
5150 p->mem_ctx, &group_sid, &members, &num_members);
5153 if (!NT_STATUS_IS_OK(status)) {
5157 init_samr_group_info5(&info->all2,
5160 0, /* num_members - in w2k3 this is always 0 */
5166 return NT_STATUS_INVALID_INFO_CLASS;
5169 *r->out.info = info;
5171 return NT_STATUS_OK;
5174 /*********************************************************************
5176 *********************************************************************/
5178 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5179 struct samr_SetGroupInfo *r)
5186 bool can_mod_accounts;
5187 DISP_INFO *disp_info = NULL;
5189 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5190 return NT_STATUS_INVALID_HANDLE;
5192 status = access_check_samr_function(acc_granted,
5193 SA_RIGHT_GROUP_SET_INFO,
5194 "_samr_SetGroupInfo");
5195 if (!NT_STATUS_IS_OK(status)) {
5200 ret = get_domain_group_from_sid(group_sid, &map);
5203 return NT_STATUS_NO_SUCH_GROUP;
5205 switch (r->in.level) {
5207 fstrcpy(map.comment, r->in.info->all.description.string);
5210 fstrcpy(map.comment, r->in.info->description.string);
5213 return NT_STATUS_INVALID_INFO_CLASS;
5216 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5218 /******** BEGIN SeAddUsers BLOCK *********/
5220 if ( can_mod_accounts )
5223 status = pdb_update_group_mapping_entry(&map);
5225 if ( can_mod_accounts )
5228 /******** End SeAddUsers BLOCK *********/
5230 if (NT_STATUS_IS_OK(status)) {
5231 force_flush_samr_cache(disp_info);
5237 /*********************************************************************
5239 *********************************************************************/
5241 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5242 struct samr_SetAliasInfo *r)
5245 struct acct_info info;
5247 bool can_mod_accounts;
5249 DISP_INFO *disp_info = NULL;
5251 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5252 return NT_STATUS_INVALID_HANDLE;
5254 status = access_check_samr_function(acc_granted,
5255 SA_RIGHT_ALIAS_SET_INFO,
5256 "_samr_SetAliasInfo");
5257 if (!NT_STATUS_IS_OK(status)) {
5261 /* get the current group information */
5264 status = pdb_get_aliasinfo( &group_sid, &info );
5267 if ( !NT_STATUS_IS_OK(status))
5270 switch (r->in.level) {
5275 /* We currently do not support renaming groups in the
5276 the BUILTIN domain. Refer to util_builtin.c to understand
5277 why. The eventually needs to be fixed to be like Windows
5278 where you can rename builtin groups, just not delete them */
5280 if ( sid_check_is_in_builtin( &group_sid ) ) {
5281 return NT_STATUS_SPECIAL_ACCOUNT;
5284 /* There has to be a valid name (and it has to be different) */
5286 if ( !r->in.info->name.string )
5287 return NT_STATUS_INVALID_PARAMETER;
5289 /* If the name is the same just reply "ok". Yes this
5290 doesn't allow you to change the case of a group name. */
5292 if ( strequal( r->in.info->name.string, info.acct_name ) )
5293 return NT_STATUS_OK;
5295 fstrcpy( info.acct_name, r->in.info->name.string);
5297 /* make sure the name doesn't already exist as a user
5300 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5301 status = can_create( p->mem_ctx, group_name );
5302 if ( !NT_STATUS_IS_OK( status ) )
5306 case ALIASINFODESCRIPTION:
5307 if (r->in.info->description.string) {
5308 fstrcpy(info.acct_desc,
5309 r->in.info->description.string);
5311 fstrcpy( info.acct_desc, "" );
5315 return NT_STATUS_INVALID_INFO_CLASS;
5318 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5320 /******** BEGIN SeAddUsers BLOCK *********/
5322 if ( can_mod_accounts )
5325 status = pdb_set_aliasinfo( &group_sid, &info );
5327 if ( can_mod_accounts )
5330 /******** End SeAddUsers BLOCK *********/
5332 if (NT_STATUS_IS_OK(status))
5333 force_flush_samr_cache(disp_info);
5338 /****************************************************************
5340 ****************************************************************/
5342 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5343 struct samr_GetDomPwInfo *r)
5345 /* Perform access check. Since this rpc does not require a
5346 policy handle it will not be caught by the access checks on
5347 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5349 if (!pipe_access_check(p)) {
5350 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5351 return NT_STATUS_ACCESS_DENIED;
5354 /* Actually, returning zeros here works quite well :-). */
5355 ZERO_STRUCTP(r->out.info);
5357 return NT_STATUS_OK;
5360 /*********************************************************************
5362 *********************************************************************/
5364 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5365 struct samr_OpenGroup *r)
5371 struct samr_info *info;
5372 SEC_DESC *psd = NULL;
5374 uint32 des_access = r->in.access_mask;
5381 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5382 return NT_STATUS_INVALID_HANDLE;
5384 status = access_check_samr_function(acc_granted,
5385 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5388 if ( !NT_STATUS_IS_OK(status) )
5391 /*check if access can be granted as requested by client. */
5392 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5393 se_map_generic(&des_access,&grp_generic_mapping);
5395 se_priv_copy( &se_rights, &se_add_users );
5397 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5398 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5399 &acc_granted, "_samr_OpenGroup");
5401 if ( !NT_STATUS_IS_OK(status) )
5404 /* this should not be hard-coded like this */
5406 if (!sid_equal(&sid, get_global_sam_sid()))
5407 return NT_STATUS_ACCESS_DENIED;
5409 sid_copy(&info_sid, get_global_sam_sid());
5410 sid_append_rid(&info_sid, r->in.rid);
5411 sid_to_fstring(sid_string, &info_sid);
5413 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5414 return NT_STATUS_NO_MEMORY;
5416 info->acc_granted = acc_granted;
5418 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5420 /* check if that group really exists */
5422 ret = get_domain_group_from_sid(info->sid, &map);
5425 return NT_STATUS_NO_SUCH_GROUP;
5427 /* get a (unique) handle. open a policy on it. */
5428 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5429 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5431 return NT_STATUS_OK;
5434 /*********************************************************************
5435 _samr_RemoveMemberFromForeignDomain
5436 *********************************************************************/
5438 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5439 struct samr_RemoveMemberFromForeignDomain *r)
5441 DOM_SID delete_sid, domain_sid;
5444 DISP_INFO *disp_info = NULL;
5446 sid_copy( &delete_sid, r->in.sid );
5448 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5449 sid_string_dbg(&delete_sid)));
5451 /* Find the policy handle. Open a policy on it. */
5453 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5454 &acc_granted, &disp_info))
5455 return NT_STATUS_INVALID_HANDLE;
5457 result = access_check_samr_function(acc_granted,
5458 STD_RIGHT_DELETE_ACCESS,
5459 "_samr_RemoveMemberFromForeignDomain");
5461 if (!NT_STATUS_IS_OK(result))
5464 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5465 sid_string_dbg(&domain_sid)));
5467 /* we can only delete a user from a group since we don't have
5468 nested groups anyways. So in the latter case, just say OK */
5470 /* TODO: The above comment nowadays is bogus. Since we have nested
5471 * groups now, and aliases members are never reported out of the unix
5472 * group membership, the "just say OK" makes this call a no-op. For
5473 * us. This needs fixing however. */
5475 /* I've only ever seen this in the wild when deleting a user from
5476 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5477 * is the user about to be deleted. I very much suspect this is the
5478 * only application of this call. To verify this, let people report
5481 if (!sid_check_is_builtin(&domain_sid)) {
5482 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5483 "global_sam_sid() = %s\n",
5484 sid_string_dbg(&domain_sid),
5485 sid_string_dbg(get_global_sam_sid())));
5486 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5487 return NT_STATUS_OK;
5490 force_flush_samr_cache(disp_info);
5492 result = NT_STATUS_OK;
5497 /*******************************************************************
5498 _samr_QueryDomainInfo2
5499 ********************************************************************/
5501 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5502 struct samr_QueryDomainInfo2 *r)
5504 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5506 r->in.domain_handle,
5511 /*******************************************************************
5513 ********************************************************************/
5515 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5516 struct samr_SetDomainInfo *r)
5518 time_t u_expire, u_min_age;
5520 time_t u_lock_duration, u_reset_time;
5522 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5524 /* find the policy handle. open a policy on it. */
5525 if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5526 return NT_STATUS_INVALID_HANDLE;
5528 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5530 switch (r->in.level) {
5532 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5533 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5534 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5535 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5536 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5537 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5538 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5543 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5544 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5553 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5554 if (u_lock_duration != -1)
5555 u_lock_duration /= 60;
5557 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5559 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5560 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5561 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5564 return NT_STATUS_INVALID_INFO_CLASS;
5567 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5569 return NT_STATUS_OK;
5572 /****************************************************************
5573 ****************************************************************/
5575 NTSTATUS _samr_Shutdown(pipes_struct *p,
5576 struct samr_Shutdown *r)
5578 p->rng_fault_state = true;
5579 return NT_STATUS_NOT_IMPLEMENTED;
5582 /****************************************************************
5583 ****************************************************************/
5585 NTSTATUS _samr_CreateUser(pipes_struct *p,
5586 struct samr_CreateUser *r)
5588 p->rng_fault_state = true;
5589 return NT_STATUS_NOT_IMPLEMENTED;
5592 /****************************************************************
5593 ****************************************************************/
5595 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5596 struct samr_SetMemberAttributesOfGroup *r)
5598 p->rng_fault_state = true;
5599 return NT_STATUS_NOT_IMPLEMENTED;
5602 /****************************************************************
5603 ****************************************************************/
5605 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5606 struct samr_ChangePasswordUser *r)
5608 p->rng_fault_state = true;
5609 return NT_STATUS_NOT_IMPLEMENTED;
5612 /****************************************************************
5613 ****************************************************************/
5615 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5616 struct samr_GetDisplayEnumerationIndex *r)
5618 p->rng_fault_state = true;
5619 return NT_STATUS_NOT_IMPLEMENTED;
5622 /****************************************************************
5623 ****************************************************************/
5625 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5626 struct samr_TestPrivateFunctionsDomain *r)
5628 p->rng_fault_state = true;
5629 return NT_STATUS_NOT_IMPLEMENTED;
5632 /****************************************************************
5633 ****************************************************************/
5635 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5636 struct samr_TestPrivateFunctionsUser *r)
5638 p->rng_fault_state = true;
5639 return NT_STATUS_NOT_IMPLEMENTED;
5642 /****************************************************************
5643 ****************************************************************/
5645 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5646 struct samr_QueryUserInfo2 *r)
5648 p->rng_fault_state = true;
5649 return NT_STATUS_NOT_IMPLEMENTED;
5652 /****************************************************************
5653 ****************************************************************/
5655 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5656 struct samr_GetDisplayEnumerationIndex2 *r)
5658 p->rng_fault_state = true;
5659 return NT_STATUS_NOT_IMPLEMENTED;
5662 /****************************************************************
5663 ****************************************************************/
5665 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5666 struct samr_AddMultipleMembersToAlias *r)
5668 p->rng_fault_state = true;
5669 return NT_STATUS_NOT_IMPLEMENTED;
5672 /****************************************************************
5673 ****************************************************************/
5675 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5676 struct samr_RemoveMultipleMembersFromAlias *r)
5678 p->rng_fault_state = true;
5679 return NT_STATUS_NOT_IMPLEMENTED;
5682 /****************************************************************
5683 ****************************************************************/
5685 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5686 struct samr_OemChangePasswordUser2 *r)
5688 p->rng_fault_state = true;
5689 return NT_STATUS_NOT_IMPLEMENTED;
5692 /****************************************************************
5693 ****************************************************************/
5695 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5696 struct samr_SetBootKeyInformation *r)
5698 p->rng_fault_state = true;
5699 return NT_STATUS_NOT_IMPLEMENTED;
5702 /****************************************************************
5703 ****************************************************************/
5705 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5706 struct samr_GetBootKeyInformation *r)
5708 p->rng_fault_state = true;
5709 return NT_STATUS_NOT_IMPLEMENTED;
5712 /****************************************************************
5713 ****************************************************************/
5715 NTSTATUS _samr_Connect3(pipes_struct *p,
5716 struct samr_Connect3 *r)
5718 p->rng_fault_state = true;
5719 return NT_STATUS_NOT_IMPLEMENTED;
5722 /****************************************************************
5723 ****************************************************************/
5725 NTSTATUS _samr_RidToSid(pipes_struct *p,
5726 struct samr_RidToSid *r)
5728 p->rng_fault_state = true;
5729 return NT_STATUS_NOT_IMPLEMENTED;
5732 /****************************************************************
5733 ****************************************************************/
5735 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5736 struct samr_SetDsrmPassword *r)
5738 p->rng_fault_state = true;
5739 return NT_STATUS_NOT_IMPLEMENTED;
5742 /****************************************************************
5743 ****************************************************************/
5745 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5746 struct samr_ValidatePassword *r)
5748 p->rng_fault_state = true;
5749 return NT_STATUS_NOT_IMPLEMENTED;