s4-smbtorture: remove trailing whitespace in RPC-LSA test.
[Samba.git] / source3 / rpc_server / srv_samr_nt.c
blob9527338d6eaaf8ac0f9bd87bc14bb58fb6d30ceb
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
34 #include "includes.h"
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
42 SAMR_USER_ACCESS_SET_LOC_COM)
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
49 #define MAX_SAM_ENTRIES_W95 50
51 typedef struct disp_info {
52 DOM_SID sid; /* identify which domain this is. */
53 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
54 struct pdb_search *users; /* querydispinfo 1 and 4 */
55 struct pdb_search *machines; /* querydispinfo 2 */
56 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
57 struct pdb_search *aliases; /* enumaliases */
59 uint16 enum_acb_mask;
60 struct pdb_search *enum_users; /* enumusers with a mask */
62 struct timed_event *cache_timeout_event; /* cache idle timeout
63 * handler. */
64 } DISP_INFO;
66 /* We keep a static list of these by SID as modern clients close down
67 all resources between each request in a complete enumeration. */
69 struct samr_info {
70 /* for use by the \PIPE\samr policy */
71 DOM_SID sid;
72 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
73 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
74 uint32 acc_granted;
75 DISP_INFO *disp_info;
78 static const struct generic_mapping sam_generic_mapping = {
79 GENERIC_RIGHTS_SAM_READ,
80 GENERIC_RIGHTS_SAM_WRITE,
81 GENERIC_RIGHTS_SAM_EXECUTE,
82 GENERIC_RIGHTS_SAM_ALL_ACCESS};
83 static const struct generic_mapping dom_generic_mapping = {
84 GENERIC_RIGHTS_DOMAIN_READ,
85 GENERIC_RIGHTS_DOMAIN_WRITE,
86 GENERIC_RIGHTS_DOMAIN_EXECUTE,
87 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
88 static const struct generic_mapping usr_generic_mapping = {
89 GENERIC_RIGHTS_USER_READ,
90 GENERIC_RIGHTS_USER_WRITE,
91 GENERIC_RIGHTS_USER_EXECUTE,
92 GENERIC_RIGHTS_USER_ALL_ACCESS};
93 static const struct generic_mapping usr_nopwchange_generic_mapping = {
94 GENERIC_RIGHTS_USER_READ,
95 GENERIC_RIGHTS_USER_WRITE,
96 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
97 GENERIC_RIGHTS_USER_ALL_ACCESS};
98 static const struct generic_mapping grp_generic_mapping = {
99 GENERIC_RIGHTS_GROUP_READ,
100 GENERIC_RIGHTS_GROUP_WRITE,
101 GENERIC_RIGHTS_GROUP_EXECUTE,
102 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
103 static const struct generic_mapping ali_generic_mapping = {
104 GENERIC_RIGHTS_ALIAS_READ,
105 GENERIC_RIGHTS_ALIAS_WRITE,
106 GENERIC_RIGHTS_ALIAS_EXECUTE,
107 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
109 /*******************************************************************
110 *******************************************************************/
112 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
113 const struct generic_mapping *map,
114 DOM_SID *sid, uint32 sid_access )
116 DOM_SID domadmin_sid;
117 SEC_ACE ace[5]; /* at most 5 entries */
118 size_t i = 0;
120 SEC_ACL *psa = NULL;
122 /* basic access for Everyone */
124 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
125 map->generic_execute | map->generic_read, 0);
127 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
129 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
130 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
131 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
132 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
134 /* Add Full Access for Domain Admins if we are a DC */
136 if ( IS_DC ) {
137 sid_copy( &domadmin_sid, get_global_sam_sid() );
138 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
139 init_sec_ace(&ace[i++], &domadmin_sid,
140 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
143 /* if we have a sid, give it some special access */
145 if ( sid ) {
146 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
149 /* create the security descriptor */
151 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
152 return NT_STATUS_NO_MEMORY;
154 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
155 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
156 psa, sd_size)) == NULL)
157 return NT_STATUS_NO_MEMORY;
159 return NT_STATUS_OK;
162 /*******************************************************************
163 Checks if access to an object should be granted, and returns that
164 level of access for further checks.
165 ********************************************************************/
167 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
168 SE_PRIV *rights, uint32 rights_mask,
169 uint32 des_access, uint32 *acc_granted,
170 const char *debug )
172 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
173 uint32 saved_mask = 0;
175 /* check privileges; certain SAM access bits should be overridden
176 by privileges (mostly having to do with creating/modifying/deleting
177 users and groups) */
179 if ( rights && user_has_any_privilege( token, rights ) ) {
181 saved_mask = (des_access & rights_mask);
182 des_access &= ~saved_mask;
184 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
185 rights_mask));
189 /* check the security descriptor first */
191 status = se_access_check(psd, token, des_access, acc_granted);
192 if (NT_STATUS_IS_OK(status)) {
193 goto done;
196 /* give root a free pass */
198 if ( geteuid() == sec_initial_uid() ) {
200 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
201 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
203 *acc_granted = des_access;
205 status = NT_STATUS_OK;
206 goto done;
210 done:
211 /* add in any bits saved during the privilege check (only
212 matters is status is ok) */
214 *acc_granted |= rights_mask;
216 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
217 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
218 des_access, *acc_granted));
220 return status;
223 /*******************************************************************
224 Checks if access to a function can be granted
225 ********************************************************************/
227 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
229 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
230 debug, acc_granted, acc_required));
232 /* check the security descriptor first */
234 if ( (acc_granted&acc_required) == acc_required )
235 return NT_STATUS_OK;
237 /* give root a free pass */
239 if (geteuid() == sec_initial_uid()) {
241 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
242 debug, acc_granted, acc_required));
243 DEBUGADD(4,("but overwritten by euid == 0\n"));
245 return NT_STATUS_OK;
248 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
249 debug, acc_granted, acc_required));
251 return NT_STATUS_ACCESS_DENIED;
254 /*******************************************************************
255 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
256 ********************************************************************/
258 static void map_max_allowed_access(const NT_USER_TOKEN *token,
259 uint32_t *pacc_requested)
261 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
262 return;
264 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
266 /* At least try for generic read. */
267 *pacc_requested = GENERIC_READ_ACCESS;
269 /* root gets anything. */
270 if (geteuid() == sec_initial_uid()) {
271 *pacc_requested |= GENERIC_ALL_ACCESS;
272 return;
275 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
277 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
278 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
279 *pacc_requested |= GENERIC_ALL_ACCESS;
280 return;
283 /* Full access for DOMAIN\Domain Admins. */
284 if ( IS_DC ) {
285 DOM_SID domadmin_sid;
286 sid_copy( &domadmin_sid, get_global_sam_sid() );
287 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
288 if (is_sid_in_token(token, &domadmin_sid)) {
289 *pacc_requested |= GENERIC_ALL_ACCESS;
290 return;
293 /* TODO ! Check privileges. */
296 /*******************************************************************
297 Fetch or create a dispinfo struct.
298 ********************************************************************/
300 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
303 * We do a static cache for DISP_INFO's here. Explanation can be found
304 * in Jeremy's checkin message to r11793:
306 * Fix the SAMR cache so it works across completely insane
307 * client behaviour (ie.:
308 * open pipe/open SAMR handle/enumerate 0 - 1024
309 * close SAMR handle, close pipe.
310 * open pipe/open SAMR handle/enumerate 1024 - 2048...
311 * close SAMR handle, close pipe.
312 * And on ad-nausium. Amazing.... probably object-oriented
313 * client side programming in action yet again.
314 * This change should *massively* improve performance when
315 * enumerating users from an LDAP database.
316 * Jeremy.
318 * "Our" and the builtin domain are the only ones where we ever
319 * enumerate stuff, so just cache 2 entries.
322 static struct disp_info *builtin_dispinfo;
323 static struct disp_info *domain_dispinfo;
325 /* There are two cases to consider here:
326 1) The SID is a domain SID and we look for an equality match, or
327 2) This is an account SID and so we return the DISP_INFO* for our
328 domain */
330 if (psid == NULL) {
331 return NULL;
334 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
336 * Necessary only once, but it does not really hurt.
338 if (builtin_dispinfo == NULL) {
339 builtin_dispinfo = talloc_zero(
340 talloc_autofree_context(), struct disp_info);
341 if (builtin_dispinfo == NULL) {
342 return NULL;
345 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
346 builtin_dispinfo->builtin_domain = true;
348 return builtin_dispinfo;
351 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
353 * Necessary only once, but it does not really hurt.
355 if (domain_dispinfo == NULL) {
356 domain_dispinfo = talloc_zero(
357 talloc_autofree_context(), struct disp_info);
358 if (domain_dispinfo == NULL) {
359 return NULL;
362 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
363 domain_dispinfo->builtin_domain = false;
365 return domain_dispinfo;
368 return NULL;
371 /*******************************************************************
372 Create a samr_info struct.
373 ********************************************************************/
375 static int samr_info_destructor(struct samr_info *info);
377 static struct samr_info *get_samr_info_by_sid(TALLOC_CTX *mem_ctx,
378 DOM_SID *psid)
380 struct samr_info *info;
381 fstring sid_str;
383 if (psid) {
384 sid_to_fstring(sid_str, psid);
385 } else {
386 fstrcpy(sid_str,"(NULL)");
389 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL) {
390 return NULL;
392 talloc_set_destructor(info, samr_info_destructor);
394 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
395 if (psid) {
396 sid_copy( &info->sid, psid);
397 info->builtin_domain = sid_check_is_builtin(psid);
398 } else {
399 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
400 info->builtin_domain = False;
403 info->disp_info = get_samr_dispinfo_by_sid(psid);
405 return info;
408 /*******************************************************************
409 Function to free the per SID data.
410 ********************************************************************/
412 static void free_samr_cache(DISP_INFO *disp_info)
414 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
415 sid_string_dbg(&disp_info->sid)));
417 /* We need to become root here because the paged search might have to
418 * tell the LDAP server we're not interested in the rest anymore. */
420 become_root();
422 TALLOC_FREE(disp_info->users);
423 TALLOC_FREE(disp_info->machines);
424 TALLOC_FREE(disp_info->groups);
425 TALLOC_FREE(disp_info->aliases);
426 TALLOC_FREE(disp_info->enum_users);
428 unbecome_root();
431 static int samr_info_destructor(struct samr_info *info)
433 /* Only free the dispinfo cache if no one bothered to set up
434 a timeout. */
436 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
437 free_samr_cache(info->disp_info);
439 return 0;
442 /*******************************************************************
443 Idle event handler. Throw away the disp info cache.
444 ********************************************************************/
446 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
447 struct timed_event *te,
448 struct timeval now,
449 void *private_data)
451 DISP_INFO *disp_info = (DISP_INFO *)private_data;
453 TALLOC_FREE(disp_info->cache_timeout_event);
455 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
456 "out\n"));
457 free_samr_cache(disp_info);
460 /*******************************************************************
461 Setup cache removal idle event handler.
462 ********************************************************************/
464 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
466 /* Remove any pending timeout and update. */
468 TALLOC_FREE(disp_info->cache_timeout_event);
470 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
471 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
472 (unsigned int)secs_fromnow ));
474 disp_info->cache_timeout_event = event_add_timed(
475 smbd_event_context(), NULL,
476 timeval_current_ofs(secs_fromnow, 0),
477 disp_info_cache_idle_timeout_handler, (void *)disp_info);
480 /*******************************************************************
481 Force flush any cache. We do this on any samr_set_xxx call.
482 We must also remove the timeout handler.
483 ********************************************************************/
485 static void force_flush_samr_cache(DISP_INFO *disp_info)
487 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
488 return;
491 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
492 TALLOC_FREE(disp_info->cache_timeout_event);
493 free_samr_cache(disp_info);
496 /*******************************************************************
497 Ensure password info is never given out. Paranioa... JRA.
498 ********************************************************************/
500 static void samr_clear_sam_passwd(struct samu *sam_pass)
503 if (!sam_pass)
504 return;
506 /* These now zero out the old password */
508 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
509 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
512 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
514 struct samr_displayentry *entry;
516 if (info->builtin_domain) {
517 /* No users in builtin. */
518 return 0;
521 if (info->users == NULL) {
522 info->users = pdb_search_users(info, acct_flags);
523 if (info->users == NULL) {
524 return 0;
527 /* Fetch the last possible entry, thus trigger an enumeration */
528 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
530 /* Ensure we cache this enumeration. */
531 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
533 return info->users->num_entries;
536 static uint32 count_sam_groups(struct disp_info *info)
538 struct samr_displayentry *entry;
540 if (info->builtin_domain) {
541 /* No groups in builtin. */
542 return 0;
545 if (info->groups == NULL) {
546 info->groups = pdb_search_groups(info);
547 if (info->groups == NULL) {
548 return 0;
551 /* Fetch the last possible entry, thus trigger an enumeration */
552 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
554 /* Ensure we cache this enumeration. */
555 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
557 return info->groups->num_entries;
560 static uint32 count_sam_aliases(struct disp_info *info)
562 struct samr_displayentry *entry;
564 if (info->aliases == NULL) {
565 info->aliases = pdb_search_aliases(info, &info->sid);
566 if (info->aliases == NULL) {
567 return 0;
570 /* Fetch the last possible entry, thus trigger an enumeration */
571 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
573 /* Ensure we cache this enumeration. */
574 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
576 return info->aliases->num_entries;
579 /*******************************************************************
580 _samr_Close
581 ********************************************************************/
583 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
585 if (!close_policy_hnd(p, r->in.handle)) {
586 return NT_STATUS_INVALID_HANDLE;
589 ZERO_STRUCTP(r->out.handle);
591 return NT_STATUS_OK;
594 /*******************************************************************
595 _samr_OpenDomain
596 ********************************************************************/
598 NTSTATUS _samr_OpenDomain(pipes_struct *p,
599 struct samr_OpenDomain *r)
601 struct samr_info *info;
602 SEC_DESC *psd = NULL;
603 uint32 acc_granted;
604 uint32 des_access = r->in.access_mask;
605 NTSTATUS status;
606 size_t sd_size;
607 SE_PRIV se_rights;
609 /* find the connection policy handle. */
611 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
612 return NT_STATUS_INVALID_HANDLE;
614 /*check if access can be granted as requested by client. */
615 map_max_allowed_access(p->server_info->ptok, &des_access);
617 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
618 se_map_generic( &des_access, &dom_generic_mapping );
620 se_priv_copy( &se_rights, &se_machine_account );
621 se_priv_add( &se_rights, &se_add_users );
623 status = access_check_samr_object( psd, p->server_info->ptok,
624 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
625 &acc_granted, "_samr_OpenDomain" );
627 if ( !NT_STATUS_IS_OK(status) )
628 return status;
630 if (!sid_check_is_domain(r->in.sid) &&
631 !sid_check_is_builtin(r->in.sid)) {
632 return NT_STATUS_NO_SUCH_DOMAIN;
635 /* associate the domain SID with the (unique) handle. */
636 if ((info = get_samr_info_by_sid(p->mem_ctx, r->in.sid))==NULL)
637 return NT_STATUS_NO_MEMORY;
638 info->acc_granted = acc_granted;
640 /* get a (unique) handle. open a policy on it. */
641 if (!create_policy_hnd(p, r->out.domain_handle, info))
642 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
644 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
646 return NT_STATUS_OK;
649 /*******************************************************************
650 _samr_GetUserPwInfo
651 ********************************************************************/
653 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
654 struct samr_GetUserPwInfo *r)
656 struct samr_info *info = NULL;
657 enum lsa_SidType sid_type;
658 uint32_t min_password_length = 0;
659 uint32_t password_properties = 0;
660 bool ret = false;
661 NTSTATUS status;
663 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
665 /* find the policy handle. open a policy on it. */
666 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
667 return NT_STATUS_INVALID_HANDLE;
670 status = access_check_samr_function(info->acc_granted,
671 SAMR_USER_ACCESS_GET_ATTRIBUTES,
672 "_samr_GetUserPwInfo" );
673 if (!NT_STATUS_IS_OK(status)) {
674 return status;
677 if (!sid_check_is_in_our_domain(&info->sid)) {
678 return NT_STATUS_OBJECT_TYPE_MISMATCH;
681 become_root();
682 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
683 unbecome_root();
684 if (ret == false) {
685 return NT_STATUS_NO_SUCH_USER;
688 switch (sid_type) {
689 case SID_NAME_USER:
690 become_root();
691 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
692 &min_password_length);
693 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
694 &password_properties);
695 unbecome_root();
697 if (lp_check_password_script() && *lp_check_password_script()) {
698 password_properties |= DOMAIN_PASSWORD_COMPLEX;
701 break;
702 default:
703 break;
706 r->out.info->min_password_length = min_password_length;
707 r->out.info->password_properties = password_properties;
709 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
711 return NT_STATUS_OK;
714 /*******************************************************************
715 ********************************************************************/
717 static bool get_lsa_policy_samr_sid( pipes_struct *p, struct policy_handle *pol,
718 DOM_SID *sid, uint32 *acc_granted,
719 DISP_INFO **ppdisp_info)
721 struct samr_info *info = NULL;
723 /* find the policy handle. open a policy on it. */
724 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
725 return False;
727 if (!info)
728 return False;
730 *sid = info->sid;
731 *acc_granted = info->acc_granted;
732 if (ppdisp_info) {
733 *ppdisp_info = info->disp_info;
736 return True;
739 /*******************************************************************
740 _samr_SetSecurity
741 ********************************************************************/
743 NTSTATUS _samr_SetSecurity(pipes_struct *p,
744 struct samr_SetSecurity *r)
746 DOM_SID pol_sid;
747 uint32 acc_granted, i;
748 SEC_ACL *dacl;
749 bool ret;
750 struct samu *sampass=NULL;
751 NTSTATUS status;
753 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
754 return NT_STATUS_INVALID_HANDLE;
756 if (!(sampass = samu_new( p->mem_ctx))) {
757 DEBUG(0,("No memory!\n"));
758 return NT_STATUS_NO_MEMORY;
761 /* get the user record */
762 become_root();
763 ret = pdb_getsampwsid(sampass, &pol_sid);
764 unbecome_root();
766 if (!ret) {
767 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
768 TALLOC_FREE(sampass);
769 return NT_STATUS_INVALID_HANDLE;
772 dacl = r->in.sdbuf->sd->dacl;
773 for (i=0; i < dacl->num_aces; i++) {
774 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
775 ret = pdb_set_pass_can_change(sampass,
776 (dacl->aces[i].access_mask &
777 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
778 True: False);
779 break;
783 if (!ret) {
784 TALLOC_FREE(sampass);
785 return NT_STATUS_ACCESS_DENIED;
788 status = access_check_samr_function(acc_granted,
789 SAMR_USER_ACCESS_SET_ATTRIBUTES,
790 "_samr_SetSecurity");
791 if (NT_STATUS_IS_OK(status)) {
792 become_root();
793 status = pdb_update_sam_account(sampass);
794 unbecome_root();
797 TALLOC_FREE(sampass);
799 return status;
802 /*******************************************************************
803 build correct perms based on policies and password times for _samr_query_sec_obj
804 *******************************************************************/
805 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
807 struct samu *sampass=NULL;
808 bool ret;
810 if ( !(sampass = samu_new( mem_ctx )) ) {
811 DEBUG(0,("No memory!\n"));
812 return False;
815 become_root();
816 ret = pdb_getsampwsid(sampass, user_sid);
817 unbecome_root();
819 if (ret == False) {
820 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
821 TALLOC_FREE(sampass);
822 return False;
825 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
827 if (pdb_get_pass_can_change(sampass)) {
828 TALLOC_FREE(sampass);
829 return True;
831 TALLOC_FREE(sampass);
832 return False;
836 /*******************************************************************
837 _samr_QuerySecurity
838 ********************************************************************/
840 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
841 struct samr_QuerySecurity *r)
843 NTSTATUS status;
844 DOM_SID pol_sid;
845 SEC_DESC * psd = NULL;
846 uint32 acc_granted;
847 size_t sd_size;
849 /* Get the SID. */
850 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
851 return NT_STATUS_INVALID_HANDLE;
853 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
854 sid_string_dbg(&pol_sid)));
856 status = access_check_samr_function(acc_granted,
857 STD_RIGHT_READ_CONTROL_ACCESS,
858 "_samr_QuerySecurity");
859 if (!NT_STATUS_IS_OK(status)) {
860 return status;
863 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
865 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
866 if (pol_sid.sid_rev_num == 0) {
867 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
868 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
869 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
870 /* check if it is our domain SID */
871 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
872 "with SID: %s\n", sid_string_dbg(&pol_sid)));
873 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
874 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
875 /* check if it is the Builtin Domain */
876 /* TODO: Builtin probably needs a different SD with restricted write access*/
877 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
878 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
879 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
880 } else if (sid_check_is_in_our_domain(&pol_sid) ||
881 sid_check_is_in_builtin(&pol_sid)) {
882 /* TODO: different SDs have to be generated for aliases groups and users.
883 Currently all three get a default user SD */
884 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
885 "with SID: %s\n", sid_string_dbg(&pol_sid)));
886 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
887 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
888 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
889 } else {
890 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
891 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
893 } else {
894 return NT_STATUS_OBJECT_TYPE_MISMATCH;
897 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
898 return NT_STATUS_NO_MEMORY;
900 return status;
903 /*******************************************************************
904 makes a SAM_ENTRY / UNISTR2* structure from a user list.
905 ********************************************************************/
907 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
908 struct samr_SamEntry **sam_pp,
909 uint32_t num_entries,
910 uint32_t start_idx,
911 struct samr_displayentry *entries)
913 uint32_t i;
914 struct samr_SamEntry *sam;
916 *sam_pp = NULL;
918 if (num_entries == 0) {
919 return NT_STATUS_OK;
922 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
923 if (sam == NULL) {
924 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
925 return NT_STATUS_NO_MEMORY;
928 for (i = 0; i < num_entries; i++) {
929 #if 0
931 * usrmgr expects a non-NULL terminated string with
932 * trust relationships
934 if (entries[i].acct_flags & ACB_DOMTRUST) {
935 init_unistr2(&uni_temp_name, entries[i].account_name,
936 UNI_FLAGS_NONE);
937 } else {
938 init_unistr2(&uni_temp_name, entries[i].account_name,
939 UNI_STR_TERMINATE);
941 #endif
942 init_lsa_String(&sam[i].name, entries[i].account_name);
943 sam[i].idx = entries[i].rid;
946 *sam_pp = sam;
948 return NT_STATUS_OK;
951 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
953 /*******************************************************************
954 _samr_EnumDomainUsers
955 ********************************************************************/
957 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
958 struct samr_EnumDomainUsers *r)
960 NTSTATUS status;
961 struct samr_info *info = NULL;
962 int num_account;
963 uint32 enum_context = *r->in.resume_handle;
964 enum remote_arch_types ra_type = get_remote_arch();
965 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
966 uint32 max_entries = max_sam_entries;
967 struct samr_displayentry *entries = NULL;
968 struct samr_SamArray *samr_array = NULL;
969 struct samr_SamEntry *samr_entries = NULL;
971 /* find the policy handle. open a policy on it. */
972 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
973 return NT_STATUS_INVALID_HANDLE;
975 status = access_check_samr_function(info->acc_granted,
976 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
977 "_samr_EnumDomainUsers");
978 if (!NT_STATUS_IS_OK(status)) {
979 return status;
982 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
984 if (info->builtin_domain) {
985 /* No users in builtin. */
986 *r->out.resume_handle = *r->in.resume_handle;
987 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
988 return status;
991 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
992 if (!samr_array) {
993 return NT_STATUS_NO_MEMORY;
995 *r->out.sam = samr_array;
997 become_root();
999 /* AS ROOT !!!! */
1001 if ((info->disp_info->enum_users != NULL) &&
1002 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1003 TALLOC_FREE(info->disp_info->enum_users);
1006 if (info->disp_info->enum_users == NULL) {
1007 info->disp_info->enum_users = pdb_search_users(
1008 info->disp_info, r->in.acct_flags);
1009 info->disp_info->enum_acb_mask = r->in.acct_flags;
1012 if (info->disp_info->enum_users == NULL) {
1013 /* END AS ROOT !!!! */
1014 unbecome_root();
1015 return NT_STATUS_ACCESS_DENIED;
1018 num_account = pdb_search_entries(info->disp_info->enum_users,
1019 enum_context, max_entries,
1020 &entries);
1022 /* END AS ROOT !!!! */
1024 unbecome_root();
1026 if (num_account == 0) {
1027 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1028 "total entries\n"));
1029 *r->out.resume_handle = *r->in.resume_handle;
1030 return NT_STATUS_OK;
1033 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1034 num_account, enum_context,
1035 entries);
1036 if (!NT_STATUS_IS_OK(status)) {
1037 return status;
1040 if (max_entries <= num_account) {
1041 status = STATUS_MORE_ENTRIES;
1042 } else {
1043 status = NT_STATUS_OK;
1046 /* Ensure we cache this enumeration. */
1047 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1049 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1051 samr_array->count = num_account;
1052 samr_array->entries = samr_entries;
1054 *r->out.resume_handle = *r->in.resume_handle + num_account;
1055 *r->out.num_entries = num_account;
1057 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1059 return status;
1062 /*******************************************************************
1063 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1064 ********************************************************************/
1066 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1067 struct samr_SamEntry **sam_pp,
1068 uint32_t num_sam_entries,
1069 struct samr_displayentry *entries)
1071 struct samr_SamEntry *sam;
1072 uint32_t i;
1074 *sam_pp = NULL;
1076 if (num_sam_entries == 0) {
1077 return;
1080 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1081 if (sam == NULL) {
1082 return;
1085 for (i = 0; i < num_sam_entries; i++) {
1087 * JRA. I think this should include the null. TNG does not.
1089 init_lsa_String(&sam[i].name, entries[i].account_name);
1090 sam[i].idx = entries[i].rid;
1093 *sam_pp = sam;
1096 /*******************************************************************
1097 _samr_EnumDomainGroups
1098 ********************************************************************/
1100 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1101 struct samr_EnumDomainGroups *r)
1103 NTSTATUS status;
1104 struct samr_info *info = NULL;
1105 struct samr_displayentry *groups;
1106 uint32 num_groups;
1107 struct samr_SamArray *samr_array = NULL;
1108 struct samr_SamEntry *samr_entries = NULL;
1110 /* find the policy handle. open a policy on it. */
1111 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1112 return NT_STATUS_INVALID_HANDLE;
1114 status = access_check_samr_function(info->acc_granted,
1115 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1116 "_samr_EnumDomainGroups");
1117 if (!NT_STATUS_IS_OK(status)) {
1118 return status;
1121 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1123 if (info->builtin_domain) {
1124 /* No groups in builtin. */
1125 *r->out.resume_handle = *r->in.resume_handle;
1126 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1127 return status;
1130 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1131 if (!samr_array) {
1132 return NT_STATUS_NO_MEMORY;
1135 /* the domain group array is being allocated in the function below */
1137 become_root();
1139 if (info->disp_info->groups == NULL) {
1140 info->disp_info->groups = pdb_search_groups(info->disp_info);
1142 if (info->disp_info->groups == NULL) {
1143 unbecome_root();
1144 return NT_STATUS_ACCESS_DENIED;
1148 num_groups = pdb_search_entries(info->disp_info->groups,
1149 *r->in.resume_handle,
1150 MAX_SAM_ENTRIES, &groups);
1151 unbecome_root();
1153 /* Ensure we cache this enumeration. */
1154 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1156 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1157 num_groups, groups);
1159 samr_array->count = num_groups;
1160 samr_array->entries = samr_entries;
1162 *r->out.sam = samr_array;
1163 *r->out.num_entries = num_groups;
1164 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1166 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1168 return status;
1171 /*******************************************************************
1172 _samr_EnumDomainAliases
1173 ********************************************************************/
1175 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1176 struct samr_EnumDomainAliases *r)
1178 NTSTATUS status;
1179 struct samr_info *info;
1180 struct samr_displayentry *aliases;
1181 uint32 num_aliases = 0;
1182 struct samr_SamArray *samr_array = NULL;
1183 struct samr_SamEntry *samr_entries = NULL;
1185 /* find the policy handle. open a policy on it. */
1186 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1187 return NT_STATUS_INVALID_HANDLE;
1189 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1190 sid_string_dbg(&info->sid)));
1192 status = access_check_samr_function(info->acc_granted,
1193 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1194 "_samr_EnumDomainAliases");
1195 if (!NT_STATUS_IS_OK(status)) {
1196 return status;
1199 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1200 if (!samr_array) {
1201 return NT_STATUS_NO_MEMORY;
1204 become_root();
1206 if (info->disp_info->aliases == NULL) {
1207 info->disp_info->aliases = pdb_search_aliases(
1208 info->disp_info, &info->sid);
1209 if (info->disp_info->aliases == NULL) {
1210 unbecome_root();
1211 return NT_STATUS_ACCESS_DENIED;
1215 num_aliases = pdb_search_entries(info->disp_info->aliases,
1216 *r->in.resume_handle,
1217 MAX_SAM_ENTRIES, &aliases);
1218 unbecome_root();
1220 /* Ensure we cache this enumeration. */
1221 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1223 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1224 num_aliases, aliases);
1226 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1228 samr_array->count = num_aliases;
1229 samr_array->entries = samr_entries;
1231 *r->out.sam = samr_array;
1232 *r->out.num_entries = num_aliases;
1233 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1235 return status;
1238 /*******************************************************************
1239 inits a samr_DispInfoGeneral structure.
1240 ********************************************************************/
1242 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1243 struct samr_DispInfoGeneral *r,
1244 uint32_t num_entries,
1245 uint32_t start_idx,
1246 struct samr_displayentry *entries)
1248 uint32 i;
1250 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1252 if (num_entries == 0) {
1253 return NT_STATUS_OK;
1256 r->count = num_entries;
1258 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1259 if (!r->entries) {
1260 return NT_STATUS_NO_MEMORY;
1263 for (i = 0; i < num_entries ; i++) {
1265 init_lsa_String(&r->entries[i].account_name,
1266 entries[i].account_name);
1268 init_lsa_String(&r->entries[i].description,
1269 entries[i].description);
1271 init_lsa_String(&r->entries[i].full_name,
1272 entries[i].fullname);
1274 r->entries[i].rid = entries[i].rid;
1275 r->entries[i].acct_flags = entries[i].acct_flags;
1276 r->entries[i].idx = start_idx+i+1;
1279 return NT_STATUS_OK;
1282 /*******************************************************************
1283 inits a samr_DispInfoFull structure.
1284 ********************************************************************/
1286 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1287 struct samr_DispInfoFull *r,
1288 uint32_t num_entries,
1289 uint32_t start_idx,
1290 struct samr_displayentry *entries)
1292 uint32_t i;
1294 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1296 if (num_entries == 0) {
1297 return NT_STATUS_OK;
1300 r->count = num_entries;
1302 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1303 if (!r->entries) {
1304 return NT_STATUS_NO_MEMORY;
1307 for (i = 0; i < num_entries ; i++) {
1309 init_lsa_String(&r->entries[i].account_name,
1310 entries[i].account_name);
1312 init_lsa_String(&r->entries[i].description,
1313 entries[i].description);
1315 r->entries[i].rid = entries[i].rid;
1316 r->entries[i].acct_flags = entries[i].acct_flags;
1317 r->entries[i].idx = start_idx+i+1;
1320 return NT_STATUS_OK;
1323 /*******************************************************************
1324 inits a samr_DispInfoFullGroups structure.
1325 ********************************************************************/
1327 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1328 struct samr_DispInfoFullGroups *r,
1329 uint32_t num_entries,
1330 uint32_t start_idx,
1331 struct samr_displayentry *entries)
1333 uint32_t i;
1335 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1337 if (num_entries == 0) {
1338 return NT_STATUS_OK;
1341 r->count = num_entries;
1343 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1344 if (!r->entries) {
1345 return NT_STATUS_NO_MEMORY;
1348 for (i = 0; i < num_entries ; i++) {
1350 init_lsa_String(&r->entries[i].account_name,
1351 entries[i].account_name);
1353 init_lsa_String(&r->entries[i].description,
1354 entries[i].description);
1356 r->entries[i].rid = entries[i].rid;
1357 r->entries[i].acct_flags = entries[i].acct_flags;
1358 r->entries[i].idx = start_idx+i+1;
1361 return NT_STATUS_OK;
1364 /*******************************************************************
1365 inits a samr_DispInfoAscii structure.
1366 ********************************************************************/
1368 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1369 struct samr_DispInfoAscii *r,
1370 uint32_t num_entries,
1371 uint32_t start_idx,
1372 struct samr_displayentry *entries)
1374 uint32_t i;
1376 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1378 if (num_entries == 0) {
1379 return NT_STATUS_OK;
1382 r->count = num_entries;
1384 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1385 if (!r->entries) {
1386 return NT_STATUS_NO_MEMORY;
1389 for (i = 0; i < num_entries ; i++) {
1391 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1392 entries[i].account_name);
1394 r->entries[i].idx = start_idx+i+1;
1397 return NT_STATUS_OK;
1400 /*******************************************************************
1401 inits a samr_DispInfoAscii structure.
1402 ********************************************************************/
1404 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1405 struct samr_DispInfoAscii *r,
1406 uint32_t num_entries,
1407 uint32_t start_idx,
1408 struct samr_displayentry *entries)
1410 uint32_t i;
1412 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1414 if (num_entries == 0) {
1415 return NT_STATUS_OK;
1418 r->count = num_entries;
1420 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1421 if (!r->entries) {
1422 return NT_STATUS_NO_MEMORY;
1425 for (i = 0; i < num_entries ; i++) {
1427 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1428 entries[i].account_name);
1430 r->entries[i].idx = start_idx+i+1;
1433 return NT_STATUS_OK;
1436 /*******************************************************************
1437 _samr_QueryDisplayInfo
1438 ********************************************************************/
1440 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1441 struct samr_QueryDisplayInfo *r)
1443 NTSTATUS status;
1444 struct samr_info *info = NULL;
1445 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1447 uint32 max_entries = r->in.max_entries;
1448 uint32 enum_context = r->in.start_idx;
1449 uint32 max_size = r->in.buf_size;
1451 union samr_DispInfo *disp_info = r->out.info;
1453 uint32 temp_size=0, total_data_size=0;
1454 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1455 uint32 num_account = 0;
1456 enum remote_arch_types ra_type = get_remote_arch();
1457 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1458 struct samr_displayentry *entries = NULL;
1460 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1462 /* find the policy handle. open a policy on it. */
1463 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1464 return NT_STATUS_INVALID_HANDLE;
1466 if (info->builtin_domain) {
1467 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1468 return NT_STATUS_OK;
1471 status = access_check_samr_function(info->acc_granted,
1472 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1473 "_samr_QueryDisplayInfo");
1474 if (!NT_STATUS_IS_OK(status)) {
1475 return status;
1479 * calculate how many entries we will return.
1480 * based on
1481 * - the number of entries the client asked
1482 * - our limit on that
1483 * - the starting point (enumeration context)
1484 * - the buffer size the client will accept
1488 * We are a lot more like W2K. Instead of reading the SAM
1489 * each time to find the records we need to send back,
1490 * we read it once and link that copy to the sam handle.
1491 * For large user list (over the MAX_SAM_ENTRIES)
1492 * it's a definitive win.
1493 * second point to notice: between enumerations
1494 * our sam is now the same as it's a snapshoot.
1495 * third point: got rid of the static SAM_USER_21 struct
1496 * no more intermediate.
1497 * con: it uses much more memory, as a full copy is stored
1498 * in memory.
1500 * If you want to change it, think twice and think
1501 * of the second point , that's really important.
1503 * JFM, 12/20/2001
1506 if ((r->in.level < 1) || (r->in.level > 5)) {
1507 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1508 (unsigned int)r->in.level ));
1509 return NT_STATUS_INVALID_INFO_CLASS;
1512 /* first limit the number of entries we will return */
1513 if(max_entries > max_sam_entries) {
1514 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1515 "entries, limiting to %d\n", max_entries,
1516 max_sam_entries));
1517 max_entries = max_sam_entries;
1520 /* calculate the size and limit on the number of entries we will
1521 * return */
1523 temp_size=max_entries*struct_size;
1525 if (temp_size>max_size) {
1526 max_entries=MIN((max_size/struct_size),max_entries);;
1527 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1528 "only %d entries\n", max_entries));
1531 become_root();
1533 /* THe following done as ROOT. Don't return without unbecome_root(). */
1535 switch (r->in.level) {
1536 case 0x1:
1537 case 0x4:
1538 if (info->disp_info->users == NULL) {
1539 info->disp_info->users = pdb_search_users(
1540 info->disp_info, ACB_NORMAL);
1541 if (info->disp_info->users == NULL) {
1542 unbecome_root();
1543 return NT_STATUS_ACCESS_DENIED;
1545 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1546 (unsigned int)enum_context ));
1547 } else {
1548 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1549 (unsigned int)enum_context ));
1552 num_account = pdb_search_entries(info->disp_info->users,
1553 enum_context, max_entries,
1554 &entries);
1555 break;
1556 case 0x2:
1557 if (info->disp_info->machines == NULL) {
1558 info->disp_info->machines = pdb_search_users(
1559 info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1560 if (info->disp_info->machines == NULL) {
1561 unbecome_root();
1562 return NT_STATUS_ACCESS_DENIED;
1564 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1565 (unsigned int)enum_context ));
1566 } else {
1567 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1568 (unsigned int)enum_context ));
1571 num_account = pdb_search_entries(info->disp_info->machines,
1572 enum_context, max_entries,
1573 &entries);
1574 break;
1575 case 0x3:
1576 case 0x5:
1577 if (info->disp_info->groups == NULL) {
1578 info->disp_info->groups = pdb_search_groups(
1579 info->disp_info);
1580 if (info->disp_info->groups == NULL) {
1581 unbecome_root();
1582 return NT_STATUS_ACCESS_DENIED;
1584 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1585 (unsigned int)enum_context ));
1586 } else {
1587 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1588 (unsigned int)enum_context ));
1591 num_account = pdb_search_entries(info->disp_info->groups,
1592 enum_context, max_entries,
1593 &entries);
1594 break;
1595 default:
1596 unbecome_root();
1597 smb_panic("info class changed");
1598 break;
1600 unbecome_root();
1603 /* Now create reply structure */
1604 switch (r->in.level) {
1605 case 0x1:
1606 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1607 num_account, enum_context,
1608 entries);
1609 break;
1610 case 0x2:
1611 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1612 num_account, enum_context,
1613 entries);
1614 break;
1615 case 0x3:
1616 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1617 num_account, enum_context,
1618 entries);
1619 break;
1620 case 0x4:
1621 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1622 num_account, enum_context,
1623 entries);
1624 break;
1625 case 0x5:
1626 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1627 num_account, enum_context,
1628 entries);
1629 break;
1630 default:
1631 smb_panic("info class changed");
1632 break;
1635 if (!NT_STATUS_IS_OK(disp_ret))
1636 return disp_ret;
1638 /* calculate the total size */
1639 total_data_size=num_account*struct_size;
1641 if (max_entries <= num_account) {
1642 status = STATUS_MORE_ENTRIES;
1643 } else {
1644 status = NT_STATUS_OK;
1647 /* Ensure we cache this enumeration. */
1648 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1650 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1652 *r->out.total_size = total_data_size;
1653 *r->out.returned_size = temp_size;
1655 return status;
1658 /****************************************************************
1659 _samr_QueryDisplayInfo2
1660 ****************************************************************/
1662 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1663 struct samr_QueryDisplayInfo2 *r)
1665 struct samr_QueryDisplayInfo q;
1667 q.in.domain_handle = r->in.domain_handle;
1668 q.in.level = r->in.level;
1669 q.in.start_idx = r->in.start_idx;
1670 q.in.max_entries = r->in.max_entries;
1671 q.in.buf_size = r->in.buf_size;
1673 q.out.total_size = r->out.total_size;
1674 q.out.returned_size = r->out.returned_size;
1675 q.out.info = r->out.info;
1677 return _samr_QueryDisplayInfo(p, &q);
1680 /****************************************************************
1681 _samr_QueryDisplayInfo3
1682 ****************************************************************/
1684 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1685 struct samr_QueryDisplayInfo3 *r)
1687 struct samr_QueryDisplayInfo q;
1689 q.in.domain_handle = r->in.domain_handle;
1690 q.in.level = r->in.level;
1691 q.in.start_idx = r->in.start_idx;
1692 q.in.max_entries = r->in.max_entries;
1693 q.in.buf_size = r->in.buf_size;
1695 q.out.total_size = r->out.total_size;
1696 q.out.returned_size = r->out.returned_size;
1697 q.out.info = r->out.info;
1699 return _samr_QueryDisplayInfo(p, &q);
1702 /*******************************************************************
1703 _samr_QueryAliasInfo
1704 ********************************************************************/
1706 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1707 struct samr_QueryAliasInfo *r)
1709 DOM_SID sid;
1710 struct acct_info info;
1711 uint32 acc_granted;
1712 NTSTATUS status;
1713 union samr_AliasInfo *alias_info = NULL;
1714 const char *alias_name = NULL;
1715 const char *alias_description = NULL;
1717 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1719 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1720 if (!alias_info) {
1721 return NT_STATUS_NO_MEMORY;
1724 /* find the policy handle. open a policy on it. */
1725 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1726 return NT_STATUS_INVALID_HANDLE;
1728 status = access_check_samr_function(acc_granted,
1729 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1730 "_samr_QueryAliasInfo");
1731 if (!NT_STATUS_IS_OK(status)) {
1732 return status;
1735 become_root();
1736 status = pdb_get_aliasinfo(&sid, &info);
1737 unbecome_root();
1739 if ( !NT_STATUS_IS_OK(status))
1740 return status;
1742 /* FIXME: info contains fstrings */
1743 alias_name = talloc_strdup(r, info.acct_name);
1744 alias_description = talloc_strdup(r, info.acct_desc);
1746 switch (r->in.level) {
1747 case ALIASINFOALL:
1748 alias_info->all.name.string = alias_name;
1749 alias_info->all.num_members = 1; /* ??? */
1750 alias_info->all.description.string = alias_description;
1751 break;
1752 case ALIASINFONAME:
1753 alias_info->name.string = alias_name;
1754 break;
1755 case ALIASINFODESCRIPTION:
1756 alias_info->description.string = alias_description;
1757 break;
1758 default:
1759 return NT_STATUS_INVALID_INFO_CLASS;
1762 *r->out.info = alias_info;
1764 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1766 return NT_STATUS_OK;
1769 /*******************************************************************
1770 _samr_LookupNames
1771 ********************************************************************/
1773 NTSTATUS _samr_LookupNames(pipes_struct *p,
1774 struct samr_LookupNames *r)
1776 NTSTATUS status;
1777 uint32 *rid;
1778 enum lsa_SidType *type;
1779 int i;
1780 int num_rids = r->in.num_names;
1781 DOM_SID pol_sid;
1782 uint32 acc_granted;
1783 struct samr_Ids rids, types;
1784 uint32_t num_mapped = 0;
1786 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1788 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1789 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1792 status = access_check_samr_function(acc_granted,
1793 0, /* Don't know the acc_bits yet */
1794 "_samr_LookupNames");
1795 if (!NT_STATUS_IS_OK(status)) {
1796 return status;
1799 if (num_rids > MAX_SAM_ENTRIES) {
1800 num_rids = MAX_SAM_ENTRIES;
1801 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1804 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1805 NT_STATUS_HAVE_NO_MEMORY(rid);
1807 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1808 NT_STATUS_HAVE_NO_MEMORY(type);
1810 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1811 sid_string_dbg(&pol_sid)));
1813 for (i = 0; i < num_rids; i++) {
1815 status = NT_STATUS_NONE_MAPPED;
1816 type[i] = SID_NAME_UNKNOWN;
1818 rid[i] = 0xffffffff;
1820 if (sid_check_is_builtin(&pol_sid)) {
1821 if (lookup_builtin_name(r->in.names[i].string,
1822 &rid[i]))
1824 type[i] = SID_NAME_ALIAS;
1826 } else {
1827 lookup_global_sam_name(r->in.names[i].string, 0,
1828 &rid[i], &type[i]);
1831 if (type[i] != SID_NAME_UNKNOWN) {
1832 num_mapped++;
1836 if (num_mapped == num_rids) {
1837 status = NT_STATUS_OK;
1838 } else if (num_mapped == 0) {
1839 status = NT_STATUS_NONE_MAPPED;
1840 } else {
1841 status = STATUS_SOME_UNMAPPED;
1844 rids.count = num_rids;
1845 rids.ids = rid;
1847 types.count = num_rids;
1848 types.ids = type;
1850 *r->out.rids = rids;
1851 *r->out.types = types;
1853 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1855 return status;
1858 /****************************************************************
1859 _samr_ChangePasswordUser
1860 ****************************************************************/
1862 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1863 struct samr_ChangePasswordUser *r)
1865 NTSTATUS status;
1866 bool ret = false;
1867 struct samu *pwd;
1868 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1869 struct samr_Password lm_pwd, nt_pwd;
1870 uint32_t acc_granted;
1871 struct dom_sid sid;
1873 DISP_INFO *disp_info = NULL;
1875 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) {
1876 return NT_STATUS_INVALID_HANDLE;
1879 status = access_check_samr_function(acc_granted,
1880 SAMR_USER_ACCESS_SET_PASSWORD,
1881 "_samr_ChangePasswordUser");
1882 if (!NT_STATUS_IS_OK(status)) {
1883 return status;
1886 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1887 sid_string_dbg(&sid)));
1889 if (!(pwd = samu_new(NULL))) {
1890 return NT_STATUS_NO_MEMORY;
1893 become_root();
1894 ret = pdb_getsampwsid(pwd, &sid);
1895 unbecome_root();
1897 if (!ret) {
1898 TALLOC_FREE(pwd);
1899 return NT_STATUS_WRONG_PASSWORD;
1903 const uint8_t *lm_pass, *nt_pass;
1905 lm_pass = pdb_get_lanman_passwd(pwd);
1906 nt_pass = pdb_get_nt_passwd(pwd);
1908 if (!lm_pass || !nt_pass) {
1909 status = NT_STATUS_WRONG_PASSWORD;
1910 goto out;
1913 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1914 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1917 /* basic sanity checking on parameters. Do this before any database ops */
1918 if (!r->in.lm_present || !r->in.nt_present ||
1919 !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1920 !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1921 /* we should really handle a change with lm not
1922 present */
1923 status = NT_STATUS_INVALID_PARAMETER_MIX;
1924 goto out;
1927 /* decrypt and check the new lm hash */
1928 D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1929 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1930 if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1931 status = NT_STATUS_WRONG_PASSWORD;
1932 goto out;
1935 /* decrypt and check the new nt hash */
1936 D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1937 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1938 if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1939 status = NT_STATUS_WRONG_PASSWORD;
1940 goto out;
1943 /* The NT Cross is not required by Win2k3 R2, but if present
1944 check the nt cross hash */
1945 if (r->in.cross1_present && r->in.nt_cross) {
1946 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1947 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1948 status = NT_STATUS_WRONG_PASSWORD;
1949 goto out;
1953 /* The LM Cross is not required by Win2k3 R2, but if present
1954 check the lm cross hash */
1955 if (r->in.cross2_present && r->in.lm_cross) {
1956 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1957 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1958 status = NT_STATUS_WRONG_PASSWORD;
1959 goto out;
1963 if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1964 !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1965 status = NT_STATUS_ACCESS_DENIED;
1966 goto out;
1969 status = pdb_update_sam_account(pwd);
1970 out:
1971 TALLOC_FREE(pwd);
1973 return status;
1976 /*******************************************************************
1977 _samr_ChangePasswordUser2
1978 ********************************************************************/
1980 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1981 struct samr_ChangePasswordUser2 *r)
1983 NTSTATUS status;
1984 fstring user_name;
1985 fstring wks;
1987 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1989 fstrcpy(user_name, r->in.account->string);
1990 fstrcpy(wks, r->in.server->string);
1992 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1995 * Pass the user through the NT -> unix user mapping
1996 * function.
1999 (void)map_username(user_name);
2002 * UNIX username case mangling not required, pass_oem_change
2003 * is case insensitive.
2006 status = pass_oem_change(user_name,
2007 r->in.lm_password->data,
2008 r->in.lm_verifier->hash,
2009 r->in.nt_password->data,
2010 r->in.nt_verifier->hash,
2011 NULL);
2013 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
2015 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2016 return NT_STATUS_WRONG_PASSWORD;
2019 return status;
2022 /****************************************************************
2023 _samr_OemChangePasswordUser2
2024 ****************************************************************/
2026 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
2027 struct samr_OemChangePasswordUser2 *r)
2029 NTSTATUS status;
2030 fstring user_name;
2031 const char *wks = NULL;
2033 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2035 fstrcpy(user_name, r->in.account->string);
2036 if (r->in.server && r->in.server->string) {
2037 wks = r->in.server->string;
2040 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
2043 * Pass the user through the NT -> unix user mapping
2044 * function.
2047 (void)map_username(user_name);
2050 * UNIX username case mangling not required, pass_oem_change
2051 * is case insensitive.
2054 if (!r->in.hash || !r->in.password) {
2055 return NT_STATUS_INVALID_PARAMETER;
2058 status = pass_oem_change(user_name,
2059 r->in.password->data,
2060 r->in.hash->hash,
2063 NULL);
2065 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2066 return NT_STATUS_WRONG_PASSWORD;
2069 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2071 return status;
2074 /*******************************************************************
2075 _samr_ChangePasswordUser3
2076 ********************************************************************/
2078 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
2079 struct samr_ChangePasswordUser3 *r)
2081 NTSTATUS status;
2082 fstring user_name;
2083 const char *wks = NULL;
2084 uint32 reject_reason;
2085 struct samr_DomInfo1 *dominfo = NULL;
2086 struct samr_ChangeReject *reject = NULL;
2087 uint32_t tmp;
2089 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2091 fstrcpy(user_name, r->in.account->string);
2092 if (r->in.server && r->in.server->string) {
2093 wks = r->in.server->string;
2096 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2099 * Pass the user through the NT -> unix user mapping
2100 * function.
2103 (void)map_username(user_name);
2106 * UNIX username case mangling not required, pass_oem_change
2107 * is case insensitive.
2110 status = pass_oem_change(user_name,
2111 r->in.lm_password->data,
2112 r->in.lm_verifier->hash,
2113 r->in.nt_password->data,
2114 r->in.nt_verifier->hash,
2115 &reject_reason);
2116 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2117 return NT_STATUS_WRONG_PASSWORD;
2120 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2121 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2123 time_t u_expire, u_min_age;
2124 uint32 account_policy_temp;
2126 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2127 if (!dominfo) {
2128 return NT_STATUS_NO_MEMORY;
2131 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2132 if (!reject) {
2133 return NT_STATUS_NO_MEMORY;
2136 become_root();
2138 /* AS ROOT !!! */
2140 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
2141 dominfo->min_password_length = tmp;
2143 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
2144 dominfo->password_history_length = tmp;
2146 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2147 &dominfo->password_properties);
2149 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2150 u_expire = account_policy_temp;
2152 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2153 u_min_age = account_policy_temp;
2155 /* !AS ROOT */
2157 unbecome_root();
2159 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2160 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2162 if (lp_check_password_script() && *lp_check_password_script()) {
2163 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2166 reject->reason = reject_reason;
2168 *r->out.dominfo = dominfo;
2169 *r->out.reject = reject;
2172 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2174 return status;
2177 /*******************************************************************
2178 makes a SAMR_R_LOOKUP_RIDS structure.
2179 ********************************************************************/
2181 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2182 const char **names,
2183 struct lsa_String **lsa_name_array_p)
2185 struct lsa_String *lsa_name_array = NULL;
2186 uint32_t i;
2188 *lsa_name_array_p = NULL;
2190 if (num_names != 0) {
2191 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2192 if (!lsa_name_array) {
2193 return false;
2197 for (i = 0; i < num_names; i++) {
2198 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2199 init_lsa_String(&lsa_name_array[i], names[i]);
2202 *lsa_name_array_p = lsa_name_array;
2204 return true;
2207 /*******************************************************************
2208 _samr_LookupRids
2209 ********************************************************************/
2211 NTSTATUS _samr_LookupRids(pipes_struct *p,
2212 struct samr_LookupRids *r)
2214 NTSTATUS status;
2215 const char **names;
2216 enum lsa_SidType *attrs = NULL;
2217 uint32 *wire_attrs = NULL;
2218 DOM_SID pol_sid;
2219 int num_rids = (int)r->in.num_rids;
2220 uint32 acc_granted;
2221 int i;
2222 struct lsa_Strings names_array;
2223 struct samr_Ids types_array;
2224 struct lsa_String *lsa_names = NULL;
2226 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2228 /* find the policy handle. open a policy on it. */
2229 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2230 return NT_STATUS_INVALID_HANDLE;
2232 status = access_check_samr_function(acc_granted,
2233 0, /* Don't know the acc_bits yet */
2234 "_samr_LookupRids");
2235 if (!NT_STATUS_IS_OK(status)) {
2236 return status;
2239 if (num_rids > 1000) {
2240 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2241 "to samba4 idl this is not possible\n", num_rids));
2242 return NT_STATUS_UNSUCCESSFUL;
2245 if (num_rids) {
2246 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2247 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2248 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2250 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2251 return NT_STATUS_NO_MEMORY;
2252 } else {
2253 names = NULL;
2254 attrs = NULL;
2255 wire_attrs = NULL;
2258 become_root(); /* lookup_sid can require root privs */
2259 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2260 names, attrs);
2261 unbecome_root();
2263 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2264 status = NT_STATUS_OK;
2267 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2268 &lsa_names)) {
2269 return NT_STATUS_NO_MEMORY;
2272 /* Convert from enum lsa_SidType to uint32 for wire format. */
2273 for (i = 0; i < num_rids; i++) {
2274 wire_attrs[i] = (uint32)attrs[i];
2277 names_array.count = num_rids;
2278 names_array.names = lsa_names;
2280 types_array.count = num_rids;
2281 types_array.ids = wire_attrs;
2283 *r->out.names = names_array;
2284 *r->out.types = types_array;
2286 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2288 return status;
2291 /*******************************************************************
2292 _samr_OpenUser
2293 ********************************************************************/
2295 NTSTATUS _samr_OpenUser(pipes_struct *p,
2296 struct samr_OpenUser *r)
2298 struct samu *sampass=NULL;
2299 DOM_SID sid;
2300 struct samr_info *info = NULL;
2301 SEC_DESC *psd = NULL;
2302 uint32 acc_granted;
2303 uint32 des_access = r->in.access_mask;
2304 size_t sd_size;
2305 bool ret;
2306 NTSTATUS nt_status;
2307 SE_PRIV se_rights;
2309 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2311 if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
2312 return NT_STATUS_INVALID_HANDLE;
2314 nt_status = access_check_samr_function(acc_granted,
2315 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2316 "_samr_OpenUser" );
2318 if ( !NT_STATUS_IS_OK(nt_status) )
2319 return nt_status;
2321 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2322 return NT_STATUS_NO_MEMORY;
2325 /* append the user's RID to it */
2327 if (!sid_append_rid(&sid, r->in.rid))
2328 return NT_STATUS_NO_SUCH_USER;
2330 /* check if access can be granted as requested by client. */
2332 map_max_allowed_access(p->server_info->ptok, &des_access);
2334 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2335 se_map_generic(&des_access, &usr_generic_mapping);
2337 se_priv_copy( &se_rights, &se_machine_account );
2338 se_priv_add( &se_rights, &se_add_users );
2340 nt_status = access_check_samr_object(psd, p->server_info->ptok,
2341 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2342 &acc_granted, "_samr_OpenUser");
2344 if ( !NT_STATUS_IS_OK(nt_status) )
2345 return nt_status;
2347 become_root();
2348 ret=pdb_getsampwsid(sampass, &sid);
2349 unbecome_root();
2351 /* check that the SID exists in our domain. */
2352 if (ret == False) {
2353 return NT_STATUS_NO_SUCH_USER;
2356 TALLOC_FREE(sampass);
2358 /* associate the user's SID and access bits with the new handle. */
2359 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
2360 return NT_STATUS_NO_MEMORY;
2361 info->acc_granted = acc_granted;
2363 /* get a (unique) handle. open a policy on it. */
2364 if (!create_policy_hnd(p, r->out.user_handle, info))
2365 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2367 return NT_STATUS_OK;
2370 /*************************************************************************
2371 *************************************************************************/
2373 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2374 DATA_BLOB *blob,
2375 struct lsa_BinaryString **_r)
2377 struct lsa_BinaryString *r;
2379 if (!blob || !_r) {
2380 return NT_STATUS_INVALID_PARAMETER;
2383 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2384 if (!r) {
2385 return NT_STATUS_NO_MEMORY;
2388 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2389 if (!r->array) {
2390 return NT_STATUS_NO_MEMORY;
2392 memcpy(r->array, blob->data, blob->length);
2393 r->size = blob->length;
2394 r->length = blob->length;
2396 if (!r->array) {
2397 return NT_STATUS_NO_MEMORY;
2400 *_r = r;
2402 return NT_STATUS_OK;
2405 /*************************************************************************
2406 get_user_info_1.
2407 *************************************************************************/
2409 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2410 struct samr_UserInfo1 *r,
2411 struct samu *pw,
2412 DOM_SID *domain_sid)
2414 const DOM_SID *sid_group;
2415 uint32_t primary_gid;
2417 become_root();
2418 sid_group = pdb_get_group_sid(pw);
2419 unbecome_root();
2421 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2422 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2423 "which conflicts with the domain sid %s. Failing operation.\n",
2424 pdb_get_username(pw), sid_string_dbg(sid_group),
2425 sid_string_dbg(domain_sid)));
2426 return NT_STATUS_UNSUCCESSFUL;
2429 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2430 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2431 r->primary_gid = primary_gid;
2432 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2433 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2435 return NT_STATUS_OK;
2438 /*************************************************************************
2439 get_user_info_2.
2440 *************************************************************************/
2442 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2443 struct samr_UserInfo2 *r,
2444 struct samu *pw)
2446 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2447 r->unknown.string = NULL;
2448 r->country_code = 0;
2449 r->code_page = 0;
2451 return NT_STATUS_OK;
2454 /*************************************************************************
2455 get_user_info_3.
2456 *************************************************************************/
2458 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2459 struct samr_UserInfo3 *r,
2460 struct samu *pw,
2461 DOM_SID *domain_sid)
2463 const DOM_SID *sid_user, *sid_group;
2464 uint32_t rid, primary_gid;
2466 sid_user = pdb_get_user_sid(pw);
2468 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2469 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2470 "the domain sid %s. Failing operation.\n",
2471 pdb_get_username(pw), sid_string_dbg(sid_user),
2472 sid_string_dbg(domain_sid)));
2473 return NT_STATUS_UNSUCCESSFUL;
2476 become_root();
2477 sid_group = pdb_get_group_sid(pw);
2478 unbecome_root();
2480 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2481 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2482 "which conflicts with the domain sid %s. Failing operation.\n",
2483 pdb_get_username(pw), sid_string_dbg(sid_group),
2484 sid_string_dbg(domain_sid)));
2485 return NT_STATUS_UNSUCCESSFUL;
2488 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2489 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2490 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2491 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2492 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2494 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2495 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2496 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2497 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2498 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2499 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2500 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2502 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2503 r->rid = rid;
2504 r->primary_gid = primary_gid;
2505 r->acct_flags = pdb_get_acct_ctrl(pw);
2506 r->bad_password_count = pdb_get_bad_password_count(pw);
2507 r->logon_count = pdb_get_logon_count(pw);
2509 return NT_STATUS_OK;
2512 /*************************************************************************
2513 get_user_info_4.
2514 *************************************************************************/
2516 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2517 struct samr_UserInfo4 *r,
2518 struct samu *pw)
2520 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2522 return NT_STATUS_OK;
2525 /*************************************************************************
2526 get_user_info_5.
2527 *************************************************************************/
2529 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2530 struct samr_UserInfo5 *r,
2531 struct samu *pw,
2532 DOM_SID *domain_sid)
2534 const DOM_SID *sid_user, *sid_group;
2535 uint32_t rid, primary_gid;
2537 sid_user = pdb_get_user_sid(pw);
2539 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2540 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2541 "the domain sid %s. Failing operation.\n",
2542 pdb_get_username(pw), sid_string_dbg(sid_user),
2543 sid_string_dbg(domain_sid)));
2544 return NT_STATUS_UNSUCCESSFUL;
2547 become_root();
2548 sid_group = pdb_get_group_sid(pw);
2549 unbecome_root();
2551 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2552 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2553 "which conflicts with the domain sid %s. Failing operation.\n",
2554 pdb_get_username(pw), sid_string_dbg(sid_group),
2555 sid_string_dbg(domain_sid)));
2556 return NT_STATUS_UNSUCCESSFUL;
2559 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2560 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2561 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2562 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2564 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2565 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2566 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2567 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2568 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2569 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2570 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2571 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2573 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2574 r->rid = rid;
2575 r->primary_gid = primary_gid;
2576 r->acct_flags = pdb_get_acct_ctrl(pw);
2577 r->bad_password_count = pdb_get_bad_password_count(pw);
2578 r->logon_count = pdb_get_logon_count(pw);
2580 return NT_STATUS_OK;
2583 /*************************************************************************
2584 get_user_info_6.
2585 *************************************************************************/
2587 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2588 struct samr_UserInfo6 *r,
2589 struct samu *pw)
2591 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2592 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2594 return NT_STATUS_OK;
2597 /*************************************************************************
2598 get_user_info_7. Safe. Only gives out account_name.
2599 *************************************************************************/
2601 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2602 struct samr_UserInfo7 *r,
2603 struct samu *smbpass)
2605 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2606 if (!r->account_name.string) {
2607 return NT_STATUS_NO_MEMORY;
2610 return NT_STATUS_OK;
2613 /*************************************************************************
2614 get_user_info_8.
2615 *************************************************************************/
2617 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2618 struct samr_UserInfo8 *r,
2619 struct samu *pw)
2621 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2623 return NT_STATUS_OK;
2626 /*************************************************************************
2627 get_user_info_9. Only gives out primary group SID.
2628 *************************************************************************/
2630 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2631 struct samr_UserInfo9 *r,
2632 struct samu *smbpass)
2634 r->primary_gid = pdb_get_group_rid(smbpass);
2636 return NT_STATUS_OK;
2639 /*************************************************************************
2640 get_user_info_10.
2641 *************************************************************************/
2643 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2644 struct samr_UserInfo10 *r,
2645 struct samu *pw)
2647 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2648 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2650 return NT_STATUS_OK;
2653 /*************************************************************************
2654 get_user_info_11.
2655 *************************************************************************/
2657 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2658 struct samr_UserInfo11 *r,
2659 struct samu *pw)
2661 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2663 return NT_STATUS_OK;
2666 /*************************************************************************
2667 get_user_info_12.
2668 *************************************************************************/
2670 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2671 struct samr_UserInfo12 *r,
2672 struct samu *pw)
2674 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2676 return NT_STATUS_OK;
2679 /*************************************************************************
2680 get_user_info_13.
2681 *************************************************************************/
2683 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2684 struct samr_UserInfo13 *r,
2685 struct samu *pw)
2687 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2689 return NT_STATUS_OK;
2692 /*************************************************************************
2693 get_user_info_14.
2694 *************************************************************************/
2696 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2697 struct samr_UserInfo14 *r,
2698 struct samu *pw)
2700 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2702 return NT_STATUS_OK;
2705 /*************************************************************************
2706 get_user_info_16. Safe. Only gives out acb bits.
2707 *************************************************************************/
2709 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2710 struct samr_UserInfo16 *r,
2711 struct samu *smbpass)
2713 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2715 return NT_STATUS_OK;
2718 /*************************************************************************
2719 get_user_info_17.
2720 *************************************************************************/
2722 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2723 struct samr_UserInfo17 *r,
2724 struct samu *pw)
2726 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2728 return NT_STATUS_OK;
2731 /*************************************************************************
2732 get_user_info_18. OK - this is the killer as it gives out password info.
2733 Ensure that this is only allowed on an encrypted connection with a root
2734 user. JRA.
2735 *************************************************************************/
2737 static NTSTATUS get_user_info_18(pipes_struct *p,
2738 TALLOC_CTX *mem_ctx,
2739 struct samr_UserInfo18 *r,
2740 DOM_SID *user_sid)
2742 struct samu *smbpass=NULL;
2743 bool ret;
2745 ZERO_STRUCTP(r);
2747 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2748 return NT_STATUS_ACCESS_DENIED;
2751 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2752 return NT_STATUS_ACCESS_DENIED;
2756 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2759 if ( !(smbpass = samu_new( mem_ctx )) ) {
2760 return NT_STATUS_NO_MEMORY;
2763 ret = pdb_getsampwsid(smbpass, user_sid);
2765 if (ret == False) {
2766 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2767 TALLOC_FREE(smbpass);
2768 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2771 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2773 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2774 TALLOC_FREE(smbpass);
2775 return NT_STATUS_ACCOUNT_DISABLED;
2778 r->lm_pwd_active = true;
2779 r->nt_pwd_active = true;
2780 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2781 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2782 r->password_expired = 0; /* FIXME */
2784 TALLOC_FREE(smbpass);
2786 return NT_STATUS_OK;
2789 /*************************************************************************
2790 get_user_info_20
2791 *************************************************************************/
2793 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2794 struct samr_UserInfo20 *r,
2795 struct samu *sampass)
2797 const char *munged_dial = NULL;
2798 DATA_BLOB blob;
2799 NTSTATUS status;
2800 struct lsa_BinaryString *parameters = NULL;
2802 ZERO_STRUCTP(r);
2804 munged_dial = pdb_get_munged_dial(sampass);
2806 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2807 munged_dial, (int)strlen(munged_dial)));
2809 if (munged_dial) {
2810 blob = base64_decode_data_blob(munged_dial);
2811 } else {
2812 blob = data_blob_string_const_null("");
2815 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2816 data_blob_free(&blob);
2817 if (!NT_STATUS_IS_OK(status)) {
2818 return status;
2821 r->parameters = *parameters;
2823 return NT_STATUS_OK;
2827 /*************************************************************************
2828 get_user_info_21
2829 *************************************************************************/
2831 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2832 struct samr_UserInfo21 *r,
2833 struct samu *pw,
2834 DOM_SID *domain_sid)
2836 NTSTATUS status;
2837 const DOM_SID *sid_user, *sid_group;
2838 uint32_t rid, primary_gid;
2839 NTTIME force_password_change;
2840 time_t must_change_time;
2841 struct lsa_BinaryString *parameters = NULL;
2842 const char *munged_dial = NULL;
2843 DATA_BLOB blob;
2845 ZERO_STRUCTP(r);
2847 sid_user = pdb_get_user_sid(pw);
2849 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2850 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2851 "the domain sid %s. Failing operation.\n",
2852 pdb_get_username(pw), sid_string_dbg(sid_user),
2853 sid_string_dbg(domain_sid)));
2854 return NT_STATUS_UNSUCCESSFUL;
2857 become_root();
2858 sid_group = pdb_get_group_sid(pw);
2859 unbecome_root();
2861 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2862 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2863 "which conflicts with the domain sid %s. Failing operation.\n",
2864 pdb_get_username(pw), sid_string_dbg(sid_group),
2865 sid_string_dbg(domain_sid)));
2866 return NT_STATUS_UNSUCCESSFUL;
2869 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2870 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2871 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2872 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2873 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2875 must_change_time = pdb_get_pass_must_change_time(pw);
2876 if (must_change_time == get_time_t_max()) {
2877 unix_to_nt_time_abs(&force_password_change, must_change_time);
2878 } else {
2879 unix_to_nt_time(&force_password_change, must_change_time);
2882 munged_dial = pdb_get_munged_dial(pw);
2883 if (munged_dial) {
2884 blob = base64_decode_data_blob(munged_dial);
2885 } else {
2886 blob = data_blob_string_const_null("");
2889 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2890 data_blob_free(&blob);
2891 if (!NT_STATUS_IS_OK(status)) {
2892 return status;
2895 r->force_password_change = force_password_change;
2897 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2898 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2899 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2900 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2901 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2902 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2903 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2904 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2905 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2907 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2908 r->parameters = *parameters;
2909 r->rid = rid;
2910 r->primary_gid = primary_gid;
2911 r->acct_flags = pdb_get_acct_ctrl(pw);
2912 r->bad_password_count = pdb_get_bad_password_count(pw);
2913 r->logon_count = pdb_get_logon_count(pw);
2914 r->fields_present = pdb_build_fields_present(pw);
2915 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2916 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2917 r->country_code = 0;
2918 r->code_page = 0;
2919 r->lm_password_set = 0;
2920 r->nt_password_set = 0;
2922 #if 0
2925 Look at a user on a real NT4 PDC with usrmgr, press
2926 'ok'. Then you will see that fields_present is set to
2927 0x08f827fa. Look at the user immediately after that again,
2928 and you will see that 0x00fffff is returned. This solves
2929 the problem that you get access denied after having looked
2930 at the user.
2931 -- Volker
2934 #endif
2937 return NT_STATUS_OK;
2940 /*******************************************************************
2941 _samr_QueryUserInfo
2942 ********************************************************************/
2944 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2945 struct samr_QueryUserInfo *r)
2947 NTSTATUS status;
2948 union samr_UserInfo *user_info = NULL;
2949 struct samr_info *info = NULL;
2950 DOM_SID domain_sid;
2951 uint32 rid;
2952 bool ret = false;
2953 struct samu *pwd = NULL;
2955 /* search for the handle */
2956 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2957 return NT_STATUS_INVALID_HANDLE;
2959 status = access_check_samr_function(info->acc_granted,
2960 SAMR_USER_ACCESS_GET_ATTRIBUTES,
2961 "_samr_QueryUserInfo");
2962 if (!NT_STATUS_IS_OK(status)) {
2963 return status;
2966 domain_sid = info->sid;
2968 sid_split_rid(&domain_sid, &rid);
2970 if (!sid_check_is_in_our_domain(&info->sid))
2971 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2973 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2974 sid_string_dbg(&info->sid)));
2976 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2977 if (!user_info) {
2978 return NT_STATUS_NO_MEMORY;
2981 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2983 if (!(pwd = samu_new(p->mem_ctx))) {
2984 return NT_STATUS_NO_MEMORY;
2987 become_root();
2988 ret = pdb_getsampwsid(pwd, &info->sid);
2989 unbecome_root();
2991 if (ret == false) {
2992 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2993 TALLOC_FREE(pwd);
2994 return NT_STATUS_NO_SUCH_USER;
2997 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2999 samr_clear_sam_passwd(pwd);
3001 switch (r->in.level) {
3002 case 1:
3003 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3004 break;
3005 case 2:
3006 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3007 break;
3008 case 3:
3009 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3010 break;
3011 case 4:
3012 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3013 break;
3014 case 5:
3015 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3016 break;
3017 case 6:
3018 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3019 break;
3020 case 7:
3021 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3022 break;
3023 case 8:
3024 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3025 break;
3026 case 9:
3027 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3028 break;
3029 case 10:
3030 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3031 break;
3032 case 11:
3033 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3034 break;
3035 case 12:
3036 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3037 break;
3038 case 13:
3039 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3040 break;
3041 case 14:
3042 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3043 break;
3044 case 16:
3045 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3046 break;
3047 case 17:
3048 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3049 break;
3050 case 18:
3051 /* level 18 is special */
3052 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
3053 break;
3054 case 20:
3055 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3056 break;
3057 case 21:
3058 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
3059 break;
3060 default:
3061 status = NT_STATUS_INVALID_INFO_CLASS;
3062 break;
3065 TALLOC_FREE(pwd);
3067 *r->out.info = user_info;
3069 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3071 return status;
3074 /****************************************************************
3075 ****************************************************************/
3077 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3078 struct samr_QueryUserInfo2 *r)
3080 struct samr_QueryUserInfo u;
3082 u.in.user_handle = r->in.user_handle;
3083 u.in.level = r->in.level;
3084 u.out.info = r->out.info;
3086 return _samr_QueryUserInfo(p, &u);
3089 /*******************************************************************
3090 _samr_GetGroupsForUser
3091 ********************************************************************/
3093 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3094 struct samr_GetGroupsForUser *r)
3096 struct samu *sam_pass=NULL;
3097 DOM_SID sid;
3098 DOM_SID *sids;
3099 struct samr_RidWithAttribute dom_gid;
3100 struct samr_RidWithAttribute *gids = NULL;
3101 uint32 primary_group_rid;
3102 size_t num_groups = 0;
3103 gid_t *unix_gids;
3104 size_t i, num_gids;
3105 uint32 acc_granted;
3106 bool ret;
3107 NTSTATUS result;
3108 bool success = False;
3110 struct samr_RidWithAttributeArray *rids = NULL;
3113 * from the SID in the request:
3114 * we should send back the list of DOMAIN GROUPS
3115 * the user is a member of
3117 * and only the DOMAIN GROUPS
3118 * no ALIASES !!! neither aliases of the domain
3119 * nor aliases of the builtin SID
3121 * JFM, 12/2/2001
3124 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3126 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3127 if (!rids) {
3128 return NT_STATUS_NO_MEMORY;
3131 /* find the policy handle. open a policy on it. */
3132 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
3133 return NT_STATUS_INVALID_HANDLE;
3135 result = access_check_samr_function(acc_granted,
3136 SAMR_USER_ACCESS_GET_GROUPS,
3137 "_samr_GetGroupsForUser");
3138 if (!NT_STATUS_IS_OK(result)) {
3139 return result;
3142 if (!sid_check_is_in_our_domain(&sid))
3143 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3145 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3146 return NT_STATUS_NO_MEMORY;
3149 become_root();
3150 ret = pdb_getsampwsid(sam_pass, &sid);
3151 unbecome_root();
3153 if (!ret) {
3154 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3155 sid_string_dbg(&sid)));
3156 return NT_STATUS_NO_SUCH_USER;
3159 sids = NULL;
3161 /* make both calls inside the root block */
3162 become_root();
3163 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3164 &sids, &unix_gids, &num_groups);
3165 if ( NT_STATUS_IS_OK(result) ) {
3166 success = sid_peek_check_rid(get_global_sam_sid(),
3167 pdb_get_group_sid(sam_pass),
3168 &primary_group_rid);
3170 unbecome_root();
3172 if (!NT_STATUS_IS_OK(result)) {
3173 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3174 sid_string_dbg(&sid)));
3175 return result;
3178 if ( !success ) {
3179 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3180 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3181 pdb_get_username(sam_pass)));
3182 TALLOC_FREE(sam_pass);
3183 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3186 gids = NULL;
3187 num_gids = 0;
3189 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3190 SE_GROUP_ENABLED);
3191 dom_gid.rid = primary_group_rid;
3192 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3194 for (i=0; i<num_groups; i++) {
3196 if (!sid_peek_check_rid(get_global_sam_sid(),
3197 &(sids[i]), &dom_gid.rid)) {
3198 DEBUG(10, ("Found sid %s not in our domain\n",
3199 sid_string_dbg(&sids[i])));
3200 continue;
3203 if (dom_gid.rid == primary_group_rid) {
3204 /* We added the primary group directly from the
3205 * sam_account. The other SIDs are unique from
3206 * enum_group_memberships */
3207 continue;
3210 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3213 rids->count = num_gids;
3214 rids->rids = gids;
3216 *r->out.rids = rids;
3218 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3220 return result;
3223 /*******************************************************************
3224 _samr_QueryDomainInfo
3225 ********************************************************************/
3227 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3228 struct samr_QueryDomainInfo *r)
3230 NTSTATUS status = NT_STATUS_OK;
3231 struct samr_info *info = NULL;
3232 union samr_DomainInfo *dom_info;
3233 time_t u_expire, u_min_age;
3235 time_t u_lock_duration, u_reset_time;
3236 uint32_t u_logout;
3238 uint32 account_policy_temp;
3240 time_t seq_num;
3241 uint32 server_role;
3243 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3245 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3246 if (!dom_info) {
3247 return NT_STATUS_NO_MEMORY;
3250 /* find the policy handle. open a policy on it. */
3251 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
3252 return NT_STATUS_INVALID_HANDLE;
3255 status = access_check_samr_function(info->acc_granted,
3256 SAMR_ACCESS_LOOKUP_DOMAIN,
3257 "_samr_QueryDomainInfo" );
3259 if ( !NT_STATUS_IS_OK(status) )
3260 return status;
3262 switch (r->in.level) {
3263 case 0x01:
3265 become_root();
3267 /* AS ROOT !!! */
3269 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
3270 &account_policy_temp);
3271 dom_info->info1.min_password_length = account_policy_temp;
3273 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
3274 dom_info->info1.password_history_length = account_policy_temp;
3276 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
3277 &dom_info->info1.password_properties);
3279 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
3280 u_expire = account_policy_temp;
3282 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
3283 u_min_age = account_policy_temp;
3285 /* !AS ROOT */
3287 unbecome_root();
3289 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
3290 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
3292 if (lp_check_password_script() && *lp_check_password_script()) {
3293 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
3296 break;
3297 case 0x02:
3299 become_root();
3301 /* AS ROOT !!! */
3303 dom_info->general.num_users = count_sam_users(info->disp_info, ACB_NORMAL);
3304 dom_info->general.num_groups = count_sam_groups(info->disp_info);
3305 dom_info->general.num_aliases = count_sam_aliases(info->disp_info);
3307 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3309 unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
3311 if (!pdb_get_seq_num(&seq_num))
3312 seq_num = time(NULL);
3314 /* !AS ROOT */
3316 unbecome_root();
3318 server_role = ROLE_DOMAIN_PDC;
3319 if (lp_server_role() == ROLE_DOMAIN_BDC)
3320 server_role = ROLE_DOMAIN_BDC;
3322 dom_info->general.oem_information.string = lp_serverstring();
3323 dom_info->general.domain_name.string = lp_workgroup();
3324 dom_info->general.primary.string = global_myname();
3325 dom_info->general.sequence_num = seq_num;
3326 dom_info->general.domain_server_state = DOMAIN_SERVER_ENABLED;
3327 dom_info->general.role = server_role;
3328 dom_info->general.unknown3 = 1;
3330 break;
3331 case 0x03:
3333 become_root();
3335 /* AS ROOT !!! */
3338 uint32 ul;
3339 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3340 u_logout = (time_t)ul;
3343 /* !AS ROOT */
3345 unbecome_root();
3347 unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
3349 break;
3350 case 0x04:
3351 dom_info->oem.oem_information.string = lp_serverstring();
3352 break;
3353 case 0x05:
3354 dom_info->info5.domain_name.string = get_global_sam_name();
3355 break;
3356 case 0x06:
3357 /* NT returns its own name when a PDC. win2k and later
3358 * only the name of the PDC if itself is a BDC (samba4
3359 * idl) */
3360 dom_info->info6.primary.string = global_myname();
3361 break;
3362 case 0x07:
3363 server_role = ROLE_DOMAIN_PDC;
3364 if (lp_server_role() == ROLE_DOMAIN_BDC)
3365 server_role = ROLE_DOMAIN_BDC;
3367 dom_info->info7.role = server_role;
3368 break;
3369 case 0x08:
3371 become_root();
3373 /* AS ROOT !!! */
3375 if (!pdb_get_seq_num(&seq_num)) {
3376 seq_num = time(NULL);
3379 /* !AS ROOT */
3381 unbecome_root();
3383 dom_info->info8.sequence_num = seq_num;
3384 dom_info->info8.domain_create_time = 0;
3386 break;
3387 case 0x09:
3389 dom_info->info9.domain_server_state = DOMAIN_SERVER_ENABLED;
3391 break;
3392 case 0x0b:
3394 /* AS ROOT !!! */
3396 become_root();
3398 dom_info->general2.general.num_users = count_sam_users(
3399 info->disp_info, ACB_NORMAL);
3400 dom_info->general2.general.num_groups = count_sam_groups(
3401 info->disp_info);
3402 dom_info->general2.general.num_aliases = count_sam_aliases(
3403 info->disp_info);
3405 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3407 unix_to_nt_time_abs(&dom_info->general2.general.force_logoff_time, u_logout);
3409 if (!pdb_get_seq_num(&seq_num))
3410 seq_num = time(NULL);
3412 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3413 u_lock_duration = account_policy_temp;
3414 if (u_lock_duration != -1) {
3415 u_lock_duration *= 60;
3418 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3419 u_reset_time = account_policy_temp * 60;
3421 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3422 &account_policy_temp);
3423 dom_info->general2.lockout_threshold = account_policy_temp;
3425 /* !AS ROOT */
3427 unbecome_root();
3429 server_role = ROLE_DOMAIN_PDC;
3430 if (lp_server_role() == ROLE_DOMAIN_BDC)
3431 server_role = ROLE_DOMAIN_BDC;
3433 dom_info->general2.general.oem_information.string = lp_serverstring();
3434 dom_info->general2.general.domain_name.string = lp_workgroup();
3435 dom_info->general2.general.primary.string = global_myname();
3436 dom_info->general2.general.sequence_num = seq_num;
3437 dom_info->general2.general.domain_server_state = DOMAIN_SERVER_ENABLED;
3438 dom_info->general2.general.role = server_role;
3439 dom_info->general2.general.unknown3 = 1;
3441 unix_to_nt_time_abs(&dom_info->general2.lockout_duration,
3442 u_lock_duration);
3443 unix_to_nt_time_abs(&dom_info->general2.lockout_window,
3444 u_reset_time);
3446 break;
3447 case 0x0c:
3449 become_root();
3451 /* AS ROOT !!! */
3453 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3454 u_lock_duration = account_policy_temp;
3455 if (u_lock_duration != -1) {
3456 u_lock_duration *= 60;
3459 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3460 u_reset_time = account_policy_temp * 60;
3462 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3463 &account_policy_temp);
3464 dom_info->info12.lockout_threshold = account_policy_temp;
3466 /* !AS ROOT */
3468 unbecome_root();
3470 unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
3471 u_lock_duration);
3472 unix_to_nt_time_abs(&dom_info->info12.lockout_window,
3473 u_reset_time);
3475 break;
3476 case 0x0d:
3478 become_root();
3480 /* AS ROOT !!! */
3482 if (!pdb_get_seq_num(&seq_num)) {
3483 seq_num = time(NULL);
3486 /* !AS ROOT */
3488 unbecome_root();
3490 dom_info->info13.sequence_num = seq_num;
3491 dom_info->info13.domain_create_time = 0;
3492 dom_info->info13.modified_count_at_last_promotion = 0;
3494 break;
3495 default:
3496 return NT_STATUS_INVALID_INFO_CLASS;
3499 *r->out.info = dom_info;
3501 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3503 return status;
3506 /* W2k3 seems to use the same check for all 3 objects that can be created via
3507 * SAMR, if you try to create for example "Dialup" as an alias it says
3508 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3509 * database. */
3511 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3513 enum lsa_SidType type;
3514 bool result;
3516 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3518 become_root();
3519 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3520 * whether the name already exists */
3521 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3522 NULL, NULL, NULL, &type);
3523 unbecome_root();
3525 if (!result) {
3526 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3527 return NT_STATUS_OK;
3530 DEBUG(5, ("trying to create %s, exists as %s\n",
3531 new_name, sid_type_lookup(type)));
3533 if (type == SID_NAME_DOM_GRP) {
3534 return NT_STATUS_GROUP_EXISTS;
3536 if (type == SID_NAME_ALIAS) {
3537 return NT_STATUS_ALIAS_EXISTS;
3540 /* Yes, the default is NT_STATUS_USER_EXISTS */
3541 return NT_STATUS_USER_EXISTS;
3544 /*******************************************************************
3545 _samr_CreateUser2
3546 ********************************************************************/
3548 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3549 struct samr_CreateUser2 *r)
3551 const char *account = NULL;
3552 DOM_SID sid;
3553 uint32_t acb_info = r->in.acct_flags;
3554 struct samr_info *info = NULL;
3555 NTSTATUS nt_status;
3556 uint32 acc_granted;
3557 SEC_DESC *psd;
3558 size_t sd_size;
3559 /* check this, when giving away 'add computer to domain' privs */
3560 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3561 bool can_add_account = False;
3562 SE_PRIV se_rights;
3563 DISP_INFO *disp_info = NULL;
3565 /* Get the domain SID stored in the domain policy */
3566 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted,
3567 &disp_info))
3568 return NT_STATUS_INVALID_HANDLE;
3570 if (disp_info->builtin_domain) {
3571 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3572 return NT_STATUS_ACCESS_DENIED;
3575 nt_status = access_check_samr_function(acc_granted,
3576 SAMR_DOMAIN_ACCESS_CREATE_USER,
3577 "_samr_CreateUser2");
3578 if (!NT_STATUS_IS_OK(nt_status)) {
3579 return nt_status;
3582 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3583 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3584 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3585 this parameter is not an account type */
3586 return NT_STATUS_INVALID_PARAMETER;
3589 account = r->in.account_name->string;
3590 if (account == NULL) {
3591 return NT_STATUS_NO_MEMORY;
3594 nt_status = can_create(p->mem_ctx, account);
3595 if (!NT_STATUS_IS_OK(nt_status)) {
3596 return nt_status;
3599 /* determine which user right we need to check based on the acb_info */
3601 if ( acb_info & ACB_WSTRUST )
3603 se_priv_copy( &se_rights, &se_machine_account );
3604 can_add_account = user_has_privileges(
3605 p->server_info->ptok, &se_rights );
3607 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3608 account for domain trusts and changes the ACB flags later */
3609 else if ( acb_info & ACB_NORMAL &&
3610 (account[strlen(account)-1] != '$') )
3612 se_priv_copy( &se_rights, &se_add_users );
3613 can_add_account = user_has_privileges(
3614 p->server_info->ptok, &se_rights );
3616 else /* implicit assumption of a BDC or domain trust account here
3617 * (we already check the flags earlier) */
3619 if ( lp_enable_privileges() ) {
3620 /* only Domain Admins can add a BDC or domain trust */
3621 se_priv_copy( &se_rights, &se_priv_none );
3622 can_add_account = nt_token_check_domain_rid(
3623 p->server_info->ptok,
3624 DOMAIN_GROUP_RID_ADMINS );
3628 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3629 uidtoname(p->server_info->utok.uid),
3630 can_add_account ? "True":"False" ));
3632 /********** BEGIN Admin BLOCK **********/
3634 if ( can_add_account )
3635 become_root();
3637 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3638 r->out.rid);
3640 if ( can_add_account )
3641 unbecome_root();
3643 /********** END Admin BLOCK **********/
3645 /* now check for failure */
3647 if ( !NT_STATUS_IS_OK(nt_status) )
3648 return nt_status;
3650 /* Get the user's SID */
3652 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3654 map_max_allowed_access(p->server_info->ptok, &des_access);
3656 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3657 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3658 se_map_generic(&des_access, &usr_generic_mapping);
3660 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3661 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3662 &acc_granted, "_samr_CreateUser2");
3664 if ( !NT_STATUS_IS_OK(nt_status) ) {
3665 return nt_status;
3668 /* associate the user's SID with the new handle. */
3669 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL) {
3670 return NT_STATUS_NO_MEMORY;
3673 ZERO_STRUCTP(info);
3674 info->sid = sid;
3675 info->acc_granted = acc_granted;
3677 /* get a (unique) handle. open a policy on it. */
3678 if (!create_policy_hnd(p, r->out.user_handle, info)) {
3679 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3682 /* After a "set" ensure we have no cached display info. */
3683 force_flush_samr_cache(info->disp_info);
3685 *r->out.access_granted = acc_granted;
3687 return NT_STATUS_OK;
3690 /****************************************************************
3691 ****************************************************************/
3693 NTSTATUS _samr_CreateUser(pipes_struct *p,
3694 struct samr_CreateUser *r)
3696 struct samr_CreateUser2 c;
3697 uint32_t access_granted;
3699 c.in.domain_handle = r->in.domain_handle;
3700 c.in.account_name = r->in.account_name;
3701 c.in.acct_flags = ACB_NORMAL;
3702 c.in.access_mask = r->in.access_mask;
3703 c.out.user_handle = r->out.user_handle;
3704 c.out.access_granted = &access_granted;
3705 c.out.rid = r->out.rid;
3707 return _samr_CreateUser2(p, &c);
3710 /*******************************************************************
3711 _samr_Connect
3712 ********************************************************************/
3714 NTSTATUS _samr_Connect(pipes_struct *p,
3715 struct samr_Connect *r)
3717 struct samr_info *info = NULL;
3718 uint32 des_access = r->in.access_mask;
3720 /* Access check */
3722 if (!pipe_access_check(p)) {
3723 DEBUG(3, ("access denied to _samr_Connect\n"));
3724 return NT_STATUS_ACCESS_DENIED;
3727 /* set up the SAMR connect_anon response */
3729 /* associate the user's SID with the new handle. */
3730 if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
3731 return NT_STATUS_NO_MEMORY;
3733 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3734 was observed from a win98 client trying to enumerate users (when configured
3735 user level access control on shares) --jerry */
3737 map_max_allowed_access(p->server_info->ptok, &des_access);
3739 se_map_generic( &des_access, &sam_generic_mapping );
3740 info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_LOOKUP_DOMAIN);
3742 /* get a (unique) handle. open a policy on it. */
3743 if (!create_policy_hnd(p, r->out.connect_handle, info))
3744 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3746 return NT_STATUS_OK;
3749 /*******************************************************************
3750 _samr_Connect2
3751 ********************************************************************/
3753 NTSTATUS _samr_Connect2(pipes_struct *p,
3754 struct samr_Connect2 *r)
3756 struct samr_info *info = NULL;
3757 SEC_DESC *psd = NULL;
3758 uint32 acc_granted;
3759 uint32 des_access = r->in.access_mask;
3760 NTSTATUS nt_status;
3761 size_t sd_size;
3762 const char *fn = "_samr_Connect2";
3764 switch (p->hdr_req.opnum) {
3765 case NDR_SAMR_CONNECT2:
3766 fn = "_samr_Connect2";
3767 break;
3768 case NDR_SAMR_CONNECT3:
3769 fn = "_samr_Connect3";
3770 break;
3771 case NDR_SAMR_CONNECT4:
3772 fn = "_samr_Connect4";
3773 break;
3774 case NDR_SAMR_CONNECT5:
3775 fn = "_samr_Connect5";
3776 break;
3779 DEBUG(5,("%s: %d\n", fn, __LINE__));
3781 /* Access check */
3783 if (!pipe_access_check(p)) {
3784 DEBUG(3, ("access denied to %s\n", fn));
3785 return NT_STATUS_ACCESS_DENIED;
3788 map_max_allowed_access(p->server_info->ptok, &des_access);
3790 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3791 se_map_generic(&des_access, &sam_generic_mapping);
3793 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3794 NULL, 0, des_access, &acc_granted, fn);
3796 if ( !NT_STATUS_IS_OK(nt_status) )
3797 return nt_status;
3799 /* associate the user's SID and access granted with the new handle. */
3800 if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
3801 return NT_STATUS_NO_MEMORY;
3803 info->acc_granted = acc_granted;
3804 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3806 /* get a (unique) handle. open a policy on it. */
3807 if (!create_policy_hnd(p, r->out.connect_handle, info))
3808 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3810 DEBUG(5,("%s: %d\n", fn, __LINE__));
3812 return nt_status;
3815 /****************************************************************
3816 _samr_Connect3
3817 ****************************************************************/
3819 NTSTATUS _samr_Connect3(pipes_struct *p,
3820 struct samr_Connect3 *r)
3822 struct samr_Connect2 c;
3824 c.in.system_name = r->in.system_name;
3825 c.in.access_mask = r->in.access_mask;
3826 c.out.connect_handle = r->out.connect_handle;
3828 return _samr_Connect2(p, &c);
3831 /*******************************************************************
3832 _samr_Connect4
3833 ********************************************************************/
3835 NTSTATUS _samr_Connect4(pipes_struct *p,
3836 struct samr_Connect4 *r)
3838 struct samr_Connect2 c;
3840 c.in.system_name = r->in.system_name;
3841 c.in.access_mask = r->in.access_mask;
3842 c.out.connect_handle = r->out.connect_handle;
3844 return _samr_Connect2(p, &c);
3847 /*******************************************************************
3848 _samr_Connect5
3849 ********************************************************************/
3851 NTSTATUS _samr_Connect5(pipes_struct *p,
3852 struct samr_Connect5 *r)
3854 NTSTATUS status;
3855 struct samr_Connect2 c;
3856 struct samr_ConnectInfo1 info1;
3858 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3859 info1.unknown2 = 0;
3861 c.in.system_name = r->in.system_name;
3862 c.in.access_mask = r->in.access_mask;
3863 c.out.connect_handle = r->out.connect_handle;
3865 *r->out.level_out = 1;
3867 status = _samr_Connect2(p, &c);
3868 if (!NT_STATUS_IS_OK(status)) {
3869 return status;
3872 r->out.info_out->info1 = info1;
3874 return NT_STATUS_OK;
3877 /**********************************************************************
3878 _samr_LookupDomain
3879 **********************************************************************/
3881 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3882 struct samr_LookupDomain *r)
3884 NTSTATUS status = NT_STATUS_OK;
3885 struct samr_info *info;
3886 const char *domain_name;
3887 DOM_SID *sid = NULL;
3889 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3890 return NT_STATUS_INVALID_HANDLE;
3892 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3893 Reverted that change so we will work with RAS servers again */
3895 status = access_check_samr_function(info->acc_granted,
3896 SAMR_ACCESS_LOOKUP_DOMAIN,
3897 "_samr_LookupDomain");
3898 if (!NT_STATUS_IS_OK(status)) {
3899 return status;
3902 domain_name = r->in.domain_name->string;
3903 if (!domain_name) {
3904 return NT_STATUS_INVALID_PARAMETER;
3907 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3908 if (!sid) {
3909 return NT_STATUS_NO_MEMORY;
3912 if (strequal(domain_name, builtin_domain_name())) {
3913 sid_copy(sid, &global_sid_Builtin);
3914 } else {
3915 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3916 status = NT_STATUS_NO_SUCH_DOMAIN;
3920 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3921 sid_string_dbg(sid)));
3923 *r->out.sid = sid;
3925 return status;
3928 /**********************************************************************
3929 _samr_EnumDomains
3930 **********************************************************************/
3932 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3933 struct samr_EnumDomains *r)
3935 NTSTATUS status;
3936 struct samr_info *info;
3937 uint32_t num_entries = 2;
3938 struct samr_SamEntry *entry_array = NULL;
3939 struct samr_SamArray *sam;
3941 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3942 return NT_STATUS_INVALID_HANDLE;
3944 status = access_check_samr_function(info->acc_granted,
3945 SAMR_ACCESS_ENUM_DOMAINS,
3946 "_samr_EnumDomains");
3947 if (!NT_STATUS_IS_OK(status)) {
3948 return status;
3951 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3952 if (!sam) {
3953 return NT_STATUS_NO_MEMORY;
3956 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3957 struct samr_SamEntry,
3958 num_entries);
3959 if (!entry_array) {
3960 return NT_STATUS_NO_MEMORY;
3963 entry_array[0].idx = 0;
3964 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3966 entry_array[1].idx = 1;
3967 init_lsa_String(&entry_array[1].name, "Builtin");
3969 sam->count = num_entries;
3970 sam->entries = entry_array;
3972 *r->out.sam = sam;
3973 *r->out.num_entries = num_entries;
3975 return status;
3978 /*******************************************************************
3979 _samr_OpenAlias
3980 ********************************************************************/
3982 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3983 struct samr_OpenAlias *r)
3985 DOM_SID sid;
3986 uint32 alias_rid = r->in.rid;
3987 struct samr_info *info = NULL;
3988 SEC_DESC *psd = NULL;
3989 uint32 acc_granted;
3990 uint32 des_access = r->in.access_mask;
3991 size_t sd_size;
3992 NTSTATUS status;
3993 SE_PRIV se_rights;
3995 /* find the domain policy and get the SID / access bits stored in the domain policy */
3997 if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
3998 return NT_STATUS_INVALID_HANDLE;
4000 status = access_check_samr_function(acc_granted,
4001 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4002 "_samr_OpenAlias");
4004 if ( !NT_STATUS_IS_OK(status) )
4005 return status;
4007 /* append the alias' RID to it */
4009 if (!sid_append_rid(&sid, alias_rid))
4010 return NT_STATUS_NO_SUCH_ALIAS;
4012 /*check if access can be granted as requested by client. */
4014 map_max_allowed_access(p->server_info->ptok, &des_access);
4016 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4017 se_map_generic(&des_access,&ali_generic_mapping);
4019 se_priv_copy( &se_rights, &se_add_users );
4022 status = access_check_samr_object(psd, p->server_info->ptok,
4023 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
4024 &acc_granted, "_samr_OpenAlias");
4026 if ( !NT_STATUS_IS_OK(status) )
4027 return status;
4030 /* Check we actually have the requested alias */
4031 enum lsa_SidType type;
4032 bool result;
4033 gid_t gid;
4035 become_root();
4036 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4037 unbecome_root();
4039 if (!result || (type != SID_NAME_ALIAS)) {
4040 return NT_STATUS_NO_SUCH_ALIAS;
4043 /* make sure there is a mapping */
4045 if ( !sid_to_gid( &sid, &gid ) ) {
4046 return NT_STATUS_NO_SUCH_ALIAS;
4051 /* associate the alias SID with the new handle. */
4052 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
4053 return NT_STATUS_NO_MEMORY;
4055 info->acc_granted = acc_granted;
4057 /* get a (unique) handle. open a policy on it. */
4058 if (!create_policy_hnd(p, r->out.alias_handle, info))
4059 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4061 return NT_STATUS_OK;
4064 /*******************************************************************
4065 set_user_info_2
4066 ********************************************************************/
4068 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4069 struct samr_UserInfo2 *id2,
4070 struct samu *pwd)
4072 if (id2 == NULL) {
4073 DEBUG(5,("set_user_info_2: NULL id2\n"));
4074 return NT_STATUS_ACCESS_DENIED;
4077 copy_id2_to_sam_passwd(pwd, id2);
4079 return pdb_update_sam_account(pwd);
4082 /*******************************************************************
4083 set_user_info_4
4084 ********************************************************************/
4086 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4087 struct samr_UserInfo4 *id4,
4088 struct samu *pwd)
4090 if (id4 == NULL) {
4091 DEBUG(5,("set_user_info_2: NULL id4\n"));
4092 return NT_STATUS_ACCESS_DENIED;
4095 copy_id4_to_sam_passwd(pwd, id4);
4097 return pdb_update_sam_account(pwd);
4100 /*******************************************************************
4101 set_user_info_6
4102 ********************************************************************/
4104 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4105 struct samr_UserInfo6 *id6,
4106 struct samu *pwd)
4108 if (id6 == NULL) {
4109 DEBUG(5,("set_user_info_6: NULL id6\n"));
4110 return NT_STATUS_ACCESS_DENIED;
4113 copy_id6_to_sam_passwd(pwd, id6);
4115 return pdb_update_sam_account(pwd);
4118 /*******************************************************************
4119 set_user_info_7
4120 ********************************************************************/
4122 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4123 struct samr_UserInfo7 *id7,
4124 struct samu *pwd)
4126 NTSTATUS rc;
4128 if (id7 == NULL) {
4129 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4130 return NT_STATUS_ACCESS_DENIED;
4133 if (!id7->account_name.string) {
4134 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4135 return NT_STATUS_ACCESS_DENIED;
4138 /* check to see if the new username already exists. Note: we can't
4139 reliably lock all backends, so there is potentially the
4140 possibility that a user can be created in between this check and
4141 the rename. The rename should fail, but may not get the
4142 exact same failure status code. I think this is small enough
4143 of a window for this type of operation and the results are
4144 simply that the rename fails with a slightly different status
4145 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4147 rc = can_create(mem_ctx, id7->account_name.string);
4149 /* when there is nothing to change, we're done here */
4150 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4151 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4152 return NT_STATUS_OK;
4154 if (!NT_STATUS_IS_OK(rc)) {
4155 return rc;
4158 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4160 return rc;
4163 /*******************************************************************
4164 set_user_info_8
4165 ********************************************************************/
4167 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4168 struct samr_UserInfo8 *id8,
4169 struct samu *pwd)
4171 if (id8 == NULL) {
4172 DEBUG(5,("set_user_info_8: NULL id8\n"));
4173 return NT_STATUS_ACCESS_DENIED;
4176 copy_id8_to_sam_passwd(pwd, id8);
4178 return pdb_update_sam_account(pwd);
4181 /*******************************************************************
4182 set_user_info_10
4183 ********************************************************************/
4185 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4186 struct samr_UserInfo10 *id10,
4187 struct samu *pwd)
4189 if (id10 == NULL) {
4190 DEBUG(5,("set_user_info_8: NULL id10\n"));
4191 return NT_STATUS_ACCESS_DENIED;
4194 copy_id10_to_sam_passwd(pwd, id10);
4196 return pdb_update_sam_account(pwd);
4199 /*******************************************************************
4200 set_user_info_11
4201 ********************************************************************/
4203 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4204 struct samr_UserInfo11 *id11,
4205 struct samu *pwd)
4207 if (id11 == NULL) {
4208 DEBUG(5,("set_user_info_11: NULL id11\n"));
4209 return NT_STATUS_ACCESS_DENIED;
4212 copy_id11_to_sam_passwd(pwd, id11);
4214 return pdb_update_sam_account(pwd);
4217 /*******************************************************************
4218 set_user_info_12
4219 ********************************************************************/
4221 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4222 struct samr_UserInfo12 *id12,
4223 struct samu *pwd)
4225 if (id12 == NULL) {
4226 DEBUG(5,("set_user_info_12: NULL id12\n"));
4227 return NT_STATUS_ACCESS_DENIED;
4230 copy_id12_to_sam_passwd(pwd, id12);
4232 return pdb_update_sam_account(pwd);
4235 /*******************************************************************
4236 set_user_info_13
4237 ********************************************************************/
4239 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4240 struct samr_UserInfo13 *id13,
4241 struct samu *pwd)
4243 if (id13 == NULL) {
4244 DEBUG(5,("set_user_info_13: NULL id13\n"));
4245 return NT_STATUS_ACCESS_DENIED;
4248 copy_id13_to_sam_passwd(pwd, id13);
4250 return pdb_update_sam_account(pwd);
4253 /*******************************************************************
4254 set_user_info_14
4255 ********************************************************************/
4257 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4258 struct samr_UserInfo14 *id14,
4259 struct samu *pwd)
4261 if (id14 == NULL) {
4262 DEBUG(5,("set_user_info_14: NULL id14\n"));
4263 return NT_STATUS_ACCESS_DENIED;
4266 copy_id14_to_sam_passwd(pwd, id14);
4268 return pdb_update_sam_account(pwd);
4271 /*******************************************************************
4272 set_user_info_16
4273 ********************************************************************/
4275 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4276 struct samr_UserInfo16 *id16,
4277 struct samu *pwd)
4279 if (id16 == NULL) {
4280 DEBUG(5,("set_user_info_16: NULL id16\n"));
4281 return NT_STATUS_ACCESS_DENIED;
4284 copy_id16_to_sam_passwd(pwd, id16);
4286 return pdb_update_sam_account(pwd);
4289 /*******************************************************************
4290 set_user_info_17
4291 ********************************************************************/
4293 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4294 struct samr_UserInfo17 *id17,
4295 struct samu *pwd)
4297 if (id17 == NULL) {
4298 DEBUG(5,("set_user_info_17: NULL id17\n"));
4299 return NT_STATUS_ACCESS_DENIED;
4302 copy_id17_to_sam_passwd(pwd, id17);
4304 return pdb_update_sam_account(pwd);
4307 /*******************************************************************
4308 set_user_info_18
4309 ********************************************************************/
4311 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4312 TALLOC_CTX *mem_ctx,
4313 DATA_BLOB *session_key,
4314 struct samu *pwd)
4316 if (id18 == NULL) {
4317 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4318 return NT_STATUS_INVALID_PARAMETER;
4321 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4322 if (!session_key->length) {
4323 return NT_STATUS_NO_USER_SESSION_KEY;
4327 if (id18->nt_pwd_active) {
4329 DATA_BLOB in, out;
4331 in = data_blob_const(id18->nt_pwd.hash, 16);
4332 out = data_blob_talloc_zero(mem_ctx, 16);
4334 sess_crypt_blob(&out, &in, session_key, false);
4336 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4337 return NT_STATUS_ACCESS_DENIED;
4340 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4343 if (id18->lm_pwd_active) {
4345 DATA_BLOB in, out;
4347 in = data_blob_const(id18->lm_pwd.hash, 16);
4348 out = data_blob_talloc_zero(mem_ctx, 16);
4350 sess_crypt_blob(&out, &in, session_key, false);
4352 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4353 return NT_STATUS_ACCESS_DENIED;
4356 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4359 copy_id18_to_sam_passwd(pwd, id18);
4361 return pdb_update_sam_account(pwd);
4364 /*******************************************************************
4365 set_user_info_20
4366 ********************************************************************/
4368 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4369 struct samr_UserInfo20 *id20,
4370 struct samu *pwd)
4372 if (id20 == NULL) {
4373 DEBUG(5,("set_user_info_20: NULL id20\n"));
4374 return NT_STATUS_ACCESS_DENIED;
4377 copy_id20_to_sam_passwd(pwd, id20);
4379 return pdb_update_sam_account(pwd);
4382 /*******************************************************************
4383 set_user_info_21
4384 ********************************************************************/
4386 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4387 TALLOC_CTX *mem_ctx,
4388 DATA_BLOB *session_key,
4389 struct samu *pwd)
4391 NTSTATUS status;
4393 if (id21 == NULL) {
4394 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4395 return NT_STATUS_INVALID_PARAMETER;
4398 if (id21->fields_present == 0) {
4399 return NT_STATUS_INVALID_PARAMETER;
4402 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4403 return NT_STATUS_ACCESS_DENIED;
4406 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4407 if (id21->nt_password_set) {
4408 DATA_BLOB in, out;
4410 if ((id21->nt_owf_password.length != 16) ||
4411 (id21->nt_owf_password.size != 16)) {
4412 return NT_STATUS_INVALID_PARAMETER;
4415 if (!session_key->length) {
4416 return NT_STATUS_NO_USER_SESSION_KEY;
4419 in = data_blob_const(id21->nt_owf_password.array, 16);
4420 out = data_blob_talloc_zero(mem_ctx, 16);
4422 sess_crypt_blob(&out, &in, session_key, false);
4424 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4425 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4429 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4430 if (id21->lm_password_set) {
4431 DATA_BLOB in, out;
4433 if ((id21->lm_owf_password.length != 16) ||
4434 (id21->lm_owf_password.size != 16)) {
4435 return NT_STATUS_INVALID_PARAMETER;
4438 if (!session_key->length) {
4439 return NT_STATUS_NO_USER_SESSION_KEY;
4442 in = data_blob_const(id21->lm_owf_password.array, 16);
4443 out = data_blob_talloc_zero(mem_ctx, 16);
4445 sess_crypt_blob(&out, &in, session_key, false);
4447 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4448 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4452 /* we need to separately check for an account rename first */
4454 if (id21->account_name.string &&
4455 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4458 /* check to see if the new username already exists. Note: we can't
4459 reliably lock all backends, so there is potentially the
4460 possibility that a user can be created in between this check and
4461 the rename. The rename should fail, but may not get the
4462 exact same failure status code. I think this is small enough
4463 of a window for this type of operation and the results are
4464 simply that the rename fails with a slightly different status
4465 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4467 status = can_create(mem_ctx, id21->account_name.string);
4468 if (!NT_STATUS_IS_OK(status)) {
4469 return status;
4472 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4474 if (!NT_STATUS_IS_OK(status)) {
4475 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4476 nt_errstr(status)));
4477 return status;
4480 /* set the new username so that later
4481 functions can work on the new account */
4482 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4485 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4488 * The funny part about the previous two calls is
4489 * that pwd still has the password hashes from the
4490 * passdb entry. These have not been updated from
4491 * id21. I don't know if they need to be set. --jerry
4494 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4495 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4496 if ( !NT_STATUS_IS_OK(status) ) {
4497 return status;
4501 /* Don't worry about writing out the user account since the
4502 primary group SID is generated solely from the user's Unix
4503 primary group. */
4505 /* write the change out */
4506 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4507 return status;
4510 return NT_STATUS_OK;
4513 /*******************************************************************
4514 set_user_info_23
4515 ********************************************************************/
4517 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4518 struct samr_UserInfo23 *id23,
4519 struct samu *pwd)
4521 char *plaintext_buf = NULL;
4522 uint32 len = 0;
4523 uint32_t acct_ctrl;
4524 NTSTATUS status;
4526 if (id23 == NULL) {
4527 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4528 return NT_STATUS_INVALID_PARAMETER;
4531 if (id23->info.fields_present == 0) {
4532 return NT_STATUS_INVALID_PARAMETER;
4535 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4536 return NT_STATUS_ACCESS_DENIED;
4539 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4540 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4542 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4543 pdb_get_username(pwd)));
4545 if (!decode_pw_buffer(mem_ctx,
4546 id23->password.data,
4547 &plaintext_buf,
4548 &len,
4549 STR_UNICODE)) {
4550 return NT_STATUS_WRONG_PASSWORD;
4553 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4554 return NT_STATUS_ACCESS_DENIED;
4558 copy_id23_to_sam_passwd(pwd, id23);
4560 acct_ctrl = pdb_get_acct_ctrl(pwd);
4562 /* if it's a trust account, don't update /etc/passwd */
4563 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4564 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4565 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4566 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4567 } else if (plaintext_buf) {
4568 /* update the UNIX password */
4569 if (lp_unix_password_sync() ) {
4570 struct passwd *passwd;
4571 if (pdb_get_username(pwd) == NULL) {
4572 DEBUG(1, ("chgpasswd: User without name???\n"));
4573 return NT_STATUS_ACCESS_DENIED;
4576 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4577 if (passwd == NULL) {
4578 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4581 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4582 return NT_STATUS_ACCESS_DENIED;
4584 TALLOC_FREE(passwd);
4588 if (plaintext_buf) {
4589 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4592 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4593 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4594 pwd)))) {
4595 return status;
4598 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4599 return status;
4602 return NT_STATUS_OK;
4605 /*******************************************************************
4606 set_user_info_pw
4607 ********************************************************************/
4609 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4611 uint32 len = 0;
4612 char *plaintext_buf = NULL;
4613 uint32 acct_ctrl;
4615 DEBUG(5, ("Attempting administrator password change for user %s\n",
4616 pdb_get_username(pwd)));
4618 acct_ctrl = pdb_get_acct_ctrl(pwd);
4620 if (!decode_pw_buffer(talloc_tos(),
4621 pass,
4622 &plaintext_buf,
4623 &len,
4624 STR_UNICODE)) {
4625 return False;
4628 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4629 return False;
4632 /* if it's a trust account, don't update /etc/passwd */
4633 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4634 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4635 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4636 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4637 } else {
4638 /* update the UNIX password */
4639 if (lp_unix_password_sync()) {
4640 struct passwd *passwd;
4642 if (pdb_get_username(pwd) == NULL) {
4643 DEBUG(1, ("chgpasswd: User without name???\n"));
4644 return False;
4647 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4648 if (passwd == NULL) {
4649 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4652 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4653 return False;
4655 TALLOC_FREE(passwd);
4659 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4661 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4663 return True;
4666 /*******************************************************************
4667 set_user_info_24
4668 ********************************************************************/
4670 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4671 struct samr_UserInfo24 *id24,
4672 struct samu *pwd)
4674 NTSTATUS status;
4676 if (id24 == NULL) {
4677 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4678 return NT_STATUS_INVALID_PARAMETER;
4681 if (!set_user_info_pw(id24->password.data, pwd)) {
4682 return NT_STATUS_WRONG_PASSWORD;
4685 copy_id24_to_sam_passwd(pwd, id24);
4687 status = pdb_update_sam_account(pwd);
4688 if (!NT_STATUS_IS_OK(status)) {
4689 return status;
4692 return NT_STATUS_OK;
4695 /*******************************************************************
4696 set_user_info_25
4697 ********************************************************************/
4699 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4700 struct samr_UserInfo25 *id25,
4701 struct samu *pwd)
4703 NTSTATUS status;
4705 if (id25 == NULL) {
4706 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4707 return NT_STATUS_INVALID_PARAMETER;
4710 if (id25->info.fields_present == 0) {
4711 return NT_STATUS_INVALID_PARAMETER;
4714 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4715 return NT_STATUS_ACCESS_DENIED;
4718 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4719 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4721 if (!set_user_info_pw(id25->password.data, pwd)) {
4722 return NT_STATUS_WRONG_PASSWORD;
4726 copy_id25_to_sam_passwd(pwd, id25);
4728 /* write the change out */
4729 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4730 return status;
4734 * We need to "pdb_update_sam_account" before the unix primary group
4735 * is set, because the idealx scripts would also change the
4736 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4737 * the delete explicit / add explicit, which would then fail to find
4738 * the previous primaryGroupSid value.
4741 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4742 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4743 if ( !NT_STATUS_IS_OK(status) ) {
4744 return status;
4748 return NT_STATUS_OK;
4751 /*******************************************************************
4752 set_user_info_26
4753 ********************************************************************/
4755 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4756 struct samr_UserInfo26 *id26,
4757 struct samu *pwd)
4759 NTSTATUS status;
4761 if (id26 == NULL) {
4762 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4763 return NT_STATUS_INVALID_PARAMETER;
4766 if (!set_user_info_pw(id26->password.data, pwd)) {
4767 return NT_STATUS_WRONG_PASSWORD;
4770 copy_id26_to_sam_passwd(pwd, id26);
4772 status = pdb_update_sam_account(pwd);
4773 if (!NT_STATUS_IS_OK(status)) {
4774 return status;
4777 return NT_STATUS_OK;
4781 /*******************************************************************
4782 samr_SetUserInfo
4783 ********************************************************************/
4785 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4786 struct samr_SetUserInfo *r)
4788 NTSTATUS status;
4789 struct samu *pwd = NULL;
4790 DOM_SID sid;
4791 union samr_UserInfo *info = r->in.info;
4792 uint16_t switch_value = r->in.level;
4793 uint32_t acc_granted;
4794 uint32_t acc_required;
4795 bool ret;
4796 bool has_enough_rights = False;
4797 uint32_t acb_info;
4798 DISP_INFO *disp_info = NULL;
4800 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4802 /* find the policy handle. open a policy on it. */
4803 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) {
4804 return NT_STATUS_INVALID_HANDLE;
4807 /* This is tricky. A WinXP domain join sets
4808 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4809 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4810 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4811 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4812 we'll use the set from the WinXP join as the basis. */
4814 switch (switch_value) {
4815 case 18:
4816 case 24:
4817 case 25:
4818 case 26:
4819 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4820 break;
4821 default:
4822 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4823 SAMR_USER_ACCESS_SET_ATTRIBUTES |
4824 SAMR_USER_ACCESS_GET_ATTRIBUTES;
4825 break;
4828 status = access_check_samr_function(acc_granted,
4829 acc_required,
4830 "_samr_SetUserInfo");
4831 if (!NT_STATUS_IS_OK(status)) {
4832 return status;
4835 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4836 sid_string_dbg(&sid), switch_value));
4838 if (info == NULL) {
4839 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4840 return NT_STATUS_INVALID_INFO_CLASS;
4843 if (!(pwd = samu_new(NULL))) {
4844 return NT_STATUS_NO_MEMORY;
4847 become_root();
4848 ret = pdb_getsampwsid(pwd, &sid);
4849 unbecome_root();
4851 if (!ret) {
4852 TALLOC_FREE(pwd);
4853 return NT_STATUS_NO_SUCH_USER;
4856 /* deal with machine password changes differently from userinfo changes */
4857 /* check to see if we have the sufficient rights */
4859 acb_info = pdb_get_acct_ctrl(pwd);
4860 if (acb_info & ACB_WSTRUST)
4861 has_enough_rights = user_has_privileges(p->server_info->ptok,
4862 &se_machine_account);
4863 else if (acb_info & ACB_NORMAL)
4864 has_enough_rights = user_has_privileges(p->server_info->ptok,
4865 &se_add_users);
4866 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4867 if (lp_enable_privileges()) {
4868 has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
4869 DOMAIN_GROUP_RID_ADMINS);
4873 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4874 uidtoname(p->server_info->utok.uid),
4875 has_enough_rights ? "" : " not"));
4877 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4879 if (has_enough_rights) {
4880 become_root();
4883 /* ok! user info levels (lots: see MSDEV help), off we go... */
4885 switch (switch_value) {
4887 case 2:
4888 status = set_user_info_2(p->mem_ctx,
4889 &info->info2, pwd);
4890 break;
4892 case 4:
4893 status = set_user_info_4(p->mem_ctx,
4894 &info->info4, pwd);
4895 break;
4897 case 6:
4898 status = set_user_info_6(p->mem_ctx,
4899 &info->info6, pwd);
4900 break;
4902 case 7:
4903 status = set_user_info_7(p->mem_ctx,
4904 &info->info7, pwd);
4905 break;
4907 case 8:
4908 status = set_user_info_8(p->mem_ctx,
4909 &info->info8, pwd);
4910 break;
4912 case 10:
4913 status = set_user_info_10(p->mem_ctx,
4914 &info->info10, pwd);
4915 break;
4917 case 11:
4918 status = set_user_info_11(p->mem_ctx,
4919 &info->info11, pwd);
4920 break;
4922 case 12:
4923 status = set_user_info_12(p->mem_ctx,
4924 &info->info12, pwd);
4925 break;
4927 case 13:
4928 status = set_user_info_13(p->mem_ctx,
4929 &info->info13, pwd);
4930 break;
4932 case 14:
4933 status = set_user_info_14(p->mem_ctx,
4934 &info->info14, pwd);
4935 break;
4937 case 16:
4938 status = set_user_info_16(p->mem_ctx,
4939 &info->info16, pwd);
4940 break;
4942 case 17:
4943 status = set_user_info_17(p->mem_ctx,
4944 &info->info17, pwd);
4945 break;
4947 case 18:
4948 /* Used by AS/U JRA. */
4949 status = set_user_info_18(&info->info18,
4950 p->mem_ctx,
4951 &p->server_info->user_session_key,
4952 pwd);
4953 break;
4955 case 20:
4956 status = set_user_info_20(p->mem_ctx,
4957 &info->info20, pwd);
4958 break;
4960 case 21:
4961 status = set_user_info_21(&info->info21,
4962 p->mem_ctx,
4963 &p->server_info->user_session_key,
4964 pwd);
4965 break;
4967 case 23:
4968 if (!p->server_info->user_session_key.length) {
4969 status = NT_STATUS_NO_USER_SESSION_KEY;
4971 SamOEMhashBlob(info->info23.password.data, 516,
4972 &p->server_info->user_session_key);
4974 dump_data(100, info->info23.password.data, 516);
4976 status = set_user_info_23(p->mem_ctx,
4977 &info->info23, pwd);
4978 break;
4980 case 24:
4981 if (!p->server_info->user_session_key.length) {
4982 status = NT_STATUS_NO_USER_SESSION_KEY;
4984 SamOEMhashBlob(info->info24.password.data,
4985 516,
4986 &p->server_info->user_session_key);
4988 dump_data(100, info->info24.password.data, 516);
4990 status = set_user_info_24(p->mem_ctx,
4991 &info->info24, pwd);
4992 break;
4994 case 25:
4995 if (!p->server_info->user_session_key.length) {
4996 status = NT_STATUS_NO_USER_SESSION_KEY;
4998 encode_or_decode_arc4_passwd_buffer(
4999 info->info25.password.data,
5000 &p->server_info->user_session_key);
5002 dump_data(100, info->info25.password.data, 532);
5004 status = set_user_info_25(p->mem_ctx,
5005 &info->info25, pwd);
5006 break;
5008 case 26:
5009 if (!p->server_info->user_session_key.length) {
5010 status = NT_STATUS_NO_USER_SESSION_KEY;
5012 encode_or_decode_arc4_passwd_buffer(
5013 info->info26.password.data,
5014 &p->server_info->user_session_key);
5016 dump_data(100, info->info26.password.data, 516);
5018 status = set_user_info_26(p->mem_ctx,
5019 &info->info26, pwd);
5020 break;
5022 default:
5023 status = NT_STATUS_INVALID_INFO_CLASS;
5026 TALLOC_FREE(pwd);
5028 if (has_enough_rights) {
5029 unbecome_root();
5032 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
5034 if (NT_STATUS_IS_OK(status)) {
5035 force_flush_samr_cache(disp_info);
5038 return status;
5041 /*******************************************************************
5042 _samr_SetUserInfo2
5043 ********************************************************************/
5045 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
5046 struct samr_SetUserInfo2 *r)
5048 struct samr_SetUserInfo q;
5050 q.in.user_handle = r->in.user_handle;
5051 q.in.level = r->in.level;
5052 q.in.info = r->in.info;
5054 return _samr_SetUserInfo(p, &q);
5057 /*********************************************************************
5058 _samr_GetAliasMembership
5059 *********************************************************************/
5061 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
5062 struct samr_GetAliasMembership *r)
5064 size_t num_alias_rids;
5065 uint32 *alias_rids;
5066 struct samr_info *info = NULL;
5067 size_t i;
5069 NTSTATUS ntstatus1;
5070 NTSTATUS ntstatus2;
5072 DOM_SID *members;
5074 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5076 /* find the policy handle. open a policy on it. */
5077 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5078 return NT_STATUS_INVALID_HANDLE;
5080 ntstatus1 = access_check_samr_function(info->acc_granted,
5081 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
5082 "_samr_GetAliasMembership");
5083 ntstatus2 = access_check_samr_function(info->acc_granted,
5084 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
5085 "_samr_GetAliasMembership");
5087 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
5088 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
5089 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
5090 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
5094 if (!sid_check_is_domain(&info->sid) &&
5095 !sid_check_is_builtin(&info->sid))
5096 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5098 if (r->in.sids->num_sids) {
5099 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
5101 if (members == NULL)
5102 return NT_STATUS_NO_MEMORY;
5103 } else {
5104 members = NULL;
5107 for (i=0; i<r->in.sids->num_sids; i++)
5108 sid_copy(&members[i], r->in.sids->sids[i].sid);
5110 alias_rids = NULL;
5111 num_alias_rids = 0;
5113 become_root();
5114 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
5115 r->in.sids->num_sids,
5116 &alias_rids, &num_alias_rids);
5117 unbecome_root();
5119 if (!NT_STATUS_IS_OK(ntstatus1)) {
5120 return ntstatus1;
5123 r->out.rids->count = num_alias_rids;
5124 r->out.rids->ids = alias_rids;
5126 return NT_STATUS_OK;
5129 /*********************************************************************
5130 _samr_GetMembersInAlias
5131 *********************************************************************/
5133 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5134 struct samr_GetMembersInAlias *r)
5136 NTSTATUS status;
5137 size_t i;
5138 size_t num_sids = 0;
5139 struct lsa_SidPtr *sids = NULL;
5140 DOM_SID *pdb_sids = NULL;
5142 DOM_SID alias_sid;
5144 uint32 acc_granted;
5146 /* find the policy handle. open a policy on it. */
5147 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
5148 return NT_STATUS_INVALID_HANDLE;
5150 status = access_check_samr_function(acc_granted,
5151 SAMR_ALIAS_ACCESS_GET_MEMBERS,
5152 "_samr_GetMembersInAlias");
5153 if (!NT_STATUS_IS_OK(status)) {
5154 return status;
5157 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5159 become_root();
5160 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
5161 unbecome_root();
5163 if (!NT_STATUS_IS_OK(status)) {
5164 return status;
5167 if (num_sids) {
5168 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5169 if (sids == NULL) {
5170 TALLOC_FREE(pdb_sids);
5171 return NT_STATUS_NO_MEMORY;
5175 for (i = 0; i < num_sids; i++) {
5176 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5177 if (!sids[i].sid) {
5178 TALLOC_FREE(pdb_sids);
5179 return NT_STATUS_NO_MEMORY;
5183 r->out.sids->num_sids = num_sids;
5184 r->out.sids->sids = sids;
5186 TALLOC_FREE(pdb_sids);
5188 return NT_STATUS_OK;
5191 /*********************************************************************
5192 _samr_QueryGroupMember
5193 *********************************************************************/
5195 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5196 struct samr_QueryGroupMember *r)
5198 DOM_SID group_sid;
5199 size_t i, num_members;
5201 uint32 *rid=NULL;
5202 uint32 *attr=NULL;
5204 uint32 acc_granted;
5206 NTSTATUS status;
5207 struct samr_RidTypeArray *rids = NULL;
5209 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5210 if (!rids) {
5211 return NT_STATUS_NO_MEMORY;
5214 /* find the policy handle. open a policy on it. */
5215 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5216 return NT_STATUS_INVALID_HANDLE;
5218 status = access_check_samr_function(acc_granted,
5219 SAMR_GROUP_ACCESS_GET_MEMBERS,
5220 "_samr_QueryGroupMember");
5221 if (!NT_STATUS_IS_OK(status)) {
5222 return status;
5225 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
5227 if (!sid_check_is_in_our_domain(&group_sid)) {
5228 DEBUG(3, ("sid %s is not in our domain\n",
5229 sid_string_dbg(&group_sid)));
5230 return NT_STATUS_NO_SUCH_GROUP;
5233 DEBUG(10, ("lookup on Domain SID\n"));
5235 become_root();
5236 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
5237 &rid, &num_members);
5238 unbecome_root();
5240 if (!NT_STATUS_IS_OK(status))
5241 return status;
5243 if (num_members) {
5244 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5245 if (attr == NULL) {
5246 return NT_STATUS_NO_MEMORY;
5248 } else {
5249 attr = NULL;
5252 for (i=0; i<num_members; i++)
5253 attr[i] = SID_NAME_USER;
5255 rids->count = num_members;
5256 rids->types = attr;
5257 rids->rids = rid;
5259 *r->out.rids = rids;
5261 return NT_STATUS_OK;
5264 /*********************************************************************
5265 _samr_AddAliasMember
5266 *********************************************************************/
5268 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5269 struct samr_AddAliasMember *r)
5271 DOM_SID alias_sid;
5272 uint32 acc_granted;
5273 SE_PRIV se_rights;
5274 bool can_add_accounts;
5275 NTSTATUS status;
5276 DISP_INFO *disp_info = NULL;
5278 /* Find the policy handle. Open a policy on it. */
5279 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5280 return NT_STATUS_INVALID_HANDLE;
5282 status = access_check_samr_function(acc_granted,
5283 SAMR_ALIAS_ACCESS_ADD_MEMBER,
5284 "_samr_AddAliasMember");
5285 if (!NT_STATUS_IS_OK(status)) {
5286 return status;
5289 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5291 se_priv_copy( &se_rights, &se_add_users );
5292 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5294 /******** BEGIN SeAddUsers BLOCK *********/
5296 if ( can_add_accounts )
5297 become_root();
5299 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
5301 if ( can_add_accounts )
5302 unbecome_root();
5304 /******** END SeAddUsers BLOCK *********/
5306 if (NT_STATUS_IS_OK(status)) {
5307 force_flush_samr_cache(disp_info);
5310 return status;
5313 /*********************************************************************
5314 _samr_DeleteAliasMember
5315 *********************************************************************/
5317 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5318 struct samr_DeleteAliasMember *r)
5320 DOM_SID alias_sid;
5321 uint32 acc_granted;
5322 SE_PRIV se_rights;
5323 bool can_add_accounts;
5324 NTSTATUS status;
5325 DISP_INFO *disp_info = NULL;
5327 /* Find the policy handle. Open a policy on it. */
5328 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5329 return NT_STATUS_INVALID_HANDLE;
5331 status = access_check_samr_function(acc_granted,
5332 SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
5333 "_samr_DeleteAliasMember");
5334 if (!NT_STATUS_IS_OK(status)) {
5335 return status;
5338 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5339 sid_string_dbg(&alias_sid)));
5341 se_priv_copy( &se_rights, &se_add_users );
5342 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5344 /******** BEGIN SeAddUsers BLOCK *********/
5346 if ( can_add_accounts )
5347 become_root();
5349 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
5351 if ( can_add_accounts )
5352 unbecome_root();
5354 /******** END SeAddUsers BLOCK *********/
5356 if (NT_STATUS_IS_OK(status)) {
5357 force_flush_samr_cache(disp_info);
5360 return status;
5363 /*********************************************************************
5364 _samr_AddGroupMember
5365 *********************************************************************/
5367 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5368 struct samr_AddGroupMember *r)
5370 NTSTATUS status;
5371 DOM_SID group_sid;
5372 uint32 group_rid;
5373 uint32 acc_granted;
5374 SE_PRIV se_rights;
5375 bool can_add_accounts;
5376 DISP_INFO *disp_info = NULL;
5378 /* Find the policy handle. Open a policy on it. */
5379 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5380 return NT_STATUS_INVALID_HANDLE;
5382 status = access_check_samr_function(acc_granted,
5383 SAMR_GROUP_ACCESS_ADD_MEMBER,
5384 "_samr_AddGroupMember");
5385 if (!NT_STATUS_IS_OK(status)) {
5386 return status;
5389 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
5391 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
5392 &group_rid)) {
5393 return NT_STATUS_INVALID_HANDLE;
5396 se_priv_copy( &se_rights, &se_add_users );
5397 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5399 /******** BEGIN SeAddUsers BLOCK *********/
5401 if ( can_add_accounts )
5402 become_root();
5404 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5406 if ( can_add_accounts )
5407 unbecome_root();
5409 /******** END SeAddUsers BLOCK *********/
5411 force_flush_samr_cache(disp_info);
5413 return status;
5416 /*********************************************************************
5417 _samr_DeleteGroupMember
5418 *********************************************************************/
5420 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5421 struct samr_DeleteGroupMember *r)
5424 NTSTATUS status;
5425 DOM_SID group_sid;
5426 uint32 group_rid;
5427 uint32 acc_granted;
5428 SE_PRIV se_rights;
5429 bool can_add_accounts;
5430 DISP_INFO *disp_info = NULL;
5433 * delete the group member named r->in.rid
5434 * who is a member of the sid associated with the handle
5435 * the rid is a user's rid as the group is a domain group.
5438 /* Find the policy handle. Open a policy on it. */
5439 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5440 return NT_STATUS_INVALID_HANDLE;
5442 status = access_check_samr_function(acc_granted,
5443 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
5444 "_samr_DeleteGroupMember");
5445 if (!NT_STATUS_IS_OK(status)) {
5446 return status;
5449 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
5450 &group_rid)) {
5451 return NT_STATUS_INVALID_HANDLE;
5454 se_priv_copy( &se_rights, &se_add_users );
5455 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5457 /******** BEGIN SeAddUsers BLOCK *********/
5459 if ( can_add_accounts )
5460 become_root();
5462 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5464 if ( can_add_accounts )
5465 unbecome_root();
5467 /******** END SeAddUsers BLOCK *********/
5469 force_flush_samr_cache(disp_info);
5471 return status;
5474 /*********************************************************************
5475 _samr_DeleteUser
5476 *********************************************************************/
5478 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5479 struct samr_DeleteUser *r)
5481 NTSTATUS status;
5482 DOM_SID user_sid;
5483 struct samu *sam_pass=NULL;
5484 uint32 acc_granted;
5485 bool can_add_accounts;
5486 uint32 acb_info;
5487 DISP_INFO *disp_info = NULL;
5488 bool ret;
5490 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5492 /* Find the policy handle. Open a policy on it. */
5493 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
5494 return NT_STATUS_INVALID_HANDLE;
5496 status = access_check_samr_function(acc_granted,
5497 STD_RIGHT_DELETE_ACCESS,
5498 "_samr_DeleteUser");
5499 if (!NT_STATUS_IS_OK(status)) {
5500 return status;
5503 if (!sid_check_is_in_our_domain(&user_sid))
5504 return NT_STATUS_CANNOT_DELETE;
5506 /* check if the user exists before trying to delete */
5507 if ( !(sam_pass = samu_new( NULL )) ) {
5508 return NT_STATUS_NO_MEMORY;
5511 become_root();
5512 ret = pdb_getsampwsid(sam_pass, &user_sid);
5513 unbecome_root();
5515 if( !ret ) {
5516 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5517 sid_string_dbg(&user_sid)));
5518 TALLOC_FREE(sam_pass);
5519 return NT_STATUS_NO_SUCH_USER;
5522 acb_info = pdb_get_acct_ctrl(sam_pass);
5524 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
5525 if ( acb_info & ACB_WSTRUST ) {
5526 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
5527 } else {
5528 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5531 /******** BEGIN SeAddUsers BLOCK *********/
5533 if ( can_add_accounts )
5534 become_root();
5536 status = pdb_delete_user(p->mem_ctx, sam_pass);
5538 if ( can_add_accounts )
5539 unbecome_root();
5541 /******** END SeAddUsers BLOCK *********/
5543 if ( !NT_STATUS_IS_OK(status) ) {
5544 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5545 "user %s: %s.\n", pdb_get_username(sam_pass),
5546 nt_errstr(status)));
5547 TALLOC_FREE(sam_pass);
5548 return status;
5552 TALLOC_FREE(sam_pass);
5554 if (!close_policy_hnd(p, r->in.user_handle))
5555 return NT_STATUS_OBJECT_NAME_INVALID;
5557 ZERO_STRUCTP(r->out.user_handle);
5559 force_flush_samr_cache(disp_info);
5561 return NT_STATUS_OK;
5564 /*********************************************************************
5565 _samr_DeleteDomainGroup
5566 *********************************************************************/
5568 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5569 struct samr_DeleteDomainGroup *r)
5571 NTSTATUS status;
5572 DOM_SID group_sid;
5573 uint32 group_rid;
5574 uint32 acc_granted;
5575 SE_PRIV se_rights;
5576 bool can_add_accounts;
5577 DISP_INFO *disp_info = NULL;
5579 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5581 /* Find the policy handle. Open a policy on it. */
5582 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5583 return NT_STATUS_INVALID_HANDLE;
5585 status = access_check_samr_function(acc_granted,
5586 STD_RIGHT_DELETE_ACCESS,
5587 "_samr_DeleteDomainGroup");
5588 if (!NT_STATUS_IS_OK(status)) {
5589 return status;
5592 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
5594 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
5595 &group_rid)) {
5596 return NT_STATUS_NO_SUCH_GROUP;
5599 se_priv_copy( &se_rights, &se_add_users );
5600 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5602 /******** BEGIN SeAddUsers BLOCK *********/
5604 if ( can_add_accounts )
5605 become_root();
5607 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5609 if ( can_add_accounts )
5610 unbecome_root();
5612 /******** END SeAddUsers BLOCK *********/
5614 if ( !NT_STATUS_IS_OK(status) ) {
5615 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5616 "entry for group %s: %s\n",
5617 sid_string_dbg(&group_sid),
5618 nt_errstr(status)));
5619 return status;
5622 if (!close_policy_hnd(p, r->in.group_handle))
5623 return NT_STATUS_OBJECT_NAME_INVALID;
5625 force_flush_samr_cache(disp_info);
5627 return NT_STATUS_OK;
5630 /*********************************************************************
5631 _samr_DeleteDomAlias
5632 *********************************************************************/
5634 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5635 struct samr_DeleteDomAlias *r)
5637 DOM_SID alias_sid;
5638 uint32 acc_granted;
5639 SE_PRIV se_rights;
5640 bool can_add_accounts;
5641 NTSTATUS status;
5642 DISP_INFO *disp_info = NULL;
5644 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5646 /* Find the policy handle. Open a policy on it. */
5647 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5648 return NT_STATUS_INVALID_HANDLE;
5650 /* copy the handle to the outgoing reply */
5652 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
5654 status = access_check_samr_function(acc_granted,
5655 STD_RIGHT_DELETE_ACCESS,
5656 "_samr_DeleteDomAlias");
5657 if (!NT_STATUS_IS_OK(status)) {
5658 return status;
5661 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5663 /* Don't let Windows delete builtin groups */
5665 if ( sid_check_is_in_builtin( &alias_sid ) ) {
5666 return NT_STATUS_SPECIAL_ACCOUNT;
5669 if (!sid_check_is_in_our_domain(&alias_sid))
5670 return NT_STATUS_NO_SUCH_ALIAS;
5672 DEBUG(10, ("lookup on Local SID\n"));
5674 se_priv_copy( &se_rights, &se_add_users );
5675 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5677 /******** BEGIN SeAddUsers BLOCK *********/
5679 if ( can_add_accounts )
5680 become_root();
5682 /* Have passdb delete the alias */
5683 status = pdb_delete_alias(&alias_sid);
5685 if ( can_add_accounts )
5686 unbecome_root();
5688 /******** END SeAddUsers BLOCK *********/
5690 if ( !NT_STATUS_IS_OK(status))
5691 return status;
5693 if (!close_policy_hnd(p, r->in.alias_handle))
5694 return NT_STATUS_OBJECT_NAME_INVALID;
5696 force_flush_samr_cache(disp_info);
5698 return NT_STATUS_OK;
5701 /*********************************************************************
5702 _samr_CreateDomainGroup
5703 *********************************************************************/
5705 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5706 struct samr_CreateDomainGroup *r)
5709 NTSTATUS status;
5710 DOM_SID dom_sid;
5711 DOM_SID info_sid;
5712 const char *name;
5713 struct samr_info *info;
5714 uint32 acc_granted;
5715 SE_PRIV se_rights;
5716 bool can_add_accounts;
5717 DISP_INFO *disp_info = NULL;
5719 /* Find the policy handle. Open a policy on it. */
5720 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5721 return NT_STATUS_INVALID_HANDLE;
5723 status = access_check_samr_function(acc_granted,
5724 SAMR_DOMAIN_ACCESS_CREATE_GROUP,
5725 "_samr_CreateDomainGroup");
5726 if (!NT_STATUS_IS_OK(status)) {
5727 return status;
5730 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5731 return NT_STATUS_ACCESS_DENIED;
5733 name = r->in.name->string;
5734 if (name == NULL) {
5735 return NT_STATUS_NO_MEMORY;
5738 status = can_create(p->mem_ctx, name);
5739 if (!NT_STATUS_IS_OK(status)) {
5740 return status;
5743 se_priv_copy( &se_rights, &se_add_users );
5744 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5746 /******** BEGIN SeAddUsers BLOCK *********/
5748 if ( can_add_accounts )
5749 become_root();
5751 /* check that we successfully create the UNIX group */
5753 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5755 if ( can_add_accounts )
5756 unbecome_root();
5758 /******** END SeAddUsers BLOCK *********/
5760 /* check if we should bail out here */
5762 if ( !NT_STATUS_IS_OK(status) )
5763 return status;
5765 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5767 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5768 return NT_STATUS_NO_MEMORY;
5770 /* they created it; let the user do what he wants with it */
5772 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5774 /* get a (unique) handle. open a policy on it. */
5775 if (!create_policy_hnd(p, r->out.group_handle, info))
5776 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5778 force_flush_samr_cache(disp_info);
5780 return NT_STATUS_OK;
5783 /*********************************************************************
5784 _samr_CreateDomAlias
5785 *********************************************************************/
5787 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5788 struct samr_CreateDomAlias *r)
5790 DOM_SID dom_sid;
5791 DOM_SID info_sid;
5792 const char *name = NULL;
5793 struct samr_info *info;
5794 uint32 acc_granted;
5795 gid_t gid;
5796 NTSTATUS result;
5797 SE_PRIV se_rights;
5798 bool can_add_accounts;
5799 DISP_INFO *disp_info = NULL;
5801 /* Find the policy handle. Open a policy on it. */
5802 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5803 return NT_STATUS_INVALID_HANDLE;
5805 result = access_check_samr_function(acc_granted,
5806 SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
5807 "_samr_CreateDomAlias");
5808 if (!NT_STATUS_IS_OK(result)) {
5809 return result;
5812 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5813 return NT_STATUS_ACCESS_DENIED;
5815 name = r->in.alias_name->string;
5817 se_priv_copy( &se_rights, &se_add_users );
5818 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5820 result = can_create(p->mem_ctx, name);
5821 if (!NT_STATUS_IS_OK(result)) {
5822 return result;
5825 /******** BEGIN SeAddUsers BLOCK *********/
5827 if ( can_add_accounts )
5828 become_root();
5830 /* Have passdb create the alias */
5831 result = pdb_create_alias(name, r->out.rid);
5833 if ( can_add_accounts )
5834 unbecome_root();
5836 /******** END SeAddUsers BLOCK *********/
5838 if (!NT_STATUS_IS_OK(result)) {
5839 DEBUG(10, ("pdb_create_alias failed: %s\n",
5840 nt_errstr(result)));
5841 return result;
5844 sid_copy(&info_sid, get_global_sam_sid());
5845 sid_append_rid(&info_sid, *r->out.rid);
5847 if (!sid_to_gid(&info_sid, &gid)) {
5848 DEBUG(10, ("Could not find alias just created\n"));
5849 return NT_STATUS_ACCESS_DENIED;
5852 /* check if the group has been successfully created */
5853 if ( getgrgid(gid) == NULL ) {
5854 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5855 gid));
5856 return NT_STATUS_ACCESS_DENIED;
5859 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5860 return NT_STATUS_NO_MEMORY;
5862 /* they created it; let the user do what he wants with it */
5864 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5866 /* get a (unique) handle. open a policy on it. */
5867 if (!create_policy_hnd(p, r->out.alias_handle, info))
5868 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5870 force_flush_samr_cache(disp_info);
5872 return NT_STATUS_OK;
5875 /*********************************************************************
5876 _samr_QueryGroupInfo
5877 *********************************************************************/
5879 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5880 struct samr_QueryGroupInfo *r)
5882 NTSTATUS status;
5883 DOM_SID group_sid;
5884 GROUP_MAP map;
5885 union samr_GroupInfo *info = NULL;
5886 uint32 acc_granted;
5887 bool ret;
5888 uint32_t attributes = SE_GROUP_MANDATORY |
5889 SE_GROUP_ENABLED_BY_DEFAULT |
5890 SE_GROUP_ENABLED;
5891 const char *group_name = NULL;
5892 const char *group_description = NULL;
5894 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5895 return NT_STATUS_INVALID_HANDLE;
5897 status = access_check_samr_function(acc_granted,
5898 SAMR_GROUP_ACCESS_LOOKUP_INFO,
5899 "_samr_QueryGroupInfo");
5900 if (!NT_STATUS_IS_OK(status)) {
5901 return status;
5904 become_root();
5905 ret = get_domain_group_from_sid(group_sid, &map);
5906 unbecome_root();
5907 if (!ret)
5908 return NT_STATUS_INVALID_HANDLE;
5910 /* FIXME: map contains fstrings */
5911 group_name = talloc_strdup(r, map.nt_name);
5912 group_description = talloc_strdup(r, map.comment);
5914 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5915 if (!info) {
5916 return NT_STATUS_NO_MEMORY;
5919 switch (r->in.level) {
5920 case 1: {
5921 uint32 *members;
5922 size_t num_members;
5924 become_root();
5925 status = pdb_enum_group_members(
5926 p->mem_ctx, &group_sid, &members, &num_members);
5927 unbecome_root();
5929 if (!NT_STATUS_IS_OK(status)) {
5930 return status;
5933 info->all.name.string = group_name;
5934 info->all.attributes = attributes;
5935 info->all.num_members = num_members;
5936 info->all.description.string = group_description;
5937 break;
5939 case 2:
5940 info->name.string = group_name;
5941 break;
5942 case 3:
5943 info->attributes.attributes = attributes;
5944 break;
5945 case 4:
5946 info->description.string = group_description;
5947 break;
5948 case 5: {
5950 uint32 *members;
5951 size_t num_members;
5955 become_root();
5956 status = pdb_enum_group_members(
5957 p->mem_ctx, &group_sid, &members, &num_members);
5958 unbecome_root();
5960 if (!NT_STATUS_IS_OK(status)) {
5961 return status;
5964 info->all2.name.string = group_name;
5965 info->all2.attributes = attributes;
5966 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5967 info->all2.description.string = group_description;
5969 break;
5971 default:
5972 return NT_STATUS_INVALID_INFO_CLASS;
5975 *r->out.info = info;
5977 return NT_STATUS_OK;
5980 /*********************************************************************
5981 _samr_SetGroupInfo
5982 *********************************************************************/
5984 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5985 struct samr_SetGroupInfo *r)
5987 DOM_SID group_sid;
5988 GROUP_MAP map;
5989 uint32 acc_granted;
5990 NTSTATUS status;
5991 bool ret;
5992 bool can_mod_accounts;
5993 DISP_INFO *disp_info = NULL;
5995 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5996 return NT_STATUS_INVALID_HANDLE;
5998 status = access_check_samr_function(acc_granted,
5999 SAMR_GROUP_ACCESS_SET_INFO,
6000 "_samr_SetGroupInfo");
6001 if (!NT_STATUS_IS_OK(status)) {
6002 return status;
6005 become_root();
6006 ret = get_domain_group_from_sid(group_sid, &map);
6007 unbecome_root();
6008 if (!ret)
6009 return NT_STATUS_NO_SUCH_GROUP;
6011 switch (r->in.level) {
6012 case 1:
6013 fstrcpy(map.comment, r->in.info->all.description.string);
6014 break;
6015 case 2:
6016 /* group rename is not supported yet */
6017 return NT_STATUS_NOT_SUPPORTED;
6018 case 4:
6019 fstrcpy(map.comment, r->in.info->description.string);
6020 break;
6021 default:
6022 return NT_STATUS_INVALID_INFO_CLASS;
6025 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
6027 /******** BEGIN SeAddUsers BLOCK *********/
6029 if ( can_mod_accounts )
6030 become_root();
6032 status = pdb_update_group_mapping_entry(&map);
6034 if ( can_mod_accounts )
6035 unbecome_root();
6037 /******** End SeAddUsers BLOCK *********/
6039 if (NT_STATUS_IS_OK(status)) {
6040 force_flush_samr_cache(disp_info);
6043 return status;
6046 /*********************************************************************
6047 _samr_SetAliasInfo
6048 *********************************************************************/
6050 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
6051 struct samr_SetAliasInfo *r)
6053 DOM_SID group_sid;
6054 struct acct_info info;
6055 uint32 acc_granted;
6056 bool can_mod_accounts;
6057 NTSTATUS status;
6058 DISP_INFO *disp_info = NULL;
6060 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
6061 return NT_STATUS_INVALID_HANDLE;
6063 status = access_check_samr_function(acc_granted,
6064 SAMR_ALIAS_ACCESS_SET_INFO,
6065 "_samr_SetAliasInfo");
6066 if (!NT_STATUS_IS_OK(status)) {
6067 return status;
6070 /* get the current group information */
6072 become_root();
6073 status = pdb_get_aliasinfo( &group_sid, &info );
6074 unbecome_root();
6076 if ( !NT_STATUS_IS_OK(status))
6077 return status;
6079 switch (r->in.level) {
6080 case ALIASINFONAME:
6082 fstring group_name;
6084 /* We currently do not support renaming groups in the
6085 the BUILTIN domain. Refer to util_builtin.c to understand
6086 why. The eventually needs to be fixed to be like Windows
6087 where you can rename builtin groups, just not delete them */
6089 if ( sid_check_is_in_builtin( &group_sid ) ) {
6090 return NT_STATUS_SPECIAL_ACCOUNT;
6093 /* There has to be a valid name (and it has to be different) */
6095 if ( !r->in.info->name.string )
6096 return NT_STATUS_INVALID_PARAMETER;
6098 /* If the name is the same just reply "ok". Yes this
6099 doesn't allow you to change the case of a group name. */
6101 if ( strequal( r->in.info->name.string, info.acct_name ) )
6102 return NT_STATUS_OK;
6104 fstrcpy( info.acct_name, r->in.info->name.string);
6106 /* make sure the name doesn't already exist as a user
6107 or local group */
6109 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6110 status = can_create( p->mem_ctx, group_name );
6111 if ( !NT_STATUS_IS_OK( status ) )
6112 return status;
6113 break;
6115 case ALIASINFODESCRIPTION:
6116 if (r->in.info->description.string) {
6117 fstrcpy(info.acct_desc,
6118 r->in.info->description.string);
6119 } else {
6120 fstrcpy( info.acct_desc, "" );
6122 break;
6123 default:
6124 return NT_STATUS_INVALID_INFO_CLASS;
6127 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
6129 /******** BEGIN SeAddUsers BLOCK *********/
6131 if ( can_mod_accounts )
6132 become_root();
6134 status = pdb_set_aliasinfo( &group_sid, &info );
6136 if ( can_mod_accounts )
6137 unbecome_root();
6139 /******** End SeAddUsers BLOCK *********/
6141 if (NT_STATUS_IS_OK(status))
6142 force_flush_samr_cache(disp_info);
6144 return status;
6147 /****************************************************************
6148 _samr_GetDomPwInfo
6149 ****************************************************************/
6151 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
6152 struct samr_GetDomPwInfo *r)
6154 uint32_t min_password_length = 0;
6155 uint32_t password_properties = 0;
6157 /* Perform access check. Since this rpc does not require a
6158 policy handle it will not be caught by the access checks on
6159 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6161 if (!pipe_access_check(p)) {
6162 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6163 return NT_STATUS_ACCESS_DENIED;
6166 become_root();
6167 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
6168 &min_password_length);
6169 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
6170 &password_properties);
6171 unbecome_root();
6173 if (lp_check_password_script() && *lp_check_password_script()) {
6174 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6177 r->out.info->min_password_length = min_password_length;
6178 r->out.info->password_properties = password_properties;
6180 return NT_STATUS_OK;
6183 /*********************************************************************
6184 _samr_OpenGroup
6185 *********************************************************************/
6187 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6188 struct samr_OpenGroup *r)
6191 DOM_SID sid;
6192 DOM_SID info_sid;
6193 GROUP_MAP map;
6194 struct samr_info *info;
6195 SEC_DESC *psd = NULL;
6196 uint32 acc_granted;
6197 uint32 des_access = r->in.access_mask;
6198 size_t sd_size;
6199 NTSTATUS status;
6200 fstring sid_string;
6201 bool ret;
6202 SE_PRIV se_rights;
6204 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
6205 return NT_STATUS_INVALID_HANDLE;
6207 status = access_check_samr_function(acc_granted,
6208 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
6209 "_samr_OpenGroup");
6211 if ( !NT_STATUS_IS_OK(status) )
6212 return status;
6214 /*check if access can be granted as requested by client. */
6215 map_max_allowed_access(p->server_info->ptok, &des_access);
6217 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6218 se_map_generic(&des_access,&grp_generic_mapping);
6220 se_priv_copy( &se_rights, &se_add_users );
6222 status = access_check_samr_object(psd, p->server_info->ptok,
6223 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
6224 &acc_granted, "_samr_OpenGroup");
6226 if ( !NT_STATUS_IS_OK(status) )
6227 return status;
6229 /* this should not be hard-coded like this */
6231 if (!sid_equal(&sid, get_global_sam_sid()))
6232 return NT_STATUS_ACCESS_DENIED;
6234 sid_copy(&info_sid, get_global_sam_sid());
6235 sid_append_rid(&info_sid, r->in.rid);
6236 sid_to_fstring(sid_string, &info_sid);
6238 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
6239 return NT_STATUS_NO_MEMORY;
6241 info->acc_granted = acc_granted;
6243 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
6245 /* check if that group really exists */
6246 become_root();
6247 ret = get_domain_group_from_sid(info->sid, &map);
6248 unbecome_root();
6249 if (!ret)
6250 return NT_STATUS_NO_SUCH_GROUP;
6252 /* get a (unique) handle. open a policy on it. */
6253 if (!create_policy_hnd(p, r->out.group_handle, info))
6254 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6256 return NT_STATUS_OK;
6259 /*********************************************************************
6260 _samr_RemoveMemberFromForeignDomain
6261 *********************************************************************/
6263 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6264 struct samr_RemoveMemberFromForeignDomain *r)
6266 DOM_SID delete_sid, domain_sid;
6267 uint32 acc_granted;
6268 NTSTATUS result;
6269 DISP_INFO *disp_info = NULL;
6271 sid_copy( &delete_sid, r->in.sid );
6273 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6274 sid_string_dbg(&delete_sid)));
6276 /* Find the policy handle. Open a policy on it. */
6278 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
6279 &acc_granted, &disp_info))
6280 return NT_STATUS_INVALID_HANDLE;
6282 result = access_check_samr_function(acc_granted,
6283 STD_RIGHT_DELETE_ACCESS,
6284 "_samr_RemoveMemberFromForeignDomain");
6286 if (!NT_STATUS_IS_OK(result))
6287 return result;
6289 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6290 sid_string_dbg(&domain_sid)));
6292 /* we can only delete a user from a group since we don't have
6293 nested groups anyways. So in the latter case, just say OK */
6295 /* TODO: The above comment nowadays is bogus. Since we have nested
6296 * groups now, and aliases members are never reported out of the unix
6297 * group membership, the "just say OK" makes this call a no-op. For
6298 * us. This needs fixing however. */
6300 /* I've only ever seen this in the wild when deleting a user from
6301 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6302 * is the user about to be deleted. I very much suspect this is the
6303 * only application of this call. To verify this, let people report
6304 * other cases. */
6306 if (!sid_check_is_builtin(&domain_sid)) {
6307 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6308 "global_sam_sid() = %s\n",
6309 sid_string_dbg(&domain_sid),
6310 sid_string_dbg(get_global_sam_sid())));
6311 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6312 return NT_STATUS_OK;
6315 force_flush_samr_cache(disp_info);
6317 result = NT_STATUS_OK;
6319 return result;
6322 /*******************************************************************
6323 _samr_QueryDomainInfo2
6324 ********************************************************************/
6326 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6327 struct samr_QueryDomainInfo2 *r)
6329 struct samr_QueryDomainInfo q;
6331 q.in.domain_handle = r->in.domain_handle;
6332 q.in.level = r->in.level;
6334 q.out.info = r->out.info;
6336 return _samr_QueryDomainInfo(p, &q);
6339 /*******************************************************************
6340 _samr_SetDomainInfo
6341 ********************************************************************/
6343 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6344 struct samr_SetDomainInfo *r)
6346 struct samr_info *info = NULL;
6347 time_t u_expire, u_min_age;
6348 time_t u_logout;
6349 time_t u_lock_duration, u_reset_time;
6350 NTSTATUS result;
6352 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6354 /* find the policy handle. open a policy on it. */
6355 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
6356 return NT_STATUS_INVALID_HANDLE;
6358 /* We do have different access bits for info
6359 * levels here, but we're really just looking for
6360 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
6361 * this maps to different specific bits. So
6362 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
6363 * set we are ok. */
6365 result = access_check_samr_function(info->acc_granted,
6366 SAMR_DOMAIN_ACCESS_SET_INFO_1,
6367 "_samr_SetDomainInfo");
6369 if (!NT_STATUS_IS_OK(result))
6370 return result;
6372 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6374 switch (r->in.level) {
6375 case 0x01:
6376 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
6377 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
6378 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
6379 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
6380 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
6381 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
6382 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
6383 break;
6384 case 0x03:
6385 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
6386 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
6387 break;
6388 case 0x04:
6389 break;
6390 case 0x06:
6391 break;
6392 case 0x07:
6393 break;
6394 case 0x09:
6395 break;
6396 case 0x0c:
6397 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
6398 if (u_lock_duration != -1)
6399 u_lock_duration /= 60;
6401 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
6403 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6404 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
6405 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
6406 break;
6407 default:
6408 return NT_STATUS_INVALID_INFO_CLASS;
6411 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6413 return NT_STATUS_OK;
6416 /****************************************************************
6417 _samr_GetDisplayEnumerationIndex
6418 ****************************************************************/
6420 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6421 struct samr_GetDisplayEnumerationIndex *r)
6423 struct samr_info *info = NULL;
6424 uint32_t max_entries = (uint32_t) -1;
6425 uint32_t enum_context = 0;
6426 int i;
6427 uint32_t num_account = 0;
6428 struct samr_displayentry *entries = NULL;
6429 NTSTATUS status;
6431 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6433 /* find the policy handle. open a policy on it. */
6434 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
6435 return NT_STATUS_INVALID_HANDLE;
6438 status = access_check_samr_function(info->acc_granted,
6439 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
6440 "_samr_GetDisplayEnumerationIndex");
6441 if (!NT_STATUS_IS_OK(status)) {
6442 return status;
6445 if ((r->in.level < 1) || (r->in.level > 3)) {
6446 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6447 "Unknown info level (%u)\n",
6448 r->in.level));
6449 return NT_STATUS_INVALID_INFO_CLASS;
6452 become_root();
6454 /* The following done as ROOT. Don't return without unbecome_root(). */
6456 switch (r->in.level) {
6457 case 1:
6458 if (info->disp_info->users == NULL) {
6459 info->disp_info->users = pdb_search_users(
6460 info->disp_info, ACB_NORMAL);
6461 if (info->disp_info->users == NULL) {
6462 unbecome_root();
6463 return NT_STATUS_ACCESS_DENIED;
6465 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6466 "starting user enumeration at index %u\n",
6467 (unsigned int)enum_context));
6468 } else {
6469 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6470 "using cached user enumeration at index %u\n",
6471 (unsigned int)enum_context));
6473 num_account = pdb_search_entries(info->disp_info->users,
6474 enum_context, max_entries,
6475 &entries);
6476 break;
6477 case 2:
6478 if (info->disp_info->machines == NULL) {
6479 info->disp_info->machines = pdb_search_users(
6480 info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6481 if (info->disp_info->machines == NULL) {
6482 unbecome_root();
6483 return NT_STATUS_ACCESS_DENIED;
6485 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6486 "starting machine enumeration at index %u\n",
6487 (unsigned int)enum_context));
6488 } else {
6489 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6490 "using cached machine enumeration at index %u\n",
6491 (unsigned int)enum_context));
6493 num_account = pdb_search_entries(info->disp_info->machines,
6494 enum_context, max_entries,
6495 &entries);
6496 break;
6497 case 3:
6498 if (info->disp_info->groups == NULL) {
6499 info->disp_info->groups = pdb_search_groups(
6500 info->disp_info);
6501 if (info->disp_info->groups == NULL) {
6502 unbecome_root();
6503 return NT_STATUS_ACCESS_DENIED;
6505 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6506 "starting group enumeration at index %u\n",
6507 (unsigned int)enum_context));
6508 } else {
6509 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6510 "using cached group enumeration at index %u\n",
6511 (unsigned int)enum_context));
6513 num_account = pdb_search_entries(info->disp_info->groups,
6514 enum_context, max_entries,
6515 &entries);
6516 break;
6517 default:
6518 unbecome_root();
6519 smb_panic("info class changed");
6520 break;
6523 unbecome_root();
6525 /* Ensure we cache this enumeration. */
6526 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
6528 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6529 r->in.name->string));
6531 for (i=0; i<num_account; i++) {
6532 if (strequal(entries[i].account_name, r->in.name->string)) {
6533 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6534 "found %s at idx %d\n",
6535 r->in.name->string, i));
6536 *r->out.idx = i;
6537 return NT_STATUS_OK;
6541 /* assuming account_name lives at the very end */
6542 *r->out.idx = num_account;
6544 return NT_STATUS_NO_MORE_ENTRIES;
6547 /****************************************************************
6548 _samr_GetDisplayEnumerationIndex2
6549 ****************************************************************/
6551 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6552 struct samr_GetDisplayEnumerationIndex2 *r)
6554 struct samr_GetDisplayEnumerationIndex q;
6556 q.in.domain_handle = r->in.domain_handle;
6557 q.in.level = r->in.level;
6558 q.in.name = r->in.name;
6560 q.out.idx = r->out.idx;
6562 return _samr_GetDisplayEnumerationIndex(p, &q);
6565 /****************************************************************
6566 ****************************************************************/
6568 NTSTATUS _samr_Shutdown(pipes_struct *p,
6569 struct samr_Shutdown *r)
6571 p->rng_fault_state = true;
6572 return NT_STATUS_NOT_IMPLEMENTED;
6575 /****************************************************************
6576 ****************************************************************/
6578 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6579 struct samr_SetMemberAttributesOfGroup *r)
6581 p->rng_fault_state = true;
6582 return NT_STATUS_NOT_IMPLEMENTED;
6585 /****************************************************************
6586 ****************************************************************/
6588 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6589 struct samr_TestPrivateFunctionsDomain *r)
6591 p->rng_fault_state = true;
6592 return NT_STATUS_NOT_IMPLEMENTED;
6595 /****************************************************************
6596 ****************************************************************/
6598 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6599 struct samr_TestPrivateFunctionsUser *r)
6601 return NT_STATUS_NOT_IMPLEMENTED;
6604 /****************************************************************
6605 ****************************************************************/
6607 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6608 struct samr_AddMultipleMembersToAlias *r)
6610 p->rng_fault_state = true;
6611 return NT_STATUS_NOT_IMPLEMENTED;
6614 /****************************************************************
6615 ****************************************************************/
6617 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6618 struct samr_RemoveMultipleMembersFromAlias *r)
6620 p->rng_fault_state = true;
6621 return NT_STATUS_NOT_IMPLEMENTED;
6624 /****************************************************************
6625 ****************************************************************/
6627 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6628 struct samr_SetBootKeyInformation *r)
6630 p->rng_fault_state = true;
6631 return NT_STATUS_NOT_IMPLEMENTED;
6634 /****************************************************************
6635 ****************************************************************/
6637 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6638 struct samr_GetBootKeyInformation *r)
6640 p->rng_fault_state = true;
6641 return NT_STATUS_NOT_IMPLEMENTED;
6644 /****************************************************************
6645 ****************************************************************/
6647 NTSTATUS _samr_RidToSid(pipes_struct *p,
6648 struct samr_RidToSid *r)
6650 p->rng_fault_state = true;
6651 return NT_STATUS_NOT_IMPLEMENTED;
6654 /****************************************************************
6655 ****************************************************************/
6657 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6658 struct samr_SetDsrmPassword *r)
6660 p->rng_fault_state = true;
6661 return NT_STATUS_NOT_IMPLEMENTED;
6664 /****************************************************************
6665 ****************************************************************/
6667 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6668 struct samr_ValidatePassword *r)
6670 p->rng_fault_state = true;
6671 return NT_STATUS_NOT_IMPLEMENTED;