2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2005,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 * This is the implementation of the SAMR code.
36 #define DBGC_CLASS DBGC_RPC_SRV
38 #define SAMR_USR_RIGHTS_WRITE_PW \
39 ( READ_CONTROL_ACCESS | \
40 SA_RIGHT_USER_CHANGE_PASSWORD | \
41 SA_RIGHT_USER_SET_LOC_COM )
42 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
43 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
45 #define DISP_INFO_CACHE_TIMEOUT 10
47 typedef struct disp_info {
48 DOM_SID sid; /* identify which domain this is. */
49 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
50 struct pdb_search *users; /* querydispinfo 1 and 4 */
51 struct pdb_search *machines; /* querydispinfo 2 */
52 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
53 struct pdb_search *aliases; /* enumaliases */
56 struct pdb_search *enum_users; /* enumusers with a mask */
58 struct timed_event *cache_timeout_event; /* cache idle timeout
62 /* We keep a static list of these by SID as modern clients close down
63 all resources between each request in a complete enumeration. */
66 /* for use by the \PIPE\samr policy */
68 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
69 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
75 static const struct generic_mapping sam_generic_mapping = {
76 GENERIC_RIGHTS_SAM_READ,
77 GENERIC_RIGHTS_SAM_WRITE,
78 GENERIC_RIGHTS_SAM_EXECUTE,
79 GENERIC_RIGHTS_SAM_ALL_ACCESS};
80 static const struct generic_mapping dom_generic_mapping = {
81 GENERIC_RIGHTS_DOMAIN_READ,
82 GENERIC_RIGHTS_DOMAIN_WRITE,
83 GENERIC_RIGHTS_DOMAIN_EXECUTE,
84 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
85 static const struct generic_mapping usr_generic_mapping = {
86 GENERIC_RIGHTS_USER_READ,
87 GENERIC_RIGHTS_USER_WRITE,
88 GENERIC_RIGHTS_USER_EXECUTE,
89 GENERIC_RIGHTS_USER_ALL_ACCESS};
90 static const struct generic_mapping usr_nopwchange_generic_mapping = {
91 GENERIC_RIGHTS_USER_READ,
92 GENERIC_RIGHTS_USER_WRITE,
93 GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
94 GENERIC_RIGHTS_USER_ALL_ACCESS};
95 static const struct generic_mapping grp_generic_mapping = {
96 GENERIC_RIGHTS_GROUP_READ,
97 GENERIC_RIGHTS_GROUP_WRITE,
98 GENERIC_RIGHTS_GROUP_EXECUTE,
99 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
100 static const struct generic_mapping ali_generic_mapping = {
101 GENERIC_RIGHTS_ALIAS_READ,
102 GENERIC_RIGHTS_ALIAS_WRITE,
103 GENERIC_RIGHTS_ALIAS_EXECUTE,
104 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
106 /*******************************************************************
107 *******************************************************************/
109 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
110 const struct generic_mapping *map,
111 DOM_SID *sid, uint32 sid_access )
113 DOM_SID domadmin_sid;
114 SEC_ACE ace[5]; /* at most 5 entries */
120 /* basic access for Everyone */
122 init_sec_access(&mask, map->generic_execute | map->generic_read );
123 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
125 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
127 init_sec_access(&mask, map->generic_all);
129 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
130 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
132 /* Add Full Access for Domain Admins if we are a DC */
135 sid_copy( &domadmin_sid, get_global_sam_sid() );
136 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
137 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
140 /* if we have a sid, give it some special access */
143 init_sec_access( &mask, sid_access );
144 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
147 /* create the security descriptor */
149 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
150 return NT_STATUS_NO_MEMORY;
152 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
153 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
154 psa, sd_size)) == NULL)
155 return NT_STATUS_NO_MEMORY;
160 /*******************************************************************
161 Checks if access to an object should be granted, and returns that
162 level of access for further checks.
163 ********************************************************************/
165 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
166 SE_PRIV *rights, uint32 rights_mask,
167 uint32 des_access, uint32 *acc_granted,
170 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
171 uint32 saved_mask = 0;
173 /* check privileges; certain SAM access bits should be overridden
174 by privileges (mostly having to do with creating/modifying/deleting
177 if ( rights && user_has_any_privilege( token, rights ) ) {
179 saved_mask = (des_access & rights_mask);
180 des_access &= ~saved_mask;
182 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
187 /* check the security descriptor first */
189 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
192 /* give root a free pass */
194 if ( geteuid() == sec_initial_uid() ) {
196 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
197 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
199 *acc_granted = des_access;
201 status = NT_STATUS_OK;
207 /* add in any bits saved during the privilege check (only
208 matters is status is ok) */
210 *acc_granted |= rights_mask;
212 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
213 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
214 des_access, *acc_granted));
219 /*******************************************************************
220 Checks if access to a function can be granted
221 ********************************************************************/
223 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
225 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
226 debug, acc_granted, acc_required));
228 /* check the security descriptor first */
230 if ( (acc_granted&acc_required) == acc_required )
233 /* give root a free pass */
235 if (geteuid() == sec_initial_uid()) {
237 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
238 debug, acc_granted, acc_required));
239 DEBUGADD(4,("but overwritten by euid == 0\n"));
244 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
245 debug, acc_granted, acc_required));
247 return NT_STATUS_ACCESS_DENIED;
250 /*******************************************************************
251 Fetch or create a dispinfo struct.
252 ********************************************************************/
254 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
257 * We do a static cache for DISP_INFO's here. Explanation can be found
258 * in Jeremy's checkin message to r11793:
260 * Fix the SAMR cache so it works across completely insane
261 * client behaviour (ie.:
262 * open pipe/open SAMR handle/enumerate 0 - 1024
263 * close SAMR handle, close pipe.
264 * open pipe/open SAMR handle/enumerate 1024 - 2048...
265 * close SAMR handle, close pipe.
266 * And on ad-nausium. Amazing.... probably object-oriented
267 * client side programming in action yet again.
268 * This change should *massively* improve performance when
269 * enumerating users from an LDAP database.
272 * "Our" and the builtin domain are the only ones where we ever
273 * enumerate stuff, so just cache 2 entries.
276 static struct disp_info builtin_dispinfo;
277 static struct disp_info domain_dispinfo;
279 /* There are two cases to consider here:
280 1) The SID is a domain SID and we look for an equality match, or
281 2) This is an account SID and so we return the DISP_INFO* for our
288 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
290 * Necessary only once, but it does not really hurt.
292 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
294 return &builtin_dispinfo;
297 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
299 * Necessary only once, but it does not really hurt.
301 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
303 return &domain_dispinfo;
309 /*******************************************************************
310 Create a samr_info struct.
311 ********************************************************************/
313 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
315 struct samr_info *info;
320 sid_to_fstring(sid_str, psid);
322 fstrcpy(sid_str,"(NULL)");
325 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
327 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
330 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
332 sid_copy( &info->sid, psid);
333 info->builtin_domain = sid_check_is_builtin(psid);
335 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
336 info->builtin_domain = False;
338 info->mem_ctx = mem_ctx;
340 info->disp_info = get_samr_dispinfo_by_sid(psid);
345 /*******************************************************************
346 Function to free the per SID data.
347 ********************************************************************/
349 static void free_samr_cache(DISP_INFO *disp_info)
351 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
352 sid_string_dbg(&disp_info->sid)));
354 /* We need to become root here because the paged search might have to
355 * tell the LDAP server we're not interested in the rest anymore. */
359 if (disp_info->users) {
360 DEBUG(10,("free_samr_cache: deleting users cache\n"));
361 pdb_search_destroy(disp_info->users);
362 disp_info->users = NULL;
364 if (disp_info->machines) {
365 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
366 pdb_search_destroy(disp_info->machines);
367 disp_info->machines = NULL;
369 if (disp_info->groups) {
370 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
371 pdb_search_destroy(disp_info->groups);
372 disp_info->groups = NULL;
374 if (disp_info->aliases) {
375 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
376 pdb_search_destroy(disp_info->aliases);
377 disp_info->aliases = NULL;
379 if (disp_info->enum_users) {
380 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
381 pdb_search_destroy(disp_info->enum_users);
382 disp_info->enum_users = NULL;
384 disp_info->enum_acb_mask = 0;
389 /*******************************************************************
390 Function to free the per handle data.
391 ********************************************************************/
393 static void free_samr_info(void *ptr)
395 struct samr_info *info=(struct samr_info *) ptr;
397 /* Only free the dispinfo cache if no one bothered to set up
400 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
401 free_samr_cache(info->disp_info);
404 talloc_destroy(info->mem_ctx);
407 /*******************************************************************
408 Idle event handler. Throw away the disp info cache.
409 ********************************************************************/
411 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
412 struct timed_event *te,
413 const struct timeval *now,
416 DISP_INFO *disp_info = (DISP_INFO *)private_data;
418 TALLOC_FREE(disp_info->cache_timeout_event);
420 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
422 free_samr_cache(disp_info);
425 /*******************************************************************
426 Setup cache removal idle event handler.
427 ********************************************************************/
429 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
431 /* Remove any pending timeout and update. */
433 TALLOC_FREE(disp_info->cache_timeout_event);
435 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
436 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
437 (unsigned int)secs_fromnow ));
439 disp_info->cache_timeout_event = event_add_timed(
440 smbd_event_context(), NULL,
441 timeval_current_ofs(secs_fromnow, 0),
442 "disp_info_cache_idle_timeout_handler",
443 disp_info_cache_idle_timeout_handler, (void *)disp_info);
446 /*******************************************************************
447 Force flush any cache. We do this on any samr_set_xxx call.
448 We must also remove the timeout handler.
449 ********************************************************************/
451 static void force_flush_samr_cache(DISP_INFO *disp_info)
453 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
457 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
458 TALLOC_FREE(disp_info->cache_timeout_event);
459 free_samr_cache(disp_info);
462 /*******************************************************************
463 Ensure password info is never given out. Paranioa... JRA.
464 ********************************************************************/
466 static void samr_clear_sam_passwd(struct samu *sam_pass)
472 /* These now zero out the old password */
474 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
475 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
478 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
480 struct samr_displayentry *entry;
482 if (info->builtin_domain) {
483 /* No users in builtin. */
487 if (info->users == NULL) {
488 info->users = pdb_search_users(acct_flags);
489 if (info->users == NULL) {
493 /* Fetch the last possible entry, thus trigger an enumeration */
494 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
496 /* Ensure we cache this enumeration. */
497 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
499 return info->users->num_entries;
502 static uint32 count_sam_groups(struct disp_info *info)
504 struct samr_displayentry *entry;
506 if (info->builtin_domain) {
507 /* No groups in builtin. */
511 if (info->groups == NULL) {
512 info->groups = pdb_search_groups();
513 if (info->groups == NULL) {
517 /* Fetch the last possible entry, thus trigger an enumeration */
518 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
520 /* Ensure we cache this enumeration. */
521 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
523 return info->groups->num_entries;
526 static uint32 count_sam_aliases(struct disp_info *info)
528 struct samr_displayentry *entry;
530 if (info->aliases == NULL) {
531 info->aliases = pdb_search_aliases(&info->sid);
532 if (info->aliases == NULL) {
536 /* Fetch the last possible entry, thus trigger an enumeration */
537 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
539 /* Ensure we cache this enumeration. */
540 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
542 return info->aliases->num_entries;
545 /*******************************************************************
547 ********************************************************************/
549 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
551 if (!close_policy_hnd(p, r->in.handle)) {
552 return NT_STATUS_INVALID_HANDLE;
555 ZERO_STRUCTP(r->out.handle);
560 /*******************************************************************
562 ********************************************************************/
564 NTSTATUS _samr_OpenDomain(pipes_struct *p,
565 struct samr_OpenDomain *r)
567 struct samr_info *info;
568 SEC_DESC *psd = NULL;
570 uint32 des_access = r->in.access_mask;
575 /* find the connection policy handle. */
577 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
578 return NT_STATUS_INVALID_HANDLE;
580 status = access_check_samr_function(info->acc_granted,
581 SA_RIGHT_SAM_OPEN_DOMAIN,
582 "_samr_OpenDomain" );
584 if ( !NT_STATUS_IS_OK(status) )
587 /*check if access can be granted as requested by client. */
589 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
590 se_map_generic( &des_access, &dom_generic_mapping );
592 se_priv_copy( &se_rights, &se_machine_account );
593 se_priv_add( &se_rights, &se_add_users );
595 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
596 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
597 &acc_granted, "_samr_OpenDomain" );
599 if ( !NT_STATUS_IS_OK(status) )
602 if (!sid_check_is_domain(r->in.sid) &&
603 !sid_check_is_builtin(r->in.sid)) {
604 return NT_STATUS_NO_SUCH_DOMAIN;
607 /* associate the domain SID with the (unique) handle. */
608 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
609 return NT_STATUS_NO_MEMORY;
610 info->acc_granted = acc_granted;
612 /* get a (unique) handle. open a policy on it. */
613 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
614 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
616 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
621 /*******************************************************************
623 ********************************************************************/
625 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
626 struct samr_GetUserPwInfo *r)
628 struct samr_info *info = NULL;
630 /* find the policy handle. open a policy on it. */
631 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
632 return NT_STATUS_INVALID_HANDLE;
634 if (!sid_check_is_in_our_domain(&info->sid))
635 return NT_STATUS_OBJECT_TYPE_MISMATCH;
637 ZERO_STRUCTP(r->out.info);
639 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
642 * NT sometimes return NT_STATUS_ACCESS_DENIED
643 * I don't know yet why.
649 /*******************************************************************
650 ********************************************************************/
652 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
653 DOM_SID *sid, uint32 *acc_granted,
654 DISP_INFO **ppdisp_info)
656 struct samr_info *info = NULL;
658 /* find the policy handle. open a policy on it. */
659 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
666 *acc_granted = info->acc_granted;
668 *ppdisp_info = info->disp_info;
674 /*******************************************************************
676 ********************************************************************/
678 NTSTATUS _samr_SetSecurity(pipes_struct *p,
679 struct samr_SetSecurity *r)
682 uint32 acc_granted, i;
685 struct samu *sampass=NULL;
688 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
689 return NT_STATUS_INVALID_HANDLE;
691 if (!(sampass = samu_new( p->mem_ctx))) {
692 DEBUG(0,("No memory!\n"));
693 return NT_STATUS_NO_MEMORY;
696 /* get the user record */
698 ret = pdb_getsampwsid(sampass, &pol_sid);
702 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
703 TALLOC_FREE(sampass);
704 return NT_STATUS_INVALID_HANDLE;
707 dacl = r->in.sdbuf->sd->dacl;
708 for (i=0; i < dacl->num_aces; i++) {
709 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
710 ret = pdb_set_pass_can_change(sampass,
711 (dacl->aces[i].access_mask &
712 SA_RIGHT_USER_CHANGE_PASSWORD) ?
719 TALLOC_FREE(sampass);
720 return NT_STATUS_ACCESS_DENIED;
723 status = access_check_samr_function(acc_granted,
724 SA_RIGHT_USER_SET_ATTRIBUTES,
725 "_samr_SetSecurity");
726 if (NT_STATUS_IS_OK(status)) {
728 status = pdb_update_sam_account(sampass);
732 TALLOC_FREE(sampass);
737 /*******************************************************************
738 build correct perms based on policies and password times for _samr_query_sec_obj
739 *******************************************************************/
740 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
742 struct samu *sampass=NULL;
745 if ( !(sampass = samu_new( mem_ctx )) ) {
746 DEBUG(0,("No memory!\n"));
751 ret = pdb_getsampwsid(sampass, user_sid);
755 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
756 TALLOC_FREE(sampass);
760 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
762 if (pdb_get_pass_can_change(sampass)) {
763 TALLOC_FREE(sampass);
766 TALLOC_FREE(sampass);
771 /*******************************************************************
773 ********************************************************************/
775 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
776 struct samr_QuerySecurity *r)
780 SEC_DESC * psd = NULL;
785 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
786 return NT_STATUS_INVALID_HANDLE;
788 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
789 sid_string_dbg(&pol_sid)));
791 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
793 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
794 if (pol_sid.sid_rev_num == 0) {
795 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
796 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
797 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
798 /* check if it is our domain SID */
799 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
800 "with SID: %s\n", sid_string_dbg(&pol_sid)));
801 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
802 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
803 /* check if it is the Builtin Domain */
804 /* TODO: Builtin probably needs a different SD with restricted write access*/
805 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
806 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
807 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
808 } else if (sid_check_is_in_our_domain(&pol_sid) ||
809 sid_check_is_in_builtin(&pol_sid)) {
810 /* TODO: different SDs have to be generated for aliases groups and users.
811 Currently all three get a default user SD */
812 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
813 "with SID: %s\n", sid_string_dbg(&pol_sid)));
814 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
815 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
816 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
818 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
819 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
822 return NT_STATUS_OBJECT_TYPE_MISMATCH;
825 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
826 return NT_STATUS_NO_MEMORY;
831 /*******************************************************************
832 makes a SAM_ENTRY / UNISTR2* structure from a user list.
833 ********************************************************************/
835 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
836 struct samr_SamEntry **sam_pp,
837 uint32_t num_entries,
839 struct samr_displayentry *entries)
842 struct samr_SamEntry *sam;
846 if (num_entries == 0) {
850 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
852 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
853 return NT_STATUS_NO_MEMORY;
856 for (i = 0; i < num_entries; i++) {
859 * usrmgr expects a non-NULL terminated string with
860 * trust relationships
862 if (entries[i].acct_flags & ACB_DOMTRUST) {
863 init_unistr2(&uni_temp_name, entries[i].account_name,
866 init_unistr2(&uni_temp_name, entries[i].account_name,
870 init_lsa_String(&sam[i].name, entries[i].account_name);
871 sam[i].idx = entries[i].rid;
879 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
881 /*******************************************************************
882 _samr_EnumDomainUsers
883 ********************************************************************/
885 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
886 struct samr_EnumDomainUsers *r)
889 struct samr_info *info = NULL;
891 uint32 enum_context = *r->in.resume_handle;
892 enum remote_arch_types ra_type = get_remote_arch();
893 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
894 uint32 max_entries = max_sam_entries;
895 struct samr_displayentry *entries = NULL;
896 struct samr_SamArray *samr_array = NULL;
897 struct samr_SamEntry *samr_entries = NULL;
899 /* find the policy handle. open a policy on it. */
900 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
901 return NT_STATUS_INVALID_HANDLE;
903 status = access_check_samr_function(info->acc_granted,
904 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
905 "_samr_EnumDomainUsers");
906 if (!NT_STATUS_IS_OK(status)) {
910 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
912 if (info->builtin_domain) {
913 /* No users in builtin. */
914 *r->out.resume_handle = *r->in.resume_handle;
915 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
919 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
921 return NT_STATUS_NO_MEMORY;
928 if ((info->disp_info->enum_users != NULL) &&
929 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
930 pdb_search_destroy(info->disp_info->enum_users);
931 info->disp_info->enum_users = NULL;
934 if (info->disp_info->enum_users == NULL) {
935 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
936 info->disp_info->enum_acb_mask = r->in.acct_flags;
939 if (info->disp_info->enum_users == NULL) {
940 /* END AS ROOT !!!! */
942 return NT_STATUS_ACCESS_DENIED;
945 num_account = pdb_search_entries(info->disp_info->enum_users,
946 enum_context, max_entries,
949 /* END AS ROOT !!!! */
953 if (num_account == 0) {
954 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
956 *r->out.resume_handle = *r->in.resume_handle;
960 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
961 num_account, enum_context,
963 if (!NT_STATUS_IS_OK(status)) {
967 if (max_entries <= num_account) {
968 status = STATUS_MORE_ENTRIES;
970 status = NT_STATUS_OK;
973 /* Ensure we cache this enumeration. */
974 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
976 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
978 samr_array->count = num_account;
979 samr_array->entries = samr_entries;
981 *r->out.resume_handle = *r->in.resume_handle + num_account;
982 *r->out.sam = samr_array;
983 *r->out.num_entries = num_account;
985 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
990 /*******************************************************************
991 makes a SAM_ENTRY / UNISTR2* structure from a group list.
992 ********************************************************************/
994 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
995 struct samr_SamEntry **sam_pp,
996 uint32_t num_sam_entries,
997 struct samr_displayentry *entries)
999 struct samr_SamEntry *sam;
1004 if (num_sam_entries == 0) {
1008 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1013 for (i = 0; i < num_sam_entries; i++) {
1015 * JRA. I think this should include the null. TNG does not.
1017 init_lsa_String(&sam[i].name, entries[i].account_name);
1018 sam[i].idx = entries[i].rid;
1024 /*******************************************************************
1025 _samr_EnumDomainGroups
1026 ********************************************************************/
1028 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1029 struct samr_EnumDomainGroups *r)
1032 struct samr_info *info = NULL;
1033 struct samr_displayentry *groups;
1035 struct samr_SamArray *samr_array = NULL;
1036 struct samr_SamEntry *samr_entries = NULL;
1038 /* find the policy handle. open a policy on it. */
1039 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1040 return NT_STATUS_INVALID_HANDLE;
1042 status = access_check_samr_function(info->acc_granted,
1043 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1044 "_samr_EnumDomainGroups");
1045 if (!NT_STATUS_IS_OK(status)) {
1049 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1051 if (info->builtin_domain) {
1052 /* No groups in builtin. */
1053 *r->out.resume_handle = *r->in.resume_handle;
1054 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1058 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1060 return NT_STATUS_NO_MEMORY;
1063 /* the domain group array is being allocated in the function below */
1067 if (info->disp_info->groups == NULL) {
1068 info->disp_info->groups = pdb_search_groups();
1070 if (info->disp_info->groups == NULL) {
1072 return NT_STATUS_ACCESS_DENIED;
1076 num_groups = pdb_search_entries(info->disp_info->groups,
1077 *r->in.resume_handle,
1078 MAX_SAM_ENTRIES, &groups);
1081 /* Ensure we cache this enumeration. */
1082 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1084 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1085 num_groups, groups);
1087 samr_array->count = num_groups;
1088 samr_array->entries = samr_entries;
1090 *r->out.sam = samr_array;
1091 *r->out.num_entries = num_groups;
1092 /* this was missing, IMHO:
1093 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1096 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1101 /*******************************************************************
1102 _samr_EnumDomainAliases
1103 ********************************************************************/
1105 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1106 struct samr_EnumDomainAliases *r)
1109 struct samr_info *info;
1110 struct samr_displayentry *aliases;
1111 uint32 num_aliases = 0;
1112 struct samr_SamArray *samr_array = NULL;
1113 struct samr_SamEntry *samr_entries = NULL;
1115 /* find the policy handle. open a policy on it. */
1116 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1117 return NT_STATUS_INVALID_HANDLE;
1119 status = access_check_samr_function(info->acc_granted,
1120 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1121 "_samr_EnumDomainAliases");
1122 if (!NT_STATUS_IS_OK(status)) {
1126 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1127 sid_string_dbg(&info->sid)));
1129 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1131 return NT_STATUS_NO_MEMORY;
1136 if (info->disp_info->aliases == NULL) {
1137 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1138 if (info->disp_info->aliases == NULL) {
1140 return NT_STATUS_ACCESS_DENIED;
1144 num_aliases = pdb_search_entries(info->disp_info->aliases,
1145 *r->in.resume_handle,
1146 MAX_SAM_ENTRIES, &aliases);
1149 /* Ensure we cache this enumeration. */
1150 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1152 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1153 num_aliases, aliases);
1155 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1157 samr_array->count = num_aliases;
1158 samr_array->entries = samr_entries;
1160 *r->out.sam = samr_array;
1161 *r->out.num_entries = num_aliases;
1162 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1167 /*******************************************************************
1168 inits a samr_DispInfoGeneral structure.
1169 ********************************************************************/
1171 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1172 struct samr_DispInfoGeneral *r,
1173 uint32_t num_entries,
1175 struct samr_displayentry *entries)
1179 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1181 if (num_entries == 0) {
1182 return NT_STATUS_OK;
1185 r->count = num_entries;
1187 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1189 return NT_STATUS_NO_MEMORY;
1192 for (i = 0; i < num_entries ; i++) {
1194 init_lsa_String(&r->entries[i].account_name,
1195 entries[i].account_name);
1197 init_lsa_String(&r->entries[i].description,
1198 entries[i].description);
1200 init_lsa_String(&r->entries[i].full_name,
1201 entries[i].fullname);
1203 r->entries[i].rid = entries[i].rid;
1204 r->entries[i].acct_flags = entries[i].acct_flags;
1205 r->entries[i].idx = start_idx+i+1;
1208 return NT_STATUS_OK;
1211 /*******************************************************************
1212 inits a samr_DispInfoFull structure.
1213 ********************************************************************/
1215 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1216 struct samr_DispInfoFull *r,
1217 uint32_t num_entries,
1219 struct samr_displayentry *entries)
1223 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1225 if (num_entries == 0) {
1226 return NT_STATUS_OK;
1229 r->count = num_entries;
1231 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1233 return NT_STATUS_NO_MEMORY;
1236 for (i = 0; i < num_entries ; i++) {
1238 init_lsa_String(&r->entries[i].account_name,
1239 entries[i].account_name);
1241 init_lsa_String(&r->entries[i].description,
1242 entries[i].description);
1244 r->entries[i].rid = entries[i].rid;
1245 r->entries[i].acct_flags = entries[i].acct_flags;
1246 r->entries[i].idx = start_idx+i+1;
1249 return NT_STATUS_OK;
1252 /*******************************************************************
1253 inits a samr_DispInfoFullGroups structure.
1254 ********************************************************************/
1256 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1257 struct samr_DispInfoFullGroups *r,
1258 uint32_t num_entries,
1260 struct samr_displayentry *entries)
1264 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1266 if (num_entries == 0) {
1267 return NT_STATUS_OK;
1270 r->count = num_entries;
1272 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1274 return NT_STATUS_NO_MEMORY;
1277 for (i = 0; i < num_entries ; i++) {
1279 init_lsa_String(&r->entries[i].account_name,
1280 entries[i].account_name);
1282 init_lsa_String(&r->entries[i].description,
1283 entries[i].description);
1285 r->entries[i].rid = entries[i].rid;
1286 r->entries[i].acct_flags = entries[i].acct_flags;
1287 r->entries[i].idx = start_idx+i+1;
1290 return NT_STATUS_OK;
1293 /*******************************************************************
1294 inits a samr_DispInfoAscii structure.
1295 ********************************************************************/
1297 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1298 struct samr_DispInfoAscii *r,
1299 uint32_t num_entries,
1301 struct samr_displayentry *entries)
1305 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1307 if (num_entries == 0) {
1308 return NT_STATUS_OK;
1311 r->count = num_entries;
1313 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1315 return NT_STATUS_NO_MEMORY;
1318 for (i = 0; i < num_entries ; i++) {
1320 init_lsa_AsciiString(&r->entries[i].account_name,
1321 entries[i].account_name);
1323 r->entries[i].idx = start_idx+i+1;
1326 return NT_STATUS_OK;
1329 /*******************************************************************
1330 inits a samr_DispInfoAscii structure.
1331 ********************************************************************/
1333 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1334 struct samr_DispInfoAscii *r,
1335 uint32_t num_entries,
1337 struct samr_displayentry *entries)
1341 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1343 if (num_entries == 0) {
1344 return NT_STATUS_OK;
1347 r->count = num_entries;
1349 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1351 return NT_STATUS_NO_MEMORY;
1354 for (i = 0; i < num_entries ; i++) {
1356 init_lsa_AsciiString(&r->entries[i].account_name,
1357 entries[i].account_name);
1359 r->entries[i].idx = start_idx+i+1;
1362 return NT_STATUS_OK;
1365 /*******************************************************************
1366 _samr_QueryDisplayInfo
1367 ********************************************************************/
1369 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1370 struct samr_QueryDisplayInfo *r)
1373 struct samr_info *info = NULL;
1374 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1376 uint32 max_entries = r->in.max_entries;
1377 uint32 enum_context = r->in.start_idx;
1378 uint32 max_size = r->in.buf_size;
1380 union samr_DispInfo *disp_info = r->out.info;
1382 uint32 temp_size=0, total_data_size=0;
1383 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1384 uint32 num_account = 0;
1385 enum remote_arch_types ra_type = get_remote_arch();
1386 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1387 struct samr_displayentry *entries = NULL;
1389 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1391 /* find the policy handle. open a policy on it. */
1392 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1393 return NT_STATUS_INVALID_HANDLE;
1396 * calculate how many entries we will return.
1398 * - the number of entries the client asked
1399 * - our limit on that
1400 * - the starting point (enumeration context)
1401 * - the buffer size the client will accept
1405 * We are a lot more like W2K. Instead of reading the SAM
1406 * each time to find the records we need to send back,
1407 * we read it once and link that copy to the sam handle.
1408 * For large user list (over the MAX_SAM_ENTRIES)
1409 * it's a definitive win.
1410 * second point to notice: between enumerations
1411 * our sam is now the same as it's a snapshoot.
1412 * third point: got rid of the static SAM_USER_21 struct
1413 * no more intermediate.
1414 * con: it uses much more memory, as a full copy is stored
1417 * If you want to change it, think twice and think
1418 * of the second point , that's really important.
1423 if ((r->in.level < 1) || (r->in.level > 5)) {
1424 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1425 (unsigned int)r->in.level ));
1426 return NT_STATUS_INVALID_INFO_CLASS;
1429 /* first limit the number of entries we will return */
1430 if(max_entries > max_sam_entries) {
1431 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1432 "entries, limiting to %d\n", max_entries,
1434 max_entries = max_sam_entries;
1437 /* calculate the size and limit on the number of entries we will
1440 temp_size=max_entries*struct_size;
1442 if (temp_size>max_size) {
1443 max_entries=MIN((max_size/struct_size),max_entries);;
1444 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1445 "only %d entries\n", max_entries));
1450 /* THe following done as ROOT. Don't return without unbecome_root(). */
1452 switch (r->in.level) {
1455 if (info->disp_info->users == NULL) {
1456 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1457 if (info->disp_info->users == NULL) {
1459 return NT_STATUS_ACCESS_DENIED;
1461 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1462 (unsigned int)enum_context ));
1464 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1465 (unsigned int)enum_context ));
1468 num_account = pdb_search_entries(info->disp_info->users,
1469 enum_context, max_entries,
1473 if (info->disp_info->machines == NULL) {
1474 info->disp_info->machines =
1475 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1476 if (info->disp_info->machines == NULL) {
1478 return NT_STATUS_ACCESS_DENIED;
1480 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1481 (unsigned int)enum_context ));
1483 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1484 (unsigned int)enum_context ));
1487 num_account = pdb_search_entries(info->disp_info->machines,
1488 enum_context, max_entries,
1493 if (info->disp_info->groups == NULL) {
1494 info->disp_info->groups = pdb_search_groups();
1495 if (info->disp_info->groups == NULL) {
1497 return NT_STATUS_ACCESS_DENIED;
1499 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1500 (unsigned int)enum_context ));
1502 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1503 (unsigned int)enum_context ));
1506 num_account = pdb_search_entries(info->disp_info->groups,
1507 enum_context, max_entries,
1512 smb_panic("info class changed");
1518 /* Now create reply structure */
1519 switch (r->in.level) {
1521 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1522 num_account, enum_context,
1526 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1527 num_account, enum_context,
1531 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1532 num_account, enum_context,
1536 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1537 num_account, enum_context,
1541 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1542 num_account, enum_context,
1546 smb_panic("info class changed");
1550 if (!NT_STATUS_IS_OK(disp_ret))
1553 /* calculate the total size */
1554 total_data_size=num_account*struct_size;
1557 status = STATUS_MORE_ENTRIES;
1559 status = NT_STATUS_OK;
1562 /* Ensure we cache this enumeration. */
1563 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1565 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1567 *r->out.total_size = total_data_size;
1568 *r->out.returned_size = temp_size;
1573 /****************************************************************
1574 _samr_QueryDisplayInfo2
1575 ****************************************************************/
1577 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1578 struct samr_QueryDisplayInfo2 *r)
1580 struct samr_QueryDisplayInfo q;
1582 q.in.domain_handle = r->in.domain_handle;
1583 q.in.level = r->in.level;
1584 q.in.start_idx = r->in.start_idx;
1585 q.in.max_entries = r->in.max_entries;
1586 q.in.buf_size = r->in.buf_size;
1588 q.out.total_size = r->out.total_size;
1589 q.out.returned_size = r->out.returned_size;
1590 q.out.info = r->out.info;
1592 return _samr_QueryDisplayInfo(p, &q);
1595 /****************************************************************
1596 _samr_QueryDisplayInfo3
1597 ****************************************************************/
1599 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1600 struct samr_QueryDisplayInfo3 *r)
1602 struct samr_QueryDisplayInfo q;
1604 q.in.domain_handle = r->in.domain_handle;
1605 q.in.level = r->in.level;
1606 q.in.start_idx = r->in.start_idx;
1607 q.in.max_entries = r->in.max_entries;
1608 q.in.buf_size = r->in.buf_size;
1610 q.out.total_size = r->out.total_size;
1611 q.out.returned_size = r->out.returned_size;
1612 q.out.info = r->out.info;
1614 return _samr_QueryDisplayInfo(p, &q);
1617 /*******************************************************************
1618 _samr_QueryAliasInfo
1619 ********************************************************************/
1621 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1622 struct samr_QueryAliasInfo *r)
1625 struct acct_info info;
1628 union samr_AliasInfo *alias_info = NULL;
1629 const char *alias_name = NULL;
1630 const char *alias_description = NULL;
1632 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1634 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1636 return NT_STATUS_NO_MEMORY;
1639 /* find the policy handle. open a policy on it. */
1640 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1641 return NT_STATUS_INVALID_HANDLE;
1643 status = access_check_samr_function(acc_granted,
1644 SA_RIGHT_ALIAS_LOOKUP_INFO,
1645 "_samr_QueryAliasInfo");
1646 if (!NT_STATUS_IS_OK(status)) {
1651 status = pdb_get_aliasinfo(&sid, &info);
1654 if ( !NT_STATUS_IS_OK(status))
1657 /* FIXME: info contains fstrings */
1658 alias_name = talloc_strdup(r, info.acct_name);
1659 alias_description = talloc_strdup(r, info.acct_desc);
1661 switch (r->in.level) {
1663 init_samr_alias_info1(&alias_info->all,
1668 case ALIASINFODESCRIPTION:
1669 init_samr_alias_info3(&alias_info->description,
1673 return NT_STATUS_INVALID_INFO_CLASS;
1676 *r->out.info = alias_info;
1678 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1680 return NT_STATUS_OK;
1684 /*******************************************************************
1685 samr_reply_lookup_ids
1686 ********************************************************************/
1688 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1690 uint32 rid[MAX_SAM_ENTRIES];
1691 int num_rids = q_u->num_sids1;
1693 r_u->status = NT_STATUS_OK;
1695 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1697 if (num_rids > MAX_SAM_ENTRIES) {
1698 num_rids = MAX_SAM_ENTRIES;
1699 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1704 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1706 for (i = 0; i < num_rids && status == 0; i++)
1708 struct sam_passwd *sam_pass;
1712 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1713 q_u->uni_user_name[i].uni_str_len));
1715 /* find the user account */
1717 sam_pass = get_smb21pwd_entry(user_name, 0);
1720 if (sam_pass == NULL)
1722 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1727 rid[i] = sam_pass->user_rid;
1733 rid[0] = BUILTIN_ALIAS_RID_USERS;
1735 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1737 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1743 /*******************************************************************
1745 ********************************************************************/
1747 NTSTATUS _samr_LookupNames(pipes_struct *p,
1748 struct samr_LookupNames *r)
1751 uint32 rid[MAX_SAM_ENTRIES];
1752 enum lsa_SidType type[MAX_SAM_ENTRIES];
1754 int num_rids = r->in.num_names;
1757 struct samr_Ids rids, types;
1759 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1764 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1765 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1768 status = access_check_samr_function(acc_granted,
1769 0, /* Don't know the acc_bits yet */
1770 "_samr_LookupNames");
1771 if (!NT_STATUS_IS_OK(status)) {
1775 if (num_rids > MAX_SAM_ENTRIES) {
1776 num_rids = MAX_SAM_ENTRIES;
1777 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1780 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1781 sid_string_dbg(&pol_sid)));
1783 for (i = 0; i < num_rids; i++) {
1785 status = NT_STATUS_NONE_MAPPED;
1786 type[i] = SID_NAME_UNKNOWN;
1788 rid[i] = 0xffffffff;
1790 if (sid_check_is_builtin(&pol_sid)) {
1791 if (lookup_builtin_name(r->in.names[i].string,
1794 type[i] = SID_NAME_ALIAS;
1797 lookup_global_sam_name(r->in.names[i].string, 0,
1801 if (type[i] != SID_NAME_UNKNOWN) {
1802 status = NT_STATUS_OK;
1806 rids.count = num_rids;
1809 types.count = num_rids;
1812 *r->out.rids = rids;
1813 *r->out.types = types;
1815 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1820 /*******************************************************************
1821 _samr_ChangePasswordUser2
1822 ********************************************************************/
1824 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1825 struct samr_ChangePasswordUser2 *r)
1831 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1833 fstrcpy(user_name, r->in.account->string);
1834 fstrcpy(wks, r->in.server->string);
1836 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1839 * Pass the user through the NT -> unix user mapping
1843 (void)map_username(user_name);
1846 * UNIX username case mangling not required, pass_oem_change
1847 * is case insensitive.
1850 status = pass_oem_change(user_name,
1851 r->in.lm_password->data,
1852 r->in.lm_verifier->hash,
1853 r->in.nt_password->data,
1854 r->in.nt_verifier->hash,
1857 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1862 /*******************************************************************
1863 _samr_ChangePasswordUser3
1864 ********************************************************************/
1866 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1867 struct samr_ChangePasswordUser3 *r)
1871 const char *wks = NULL;
1872 uint32 reject_reason;
1873 struct samr_DomInfo1 *dominfo = NULL;
1874 struct samr_ChangeReject *reject = NULL;
1876 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1878 fstrcpy(user_name, r->in.account->string);
1879 if (r->in.server && r->in.server->string) {
1880 wks = r->in.server->string;
1883 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1886 * Pass the user through the NT -> unix user mapping
1890 (void)map_username(user_name);
1893 * UNIX username case mangling not required, pass_oem_change
1894 * is case insensitive.
1897 status = pass_oem_change(user_name,
1898 r->in.lm_password->data,
1899 r->in.lm_verifier->hash,
1900 r->in.nt_password->data,
1901 r->in.nt_verifier->hash,
1904 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1905 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1907 uint32 min_pass_len,pass_hist,password_properties;
1908 time_t u_expire, u_min_age;
1909 NTTIME nt_expire, nt_min_age;
1910 uint32 account_policy_temp;
1912 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1914 return NT_STATUS_NO_MEMORY;
1917 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1919 return NT_STATUS_NO_MEMORY;
1926 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1927 min_pass_len = account_policy_temp;
1929 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1930 pass_hist = account_policy_temp;
1932 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1933 password_properties = account_policy_temp;
1935 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1936 u_expire = account_policy_temp;
1938 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1939 u_min_age = account_policy_temp;
1945 unix_to_nt_time_abs(&nt_expire, u_expire);
1946 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1948 if (lp_check_password_script() && *lp_check_password_script()) {
1949 password_properties |= DOMAIN_PASSWORD_COMPLEX;
1952 init_samr_DomInfo1(dominfo,
1955 password_properties,
1959 reject->reason = reject_reason;
1961 *r->out.dominfo = dominfo;
1962 *r->out.reject = reject;
1965 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1970 /*******************************************************************
1971 makes a SAMR_R_LOOKUP_RIDS structure.
1972 ********************************************************************/
1974 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1976 struct lsa_String **lsa_name_array_p)
1978 struct lsa_String *lsa_name_array = NULL;
1981 *lsa_name_array_p = NULL;
1983 if (num_names != 0) {
1984 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
1985 if (!lsa_name_array) {
1990 for (i = 0; i < num_names; i++) {
1991 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
1992 init_lsa_String(&lsa_name_array[i], names[i]);
1995 *lsa_name_array_p = lsa_name_array;
2000 /*******************************************************************
2002 ********************************************************************/
2004 NTSTATUS _samr_LookupRids(pipes_struct *p,
2005 struct samr_LookupRids *r)
2009 enum lsa_SidType *attrs = NULL;
2010 uint32 *wire_attrs = NULL;
2012 int num_rids = (int)r->in.num_rids;
2015 struct lsa_Strings names_array;
2016 struct samr_Ids types_array;
2017 struct lsa_String *lsa_names = NULL;
2019 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2021 /* find the policy handle. open a policy on it. */
2022 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2023 return NT_STATUS_INVALID_HANDLE;
2025 if (num_rids > 1000) {
2026 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2027 "to samba4 idl this is not possible\n", num_rids));
2028 return NT_STATUS_UNSUCCESSFUL;
2032 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2033 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2034 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2036 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2037 return NT_STATUS_NO_MEMORY;
2044 become_root(); /* lookup_sid can require root privs */
2045 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2049 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2050 status = NT_STATUS_OK;
2053 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2055 return NT_STATUS_NO_MEMORY;
2058 /* Convert from enum lsa_SidType to uint32 for wire format. */
2059 for (i = 0; i < num_rids; i++) {
2060 wire_attrs[i] = (uint32)attrs[i];
2063 names_array.count = num_rids;
2064 names_array.names = lsa_names;
2066 types_array.count = num_rids;
2067 types_array.ids = wire_attrs;
2069 *r->out.names = names_array;
2070 *r->out.types = types_array;
2072 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2077 /*******************************************************************
2079 ********************************************************************/
2081 NTSTATUS _samr_OpenUser(pipes_struct *p,
2082 struct samr_OpenUser *r)
2084 struct samu *sampass=NULL;
2086 POLICY_HND domain_pol = *r->in.domain_handle;
2087 POLICY_HND *user_pol = r->out.user_handle;
2088 struct samr_info *info = NULL;
2089 SEC_DESC *psd = NULL;
2091 uint32 des_access = r->in.access_mask;
2097 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2099 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2100 return NT_STATUS_INVALID_HANDLE;
2102 nt_status = access_check_samr_function(acc_granted,
2103 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2106 if ( !NT_STATUS_IS_OK(nt_status) )
2109 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2110 return NT_STATUS_NO_MEMORY;
2113 /* append the user's RID to it */
2115 if (!sid_append_rid(&sid, r->in.rid))
2116 return NT_STATUS_NO_SUCH_USER;
2118 /* check if access can be granted as requested by client. */
2120 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2121 se_map_generic(&des_access, &usr_generic_mapping);
2123 se_priv_copy( &se_rights, &se_machine_account );
2124 se_priv_add( &se_rights, &se_add_users );
2126 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2127 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2128 &acc_granted, "_samr_OpenUser");
2130 if ( !NT_STATUS_IS_OK(nt_status) )
2134 ret=pdb_getsampwsid(sampass, &sid);
2137 /* check that the SID exists in our domain. */
2139 return NT_STATUS_NO_SUCH_USER;
2142 TALLOC_FREE(sampass);
2144 /* associate the user's SID and access bits with the new handle. */
2145 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2146 return NT_STATUS_NO_MEMORY;
2147 info->acc_granted = acc_granted;
2149 /* get a (unique) handle. open a policy on it. */
2150 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2151 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2153 return NT_STATUS_OK;
2156 /*************************************************************************
2157 get_user_info_7. Safe. Only gives out account_name.
2158 *************************************************************************/
2160 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2161 struct samr_UserInfo7 *r,
2164 struct samu *smbpass=NULL;
2166 const char *account_name = NULL;
2170 if ( !(smbpass = samu_new( mem_ctx )) ) {
2171 return NT_STATUS_NO_MEMORY;
2175 ret = pdb_getsampwsid(smbpass, user_sid);
2179 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2180 return NT_STATUS_NO_SUCH_USER;
2183 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2184 if (!account_name) {
2185 TALLOC_FREE(smbpass);
2186 return NT_STATUS_NO_MEMORY;
2188 TALLOC_FREE(smbpass);
2190 DEBUG(3,("User:[%s]\n", account_name));
2192 init_samr_user_info7(r, account_name);
2194 return NT_STATUS_OK;
2197 /*************************************************************************
2198 get_user_info_9. Only gives out primary group SID.
2199 *************************************************************************/
2201 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2202 struct samr_UserInfo9 *r,
2205 struct samu *smbpass=NULL;
2210 if ( !(smbpass = samu_new( mem_ctx )) ) {
2211 return NT_STATUS_NO_MEMORY;
2215 ret = pdb_getsampwsid(smbpass, user_sid);
2219 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2220 TALLOC_FREE(smbpass);
2221 return NT_STATUS_NO_SUCH_USER;
2224 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2226 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2228 TALLOC_FREE(smbpass);
2230 return NT_STATUS_OK;
2233 /*************************************************************************
2234 get_user_info_16. Safe. Only gives out acb bits.
2235 *************************************************************************/
2237 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2238 struct samr_UserInfo16 *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_info16(r, pdb_get_acct_ctrl(smbpass));
2264 TALLOC_FREE(smbpass);
2266 return NT_STATUS_OK;
2269 /*************************************************************************
2270 get_user_info_18. OK - this is the killer as it gives out password info.
2271 Ensure that this is only allowed on an encrypted connection with a root
2273 *************************************************************************/
2275 static NTSTATUS get_user_info_18(pipes_struct *p,
2276 TALLOC_CTX *mem_ctx,
2277 struct samr_UserInfo18 *r,
2280 struct samu *smbpass=NULL;
2285 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2286 return NT_STATUS_ACCESS_DENIED;
2289 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2290 return NT_STATUS_ACCESS_DENIED;
2294 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2297 if ( !(smbpass = samu_new( mem_ctx )) ) {
2298 return NT_STATUS_NO_MEMORY;
2301 ret = pdb_getsampwsid(smbpass, user_sid);
2304 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2305 TALLOC_FREE(smbpass);
2306 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2309 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2311 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2312 TALLOC_FREE(smbpass);
2313 return NT_STATUS_ACCOUNT_DISABLED;
2316 init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2317 pdb_get_nt_passwd(smbpass));
2319 TALLOC_FREE(smbpass);
2321 return NT_STATUS_OK;
2324 /*************************************************************************
2326 *************************************************************************/
2328 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2329 struct samr_UserInfo20 *r,
2332 struct samu *sampass=NULL;
2334 const char *munged_dial = NULL;
2335 const char *munged_dial_decoded = NULL;
2340 if ( !(sampass = samu_new( mem_ctx )) ) {
2341 return NT_STATUS_NO_MEMORY;
2345 ret = pdb_getsampwsid(sampass, user_sid);
2349 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2350 TALLOC_FREE(sampass);
2351 return NT_STATUS_NO_SUCH_USER;
2354 munged_dial = pdb_get_munged_dial(sampass);
2356 samr_clear_sam_passwd(sampass);
2358 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
2361 blob = base64_decode_data_blob(munged_dial);
2362 munged_dial_decoded = talloc_strndup(mem_ctx,
2363 (const char *)blob.data,
2365 data_blob_free(&blob);
2366 if (!munged_dial_decoded) {
2367 TALLOC_FREE(sampass);
2368 return NT_STATUS_NO_MEMORY;
2373 init_unistr2_from_datablob(&usr->uni_munged_dial, &blob);
2374 init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
2375 data_blob_free(&blob);
2377 init_samr_user_info20(r, munged_dial_decoded);
2379 TALLOC_FREE(sampass);
2381 return NT_STATUS_OK;
2385 /*************************************************************************
2387 *************************************************************************/
2389 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2390 struct samr_UserInfo21 *r,
2392 DOM_SID *domain_sid)
2394 struct samu *pw = NULL;
2396 const DOM_SID *sid_user, *sid_group;
2397 uint32_t rid, primary_gid;
2398 NTTIME last_logon, last_logoff, last_password_change,
2399 acct_expiry, allow_password_change, force_password_change;
2400 time_t must_change_time;
2401 uint8_t password_expired;
2402 const char *account_name, *full_name, *home_directory, *home_drive,
2403 *logon_script, *profile_path, *description,
2404 *workstations, *comment, *parameters;
2405 struct samr_LogonHours logon_hours;
2406 const char *munged_dial = NULL;
2411 if (!(pw = samu_new(mem_ctx))) {
2412 return NT_STATUS_NO_MEMORY;
2416 ret = pdb_getsampwsid(pw, user_sid);
2420 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2422 return NT_STATUS_NO_SUCH_USER;
2425 samr_clear_sam_passwd(pw);
2427 DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2429 sid_user = pdb_get_user_sid(pw);
2431 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2432 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2433 "the domain sid %s. Failing operation.\n",
2434 pdb_get_username(pw), sid_string_dbg(sid_user),
2435 sid_string_dbg(domain_sid)));
2437 return NT_STATUS_UNSUCCESSFUL;
2441 sid_group = pdb_get_group_sid(pw);
2444 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2445 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2446 "which conflicts with the domain sid %s. Failing operation.\n",
2447 pdb_get_username(pw), sid_string_dbg(sid_group),
2448 sid_string_dbg(domain_sid)));
2450 return NT_STATUS_UNSUCCESSFUL;
2453 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2454 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2455 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2456 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2457 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2459 must_change_time = pdb_get_pass_must_change_time(pw);
2460 if (must_change_time == get_time_t_max()) {
2461 unix_to_nt_time_abs(&force_password_change, must_change_time);
2463 unix_to_nt_time(&force_password_change, must_change_time);
2466 if (pdb_get_pass_must_change_time(pw) == 0) {
2467 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2469 password_expired = 0;
2472 munged_dial = pdb_get_munged_dial(pw);
2474 blob = base64_decode_data_blob(munged_dial);
2475 parameters = talloc_strndup(mem_ctx, (const char *)blob.data, blob.length);
2476 data_blob_free(&blob);
2479 return NT_STATUS_NO_MEMORY;
2486 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2487 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2488 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2489 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2490 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2491 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2492 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2493 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2494 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2496 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2500 Look at a user on a real NT4 PDC with usrmgr, press
2501 'ok'. Then you will see that fields_present is set to
2502 0x08f827fa. Look at the user immediately after that again,
2503 and you will see that 0x00fffff is returned. This solves
2504 the problem that you get access denied after having looked
2510 init_unistr2_from_datablob(&usr->uni_munged_dial, &munged_dial_blob);
2511 init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
2512 data_blob_free(&munged_dial_blob);
2516 init_samr_user_info21(r,
2519 last_password_change,
2521 allow_password_change,
2522 force_password_change,
2535 pdb_get_acct_ctrl(pw),
2536 pdb_build_fields_present(pw),
2538 pdb_get_bad_password_count(pw),
2539 pdb_get_logon_count(pw),
2540 0, /* country_code */
2542 0, /* nt_password_set */
2543 0, /* lm_password_set */
2547 return NT_STATUS_OK;
2550 /*******************************************************************
2552 ********************************************************************/
2554 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2555 struct samr_QueryUserInfo *r)
2558 union samr_UserInfo *user_info = NULL;
2559 struct samr_info *info = NULL;
2563 /* search for the handle */
2564 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2565 return NT_STATUS_INVALID_HANDLE;
2567 domain_sid = info->sid;
2569 sid_split_rid(&domain_sid, &rid);
2571 if (!sid_check_is_in_our_domain(&info->sid))
2572 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2574 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2575 sid_string_dbg(&info->sid)));
2577 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2579 return NT_STATUS_NO_MEMORY;
2582 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2584 switch (r->in.level) {
2586 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2587 if (!NT_STATUS_IS_OK(status)) {
2592 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2593 if (!NT_STATUS_IS_OK(status)) {
2598 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2599 if (!NT_STATUS_IS_OK(status)) {
2605 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2606 if (!NT_STATUS_IS_OK(status)) {
2612 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2613 if (!NT_STATUS_IS_OK(status)) {
2619 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2620 &info->sid, &domain_sid);
2621 if (!NT_STATUS_IS_OK(status)) {
2627 return NT_STATUS_INVALID_INFO_CLASS;
2630 *r->out.info = user_info;
2632 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2637 /*******************************************************************
2638 _samr_GetGroupsForUser
2639 ********************************************************************/
2641 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2642 struct samr_GetGroupsForUser *r)
2644 struct samu *sam_pass=NULL;
2647 struct samr_RidWithAttribute dom_gid;
2648 struct samr_RidWithAttribute *gids = NULL;
2649 uint32 primary_group_rid;
2650 size_t num_groups = 0;
2656 bool success = False;
2658 struct samr_RidWithAttributeArray *rids = NULL;
2661 * from the SID in the request:
2662 * we should send back the list of DOMAIN GROUPS
2663 * the user is a member of
2665 * and only the DOMAIN GROUPS
2666 * no ALIASES !!! neither aliases of the domain
2667 * nor aliases of the builtin SID
2672 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2674 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2676 return NT_STATUS_NO_MEMORY;
2679 /* find the policy handle. open a policy on it. */
2680 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2681 return NT_STATUS_INVALID_HANDLE;
2683 result = access_check_samr_function(acc_granted,
2684 SA_RIGHT_USER_GET_GROUPS,
2685 "_samr_GetGroupsForUser");
2686 if (!NT_STATUS_IS_OK(result)) {
2690 if (!sid_check_is_in_our_domain(&sid))
2691 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2693 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2694 return NT_STATUS_NO_MEMORY;
2698 ret = pdb_getsampwsid(sam_pass, &sid);
2702 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2703 sid_string_dbg(&sid)));
2704 return NT_STATUS_NO_SUCH_USER;
2709 /* make both calls inside the root block */
2711 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2712 &sids, &unix_gids, &num_groups);
2713 if ( NT_STATUS_IS_OK(result) ) {
2714 success = sid_peek_check_rid(get_global_sam_sid(),
2715 pdb_get_group_sid(sam_pass),
2716 &primary_group_rid);
2720 if (!NT_STATUS_IS_OK(result)) {
2721 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2722 sid_string_dbg(&sid)));
2727 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2728 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2729 pdb_get_username(sam_pass)));
2730 TALLOC_FREE(sam_pass);
2731 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2737 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2739 dom_gid.rid = primary_group_rid;
2740 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2742 for (i=0; i<num_groups; i++) {
2744 if (!sid_peek_check_rid(get_global_sam_sid(),
2745 &(sids[i]), &dom_gid.rid)) {
2746 DEBUG(10, ("Found sid %s not in our domain\n",
2747 sid_string_dbg(&sids[i])));
2751 if (dom_gid.rid == primary_group_rid) {
2752 /* We added the primary group directly from the
2753 * sam_account. The other SIDs are unique from
2754 * enum_group_memberships */
2758 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2761 rids->count = num_gids;
2764 *r->out.rids = rids;
2766 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2771 /*******************************************************************
2772 samr_QueryDomainInfo_internal
2773 ********************************************************************/
2775 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2777 struct policy_handle *handle,
2779 union samr_DomainInfo **dom_info_ptr)
2781 NTSTATUS status = NT_STATUS_OK;
2782 struct samr_info *info = NULL;
2783 union samr_DomainInfo *dom_info;
2784 uint32 min_pass_len,pass_hist,password_properties;
2785 time_t u_expire, u_min_age;
2786 NTTIME nt_expire, nt_min_age;
2788 time_t u_lock_duration, u_reset_time;
2789 NTTIME nt_lock_duration, nt_reset_time;
2794 uint32 account_policy_temp;
2799 uint32 num_users=0, num_groups=0, num_aliases=0;
2801 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2803 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2805 return NT_STATUS_NO_MEMORY;
2808 *dom_info_ptr = dom_info;
2810 /* find the policy handle. open a policy on it. */
2811 if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2812 return NT_STATUS_INVALID_HANDLE;
2822 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2823 min_pass_len = account_policy_temp;
2825 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2826 pass_hist = account_policy_temp;
2828 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2829 password_properties = account_policy_temp;
2831 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2832 u_expire = account_policy_temp;
2834 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2835 u_min_age = account_policy_temp;
2841 unix_to_nt_time_abs(&nt_expire, u_expire);
2842 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2844 init_samr_DomInfo1(&dom_info->info1,
2845 (uint16)min_pass_len,
2847 password_properties,
2857 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2858 num_groups = count_sam_groups(info->disp_info);
2859 num_aliases = count_sam_aliases(info->disp_info);
2861 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2862 u_logout = account_policy_temp;
2864 unix_to_nt_time_abs(&nt_logout, u_logout);
2866 if (!pdb_get_seq_num(&seq_num))
2867 seq_num = time(NULL);
2873 server_role = ROLE_DOMAIN_PDC;
2874 if (lp_server_role() == ROLE_DOMAIN_BDC)
2875 server_role = ROLE_DOMAIN_BDC;
2877 init_samr_DomInfo2(&dom_info->info2,
2898 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2899 u_logout = (time_t)ul;
2906 unix_to_nt_time_abs(&nt_logout, u_logout);
2908 init_samr_DomInfo3(&dom_info->info3,
2913 init_samr_DomInfo4(&dom_info->info4,
2917 init_samr_DomInfo5(&dom_info->info5,
2918 get_global_sam_name());
2921 /* NT returns its own name when a PDC. win2k and later
2922 * only the name of the PDC if itself is a BDC (samba4
2924 init_samr_DomInfo6(&dom_info->info6,
2928 server_role = ROLE_DOMAIN_PDC;
2929 if (lp_server_role() == ROLE_DOMAIN_BDC)
2930 server_role = ROLE_DOMAIN_BDC;
2932 init_samr_DomInfo7(&dom_info->info7,
2941 if (!pdb_get_seq_num(&seq_num)) {
2942 seq_num = time(NULL);
2949 init_samr_DomInfo8(&dom_info->info8,
2959 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2960 u_lock_duration = account_policy_temp;
2961 if (u_lock_duration != -1) {
2962 u_lock_duration *= 60;
2965 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2966 u_reset_time = account_policy_temp * 60;
2968 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2969 lockout = account_policy_temp;
2975 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2976 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2978 init_samr_DomInfo12(&dom_info->info12,
2984 return NT_STATUS_INVALID_INFO_CLASS;
2987 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2992 /*******************************************************************
2993 _samr_QueryDomainInfo
2994 ********************************************************************/
2996 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2997 struct samr_QueryDomainInfo *r)
2999 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
3001 r->in.domain_handle,
3006 /* W2k3 seems to use the same check for all 3 objects that can be created via
3007 * SAMR, if you try to create for example "Dialup" as an alias it says
3008 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3011 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3013 enum lsa_SidType type;
3016 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3019 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3020 * whether the name already exists */
3021 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3022 NULL, NULL, NULL, &type);
3026 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3027 return NT_STATUS_OK;
3030 DEBUG(5, ("trying to create %s, exists as %s\n",
3031 new_name, sid_type_lookup(type)));
3033 if (type == SID_NAME_DOM_GRP) {
3034 return NT_STATUS_GROUP_EXISTS;
3036 if (type == SID_NAME_ALIAS) {
3037 return NT_STATUS_ALIAS_EXISTS;
3040 /* Yes, the default is NT_STATUS_USER_EXISTS */
3041 return NT_STATUS_USER_EXISTS;
3044 /*******************************************************************
3046 ********************************************************************/
3048 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3049 struct samr_CreateUser2 *r)
3051 const char *account = NULL;
3053 POLICY_HND dom_pol = *r->in.domain_handle;
3054 uint32_t acb_info = r->in.acct_flags;
3055 POLICY_HND *user_pol = r->out.user_handle;
3056 struct samr_info *info = NULL;
3061 /* check this, when giving away 'add computer to domain' privs */
3062 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3063 bool can_add_account = False;
3065 DISP_INFO *disp_info = NULL;
3067 /* Get the domain SID stored in the domain policy */
3068 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3070 return NT_STATUS_INVALID_HANDLE;
3072 nt_status = access_check_samr_function(acc_granted,
3073 SA_RIGHT_DOMAIN_CREATE_USER,
3074 "_samr_CreateUser2");
3075 if (!NT_STATUS_IS_OK(nt_status)) {
3079 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3080 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3081 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3082 this parameter is not an account type */
3083 return NT_STATUS_INVALID_PARAMETER;
3086 account = r->in.account_name->string;
3087 if (account == NULL) {
3088 return NT_STATUS_NO_MEMORY;
3091 nt_status = can_create(p->mem_ctx, account);
3092 if (!NT_STATUS_IS_OK(nt_status)) {
3096 /* determine which user right we need to check based on the acb_info */
3098 if ( acb_info & ACB_WSTRUST )
3100 se_priv_copy( &se_rights, &se_machine_account );
3101 can_add_account = user_has_privileges(
3102 p->pipe_user.nt_user_token, &se_rights );
3104 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3105 account for domain trusts and changes the ACB flags later */
3106 else if ( acb_info & ACB_NORMAL &&
3107 (account[strlen(account)-1] != '$') )
3109 se_priv_copy( &se_rights, &se_add_users );
3110 can_add_account = user_has_privileges(
3111 p->pipe_user.nt_user_token, &se_rights );
3113 else /* implicit assumption of a BDC or domain trust account here
3114 * (we already check the flags earlier) */
3116 if ( lp_enable_privileges() ) {
3117 /* only Domain Admins can add a BDC or domain trust */
3118 se_priv_copy( &se_rights, &se_priv_none );
3119 can_add_account = nt_token_check_domain_rid(
3120 p->pipe_user.nt_user_token,
3121 DOMAIN_GROUP_RID_ADMINS );
3125 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3126 uidtoname(p->pipe_user.ut.uid),
3127 can_add_account ? "True":"False" ));
3129 /********** BEGIN Admin BLOCK **********/
3131 if ( can_add_account )
3134 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3137 if ( can_add_account )
3140 /********** END Admin BLOCK **********/
3142 /* now check for failure */
3144 if ( !NT_STATUS_IS_OK(nt_status) )
3147 /* Get the user's SID */
3149 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3151 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3152 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3153 se_map_generic(&des_access, &usr_generic_mapping);
3155 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3156 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3157 &acc_granted, "_samr_CreateUser2");
3159 if ( !NT_STATUS_IS_OK(nt_status) ) {
3163 /* associate the user's SID with the new handle. */
3164 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3165 return NT_STATUS_NO_MEMORY;
3170 info->acc_granted = acc_granted;
3172 /* get a (unique) handle. open a policy on it. */
3173 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3174 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3177 /* After a "set" ensure we have no cached display info. */
3178 force_flush_samr_cache(info->disp_info);
3180 *r->out.access_granted = acc_granted;
3182 return NT_STATUS_OK;
3185 /*******************************************************************
3187 ********************************************************************/
3189 NTSTATUS _samr_Connect(pipes_struct *p,
3190 struct samr_Connect *r)
3192 struct samr_info *info = NULL;
3193 uint32 des_access = r->in.access_mask;
3197 if (!pipe_access_check(p)) {
3198 DEBUG(3, ("access denied to _samr_Connect\n"));
3199 return NT_STATUS_ACCESS_DENIED;
3202 /* set up the SAMR connect_anon response */
3204 /* associate the user's SID with the new handle. */
3205 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3206 return NT_STATUS_NO_MEMORY;
3208 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3209 was observed from a win98 client trying to enumerate users (when configured
3210 user level access control on shares) --jerry */
3212 if (des_access == MAXIMUM_ALLOWED_ACCESS) {
3213 /* Map to max possible knowing we're filtered below. */
3214 des_access = GENERIC_ALL_ACCESS;
3217 se_map_generic( &des_access, &sam_generic_mapping );
3218 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3220 /* get a (unique) handle. open a policy on it. */
3221 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3222 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3224 return NT_STATUS_OK;
3227 /*******************************************************************
3229 ********************************************************************/
3231 NTSTATUS _samr_Connect2(pipes_struct *p,
3232 struct samr_Connect2 *r)
3234 struct samr_info *info = NULL;
3235 SEC_DESC *psd = NULL;
3237 uint32 des_access = r->in.access_mask;
3242 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3246 if (!pipe_access_check(p)) {
3247 DEBUG(3, ("access denied to _samr_Connect2\n"));
3248 return NT_STATUS_ACCESS_DENIED;
3251 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3252 se_map_generic(&des_access, &sam_generic_mapping);
3254 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3255 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3257 if ( !NT_STATUS_IS_OK(nt_status) )
3260 /* associate the user's SID and access granted with the new handle. */
3261 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3262 return NT_STATUS_NO_MEMORY;
3264 info->acc_granted = acc_granted;
3265 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3267 /* get a (unique) handle. open a policy on it. */
3268 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3269 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3271 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3276 /*******************************************************************
3278 ********************************************************************/
3280 NTSTATUS _samr_Connect4(pipes_struct *p,
3281 struct samr_Connect4 *r)
3283 struct samr_info *info = NULL;
3284 SEC_DESC *psd = NULL;
3286 uint32 des_access = r->in.access_mask;
3291 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3295 if (!pipe_access_check(p)) {
3296 DEBUG(3, ("access denied to samr_Connect4\n"));
3297 return NT_STATUS_ACCESS_DENIED;
3300 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3301 se_map_generic(&des_access, &sam_generic_mapping);
3303 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3304 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3306 if ( !NT_STATUS_IS_OK(nt_status) )
3309 /* associate the user's SID and access granted with the new handle. */
3310 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3311 return NT_STATUS_NO_MEMORY;
3313 info->acc_granted = acc_granted;
3314 info->status = r->in.access_mask; /* ??? */
3316 /* get a (unique) handle. open a policy on it. */
3317 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3318 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3320 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3322 return NT_STATUS_OK;
3325 /*******************************************************************
3327 ********************************************************************/
3329 NTSTATUS _samr_Connect5(pipes_struct *p,
3330 struct samr_Connect5 *r)
3332 struct samr_info *info = NULL;
3333 SEC_DESC *psd = NULL;
3335 uint32 des_access = r->in.access_mask;
3338 struct samr_ConnectInfo1 info1;
3340 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3344 if (!pipe_access_check(p)) {
3345 DEBUG(3, ("access denied to samr_Connect5\n"));
3346 return NT_STATUS_ACCESS_DENIED;
3349 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3350 se_map_generic(&des_access, &sam_generic_mapping);
3352 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3353 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3355 if ( !NT_STATUS_IS_OK(nt_status) )
3358 /* associate the user's SID and access granted with the new handle. */
3359 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3360 return NT_STATUS_NO_MEMORY;
3362 info->acc_granted = acc_granted;
3363 info->status = r->in.access_mask; /* ??? */
3365 /* get a (unique) handle. open a policy on it. */
3366 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3367 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3369 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3371 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3374 *r->out.level_out = 1;
3375 r->out.info_out->info1 = info1;
3377 return NT_STATUS_OK;
3380 /**********************************************************************
3382 **********************************************************************/
3384 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3385 struct samr_LookupDomain *r)
3387 NTSTATUS status = NT_STATUS_OK;
3388 struct samr_info *info;
3389 const char *domain_name;
3390 DOM_SID *sid = NULL;
3392 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3393 return NT_STATUS_INVALID_HANDLE;
3395 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3396 Reverted that change so we will work with RAS servers again */
3398 status = access_check_samr_function(info->acc_granted,
3399 SA_RIGHT_SAM_OPEN_DOMAIN,
3400 "_samr_LookupDomain");
3401 if (!NT_STATUS_IS_OK(status)) {
3405 domain_name = r->in.domain_name->string;
3407 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3409 return NT_STATUS_NO_MEMORY;
3412 if (strequal(domain_name, builtin_domain_name())) {
3413 sid_copy(sid, &global_sid_Builtin);
3415 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3416 status = NT_STATUS_NO_SUCH_DOMAIN;
3420 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3421 sid_string_dbg(sid)));
3428 /**********************************************************************
3430 **********************************************************************/
3432 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3433 struct samr_EnumDomains *r)
3436 struct samr_info *info;
3437 uint32_t num_entries = 2;
3438 struct samr_SamEntry *entry_array = NULL;
3439 struct samr_SamArray *sam;
3441 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3442 return NT_STATUS_INVALID_HANDLE;
3444 status = access_check_samr_function(info->acc_granted,
3445 SA_RIGHT_SAM_ENUM_DOMAINS,
3446 "_samr_EnumDomains");
3447 if (!NT_STATUS_IS_OK(status)) {
3451 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3453 return NT_STATUS_NO_MEMORY;
3456 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3457 struct samr_SamEntry,
3460 return NT_STATUS_NO_MEMORY;
3463 entry_array[0].idx = 0;
3464 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3466 entry_array[1].idx = 1;
3467 init_lsa_String(&entry_array[1].name, "Builtin");
3469 sam->count = num_entries;
3470 sam->entries = entry_array;
3473 *r->out.num_entries = num_entries;
3478 /*******************************************************************
3480 ********************************************************************/
3482 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3483 struct samr_OpenAlias *r)
3486 POLICY_HND domain_pol = *r->in.domain_handle;
3487 uint32 alias_rid = r->in.rid;
3488 POLICY_HND *alias_pol = r->out.alias_handle;
3489 struct samr_info *info = NULL;
3490 SEC_DESC *psd = NULL;
3492 uint32 des_access = r->in.access_mask;
3497 /* find the domain policy and get the SID / access bits stored in the domain policy */
3499 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3500 return NT_STATUS_INVALID_HANDLE;
3502 status = access_check_samr_function(acc_granted,
3503 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3506 if ( !NT_STATUS_IS_OK(status) )
3509 /* append the alias' RID to it */
3511 if (!sid_append_rid(&sid, alias_rid))
3512 return NT_STATUS_NO_SUCH_ALIAS;
3514 /*check if access can be granted as requested by client. */
3516 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3517 se_map_generic(&des_access,&ali_generic_mapping);
3519 se_priv_copy( &se_rights, &se_add_users );
3522 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3523 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3524 &acc_granted, "_samr_OpenAlias");
3526 if ( !NT_STATUS_IS_OK(status) )
3530 /* Check we actually have the requested alias */
3531 enum lsa_SidType type;
3536 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3539 if (!result || (type != SID_NAME_ALIAS)) {
3540 return NT_STATUS_NO_SUCH_ALIAS;
3543 /* make sure there is a mapping */
3545 if ( !sid_to_gid( &sid, &gid ) ) {
3546 return NT_STATUS_NO_SUCH_ALIAS;
3551 /* associate the alias SID with the new handle. */
3552 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3553 return NT_STATUS_NO_MEMORY;
3555 info->acc_granted = acc_granted;
3557 /* get a (unique) handle. open a policy on it. */
3558 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3559 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3561 return NT_STATUS_OK;
3564 /*******************************************************************
3566 ********************************************************************/
3568 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3569 struct samr_UserInfo7 *id7,
3575 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3577 return NT_STATUS_ACCESS_DENIED;
3580 if (!id7->account_name.string) {
3581 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3583 return NT_STATUS_ACCESS_DENIED;
3586 /* check to see if the new username already exists. Note: we can't
3587 reliably lock all backends, so there is potentially the
3588 possibility that a user can be created in between this check and
3589 the rename. The rename should fail, but may not get the
3590 exact same failure status code. I think this is small enough
3591 of a window for this type of operation and the results are
3592 simply that the rename fails with a slightly different status
3593 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3595 rc = can_create(mem_ctx, id7->account_name.string);
3596 if (!NT_STATUS_IS_OK(rc)) {
3600 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3606 /*******************************************************************
3608 ********************************************************************/
3610 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3614 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3619 /* FIX ME: check if the value is really changed --metze */
3620 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3625 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3635 /*******************************************************************
3637 ********************************************************************/
3639 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3643 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3648 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3652 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3656 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3661 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3670 /*******************************************************************
3672 ********************************************************************/
3674 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3678 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3682 copy_id20_to_sam_passwd(pwd, id20);
3684 /* write the change out */
3685 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3695 /*******************************************************************
3697 ********************************************************************/
3699 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3700 struct samr_UserInfo21 *id21,
3706 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3707 return NT_STATUS_INVALID_PARAMETER;
3710 /* we need to separately check for an account rename first */
3712 if (id21->account_name.string &&
3713 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3716 /* check to see if the new username already exists. Note: we can't
3717 reliably lock all backends, so there is potentially the
3718 possibility that a user can be created in between this check and
3719 the rename. The rename should fail, but may not get the
3720 exact same failure status code. I think this is small enough
3721 of a window for this type of operation and the results are
3722 simply that the rename fails with a slightly different status
3723 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3725 status = can_create(mem_ctx, id21->account_name.string);
3726 if (!NT_STATUS_IS_OK(status)) {
3730 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3732 if (!NT_STATUS_IS_OK(status)) {
3733 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3734 nt_errstr(status)));
3739 /* set the new username so that later
3740 functions can work on the new account */
3741 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3744 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3747 * The funny part about the previous two calls is
3748 * that pwd still has the password hashes from the
3749 * passdb entry. These have not been updated from
3750 * id21. I don't know if they need to be set. --jerry
3753 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3754 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3755 if ( !NT_STATUS_IS_OK(status) ) {
3760 /* Don't worry about writing out the user account since the
3761 primary group SID is generated solely from the user's Unix
3764 /* write the change out */
3765 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3772 return NT_STATUS_OK;
3775 /*******************************************************************
3777 ********************************************************************/
3779 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3780 struct samr_UserInfo23 *id23,
3783 char *plaintext_buf = NULL;
3789 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3790 return NT_STATUS_INVALID_PARAMETER;
3793 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3794 pdb_get_username(pwd)));
3796 acct_ctrl = pdb_get_acct_ctrl(pwd);
3798 if (!decode_pw_buffer(mem_ctx,
3799 id23->password.data,
3804 return NT_STATUS_INVALID_PARAMETER;
3807 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3809 return NT_STATUS_ACCESS_DENIED;
3812 copy_id23_to_sam_passwd(pwd, id23);
3814 /* if it's a trust account, don't update /etc/passwd */
3815 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3816 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3817 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3818 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3820 /* update the UNIX password */
3821 if (lp_unix_password_sync() ) {
3822 struct passwd *passwd;
3823 if (pdb_get_username(pwd) == NULL) {
3824 DEBUG(1, ("chgpasswd: User without name???\n"));
3826 return NT_STATUS_ACCESS_DENIED;
3829 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3830 if (passwd == NULL) {
3831 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3834 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3836 return NT_STATUS_ACCESS_DENIED;
3838 TALLOC_FREE(passwd);
3842 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3844 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3845 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3851 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3858 return NT_STATUS_OK;
3861 /*******************************************************************
3863 ********************************************************************/
3865 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
3868 char *plaintext_buf = NULL;
3870 time_t last_set_time;
3871 enum pdb_value_state last_set_state;
3873 DEBUG(5, ("Attempting administrator password change for user %s\n",
3874 pdb_get_username(pwd)));
3876 acct_ctrl = pdb_get_acct_ctrl(pwd);
3877 /* we need to know if it's expired, because this is an admin change, not a
3878 user change, so it's still expired when we're done */
3879 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3880 last_set_time = pdb_get_pass_last_set_time(pwd);
3882 if (!decode_pw_buffer(talloc_tos(),
3891 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3896 /* if it's a trust account, don't update /etc/passwd */
3897 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3898 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3899 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3900 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3902 /* update the UNIX password */
3903 if (lp_unix_password_sync()) {
3904 struct passwd *passwd;
3906 if (pdb_get_username(pwd) == NULL) {
3907 DEBUG(1, ("chgpasswd: User without name???\n"));
3912 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3913 if (passwd == NULL) {
3914 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3917 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3921 TALLOC_FREE(passwd);
3925 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3927 /* restore last set time as this is an admin change, not a user pw change */
3928 pdb_set_pass_last_set_time (pwd, last_set_time, last_set_state);
3930 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3932 /* update the SAMBA password */
3933 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3943 /*******************************************************************
3945 ********************************************************************/
3947 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
3948 struct samr_UserInfo25 *id25,
3954 DEBUG(5, ("set_user_info_25: NULL id25\n"));
3955 return NT_STATUS_INVALID_PARAMETER;
3958 copy_id25_to_sam_passwd(pwd, id25);
3960 /* write the change out */
3961 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3967 * We need to "pdb_update_sam_account" before the unix primary group
3968 * is set, because the idealx scripts would also change the
3969 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
3970 * the delete explicit / add explicit, which would then fail to find
3971 * the previous primaryGroupSid value.
3974 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3975 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3976 if ( !NT_STATUS_IS_OK(status) ) {
3981 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
3984 return NT_STATUS_OK;
3987 /*******************************************************************
3988 samr_SetUserInfo_internal
3989 ********************************************************************/
3991 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
3993 struct policy_handle *user_handle,
3995 union samr_UserInfo *info)
3998 struct samu *pwd = NULL;
4000 POLICY_HND *pol = user_handle;
4001 uint16_t switch_value = level;
4002 uint32_t acc_granted;
4003 uint32_t acc_required;
4005 bool has_enough_rights = False;
4007 DISP_INFO *disp_info = NULL;
4009 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4011 /* find the policy handle. open a policy on it. */
4012 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4013 return NT_STATUS_INVALID_HANDLE;
4016 /* This is tricky. A WinXP domain join sets
4017 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4018 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4019 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4020 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4021 we'll use the set from the WinXP join as the basis. */
4023 switch (switch_value) {
4028 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4031 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4032 SA_RIGHT_USER_SET_ATTRIBUTES |
4033 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4037 status = access_check_samr_function(acc_granted,
4040 if (!NT_STATUS_IS_OK(status)) {
4044 DEBUG(5, ("%s: sid:%s, level:%d\n",
4045 fn_name, sid_string_dbg(&sid), switch_value));
4048 DEBUG(5, ("%s: NULL info level\n", fn_name));
4049 return NT_STATUS_INVALID_INFO_CLASS;
4052 if (!(pwd = samu_new(NULL))) {
4053 return NT_STATUS_NO_MEMORY;
4057 ret = pdb_getsampwsid(pwd, &sid);
4062 return NT_STATUS_NO_SUCH_USER;
4065 /* deal with machine password changes differently from userinfo changes */
4066 /* check to see if we have the sufficient rights */
4068 acb_info = pdb_get_acct_ctrl(pwd);
4069 if (acb_info & ACB_WSTRUST)
4070 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4071 &se_machine_account);
4072 else if (acb_info & ACB_NORMAL)
4073 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4075 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4076 if (lp_enable_privileges()) {
4077 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4078 DOMAIN_GROUP_RID_ADMINS);
4082 DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4084 uidtoname(p->pipe_user.ut.uid),
4085 has_enough_rights ? "" : " not"));
4087 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4089 if (has_enough_rights) {
4093 /* ok! user info levels (lots: see MSDEV help), off we go... */
4095 switch (switch_value) {
4098 status = set_user_info_7(p->mem_ctx,
4103 if (!set_user_info_16(&info->info16, pwd)) {
4104 status = NT_STATUS_ACCESS_DENIED;
4109 /* Used by AS/U JRA. */
4110 if (!set_user_info_18(&info->info18, pwd)) {
4111 status = NT_STATUS_ACCESS_DENIED;
4116 if (!set_user_info_20(&info->info20, pwd)) {
4117 status = NT_STATUS_ACCESS_DENIED;
4122 status = set_user_info_21(p->mem_ctx,
4123 &info->info21, pwd);
4127 if (!p->session_key.length) {
4128 status = NT_STATUS_NO_USER_SESSION_KEY;
4130 SamOEMhashBlob(info->info23.password.data, 516,
4133 dump_data(100, info->info23.password.data, 516);
4135 status = set_user_info_23(p->mem_ctx,
4136 &info->info23, pwd);
4140 if (!p->session_key.length) {
4141 status = NT_STATUS_NO_USER_SESSION_KEY;
4143 SamOEMhashBlob(info->info24.password.data,
4147 dump_data(100, info->info24.password.data, 516);
4149 if (!set_user_info_pw(info->info24.password.data, pwd)) {
4150 status = NT_STATUS_ACCESS_DENIED;
4155 if (!p->session_key.length) {
4156 status = NT_STATUS_NO_USER_SESSION_KEY;
4158 encode_or_decode_arc4_passwd_buffer(info->info25.password.data,
4161 dump_data(100, info->info25.password.data, 532);
4163 status = set_user_info_25(p->mem_ctx,
4164 &info->info25, pwd);
4165 if (!NT_STATUS_IS_OK(status)) {
4168 if (!set_user_info_pw(info->info25.password.data, pwd)) {
4169 status = NT_STATUS_ACCESS_DENIED;
4174 if (!p->session_key.length) {
4175 status = NT_STATUS_NO_USER_SESSION_KEY;
4177 encode_or_decode_arc4_passwd_buffer(info->info26.password.data,
4180 dump_data(100, info->info26.password.data, 516);
4182 if (!set_user_info_pw(info->info26.password.data, pwd)) {
4183 status = NT_STATUS_ACCESS_DENIED;
4188 status = NT_STATUS_INVALID_INFO_CLASS;
4193 if (has_enough_rights) {
4197 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4199 if (NT_STATUS_IS_OK(status)) {
4200 force_flush_samr_cache(disp_info);
4206 /*******************************************************************
4208 ********************************************************************/
4210 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4211 struct samr_SetUserInfo *r)
4213 return samr_SetUserInfo_internal("_samr_SetUserInfo",
4220 /*******************************************************************
4222 ********************************************************************/
4224 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4225 struct samr_SetUserInfo2 *r)
4227 return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4234 /*********************************************************************
4235 _samr_GetAliasMembership
4236 *********************************************************************/
4238 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4239 struct samr_GetAliasMembership *r)
4241 size_t num_alias_rids;
4243 struct samr_info *info = NULL;
4251 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4253 /* find the policy handle. open a policy on it. */
4254 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4255 return NT_STATUS_INVALID_HANDLE;
4257 ntstatus1 = access_check_samr_function(info->acc_granted,
4258 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4259 "_samr_GetAliasMembership");
4260 ntstatus2 = access_check_samr_function(info->acc_granted,
4261 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4262 "_samr_GetAliasMembership");
4264 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4265 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4266 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4267 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4271 if (!sid_check_is_domain(&info->sid) &&
4272 !sid_check_is_builtin(&info->sid))
4273 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4275 if (r->in.sids->num_sids) {
4276 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4278 if (members == NULL)
4279 return NT_STATUS_NO_MEMORY;
4284 for (i=0; i<r->in.sids->num_sids; i++)
4285 sid_copy(&members[i], r->in.sids->sids[i].sid);
4291 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4292 r->in.sids->num_sids,
4293 &alias_rids, &num_alias_rids);
4296 if (!NT_STATUS_IS_OK(ntstatus1)) {
4300 r->out.rids->count = num_alias_rids;
4301 r->out.rids->ids = alias_rids;
4303 return NT_STATUS_OK;
4306 /*********************************************************************
4307 _samr_GetMembersInAlias
4308 *********************************************************************/
4310 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4311 struct samr_GetMembersInAlias *r)
4315 size_t num_sids = 0;
4316 struct lsa_SidPtr *sids = NULL;
4317 DOM_SID *pdb_sids = NULL;
4323 /* find the policy handle. open a policy on it. */
4324 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4325 return NT_STATUS_INVALID_HANDLE;
4327 status = access_check_samr_function(acc_granted,
4328 SA_RIGHT_ALIAS_GET_MEMBERS,
4329 "_samr_GetMembersInAlias");
4330 if (!NT_STATUS_IS_OK(status)) {
4334 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4337 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4340 if (!NT_STATUS_IS_OK(status)) {
4345 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4347 TALLOC_FREE(pdb_sids);
4348 return NT_STATUS_NO_MEMORY;
4352 for (i = 0; i < num_sids; i++) {
4353 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4355 TALLOC_FREE(pdb_sids);
4356 return NT_STATUS_NO_MEMORY;
4360 r->out.sids->num_sids = num_sids;
4361 r->out.sids->sids = sids;
4363 TALLOC_FREE(pdb_sids);
4365 return NT_STATUS_OK;
4368 /*********************************************************************
4369 _samr_QueryGroupMember
4370 *********************************************************************/
4372 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4373 struct samr_QueryGroupMember *r)
4376 size_t i, num_members;
4384 struct samr_RidTypeArray *rids = NULL;
4386 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4388 return NT_STATUS_NO_MEMORY;
4391 /* find the policy handle. open a policy on it. */
4392 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4393 return NT_STATUS_INVALID_HANDLE;
4395 status = access_check_samr_function(acc_granted,
4396 SA_RIGHT_GROUP_GET_MEMBERS,
4397 "_samr_QueryGroupMember");
4398 if (!NT_STATUS_IS_OK(status)) {
4402 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4404 if (!sid_check_is_in_our_domain(&group_sid)) {
4405 DEBUG(3, ("sid %s is not in our domain\n",
4406 sid_string_dbg(&group_sid)));
4407 return NT_STATUS_NO_SUCH_GROUP;
4410 DEBUG(10, ("lookup on Domain SID\n"));
4413 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4414 &rid, &num_members);
4417 if (!NT_STATUS_IS_OK(status))
4421 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4423 return NT_STATUS_NO_MEMORY;
4429 for (i=0; i<num_members; i++)
4430 attr[i] = SID_NAME_USER;
4432 rids->count = num_members;
4436 *r->out.rids = rids;
4438 return NT_STATUS_OK;
4441 /*********************************************************************
4442 _samr_AddAliasMember
4443 *********************************************************************/
4445 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4446 struct samr_AddAliasMember *r)
4451 bool can_add_accounts;
4453 DISP_INFO *disp_info = NULL;
4455 /* Find the policy handle. Open a policy on it. */
4456 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4457 return NT_STATUS_INVALID_HANDLE;
4459 status = access_check_samr_function(acc_granted,
4460 SA_RIGHT_ALIAS_ADD_MEMBER,
4461 "_samr_AddAliasMember");
4462 if (!NT_STATUS_IS_OK(status)) {
4466 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4468 se_priv_copy( &se_rights, &se_add_users );
4469 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4471 /******** BEGIN SeAddUsers BLOCK *********/
4473 if ( can_add_accounts )
4476 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4478 if ( can_add_accounts )
4481 /******** END SeAddUsers BLOCK *********/
4483 if (NT_STATUS_IS_OK(status)) {
4484 force_flush_samr_cache(disp_info);
4490 /*********************************************************************
4491 _samr_DeleteAliasMember
4492 *********************************************************************/
4494 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4495 struct samr_DeleteAliasMember *r)
4500 bool can_add_accounts;
4502 DISP_INFO *disp_info = NULL;
4504 /* Find the policy handle. Open a policy on it. */
4505 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4506 return NT_STATUS_INVALID_HANDLE;
4508 status = access_check_samr_function(acc_granted,
4509 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4510 "_samr_DeleteAliasMember");
4511 if (!NT_STATUS_IS_OK(status)) {
4515 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4516 sid_string_dbg(&alias_sid)));
4518 se_priv_copy( &se_rights, &se_add_users );
4519 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4521 /******** BEGIN SeAddUsers BLOCK *********/
4523 if ( can_add_accounts )
4526 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4528 if ( can_add_accounts )
4531 /******** END SeAddUsers BLOCK *********/
4533 if (NT_STATUS_IS_OK(status)) {
4534 force_flush_samr_cache(disp_info);
4540 /*********************************************************************
4541 _samr_AddGroupMember
4542 *********************************************************************/
4544 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4545 struct samr_AddGroupMember *r)
4552 bool can_add_accounts;
4553 DISP_INFO *disp_info = NULL;
4555 /* Find the policy handle. Open a policy on it. */
4556 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4557 return NT_STATUS_INVALID_HANDLE;
4559 status = access_check_samr_function(acc_granted,
4560 SA_RIGHT_GROUP_ADD_MEMBER,
4561 "_samr_AddGroupMember");
4562 if (!NT_STATUS_IS_OK(status)) {
4566 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4568 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4570 return NT_STATUS_INVALID_HANDLE;
4573 se_priv_copy( &se_rights, &se_add_users );
4574 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4576 /******** BEGIN SeAddUsers BLOCK *********/
4578 if ( can_add_accounts )
4581 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4583 if ( can_add_accounts )
4586 /******** END SeAddUsers BLOCK *********/
4588 force_flush_samr_cache(disp_info);
4593 /*********************************************************************
4594 _samr_DeleteGroupMember
4595 *********************************************************************/
4597 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4598 struct samr_DeleteGroupMember *r)
4606 bool can_add_accounts;
4607 DISP_INFO *disp_info = NULL;
4610 * delete the group member named r->in.rid
4611 * who is a member of the sid associated with the handle
4612 * the rid is a user's rid as the group is a domain group.
4615 /* Find the policy handle. Open a policy on it. */
4616 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4617 return NT_STATUS_INVALID_HANDLE;
4619 status = access_check_samr_function(acc_granted,
4620 SA_RIGHT_GROUP_REMOVE_MEMBER,
4621 "_samr_DeleteGroupMember");
4622 if (!NT_STATUS_IS_OK(status)) {
4626 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4628 return NT_STATUS_INVALID_HANDLE;
4631 se_priv_copy( &se_rights, &se_add_users );
4632 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4634 /******** BEGIN SeAddUsers BLOCK *********/
4636 if ( can_add_accounts )
4639 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4641 if ( can_add_accounts )
4644 /******** END SeAddUsers BLOCK *********/
4646 force_flush_samr_cache(disp_info);
4651 /*********************************************************************
4653 *********************************************************************/
4655 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4656 struct samr_DeleteUser *r)
4660 struct samu *sam_pass=NULL;
4662 bool can_add_accounts;
4664 DISP_INFO *disp_info = NULL;
4667 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4669 /* Find the policy handle. Open a policy on it. */
4670 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4671 return NT_STATUS_INVALID_HANDLE;
4673 status = access_check_samr_function(acc_granted,
4674 STD_RIGHT_DELETE_ACCESS,
4675 "_samr_DeleteUser");
4676 if (!NT_STATUS_IS_OK(status)) {
4680 if (!sid_check_is_in_our_domain(&user_sid))
4681 return NT_STATUS_CANNOT_DELETE;
4683 /* check if the user exists before trying to delete */
4684 if ( !(sam_pass = samu_new( NULL )) ) {
4685 return NT_STATUS_NO_MEMORY;
4689 ret = pdb_getsampwsid(sam_pass, &user_sid);
4693 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4694 sid_string_dbg(&user_sid)));
4695 TALLOC_FREE(sam_pass);
4696 return NT_STATUS_NO_SUCH_USER;
4699 acb_info = pdb_get_acct_ctrl(sam_pass);
4701 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4702 if ( acb_info & ACB_WSTRUST ) {
4703 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4705 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4708 /******** BEGIN SeAddUsers BLOCK *********/
4710 if ( can_add_accounts )
4713 status = pdb_delete_user(p->mem_ctx, sam_pass);
4715 if ( can_add_accounts )
4718 /******** END SeAddUsers BLOCK *********/
4720 if ( !NT_STATUS_IS_OK(status) ) {
4721 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4722 "user %s: %s.\n", pdb_get_username(sam_pass),
4723 nt_errstr(status)));
4724 TALLOC_FREE(sam_pass);
4729 TALLOC_FREE(sam_pass);
4731 if (!close_policy_hnd(p, r->in.user_handle))
4732 return NT_STATUS_OBJECT_NAME_INVALID;
4734 force_flush_samr_cache(disp_info);
4736 return NT_STATUS_OK;
4739 /*********************************************************************
4740 _samr_DeleteDomainGroup
4741 *********************************************************************/
4743 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4744 struct samr_DeleteDomainGroup *r)
4751 bool can_add_accounts;
4752 DISP_INFO *disp_info = NULL;
4754 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4756 /* Find the policy handle. Open a policy on it. */
4757 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4758 return NT_STATUS_INVALID_HANDLE;
4760 status = access_check_samr_function(acc_granted,
4761 STD_RIGHT_DELETE_ACCESS,
4762 "_samr_DeleteDomainGroup");
4763 if (!NT_STATUS_IS_OK(status)) {
4767 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4769 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4771 return NT_STATUS_NO_SUCH_GROUP;
4774 se_priv_copy( &se_rights, &se_add_users );
4775 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4777 /******** BEGIN SeAddUsers BLOCK *********/
4779 if ( can_add_accounts )
4782 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4784 if ( can_add_accounts )
4787 /******** END SeAddUsers BLOCK *********/
4789 if ( !NT_STATUS_IS_OK(status) ) {
4790 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4791 "entry for group %s: %s\n",
4792 sid_string_dbg(&group_sid),
4793 nt_errstr(status)));
4797 if (!close_policy_hnd(p, r->in.group_handle))
4798 return NT_STATUS_OBJECT_NAME_INVALID;
4800 force_flush_samr_cache(disp_info);
4802 return NT_STATUS_OK;
4805 /*********************************************************************
4806 _samr_DeleteDomAlias
4807 *********************************************************************/
4809 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4810 struct samr_DeleteDomAlias *r)
4815 bool can_add_accounts;
4817 DISP_INFO *disp_info = NULL;
4819 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4821 /* Find the policy handle. Open a policy on it. */
4822 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4823 return NT_STATUS_INVALID_HANDLE;
4825 /* copy the handle to the outgoing reply */
4827 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4829 status = access_check_samr_function(acc_granted,
4830 STD_RIGHT_DELETE_ACCESS,
4831 "_samr_DeleteDomAlias");
4832 if (!NT_STATUS_IS_OK(status)) {
4836 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4838 /* Don't let Windows delete builtin groups */
4840 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4841 return NT_STATUS_SPECIAL_ACCOUNT;
4844 if (!sid_check_is_in_our_domain(&alias_sid))
4845 return NT_STATUS_NO_SUCH_ALIAS;
4847 DEBUG(10, ("lookup on Local SID\n"));
4849 se_priv_copy( &se_rights, &se_add_users );
4850 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4852 /******** BEGIN SeAddUsers BLOCK *********/
4854 if ( can_add_accounts )
4857 /* Have passdb delete the alias */
4858 status = pdb_delete_alias(&alias_sid);
4860 if ( can_add_accounts )
4863 /******** END SeAddUsers BLOCK *********/
4865 if ( !NT_STATUS_IS_OK(status))
4868 if (!close_policy_hnd(p, r->in.alias_handle))
4869 return NT_STATUS_OBJECT_NAME_INVALID;
4871 force_flush_samr_cache(disp_info);
4873 return NT_STATUS_OK;
4876 /*********************************************************************
4877 _samr_CreateDomainGroup
4878 *********************************************************************/
4880 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4881 struct samr_CreateDomainGroup *r)
4888 struct samr_info *info;
4891 bool can_add_accounts;
4892 DISP_INFO *disp_info = NULL;
4894 /* Find the policy handle. Open a policy on it. */
4895 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4896 return NT_STATUS_INVALID_HANDLE;
4898 status = access_check_samr_function(acc_granted,
4899 SA_RIGHT_DOMAIN_CREATE_GROUP,
4900 "_samr_CreateDomainGroup");
4901 if (!NT_STATUS_IS_OK(status)) {
4905 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4906 return NT_STATUS_ACCESS_DENIED;
4908 name = r->in.name->string;
4910 return NT_STATUS_NO_MEMORY;
4913 status = can_create(p->mem_ctx, name);
4914 if (!NT_STATUS_IS_OK(status)) {
4918 se_priv_copy( &se_rights, &se_add_users );
4919 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4921 /******** BEGIN SeAddUsers BLOCK *********/
4923 if ( can_add_accounts )
4926 /* check that we successfully create the UNIX group */
4928 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
4930 if ( can_add_accounts )
4933 /******** END SeAddUsers BLOCK *********/
4935 /* check if we should bail out here */
4937 if ( !NT_STATUS_IS_OK(status) )
4940 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
4942 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4943 return NT_STATUS_NO_MEMORY;
4945 /* they created it; let the user do what he wants with it */
4947 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
4949 /* get a (unique) handle. open a policy on it. */
4950 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
4951 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4953 force_flush_samr_cache(disp_info);
4955 return NT_STATUS_OK;
4958 /*********************************************************************
4959 _samr_CreateDomAlias
4960 *********************************************************************/
4962 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
4963 struct samr_CreateDomAlias *r)
4967 const char *name = NULL;
4968 struct samr_info *info;
4973 bool can_add_accounts;
4974 DISP_INFO *disp_info = NULL;
4976 /* Find the policy handle. Open a policy on it. */
4977 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4978 return NT_STATUS_INVALID_HANDLE;
4980 result = access_check_samr_function(acc_granted,
4981 SA_RIGHT_DOMAIN_CREATE_ALIAS,
4982 "_samr_CreateDomAlias");
4983 if (!NT_STATUS_IS_OK(result)) {
4987 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4988 return NT_STATUS_ACCESS_DENIED;
4990 name = r->in.alias_name->string;
4992 se_priv_copy( &se_rights, &se_add_users );
4993 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4995 result = can_create(p->mem_ctx, name);
4996 if (!NT_STATUS_IS_OK(result)) {
5000 /******** BEGIN SeAddUsers BLOCK *********/
5002 if ( can_add_accounts )
5005 /* Have passdb create the alias */
5006 result = pdb_create_alias(name, r->out.rid);
5008 if ( can_add_accounts )
5011 /******** END SeAddUsers BLOCK *********/
5013 if (!NT_STATUS_IS_OK(result)) {
5014 DEBUG(10, ("pdb_create_alias failed: %s\n",
5015 nt_errstr(result)));
5019 sid_copy(&info_sid, get_global_sam_sid());
5020 sid_append_rid(&info_sid, *r->out.rid);
5022 if (!sid_to_gid(&info_sid, &gid)) {
5023 DEBUG(10, ("Could not find alias just created\n"));
5024 return NT_STATUS_ACCESS_DENIED;
5027 /* check if the group has been successfully created */
5028 if ( getgrgid(gid) == NULL ) {
5029 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5031 return NT_STATUS_ACCESS_DENIED;
5034 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5035 return NT_STATUS_NO_MEMORY;
5037 /* they created it; let the user do what he wants with it */
5039 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5041 /* get a (unique) handle. open a policy on it. */
5042 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5043 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5045 force_flush_samr_cache(disp_info);
5047 return NT_STATUS_OK;
5050 /*********************************************************************
5051 _samr_QueryGroupInfo
5052 *********************************************************************/
5054 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5055 struct samr_QueryGroupInfo *r)
5060 union samr_GroupInfo *info = NULL;
5063 uint32_t attributes = SE_GROUP_MANDATORY |
5064 SE_GROUP_ENABLED_BY_DEFAULT |
5066 const char *group_name = NULL;
5067 const char *group_description = NULL;
5069 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5070 return NT_STATUS_INVALID_HANDLE;
5072 status = access_check_samr_function(acc_granted,
5073 SA_RIGHT_GROUP_LOOKUP_INFO,
5074 "_samr_QueryGroupInfo");
5075 if (!NT_STATUS_IS_OK(status)) {
5080 ret = get_domain_group_from_sid(group_sid, &map);
5083 return NT_STATUS_INVALID_HANDLE;
5085 /* FIXME: map contains fstrings */
5086 group_name = talloc_strdup(r, map.nt_name);
5087 group_description = talloc_strdup(r, map.comment);
5089 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5091 return NT_STATUS_NO_MEMORY;
5094 switch (r->in.level) {
5100 status = pdb_enum_group_members(
5101 p->mem_ctx, &group_sid, &members, &num_members);
5104 if (!NT_STATUS_IS_OK(status)) {
5108 init_samr_group_info1(&info->all,
5116 init_samr_group_info2(&info->name,
5120 init_samr_group_info3(&info->attributes,
5124 init_samr_group_info4(&info->description,
5135 status = pdb_enum_group_members(
5136 p->mem_ctx, &group_sid, &members, &num_members);
5139 if (!NT_STATUS_IS_OK(status)) {
5143 init_samr_group_info5(&info->all2,
5146 0, /* num_members - in w2k3 this is always 0 */
5152 return NT_STATUS_INVALID_INFO_CLASS;
5155 *r->out.info = info;
5157 return NT_STATUS_OK;
5160 /*********************************************************************
5162 *********************************************************************/
5164 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5165 struct samr_SetGroupInfo *r)
5172 bool can_mod_accounts;
5173 DISP_INFO *disp_info = NULL;
5175 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5176 return NT_STATUS_INVALID_HANDLE;
5178 status = access_check_samr_function(acc_granted,
5179 SA_RIGHT_GROUP_SET_INFO,
5180 "_samr_SetGroupInfo");
5181 if (!NT_STATUS_IS_OK(status)) {
5186 ret = get_domain_group_from_sid(group_sid, &map);
5189 return NT_STATUS_NO_SUCH_GROUP;
5191 switch (r->in.level) {
5193 fstrcpy(map.comment, r->in.info->all.description.string);
5196 fstrcpy(map.comment, r->in.info->description.string);
5199 return NT_STATUS_INVALID_INFO_CLASS;
5202 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5204 /******** BEGIN SeAddUsers BLOCK *********/
5206 if ( can_mod_accounts )
5209 status = pdb_update_group_mapping_entry(&map);
5211 if ( can_mod_accounts )
5214 /******** End SeAddUsers BLOCK *********/
5216 if (NT_STATUS_IS_OK(status)) {
5217 force_flush_samr_cache(disp_info);
5223 /*********************************************************************
5225 *********************************************************************/
5227 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5228 struct samr_SetAliasInfo *r)
5231 struct acct_info info;
5233 bool can_mod_accounts;
5235 DISP_INFO *disp_info = NULL;
5237 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5238 return NT_STATUS_INVALID_HANDLE;
5240 status = access_check_samr_function(acc_granted,
5241 SA_RIGHT_ALIAS_SET_INFO,
5242 "_samr_SetAliasInfo");
5243 if (!NT_STATUS_IS_OK(status)) {
5247 /* get the current group information */
5250 status = pdb_get_aliasinfo( &group_sid, &info );
5253 if ( !NT_STATUS_IS_OK(status))
5256 switch (r->in.level) {
5261 /* We currently do not support renaming groups in the
5262 the BUILTIN domain. Refer to util_builtin.c to understand
5263 why. The eventually needs to be fixed to be like Windows
5264 where you can rename builtin groups, just not delete them */
5266 if ( sid_check_is_in_builtin( &group_sid ) ) {
5267 return NT_STATUS_SPECIAL_ACCOUNT;
5270 /* There has to be a valid name (and it has to be different) */
5272 if ( !r->in.info->name.string )
5273 return NT_STATUS_INVALID_PARAMETER;
5275 /* If the name is the same just reply "ok". Yes this
5276 doesn't allow you to change the case of a group name. */
5278 if ( strequal( r->in.info->name.string, info.acct_name ) )
5279 return NT_STATUS_OK;
5281 fstrcpy( info.acct_name, r->in.info->name.string);
5283 /* make sure the name doesn't already exist as a user
5286 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5287 status = can_create( p->mem_ctx, group_name );
5288 if ( !NT_STATUS_IS_OK( status ) )
5292 case ALIASINFODESCRIPTION:
5293 if (r->in.info->description.string) {
5294 fstrcpy(info.acct_desc,
5295 r->in.info->description.string);
5297 fstrcpy( info.acct_desc, "" );
5301 return NT_STATUS_INVALID_INFO_CLASS;
5304 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5306 /******** BEGIN SeAddUsers BLOCK *********/
5308 if ( can_mod_accounts )
5311 status = pdb_set_aliasinfo( &group_sid, &info );
5313 if ( can_mod_accounts )
5316 /******** End SeAddUsers BLOCK *********/
5318 if (NT_STATUS_IS_OK(status))
5319 force_flush_samr_cache(disp_info);
5324 /****************************************************************
5326 ****************************************************************/
5328 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5329 struct samr_GetDomPwInfo *r)
5331 /* Perform access check. Since this rpc does not require a
5332 policy handle it will not be caught by the access checks on
5333 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5335 if (!pipe_access_check(p)) {
5336 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5337 return NT_STATUS_ACCESS_DENIED;
5340 /* Actually, returning zeros here works quite well :-). */
5341 ZERO_STRUCTP(r->out.info);
5343 return NT_STATUS_OK;
5346 /*********************************************************************
5348 *********************************************************************/
5350 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5351 struct samr_OpenGroup *r)
5357 struct samr_info *info;
5358 SEC_DESC *psd = NULL;
5360 uint32 des_access = r->in.access_mask;
5367 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5368 return NT_STATUS_INVALID_HANDLE;
5370 status = access_check_samr_function(acc_granted,
5371 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5374 if ( !NT_STATUS_IS_OK(status) )
5377 /*check if access can be granted as requested by client. */
5378 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5379 se_map_generic(&des_access,&grp_generic_mapping);
5381 se_priv_copy( &se_rights, &se_add_users );
5383 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5384 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5385 &acc_granted, "_samr_OpenGroup");
5387 if ( !NT_STATUS_IS_OK(status) )
5390 /* this should not be hard-coded like this */
5392 if (!sid_equal(&sid, get_global_sam_sid()))
5393 return NT_STATUS_ACCESS_DENIED;
5395 sid_copy(&info_sid, get_global_sam_sid());
5396 sid_append_rid(&info_sid, r->in.rid);
5397 sid_to_fstring(sid_string, &info_sid);
5399 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5400 return NT_STATUS_NO_MEMORY;
5402 info->acc_granted = acc_granted;
5404 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5406 /* check if that group really exists */
5408 ret = get_domain_group_from_sid(info->sid, &map);
5411 return NT_STATUS_NO_SUCH_GROUP;
5413 /* get a (unique) handle. open a policy on it. */
5414 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5415 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5417 return NT_STATUS_OK;
5420 /*********************************************************************
5421 _samr_RemoveMemberFromForeignDomain
5422 *********************************************************************/
5424 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5425 struct samr_RemoveMemberFromForeignDomain *r)
5427 DOM_SID delete_sid, domain_sid;
5430 DISP_INFO *disp_info = NULL;
5432 sid_copy( &delete_sid, r->in.sid );
5434 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5435 sid_string_dbg(&delete_sid)));
5437 /* Find the policy handle. Open a policy on it. */
5439 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5440 &acc_granted, &disp_info))
5441 return NT_STATUS_INVALID_HANDLE;
5443 result = access_check_samr_function(acc_granted,
5444 STD_RIGHT_DELETE_ACCESS,
5445 "_samr_RemoveMemberFromForeignDomain");
5447 if (!NT_STATUS_IS_OK(result))
5450 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5451 sid_string_dbg(&domain_sid)));
5453 /* we can only delete a user from a group since we don't have
5454 nested groups anyways. So in the latter case, just say OK */
5456 /* TODO: The above comment nowadays is bogus. Since we have nested
5457 * groups now, and aliases members are never reported out of the unix
5458 * group membership, the "just say OK" makes this call a no-op. For
5459 * us. This needs fixing however. */
5461 /* I've only ever seen this in the wild when deleting a user from
5462 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5463 * is the user about to be deleted. I very much suspect this is the
5464 * only application of this call. To verify this, let people report
5467 if (!sid_check_is_builtin(&domain_sid)) {
5468 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5469 "global_sam_sid() = %s\n",
5470 sid_string_dbg(&domain_sid),
5471 sid_string_dbg(get_global_sam_sid())));
5472 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5473 return NT_STATUS_OK;
5476 force_flush_samr_cache(disp_info);
5478 result = NT_STATUS_OK;
5483 /*******************************************************************
5484 _samr_QueryDomainInfo2
5485 ********************************************************************/
5487 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5488 struct samr_QueryDomainInfo2 *r)
5490 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5492 r->in.domain_handle,
5497 /*******************************************************************
5499 ********************************************************************/
5501 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5502 struct samr_SetDomainInfo *r)
5504 time_t u_expire, u_min_age;
5506 time_t u_lock_duration, u_reset_time;
5508 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5510 /* find the policy handle. open a policy on it. */
5511 if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5512 return NT_STATUS_INVALID_HANDLE;
5514 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5516 switch (r->in.level) {
5518 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5519 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5520 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5521 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5522 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5523 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5524 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5529 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5530 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5539 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5540 if (u_lock_duration != -1)
5541 u_lock_duration /= 60;
5543 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5545 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5546 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5547 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5550 return NT_STATUS_INVALID_INFO_CLASS;
5553 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5555 return NT_STATUS_OK;
5558 /****************************************************************
5559 ****************************************************************/
5561 NTSTATUS _samr_Shutdown(pipes_struct *p,
5562 struct samr_Shutdown *r)
5564 p->rng_fault_state = true;
5565 return NT_STATUS_NOT_IMPLEMENTED;
5568 /****************************************************************
5569 ****************************************************************/
5571 NTSTATUS _samr_CreateUser(pipes_struct *p,
5572 struct samr_CreateUser *r)
5574 p->rng_fault_state = true;
5575 return NT_STATUS_NOT_IMPLEMENTED;
5578 /****************************************************************
5579 ****************************************************************/
5581 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5582 struct samr_SetMemberAttributesOfGroup *r)
5584 p->rng_fault_state = true;
5585 return NT_STATUS_NOT_IMPLEMENTED;
5588 /****************************************************************
5589 ****************************************************************/
5591 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5592 struct samr_ChangePasswordUser *r)
5594 p->rng_fault_state = true;
5595 return NT_STATUS_NOT_IMPLEMENTED;
5598 /****************************************************************
5599 ****************************************************************/
5601 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5602 struct samr_GetDisplayEnumerationIndex *r)
5604 p->rng_fault_state = true;
5605 return NT_STATUS_NOT_IMPLEMENTED;
5608 /****************************************************************
5609 ****************************************************************/
5611 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5612 struct samr_TestPrivateFunctionsDomain *r)
5614 p->rng_fault_state = true;
5615 return NT_STATUS_NOT_IMPLEMENTED;
5618 /****************************************************************
5619 ****************************************************************/
5621 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5622 struct samr_TestPrivateFunctionsUser *r)
5624 p->rng_fault_state = true;
5625 return NT_STATUS_NOT_IMPLEMENTED;
5628 /****************************************************************
5629 ****************************************************************/
5631 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5632 struct samr_QueryUserInfo2 *r)
5634 p->rng_fault_state = true;
5635 return NT_STATUS_NOT_IMPLEMENTED;
5638 /****************************************************************
5639 ****************************************************************/
5641 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5642 struct samr_GetDisplayEnumerationIndex2 *r)
5644 p->rng_fault_state = true;
5645 return NT_STATUS_NOT_IMPLEMENTED;
5648 /****************************************************************
5649 ****************************************************************/
5651 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5652 struct samr_AddMultipleMembersToAlias *r)
5654 p->rng_fault_state = true;
5655 return NT_STATUS_NOT_IMPLEMENTED;
5658 /****************************************************************
5659 ****************************************************************/
5661 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5662 struct samr_RemoveMultipleMembersFromAlias *r)
5664 p->rng_fault_state = true;
5665 return NT_STATUS_NOT_IMPLEMENTED;
5668 /****************************************************************
5669 ****************************************************************/
5671 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5672 struct samr_OemChangePasswordUser2 *r)
5674 p->rng_fault_state = true;
5675 return NT_STATUS_NOT_IMPLEMENTED;
5678 /****************************************************************
5679 ****************************************************************/
5681 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5682 struct samr_SetBootKeyInformation *r)
5684 p->rng_fault_state = true;
5685 return NT_STATUS_NOT_IMPLEMENTED;
5688 /****************************************************************
5689 ****************************************************************/
5691 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5692 struct samr_GetBootKeyInformation *r)
5694 p->rng_fault_state = true;
5695 return NT_STATUS_NOT_IMPLEMENTED;
5698 /****************************************************************
5699 ****************************************************************/
5701 NTSTATUS _samr_Connect3(pipes_struct *p,
5702 struct samr_Connect3 *r)
5704 p->rng_fault_state = true;
5705 return NT_STATUS_NOT_IMPLEMENTED;
5708 /****************************************************************
5709 ****************************************************************/
5711 NTSTATUS _samr_RidToSid(pipes_struct *p,
5712 struct samr_RidToSid *r)
5714 p->rng_fault_state = true;
5715 return NT_STATUS_NOT_IMPLEMENTED;
5718 /****************************************************************
5719 ****************************************************************/
5721 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5722 struct samr_SetDsrmPassword *r)
5724 p->rng_fault_state = true;
5725 return NT_STATUS_NOT_IMPLEMENTED;
5728 /****************************************************************
5729 ****************************************************************/
5731 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5732 struct samr_ValidatePassword *r)
5734 p->rng_fault_state = true;
5735 return NT_STATUS_NOT_IMPLEMENTED;