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, "_samr_OpenDomain" );
583 if ( !NT_STATUS_IS_OK(status) )
586 /*check if access can be granted as requested by client. */
588 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
589 se_map_generic( &des_access, &dom_generic_mapping );
591 se_priv_copy( &se_rights, &se_machine_account );
592 se_priv_add( &se_rights, &se_add_users );
594 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
595 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
596 &acc_granted, "_samr_OpenDomain" );
598 if ( !NT_STATUS_IS_OK(status) )
601 if (!sid_check_is_domain(r->in.sid) &&
602 !sid_check_is_builtin(r->in.sid)) {
603 return NT_STATUS_NO_SUCH_DOMAIN;
606 /* associate the domain SID with the (unique) handle. */
607 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
608 return NT_STATUS_NO_MEMORY;
609 info->acc_granted = acc_granted;
611 /* get a (unique) handle. open a policy on it. */
612 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
613 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
615 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
620 /*******************************************************************
622 ********************************************************************/
624 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
625 struct samr_GetUserPwInfo *r)
627 struct samr_info *info = NULL;
629 /* find the policy handle. open a policy on it. */
630 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
631 return NT_STATUS_INVALID_HANDLE;
633 if (!sid_check_is_in_our_domain(&info->sid))
634 return NT_STATUS_OBJECT_TYPE_MISMATCH;
636 ZERO_STRUCTP(r->out.info);
638 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
641 * NT sometimes return NT_STATUS_ACCESS_DENIED
642 * I don't know yet why.
648 /*******************************************************************
649 ********************************************************************/
651 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
652 DOM_SID *sid, uint32 *acc_granted,
653 DISP_INFO **ppdisp_info)
655 struct samr_info *info = NULL;
657 /* find the policy handle. open a policy on it. */
658 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
665 *acc_granted = info->acc_granted;
667 *ppdisp_info = info->disp_info;
673 /*******************************************************************
675 ********************************************************************/
677 NTSTATUS _samr_SetSecurity(pipes_struct *p,
678 struct samr_SetSecurity *r)
681 uint32 acc_granted, i;
684 struct samu *sampass=NULL;
687 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
688 return NT_STATUS_INVALID_HANDLE;
690 if (!(sampass = samu_new( p->mem_ctx))) {
691 DEBUG(0,("No memory!\n"));
692 return NT_STATUS_NO_MEMORY;
695 /* get the user record */
697 ret = pdb_getsampwsid(sampass, &pol_sid);
701 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
702 TALLOC_FREE(sampass);
703 return NT_STATUS_INVALID_HANDLE;
706 dacl = r->in.sdbuf->sd->dacl;
707 for (i=0; i < dacl->num_aces; i++) {
708 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
709 ret = pdb_set_pass_can_change(sampass,
710 (dacl->aces[i].access_mask &
711 SA_RIGHT_USER_CHANGE_PASSWORD) ?
718 TALLOC_FREE(sampass);
719 return NT_STATUS_ACCESS_DENIED;
722 status = access_check_samr_function(acc_granted, SA_RIGHT_USER_SET_ATTRIBUTES, "_samr_SetSecurity");
723 if (NT_STATUS_IS_OK(status)) {
725 status = pdb_update_sam_account(sampass);
729 TALLOC_FREE(sampass);
734 /*******************************************************************
735 build correct perms based on policies and password times for _samr_query_sec_obj
736 *******************************************************************/
737 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
739 struct samu *sampass=NULL;
742 if ( !(sampass = samu_new( mem_ctx )) ) {
743 DEBUG(0,("No memory!\n"));
748 ret = pdb_getsampwsid(sampass, user_sid);
752 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
753 TALLOC_FREE(sampass);
757 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
759 if (pdb_get_pass_can_change(sampass)) {
760 TALLOC_FREE(sampass);
763 TALLOC_FREE(sampass);
768 /*******************************************************************
770 ********************************************************************/
772 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
773 struct samr_QuerySecurity *r)
777 SEC_DESC * psd = NULL;
782 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
783 return NT_STATUS_INVALID_HANDLE;
785 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
786 sid_string_dbg(&pol_sid)));
788 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
790 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
791 if (pol_sid.sid_rev_num == 0) {
792 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
793 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
794 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
795 /* check if it is our domain SID */
796 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
797 "with SID: %s\n", sid_string_dbg(&pol_sid)));
798 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
799 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
800 /* check if it is the Builtin Domain */
801 /* TODO: Builtin probably needs a different SD with restricted write access*/
802 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
803 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
804 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
805 } else if (sid_check_is_in_our_domain(&pol_sid) ||
806 sid_check_is_in_builtin(&pol_sid)) {
807 /* TODO: different SDs have to be generated for aliases groups and users.
808 Currently all three get a default user SD */
809 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
810 "with SID: %s\n", sid_string_dbg(&pol_sid)));
811 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
812 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
813 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
815 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
816 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
819 return NT_STATUS_OBJECT_TYPE_MISMATCH;
822 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
823 return NT_STATUS_NO_MEMORY;
828 /*******************************************************************
829 makes a SAM_ENTRY / UNISTR2* structure from a user list.
830 ********************************************************************/
832 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp,
833 UNISTR2 **uni_name_pp,
834 uint32 num_entries, uint32 start_idx,
835 struct samr_displayentry *entries)
844 if (num_entries == 0)
847 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries);
849 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_entries);
851 if (sam == NULL || uni_name == NULL) {
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++) {
857 UNISTR2 uni_temp_name;
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_sam_entry(&sam[i], &uni_temp_name, entries[i].rid);
871 copy_unistr2(&uni_name[i], &uni_temp_name);
875 *uni_name_pp = uni_name;
879 /*******************************************************************
880 samr_reply_enum_dom_users
881 ********************************************************************/
883 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
884 SAMR_R_ENUM_DOM_USERS *r_u)
886 struct samr_info *info = NULL;
888 uint32 enum_context=q_u->start_idx;
889 enum remote_arch_types ra_type = get_remote_arch();
890 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
891 uint32 max_entries = max_sam_entries;
892 struct samr_displayentry *entries = NULL;
894 r_u->status = NT_STATUS_OK;
896 /* find the policy handle. open a policy on it. */
897 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
898 return NT_STATUS_INVALID_HANDLE;
900 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
901 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
902 "_samr_enum_dom_users"))) {
906 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
908 if (info->builtin_domain) {
909 /* No users in builtin. */
910 init_samr_r_enum_dom_users(r_u, q_u->start_idx, 0);
911 DEBUG(5,("_samr_enum_dom_users: No users in BUILTIN\n"));
919 if ((info->disp_info->enum_users != NULL) &&
920 (info->disp_info->enum_acb_mask != q_u->acb_mask)) {
921 pdb_search_destroy(info->disp_info->enum_users);
922 info->disp_info->enum_users = NULL;
925 if (info->disp_info->enum_users == NULL) {
926 info->disp_info->enum_users = pdb_search_users(q_u->acb_mask);
927 info->disp_info->enum_acb_mask = q_u->acb_mask;
930 if (info->disp_info->enum_users == NULL) {
931 /* END AS ROOT !!!! */
933 return NT_STATUS_ACCESS_DENIED;
936 num_account = pdb_search_entries(info->disp_info->enum_users,
937 enum_context, max_entries,
940 /* END AS ROOT !!!! */
944 if (num_account == 0) {
945 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over "
947 init_samr_r_enum_dom_users(r_u, q_u->start_idx, 0);
951 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam,
953 num_account, enum_context,
956 if (!NT_STATUS_IS_OK(r_u->status))
959 if (max_entries <= num_account) {
960 r_u->status = STATUS_MORE_ENTRIES;
962 r_u->status = NT_STATUS_OK;
965 /* Ensure we cache this enumeration. */
966 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
968 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
970 init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_account,
973 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
978 /*******************************************************************
979 makes a SAM_ENTRY / UNISTR2* structure from a group list.
980 ********************************************************************/
982 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp,
983 UNISTR2 **uni_name_pp,
984 uint32 num_sam_entries,
985 struct samr_displayentry *entries)
994 if (num_sam_entries == 0)
997 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
998 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
1000 if (sam == NULL || uni_name == NULL) {
1001 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
1005 for (i = 0; i < num_sam_entries; i++) {
1007 * JRA. I think this should include the null. TNG does not.
1009 init_unistr2(&uni_name[i], entries[i].account_name,
1011 init_sam_entry(&sam[i], &uni_name[i], entries[i].rid);
1015 *uni_name_pp = uni_name;
1018 /*******************************************************************
1019 samr_reply_enum_dom_groups
1020 ********************************************************************/
1022 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1024 struct samr_info *info = NULL;
1025 struct samr_displayentry *groups;
1028 r_u->status = NT_STATUS_OK;
1030 /* find the policy handle. open a policy on it. */
1031 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1032 return NT_STATUS_INVALID_HANDLE;
1034 r_u->status = access_check_samr_function(info->acc_granted,
1035 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1036 "_samr_enum_dom_groups");
1037 if (!NT_STATUS_IS_OK(r_u->status))
1040 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1042 if (info->builtin_domain) {
1043 /* No groups in builtin. */
1044 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, 0);
1045 DEBUG(5,("_samr_enum_dom_users: No groups in BUILTIN\n"));
1049 /* the domain group array is being allocated in the function below */
1053 if (info->disp_info->groups == NULL) {
1054 info->disp_info->groups = pdb_search_groups();
1056 if (info->disp_info->groups == NULL) {
1058 return NT_STATUS_ACCESS_DENIED;
1062 num_groups = pdb_search_entries(info->disp_info->groups, q_u->start_idx,
1063 MAX_SAM_ENTRIES, &groups);
1066 /* Ensure we cache this enumeration. */
1067 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1069 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name,
1070 num_groups, groups);
1072 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_groups);
1074 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1079 /*******************************************************************
1080 samr_reply_enum_dom_aliases
1081 ********************************************************************/
1083 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1085 struct samr_info *info;
1086 struct samr_displayentry *aliases;
1087 uint32 num_aliases = 0;
1089 /* find the policy handle. open a policy on it. */
1090 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1091 return NT_STATUS_INVALID_HANDLE;
1093 r_u->status = access_check_samr_function(info->acc_granted,
1094 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1095 "_samr_enum_dom_aliases");
1096 if (!NT_STATUS_IS_OK(r_u->status))
1099 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n",
1100 sid_string_dbg(&info->sid)));
1104 if (info->disp_info->aliases == NULL) {
1105 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1106 if (info->disp_info->aliases == NULL) {
1108 return NT_STATUS_ACCESS_DENIED;
1112 num_aliases = pdb_search_entries(info->disp_info->aliases, q_u->start_idx,
1113 MAX_SAM_ENTRIES, &aliases);
1116 /* Ensure we cache this enumeration. */
1117 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1119 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name,
1120 num_aliases, aliases);
1122 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_aliases,
1125 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1130 /*******************************************************************
1131 samr_reply_query_dispinfo
1132 ********************************************************************/
1134 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1135 SAMR_R_QUERY_DISPINFO *r_u)
1137 struct samr_info *info = NULL;
1138 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1140 uint32 max_entries=q_u->max_entries;
1141 uint32 enum_context=q_u->start_idx;
1142 uint32 max_size=q_u->max_size;
1144 SAM_DISPINFO_CTR *ctr;
1145 uint32 temp_size=0, total_data_size=0;
1146 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1147 uint32 num_account = 0;
1148 enum remote_arch_types ra_type = get_remote_arch();
1149 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1150 struct samr_displayentry *entries = NULL;
1152 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1153 r_u->status = NT_STATUS_UNSUCCESSFUL;
1155 /* find the policy handle. open a policy on it. */
1156 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info))
1157 return NT_STATUS_INVALID_HANDLE;
1160 * calculate how many entries we will return.
1162 * - the number of entries the client asked
1163 * - our limit on that
1164 * - the starting point (enumeration context)
1165 * - the buffer size the client will accept
1169 * We are a lot more like W2K. Instead of reading the SAM
1170 * each time to find the records we need to send back,
1171 * we read it once and link that copy to the sam handle.
1172 * For large user list (over the MAX_SAM_ENTRIES)
1173 * it's a definitive win.
1174 * second point to notice: between enumerations
1175 * our sam is now the same as it's a snapshoot.
1176 * third point: got rid of the static SAM_USER_21 struct
1177 * no more intermediate.
1178 * con: it uses much more memory, as a full copy is stored
1181 * If you want to change it, think twice and think
1182 * of the second point , that's really important.
1187 if ((q_u->switch_level < 1) || (q_u->switch_level > 5)) {
1188 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n",
1189 (unsigned int)q_u->switch_level ));
1190 return NT_STATUS_INVALID_INFO_CLASS;
1193 /* first limit the number of entries we will return */
1194 if(max_entries > max_sam_entries) {
1195 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d "
1196 "entries, limiting to %d\n", max_entries,
1198 max_entries = max_sam_entries;
1201 /* calculate the size and limit on the number of entries we will
1204 temp_size=max_entries*struct_size;
1206 if (temp_size>max_size) {
1207 max_entries=MIN((max_size/struct_size),max_entries);;
1208 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to "
1209 "only %d entries\n", max_entries));
1212 if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
1213 return NT_STATUS_NO_MEMORY;
1219 /* THe following done as ROOT. Don't return without unbecome_root(). */
1221 switch (q_u->switch_level) {
1224 if (info->disp_info->users == NULL) {
1225 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1226 if (info->disp_info->users == NULL) {
1228 return NT_STATUS_ACCESS_DENIED;
1230 DEBUG(10,("samr_reply_query_dispinfo: starting user enumeration at index %u\n",
1231 (unsigned int)enum_context ));
1233 DEBUG(10,("samr_reply_query_dispinfo: using cached user enumeration at index %u\n",
1234 (unsigned int)enum_context ));
1237 num_account = pdb_search_entries(info->disp_info->users,
1238 enum_context, max_entries,
1242 if (info->disp_info->machines == NULL) {
1243 info->disp_info->machines =
1244 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1245 if (info->disp_info->machines == NULL) {
1247 return NT_STATUS_ACCESS_DENIED;
1249 DEBUG(10,("samr_reply_query_dispinfo: starting machine enumeration at index %u\n",
1250 (unsigned int)enum_context ));
1252 DEBUG(10,("samr_reply_query_dispinfo: using cached machine enumeration at index %u\n",
1253 (unsigned int)enum_context ));
1256 num_account = pdb_search_entries(info->disp_info->machines,
1257 enum_context, max_entries,
1262 if (info->disp_info->groups == NULL) {
1263 info->disp_info->groups = pdb_search_groups();
1264 if (info->disp_info->groups == NULL) {
1266 return NT_STATUS_ACCESS_DENIED;
1268 DEBUG(10,("samr_reply_query_dispinfo: starting group enumeration at index %u\n",
1269 (unsigned int)enum_context ));
1271 DEBUG(10,("samr_reply_query_dispinfo: using cached group enumeration at index %u\n",
1272 (unsigned int)enum_context ));
1275 num_account = pdb_search_entries(info->disp_info->groups,
1276 enum_context, max_entries,
1281 smb_panic("info class changed");
1286 /* Now create reply structure */
1287 switch (q_u->switch_level) {
1289 disp_ret = init_sam_dispinfo_1(p->mem_ctx, &ctr->sam.info1,
1290 num_account, enum_context,
1294 disp_ret = init_sam_dispinfo_2(p->mem_ctx, &ctr->sam.info2,
1295 num_account, enum_context,
1299 disp_ret = init_sam_dispinfo_3(p->mem_ctx, &ctr->sam.info3,
1300 num_account, enum_context,
1304 disp_ret = init_sam_dispinfo_4(p->mem_ctx, &ctr->sam.info4,
1305 num_account, enum_context,
1309 disp_ret = init_sam_dispinfo_5(p->mem_ctx, &ctr->sam.info5,
1310 num_account, enum_context,
1314 smb_panic("info class changed");
1318 if (!NT_STATUS_IS_OK(disp_ret))
1321 /* calculate the total size */
1322 total_data_size=num_account*struct_size;
1325 r_u->status = STATUS_MORE_ENTRIES;
1327 r_u->status = NT_STATUS_OK;
1330 /* Ensure we cache this enumeration. */
1331 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1333 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1335 init_samr_r_query_dispinfo(r_u, num_account, total_data_size,
1336 temp_size, q_u->switch_level, ctr,
1343 /*******************************************************************
1344 _samr_QueryAliasInfo
1345 ********************************************************************/
1347 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1348 struct samr_QueryAliasInfo *r)
1351 struct acct_info info;
1354 union samr_AliasInfo *alias_info = NULL;
1355 const char *alias_name = NULL;
1356 const char *alias_description = NULL;
1358 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1360 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1362 return NT_STATUS_NO_MEMORY;
1365 /* find the policy handle. open a policy on it. */
1366 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1367 return NT_STATUS_INVALID_HANDLE;
1369 status = access_check_samr_function(acc_granted,
1370 SA_RIGHT_ALIAS_LOOKUP_INFO,
1371 "_samr_QueryAliasInfo");
1372 if (!NT_STATUS_IS_OK(status)) {
1377 status = pdb_get_aliasinfo(&sid, &info);
1380 if ( !NT_STATUS_IS_OK(status))
1383 /* FIXME: info contains fstrings */
1384 alias_name = talloc_strdup(r, info.acct_name);
1385 alias_description = talloc_strdup(r, info.acct_desc);
1387 switch (r->in.level) {
1389 init_samr_alias_info1(&alias_info->all,
1394 case ALIASINFODESCRIPTION:
1395 init_samr_alias_info3(&alias_info->description,
1399 return NT_STATUS_INVALID_INFO_CLASS;
1402 *r->out.info = alias_info;
1404 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1406 return NT_STATUS_OK;
1410 /*******************************************************************
1411 samr_reply_lookup_ids
1412 ********************************************************************/
1414 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1416 uint32 rid[MAX_SAM_ENTRIES];
1417 int num_rids = q_u->num_sids1;
1419 r_u->status = NT_STATUS_OK;
1421 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1423 if (num_rids > MAX_SAM_ENTRIES) {
1424 num_rids = MAX_SAM_ENTRIES;
1425 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1430 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1432 for (i = 0; i < num_rids && status == 0; i++)
1434 struct sam_passwd *sam_pass;
1438 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1439 q_u->uni_user_name[i].uni_str_len));
1441 /* find the user account */
1443 sam_pass = get_smb21pwd_entry(user_name, 0);
1446 if (sam_pass == NULL)
1448 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1453 rid[i] = sam_pass->user_rid;
1459 rid[0] = BUILTIN_ALIAS_RID_USERS;
1461 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1463 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1469 /*******************************************************************
1471 ********************************************************************/
1473 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1475 uint32 rid[MAX_SAM_ENTRIES];
1476 enum lsa_SidType type[MAX_SAM_ENTRIES];
1478 int num_rids = q_u->num_names2;
1482 r_u->status = NT_STATUS_OK;
1484 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1489 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL)) {
1490 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1494 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1498 if (num_rids > MAX_SAM_ENTRIES) {
1499 num_rids = MAX_SAM_ENTRIES;
1500 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1503 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n",
1504 sid_string_dbg(&pol_sid)));
1506 for (i = 0; i < num_rids; i++) {
1510 r_u->status = NT_STATUS_NONE_MAPPED;
1511 type[i] = SID_NAME_UNKNOWN;
1513 rid [i] = 0xffffffff;
1515 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1521 if (sid_check_is_builtin(&pol_sid)) {
1522 if (lookup_builtin_name(name, &rid[i])) {
1523 type[i] = SID_NAME_ALIAS;
1526 lookup_global_sam_name(name, 0, &rid[i], &type[i]);
1529 if (type[i] != SID_NAME_UNKNOWN) {
1530 r_u->status = NT_STATUS_OK;
1534 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, type, r_u->status);
1536 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1541 /*******************************************************************
1542 _samr_ChangePasswordUser2
1543 ********************************************************************/
1544 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1545 struct samr_ChangePasswordUser2 *r)
1552 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1554 fstrcpy(user_name, r->in.account->string);
1555 fstrcpy(wks, r->in.server->string);
1557 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1560 * Pass the user through the NT -> unix user mapping
1564 (void)map_username(user_name);
1567 * UNIX username case mangling not required, pass_oem_change
1568 * is case insensitive.
1571 status = pass_oem_change(user_name, r->in.lm_password->data, r->in.lm_verifier->hash,
1572 r->in.nt_password->data, r->in.nt_verifier->hash, NULL);
1574 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1579 /*******************************************************************
1580 _samr_ChangePasswordUser3
1581 ********************************************************************/
1583 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1584 struct samr_ChangePasswordUser3 *r)
1588 const char *wks = NULL;
1589 uint32 reject_reason;
1590 struct samr_DomInfo1 *dominfo = NULL;
1591 struct samr_ChangeReject *reject = NULL;
1593 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1595 fstrcpy(user_name, r->in.account->string);
1596 if (r->in.server && r->in.server->string) {
1597 wks = r->in.server->string;
1600 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1603 * Pass the user through the NT -> unix user mapping
1607 (void)map_username(user_name);
1610 * UNIX username case mangling not required, pass_oem_change
1611 * is case insensitive.
1614 status = pass_oem_change(user_name,
1615 r->in.lm_password->data,
1616 r->in.lm_verifier->hash,
1617 r->in.nt_password->data,
1618 r->in.nt_verifier->hash,
1621 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1622 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1624 uint32 min_pass_len,pass_hist,password_properties;
1625 time_t u_expire, u_min_age;
1626 NTTIME nt_expire, nt_min_age;
1627 uint32 account_policy_temp;
1629 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1631 return NT_STATUS_NO_MEMORY;
1634 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1636 return NT_STATUS_NO_MEMORY;
1643 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1644 min_pass_len = account_policy_temp;
1646 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1647 pass_hist = account_policy_temp;
1649 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1650 password_properties = account_policy_temp;
1652 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1653 u_expire = account_policy_temp;
1655 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1656 u_min_age = account_policy_temp;
1662 unix_to_nt_time_abs(&nt_expire, u_expire);
1663 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1665 if (lp_check_password_script() && *lp_check_password_script()) {
1666 password_properties |= DOMAIN_PASSWORD_COMPLEX;
1669 init_samr_DomInfo1(dominfo,
1672 password_properties,
1676 reject->reason = reject_reason;
1678 *r->out.dominfo = dominfo;
1679 *r->out.reject = reject;
1682 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1687 /*******************************************************************
1688 makes a SAMR_R_LOOKUP_RIDS structure.
1689 ********************************************************************/
1691 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1692 const char **names, UNIHDR **pp_hdr_name,
1693 UNISTR2 **pp_uni_name)
1696 UNIHDR *hdr_name=NULL;
1697 UNISTR2 *uni_name=NULL;
1699 *pp_uni_name = NULL;
1700 *pp_hdr_name = NULL;
1702 if (num_names != 0) {
1703 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1704 if (hdr_name == NULL)
1707 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1708 if (uni_name == NULL)
1712 for (i = 0; i < num_names; i++) {
1713 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
1714 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1715 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1718 *pp_uni_name = uni_name;
1719 *pp_hdr_name = hdr_name;
1724 /*******************************************************************
1726 ********************************************************************/
1728 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1731 enum lsa_SidType *attrs = NULL;
1732 uint32 *wire_attrs = NULL;
1733 UNIHDR *hdr_name = NULL;
1734 UNISTR2 *uni_name = NULL;
1736 int num_rids = (int)q_u->num_rids1;
1740 r_u->status = NT_STATUS_OK;
1742 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1744 /* find the policy handle. open a policy on it. */
1745 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL))
1746 return NT_STATUS_INVALID_HANDLE;
1748 if (num_rids > 1000) {
1749 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
1750 "to samba4 idl this is not possible\n", num_rids));
1751 return NT_STATUS_UNSUCCESSFUL;
1755 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
1756 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
1757 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
1759 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
1760 return NT_STATUS_NO_MEMORY;
1767 become_root(); /* lookup_sid can require root privs */
1768 r_u->status = pdb_lookup_rids(&pol_sid, num_rids, q_u->rid,
1772 if ( NT_STATUS_EQUAL(r_u->status, NT_STATUS_NONE_MAPPED) && (num_rids == 0) ) {
1773 r_u->status = NT_STATUS_OK;
1776 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
1777 &hdr_name, &uni_name))
1778 return NT_STATUS_NO_MEMORY;
1780 /* Convert from enum lsa_SidType to uint32 for wire format. */
1781 for (i = 0; i < num_rids; i++) {
1782 wire_attrs[i] = (uint32)attrs[i];
1785 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, wire_attrs);
1787 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1792 /*******************************************************************
1794 ********************************************************************/
1796 NTSTATUS _samr_OpenUser(pipes_struct *p,
1797 struct samr_OpenUser *r)
1799 struct samu *sampass=NULL;
1801 POLICY_HND domain_pol = *r->in.domain_handle;
1802 POLICY_HND *user_pol = r->out.user_handle;
1803 struct samr_info *info = NULL;
1804 SEC_DESC *psd = NULL;
1806 uint32 des_access = r->in.access_mask;
1812 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1814 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
1815 return NT_STATUS_INVALID_HANDLE;
1817 nt_status = access_check_samr_function( acc_granted,
1818 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_OpenUser" );
1820 if ( !NT_STATUS_IS_OK(nt_status) )
1823 if ( !(sampass = samu_new( p->mem_ctx )) ) {
1824 return NT_STATUS_NO_MEMORY;
1827 /* append the user's RID to it */
1829 if (!sid_append_rid(&sid, r->in.rid))
1830 return NT_STATUS_NO_SUCH_USER;
1832 /* check if access can be granted as requested by client. */
1834 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
1835 se_map_generic(&des_access, &usr_generic_mapping);
1837 se_priv_copy( &se_rights, &se_machine_account );
1838 se_priv_add( &se_rights, &se_add_users );
1840 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
1841 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
1842 &acc_granted, "_samr_OpenUser");
1844 if ( !NT_STATUS_IS_OK(nt_status) )
1848 ret=pdb_getsampwsid(sampass, &sid);
1851 /* check that the SID exists in our domain. */
1853 return NT_STATUS_NO_SUCH_USER;
1856 TALLOC_FREE(sampass);
1858 /* associate the user's SID and access bits with the new handle. */
1859 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1860 return NT_STATUS_NO_MEMORY;
1861 info->acc_granted = acc_granted;
1863 /* get a (unique) handle. open a policy on it. */
1864 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1865 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1867 return NT_STATUS_OK;
1870 /*************************************************************************
1871 get_user_info_7. Safe. Only gives out account_name.
1872 *************************************************************************/
1874 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, SAM_USER_INFO_7 *id7, DOM_SID *user_sid)
1876 struct samu *smbpass=NULL;
1879 if ( !(smbpass = samu_new( mem_ctx )) ) {
1880 return NT_STATUS_NO_MEMORY;
1884 ret = pdb_getsampwsid(smbpass, user_sid);
1888 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
1889 return NT_STATUS_NO_SUCH_USER;
1892 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1895 init_sam_user_info7(id7, pdb_get_username(smbpass) );
1897 TALLOC_FREE(smbpass);
1899 return NT_STATUS_OK;
1902 /*************************************************************************
1903 get_user_info_9. Only gives out primary group SID.
1904 *************************************************************************/
1905 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx, SAM_USER_INFO_9 * id9, DOM_SID *user_sid)
1907 struct samu *smbpass=NULL;
1910 if ( !(smbpass = samu_new( mem_ctx )) ) {
1911 return NT_STATUS_NO_MEMORY;
1915 ret = pdb_getsampwsid(smbpass, user_sid);
1919 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
1920 return NT_STATUS_NO_SUCH_USER;
1923 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1926 init_sam_user_info9(id9, pdb_get_group_rid(smbpass) );
1928 TALLOC_FREE(smbpass);
1930 return NT_STATUS_OK;
1933 /*************************************************************************
1934 get_user_info_16. Safe. Only gives out acb bits.
1935 *************************************************************************/
1937 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx, SAM_USER_INFO_16 *id16, DOM_SID *user_sid)
1939 struct samu *smbpass=NULL;
1942 if ( !(smbpass = samu_new( mem_ctx )) ) {
1943 return NT_STATUS_NO_MEMORY;
1947 ret = pdb_getsampwsid(smbpass, user_sid);
1951 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
1952 return NT_STATUS_NO_SUCH_USER;
1955 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1958 init_sam_user_info16(id16, pdb_get_acct_ctrl(smbpass) );
1960 TALLOC_FREE(smbpass);
1962 return NT_STATUS_OK;
1965 /*************************************************************************
1966 get_user_info_18. OK - this is the killer as it gives out password info.
1967 Ensure that this is only allowed on an encrypted connection with a root
1969 *************************************************************************/
1971 static NTSTATUS get_user_info_18(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_18 * id18, DOM_SID *user_sid)
1973 struct samu *smbpass=NULL;
1976 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
1977 return NT_STATUS_ACCESS_DENIED;
1980 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
1981 return NT_STATUS_ACCESS_DENIED;
1985 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1988 if ( !(smbpass = samu_new( mem_ctx )) ) {
1989 return NT_STATUS_NO_MEMORY;
1992 ret = pdb_getsampwsid(smbpass, user_sid);
1995 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
1996 TALLOC_FREE(smbpass);
1997 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2000 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2002 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2003 TALLOC_FREE(smbpass);
2004 return NT_STATUS_ACCOUNT_DISABLED;
2008 init_sam_user_info18(id18, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
2010 TALLOC_FREE(smbpass);
2012 return NT_STATUS_OK;
2015 /*************************************************************************
2017 *************************************************************************/
2019 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
2021 struct samu *sampass=NULL;
2024 if ( !(sampass = samu_new( mem_ctx )) ) {
2025 return NT_STATUS_NO_MEMORY;
2029 ret = pdb_getsampwsid(sampass, user_sid);
2033 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2034 return NT_STATUS_NO_SUCH_USER;
2037 samr_clear_sam_passwd(sampass);
2039 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
2042 init_sam_user_info20A(id20, sampass);
2044 TALLOC_FREE(sampass);
2046 return NT_STATUS_OK;
2049 /*************************************************************************
2051 *************************************************************************/
2053 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
2054 DOM_SID *user_sid, DOM_SID *domain_sid)
2056 struct samu *sampass=NULL;
2060 if ( !(sampass = samu_new( mem_ctx )) ) {
2061 return NT_STATUS_NO_MEMORY;
2065 ret = pdb_getsampwsid(sampass, user_sid);
2069 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2070 return NT_STATUS_NO_SUCH_USER;
2073 samr_clear_sam_passwd(sampass);
2075 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
2078 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
2080 TALLOC_FREE(sampass);
2085 /*******************************************************************
2086 _samr_query_userinfo
2087 ********************************************************************/
2089 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
2091 SAM_USERINFO_CTR *ctr;
2092 struct samr_info *info = NULL;
2096 r_u->status=NT_STATUS_OK;
2098 /* search for the handle */
2099 if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
2100 return NT_STATUS_INVALID_HANDLE;
2102 domain_sid = info->sid;
2104 sid_split_rid(&domain_sid, &rid);
2106 if (!sid_check_is_in_our_domain(&info->sid))
2107 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2109 DEBUG(5,("_samr_query_userinfo: sid:%s\n",
2110 sid_string_dbg(&info->sid)));
2112 ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
2114 return NT_STATUS_NO_MEMORY;
2118 /* ok! user info levels (lots: see MSDEV help), off we go... */
2119 ctr->switch_value = q_u->switch_value;
2121 DEBUG(5,("_samr_query_userinfo: user info level: %d\n", q_u->switch_value));
2123 switch (q_u->switch_value) {
2125 ctr->info.id7 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_7);
2126 if (ctr->info.id7 == NULL)
2127 return NT_STATUS_NO_MEMORY;
2129 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_7(p->mem_ctx, ctr->info.id7, &info->sid)))
2133 ctr->info.id9 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_9);
2134 if (ctr->info.id9 == NULL)
2135 return NT_STATUS_NO_MEMORY;
2137 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_9(p->mem_ctx, ctr->info.id9, &info->sid)))
2141 ctr->info.id16 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_16);
2142 if (ctr->info.id16 == NULL)
2143 return NT_STATUS_NO_MEMORY;
2145 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_16(p->mem_ctx, ctr->info.id16, &info->sid)))
2150 ctr->info.id18 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_18);
2151 if (ctr->info.id18 == NULL)
2152 return NT_STATUS_NO_MEMORY;
2154 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_18(p, p->mem_ctx, ctr->info.id18, &info->sid)))
2159 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
2160 if (ctr->info.id20 == NULL)
2161 return NT_STATUS_NO_MEMORY;
2162 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
2167 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
2168 if (ctr->info.id21 == NULL)
2169 return NT_STATUS_NO_MEMORY;
2170 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
2171 &info->sid, &domain_sid)))
2176 return NT_STATUS_INVALID_INFO_CLASS;
2179 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
2181 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
2186 /*******************************************************************
2187 _samr_GetGroupsForUser
2188 ********************************************************************/
2190 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2191 struct samr_GetGroupsForUser *r)
2193 struct samu *sam_pass=NULL;
2196 struct samr_RidWithAttribute dom_gid;
2197 struct samr_RidWithAttribute *gids = NULL;
2198 uint32 primary_group_rid;
2199 size_t num_groups = 0;
2205 bool success = False;
2207 struct samr_RidWithAttributeArray *rids = NULL;
2210 * from the SID in the request:
2211 * we should send back the list of DOMAIN GROUPS
2212 * the user is a member of
2214 * and only the DOMAIN GROUPS
2215 * no ALIASES !!! neither aliases of the domain
2216 * nor aliases of the builtin SID
2221 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2223 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2225 return NT_STATUS_NO_MEMORY;
2228 /* find the policy handle. open a policy on it. */
2229 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2230 return NT_STATUS_INVALID_HANDLE;
2232 result = access_check_samr_function(acc_granted,
2233 SA_RIGHT_USER_GET_GROUPS,
2234 "_samr_GetGroupsForUser");
2235 if (!NT_STATUS_IS_OK(result)) {
2239 if (!sid_check_is_in_our_domain(&sid))
2240 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2242 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2243 return NT_STATUS_NO_MEMORY;
2247 ret = pdb_getsampwsid(sam_pass, &sid);
2251 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2252 sid_string_dbg(&sid)));
2253 return NT_STATUS_NO_SUCH_USER;
2258 /* make both calls inside the root block */
2260 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2261 &sids, &unix_gids, &num_groups);
2262 if ( NT_STATUS_IS_OK(result) ) {
2263 success = sid_peek_check_rid(get_global_sam_sid(),
2264 pdb_get_group_sid(sam_pass),
2265 &primary_group_rid);
2269 if (!NT_STATUS_IS_OK(result)) {
2270 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2271 sid_string_dbg(&sid)));
2276 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2277 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2278 pdb_get_username(sam_pass)));
2279 TALLOC_FREE(sam_pass);
2280 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2286 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2288 dom_gid.rid = primary_group_rid;
2289 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2291 for (i=0; i<num_groups; i++) {
2293 if (!sid_peek_check_rid(get_global_sam_sid(),
2294 &(sids[i]), &dom_gid.rid)) {
2295 DEBUG(10, ("Found sid %s not in our domain\n",
2296 sid_string_dbg(&sids[i])));
2300 if (dom_gid.rid == primary_group_rid) {
2301 /* We added the primary group directly from the
2302 * sam_account. The other SIDs are unique from
2303 * enum_group_memberships */
2307 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2310 rids->count = num_gids;
2313 *r->out.rids = rids;
2315 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2320 /*******************************************************************
2321 samr_QueryDomainInfo_internal
2322 ********************************************************************/
2324 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2326 struct policy_handle *handle,
2328 union samr_DomainInfo **dom_info_ptr)
2330 NTSTATUS status = NT_STATUS_OK;
2331 struct samr_info *info = NULL;
2332 union samr_DomainInfo *dom_info;
2333 uint32 min_pass_len,pass_hist,password_properties;
2334 time_t u_expire, u_min_age;
2335 NTTIME nt_expire, nt_min_age;
2337 time_t u_lock_duration, u_reset_time;
2338 NTTIME nt_lock_duration, nt_reset_time;
2343 uint32 account_policy_temp;
2348 uint32 num_users=0, num_groups=0, num_aliases=0;
2350 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2352 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2354 return NT_STATUS_NO_MEMORY;
2357 *dom_info_ptr = dom_info;
2359 /* find the policy handle. open a policy on it. */
2360 if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2361 return NT_STATUS_INVALID_HANDLE;
2371 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2372 min_pass_len = account_policy_temp;
2374 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2375 pass_hist = account_policy_temp;
2377 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2378 password_properties = account_policy_temp;
2380 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2381 u_expire = account_policy_temp;
2383 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2384 u_min_age = account_policy_temp;
2390 unix_to_nt_time_abs(&nt_expire, u_expire);
2391 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2393 init_samr_DomInfo1(&dom_info->info1,
2394 (uint16)min_pass_len,
2396 password_properties,
2406 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2407 num_groups = count_sam_groups(info->disp_info);
2408 num_aliases = count_sam_aliases(info->disp_info);
2410 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2411 u_logout = account_policy_temp;
2413 unix_to_nt_time_abs(&nt_logout, u_logout);
2415 if (!pdb_get_seq_num(&seq_num))
2416 seq_num = time(NULL);
2422 server_role = ROLE_DOMAIN_PDC;
2423 if (lp_server_role() == ROLE_DOMAIN_BDC)
2424 server_role = ROLE_DOMAIN_BDC;
2426 init_samr_DomInfo2(&dom_info->info2,
2447 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2448 u_logout = (time_t)ul;
2455 unix_to_nt_time_abs(&nt_logout, u_logout);
2457 init_samr_DomInfo3(&dom_info->info3,
2462 init_samr_DomInfo4(&dom_info->info4,
2466 init_samr_DomInfo5(&dom_info->info5,
2467 get_global_sam_name());
2470 /* NT returns its own name when a PDC. win2k and later
2471 * only the name of the PDC if itself is a BDC (samba4
2473 init_samr_DomInfo6(&dom_info->info6,
2477 server_role = ROLE_DOMAIN_PDC;
2478 if (lp_server_role() == ROLE_DOMAIN_BDC)
2479 server_role = ROLE_DOMAIN_BDC;
2481 init_samr_DomInfo7(&dom_info->info7,
2490 if (!pdb_get_seq_num(&seq_num)) {
2491 seq_num = time(NULL);
2498 init_samr_DomInfo8(&dom_info->info8,
2508 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2509 u_lock_duration = account_policy_temp;
2510 if (u_lock_duration != -1) {
2511 u_lock_duration *= 60;
2514 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2515 u_reset_time = account_policy_temp * 60;
2517 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2518 lockout = account_policy_temp;
2524 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2525 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2527 init_samr_DomInfo12(&dom_info->info12,
2533 return NT_STATUS_INVALID_INFO_CLASS;
2536 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2541 /*******************************************************************
2542 _samr_QueryDomainInfo
2543 ********************************************************************/
2545 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2546 struct samr_QueryDomainInfo *r)
2548 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
2550 r->in.domain_handle,
2555 /* W2k3 seems to use the same check for all 3 objects that can be created via
2556 * SAMR, if you try to create for example "Dialup" as an alias it says
2557 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
2560 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
2562 enum lsa_SidType type;
2565 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
2568 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
2569 * whether the name already exists */
2570 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
2571 NULL, NULL, NULL, &type);
2575 DEBUG(10, ("%s does not exist, can create it\n", new_name));
2576 return NT_STATUS_OK;
2579 DEBUG(5, ("trying to create %s, exists as %s\n",
2580 new_name, sid_type_lookup(type)));
2582 if (type == SID_NAME_DOM_GRP) {
2583 return NT_STATUS_GROUP_EXISTS;
2585 if (type == SID_NAME_ALIAS) {
2586 return NT_STATUS_ALIAS_EXISTS;
2589 /* Yes, the default is NT_STATUS_USER_EXISTS */
2590 return NT_STATUS_USER_EXISTS;
2593 /*******************************************************************
2595 ********************************************************************/
2597 NTSTATUS _samr_CreateUser2(pipes_struct *p,
2598 struct samr_CreateUser2 *r)
2600 const char *account = NULL;
2602 POLICY_HND dom_pol = *r->in.domain_handle;
2603 uint32_t acb_info = r->in.acct_flags;
2604 POLICY_HND *user_pol = r->out.user_handle;
2605 struct samr_info *info = NULL;
2610 /* check this, when giving away 'add computer to domain' privs */
2611 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2612 bool can_add_account = False;
2614 DISP_INFO *disp_info = NULL;
2616 /* Get the domain SID stored in the domain policy */
2617 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
2619 return NT_STATUS_INVALID_HANDLE;
2621 nt_status = access_check_samr_function(acc_granted,
2622 SA_RIGHT_DOMAIN_CREATE_USER,
2623 "_samr_CreateUser2");
2624 if (!NT_STATUS_IS_OK(nt_status)) {
2628 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
2629 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2630 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2631 this parameter is not an account type */
2632 return NT_STATUS_INVALID_PARAMETER;
2635 account = r->in.account_name->string;
2636 if (account == NULL) {
2637 return NT_STATUS_NO_MEMORY;
2640 nt_status = can_create(p->mem_ctx, account);
2641 if (!NT_STATUS_IS_OK(nt_status)) {
2645 /* determine which user right we need to check based on the acb_info */
2647 if ( acb_info & ACB_WSTRUST )
2649 se_priv_copy( &se_rights, &se_machine_account );
2650 can_add_account = user_has_privileges(
2651 p->pipe_user.nt_user_token, &se_rights );
2653 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
2654 account for domain trusts and changes the ACB flags later */
2655 else if ( acb_info & ACB_NORMAL &&
2656 (account[strlen(account)-1] != '$') )
2658 se_priv_copy( &se_rights, &se_add_users );
2659 can_add_account = user_has_privileges(
2660 p->pipe_user.nt_user_token, &se_rights );
2662 else /* implicit assumption of a BDC or domain trust account here
2663 * (we already check the flags earlier) */
2665 if ( lp_enable_privileges() ) {
2666 /* only Domain Admins can add a BDC or domain trust */
2667 se_priv_copy( &se_rights, &se_priv_none );
2668 can_add_account = nt_token_check_domain_rid(
2669 p->pipe_user.nt_user_token,
2670 DOMAIN_GROUP_RID_ADMINS );
2674 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
2675 uidtoname(p->pipe_user.ut.uid),
2676 can_add_account ? "True":"False" ));
2678 /********** BEGIN Admin BLOCK **********/
2680 if ( can_add_account )
2683 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
2686 if ( can_add_account )
2689 /********** END Admin BLOCK **********/
2691 /* now check for failure */
2693 if ( !NT_STATUS_IS_OK(nt_status) )
2696 /* Get the user's SID */
2698 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
2700 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
2701 &sid, SAMR_USR_RIGHTS_WRITE_PW);
2702 se_map_generic(&des_access, &usr_generic_mapping);
2704 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2705 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2706 &acc_granted, "_samr_CreateUser2");
2708 if ( !NT_STATUS_IS_OK(nt_status) ) {
2712 /* associate the user's SID with the new handle. */
2713 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2714 return NT_STATUS_NO_MEMORY;
2719 info->acc_granted = acc_granted;
2721 /* get a (unique) handle. open a policy on it. */
2722 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2723 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2726 /* After a "set" ensure we have no cached display info. */
2727 force_flush_samr_cache(info->disp_info);
2729 *r->out.access_granted = acc_granted;
2731 return NT_STATUS_OK;
2734 /*******************************************************************
2736 ********************************************************************/
2738 NTSTATUS _samr_Connect(pipes_struct *p,
2739 struct samr_Connect *r)
2741 struct samr_info *info = NULL;
2742 uint32 des_access = r->in.access_mask;
2746 if (!pipe_access_check(p)) {
2747 DEBUG(3, ("access denied to _samr_Connect\n"));
2748 return NT_STATUS_ACCESS_DENIED;
2751 /* set up the SAMR connect_anon response */
2753 /* associate the user's SID with the new handle. */
2754 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2755 return NT_STATUS_NO_MEMORY;
2757 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2758 was observed from a win98 client trying to enumerate users (when configured
2759 user level access control on shares) --jerry */
2761 if (des_access == MAXIMUM_ALLOWED_ACCESS) {
2762 /* Map to max possible knowing we're filtered below. */
2763 des_access = GENERIC_ALL_ACCESS;
2766 se_map_generic( &des_access, &sam_generic_mapping );
2767 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2769 /* get a (unique) handle. open a policy on it. */
2770 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
2771 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2773 return NT_STATUS_OK;
2776 /*******************************************************************
2778 ********************************************************************/
2780 NTSTATUS _samr_Connect2(pipes_struct *p,
2781 struct samr_Connect2 *r)
2783 struct samr_info *info = NULL;
2784 SEC_DESC *psd = NULL;
2786 uint32 des_access = r->in.access_mask;
2791 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
2795 if (!pipe_access_check(p)) {
2796 DEBUG(3, ("access denied to _samr_Connect2\n"));
2797 return NT_STATUS_ACCESS_DENIED;
2800 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2801 se_map_generic(&des_access, &sam_generic_mapping);
2803 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2804 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
2806 if ( !NT_STATUS_IS_OK(nt_status) )
2809 /* associate the user's SID and access granted with the new handle. */
2810 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2811 return NT_STATUS_NO_MEMORY;
2813 info->acc_granted = acc_granted;
2814 info->status = r->in.access_mask; /* this looks so wrong... - gd */
2816 /* get a (unique) handle. open a policy on it. */
2817 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
2818 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2820 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
2825 /*******************************************************************
2827 ********************************************************************/
2829 NTSTATUS _samr_Connect4(pipes_struct *p,
2830 struct samr_Connect4 *r)
2832 struct samr_info *info = NULL;
2833 SEC_DESC *psd = NULL;
2835 uint32 des_access = r->in.access_mask;
2840 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
2844 if (!pipe_access_check(p)) {
2845 DEBUG(3, ("access denied to samr_Connect4\n"));
2846 return NT_STATUS_ACCESS_DENIED;
2849 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2850 se_map_generic(&des_access, &sam_generic_mapping);
2852 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2853 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
2855 if ( !NT_STATUS_IS_OK(nt_status) )
2858 /* associate the user's SID and access granted with the new handle. */
2859 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2860 return NT_STATUS_NO_MEMORY;
2862 info->acc_granted = acc_granted;
2863 info->status = r->in.access_mask; /* ??? */
2865 /* get a (unique) handle. open a policy on it. */
2866 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
2867 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2869 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
2871 return NT_STATUS_OK;
2874 /*******************************************************************
2876 ********************************************************************/
2878 NTSTATUS _samr_Connect5(pipes_struct *p,
2879 struct samr_Connect5 *r)
2881 struct samr_info *info = NULL;
2882 SEC_DESC *psd = NULL;
2884 uint32 des_access = r->in.access_mask;
2887 struct samr_ConnectInfo1 info1;
2889 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
2893 if (!pipe_access_check(p)) {
2894 DEBUG(3, ("access denied to samr_Connect5\n"));
2895 return NT_STATUS_ACCESS_DENIED;
2898 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2899 se_map_generic(&des_access, &sam_generic_mapping);
2901 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2902 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
2904 if ( !NT_STATUS_IS_OK(nt_status) )
2907 /* associate the user's SID and access granted with the new handle. */
2908 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2909 return NT_STATUS_NO_MEMORY;
2911 info->acc_granted = acc_granted;
2912 info->status = r->in.access_mask; /* ??? */
2914 /* get a (unique) handle. open a policy on it. */
2915 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
2916 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2918 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
2920 info1.client_version = SAMR_CONNECT_AFTER_W2K;
2923 *r->out.level_out = 1;
2924 r->out.info_out->info1 = info1;
2926 return NT_STATUS_OK;
2929 /**********************************************************************
2931 **********************************************************************/
2932 NTSTATUS _samr_LookupDomain(pipes_struct *p,
2933 struct samr_LookupDomain *r)
2935 NTSTATUS status = NT_STATUS_OK;
2936 struct samr_info *info;
2937 const char *domain_name;
2938 DOM_SID *sid = NULL;
2940 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
2941 return NT_STATUS_INVALID_HANDLE;
2943 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
2944 Reverted that change so we will work with RAS servers again */
2946 status = access_check_samr_function(info->acc_granted,
2947 SA_RIGHT_SAM_OPEN_DOMAIN,
2948 "_samr_LookupDomain");
2949 if (!NT_STATUS_IS_OK(status)) {
2953 domain_name = r->in.domain_name->string;
2955 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
2957 return NT_STATUS_NO_MEMORY;
2960 if (strequal(domain_name, builtin_domain_name())) {
2961 sid_copy(sid, &global_sid_Builtin);
2963 if (!secrets_fetch_domain_sid(domain_name, sid)) {
2964 status = NT_STATUS_NO_SUCH_DOMAIN;
2968 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
2969 sid_string_dbg(sid)));
2976 /******************************************************************
2977 makes a SAMR_R_ENUM_DOMAINS structure.
2978 ********************************************************************/
2980 static bool make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2981 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2987 DEBUG(5, ("make_enum_domains\n"));
2990 *pp_uni_name = NULL;
2992 if (num_sam_entries == 0)
2995 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2996 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2998 if (sam == NULL || uni_name == NULL)
3001 for (i = 0; i < num_sam_entries; i++) {
3002 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
3003 init_sam_entry(&sam[i], &uni_name[i], 0);
3007 *pp_uni_name = uni_name;
3012 /**********************************************************************
3013 api_samr_enum_domains
3014 **********************************************************************/
3016 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
3018 struct samr_info *info;
3019 uint32 num_entries = 2;
3023 r_u->status = NT_STATUS_OK;
3025 if (!find_policy_by_hnd(p, &q_u->pol, (void**)(void *)&info))
3026 return NT_STATUS_INVALID_HANDLE;
3028 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
3032 name = get_global_sam_name();
3034 fstrcpy(dom[0],name);
3036 fstrcpy(dom[1],"Builtin");
3038 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
3039 return NT_STATUS_NO_MEMORY;
3041 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
3046 /*******************************************************************
3048 ********************************************************************/
3050 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3051 struct samr_OpenAlias *r)
3054 POLICY_HND domain_pol = *r->in.domain_handle;
3055 uint32 alias_rid = r->in.rid;
3056 POLICY_HND *alias_pol = r->out.alias_handle;
3057 struct samr_info *info = NULL;
3058 SEC_DESC *psd = NULL;
3060 uint32 des_access = r->in.access_mask;
3065 /* find the domain policy and get the SID / access bits stored in the domain policy */
3067 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3068 return NT_STATUS_INVALID_HANDLE;
3070 status = access_check_samr_function(acc_granted,
3071 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_OpenAlias");
3073 if ( !NT_STATUS_IS_OK(status) )
3076 /* append the alias' RID to it */
3078 if (!sid_append_rid(&sid, alias_rid))
3079 return NT_STATUS_NO_SUCH_ALIAS;
3081 /*check if access can be granted as requested by client. */
3083 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3084 se_map_generic(&des_access,&ali_generic_mapping);
3086 se_priv_copy( &se_rights, &se_add_users );
3089 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3090 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3091 &acc_granted, "_samr_OpenAlias");
3093 if ( !NT_STATUS_IS_OK(status) )
3097 /* Check we actually have the requested alias */
3098 enum lsa_SidType type;
3103 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3106 if (!result || (type != SID_NAME_ALIAS)) {
3107 return NT_STATUS_NO_SUCH_ALIAS;
3110 /* make sure there is a mapping */
3112 if ( !sid_to_gid( &sid, &gid ) ) {
3113 return NT_STATUS_NO_SUCH_ALIAS;
3118 /* associate the alias SID with the new handle. */
3119 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3120 return NT_STATUS_NO_MEMORY;
3122 info->acc_granted = acc_granted;
3124 /* get a (unique) handle. open a policy on it. */
3125 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3126 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3128 return NT_STATUS_OK;
3131 /*******************************************************************
3133 ********************************************************************/
3134 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3135 const SAM_USER_INFO_7 *id7, struct samu *pwd)
3141 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3143 return NT_STATUS_ACCESS_DENIED;
3146 if(!rpcstr_pull(new_name, id7->uni_name.buffer, sizeof(new_name), id7->uni_name.uni_str_len*2, 0)) {
3147 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3149 return NT_STATUS_ACCESS_DENIED;
3152 /* check to see if the new username already exists. Note: we can't
3153 reliably lock all backends, so there is potentially the
3154 possibility that a user can be created in between this check and
3155 the rename. The rename should fail, but may not get the
3156 exact same failure status code. I think this is small enough
3157 of a window for this type of operation and the results are
3158 simply that the rename fails with a slightly different status
3159 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3161 rc = can_create(mem_ctx, new_name);
3162 if (!NT_STATUS_IS_OK(rc)) {
3166 rc = pdb_rename_sam_account(pwd, new_name);
3172 /*******************************************************************
3174 ********************************************************************/
3176 static bool set_user_info_16(const SAM_USER_INFO_16 *id16, struct samu *pwd)
3179 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3184 /* FIX ME: check if the value is really changed --metze */
3185 if (!pdb_set_acct_ctrl(pwd, id16->acb_info, PDB_CHANGED)) {
3190 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3200 /*******************************************************************
3202 ********************************************************************/
3204 static bool set_user_info_18(SAM_USER_INFO_18 *id18, struct samu *pwd)
3208 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3213 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd, PDB_CHANGED)) {
3217 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd, PDB_CHANGED)) {
3221 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3226 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3235 /*******************************************************************
3237 ********************************************************************/
3239 static bool set_user_info_20(SAM_USER_INFO_20 *id20, struct samu *pwd)
3242 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3246 copy_id20_to_sam_passwd(pwd, id20);
3248 /* write the change out */
3249 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3258 /*******************************************************************
3260 ********************************************************************/
3262 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
3269 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3270 return NT_STATUS_INVALID_PARAMETER;
3273 /* we need to separately check for an account rename first */
3275 if (rpcstr_pull(new_name, id21->uni_user_name.buffer,
3276 sizeof(new_name), id21->uni_user_name.uni_str_len*2, 0)
3277 && (!strequal(new_name, pdb_get_username(pwd))))
3280 /* check to see if the new username already exists. Note: we can't
3281 reliably lock all backends, so there is potentially the
3282 possibility that a user can be created in between this check and
3283 the rename. The rename should fail, but may not get the
3284 exact same failure status code. I think this is small enough
3285 of a window for this type of operation and the results are
3286 simply that the rename fails with a slightly different status
3287 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3289 status = can_create(mem_ctx, new_name);
3290 if (!NT_STATUS_IS_OK(status)) {
3294 status = pdb_rename_sam_account(pwd, new_name);
3296 if (!NT_STATUS_IS_OK(status)) {
3297 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3298 nt_errstr(status)));
3303 /* set the new username so that later
3304 functions can work on the new account */
3305 pdb_set_username(pwd, new_name, PDB_SET);
3308 copy_id21_to_sam_passwd(pwd, id21);
3311 * The funny part about the previous two calls is
3312 * that pwd still has the password hashes from the
3313 * passdb entry. These have not been updated from
3314 * id21. I don't know if they need to be set. --jerry
3317 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3318 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3319 if ( !NT_STATUS_IS_OK(status) ) {
3324 /* Don't worry about writing out the user account since the
3325 primary group SID is generated solely from the user's Unix
3328 /* write the change out */
3329 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3336 return NT_STATUS_OK;
3339 /*******************************************************************
3341 ********************************************************************/
3343 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23,
3346 char *plaintext_buf = NULL;
3352 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3353 return NT_STATUS_INVALID_PARAMETER;
3356 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3357 pdb_get_username(pwd)));
3359 acct_ctrl = pdb_get_acct_ctrl(pwd);
3361 if (!decode_pw_buffer(mem_ctx,
3367 return NT_STATUS_INVALID_PARAMETER;
3370 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3372 return NT_STATUS_ACCESS_DENIED;
3375 copy_id23_to_sam_passwd(pwd, id23);
3377 /* if it's a trust account, don't update /etc/passwd */
3378 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3379 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3380 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3381 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3383 /* update the UNIX password */
3384 if (lp_unix_password_sync() ) {
3385 struct passwd *passwd;
3386 if (pdb_get_username(pwd) == NULL) {
3387 DEBUG(1, ("chgpasswd: User without name???\n"));
3389 return NT_STATUS_ACCESS_DENIED;
3392 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3393 if (passwd == NULL) {
3394 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3397 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3399 return NT_STATUS_ACCESS_DENIED;
3401 TALLOC_FREE(passwd);
3405 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3407 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3408 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3414 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3421 return NT_STATUS_OK;
3424 /*******************************************************************
3426 ********************************************************************/
3428 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
3431 char *plaintext_buf = NULL;
3433 time_t last_set_time;
3434 enum pdb_value_state last_set_state;
3436 DEBUG(5, ("Attempting administrator password change for user %s\n",
3437 pdb_get_username(pwd)));
3439 acct_ctrl = pdb_get_acct_ctrl(pwd);
3440 /* we need to know if it's expired, because this is an admin change, not a
3441 user change, so it's still expired when we're done */
3442 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3443 last_set_time = pdb_get_pass_last_set_time(pwd);
3445 if (!decode_pw_buffer(talloc_tos(),
3454 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3459 /* if it's a trust account, don't update /etc/passwd */
3460 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3461 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3462 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3463 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3465 /* update the UNIX password */
3466 if (lp_unix_password_sync()) {
3467 struct passwd *passwd;
3469 if (pdb_get_username(pwd) == NULL) {
3470 DEBUG(1, ("chgpasswd: User without name???\n"));
3475 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3476 if (passwd == NULL) {
3477 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3480 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3484 TALLOC_FREE(passwd);
3488 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3490 /* restore last set time as this is an admin change, not a user pw change */
3491 pdb_set_pass_last_set_time (pwd, last_set_time, last_set_state);
3493 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3495 /* update the SAMBA password */
3496 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3506 /*******************************************************************
3508 ********************************************************************/
3510 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx, SAM_USER_INFO_25 *id25,
3516 DEBUG(5, ("set_user_info_25: NULL id25\n"));
3517 return NT_STATUS_INVALID_PARAMETER;
3520 copy_id25_to_sam_passwd(pwd, id25);
3522 /* write the change out */
3523 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3529 * We need to "pdb_update_sam_account" before the unix primary group
3530 * is set, because the idealx scripts would also change the
3531 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
3532 * the delete explicit / add explicit, which would then fail to find
3533 * the previous primaryGroupSid value.
3536 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3537 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3538 if ( !NT_STATUS_IS_OK(status) ) {
3543 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
3546 return NT_STATUS_OK;
3549 /*******************************************************************
3550 samr_reply_set_userinfo
3551 ********************************************************************/
3553 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3555 struct samu *pwd = NULL;
3557 POLICY_HND *pol = &q_u->pol;
3558 uint16 switch_value = q_u->switch_value;
3559 SAM_USERINFO_CTR *ctr = q_u->ctr;
3561 uint32 acc_required;
3563 bool has_enough_rights = False;
3565 DISP_INFO *disp_info = NULL;
3567 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3569 r_u->status = NT_STATUS_OK;
3571 /* find the policy handle. open a policy on it. */
3572 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info))
3573 return NT_STATUS_INVALID_HANDLE;
3575 /* This is tricky. A WinXP domain join sets
3576 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
3577 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
3578 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
3579 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
3580 we'll use the set from the WinXP join as the basis. */
3582 switch (switch_value) {
3587 acc_required = SA_RIGHT_USER_SET_PASSWORD;
3590 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3594 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3598 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n",
3599 sid_string_dbg(&sid), switch_value));
3602 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3603 return NT_STATUS_INVALID_INFO_CLASS;
3606 if ( !(pwd = samu_new( NULL )) ) {
3607 return NT_STATUS_NO_MEMORY;
3611 ret = pdb_getsampwsid(pwd, &sid);
3616 return NT_STATUS_NO_SUCH_USER;
3619 /* deal with machine password changes differently from userinfo changes */
3620 /* check to see if we have the sufficient rights */
3622 acb_info = pdb_get_acct_ctrl(pwd);
3623 if ( acb_info & ACB_WSTRUST )
3624 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3625 else if ( acb_info & ACB_NORMAL )
3626 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3627 else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3628 if ( lp_enable_privileges() )
3629 has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3632 DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3633 uidtoname(p->pipe_user.ut.uid),
3634 has_enough_rights ? "" : " not"));
3636 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3638 if ( has_enough_rights )
3641 /* ok! user info levels (lots: see MSDEV help), off we go... */
3643 switch (switch_value) {
3645 if (!set_user_info_18(ctr->info.id18, pwd))
3646 r_u->status = NT_STATUS_ACCESS_DENIED;
3650 if (!p->session_key.length) {
3651 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3653 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3655 dump_data(100, ctr->info.id24->pass, 516);
3657 if (!set_user_info_pw(ctr->info.id24->pass, pwd))
3658 r_u->status = NT_STATUS_ACCESS_DENIED;
3662 if (!p->session_key.length) {
3663 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3665 encode_or_decode_arc4_passwd_buffer(ctr->info.id25->pass, &p->session_key);
3667 dump_data(100, ctr->info.id25->pass, 532);
3669 r_u->status = set_user_info_25(p->mem_ctx,
3670 ctr->info.id25, pwd);
3671 if (!NT_STATUS_IS_OK(r_u->status)) {
3674 if (!set_user_info_pw(ctr->info.id25->pass, pwd))
3675 r_u->status = NT_STATUS_ACCESS_DENIED;
3679 if (!p->session_key.length) {
3680 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3682 encode_or_decode_arc4_passwd_buffer(ctr->info.id26->pass, &p->session_key);
3684 dump_data(100, ctr->info.id26->pass, 516);
3686 if (!set_user_info_pw(ctr->info.id26->pass, pwd))
3687 r_u->status = NT_STATUS_ACCESS_DENIED;
3691 if (!p->session_key.length) {
3692 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3694 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3696 dump_data(100, ctr->info.id23->pass, 516);
3698 r_u->status = set_user_info_23(p->mem_ctx,
3699 ctr->info.id23, pwd);
3703 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3708 if ( has_enough_rights )
3711 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3713 if (NT_STATUS_IS_OK(r_u->status)) {
3714 force_flush_samr_cache(disp_info);
3720 /*******************************************************************
3721 samr_reply_set_userinfo2
3722 ********************************************************************/
3724 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3726 struct samu *pwd = NULL;
3728 SAM_USERINFO_CTR *ctr = q_u->ctr;
3729 POLICY_HND *pol = &q_u->pol;
3730 uint16 switch_value = q_u->switch_value;
3732 uint32 acc_required;
3734 bool has_enough_rights = False;
3736 DISP_INFO *disp_info = NULL;
3738 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3740 r_u->status = NT_STATUS_OK;
3742 /* find the policy handle. open a policy on it. */
3743 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info))
3744 return NT_STATUS_INVALID_HANDLE;
3747 #if 0 /* this really should be applied on a per info level basis --jerry */
3749 /* observed when joining XP client to Samba domain */
3750 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3752 acc_required = SA_RIGHT_USER_SET_ATTRIBUTES;
3755 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3759 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n",
3760 sid_string_dbg(&sid)));
3763 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3764 return NT_STATUS_INVALID_INFO_CLASS;
3767 switch_value=ctr->switch_value;
3769 if ( !(pwd = samu_new( NULL )) ) {
3770 return NT_STATUS_NO_MEMORY;
3774 ret = pdb_getsampwsid(pwd, &sid);
3779 return NT_STATUS_NO_SUCH_USER;
3782 acb_info = pdb_get_acct_ctrl(pwd);
3783 if ( acb_info & ACB_WSTRUST )
3784 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3785 else if ( acb_info & ACB_NORMAL )
3786 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3787 else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3788 if ( lp_enable_privileges() )
3789 has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3792 DEBUG(5, ("_samr_set_userinfo2: %s does%s possess sufficient rights\n",
3793 uidtoname(p->pipe_user.ut.uid),
3794 has_enough_rights ? "" : " not"));
3796 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3798 if ( has_enough_rights )
3801 /* ok! user info levels (lots: see MSDEV help), off we go... */
3803 switch (switch_value) {
3805 r_u->status = set_user_info_7(p->mem_ctx,
3806 ctr->info.id7, pwd);
3809 if (!set_user_info_16(ctr->info.id16, pwd))
3810 r_u->status = NT_STATUS_ACCESS_DENIED;
3813 /* Used by AS/U JRA. */
3814 if (!set_user_info_18(ctr->info.id18, pwd))
3815 r_u->status = NT_STATUS_ACCESS_DENIED;
3818 if (!set_user_info_20(ctr->info.id20, pwd))
3819 r_u->status = NT_STATUS_ACCESS_DENIED;
3822 r_u->status = set_user_info_21(p->mem_ctx,
3823 ctr->info.id21, pwd);
3826 if (!p->session_key.length) {
3827 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3829 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3831 dump_data(100, ctr->info.id23->pass, 516);
3833 r_u->status = set_user_info_23(p->mem_ctx,
3834 ctr->info.id23, pwd);
3837 if (!p->session_key.length) {
3838 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3840 encode_or_decode_arc4_passwd_buffer(ctr->info.id26->pass, &p->session_key);
3842 dump_data(100, ctr->info.id26->pass, 516);
3844 if (!set_user_info_pw(ctr->info.id26->pass, pwd))
3845 r_u->status = NT_STATUS_ACCESS_DENIED;
3848 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3851 if ( has_enough_rights )
3854 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3856 if (NT_STATUS_IS_OK(r_u->status)) {
3857 force_flush_samr_cache(disp_info);
3863 /*********************************************************************
3864 _samr_GetAliasMembership
3865 *********************************************************************/
3867 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
3868 struct samr_GetAliasMembership *r)
3870 size_t num_alias_rids;
3872 struct samr_info *info = NULL;
3880 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
3882 /* find the policy handle. open a policy on it. */
3883 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
3884 return NT_STATUS_INVALID_HANDLE;
3886 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_GetAliasMembership");
3887 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_GetAliasMembership");
3889 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3890 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3891 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3892 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3896 if (!sid_check_is_domain(&info->sid) &&
3897 !sid_check_is_builtin(&info->sid))
3898 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3900 if (r->in.sids->num_sids) {
3901 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
3903 if (members == NULL)
3904 return NT_STATUS_NO_MEMORY;
3909 for (i=0; i<r->in.sids->num_sids; i++)
3910 sid_copy(&members[i], r->in.sids->sids[i].sid);
3916 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
3917 r->in.sids->num_sids,
3918 &alias_rids, &num_alias_rids);
3921 if (!NT_STATUS_IS_OK(ntstatus1)) {
3925 r->out.rids->count = num_alias_rids;
3926 r->out.rids->ids = alias_rids;
3928 return NT_STATUS_OK;
3931 /*********************************************************************
3932 _samr_GetMembersInAlias
3933 *********************************************************************/
3935 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
3936 struct samr_GetMembersInAlias *r)
3940 size_t num_sids = 0;
3941 struct lsa_SidPtr *sids = NULL;
3942 DOM_SID *pdb_sids = NULL;
3948 /* find the policy handle. open a policy on it. */
3949 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
3950 return NT_STATUS_INVALID_HANDLE;
3952 status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_GetMembersInAlias");
3953 if (!NT_STATUS_IS_OK(status)) {
3957 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
3960 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
3963 if (!NT_STATUS_IS_OK(status)) {
3968 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
3970 TALLOC_FREE(pdb_sids);
3971 return NT_STATUS_NO_MEMORY;
3975 for (i = 0; i < num_sids; i++) {
3976 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
3978 TALLOC_FREE(pdb_sids);
3979 return NT_STATUS_NO_MEMORY;
3983 r->out.sids->num_sids = num_sids;
3984 r->out.sids->sids = sids;
3986 TALLOC_FREE(pdb_sids);
3988 return NT_STATUS_OK;
3991 /*********************************************************************
3992 _samr_QueryGroupMember
3993 *********************************************************************/
3995 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
3996 struct samr_QueryGroupMember *r)
3999 size_t i, num_members;
4007 struct samr_RidTypeArray *rids = NULL;
4009 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4011 return NT_STATUS_NO_MEMORY;
4014 /* find the policy handle. open a policy on it. */
4015 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4016 return NT_STATUS_INVALID_HANDLE;
4018 status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_QueryGroupMember");
4019 if (!NT_STATUS_IS_OK(status)) {
4023 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4025 if (!sid_check_is_in_our_domain(&group_sid)) {
4026 DEBUG(3, ("sid %s is not in our domain\n",
4027 sid_string_dbg(&group_sid)));
4028 return NT_STATUS_NO_SUCH_GROUP;
4031 DEBUG(10, ("lookup on Domain SID\n"));
4034 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4035 &rid, &num_members);
4038 if (!NT_STATUS_IS_OK(status))
4042 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4044 return NT_STATUS_NO_MEMORY;
4050 for (i=0; i<num_members; i++)
4051 attr[i] = SID_NAME_USER;
4053 rids->count = num_members;
4057 *r->out.rids = rids;
4059 return NT_STATUS_OK;
4062 /*********************************************************************
4063 _samr_AddAliasMember
4064 *********************************************************************/
4066 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4067 struct samr_AddAliasMember *r)
4072 bool can_add_accounts;
4074 DISP_INFO *disp_info = NULL;
4076 /* Find the policy handle. Open a policy on it. */
4077 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4078 return NT_STATUS_INVALID_HANDLE;
4080 status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_AddAliasMember");
4081 if (!NT_STATUS_IS_OK(status)) {
4085 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4087 se_priv_copy( &se_rights, &se_add_users );
4088 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4090 /******** BEGIN SeAddUsers BLOCK *********/
4092 if ( can_add_accounts )
4095 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4097 if ( can_add_accounts )
4100 /******** END SeAddUsers BLOCK *********/
4102 if (NT_STATUS_IS_OK(status)) {
4103 force_flush_samr_cache(disp_info);
4109 /*********************************************************************
4110 _samr_DeleteAliasMember
4111 *********************************************************************/
4113 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4114 struct samr_DeleteAliasMember *r)
4119 bool can_add_accounts;
4121 DISP_INFO *disp_info = NULL;
4123 /* Find the policy handle. Open a policy on it. */
4124 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4125 return NT_STATUS_INVALID_HANDLE;
4127 status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_DeleteAliasMember");
4128 if (!NT_STATUS_IS_OK(status)) {
4132 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4133 sid_string_dbg(&alias_sid)));
4135 se_priv_copy( &se_rights, &se_add_users );
4136 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4138 /******** BEGIN SeAddUsers BLOCK *********/
4140 if ( can_add_accounts )
4143 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4145 if ( can_add_accounts )
4148 /******** END SeAddUsers BLOCK *********/
4150 if (NT_STATUS_IS_OK(status)) {
4151 force_flush_samr_cache(disp_info);
4157 /*********************************************************************
4158 _samr_AddGroupMember
4159 *********************************************************************/
4161 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4162 struct samr_AddGroupMember *r)
4169 bool can_add_accounts;
4170 DISP_INFO *disp_info = NULL;
4172 /* Find the policy handle. Open a policy on it. */
4173 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4174 return NT_STATUS_INVALID_HANDLE;
4176 status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_AddGroupMember");
4177 if (!NT_STATUS_IS_OK(status)) {
4181 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4183 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4185 return NT_STATUS_INVALID_HANDLE;
4188 se_priv_copy( &se_rights, &se_add_users );
4189 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4191 /******** BEGIN SeAddUsers BLOCK *********/
4193 if ( can_add_accounts )
4196 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4198 if ( can_add_accounts )
4201 /******** END SeAddUsers BLOCK *********/
4203 force_flush_samr_cache(disp_info);
4208 /*********************************************************************
4209 _samr_DeleteGroupMember
4210 *********************************************************************/
4212 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4213 struct samr_DeleteGroupMember *r)
4221 bool can_add_accounts;
4222 DISP_INFO *disp_info = NULL;
4225 * delete the group member named r->in.rid
4226 * who is a member of the sid associated with the handle
4227 * the rid is a user's rid as the group is a domain group.
4230 /* Find the policy handle. Open a policy on it. */
4231 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4232 return NT_STATUS_INVALID_HANDLE;
4234 status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_DeleteGroupMember");
4235 if (!NT_STATUS_IS_OK(status)) {
4239 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4241 return NT_STATUS_INVALID_HANDLE;
4244 se_priv_copy( &se_rights, &se_add_users );
4245 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4247 /******** BEGIN SeAddUsers BLOCK *********/
4249 if ( can_add_accounts )
4252 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4254 if ( can_add_accounts )
4257 /******** END SeAddUsers BLOCK *********/
4259 force_flush_samr_cache(disp_info);
4264 /*********************************************************************
4266 *********************************************************************/
4268 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4269 struct samr_DeleteUser *r)
4273 struct samu *sam_pass=NULL;
4275 bool can_add_accounts;
4277 DISP_INFO *disp_info = NULL;
4280 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4282 /* Find the policy handle. Open a policy on it. */
4283 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4284 return NT_STATUS_INVALID_HANDLE;
4286 status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_DeleteUser");
4287 if (!NT_STATUS_IS_OK(status)) {
4291 if (!sid_check_is_in_our_domain(&user_sid))
4292 return NT_STATUS_CANNOT_DELETE;
4294 /* check if the user exists before trying to delete */
4295 if ( !(sam_pass = samu_new( NULL )) ) {
4296 return NT_STATUS_NO_MEMORY;
4300 ret = pdb_getsampwsid(sam_pass, &user_sid);
4304 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4305 sid_string_dbg(&user_sid)));
4306 TALLOC_FREE(sam_pass);
4307 return NT_STATUS_NO_SUCH_USER;
4310 acb_info = pdb_get_acct_ctrl(sam_pass);
4312 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4313 if ( acb_info & ACB_WSTRUST ) {
4314 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4316 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4319 /******** BEGIN SeAddUsers BLOCK *********/
4321 if ( can_add_accounts )
4324 status = pdb_delete_user(p->mem_ctx, sam_pass);
4326 if ( can_add_accounts )
4329 /******** END SeAddUsers BLOCK *********/
4331 if ( !NT_STATUS_IS_OK(status) ) {
4332 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4333 "user %s: %s.\n", pdb_get_username(sam_pass),
4334 nt_errstr(status)));
4335 TALLOC_FREE(sam_pass);
4340 TALLOC_FREE(sam_pass);
4342 if (!close_policy_hnd(p, r->in.user_handle))
4343 return NT_STATUS_OBJECT_NAME_INVALID;
4345 force_flush_samr_cache(disp_info);
4347 return NT_STATUS_OK;
4350 /*********************************************************************
4351 _samr_DeleteDomainGroup
4352 *********************************************************************/
4354 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4355 struct samr_DeleteDomainGroup *r)
4362 bool can_add_accounts;
4363 DISP_INFO *disp_info = NULL;
4365 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4367 /* Find the policy handle. Open a policy on it. */
4368 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4369 return NT_STATUS_INVALID_HANDLE;
4371 status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_DeleteDomainGroup");
4372 if (!NT_STATUS_IS_OK(status)) {
4376 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4378 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4380 return NT_STATUS_NO_SUCH_GROUP;
4383 se_priv_copy( &se_rights, &se_add_users );
4384 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4386 /******** BEGIN SeAddUsers BLOCK *********/
4388 if ( can_add_accounts )
4391 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4393 if ( can_add_accounts )
4396 /******** END SeAddUsers BLOCK *********/
4398 if ( !NT_STATUS_IS_OK(status) ) {
4399 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4400 "entry for group %s: %s\n",
4401 sid_string_dbg(&group_sid),
4402 nt_errstr(status)));
4406 if (!close_policy_hnd(p, r->in.group_handle))
4407 return NT_STATUS_OBJECT_NAME_INVALID;
4409 force_flush_samr_cache(disp_info);
4411 return NT_STATUS_OK;
4414 /*********************************************************************
4415 _samr_DeleteDomAlias
4416 *********************************************************************/
4418 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4419 struct samr_DeleteDomAlias *r)
4424 bool can_add_accounts;
4426 DISP_INFO *disp_info = NULL;
4428 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4430 /* Find the policy handle. Open a policy on it. */
4431 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4432 return NT_STATUS_INVALID_HANDLE;
4434 /* copy the handle to the outgoing reply */
4436 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4438 status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_DeleteDomAlias");
4439 if (!NT_STATUS_IS_OK(status)) {
4443 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4445 /* Don't let Windows delete builtin groups */
4447 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4448 return NT_STATUS_SPECIAL_ACCOUNT;
4451 if (!sid_check_is_in_our_domain(&alias_sid))
4452 return NT_STATUS_NO_SUCH_ALIAS;
4454 DEBUG(10, ("lookup on Local SID\n"));
4456 se_priv_copy( &se_rights, &se_add_users );
4457 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4459 /******** BEGIN SeAddUsers BLOCK *********/
4461 if ( can_add_accounts )
4464 /* Have passdb delete the alias */
4465 status = pdb_delete_alias(&alias_sid);
4467 if ( can_add_accounts )
4470 /******** END SeAddUsers BLOCK *********/
4472 if ( !NT_STATUS_IS_OK(status))
4475 if (!close_policy_hnd(p, r->in.alias_handle))
4476 return NT_STATUS_OBJECT_NAME_INVALID;
4478 force_flush_samr_cache(disp_info);
4480 return NT_STATUS_OK;
4483 /*********************************************************************
4484 _samr_CreateDomainGroup
4485 *********************************************************************/
4487 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4488 struct samr_CreateDomainGroup *r)
4495 struct samr_info *info;
4498 bool can_add_accounts;
4499 DISP_INFO *disp_info = NULL;
4501 /* Find the policy handle. Open a policy on it. */
4502 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4503 return NT_STATUS_INVALID_HANDLE;
4505 status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_CreateDomainGroup");
4506 if (!NT_STATUS_IS_OK(status)) {
4510 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4511 return NT_STATUS_ACCESS_DENIED;
4513 name = r->in.name->string;
4515 return NT_STATUS_NO_MEMORY;
4518 status = can_create(p->mem_ctx, name);
4519 if (!NT_STATUS_IS_OK(status)) {
4523 se_priv_copy( &se_rights, &se_add_users );
4524 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4526 /******** BEGIN SeAddUsers BLOCK *********/
4528 if ( can_add_accounts )
4531 /* check that we successfully create the UNIX group */
4533 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
4535 if ( can_add_accounts )
4538 /******** END SeAddUsers BLOCK *********/
4540 /* check if we should bail out here */
4542 if ( !NT_STATUS_IS_OK(status) )
4545 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
4547 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4548 return NT_STATUS_NO_MEMORY;
4550 /* they created it; let the user do what he wants with it */
4552 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
4554 /* get a (unique) handle. open a policy on it. */
4555 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
4556 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4558 force_flush_samr_cache(disp_info);
4560 return NT_STATUS_OK;
4563 /*********************************************************************
4564 _samr_CreateDomAlias
4565 *********************************************************************/
4567 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
4568 struct samr_CreateDomAlias *r)
4572 const char *name = NULL;
4573 struct samr_info *info;
4578 bool can_add_accounts;
4579 DISP_INFO *disp_info = NULL;
4581 /* Find the policy handle. Open a policy on it. */
4582 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4583 return NT_STATUS_INVALID_HANDLE;
4585 result = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_CreateDomAlias");
4586 if (!NT_STATUS_IS_OK(result)) {
4590 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4591 return NT_STATUS_ACCESS_DENIED;
4593 name = r->in.alias_name->string;
4595 se_priv_copy( &se_rights, &se_add_users );
4596 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4598 result = can_create(p->mem_ctx, name);
4599 if (!NT_STATUS_IS_OK(result)) {
4603 /******** BEGIN SeAddUsers BLOCK *********/
4605 if ( can_add_accounts )
4608 /* Have passdb create the alias */
4609 result = pdb_create_alias(name, r->out.rid);
4611 if ( can_add_accounts )
4614 /******** END SeAddUsers BLOCK *********/
4616 if (!NT_STATUS_IS_OK(result)) {
4617 DEBUG(10, ("pdb_create_alias failed: %s\n",
4618 nt_errstr(result)));
4622 sid_copy(&info_sid, get_global_sam_sid());
4623 sid_append_rid(&info_sid, *r->out.rid);
4625 if (!sid_to_gid(&info_sid, &gid)) {
4626 DEBUG(10, ("Could not find alias just created\n"));
4627 return NT_STATUS_ACCESS_DENIED;
4630 /* check if the group has been successfully created */
4631 if ( getgrgid(gid) == NULL ) {
4632 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
4634 return NT_STATUS_ACCESS_DENIED;
4637 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4638 return NT_STATUS_NO_MEMORY;
4640 /* they created it; let the user do what he wants with it */
4642 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
4644 /* get a (unique) handle. open a policy on it. */
4645 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
4646 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4648 force_flush_samr_cache(disp_info);
4650 return NT_STATUS_OK;
4653 /*********************************************************************
4654 _samr_QueryGroupInfo
4655 *********************************************************************/
4657 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
4658 struct samr_QueryGroupInfo *r)
4663 union samr_GroupInfo *info = NULL;
4666 uint32_t attributes = SE_GROUP_MANDATORY |
4667 SE_GROUP_ENABLED_BY_DEFAULT |
4669 const char *group_name = NULL;
4670 const char *group_description = NULL;
4672 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4673 return NT_STATUS_INVALID_HANDLE;
4675 status = access_check_samr_function(acc_granted,
4676 SA_RIGHT_GROUP_LOOKUP_INFO,
4677 "_samr_QueryGroupInfo");
4678 if (!NT_STATUS_IS_OK(status)) {
4683 ret = get_domain_group_from_sid(group_sid, &map);
4686 return NT_STATUS_INVALID_HANDLE;
4688 /* FIXME: map contains fstrings */
4689 group_name = talloc_strdup(r, map.nt_name);
4690 group_description = talloc_strdup(r, map.comment);
4692 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
4694 return NT_STATUS_NO_MEMORY;
4697 switch (r->in.level) {
4703 status = pdb_enum_group_members(
4704 p->mem_ctx, &group_sid, &members, &num_members);
4707 if (!NT_STATUS_IS_OK(status)) {
4711 init_samr_group_info1(&info->all,
4719 init_samr_group_info2(&info->name,
4723 init_samr_group_info3(&info->attributes,
4727 init_samr_group_info4(&info->description,
4738 status = pdb_enum_group_members(
4739 p->mem_ctx, &group_sid, &members, &num_members);
4742 if (!NT_STATUS_IS_OK(status)) {
4746 init_samr_group_info5(&info->all2,
4749 0, /* num_members - in w2k3 this is always 0 */
4755 return NT_STATUS_INVALID_INFO_CLASS;
4758 *r->out.info = info;
4760 return NT_STATUS_OK;
4763 /*********************************************************************
4765 *********************************************************************/
4767 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
4768 struct samr_SetGroupInfo *r)
4775 bool can_mod_accounts;
4776 DISP_INFO *disp_info = NULL;
4778 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4779 return NT_STATUS_INVALID_HANDLE;
4781 status = access_check_samr_function(acc_granted,
4782 SA_RIGHT_GROUP_SET_INFO,
4783 "_samr_SetGroupInfo");
4784 if (!NT_STATUS_IS_OK(status)) {
4789 ret = get_domain_group_from_sid(group_sid, &map);
4792 return NT_STATUS_NO_SUCH_GROUP;
4794 switch (r->in.level) {
4796 fstrcpy(map.comment, r->in.info->all.description.string);
4799 fstrcpy(map.comment, r->in.info->description.string);
4802 return NT_STATUS_INVALID_INFO_CLASS;
4805 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4807 /******** BEGIN SeAddUsers BLOCK *********/
4809 if ( can_mod_accounts )
4812 status = pdb_update_group_mapping_entry(&map);
4814 if ( can_mod_accounts )
4817 /******** End SeAddUsers BLOCK *********/
4819 if (NT_STATUS_IS_OK(status)) {
4820 force_flush_samr_cache(disp_info);
4826 /*********************************************************************
4828 *********************************************************************/
4830 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
4831 struct samr_SetAliasInfo *r)
4834 struct acct_info info;
4836 bool can_mod_accounts;
4838 DISP_INFO *disp_info = NULL;
4840 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
4841 return NT_STATUS_INVALID_HANDLE;
4843 status = access_check_samr_function(acc_granted,
4844 SA_RIGHT_ALIAS_SET_INFO,
4845 "_samr_SetAliasInfo");
4846 if (!NT_STATUS_IS_OK(status)) {
4850 /* get the current group information */
4853 status = pdb_get_aliasinfo( &group_sid, &info );
4856 if ( !NT_STATUS_IS_OK(status))
4859 switch (r->in.level) {
4864 /* We currently do not support renaming groups in the
4865 the BUILTIN domain. Refer to util_builtin.c to understand
4866 why. The eventually needs to be fixed to be like Windows
4867 where you can rename builtin groups, just not delete them */
4869 if ( sid_check_is_in_builtin( &group_sid ) ) {
4870 return NT_STATUS_SPECIAL_ACCOUNT;
4873 /* There has to be a valid name (and it has to be different) */
4875 if ( !r->in.info->name.string )
4876 return NT_STATUS_INVALID_PARAMETER;
4878 /* If the name is the same just reply "ok". Yes this
4879 doesn't allow you to change the case of a group name. */
4881 if ( strequal( r->in.info->name.string, info.acct_name ) )
4882 return NT_STATUS_OK;
4884 fstrcpy( info.acct_name, r->in.info->name.string);
4886 /* make sure the name doesn't already exist as a user
4889 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
4890 status = can_create( p->mem_ctx, group_name );
4891 if ( !NT_STATUS_IS_OK( status ) )
4895 case ALIASINFODESCRIPTION:
4896 if (r->in.info->description.string) {
4897 fstrcpy(info.acct_desc,
4898 r->in.info->description.string);
4900 fstrcpy( info.acct_desc, "" );
4904 return NT_STATUS_INVALID_INFO_CLASS;
4907 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4909 /******** BEGIN SeAddUsers BLOCK *********/
4911 if ( can_mod_accounts )
4914 status = pdb_set_aliasinfo( &group_sid, &info );
4916 if ( can_mod_accounts )
4919 /******** End SeAddUsers BLOCK *********/
4921 if (NT_STATUS_IS_OK(status))
4922 force_flush_samr_cache(disp_info);
4927 /****************************************************************
4929 ****************************************************************/
4931 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
4932 struct samr_GetDomPwInfo *r)
4934 /* Perform access check. Since this rpc does not require a
4935 policy handle it will not be caught by the access checks on
4936 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4938 if (!pipe_access_check(p)) {
4939 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
4940 return NT_STATUS_ACCESS_DENIED;
4943 /* Actually, returning zeros here works quite well :-). */
4944 ZERO_STRUCTP(r->out.info);
4946 return NT_STATUS_OK;
4949 /*********************************************************************
4951 *********************************************************************/
4953 NTSTATUS _samr_OpenGroup(pipes_struct *p,
4954 struct samr_OpenGroup *r)
4960 struct samr_info *info;
4961 SEC_DESC *psd = NULL;
4963 uint32 des_access = r->in.access_mask;
4970 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
4971 return NT_STATUS_INVALID_HANDLE;
4973 status = access_check_samr_function(acc_granted,
4974 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_OpenGroup");
4976 if ( !NT_STATUS_IS_OK(status) )
4979 /*check if access can be granted as requested by client. */
4980 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
4981 se_map_generic(&des_access,&grp_generic_mapping);
4983 se_priv_copy( &se_rights, &se_add_users );
4985 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
4986 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
4987 &acc_granted, "_samr_OpenGroup");
4989 if ( !NT_STATUS_IS_OK(status) )
4992 /* this should not be hard-coded like this */
4994 if (!sid_equal(&sid, get_global_sam_sid()))
4995 return NT_STATUS_ACCESS_DENIED;
4997 sid_copy(&info_sid, get_global_sam_sid());
4998 sid_append_rid(&info_sid, r->in.rid);
4999 sid_to_fstring(sid_string, &info_sid);
5001 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5002 return NT_STATUS_NO_MEMORY;
5004 info->acc_granted = acc_granted;
5006 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5008 /* check if that group really exists */
5010 ret = get_domain_group_from_sid(info->sid, &map);
5013 return NT_STATUS_NO_SUCH_GROUP;
5015 /* get a (unique) handle. open a policy on it. */
5016 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5017 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5019 return NT_STATUS_OK;
5022 /*********************************************************************
5023 _samr_RemoveMemberFromForeignDomain
5024 *********************************************************************/
5026 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5027 struct samr_RemoveMemberFromForeignDomain *r)
5029 DOM_SID delete_sid, domain_sid;
5032 DISP_INFO *disp_info = NULL;
5034 sid_copy( &delete_sid, r->in.sid );
5036 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5037 sid_string_dbg(&delete_sid)));
5039 /* Find the policy handle. Open a policy on it. */
5041 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5042 &acc_granted, &disp_info))
5043 return NT_STATUS_INVALID_HANDLE;
5045 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
5046 "_samr_RemoveMemberFromForeignDomain");
5048 if (!NT_STATUS_IS_OK(result))
5051 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5052 sid_string_dbg(&domain_sid)));
5054 /* we can only delete a user from a group since we don't have
5055 nested groups anyways. So in the latter case, just say OK */
5057 /* TODO: The above comment nowadays is bogus. Since we have nested
5058 * groups now, and aliases members are never reported out of the unix
5059 * group membership, the "just say OK" makes this call a no-op. For
5060 * us. This needs fixing however. */
5062 /* I've only ever seen this in the wild when deleting a user from
5063 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5064 * is the user about to be deleted. I very much suspect this is the
5065 * only application of this call. To verify this, let people report
5068 if (!sid_check_is_builtin(&domain_sid)) {
5069 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5070 "global_sam_sid() = %s\n",
5071 sid_string_dbg(&domain_sid),
5072 sid_string_dbg(get_global_sam_sid())));
5073 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5074 return NT_STATUS_OK;
5077 force_flush_samr_cache(disp_info);
5079 result = NT_STATUS_OK;
5084 /*******************************************************************
5085 _samr_QueryDomainInfo2
5086 ********************************************************************/
5088 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5089 struct samr_QueryDomainInfo2 *r)
5091 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5093 r->in.domain_handle,
5098 /*******************************************************************
5100 ********************************************************************/
5102 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5103 struct samr_SetDomainInfo *r)
5105 time_t u_expire, u_min_age;
5107 time_t u_lock_duration, u_reset_time;
5109 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5111 /* find the policy handle. open a policy on it. */
5112 if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5113 return NT_STATUS_INVALID_HANDLE;
5115 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5117 switch (r->in.level) {
5119 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5120 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5121 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5122 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5123 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5124 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5125 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5130 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5131 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5140 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5141 if (u_lock_duration != -1)
5142 u_lock_duration /= 60;
5144 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5146 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5147 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5148 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5151 return NT_STATUS_INVALID_INFO_CLASS;
5154 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5156 return NT_STATUS_OK;
5159 /****************************************************************
5160 ****************************************************************/
5162 NTSTATUS _samr_Shutdown(pipes_struct *p,
5163 struct samr_Shutdown *r)
5165 p->rng_fault_state = true;
5166 return NT_STATUS_NOT_IMPLEMENTED;
5169 /****************************************************************
5170 ****************************************************************/
5172 NTSTATUS _samr_EnumDomains(pipes_struct *p,
5173 struct samr_EnumDomains *r)
5175 p->rng_fault_state = true;
5176 return NT_STATUS_NOT_IMPLEMENTED;
5179 /****************************************************************
5180 ****************************************************************/
5182 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
5183 struct samr_EnumDomainGroups *r)
5185 p->rng_fault_state = true;
5186 return NT_STATUS_NOT_IMPLEMENTED;
5189 /****************************************************************
5190 ****************************************************************/
5192 NTSTATUS _samr_CreateUser(pipes_struct *p,
5193 struct samr_CreateUser *r)
5195 p->rng_fault_state = true;
5196 return NT_STATUS_NOT_IMPLEMENTED;
5199 /****************************************************************
5200 ****************************************************************/
5202 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
5203 struct samr_EnumDomainUsers *r)
5205 p->rng_fault_state = true;
5206 return NT_STATUS_NOT_IMPLEMENTED;
5209 /****************************************************************
5210 ****************************************************************/
5212 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
5213 struct samr_EnumDomainAliases *r)
5215 p->rng_fault_state = true;
5216 return NT_STATUS_NOT_IMPLEMENTED;
5219 /****************************************************************
5220 ****************************************************************/
5222 NTSTATUS _samr_LookupNames(pipes_struct *p,
5223 struct samr_LookupNames *r)
5225 p->rng_fault_state = true;
5226 return NT_STATUS_NOT_IMPLEMENTED;
5229 /****************************************************************
5230 ****************************************************************/
5232 NTSTATUS _samr_LookupRids(pipes_struct *p,
5233 struct samr_LookupRids *r)
5235 p->rng_fault_state = true;
5236 return NT_STATUS_NOT_IMPLEMENTED;
5239 /****************************************************************
5240 ****************************************************************/
5242 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5243 struct samr_SetMemberAttributesOfGroup *r)
5245 p->rng_fault_state = true;
5246 return NT_STATUS_NOT_IMPLEMENTED;
5249 /****************************************************************
5250 ****************************************************************/
5252 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
5253 struct samr_QueryUserInfo *r)
5255 p->rng_fault_state = true;
5256 return NT_STATUS_NOT_IMPLEMENTED;
5259 /****************************************************************
5260 ****************************************************************/
5262 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
5263 struct samr_SetUserInfo *r)
5265 p->rng_fault_state = true;
5266 return NT_STATUS_NOT_IMPLEMENTED;
5269 /****************************************************************
5270 ****************************************************************/
5272 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5273 struct samr_ChangePasswordUser *r)
5275 p->rng_fault_state = true;
5276 return NT_STATUS_NOT_IMPLEMENTED;
5279 /****************************************************************
5280 ****************************************************************/
5282 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
5283 struct samr_QueryDisplayInfo *r)
5285 p->rng_fault_state = true;
5286 return NT_STATUS_NOT_IMPLEMENTED;
5289 /****************************************************************
5290 ****************************************************************/
5292 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5293 struct samr_GetDisplayEnumerationIndex *r)
5295 p->rng_fault_state = true;
5296 return NT_STATUS_NOT_IMPLEMENTED;
5299 /****************************************************************
5300 ****************************************************************/
5302 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5303 struct samr_TestPrivateFunctionsDomain *r)
5305 p->rng_fault_state = true;
5306 return NT_STATUS_NOT_IMPLEMENTED;
5309 /****************************************************************
5310 ****************************************************************/
5312 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5313 struct samr_TestPrivateFunctionsUser *r)
5315 p->rng_fault_state = true;
5316 return NT_STATUS_NOT_IMPLEMENTED;
5319 /****************************************************************
5320 ****************************************************************/
5322 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5323 struct samr_QueryUserInfo2 *r)
5325 p->rng_fault_state = true;
5326 return NT_STATUS_NOT_IMPLEMENTED;
5329 /****************************************************************
5330 ****************************************************************/
5332 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
5333 struct samr_QueryDisplayInfo2 *r)
5335 p->rng_fault_state = true;
5336 return NT_STATUS_NOT_IMPLEMENTED;
5339 /****************************************************************
5340 ****************************************************************/
5342 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5343 struct samr_GetDisplayEnumerationIndex2 *r)
5345 p->rng_fault_state = true;
5346 return NT_STATUS_NOT_IMPLEMENTED;
5349 /****************************************************************
5350 ****************************************************************/
5352 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
5353 struct samr_QueryDisplayInfo3 *r)
5355 p->rng_fault_state = true;
5356 return NT_STATUS_NOT_IMPLEMENTED;
5359 /****************************************************************
5360 ****************************************************************/
5362 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5363 struct samr_AddMultipleMembersToAlias *r)
5365 p->rng_fault_state = true;
5366 return NT_STATUS_NOT_IMPLEMENTED;
5369 /****************************************************************
5370 ****************************************************************/
5372 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5373 struct samr_RemoveMultipleMembersFromAlias *r)
5375 p->rng_fault_state = true;
5376 return NT_STATUS_NOT_IMPLEMENTED;
5379 /****************************************************************
5380 ****************************************************************/
5382 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5383 struct samr_OemChangePasswordUser2 *r)
5385 p->rng_fault_state = true;
5386 return NT_STATUS_NOT_IMPLEMENTED;
5389 /****************************************************************
5390 ****************************************************************/
5392 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
5393 struct samr_SetUserInfo2 *r)
5395 p->rng_fault_state = true;
5396 return NT_STATUS_NOT_IMPLEMENTED;
5399 /****************************************************************
5400 ****************************************************************/
5402 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5403 struct samr_SetBootKeyInformation *r)
5405 p->rng_fault_state = true;
5406 return NT_STATUS_NOT_IMPLEMENTED;
5409 /****************************************************************
5410 ****************************************************************/
5412 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5413 struct samr_GetBootKeyInformation *r)
5415 p->rng_fault_state = true;
5416 return NT_STATUS_NOT_IMPLEMENTED;
5419 /****************************************************************
5420 ****************************************************************/
5422 NTSTATUS _samr_Connect3(pipes_struct *p,
5423 struct samr_Connect3 *r)
5425 p->rng_fault_state = true;
5426 return NT_STATUS_NOT_IMPLEMENTED;
5429 /****************************************************************
5430 ****************************************************************/
5432 NTSTATUS _samr_RidToSid(pipes_struct *p,
5433 struct samr_RidToSid *r)
5435 p->rng_fault_state = true;
5436 return NT_STATUS_NOT_IMPLEMENTED;
5439 /****************************************************************
5440 ****************************************************************/
5442 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5443 struct samr_SetDsrmPassword *r)
5445 p->rng_fault_state = true;
5446 return NT_STATUS_NOT_IMPLEMENTED;
5449 /****************************************************************
5450 ****************************************************************/
5452 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5453 struct samr_ValidatePassword *r)
5455 p->rng_fault_state = true;
5456 return NT_STATUS_NOT_IMPLEMENTED;