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.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SA_RIGHT_USER_CHANGE_PASSWORD | \
42 SA_RIGHT_USER_SET_LOC_COM )
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 typedef struct disp_info {
49 DOM_SID sid; /* identify which domain this is. */
50 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
51 struct pdb_search *users; /* querydispinfo 1 and 4 */
52 struct pdb_search *machines; /* querydispinfo 2 */
53 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
54 struct pdb_search *aliases; /* enumaliases */
57 struct pdb_search *enum_users; /* enumusers with a mask */
59 struct timed_event *cache_timeout_event; /* cache idle timeout
63 /* We keep a static list of these by SID as modern clients close down
64 all resources between each request in a complete enumeration. */
67 /* for use by the \PIPE\samr policy */
69 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
70 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
76 static const struct generic_mapping sam_generic_mapping = {
77 GENERIC_RIGHTS_SAM_READ,
78 GENERIC_RIGHTS_SAM_WRITE,
79 GENERIC_RIGHTS_SAM_EXECUTE,
80 GENERIC_RIGHTS_SAM_ALL_ACCESS};
81 static const struct generic_mapping dom_generic_mapping = {
82 GENERIC_RIGHTS_DOMAIN_READ,
83 GENERIC_RIGHTS_DOMAIN_WRITE,
84 GENERIC_RIGHTS_DOMAIN_EXECUTE,
85 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
86 static const struct generic_mapping usr_generic_mapping = {
87 GENERIC_RIGHTS_USER_READ,
88 GENERIC_RIGHTS_USER_WRITE,
89 GENERIC_RIGHTS_USER_EXECUTE,
90 GENERIC_RIGHTS_USER_ALL_ACCESS};
91 static const struct generic_mapping usr_nopwchange_generic_mapping = {
92 GENERIC_RIGHTS_USER_READ,
93 GENERIC_RIGHTS_USER_WRITE,
94 GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
95 GENERIC_RIGHTS_USER_ALL_ACCESS};
96 static const struct generic_mapping grp_generic_mapping = {
97 GENERIC_RIGHTS_GROUP_READ,
98 GENERIC_RIGHTS_GROUP_WRITE,
99 GENERIC_RIGHTS_GROUP_EXECUTE,
100 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
101 static const struct generic_mapping ali_generic_mapping = {
102 GENERIC_RIGHTS_ALIAS_READ,
103 GENERIC_RIGHTS_ALIAS_WRITE,
104 GENERIC_RIGHTS_ALIAS_EXECUTE,
105 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
107 /*******************************************************************
108 *******************************************************************/
110 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
111 const struct generic_mapping *map,
112 DOM_SID *sid, uint32 sid_access )
114 DOM_SID domadmin_sid;
115 SEC_ACE ace[5]; /* at most 5 entries */
121 /* basic access for Everyone */
123 init_sec_access(&mask, map->generic_execute | map->generic_read );
124 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
126 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
128 init_sec_access(&mask, map->generic_all);
130 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
131 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
133 /* Add Full Access for Domain Admins if we are a DC */
136 sid_copy( &domadmin_sid, get_global_sam_sid() );
137 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
138 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
141 /* if we have a sid, give it some special access */
144 init_sec_access( &mask, sid_access );
145 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
148 /* create the security descriptor */
150 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
151 return NT_STATUS_NO_MEMORY;
153 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
154 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
155 psa, sd_size)) == NULL)
156 return NT_STATUS_NO_MEMORY;
161 /*******************************************************************
162 Checks if access to an object should be granted, and returns that
163 level of access for further checks.
164 ********************************************************************/
166 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
167 SE_PRIV *rights, uint32 rights_mask,
168 uint32 des_access, uint32 *acc_granted,
171 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
172 uint32 saved_mask = 0;
174 /* check privileges; certain SAM access bits should be overridden
175 by privileges (mostly having to do with creating/modifying/deleting
178 if ( rights && user_has_any_privilege( token, rights ) ) {
180 saved_mask = (des_access & rights_mask);
181 des_access &= ~saved_mask;
183 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
188 /* check the security descriptor first */
190 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
193 /* give root a free pass */
195 if ( geteuid() == sec_initial_uid() ) {
197 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
198 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
200 *acc_granted = des_access;
202 status = NT_STATUS_OK;
208 /* add in any bits saved during the privilege check (only
209 matters is status is ok) */
211 *acc_granted |= rights_mask;
213 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
214 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
215 des_access, *acc_granted));
220 /*******************************************************************
221 Checks if access to a function can be granted
222 ********************************************************************/
224 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
226 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
227 debug, acc_granted, acc_required));
229 /* check the security descriptor first */
231 if ( (acc_granted&acc_required) == acc_required )
234 /* give root a free pass */
236 if (geteuid() == sec_initial_uid()) {
238 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
239 debug, acc_granted, acc_required));
240 DEBUGADD(4,("but overwritten by euid == 0\n"));
245 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
246 debug, acc_granted, acc_required));
248 return NT_STATUS_ACCESS_DENIED;
251 /*******************************************************************
252 Fetch or create a dispinfo struct.
253 ********************************************************************/
255 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
258 * We do a static cache for DISP_INFO's here. Explanation can be found
259 * in Jeremy's checkin message to r11793:
261 * Fix the SAMR cache so it works across completely insane
262 * client behaviour (ie.:
263 * open pipe/open SAMR handle/enumerate 0 - 1024
264 * close SAMR handle, close pipe.
265 * open pipe/open SAMR handle/enumerate 1024 - 2048...
266 * close SAMR handle, close pipe.
267 * And on ad-nausium. Amazing.... probably object-oriented
268 * client side programming in action yet again.
269 * This change should *massively* improve performance when
270 * enumerating users from an LDAP database.
273 * "Our" and the builtin domain are the only ones where we ever
274 * enumerate stuff, so just cache 2 entries.
277 static struct disp_info builtin_dispinfo;
278 static struct disp_info domain_dispinfo;
280 /* There are two cases to consider here:
281 1) The SID is a domain SID and we look for an equality match, or
282 2) This is an account SID and so we return the DISP_INFO* for our
289 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
291 * Necessary only once, but it does not really hurt.
293 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
295 return &builtin_dispinfo;
298 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
300 * Necessary only once, but it does not really hurt.
302 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
304 return &domain_dispinfo;
310 /*******************************************************************
311 Create a samr_info struct.
312 ********************************************************************/
314 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
316 struct samr_info *info;
321 sid_to_fstring(sid_str, psid);
323 fstrcpy(sid_str,"(NULL)");
326 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
328 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
331 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
333 sid_copy( &info->sid, psid);
334 info->builtin_domain = sid_check_is_builtin(psid);
336 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
337 info->builtin_domain = False;
339 info->mem_ctx = mem_ctx;
341 info->disp_info = get_samr_dispinfo_by_sid(psid);
346 /*******************************************************************
347 Function to free the per SID data.
348 ********************************************************************/
350 static void free_samr_cache(DISP_INFO *disp_info)
352 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
353 sid_string_dbg(&disp_info->sid)));
355 /* We need to become root here because the paged search might have to
356 * tell the LDAP server we're not interested in the rest anymore. */
360 if (disp_info->users) {
361 DEBUG(10,("free_samr_cache: deleting users cache\n"));
362 pdb_search_destroy(disp_info->users);
363 disp_info->users = NULL;
365 if (disp_info->machines) {
366 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
367 pdb_search_destroy(disp_info->machines);
368 disp_info->machines = NULL;
370 if (disp_info->groups) {
371 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
372 pdb_search_destroy(disp_info->groups);
373 disp_info->groups = NULL;
375 if (disp_info->aliases) {
376 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
377 pdb_search_destroy(disp_info->aliases);
378 disp_info->aliases = NULL;
380 if (disp_info->enum_users) {
381 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
382 pdb_search_destroy(disp_info->enum_users);
383 disp_info->enum_users = NULL;
385 disp_info->enum_acb_mask = 0;
390 /*******************************************************************
391 Function to free the per handle data.
392 ********************************************************************/
394 static void free_samr_info(void *ptr)
396 struct samr_info *info=(struct samr_info *) ptr;
398 /* Only free the dispinfo cache if no one bothered to set up
401 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
402 free_samr_cache(info->disp_info);
405 talloc_destroy(info->mem_ctx);
408 /*******************************************************************
409 Idle event handler. Throw away the disp info cache.
410 ********************************************************************/
412 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
413 struct timed_event *te,
414 const struct timeval *now,
417 DISP_INFO *disp_info = (DISP_INFO *)private_data;
419 TALLOC_FREE(disp_info->cache_timeout_event);
421 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
423 free_samr_cache(disp_info);
426 /*******************************************************************
427 Setup cache removal idle event handler.
428 ********************************************************************/
430 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
432 /* Remove any pending timeout and update. */
434 TALLOC_FREE(disp_info->cache_timeout_event);
436 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
437 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
438 (unsigned int)secs_fromnow ));
440 disp_info->cache_timeout_event = event_add_timed(
441 smbd_event_context(), NULL,
442 timeval_current_ofs(secs_fromnow, 0),
443 "disp_info_cache_idle_timeout_handler",
444 disp_info_cache_idle_timeout_handler, (void *)disp_info);
447 /*******************************************************************
448 Force flush any cache. We do this on any samr_set_xxx call.
449 We must also remove the timeout handler.
450 ********************************************************************/
452 static void force_flush_samr_cache(DISP_INFO *disp_info)
454 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
458 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
459 TALLOC_FREE(disp_info->cache_timeout_event);
460 free_samr_cache(disp_info);
463 /*******************************************************************
464 Ensure password info is never given out. Paranioa... JRA.
465 ********************************************************************/
467 static void samr_clear_sam_passwd(struct samu *sam_pass)
473 /* These now zero out the old password */
475 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
476 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
479 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
481 struct samr_displayentry *entry;
483 if (info->builtin_domain) {
484 /* No users in builtin. */
488 if (info->users == NULL) {
489 info->users = pdb_search_users(acct_flags);
490 if (info->users == NULL) {
494 /* Fetch the last possible entry, thus trigger an enumeration */
495 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
497 /* Ensure we cache this enumeration. */
498 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
500 return info->users->num_entries;
503 static uint32 count_sam_groups(struct disp_info *info)
505 struct samr_displayentry *entry;
507 if (info->builtin_domain) {
508 /* No groups in builtin. */
512 if (info->groups == NULL) {
513 info->groups = pdb_search_groups();
514 if (info->groups == NULL) {
518 /* Fetch the last possible entry, thus trigger an enumeration */
519 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
521 /* Ensure we cache this enumeration. */
522 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
524 return info->groups->num_entries;
527 static uint32 count_sam_aliases(struct disp_info *info)
529 struct samr_displayentry *entry;
531 if (info->aliases == NULL) {
532 info->aliases = pdb_search_aliases(&info->sid);
533 if (info->aliases == NULL) {
537 /* Fetch the last possible entry, thus trigger an enumeration */
538 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
540 /* Ensure we cache this enumeration. */
541 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
543 return info->aliases->num_entries;
546 /*******************************************************************
548 ********************************************************************/
550 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
552 if (!close_policy_hnd(p, r->in.handle)) {
553 return NT_STATUS_INVALID_HANDLE;
556 ZERO_STRUCTP(r->out.handle);
561 /*******************************************************************
563 ********************************************************************/
565 NTSTATUS _samr_OpenDomain(pipes_struct *p,
566 struct samr_OpenDomain *r)
568 struct samr_info *info;
569 SEC_DESC *psd = NULL;
571 uint32 des_access = r->in.access_mask;
576 /* find the connection policy handle. */
578 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
579 return NT_STATUS_INVALID_HANDLE;
581 status = access_check_samr_function(info->acc_granted,
582 SA_RIGHT_SAM_OPEN_DOMAIN,
583 "_samr_OpenDomain" );
585 if ( !NT_STATUS_IS_OK(status) )
588 /*check if access can be granted as requested by client. */
590 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
591 se_map_generic( &des_access, &dom_generic_mapping );
593 se_priv_copy( &se_rights, &se_machine_account );
594 se_priv_add( &se_rights, &se_add_users );
596 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
597 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
598 &acc_granted, "_samr_OpenDomain" );
600 if ( !NT_STATUS_IS_OK(status) )
603 if (!sid_check_is_domain(r->in.sid) &&
604 !sid_check_is_builtin(r->in.sid)) {
605 return NT_STATUS_NO_SUCH_DOMAIN;
608 /* associate the domain SID with the (unique) handle. */
609 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
610 return NT_STATUS_NO_MEMORY;
611 info->acc_granted = acc_granted;
613 /* get a (unique) handle. open a policy on it. */
614 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
615 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
617 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
622 /*******************************************************************
624 ********************************************************************/
626 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
627 struct samr_GetUserPwInfo *r)
629 struct samr_info *info = NULL;
631 /* find the policy handle. open a policy on it. */
632 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
633 return NT_STATUS_INVALID_HANDLE;
635 if (!sid_check_is_in_our_domain(&info->sid))
636 return NT_STATUS_OBJECT_TYPE_MISMATCH;
638 ZERO_STRUCTP(r->out.info);
640 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
643 * NT sometimes return NT_STATUS_ACCESS_DENIED
644 * I don't know yet why.
650 /*******************************************************************
651 ********************************************************************/
653 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
654 DOM_SID *sid, uint32 *acc_granted,
655 DISP_INFO **ppdisp_info)
657 struct samr_info *info = NULL;
659 /* find the policy handle. open a policy on it. */
660 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
667 *acc_granted = info->acc_granted;
669 *ppdisp_info = info->disp_info;
675 /*******************************************************************
677 ********************************************************************/
679 NTSTATUS _samr_SetSecurity(pipes_struct *p,
680 struct samr_SetSecurity *r)
683 uint32 acc_granted, i;
686 struct samu *sampass=NULL;
689 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
690 return NT_STATUS_INVALID_HANDLE;
692 if (!(sampass = samu_new( p->mem_ctx))) {
693 DEBUG(0,("No memory!\n"));
694 return NT_STATUS_NO_MEMORY;
697 /* get the user record */
699 ret = pdb_getsampwsid(sampass, &pol_sid);
703 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
704 TALLOC_FREE(sampass);
705 return NT_STATUS_INVALID_HANDLE;
708 dacl = r->in.sdbuf->sd->dacl;
709 for (i=0; i < dacl->num_aces; i++) {
710 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
711 ret = pdb_set_pass_can_change(sampass,
712 (dacl->aces[i].access_mask &
713 SA_RIGHT_USER_CHANGE_PASSWORD) ?
720 TALLOC_FREE(sampass);
721 return NT_STATUS_ACCESS_DENIED;
724 status = access_check_samr_function(acc_granted,
725 SA_RIGHT_USER_SET_ATTRIBUTES,
726 "_samr_SetSecurity");
727 if (NT_STATUS_IS_OK(status)) {
729 status = pdb_update_sam_account(sampass);
733 TALLOC_FREE(sampass);
738 /*******************************************************************
739 build correct perms based on policies and password times for _samr_query_sec_obj
740 *******************************************************************/
741 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
743 struct samu *sampass=NULL;
746 if ( !(sampass = samu_new( mem_ctx )) ) {
747 DEBUG(0,("No memory!\n"));
752 ret = pdb_getsampwsid(sampass, user_sid);
756 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
757 TALLOC_FREE(sampass);
761 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
763 if (pdb_get_pass_can_change(sampass)) {
764 TALLOC_FREE(sampass);
767 TALLOC_FREE(sampass);
772 /*******************************************************************
774 ********************************************************************/
776 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
777 struct samr_QuerySecurity *r)
781 SEC_DESC * psd = NULL;
786 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
787 return NT_STATUS_INVALID_HANDLE;
789 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
790 sid_string_dbg(&pol_sid)));
792 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
794 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
795 if (pol_sid.sid_rev_num == 0) {
796 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
797 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
798 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
799 /* check if it is our domain SID */
800 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
801 "with SID: %s\n", sid_string_dbg(&pol_sid)));
802 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
803 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
804 /* check if it is the Builtin Domain */
805 /* TODO: Builtin probably needs a different SD with restricted write access*/
806 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
807 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
808 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
809 } else if (sid_check_is_in_our_domain(&pol_sid) ||
810 sid_check_is_in_builtin(&pol_sid)) {
811 /* TODO: different SDs have to be generated for aliases groups and users.
812 Currently all three get a default user SD */
813 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
814 "with SID: %s\n", sid_string_dbg(&pol_sid)));
815 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
816 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
817 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
819 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
820 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
823 return NT_STATUS_OBJECT_TYPE_MISMATCH;
826 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
827 return NT_STATUS_NO_MEMORY;
832 /*******************************************************************
833 makes a SAM_ENTRY / UNISTR2* structure from a user list.
834 ********************************************************************/
836 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
837 struct samr_SamEntry **sam_pp,
838 uint32_t num_entries,
840 struct samr_displayentry *entries)
843 struct samr_SamEntry *sam;
847 if (num_entries == 0) {
851 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
853 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
854 return NT_STATUS_NO_MEMORY;
857 for (i = 0; i < num_entries; i++) {
860 * usrmgr expects a non-NULL terminated string with
861 * trust relationships
863 if (entries[i].acct_flags & ACB_DOMTRUST) {
864 init_unistr2(&uni_temp_name, entries[i].account_name,
867 init_unistr2(&uni_temp_name, entries[i].account_name,
871 init_lsa_String(&sam[i].name, entries[i].account_name);
872 sam[i].idx = entries[i].rid;
880 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
882 /*******************************************************************
883 _samr_EnumDomainUsers
884 ********************************************************************/
886 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
887 struct samr_EnumDomainUsers *r)
890 struct samr_info *info = NULL;
892 uint32 enum_context = *r->in.resume_handle;
893 enum remote_arch_types ra_type = get_remote_arch();
894 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
895 uint32 max_entries = max_sam_entries;
896 struct samr_displayentry *entries = NULL;
897 struct samr_SamArray *samr_array = NULL;
898 struct samr_SamEntry *samr_entries = NULL;
900 /* find the policy handle. open a policy on it. */
901 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
902 return NT_STATUS_INVALID_HANDLE;
904 status = access_check_samr_function(info->acc_granted,
905 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
906 "_samr_EnumDomainUsers");
907 if (!NT_STATUS_IS_OK(status)) {
911 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
913 if (info->builtin_domain) {
914 /* No users in builtin. */
915 *r->out.resume_handle = *r->in.resume_handle;
916 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
920 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
922 return NT_STATUS_NO_MEMORY;
929 if ((info->disp_info->enum_users != NULL) &&
930 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
931 pdb_search_destroy(info->disp_info->enum_users);
932 info->disp_info->enum_users = NULL;
935 if (info->disp_info->enum_users == NULL) {
936 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
937 info->disp_info->enum_acb_mask = r->in.acct_flags;
940 if (info->disp_info->enum_users == NULL) {
941 /* END AS ROOT !!!! */
943 return NT_STATUS_ACCESS_DENIED;
946 num_account = pdb_search_entries(info->disp_info->enum_users,
947 enum_context, max_entries,
950 /* END AS ROOT !!!! */
954 if (num_account == 0) {
955 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
957 *r->out.resume_handle = *r->in.resume_handle;
961 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
962 num_account, enum_context,
964 if (!NT_STATUS_IS_OK(status)) {
968 if (max_entries <= num_account) {
969 status = STATUS_MORE_ENTRIES;
971 status = NT_STATUS_OK;
974 /* Ensure we cache this enumeration. */
975 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
977 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
979 samr_array->count = num_account;
980 samr_array->entries = samr_entries;
982 *r->out.resume_handle = *r->in.resume_handle + num_account;
983 *r->out.sam = samr_array;
984 *r->out.num_entries = num_account;
986 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
991 /*******************************************************************
992 makes a SAM_ENTRY / UNISTR2* structure from a group list.
993 ********************************************************************/
995 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
996 struct samr_SamEntry **sam_pp,
997 uint32_t num_sam_entries,
998 struct samr_displayentry *entries)
1000 struct samr_SamEntry *sam;
1005 if (num_sam_entries == 0) {
1009 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1014 for (i = 0; i < num_sam_entries; i++) {
1016 * JRA. I think this should include the null. TNG does not.
1018 init_lsa_String(&sam[i].name, entries[i].account_name);
1019 sam[i].idx = entries[i].rid;
1025 /*******************************************************************
1026 _samr_EnumDomainGroups
1027 ********************************************************************/
1029 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1030 struct samr_EnumDomainGroups *r)
1033 struct samr_info *info = NULL;
1034 struct samr_displayentry *groups;
1036 struct samr_SamArray *samr_array = NULL;
1037 struct samr_SamEntry *samr_entries = NULL;
1039 /* find the policy handle. open a policy on it. */
1040 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1041 return NT_STATUS_INVALID_HANDLE;
1043 status = access_check_samr_function(info->acc_granted,
1044 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1045 "_samr_EnumDomainGroups");
1046 if (!NT_STATUS_IS_OK(status)) {
1050 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1052 if (info->builtin_domain) {
1053 /* No groups in builtin. */
1054 *r->out.resume_handle = *r->in.resume_handle;
1055 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1059 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1061 return NT_STATUS_NO_MEMORY;
1064 /* the domain group array is being allocated in the function below */
1068 if (info->disp_info->groups == NULL) {
1069 info->disp_info->groups = pdb_search_groups();
1071 if (info->disp_info->groups == NULL) {
1073 return NT_STATUS_ACCESS_DENIED;
1077 num_groups = pdb_search_entries(info->disp_info->groups,
1078 *r->in.resume_handle,
1079 MAX_SAM_ENTRIES, &groups);
1082 /* Ensure we cache this enumeration. */
1083 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1085 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1086 num_groups, groups);
1088 samr_array->count = num_groups;
1089 samr_array->entries = samr_entries;
1091 *r->out.sam = samr_array;
1092 *r->out.num_entries = num_groups;
1093 /* this was missing, IMHO:
1094 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1097 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1102 /*******************************************************************
1103 _samr_EnumDomainAliases
1104 ********************************************************************/
1106 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1107 struct samr_EnumDomainAliases *r)
1110 struct samr_info *info;
1111 struct samr_displayentry *aliases;
1112 uint32 num_aliases = 0;
1113 struct samr_SamArray *samr_array = NULL;
1114 struct samr_SamEntry *samr_entries = NULL;
1116 /* find the policy handle. open a policy on it. */
1117 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1118 return NT_STATUS_INVALID_HANDLE;
1120 status = access_check_samr_function(info->acc_granted,
1121 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1122 "_samr_EnumDomainAliases");
1123 if (!NT_STATUS_IS_OK(status)) {
1127 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1128 sid_string_dbg(&info->sid)));
1130 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1132 return NT_STATUS_NO_MEMORY;
1137 if (info->disp_info->aliases == NULL) {
1138 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1139 if (info->disp_info->aliases == NULL) {
1141 return NT_STATUS_ACCESS_DENIED;
1145 num_aliases = pdb_search_entries(info->disp_info->aliases,
1146 *r->in.resume_handle,
1147 MAX_SAM_ENTRIES, &aliases);
1150 /* Ensure we cache this enumeration. */
1151 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1153 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1154 num_aliases, aliases);
1156 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1158 samr_array->count = num_aliases;
1159 samr_array->entries = samr_entries;
1161 *r->out.sam = samr_array;
1162 *r->out.num_entries = num_aliases;
1163 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1168 /*******************************************************************
1169 inits a samr_DispInfoGeneral structure.
1170 ********************************************************************/
1172 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1173 struct samr_DispInfoGeneral *r,
1174 uint32_t num_entries,
1176 struct samr_displayentry *entries)
1180 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1182 if (num_entries == 0) {
1183 return NT_STATUS_OK;
1186 r->count = num_entries;
1188 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1190 return NT_STATUS_NO_MEMORY;
1193 for (i = 0; i < num_entries ; i++) {
1195 init_lsa_String(&r->entries[i].account_name,
1196 entries[i].account_name);
1198 init_lsa_String(&r->entries[i].description,
1199 entries[i].description);
1201 init_lsa_String(&r->entries[i].full_name,
1202 entries[i].fullname);
1204 r->entries[i].rid = entries[i].rid;
1205 r->entries[i].acct_flags = entries[i].acct_flags;
1206 r->entries[i].idx = start_idx+i+1;
1209 return NT_STATUS_OK;
1212 /*******************************************************************
1213 inits a samr_DispInfoFull structure.
1214 ********************************************************************/
1216 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1217 struct samr_DispInfoFull *r,
1218 uint32_t num_entries,
1220 struct samr_displayentry *entries)
1224 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1226 if (num_entries == 0) {
1227 return NT_STATUS_OK;
1230 r->count = num_entries;
1232 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1234 return NT_STATUS_NO_MEMORY;
1237 for (i = 0; i < num_entries ; i++) {
1239 init_lsa_String(&r->entries[i].account_name,
1240 entries[i].account_name);
1242 init_lsa_String(&r->entries[i].description,
1243 entries[i].description);
1245 r->entries[i].rid = entries[i].rid;
1246 r->entries[i].acct_flags = entries[i].acct_flags;
1247 r->entries[i].idx = start_idx+i+1;
1250 return NT_STATUS_OK;
1253 /*******************************************************************
1254 inits a samr_DispInfoFullGroups structure.
1255 ********************************************************************/
1257 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1258 struct samr_DispInfoFullGroups *r,
1259 uint32_t num_entries,
1261 struct samr_displayentry *entries)
1265 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1267 if (num_entries == 0) {
1268 return NT_STATUS_OK;
1271 r->count = num_entries;
1273 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1275 return NT_STATUS_NO_MEMORY;
1278 for (i = 0; i < num_entries ; i++) {
1280 init_lsa_String(&r->entries[i].account_name,
1281 entries[i].account_name);
1283 init_lsa_String(&r->entries[i].description,
1284 entries[i].description);
1286 r->entries[i].rid = entries[i].rid;
1287 r->entries[i].acct_flags = entries[i].acct_flags;
1288 r->entries[i].idx = start_idx+i+1;
1291 return NT_STATUS_OK;
1294 /*******************************************************************
1295 inits a samr_DispInfoAscii structure.
1296 ********************************************************************/
1298 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1299 struct samr_DispInfoAscii *r,
1300 uint32_t num_entries,
1302 struct samr_displayentry *entries)
1306 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1308 if (num_entries == 0) {
1309 return NT_STATUS_OK;
1312 r->count = num_entries;
1314 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1316 return NT_STATUS_NO_MEMORY;
1319 for (i = 0; i < num_entries ; i++) {
1321 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1322 entries[i].account_name);
1324 r->entries[i].idx = start_idx+i+1;
1327 return NT_STATUS_OK;
1330 /*******************************************************************
1331 inits a samr_DispInfoAscii structure.
1332 ********************************************************************/
1334 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1335 struct samr_DispInfoAscii *r,
1336 uint32_t num_entries,
1338 struct samr_displayentry *entries)
1342 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1344 if (num_entries == 0) {
1345 return NT_STATUS_OK;
1348 r->count = num_entries;
1350 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1352 return NT_STATUS_NO_MEMORY;
1355 for (i = 0; i < num_entries ; i++) {
1357 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1358 entries[i].account_name);
1360 r->entries[i].idx = start_idx+i+1;
1363 return NT_STATUS_OK;
1366 /*******************************************************************
1367 _samr_QueryDisplayInfo
1368 ********************************************************************/
1370 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1371 struct samr_QueryDisplayInfo *r)
1374 struct samr_info *info = NULL;
1375 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1377 uint32 max_entries = r->in.max_entries;
1378 uint32 enum_context = r->in.start_idx;
1379 uint32 max_size = r->in.buf_size;
1381 union samr_DispInfo *disp_info = r->out.info;
1383 uint32 temp_size=0, total_data_size=0;
1384 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1385 uint32 num_account = 0;
1386 enum remote_arch_types ra_type = get_remote_arch();
1387 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1388 struct samr_displayentry *entries = NULL;
1390 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1392 /* find the policy handle. open a policy on it. */
1393 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1394 return NT_STATUS_INVALID_HANDLE;
1397 * calculate how many entries we will return.
1399 * - the number of entries the client asked
1400 * - our limit on that
1401 * - the starting point (enumeration context)
1402 * - the buffer size the client will accept
1406 * We are a lot more like W2K. Instead of reading the SAM
1407 * each time to find the records we need to send back,
1408 * we read it once and link that copy to the sam handle.
1409 * For large user list (over the MAX_SAM_ENTRIES)
1410 * it's a definitive win.
1411 * second point to notice: between enumerations
1412 * our sam is now the same as it's a snapshoot.
1413 * third point: got rid of the static SAM_USER_21 struct
1414 * no more intermediate.
1415 * con: it uses much more memory, as a full copy is stored
1418 * If you want to change it, think twice and think
1419 * of the second point , that's really important.
1424 if ((r->in.level < 1) || (r->in.level > 5)) {
1425 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1426 (unsigned int)r->in.level ));
1427 return NT_STATUS_INVALID_INFO_CLASS;
1430 /* first limit the number of entries we will return */
1431 if(max_entries > max_sam_entries) {
1432 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1433 "entries, limiting to %d\n", max_entries,
1435 max_entries = max_sam_entries;
1438 /* calculate the size and limit on the number of entries we will
1441 temp_size=max_entries*struct_size;
1443 if (temp_size>max_size) {
1444 max_entries=MIN((max_size/struct_size),max_entries);;
1445 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1446 "only %d entries\n", max_entries));
1451 /* THe following done as ROOT. Don't return without unbecome_root(). */
1453 switch (r->in.level) {
1456 if (info->disp_info->users == NULL) {
1457 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1458 if (info->disp_info->users == NULL) {
1460 return NT_STATUS_ACCESS_DENIED;
1462 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1463 (unsigned int)enum_context ));
1465 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1466 (unsigned int)enum_context ));
1469 num_account = pdb_search_entries(info->disp_info->users,
1470 enum_context, max_entries,
1474 if (info->disp_info->machines == NULL) {
1475 info->disp_info->machines =
1476 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1477 if (info->disp_info->machines == NULL) {
1479 return NT_STATUS_ACCESS_DENIED;
1481 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1482 (unsigned int)enum_context ));
1484 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1485 (unsigned int)enum_context ));
1488 num_account = pdb_search_entries(info->disp_info->machines,
1489 enum_context, max_entries,
1494 if (info->disp_info->groups == NULL) {
1495 info->disp_info->groups = pdb_search_groups();
1496 if (info->disp_info->groups == NULL) {
1498 return NT_STATUS_ACCESS_DENIED;
1500 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1501 (unsigned int)enum_context ));
1503 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1504 (unsigned int)enum_context ));
1507 num_account = pdb_search_entries(info->disp_info->groups,
1508 enum_context, max_entries,
1513 smb_panic("info class changed");
1519 /* Now create reply structure */
1520 switch (r->in.level) {
1522 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1523 num_account, enum_context,
1527 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1528 num_account, enum_context,
1532 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1533 num_account, enum_context,
1537 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1538 num_account, enum_context,
1542 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1543 num_account, enum_context,
1547 smb_panic("info class changed");
1551 if (!NT_STATUS_IS_OK(disp_ret))
1554 /* calculate the total size */
1555 total_data_size=num_account*struct_size;
1558 status = STATUS_MORE_ENTRIES;
1560 status = NT_STATUS_OK;
1563 /* Ensure we cache this enumeration. */
1564 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1566 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1568 *r->out.total_size = total_data_size;
1569 *r->out.returned_size = temp_size;
1574 /****************************************************************
1575 _samr_QueryDisplayInfo2
1576 ****************************************************************/
1578 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1579 struct samr_QueryDisplayInfo2 *r)
1581 struct samr_QueryDisplayInfo q;
1583 q.in.domain_handle = r->in.domain_handle;
1584 q.in.level = r->in.level;
1585 q.in.start_idx = r->in.start_idx;
1586 q.in.max_entries = r->in.max_entries;
1587 q.in.buf_size = r->in.buf_size;
1589 q.out.total_size = r->out.total_size;
1590 q.out.returned_size = r->out.returned_size;
1591 q.out.info = r->out.info;
1593 return _samr_QueryDisplayInfo(p, &q);
1596 /****************************************************************
1597 _samr_QueryDisplayInfo3
1598 ****************************************************************/
1600 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1601 struct samr_QueryDisplayInfo3 *r)
1603 struct samr_QueryDisplayInfo q;
1605 q.in.domain_handle = r->in.domain_handle;
1606 q.in.level = r->in.level;
1607 q.in.start_idx = r->in.start_idx;
1608 q.in.max_entries = r->in.max_entries;
1609 q.in.buf_size = r->in.buf_size;
1611 q.out.total_size = r->out.total_size;
1612 q.out.returned_size = r->out.returned_size;
1613 q.out.info = r->out.info;
1615 return _samr_QueryDisplayInfo(p, &q);
1618 /*******************************************************************
1619 _samr_QueryAliasInfo
1620 ********************************************************************/
1622 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1623 struct samr_QueryAliasInfo *r)
1626 struct acct_info info;
1629 union samr_AliasInfo *alias_info = NULL;
1630 const char *alias_name = NULL;
1631 const char *alias_description = NULL;
1633 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1635 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1637 return NT_STATUS_NO_MEMORY;
1640 /* find the policy handle. open a policy on it. */
1641 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1642 return NT_STATUS_INVALID_HANDLE;
1644 status = access_check_samr_function(acc_granted,
1645 SA_RIGHT_ALIAS_LOOKUP_INFO,
1646 "_samr_QueryAliasInfo");
1647 if (!NT_STATUS_IS_OK(status)) {
1652 status = pdb_get_aliasinfo(&sid, &info);
1655 if ( !NT_STATUS_IS_OK(status))
1658 /* FIXME: info contains fstrings */
1659 alias_name = talloc_strdup(r, info.acct_name);
1660 alias_description = talloc_strdup(r, info.acct_desc);
1662 switch (r->in.level) {
1664 init_samr_alias_info1(&alias_info->all,
1669 case ALIASINFODESCRIPTION:
1670 init_samr_alias_info3(&alias_info->description,
1674 return NT_STATUS_INVALID_INFO_CLASS;
1677 *r->out.info = alias_info;
1679 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1681 return NT_STATUS_OK;
1685 /*******************************************************************
1686 samr_reply_lookup_ids
1687 ********************************************************************/
1689 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1691 uint32 rid[MAX_SAM_ENTRIES];
1692 int num_rids = q_u->num_sids1;
1694 r_u->status = NT_STATUS_OK;
1696 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1698 if (num_rids > MAX_SAM_ENTRIES) {
1699 num_rids = MAX_SAM_ENTRIES;
1700 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1705 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1707 for (i = 0; i < num_rids && status == 0; i++)
1709 struct sam_passwd *sam_pass;
1713 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1714 q_u->uni_user_name[i].uni_str_len));
1716 /* find the user account */
1718 sam_pass = get_smb21pwd_entry(user_name, 0);
1721 if (sam_pass == NULL)
1723 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1728 rid[i] = sam_pass->user_rid;
1734 rid[0] = BUILTIN_ALIAS_RID_USERS;
1736 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1738 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1744 /*******************************************************************
1746 ********************************************************************/
1748 NTSTATUS _samr_LookupNames(pipes_struct *p,
1749 struct samr_LookupNames *r)
1752 uint32 rid[MAX_SAM_ENTRIES];
1753 enum lsa_SidType type[MAX_SAM_ENTRIES];
1755 int num_rids = r->in.num_names;
1758 struct samr_Ids rids, types;
1760 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1765 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1766 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1769 status = access_check_samr_function(acc_granted,
1770 0, /* Don't know the acc_bits yet */
1771 "_samr_LookupNames");
1772 if (!NT_STATUS_IS_OK(status)) {
1776 if (num_rids > MAX_SAM_ENTRIES) {
1777 num_rids = MAX_SAM_ENTRIES;
1778 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1781 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1782 sid_string_dbg(&pol_sid)));
1784 for (i = 0; i < num_rids; i++) {
1786 status = NT_STATUS_NONE_MAPPED;
1787 type[i] = SID_NAME_UNKNOWN;
1789 rid[i] = 0xffffffff;
1791 if (sid_check_is_builtin(&pol_sid)) {
1792 if (lookup_builtin_name(r->in.names[i].string,
1795 type[i] = SID_NAME_ALIAS;
1798 lookup_global_sam_name(r->in.names[i].string, 0,
1802 if (type[i] != SID_NAME_UNKNOWN) {
1803 status = NT_STATUS_OK;
1807 rids.count = num_rids;
1810 types.count = num_rids;
1813 *r->out.rids = rids;
1814 *r->out.types = types;
1816 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1821 /*******************************************************************
1822 _samr_ChangePasswordUser2
1823 ********************************************************************/
1825 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1826 struct samr_ChangePasswordUser2 *r)
1832 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1834 fstrcpy(user_name, r->in.account->string);
1835 fstrcpy(wks, r->in.server->string);
1837 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1840 * Pass the user through the NT -> unix user mapping
1844 (void)map_username(user_name);
1847 * UNIX username case mangling not required, pass_oem_change
1848 * is case insensitive.
1851 status = pass_oem_change(user_name,
1852 r->in.lm_password->data,
1853 r->in.lm_verifier->hash,
1854 r->in.nt_password->data,
1855 r->in.nt_verifier->hash,
1858 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1863 /*******************************************************************
1864 _samr_ChangePasswordUser3
1865 ********************************************************************/
1867 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1868 struct samr_ChangePasswordUser3 *r)
1872 const char *wks = NULL;
1873 uint32 reject_reason;
1874 struct samr_DomInfo1 *dominfo = NULL;
1875 struct samr_ChangeReject *reject = NULL;
1877 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1879 fstrcpy(user_name, r->in.account->string);
1880 if (r->in.server && r->in.server->string) {
1881 wks = r->in.server->string;
1884 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1887 * Pass the user through the NT -> unix user mapping
1891 (void)map_username(user_name);
1894 * UNIX username case mangling not required, pass_oem_change
1895 * is case insensitive.
1898 status = pass_oem_change(user_name,
1899 r->in.lm_password->data,
1900 r->in.lm_verifier->hash,
1901 r->in.nt_password->data,
1902 r->in.nt_verifier->hash,
1905 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1906 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1908 uint32 min_pass_len,pass_hist,password_properties;
1909 time_t u_expire, u_min_age;
1910 NTTIME nt_expire, nt_min_age;
1911 uint32 account_policy_temp;
1913 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1915 return NT_STATUS_NO_MEMORY;
1918 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1920 return NT_STATUS_NO_MEMORY;
1927 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1928 min_pass_len = account_policy_temp;
1930 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1931 pass_hist = account_policy_temp;
1933 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1934 password_properties = account_policy_temp;
1936 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1937 u_expire = account_policy_temp;
1939 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1940 u_min_age = account_policy_temp;
1946 unix_to_nt_time_abs(&nt_expire, u_expire);
1947 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1949 if (lp_check_password_script() && *lp_check_password_script()) {
1950 password_properties |= DOMAIN_PASSWORD_COMPLEX;
1953 init_samr_DomInfo1(dominfo,
1956 password_properties,
1960 reject->reason = reject_reason;
1962 *r->out.dominfo = dominfo;
1963 *r->out.reject = reject;
1966 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1971 /*******************************************************************
1972 makes a SAMR_R_LOOKUP_RIDS structure.
1973 ********************************************************************/
1975 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1977 struct lsa_String **lsa_name_array_p)
1979 struct lsa_String *lsa_name_array = NULL;
1982 *lsa_name_array_p = NULL;
1984 if (num_names != 0) {
1985 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
1986 if (!lsa_name_array) {
1991 for (i = 0; i < num_names; i++) {
1992 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
1993 init_lsa_String(&lsa_name_array[i], names[i]);
1996 *lsa_name_array_p = lsa_name_array;
2001 /*******************************************************************
2003 ********************************************************************/
2005 NTSTATUS _samr_LookupRids(pipes_struct *p,
2006 struct samr_LookupRids *r)
2010 enum lsa_SidType *attrs = NULL;
2011 uint32 *wire_attrs = NULL;
2013 int num_rids = (int)r->in.num_rids;
2016 struct lsa_Strings names_array;
2017 struct samr_Ids types_array;
2018 struct lsa_String *lsa_names = NULL;
2020 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2022 /* find the policy handle. open a policy on it. */
2023 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2024 return NT_STATUS_INVALID_HANDLE;
2026 if (num_rids > 1000) {
2027 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2028 "to samba4 idl this is not possible\n", num_rids));
2029 return NT_STATUS_UNSUCCESSFUL;
2033 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2034 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2035 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2037 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2038 return NT_STATUS_NO_MEMORY;
2045 become_root(); /* lookup_sid can require root privs */
2046 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2050 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2051 status = NT_STATUS_OK;
2054 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2056 return NT_STATUS_NO_MEMORY;
2059 /* Convert from enum lsa_SidType to uint32 for wire format. */
2060 for (i = 0; i < num_rids; i++) {
2061 wire_attrs[i] = (uint32)attrs[i];
2064 names_array.count = num_rids;
2065 names_array.names = lsa_names;
2067 types_array.count = num_rids;
2068 types_array.ids = wire_attrs;
2070 *r->out.names = names_array;
2071 *r->out.types = types_array;
2073 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2078 /*******************************************************************
2080 ********************************************************************/
2082 NTSTATUS _samr_OpenUser(pipes_struct *p,
2083 struct samr_OpenUser *r)
2085 struct samu *sampass=NULL;
2087 POLICY_HND domain_pol = *r->in.domain_handle;
2088 POLICY_HND *user_pol = r->out.user_handle;
2089 struct samr_info *info = NULL;
2090 SEC_DESC *psd = NULL;
2092 uint32 des_access = r->in.access_mask;
2098 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2100 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2101 return NT_STATUS_INVALID_HANDLE;
2103 nt_status = access_check_samr_function(acc_granted,
2104 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2107 if ( !NT_STATUS_IS_OK(nt_status) )
2110 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2111 return NT_STATUS_NO_MEMORY;
2114 /* append the user's RID to it */
2116 if (!sid_append_rid(&sid, r->in.rid))
2117 return NT_STATUS_NO_SUCH_USER;
2119 /* check if access can be granted as requested by client. */
2121 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2122 se_map_generic(&des_access, &usr_generic_mapping);
2124 se_priv_copy( &se_rights, &se_machine_account );
2125 se_priv_add( &se_rights, &se_add_users );
2127 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2128 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2129 &acc_granted, "_samr_OpenUser");
2131 if ( !NT_STATUS_IS_OK(nt_status) )
2135 ret=pdb_getsampwsid(sampass, &sid);
2138 /* check that the SID exists in our domain. */
2140 return NT_STATUS_NO_SUCH_USER;
2143 TALLOC_FREE(sampass);
2145 /* associate the user's SID and access bits with the new handle. */
2146 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2147 return NT_STATUS_NO_MEMORY;
2148 info->acc_granted = acc_granted;
2150 /* get a (unique) handle. open a policy on it. */
2151 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2152 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2154 return NT_STATUS_OK;
2157 /*************************************************************************
2158 *************************************************************************/
2160 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2162 struct lsa_BinaryString **_r)
2164 struct lsa_BinaryString *r;
2167 return NT_STATUS_INVALID_PARAMETER;
2170 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2172 return NT_STATUS_NO_MEMORY;
2175 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2177 return NT_STATUS_NO_MEMORY;
2179 memcpy(r->array, blob->data, blob->length);
2180 r->size = blob->length;
2181 r->length = blob->length;
2184 return NT_STATUS_NO_MEMORY;
2189 return NT_STATUS_OK;
2192 /*************************************************************************
2193 get_user_info_7. Safe. Only gives out account_name.
2194 *************************************************************************/
2196 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2197 struct samr_UserInfo7 *r,
2200 struct samu *smbpass=NULL;
2202 const char *account_name = NULL;
2206 if ( !(smbpass = samu_new( mem_ctx )) ) {
2207 return NT_STATUS_NO_MEMORY;
2211 ret = pdb_getsampwsid(smbpass, user_sid);
2215 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2216 return NT_STATUS_NO_SUCH_USER;
2219 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2220 if (!account_name) {
2221 TALLOC_FREE(smbpass);
2222 return NT_STATUS_NO_MEMORY;
2224 TALLOC_FREE(smbpass);
2226 DEBUG(3,("User:[%s]\n", account_name));
2228 init_samr_user_info7(r, account_name);
2230 return NT_STATUS_OK;
2233 /*************************************************************************
2234 get_user_info_9. Only gives out primary group SID.
2235 *************************************************************************/
2237 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2238 struct samr_UserInfo9 *r,
2241 struct samu *smbpass=NULL;
2246 if ( !(smbpass = samu_new( mem_ctx )) ) {
2247 return NT_STATUS_NO_MEMORY;
2251 ret = pdb_getsampwsid(smbpass, user_sid);
2255 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2256 TALLOC_FREE(smbpass);
2257 return NT_STATUS_NO_SUCH_USER;
2260 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2262 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2264 TALLOC_FREE(smbpass);
2266 return NT_STATUS_OK;
2269 /*************************************************************************
2270 get_user_info_16. Safe. Only gives out acb bits.
2271 *************************************************************************/
2273 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2274 struct samr_UserInfo16 *r,
2277 struct samu *smbpass=NULL;
2282 if ( !(smbpass = samu_new( mem_ctx )) ) {
2283 return NT_STATUS_NO_MEMORY;
2287 ret = pdb_getsampwsid(smbpass, user_sid);
2291 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2292 TALLOC_FREE(smbpass);
2293 return NT_STATUS_NO_SUCH_USER;
2296 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2298 init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2300 TALLOC_FREE(smbpass);
2302 return NT_STATUS_OK;
2305 /*************************************************************************
2306 get_user_info_18. OK - this is the killer as it gives out password info.
2307 Ensure that this is only allowed on an encrypted connection with a root
2309 *************************************************************************/
2311 static NTSTATUS get_user_info_18(pipes_struct *p,
2312 TALLOC_CTX *mem_ctx,
2313 struct samr_UserInfo18 *r,
2316 struct samu *smbpass=NULL;
2321 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2322 return NT_STATUS_ACCESS_DENIED;
2325 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2326 return NT_STATUS_ACCESS_DENIED;
2330 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2333 if ( !(smbpass = samu_new( mem_ctx )) ) {
2334 return NT_STATUS_NO_MEMORY;
2337 ret = pdb_getsampwsid(smbpass, user_sid);
2340 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2341 TALLOC_FREE(smbpass);
2342 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2345 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2347 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2348 TALLOC_FREE(smbpass);
2349 return NT_STATUS_ACCOUNT_DISABLED;
2352 init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2353 pdb_get_nt_passwd(smbpass));
2355 TALLOC_FREE(smbpass);
2357 return NT_STATUS_OK;
2360 /*************************************************************************
2362 *************************************************************************/
2364 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2365 struct samr_UserInfo20 *r,
2368 struct samu *sampass=NULL;
2370 const char *munged_dial = NULL;
2373 struct lsa_BinaryString *parameters = NULL;
2377 if ( !(sampass = samu_new( mem_ctx )) ) {
2378 return NT_STATUS_NO_MEMORY;
2382 ret = pdb_getsampwsid(sampass, user_sid);
2386 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2387 TALLOC_FREE(sampass);
2388 return NT_STATUS_NO_SUCH_USER;
2391 munged_dial = pdb_get_munged_dial(sampass);
2393 samr_clear_sam_passwd(sampass);
2395 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2396 munged_dial, strlen(munged_dial)));
2399 blob = base64_decode_data_blob(munged_dial);
2401 blob = data_blob_string_const("");
2404 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2405 data_blob_free(&blob);
2406 TALLOC_FREE(sampass);
2407 if (!NT_STATUS_IS_OK(status)) {
2411 init_samr_user_info20(r, parameters);
2413 return NT_STATUS_OK;
2417 /*************************************************************************
2419 *************************************************************************/
2421 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2422 struct samr_UserInfo21 *r,
2424 DOM_SID *domain_sid)
2427 struct samu *pw = NULL;
2429 const DOM_SID *sid_user, *sid_group;
2430 uint32_t rid, primary_gid;
2431 NTTIME last_logon, last_logoff, last_password_change,
2432 acct_expiry, allow_password_change, force_password_change;
2433 time_t must_change_time;
2434 uint8_t password_expired;
2435 const char *account_name, *full_name, *home_directory, *home_drive,
2436 *logon_script, *profile_path, *description,
2437 *workstations, *comment;
2438 struct samr_LogonHours logon_hours;
2439 struct lsa_BinaryString *parameters = NULL;
2440 const char *munged_dial = NULL;
2445 if (!(pw = samu_new(mem_ctx))) {
2446 return NT_STATUS_NO_MEMORY;
2450 ret = pdb_getsampwsid(pw, user_sid);
2454 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2456 return NT_STATUS_NO_SUCH_USER;
2459 samr_clear_sam_passwd(pw);
2461 DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2463 sid_user = pdb_get_user_sid(pw);
2465 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2466 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2467 "the domain sid %s. Failing operation.\n",
2468 pdb_get_username(pw), sid_string_dbg(sid_user),
2469 sid_string_dbg(domain_sid)));
2471 return NT_STATUS_UNSUCCESSFUL;
2475 sid_group = pdb_get_group_sid(pw);
2478 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2479 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2480 "which conflicts with the domain sid %s. Failing operation.\n",
2481 pdb_get_username(pw), sid_string_dbg(sid_group),
2482 sid_string_dbg(domain_sid)));
2484 return NT_STATUS_UNSUCCESSFUL;
2487 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2488 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2489 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2490 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2491 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2493 must_change_time = pdb_get_pass_must_change_time(pw);
2494 if (must_change_time == get_time_t_max()) {
2495 unix_to_nt_time_abs(&force_password_change, must_change_time);
2497 unix_to_nt_time(&force_password_change, must_change_time);
2500 if (pdb_get_pass_must_change_time(pw) == 0) {
2501 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2503 password_expired = 0;
2506 munged_dial = pdb_get_munged_dial(pw);
2508 blob = base64_decode_data_blob(munged_dial);
2510 blob = data_blob_string_const("");
2513 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2514 data_blob_free(&blob);
2515 if (!NT_STATUS_IS_OK(status)) {
2520 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2521 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2522 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2523 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2524 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2525 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2526 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2527 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2528 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2530 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2534 Look at a user on a real NT4 PDC with usrmgr, press
2535 'ok'. Then you will see that fields_present is set to
2536 0x08f827fa. Look at the user immediately after that again,
2537 and you will see that 0x00fffff is returned. This solves
2538 the problem that you get access denied after having looked
2545 init_samr_user_info21(r,
2548 last_password_change,
2550 allow_password_change,
2551 force_password_change,
2564 pdb_get_acct_ctrl(pw),
2565 pdb_build_fields_present(pw),
2567 pdb_get_bad_password_count(pw),
2568 pdb_get_logon_count(pw),
2569 0, /* country_code */
2571 0, /* nt_password_set */
2572 0, /* lm_password_set */
2576 return NT_STATUS_OK;
2579 /*******************************************************************
2581 ********************************************************************/
2583 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2584 struct samr_QueryUserInfo *r)
2587 union samr_UserInfo *user_info = NULL;
2588 struct samr_info *info = NULL;
2592 /* search for the handle */
2593 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2594 return NT_STATUS_INVALID_HANDLE;
2596 domain_sid = info->sid;
2598 sid_split_rid(&domain_sid, &rid);
2600 if (!sid_check_is_in_our_domain(&info->sid))
2601 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2603 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2604 sid_string_dbg(&info->sid)));
2606 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2608 return NT_STATUS_NO_MEMORY;
2611 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2613 switch (r->in.level) {
2615 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2616 if (!NT_STATUS_IS_OK(status)) {
2621 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2622 if (!NT_STATUS_IS_OK(status)) {
2627 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2628 if (!NT_STATUS_IS_OK(status)) {
2634 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2635 if (!NT_STATUS_IS_OK(status)) {
2641 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2642 if (!NT_STATUS_IS_OK(status)) {
2648 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2649 &info->sid, &domain_sid);
2650 if (!NT_STATUS_IS_OK(status)) {
2656 return NT_STATUS_INVALID_INFO_CLASS;
2659 *r->out.info = user_info;
2661 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2666 /*******************************************************************
2667 _samr_GetGroupsForUser
2668 ********************************************************************/
2670 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2671 struct samr_GetGroupsForUser *r)
2673 struct samu *sam_pass=NULL;
2676 struct samr_RidWithAttribute dom_gid;
2677 struct samr_RidWithAttribute *gids = NULL;
2678 uint32 primary_group_rid;
2679 size_t num_groups = 0;
2685 bool success = False;
2687 struct samr_RidWithAttributeArray *rids = NULL;
2690 * from the SID in the request:
2691 * we should send back the list of DOMAIN GROUPS
2692 * the user is a member of
2694 * and only the DOMAIN GROUPS
2695 * no ALIASES !!! neither aliases of the domain
2696 * nor aliases of the builtin SID
2701 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2703 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2705 return NT_STATUS_NO_MEMORY;
2708 /* find the policy handle. open a policy on it. */
2709 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2710 return NT_STATUS_INVALID_HANDLE;
2712 result = access_check_samr_function(acc_granted,
2713 SA_RIGHT_USER_GET_GROUPS,
2714 "_samr_GetGroupsForUser");
2715 if (!NT_STATUS_IS_OK(result)) {
2719 if (!sid_check_is_in_our_domain(&sid))
2720 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2722 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2723 return NT_STATUS_NO_MEMORY;
2727 ret = pdb_getsampwsid(sam_pass, &sid);
2731 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2732 sid_string_dbg(&sid)));
2733 return NT_STATUS_NO_SUCH_USER;
2738 /* make both calls inside the root block */
2740 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2741 &sids, &unix_gids, &num_groups);
2742 if ( NT_STATUS_IS_OK(result) ) {
2743 success = sid_peek_check_rid(get_global_sam_sid(),
2744 pdb_get_group_sid(sam_pass),
2745 &primary_group_rid);
2749 if (!NT_STATUS_IS_OK(result)) {
2750 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2751 sid_string_dbg(&sid)));
2756 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2757 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2758 pdb_get_username(sam_pass)));
2759 TALLOC_FREE(sam_pass);
2760 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2766 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2768 dom_gid.rid = primary_group_rid;
2769 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2771 for (i=0; i<num_groups; i++) {
2773 if (!sid_peek_check_rid(get_global_sam_sid(),
2774 &(sids[i]), &dom_gid.rid)) {
2775 DEBUG(10, ("Found sid %s not in our domain\n",
2776 sid_string_dbg(&sids[i])));
2780 if (dom_gid.rid == primary_group_rid) {
2781 /* We added the primary group directly from the
2782 * sam_account. The other SIDs are unique from
2783 * enum_group_memberships */
2787 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2790 rids->count = num_gids;
2793 *r->out.rids = rids;
2795 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2800 /*******************************************************************
2801 samr_QueryDomainInfo_internal
2802 ********************************************************************/
2804 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2806 struct policy_handle *handle,
2808 union samr_DomainInfo **dom_info_ptr)
2810 NTSTATUS status = NT_STATUS_OK;
2811 struct samr_info *info = NULL;
2812 union samr_DomainInfo *dom_info;
2813 uint32 min_pass_len,pass_hist,password_properties;
2814 time_t u_expire, u_min_age;
2815 NTTIME nt_expire, nt_min_age;
2817 time_t u_lock_duration, u_reset_time;
2818 NTTIME nt_lock_duration, nt_reset_time;
2823 uint32 account_policy_temp;
2828 uint32 num_users=0, num_groups=0, num_aliases=0;
2830 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2832 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2834 return NT_STATUS_NO_MEMORY;
2837 *dom_info_ptr = dom_info;
2839 /* find the policy handle. open a policy on it. */
2840 if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2841 return NT_STATUS_INVALID_HANDLE;
2851 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2852 min_pass_len = account_policy_temp;
2854 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2855 pass_hist = account_policy_temp;
2857 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2858 password_properties = account_policy_temp;
2860 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2861 u_expire = account_policy_temp;
2863 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2864 u_min_age = account_policy_temp;
2870 unix_to_nt_time_abs(&nt_expire, u_expire);
2871 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2873 init_samr_DomInfo1(&dom_info->info1,
2874 (uint16)min_pass_len,
2876 password_properties,
2886 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2887 num_groups = count_sam_groups(info->disp_info);
2888 num_aliases = count_sam_aliases(info->disp_info);
2890 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2891 u_logout = account_policy_temp;
2893 unix_to_nt_time_abs(&nt_logout, u_logout);
2895 if (!pdb_get_seq_num(&seq_num))
2896 seq_num = time(NULL);
2902 server_role = ROLE_DOMAIN_PDC;
2903 if (lp_server_role() == ROLE_DOMAIN_BDC)
2904 server_role = ROLE_DOMAIN_BDC;
2906 init_samr_DomInfo2(&dom_info->info2,
2927 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2928 u_logout = (time_t)ul;
2935 unix_to_nt_time_abs(&nt_logout, u_logout);
2937 init_samr_DomInfo3(&dom_info->info3,
2942 init_samr_DomInfo4(&dom_info->info4,
2946 init_samr_DomInfo5(&dom_info->info5,
2947 get_global_sam_name());
2950 /* NT returns its own name when a PDC. win2k and later
2951 * only the name of the PDC if itself is a BDC (samba4
2953 init_samr_DomInfo6(&dom_info->info6,
2957 server_role = ROLE_DOMAIN_PDC;
2958 if (lp_server_role() == ROLE_DOMAIN_BDC)
2959 server_role = ROLE_DOMAIN_BDC;
2961 init_samr_DomInfo7(&dom_info->info7,
2970 if (!pdb_get_seq_num(&seq_num)) {
2971 seq_num = time(NULL);
2978 init_samr_DomInfo8(&dom_info->info8,
2988 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2989 u_lock_duration = account_policy_temp;
2990 if (u_lock_duration != -1) {
2991 u_lock_duration *= 60;
2994 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2995 u_reset_time = account_policy_temp * 60;
2997 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2998 lockout = account_policy_temp;
3004 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3005 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3007 init_samr_DomInfo12(&dom_info->info12,
3013 return NT_STATUS_INVALID_INFO_CLASS;
3016 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
3021 /*******************************************************************
3022 _samr_QueryDomainInfo
3023 ********************************************************************/
3025 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3026 struct samr_QueryDomainInfo *r)
3028 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
3030 r->in.domain_handle,
3035 /* W2k3 seems to use the same check for all 3 objects that can be created via
3036 * SAMR, if you try to create for example "Dialup" as an alias it says
3037 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3040 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3042 enum lsa_SidType type;
3045 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3048 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3049 * whether the name already exists */
3050 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3051 NULL, NULL, NULL, &type);
3055 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3056 return NT_STATUS_OK;
3059 DEBUG(5, ("trying to create %s, exists as %s\n",
3060 new_name, sid_type_lookup(type)));
3062 if (type == SID_NAME_DOM_GRP) {
3063 return NT_STATUS_GROUP_EXISTS;
3065 if (type == SID_NAME_ALIAS) {
3066 return NT_STATUS_ALIAS_EXISTS;
3069 /* Yes, the default is NT_STATUS_USER_EXISTS */
3070 return NT_STATUS_USER_EXISTS;
3073 /*******************************************************************
3075 ********************************************************************/
3077 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3078 struct samr_CreateUser2 *r)
3080 const char *account = NULL;
3082 POLICY_HND dom_pol = *r->in.domain_handle;
3083 uint32_t acb_info = r->in.acct_flags;
3084 POLICY_HND *user_pol = r->out.user_handle;
3085 struct samr_info *info = NULL;
3090 /* check this, when giving away 'add computer to domain' privs */
3091 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3092 bool can_add_account = False;
3094 DISP_INFO *disp_info = NULL;
3096 /* Get the domain SID stored in the domain policy */
3097 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3099 return NT_STATUS_INVALID_HANDLE;
3101 nt_status = access_check_samr_function(acc_granted,
3102 SA_RIGHT_DOMAIN_CREATE_USER,
3103 "_samr_CreateUser2");
3104 if (!NT_STATUS_IS_OK(nt_status)) {
3108 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3109 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3110 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3111 this parameter is not an account type */
3112 return NT_STATUS_INVALID_PARAMETER;
3115 account = r->in.account_name->string;
3116 if (account == NULL) {
3117 return NT_STATUS_NO_MEMORY;
3120 nt_status = can_create(p->mem_ctx, account);
3121 if (!NT_STATUS_IS_OK(nt_status)) {
3125 /* determine which user right we need to check based on the acb_info */
3127 if ( acb_info & ACB_WSTRUST )
3129 se_priv_copy( &se_rights, &se_machine_account );
3130 can_add_account = user_has_privileges(
3131 p->pipe_user.nt_user_token, &se_rights );
3133 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3134 account for domain trusts and changes the ACB flags later */
3135 else if ( acb_info & ACB_NORMAL &&
3136 (account[strlen(account)-1] != '$') )
3138 se_priv_copy( &se_rights, &se_add_users );
3139 can_add_account = user_has_privileges(
3140 p->pipe_user.nt_user_token, &se_rights );
3142 else /* implicit assumption of a BDC or domain trust account here
3143 * (we already check the flags earlier) */
3145 if ( lp_enable_privileges() ) {
3146 /* only Domain Admins can add a BDC or domain trust */
3147 se_priv_copy( &se_rights, &se_priv_none );
3148 can_add_account = nt_token_check_domain_rid(
3149 p->pipe_user.nt_user_token,
3150 DOMAIN_GROUP_RID_ADMINS );
3154 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3155 uidtoname(p->pipe_user.ut.uid),
3156 can_add_account ? "True":"False" ));
3158 /********** BEGIN Admin BLOCK **********/
3160 if ( can_add_account )
3163 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3166 if ( can_add_account )
3169 /********** END Admin BLOCK **********/
3171 /* now check for failure */
3173 if ( !NT_STATUS_IS_OK(nt_status) )
3176 /* Get the user's SID */
3178 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3180 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3181 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3182 se_map_generic(&des_access, &usr_generic_mapping);
3184 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3185 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3186 &acc_granted, "_samr_CreateUser2");
3188 if ( !NT_STATUS_IS_OK(nt_status) ) {
3192 /* associate the user's SID with the new handle. */
3193 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3194 return NT_STATUS_NO_MEMORY;
3199 info->acc_granted = acc_granted;
3201 /* get a (unique) handle. open a policy on it. */
3202 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3203 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3206 /* After a "set" ensure we have no cached display info. */
3207 force_flush_samr_cache(info->disp_info);
3209 *r->out.access_granted = acc_granted;
3211 return NT_STATUS_OK;
3214 /*******************************************************************
3216 ********************************************************************/
3218 NTSTATUS _samr_Connect(pipes_struct *p,
3219 struct samr_Connect *r)
3221 struct samr_info *info = NULL;
3222 uint32 des_access = r->in.access_mask;
3226 if (!pipe_access_check(p)) {
3227 DEBUG(3, ("access denied to _samr_Connect\n"));
3228 return NT_STATUS_ACCESS_DENIED;
3231 /* set up the SAMR connect_anon response */
3233 /* associate the user's SID with the new handle. */
3234 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3235 return NT_STATUS_NO_MEMORY;
3237 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3238 was observed from a win98 client trying to enumerate users (when configured
3239 user level access control on shares) --jerry */
3241 if (des_access == MAXIMUM_ALLOWED_ACCESS) {
3242 /* Map to max possible knowing we're filtered below. */
3243 des_access = GENERIC_ALL_ACCESS;
3246 se_map_generic( &des_access, &sam_generic_mapping );
3247 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3249 /* get a (unique) handle. open a policy on it. */
3250 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3251 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3253 return NT_STATUS_OK;
3256 /*******************************************************************
3258 ********************************************************************/
3260 NTSTATUS _samr_Connect2(pipes_struct *p,
3261 struct samr_Connect2 *r)
3263 struct samr_info *info = NULL;
3264 SEC_DESC *psd = NULL;
3266 uint32 des_access = r->in.access_mask;
3271 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3275 if (!pipe_access_check(p)) {
3276 DEBUG(3, ("access denied to _samr_Connect2\n"));
3277 return NT_STATUS_ACCESS_DENIED;
3280 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3281 se_map_generic(&des_access, &sam_generic_mapping);
3283 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3284 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3286 if ( !NT_STATUS_IS_OK(nt_status) )
3289 /* associate the user's SID and access granted with the new handle. */
3290 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3291 return NT_STATUS_NO_MEMORY;
3293 info->acc_granted = acc_granted;
3294 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3296 /* get a (unique) handle. open a policy on it. */
3297 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3298 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3300 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3305 /*******************************************************************
3307 ********************************************************************/
3309 NTSTATUS _samr_Connect4(pipes_struct *p,
3310 struct samr_Connect4 *r)
3312 struct samr_info *info = NULL;
3313 SEC_DESC *psd = NULL;
3315 uint32 des_access = r->in.access_mask;
3320 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3324 if (!pipe_access_check(p)) {
3325 DEBUG(3, ("access denied to samr_Connect4\n"));
3326 return NT_STATUS_ACCESS_DENIED;
3329 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3330 se_map_generic(&des_access, &sam_generic_mapping);
3332 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3333 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3335 if ( !NT_STATUS_IS_OK(nt_status) )
3338 /* associate the user's SID and access granted with the new handle. */
3339 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3340 return NT_STATUS_NO_MEMORY;
3342 info->acc_granted = acc_granted;
3343 info->status = r->in.access_mask; /* ??? */
3345 /* get a (unique) handle. open a policy on it. */
3346 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3347 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3349 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3351 return NT_STATUS_OK;
3354 /*******************************************************************
3356 ********************************************************************/
3358 NTSTATUS _samr_Connect5(pipes_struct *p,
3359 struct samr_Connect5 *r)
3361 struct samr_info *info = NULL;
3362 SEC_DESC *psd = NULL;
3364 uint32 des_access = r->in.access_mask;
3367 struct samr_ConnectInfo1 info1;
3369 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3373 if (!pipe_access_check(p)) {
3374 DEBUG(3, ("access denied to samr_Connect5\n"));
3375 return NT_STATUS_ACCESS_DENIED;
3378 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3379 se_map_generic(&des_access, &sam_generic_mapping);
3381 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3382 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3384 if ( !NT_STATUS_IS_OK(nt_status) )
3387 /* associate the user's SID and access granted with the new handle. */
3388 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3389 return NT_STATUS_NO_MEMORY;
3391 info->acc_granted = acc_granted;
3392 info->status = r->in.access_mask; /* ??? */
3394 /* get a (unique) handle. open a policy on it. */
3395 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3396 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3398 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3400 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3403 *r->out.level_out = 1;
3404 r->out.info_out->info1 = info1;
3406 return NT_STATUS_OK;
3409 /**********************************************************************
3411 **********************************************************************/
3413 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3414 struct samr_LookupDomain *r)
3416 NTSTATUS status = NT_STATUS_OK;
3417 struct samr_info *info;
3418 const char *domain_name;
3419 DOM_SID *sid = NULL;
3421 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3422 return NT_STATUS_INVALID_HANDLE;
3424 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3425 Reverted that change so we will work with RAS servers again */
3427 status = access_check_samr_function(info->acc_granted,
3428 SA_RIGHT_SAM_OPEN_DOMAIN,
3429 "_samr_LookupDomain");
3430 if (!NT_STATUS_IS_OK(status)) {
3434 domain_name = r->in.domain_name->string;
3436 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3438 return NT_STATUS_NO_MEMORY;
3441 if (strequal(domain_name, builtin_domain_name())) {
3442 sid_copy(sid, &global_sid_Builtin);
3444 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3445 status = NT_STATUS_NO_SUCH_DOMAIN;
3449 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3450 sid_string_dbg(sid)));
3457 /**********************************************************************
3459 **********************************************************************/
3461 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3462 struct samr_EnumDomains *r)
3465 struct samr_info *info;
3466 uint32_t num_entries = 2;
3467 struct samr_SamEntry *entry_array = NULL;
3468 struct samr_SamArray *sam;
3470 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3471 return NT_STATUS_INVALID_HANDLE;
3473 status = access_check_samr_function(info->acc_granted,
3474 SA_RIGHT_SAM_ENUM_DOMAINS,
3475 "_samr_EnumDomains");
3476 if (!NT_STATUS_IS_OK(status)) {
3480 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3482 return NT_STATUS_NO_MEMORY;
3485 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3486 struct samr_SamEntry,
3489 return NT_STATUS_NO_MEMORY;
3492 entry_array[0].idx = 0;
3493 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3495 entry_array[1].idx = 1;
3496 init_lsa_String(&entry_array[1].name, "Builtin");
3498 sam->count = num_entries;
3499 sam->entries = entry_array;
3502 *r->out.num_entries = num_entries;
3507 /*******************************************************************
3509 ********************************************************************/
3511 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3512 struct samr_OpenAlias *r)
3515 POLICY_HND domain_pol = *r->in.domain_handle;
3516 uint32 alias_rid = r->in.rid;
3517 POLICY_HND *alias_pol = r->out.alias_handle;
3518 struct samr_info *info = NULL;
3519 SEC_DESC *psd = NULL;
3521 uint32 des_access = r->in.access_mask;
3526 /* find the domain policy and get the SID / access bits stored in the domain policy */
3528 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3529 return NT_STATUS_INVALID_HANDLE;
3531 status = access_check_samr_function(acc_granted,
3532 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3535 if ( !NT_STATUS_IS_OK(status) )
3538 /* append the alias' RID to it */
3540 if (!sid_append_rid(&sid, alias_rid))
3541 return NT_STATUS_NO_SUCH_ALIAS;
3543 /*check if access can be granted as requested by client. */
3545 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3546 se_map_generic(&des_access,&ali_generic_mapping);
3548 se_priv_copy( &se_rights, &se_add_users );
3551 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3552 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3553 &acc_granted, "_samr_OpenAlias");
3555 if ( !NT_STATUS_IS_OK(status) )
3559 /* Check we actually have the requested alias */
3560 enum lsa_SidType type;
3565 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3568 if (!result || (type != SID_NAME_ALIAS)) {
3569 return NT_STATUS_NO_SUCH_ALIAS;
3572 /* make sure there is a mapping */
3574 if ( !sid_to_gid( &sid, &gid ) ) {
3575 return NT_STATUS_NO_SUCH_ALIAS;
3580 /* associate the alias SID with the new handle. */
3581 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3582 return NT_STATUS_NO_MEMORY;
3584 info->acc_granted = acc_granted;
3586 /* get a (unique) handle. open a policy on it. */
3587 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3588 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3590 return NT_STATUS_OK;
3593 /*******************************************************************
3595 ********************************************************************/
3597 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3598 struct samr_UserInfo7 *id7,
3604 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3606 return NT_STATUS_ACCESS_DENIED;
3609 if (!id7->account_name.string) {
3610 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3612 return NT_STATUS_ACCESS_DENIED;
3615 /* check to see if the new username already exists. Note: we can't
3616 reliably lock all backends, so there is potentially the
3617 possibility that a user can be created in between this check and
3618 the rename. The rename should fail, but may not get the
3619 exact same failure status code. I think this is small enough
3620 of a window for this type of operation and the results are
3621 simply that the rename fails with a slightly different status
3622 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3624 rc = can_create(mem_ctx, id7->account_name.string);
3625 if (!NT_STATUS_IS_OK(rc)) {
3629 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3635 /*******************************************************************
3637 ********************************************************************/
3639 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3643 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3648 /* FIX ME: check if the value is really changed --metze */
3649 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3654 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3664 /*******************************************************************
3666 ********************************************************************/
3668 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3672 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3677 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3681 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3685 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3690 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3699 /*******************************************************************
3701 ********************************************************************/
3703 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3707 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3711 copy_id20_to_sam_passwd(pwd, id20);
3713 /* write the change out */
3714 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3724 /*******************************************************************
3726 ********************************************************************/
3728 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3729 struct samr_UserInfo21 *id21,
3735 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3736 return NT_STATUS_INVALID_PARAMETER;
3739 /* we need to separately check for an account rename first */
3741 if (id21->account_name.string &&
3742 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3745 /* check to see if the new username already exists. Note: we can't
3746 reliably lock all backends, so there is potentially the
3747 possibility that a user can be created in between this check and
3748 the rename. The rename should fail, but may not get the
3749 exact same failure status code. I think this is small enough
3750 of a window for this type of operation and the results are
3751 simply that the rename fails with a slightly different status
3752 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3754 status = can_create(mem_ctx, id21->account_name.string);
3755 if (!NT_STATUS_IS_OK(status)) {
3759 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3761 if (!NT_STATUS_IS_OK(status)) {
3762 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3763 nt_errstr(status)));
3768 /* set the new username so that later
3769 functions can work on the new account */
3770 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3773 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3776 * The funny part about the previous two calls is
3777 * that pwd still has the password hashes from the
3778 * passdb entry. These have not been updated from
3779 * id21. I don't know if they need to be set. --jerry
3782 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3783 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3784 if ( !NT_STATUS_IS_OK(status) ) {
3789 /* Don't worry about writing out the user account since the
3790 primary group SID is generated solely from the user's Unix
3793 /* write the change out */
3794 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3801 return NT_STATUS_OK;
3804 /*******************************************************************
3806 ********************************************************************/
3808 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3809 struct samr_UserInfo23 *id23,
3812 char *plaintext_buf = NULL;
3818 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3819 return NT_STATUS_INVALID_PARAMETER;
3822 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3823 pdb_get_username(pwd)));
3825 acct_ctrl = pdb_get_acct_ctrl(pwd);
3827 if (!decode_pw_buffer(mem_ctx,
3828 id23->password.data,
3833 return NT_STATUS_INVALID_PARAMETER;
3836 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3838 return NT_STATUS_ACCESS_DENIED;
3841 copy_id23_to_sam_passwd(pwd, id23);
3843 /* if it's a trust account, don't update /etc/passwd */
3844 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3845 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3846 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3847 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3849 /* update the UNIX password */
3850 if (lp_unix_password_sync() ) {
3851 struct passwd *passwd;
3852 if (pdb_get_username(pwd) == NULL) {
3853 DEBUG(1, ("chgpasswd: User without name???\n"));
3855 return NT_STATUS_ACCESS_DENIED;
3858 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3859 if (passwd == NULL) {
3860 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3863 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3865 return NT_STATUS_ACCESS_DENIED;
3867 TALLOC_FREE(passwd);
3871 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3873 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3874 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3880 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3887 return NT_STATUS_OK;
3890 /*******************************************************************
3892 ********************************************************************/
3894 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
3898 char *plaintext_buf = NULL;
3900 time_t last_set_time;
3901 enum pdb_value_state last_set_state;
3903 DEBUG(5, ("Attempting administrator password change for user %s\n",
3904 pdb_get_username(pwd)));
3906 acct_ctrl = pdb_get_acct_ctrl(pwd);
3907 /* we need to know if it's expired, because this is an admin change, not a
3908 user change, so it's still expired when we're done */
3909 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3910 last_set_time = pdb_get_pass_last_set_time(pwd);
3912 if (!decode_pw_buffer(talloc_tos(),
3921 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3926 /* if it's a trust account, don't update /etc/passwd */
3927 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3928 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3929 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3930 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3932 /* update the UNIX password */
3933 if (lp_unix_password_sync()) {
3934 struct passwd *passwd;
3936 if (pdb_get_username(pwd) == NULL) {
3937 DEBUG(1, ("chgpasswd: User without name???\n"));
3942 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3943 if (passwd == NULL) {
3944 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3947 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3951 TALLOC_FREE(passwd);
3955 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3958 * A level 25 change does reset the pwdlastset field, a level 24
3959 * change does not. I know this is probably not the full story, but
3960 * it is needed to make XP join LDAP correctly, without it the later
3961 * auth2 check can fail with PWD_MUST_CHANGE.
3965 * restore last set time as this is an admin change, not a
3968 pdb_set_pass_last_set_time (pwd, last_set_time,
3972 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3974 /* update the SAMBA password */
3975 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3985 /*******************************************************************
3987 ********************************************************************/
3989 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
3990 struct samr_UserInfo25 *id25,
3996 DEBUG(5, ("set_user_info_25: NULL id25\n"));
3997 return NT_STATUS_INVALID_PARAMETER;
4000 copy_id25_to_sam_passwd(pwd, id25);
4002 /* write the change out */
4003 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4009 * We need to "pdb_update_sam_account" before the unix primary group
4010 * is set, because the idealx scripts would also change the
4011 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4012 * the delete explicit / add explicit, which would then fail to find
4013 * the previous primaryGroupSid value.
4016 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4017 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4018 if ( !NT_STATUS_IS_OK(status) ) {
4023 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
4026 return NT_STATUS_OK;
4029 /*******************************************************************
4030 samr_SetUserInfo_internal
4031 ********************************************************************/
4033 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
4035 struct policy_handle *user_handle,
4037 union samr_UserInfo *info)
4040 struct samu *pwd = NULL;
4042 POLICY_HND *pol = user_handle;
4043 uint16_t switch_value = level;
4044 uint32_t acc_granted;
4045 uint32_t acc_required;
4047 bool has_enough_rights = False;
4049 DISP_INFO *disp_info = NULL;
4051 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4053 /* find the policy handle. open a policy on it. */
4054 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4055 return NT_STATUS_INVALID_HANDLE;
4058 /* This is tricky. A WinXP domain join sets
4059 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4060 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4061 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4062 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4063 we'll use the set from the WinXP join as the basis. */
4065 switch (switch_value) {
4070 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4073 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4074 SA_RIGHT_USER_SET_ATTRIBUTES |
4075 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4079 status = access_check_samr_function(acc_granted,
4082 if (!NT_STATUS_IS_OK(status)) {
4086 DEBUG(5, ("%s: sid:%s, level:%d\n",
4087 fn_name, sid_string_dbg(&sid), switch_value));
4090 DEBUG(5, ("%s: NULL info level\n", fn_name));
4091 return NT_STATUS_INVALID_INFO_CLASS;
4094 if (!(pwd = samu_new(NULL))) {
4095 return NT_STATUS_NO_MEMORY;
4099 ret = pdb_getsampwsid(pwd, &sid);
4104 return NT_STATUS_NO_SUCH_USER;
4107 /* deal with machine password changes differently from userinfo changes */
4108 /* check to see if we have the sufficient rights */
4110 acb_info = pdb_get_acct_ctrl(pwd);
4111 if (acb_info & ACB_WSTRUST)
4112 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4113 &se_machine_account);
4114 else if (acb_info & ACB_NORMAL)
4115 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4117 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4118 if (lp_enable_privileges()) {
4119 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4120 DOMAIN_GROUP_RID_ADMINS);
4124 DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4126 uidtoname(p->pipe_user.ut.uid),
4127 has_enough_rights ? "" : " not"));
4129 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4131 if (has_enough_rights) {
4135 /* ok! user info levels (lots: see MSDEV help), off we go... */
4137 switch (switch_value) {
4140 status = set_user_info_7(p->mem_ctx,
4145 if (!set_user_info_16(&info->info16, pwd)) {
4146 status = NT_STATUS_ACCESS_DENIED;
4151 /* Used by AS/U JRA. */
4152 if (!set_user_info_18(&info->info18, pwd)) {
4153 status = NT_STATUS_ACCESS_DENIED;
4158 if (!set_user_info_20(&info->info20, pwd)) {
4159 status = NT_STATUS_ACCESS_DENIED;
4164 status = set_user_info_21(p->mem_ctx,
4165 &info->info21, pwd);
4169 if (!p->session_key.length) {
4170 status = NT_STATUS_NO_USER_SESSION_KEY;
4172 SamOEMhashBlob(info->info23.password.data, 516,
4175 dump_data(100, info->info23.password.data, 516);
4177 status = set_user_info_23(p->mem_ctx,
4178 &info->info23, pwd);
4182 if (!p->session_key.length) {
4183 status = NT_STATUS_NO_USER_SESSION_KEY;
4185 SamOEMhashBlob(info->info24.password.data,
4189 dump_data(100, info->info24.password.data, 516);
4191 if (!set_user_info_pw(info->info24.password.data, pwd,
4193 status = NT_STATUS_ACCESS_DENIED;
4198 if (!p->session_key.length) {
4199 status = NT_STATUS_NO_USER_SESSION_KEY;
4201 encode_or_decode_arc4_passwd_buffer(info->info25.password.data,
4204 dump_data(100, info->info25.password.data, 532);
4206 status = set_user_info_25(p->mem_ctx,
4207 &info->info25, pwd);
4208 if (!NT_STATUS_IS_OK(status)) {
4211 if (!set_user_info_pw(info->info25.password.data, pwd,
4213 status = NT_STATUS_ACCESS_DENIED;
4218 if (!p->session_key.length) {
4219 status = NT_STATUS_NO_USER_SESSION_KEY;
4221 encode_or_decode_arc4_passwd_buffer(info->info26.password.data,
4224 dump_data(100, info->info26.password.data, 516);
4226 if (!set_user_info_pw(info->info26.password.data, pwd,
4228 status = NT_STATUS_ACCESS_DENIED;
4233 status = NT_STATUS_INVALID_INFO_CLASS;
4238 if (has_enough_rights) {
4242 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4244 if (NT_STATUS_IS_OK(status)) {
4245 force_flush_samr_cache(disp_info);
4251 /*******************************************************************
4253 ********************************************************************/
4255 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4256 struct samr_SetUserInfo *r)
4258 return samr_SetUserInfo_internal("_samr_SetUserInfo",
4265 /*******************************************************************
4267 ********************************************************************/
4269 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4270 struct samr_SetUserInfo2 *r)
4272 return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4279 /*********************************************************************
4280 _samr_GetAliasMembership
4281 *********************************************************************/
4283 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4284 struct samr_GetAliasMembership *r)
4286 size_t num_alias_rids;
4288 struct samr_info *info = NULL;
4296 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4298 /* find the policy handle. open a policy on it. */
4299 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4300 return NT_STATUS_INVALID_HANDLE;
4302 ntstatus1 = access_check_samr_function(info->acc_granted,
4303 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4304 "_samr_GetAliasMembership");
4305 ntstatus2 = access_check_samr_function(info->acc_granted,
4306 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4307 "_samr_GetAliasMembership");
4309 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4310 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4311 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4312 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4316 if (!sid_check_is_domain(&info->sid) &&
4317 !sid_check_is_builtin(&info->sid))
4318 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4320 if (r->in.sids->num_sids) {
4321 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4323 if (members == NULL)
4324 return NT_STATUS_NO_MEMORY;
4329 for (i=0; i<r->in.sids->num_sids; i++)
4330 sid_copy(&members[i], r->in.sids->sids[i].sid);
4336 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4337 r->in.sids->num_sids,
4338 &alias_rids, &num_alias_rids);
4341 if (!NT_STATUS_IS_OK(ntstatus1)) {
4345 r->out.rids->count = num_alias_rids;
4346 r->out.rids->ids = alias_rids;
4348 return NT_STATUS_OK;
4351 /*********************************************************************
4352 _samr_GetMembersInAlias
4353 *********************************************************************/
4355 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4356 struct samr_GetMembersInAlias *r)
4360 size_t num_sids = 0;
4361 struct lsa_SidPtr *sids = NULL;
4362 DOM_SID *pdb_sids = NULL;
4368 /* find the policy handle. open a policy on it. */
4369 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4370 return NT_STATUS_INVALID_HANDLE;
4372 status = access_check_samr_function(acc_granted,
4373 SA_RIGHT_ALIAS_GET_MEMBERS,
4374 "_samr_GetMembersInAlias");
4375 if (!NT_STATUS_IS_OK(status)) {
4379 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4382 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4385 if (!NT_STATUS_IS_OK(status)) {
4390 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4392 TALLOC_FREE(pdb_sids);
4393 return NT_STATUS_NO_MEMORY;
4397 for (i = 0; i < num_sids; i++) {
4398 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4400 TALLOC_FREE(pdb_sids);
4401 return NT_STATUS_NO_MEMORY;
4405 r->out.sids->num_sids = num_sids;
4406 r->out.sids->sids = sids;
4408 TALLOC_FREE(pdb_sids);
4410 return NT_STATUS_OK;
4413 /*********************************************************************
4414 _samr_QueryGroupMember
4415 *********************************************************************/
4417 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4418 struct samr_QueryGroupMember *r)
4421 size_t i, num_members;
4429 struct samr_RidTypeArray *rids = NULL;
4431 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4433 return NT_STATUS_NO_MEMORY;
4436 /* find the policy handle. open a policy on it. */
4437 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4438 return NT_STATUS_INVALID_HANDLE;
4440 status = access_check_samr_function(acc_granted,
4441 SA_RIGHT_GROUP_GET_MEMBERS,
4442 "_samr_QueryGroupMember");
4443 if (!NT_STATUS_IS_OK(status)) {
4447 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4449 if (!sid_check_is_in_our_domain(&group_sid)) {
4450 DEBUG(3, ("sid %s is not in our domain\n",
4451 sid_string_dbg(&group_sid)));
4452 return NT_STATUS_NO_SUCH_GROUP;
4455 DEBUG(10, ("lookup on Domain SID\n"));
4458 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4459 &rid, &num_members);
4462 if (!NT_STATUS_IS_OK(status))
4466 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4468 return NT_STATUS_NO_MEMORY;
4474 for (i=0; i<num_members; i++)
4475 attr[i] = SID_NAME_USER;
4477 rids->count = num_members;
4481 *r->out.rids = rids;
4483 return NT_STATUS_OK;
4486 /*********************************************************************
4487 _samr_AddAliasMember
4488 *********************************************************************/
4490 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4491 struct samr_AddAliasMember *r)
4496 bool can_add_accounts;
4498 DISP_INFO *disp_info = NULL;
4500 /* Find the policy handle. Open a policy on it. */
4501 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4502 return NT_STATUS_INVALID_HANDLE;
4504 status = access_check_samr_function(acc_granted,
4505 SA_RIGHT_ALIAS_ADD_MEMBER,
4506 "_samr_AddAliasMember");
4507 if (!NT_STATUS_IS_OK(status)) {
4511 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4513 se_priv_copy( &se_rights, &se_add_users );
4514 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4516 /******** BEGIN SeAddUsers BLOCK *********/
4518 if ( can_add_accounts )
4521 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4523 if ( can_add_accounts )
4526 /******** END SeAddUsers BLOCK *********/
4528 if (NT_STATUS_IS_OK(status)) {
4529 force_flush_samr_cache(disp_info);
4535 /*********************************************************************
4536 _samr_DeleteAliasMember
4537 *********************************************************************/
4539 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4540 struct samr_DeleteAliasMember *r)
4545 bool can_add_accounts;
4547 DISP_INFO *disp_info = NULL;
4549 /* Find the policy handle. Open a policy on it. */
4550 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4551 return NT_STATUS_INVALID_HANDLE;
4553 status = access_check_samr_function(acc_granted,
4554 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4555 "_samr_DeleteAliasMember");
4556 if (!NT_STATUS_IS_OK(status)) {
4560 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4561 sid_string_dbg(&alias_sid)));
4563 se_priv_copy( &se_rights, &se_add_users );
4564 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4566 /******** BEGIN SeAddUsers BLOCK *********/
4568 if ( can_add_accounts )
4571 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4573 if ( can_add_accounts )
4576 /******** END SeAddUsers BLOCK *********/
4578 if (NT_STATUS_IS_OK(status)) {
4579 force_flush_samr_cache(disp_info);
4585 /*********************************************************************
4586 _samr_AddGroupMember
4587 *********************************************************************/
4589 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4590 struct samr_AddGroupMember *r)
4597 bool can_add_accounts;
4598 DISP_INFO *disp_info = NULL;
4600 /* Find the policy handle. Open a policy on it. */
4601 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4602 return NT_STATUS_INVALID_HANDLE;
4604 status = access_check_samr_function(acc_granted,
4605 SA_RIGHT_GROUP_ADD_MEMBER,
4606 "_samr_AddGroupMember");
4607 if (!NT_STATUS_IS_OK(status)) {
4611 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4613 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4615 return NT_STATUS_INVALID_HANDLE;
4618 se_priv_copy( &se_rights, &se_add_users );
4619 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4621 /******** BEGIN SeAddUsers BLOCK *********/
4623 if ( can_add_accounts )
4626 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4628 if ( can_add_accounts )
4631 /******** END SeAddUsers BLOCK *********/
4633 force_flush_samr_cache(disp_info);
4638 /*********************************************************************
4639 _samr_DeleteGroupMember
4640 *********************************************************************/
4642 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4643 struct samr_DeleteGroupMember *r)
4651 bool can_add_accounts;
4652 DISP_INFO *disp_info = NULL;
4655 * delete the group member named r->in.rid
4656 * who is a member of the sid associated with the handle
4657 * the rid is a user's rid as the group is a domain group.
4660 /* Find the policy handle. Open a policy on it. */
4661 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4662 return NT_STATUS_INVALID_HANDLE;
4664 status = access_check_samr_function(acc_granted,
4665 SA_RIGHT_GROUP_REMOVE_MEMBER,
4666 "_samr_DeleteGroupMember");
4667 if (!NT_STATUS_IS_OK(status)) {
4671 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4673 return NT_STATUS_INVALID_HANDLE;
4676 se_priv_copy( &se_rights, &se_add_users );
4677 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4679 /******** BEGIN SeAddUsers BLOCK *********/
4681 if ( can_add_accounts )
4684 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4686 if ( can_add_accounts )
4689 /******** END SeAddUsers BLOCK *********/
4691 force_flush_samr_cache(disp_info);
4696 /*********************************************************************
4698 *********************************************************************/
4700 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4701 struct samr_DeleteUser *r)
4705 struct samu *sam_pass=NULL;
4707 bool can_add_accounts;
4709 DISP_INFO *disp_info = NULL;
4712 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4714 /* Find the policy handle. Open a policy on it. */
4715 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4716 return NT_STATUS_INVALID_HANDLE;
4718 status = access_check_samr_function(acc_granted,
4719 STD_RIGHT_DELETE_ACCESS,
4720 "_samr_DeleteUser");
4721 if (!NT_STATUS_IS_OK(status)) {
4725 if (!sid_check_is_in_our_domain(&user_sid))
4726 return NT_STATUS_CANNOT_DELETE;
4728 /* check if the user exists before trying to delete */
4729 if ( !(sam_pass = samu_new( NULL )) ) {
4730 return NT_STATUS_NO_MEMORY;
4734 ret = pdb_getsampwsid(sam_pass, &user_sid);
4738 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4739 sid_string_dbg(&user_sid)));
4740 TALLOC_FREE(sam_pass);
4741 return NT_STATUS_NO_SUCH_USER;
4744 acb_info = pdb_get_acct_ctrl(sam_pass);
4746 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4747 if ( acb_info & ACB_WSTRUST ) {
4748 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4750 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4753 /******** BEGIN SeAddUsers BLOCK *********/
4755 if ( can_add_accounts )
4758 status = pdb_delete_user(p->mem_ctx, sam_pass);
4760 if ( can_add_accounts )
4763 /******** END SeAddUsers BLOCK *********/
4765 if ( !NT_STATUS_IS_OK(status) ) {
4766 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4767 "user %s: %s.\n", pdb_get_username(sam_pass),
4768 nt_errstr(status)));
4769 TALLOC_FREE(sam_pass);
4774 TALLOC_FREE(sam_pass);
4776 if (!close_policy_hnd(p, r->in.user_handle))
4777 return NT_STATUS_OBJECT_NAME_INVALID;
4779 force_flush_samr_cache(disp_info);
4781 return NT_STATUS_OK;
4784 /*********************************************************************
4785 _samr_DeleteDomainGroup
4786 *********************************************************************/
4788 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4789 struct samr_DeleteDomainGroup *r)
4796 bool can_add_accounts;
4797 DISP_INFO *disp_info = NULL;
4799 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4801 /* Find the policy handle. Open a policy on it. */
4802 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4803 return NT_STATUS_INVALID_HANDLE;
4805 status = access_check_samr_function(acc_granted,
4806 STD_RIGHT_DELETE_ACCESS,
4807 "_samr_DeleteDomainGroup");
4808 if (!NT_STATUS_IS_OK(status)) {
4812 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4814 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4816 return NT_STATUS_NO_SUCH_GROUP;
4819 se_priv_copy( &se_rights, &se_add_users );
4820 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4822 /******** BEGIN SeAddUsers BLOCK *********/
4824 if ( can_add_accounts )
4827 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4829 if ( can_add_accounts )
4832 /******** END SeAddUsers BLOCK *********/
4834 if ( !NT_STATUS_IS_OK(status) ) {
4835 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4836 "entry for group %s: %s\n",
4837 sid_string_dbg(&group_sid),
4838 nt_errstr(status)));
4842 if (!close_policy_hnd(p, r->in.group_handle))
4843 return NT_STATUS_OBJECT_NAME_INVALID;
4845 force_flush_samr_cache(disp_info);
4847 return NT_STATUS_OK;
4850 /*********************************************************************
4851 _samr_DeleteDomAlias
4852 *********************************************************************/
4854 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4855 struct samr_DeleteDomAlias *r)
4860 bool can_add_accounts;
4862 DISP_INFO *disp_info = NULL;
4864 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4866 /* Find the policy handle. Open a policy on it. */
4867 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4868 return NT_STATUS_INVALID_HANDLE;
4870 /* copy the handle to the outgoing reply */
4872 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4874 status = access_check_samr_function(acc_granted,
4875 STD_RIGHT_DELETE_ACCESS,
4876 "_samr_DeleteDomAlias");
4877 if (!NT_STATUS_IS_OK(status)) {
4881 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4883 /* Don't let Windows delete builtin groups */
4885 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4886 return NT_STATUS_SPECIAL_ACCOUNT;
4889 if (!sid_check_is_in_our_domain(&alias_sid))
4890 return NT_STATUS_NO_SUCH_ALIAS;
4892 DEBUG(10, ("lookup on Local SID\n"));
4894 se_priv_copy( &se_rights, &se_add_users );
4895 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4897 /******** BEGIN SeAddUsers BLOCK *********/
4899 if ( can_add_accounts )
4902 /* Have passdb delete the alias */
4903 status = pdb_delete_alias(&alias_sid);
4905 if ( can_add_accounts )
4908 /******** END SeAddUsers BLOCK *********/
4910 if ( !NT_STATUS_IS_OK(status))
4913 if (!close_policy_hnd(p, r->in.alias_handle))
4914 return NT_STATUS_OBJECT_NAME_INVALID;
4916 force_flush_samr_cache(disp_info);
4918 return NT_STATUS_OK;
4921 /*********************************************************************
4922 _samr_CreateDomainGroup
4923 *********************************************************************/
4925 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4926 struct samr_CreateDomainGroup *r)
4933 struct samr_info *info;
4936 bool can_add_accounts;
4937 DISP_INFO *disp_info = NULL;
4939 /* Find the policy handle. Open a policy on it. */
4940 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4941 return NT_STATUS_INVALID_HANDLE;
4943 status = access_check_samr_function(acc_granted,
4944 SA_RIGHT_DOMAIN_CREATE_GROUP,
4945 "_samr_CreateDomainGroup");
4946 if (!NT_STATUS_IS_OK(status)) {
4950 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4951 return NT_STATUS_ACCESS_DENIED;
4953 name = r->in.name->string;
4955 return NT_STATUS_NO_MEMORY;
4958 status = can_create(p->mem_ctx, name);
4959 if (!NT_STATUS_IS_OK(status)) {
4963 se_priv_copy( &se_rights, &se_add_users );
4964 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4966 /******** BEGIN SeAddUsers BLOCK *********/
4968 if ( can_add_accounts )
4971 /* check that we successfully create the UNIX group */
4973 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
4975 if ( can_add_accounts )
4978 /******** END SeAddUsers BLOCK *********/
4980 /* check if we should bail out here */
4982 if ( !NT_STATUS_IS_OK(status) )
4985 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
4987 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4988 return NT_STATUS_NO_MEMORY;
4990 /* they created it; let the user do what he wants with it */
4992 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
4994 /* get a (unique) handle. open a policy on it. */
4995 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
4996 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4998 force_flush_samr_cache(disp_info);
5000 return NT_STATUS_OK;
5003 /*********************************************************************
5004 _samr_CreateDomAlias
5005 *********************************************************************/
5007 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5008 struct samr_CreateDomAlias *r)
5012 const char *name = NULL;
5013 struct samr_info *info;
5018 bool can_add_accounts;
5019 DISP_INFO *disp_info = NULL;
5021 /* Find the policy handle. Open a policy on it. */
5022 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5023 return NT_STATUS_INVALID_HANDLE;
5025 result = access_check_samr_function(acc_granted,
5026 SA_RIGHT_DOMAIN_CREATE_ALIAS,
5027 "_samr_CreateDomAlias");
5028 if (!NT_STATUS_IS_OK(result)) {
5032 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5033 return NT_STATUS_ACCESS_DENIED;
5035 name = r->in.alias_name->string;
5037 se_priv_copy( &se_rights, &se_add_users );
5038 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5040 result = can_create(p->mem_ctx, name);
5041 if (!NT_STATUS_IS_OK(result)) {
5045 /******** BEGIN SeAddUsers BLOCK *********/
5047 if ( can_add_accounts )
5050 /* Have passdb create the alias */
5051 result = pdb_create_alias(name, r->out.rid);
5053 if ( can_add_accounts )
5056 /******** END SeAddUsers BLOCK *********/
5058 if (!NT_STATUS_IS_OK(result)) {
5059 DEBUG(10, ("pdb_create_alias failed: %s\n",
5060 nt_errstr(result)));
5064 sid_copy(&info_sid, get_global_sam_sid());
5065 sid_append_rid(&info_sid, *r->out.rid);
5067 if (!sid_to_gid(&info_sid, &gid)) {
5068 DEBUG(10, ("Could not find alias just created\n"));
5069 return NT_STATUS_ACCESS_DENIED;
5072 /* check if the group has been successfully created */
5073 if ( getgrgid(gid) == NULL ) {
5074 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5076 return NT_STATUS_ACCESS_DENIED;
5079 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5080 return NT_STATUS_NO_MEMORY;
5082 /* they created it; let the user do what he wants with it */
5084 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5086 /* get a (unique) handle. open a policy on it. */
5087 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5088 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5090 force_flush_samr_cache(disp_info);
5092 return NT_STATUS_OK;
5095 /*********************************************************************
5096 _samr_QueryGroupInfo
5097 *********************************************************************/
5099 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5100 struct samr_QueryGroupInfo *r)
5105 union samr_GroupInfo *info = NULL;
5108 uint32_t attributes = SE_GROUP_MANDATORY |
5109 SE_GROUP_ENABLED_BY_DEFAULT |
5111 const char *group_name = NULL;
5112 const char *group_description = NULL;
5114 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5115 return NT_STATUS_INVALID_HANDLE;
5117 status = access_check_samr_function(acc_granted,
5118 SA_RIGHT_GROUP_LOOKUP_INFO,
5119 "_samr_QueryGroupInfo");
5120 if (!NT_STATUS_IS_OK(status)) {
5125 ret = get_domain_group_from_sid(group_sid, &map);
5128 return NT_STATUS_INVALID_HANDLE;
5130 /* FIXME: map contains fstrings */
5131 group_name = talloc_strdup(r, map.nt_name);
5132 group_description = talloc_strdup(r, map.comment);
5134 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5136 return NT_STATUS_NO_MEMORY;
5139 switch (r->in.level) {
5145 status = pdb_enum_group_members(
5146 p->mem_ctx, &group_sid, &members, &num_members);
5149 if (!NT_STATUS_IS_OK(status)) {
5153 init_samr_group_info1(&info->all,
5161 init_samr_group_info2(&info->name,
5165 init_samr_group_info3(&info->attributes,
5169 init_samr_group_info4(&info->description,
5180 status = pdb_enum_group_members(
5181 p->mem_ctx, &group_sid, &members, &num_members);
5184 if (!NT_STATUS_IS_OK(status)) {
5188 init_samr_group_info5(&info->all2,
5191 0, /* num_members - in w2k3 this is always 0 */
5197 return NT_STATUS_INVALID_INFO_CLASS;
5200 *r->out.info = info;
5202 return NT_STATUS_OK;
5205 /*********************************************************************
5207 *********************************************************************/
5209 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5210 struct samr_SetGroupInfo *r)
5217 bool can_mod_accounts;
5218 DISP_INFO *disp_info = NULL;
5220 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5221 return NT_STATUS_INVALID_HANDLE;
5223 status = access_check_samr_function(acc_granted,
5224 SA_RIGHT_GROUP_SET_INFO,
5225 "_samr_SetGroupInfo");
5226 if (!NT_STATUS_IS_OK(status)) {
5231 ret = get_domain_group_from_sid(group_sid, &map);
5234 return NT_STATUS_NO_SUCH_GROUP;
5236 switch (r->in.level) {
5238 fstrcpy(map.comment, r->in.info->all.description.string);
5241 fstrcpy(map.comment, r->in.info->description.string);
5244 return NT_STATUS_INVALID_INFO_CLASS;
5247 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5249 /******** BEGIN SeAddUsers BLOCK *********/
5251 if ( can_mod_accounts )
5254 status = pdb_update_group_mapping_entry(&map);
5256 if ( can_mod_accounts )
5259 /******** End SeAddUsers BLOCK *********/
5261 if (NT_STATUS_IS_OK(status)) {
5262 force_flush_samr_cache(disp_info);
5268 /*********************************************************************
5270 *********************************************************************/
5272 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5273 struct samr_SetAliasInfo *r)
5276 struct acct_info info;
5278 bool can_mod_accounts;
5280 DISP_INFO *disp_info = NULL;
5282 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5283 return NT_STATUS_INVALID_HANDLE;
5285 status = access_check_samr_function(acc_granted,
5286 SA_RIGHT_ALIAS_SET_INFO,
5287 "_samr_SetAliasInfo");
5288 if (!NT_STATUS_IS_OK(status)) {
5292 /* get the current group information */
5295 status = pdb_get_aliasinfo( &group_sid, &info );
5298 if ( !NT_STATUS_IS_OK(status))
5301 switch (r->in.level) {
5306 /* We currently do not support renaming groups in the
5307 the BUILTIN domain. Refer to util_builtin.c to understand
5308 why. The eventually needs to be fixed to be like Windows
5309 where you can rename builtin groups, just not delete them */
5311 if ( sid_check_is_in_builtin( &group_sid ) ) {
5312 return NT_STATUS_SPECIAL_ACCOUNT;
5315 /* There has to be a valid name (and it has to be different) */
5317 if ( !r->in.info->name.string )
5318 return NT_STATUS_INVALID_PARAMETER;
5320 /* If the name is the same just reply "ok". Yes this
5321 doesn't allow you to change the case of a group name. */
5323 if ( strequal( r->in.info->name.string, info.acct_name ) )
5324 return NT_STATUS_OK;
5326 fstrcpy( info.acct_name, r->in.info->name.string);
5328 /* make sure the name doesn't already exist as a user
5331 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5332 status = can_create( p->mem_ctx, group_name );
5333 if ( !NT_STATUS_IS_OK( status ) )
5337 case ALIASINFODESCRIPTION:
5338 if (r->in.info->description.string) {
5339 fstrcpy(info.acct_desc,
5340 r->in.info->description.string);
5342 fstrcpy( info.acct_desc, "" );
5346 return NT_STATUS_INVALID_INFO_CLASS;
5349 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5351 /******** BEGIN SeAddUsers BLOCK *********/
5353 if ( can_mod_accounts )
5356 status = pdb_set_aliasinfo( &group_sid, &info );
5358 if ( can_mod_accounts )
5361 /******** End SeAddUsers BLOCK *********/
5363 if (NT_STATUS_IS_OK(status))
5364 force_flush_samr_cache(disp_info);
5369 /****************************************************************
5371 ****************************************************************/
5373 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5374 struct samr_GetDomPwInfo *r)
5376 /* Perform access check. Since this rpc does not require a
5377 policy handle it will not be caught by the access checks on
5378 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5380 if (!pipe_access_check(p)) {
5381 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5382 return NT_STATUS_ACCESS_DENIED;
5385 /* Actually, returning zeros here works quite well :-). */
5386 ZERO_STRUCTP(r->out.info);
5388 return NT_STATUS_OK;
5391 /*********************************************************************
5393 *********************************************************************/
5395 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5396 struct samr_OpenGroup *r)
5402 struct samr_info *info;
5403 SEC_DESC *psd = NULL;
5405 uint32 des_access = r->in.access_mask;
5412 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5413 return NT_STATUS_INVALID_HANDLE;
5415 status = access_check_samr_function(acc_granted,
5416 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5419 if ( !NT_STATUS_IS_OK(status) )
5422 /*check if access can be granted as requested by client. */
5423 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5424 se_map_generic(&des_access,&grp_generic_mapping);
5426 se_priv_copy( &se_rights, &se_add_users );
5428 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5429 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5430 &acc_granted, "_samr_OpenGroup");
5432 if ( !NT_STATUS_IS_OK(status) )
5435 /* this should not be hard-coded like this */
5437 if (!sid_equal(&sid, get_global_sam_sid()))
5438 return NT_STATUS_ACCESS_DENIED;
5440 sid_copy(&info_sid, get_global_sam_sid());
5441 sid_append_rid(&info_sid, r->in.rid);
5442 sid_to_fstring(sid_string, &info_sid);
5444 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5445 return NT_STATUS_NO_MEMORY;
5447 info->acc_granted = acc_granted;
5449 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5451 /* check if that group really exists */
5453 ret = get_domain_group_from_sid(info->sid, &map);
5456 return NT_STATUS_NO_SUCH_GROUP;
5458 /* get a (unique) handle. open a policy on it. */
5459 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5460 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5462 return NT_STATUS_OK;
5465 /*********************************************************************
5466 _samr_RemoveMemberFromForeignDomain
5467 *********************************************************************/
5469 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5470 struct samr_RemoveMemberFromForeignDomain *r)
5472 DOM_SID delete_sid, domain_sid;
5475 DISP_INFO *disp_info = NULL;
5477 sid_copy( &delete_sid, r->in.sid );
5479 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5480 sid_string_dbg(&delete_sid)));
5482 /* Find the policy handle. Open a policy on it. */
5484 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5485 &acc_granted, &disp_info))
5486 return NT_STATUS_INVALID_HANDLE;
5488 result = access_check_samr_function(acc_granted,
5489 STD_RIGHT_DELETE_ACCESS,
5490 "_samr_RemoveMemberFromForeignDomain");
5492 if (!NT_STATUS_IS_OK(result))
5495 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5496 sid_string_dbg(&domain_sid)));
5498 /* we can only delete a user from a group since we don't have
5499 nested groups anyways. So in the latter case, just say OK */
5501 /* TODO: The above comment nowadays is bogus. Since we have nested
5502 * groups now, and aliases members are never reported out of the unix
5503 * group membership, the "just say OK" makes this call a no-op. For
5504 * us. This needs fixing however. */
5506 /* I've only ever seen this in the wild when deleting a user from
5507 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5508 * is the user about to be deleted. I very much suspect this is the
5509 * only application of this call. To verify this, let people report
5512 if (!sid_check_is_builtin(&domain_sid)) {
5513 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5514 "global_sam_sid() = %s\n",
5515 sid_string_dbg(&domain_sid),
5516 sid_string_dbg(get_global_sam_sid())));
5517 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5518 return NT_STATUS_OK;
5521 force_flush_samr_cache(disp_info);
5523 result = NT_STATUS_OK;
5528 /*******************************************************************
5529 _samr_QueryDomainInfo2
5530 ********************************************************************/
5532 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5533 struct samr_QueryDomainInfo2 *r)
5535 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5537 r->in.domain_handle,
5542 /*******************************************************************
5544 ********************************************************************/
5546 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5547 struct samr_SetDomainInfo *r)
5549 time_t u_expire, u_min_age;
5551 time_t u_lock_duration, u_reset_time;
5553 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5555 /* find the policy handle. open a policy on it. */
5556 if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5557 return NT_STATUS_INVALID_HANDLE;
5559 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5561 switch (r->in.level) {
5563 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5564 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5565 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5566 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5567 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5568 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5569 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5574 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5575 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5584 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5585 if (u_lock_duration != -1)
5586 u_lock_duration /= 60;
5588 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5590 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5591 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5592 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5595 return NT_STATUS_INVALID_INFO_CLASS;
5598 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5600 return NT_STATUS_OK;
5603 /****************************************************************
5604 ****************************************************************/
5606 NTSTATUS _samr_Shutdown(pipes_struct *p,
5607 struct samr_Shutdown *r)
5609 p->rng_fault_state = true;
5610 return NT_STATUS_NOT_IMPLEMENTED;
5613 /****************************************************************
5614 ****************************************************************/
5616 NTSTATUS _samr_CreateUser(pipes_struct *p,
5617 struct samr_CreateUser *r)
5619 p->rng_fault_state = true;
5620 return NT_STATUS_NOT_IMPLEMENTED;
5623 /****************************************************************
5624 ****************************************************************/
5626 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5627 struct samr_SetMemberAttributesOfGroup *r)
5629 p->rng_fault_state = true;
5630 return NT_STATUS_NOT_IMPLEMENTED;
5633 /****************************************************************
5634 ****************************************************************/
5636 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5637 struct samr_ChangePasswordUser *r)
5639 p->rng_fault_state = true;
5640 return NT_STATUS_NOT_IMPLEMENTED;
5643 /****************************************************************
5644 ****************************************************************/
5646 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5647 struct samr_GetDisplayEnumerationIndex *r)
5649 p->rng_fault_state = true;
5650 return NT_STATUS_NOT_IMPLEMENTED;
5653 /****************************************************************
5654 ****************************************************************/
5656 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5657 struct samr_TestPrivateFunctionsDomain *r)
5659 p->rng_fault_state = true;
5660 return NT_STATUS_NOT_IMPLEMENTED;
5663 /****************************************************************
5664 ****************************************************************/
5666 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5667 struct samr_TestPrivateFunctionsUser *r)
5669 p->rng_fault_state = true;
5670 return NT_STATUS_NOT_IMPLEMENTED;
5673 /****************************************************************
5674 ****************************************************************/
5676 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5677 struct samr_QueryUserInfo2 *r)
5679 p->rng_fault_state = true;
5680 return NT_STATUS_NOT_IMPLEMENTED;
5683 /****************************************************************
5684 ****************************************************************/
5686 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5687 struct samr_GetDisplayEnumerationIndex2 *r)
5689 p->rng_fault_state = true;
5690 return NT_STATUS_NOT_IMPLEMENTED;
5693 /****************************************************************
5694 ****************************************************************/
5696 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5697 struct samr_AddMultipleMembersToAlias *r)
5699 p->rng_fault_state = true;
5700 return NT_STATUS_NOT_IMPLEMENTED;
5703 /****************************************************************
5704 ****************************************************************/
5706 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5707 struct samr_RemoveMultipleMembersFromAlias *r)
5709 p->rng_fault_state = true;
5710 return NT_STATUS_NOT_IMPLEMENTED;
5713 /****************************************************************
5714 ****************************************************************/
5716 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5717 struct samr_OemChangePasswordUser2 *r)
5719 p->rng_fault_state = true;
5720 return NT_STATUS_NOT_IMPLEMENTED;
5723 /****************************************************************
5724 ****************************************************************/
5726 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5727 struct samr_SetBootKeyInformation *r)
5729 p->rng_fault_state = true;
5730 return NT_STATUS_NOT_IMPLEMENTED;
5733 /****************************************************************
5734 ****************************************************************/
5736 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5737 struct samr_GetBootKeyInformation *r)
5739 p->rng_fault_state = true;
5740 return NT_STATUS_NOT_IMPLEMENTED;
5743 /****************************************************************
5744 ****************************************************************/
5746 NTSTATUS _samr_Connect3(pipes_struct *p,
5747 struct samr_Connect3 *r)
5749 p->rng_fault_state = true;
5750 return NT_STATUS_NOT_IMPLEMENTED;
5753 /****************************************************************
5754 ****************************************************************/
5756 NTSTATUS _samr_RidToSid(pipes_struct *p,
5757 struct samr_RidToSid *r)
5759 p->rng_fault_state = true;
5760 return NT_STATUS_NOT_IMPLEMENTED;
5763 /****************************************************************
5764 ****************************************************************/
5766 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5767 struct samr_SetDsrmPassword *r)
5769 p->rng_fault_state = true;
5770 return NT_STATUS_NOT_IMPLEMENTED;
5773 /****************************************************************
5774 ****************************************************************/
5776 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5777 struct samr_ValidatePassword *r)
5779 p->rng_fault_state = true;
5780 return NT_STATUS_NOT_IMPLEMENTED;