s3-samr-server: fix access check in _samr_QuerySecurity().
[Samba.git] / source / rpc_server / srv_samr_nt.c
blob985dd58262fcbe2cd5821f6b3dfeec406e79a597
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 SA_RIGHT_USER_CHANGE_PASSWORD | \
42 SA_RIGHT_USER_SET_LOC_COM )
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 typedef struct disp_info {
49 DOM_SID sid; /* identify which domain this is. */
50 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
51 struct pdb_search *users; /* querydispinfo 1 and 4 */
52 struct pdb_search *machines; /* querydispinfo 2 */
53 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
54 struct pdb_search *aliases; /* enumaliases */
56 uint16 enum_acb_mask;
57 struct pdb_search *enum_users; /* enumusers with a mask */
59 struct timed_event *cache_timeout_event; /* cache idle timeout
60 * handler. */
61 } DISP_INFO;
63 /* We keep a static list of these by SID as modern clients close down
64 all resources between each request in a complete enumeration. */
66 struct samr_info {
67 /* for use by the \PIPE\samr policy */
68 DOM_SID sid;
69 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
70 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
71 uint32 acc_granted;
72 DISP_INFO *disp_info;
73 TALLOC_CTX *mem_ctx;
76 static const struct generic_mapping sam_generic_mapping = {
77 GENERIC_RIGHTS_SAM_READ,
78 GENERIC_RIGHTS_SAM_WRITE,
79 GENERIC_RIGHTS_SAM_EXECUTE,
80 GENERIC_RIGHTS_SAM_ALL_ACCESS};
81 static const struct generic_mapping dom_generic_mapping = {
82 GENERIC_RIGHTS_DOMAIN_READ,
83 GENERIC_RIGHTS_DOMAIN_WRITE,
84 GENERIC_RIGHTS_DOMAIN_EXECUTE,
85 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
86 static const struct generic_mapping usr_generic_mapping = {
87 GENERIC_RIGHTS_USER_READ,
88 GENERIC_RIGHTS_USER_WRITE,
89 GENERIC_RIGHTS_USER_EXECUTE,
90 GENERIC_RIGHTS_USER_ALL_ACCESS};
91 static const struct generic_mapping usr_nopwchange_generic_mapping = {
92 GENERIC_RIGHTS_USER_READ,
93 GENERIC_RIGHTS_USER_WRITE,
94 GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
95 GENERIC_RIGHTS_USER_ALL_ACCESS};
96 static const struct generic_mapping grp_generic_mapping = {
97 GENERIC_RIGHTS_GROUP_READ,
98 GENERIC_RIGHTS_GROUP_WRITE,
99 GENERIC_RIGHTS_GROUP_EXECUTE,
100 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
101 static const struct generic_mapping ali_generic_mapping = {
102 GENERIC_RIGHTS_ALIAS_READ,
103 GENERIC_RIGHTS_ALIAS_WRITE,
104 GENERIC_RIGHTS_ALIAS_EXECUTE,
105 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
107 /*******************************************************************
108 *******************************************************************/
110 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
111 const struct generic_mapping *map,
112 DOM_SID *sid, uint32 sid_access )
114 DOM_SID domadmin_sid;
115 SEC_ACE ace[5]; /* at most 5 entries */
116 SEC_ACCESS mask;
117 size_t i = 0;
119 SEC_ACL *psa = NULL;
121 /* basic access for Everyone */
123 init_sec_access(&mask, map->generic_execute | map->generic_read );
124 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
126 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
128 init_sec_access(&mask, map->generic_all);
130 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
131 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
133 /* Add Full Access for Domain Admins if we are a DC */
135 if ( IS_DC ) {
136 sid_copy( &domadmin_sid, get_global_sam_sid() );
137 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
138 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
141 /* if we have a sid, give it some special access */
143 if ( sid ) {
144 init_sec_access( &mask, sid_access );
145 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
148 /* create the security descriptor */
150 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
151 return NT_STATUS_NO_MEMORY;
153 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
154 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
155 psa, sd_size)) == NULL)
156 return NT_STATUS_NO_MEMORY;
158 return NT_STATUS_OK;
161 /*******************************************************************
162 Checks if access to an object should be granted, and returns that
163 level of access for further checks.
164 ********************************************************************/
166 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
167 SE_PRIV *rights, uint32 rights_mask,
168 uint32 des_access, uint32 *acc_granted,
169 const char *debug )
171 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
172 uint32 saved_mask = 0;
174 /* check privileges; certain SAM access bits should be overridden
175 by privileges (mostly having to do with creating/modifying/deleting
176 users and groups) */
178 if ( rights && user_has_any_privilege( token, rights ) ) {
180 saved_mask = (des_access & rights_mask);
181 des_access &= ~saved_mask;
183 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
184 rights_mask));
188 /* check the security descriptor first */
190 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
191 goto done;
193 /* give root a free pass */
195 if ( geteuid() == sec_initial_uid() ) {
197 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
198 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
200 *acc_granted = des_access;
202 status = NT_STATUS_OK;
203 goto done;
207 done:
208 /* add in any bits saved during the privilege check (only
209 matters is status is ok) */
211 *acc_granted |= rights_mask;
213 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
214 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
215 des_access, *acc_granted));
217 return status;
220 /*******************************************************************
221 Checks if access to a function can be granted
222 ********************************************************************/
224 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
226 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
227 debug, acc_granted, acc_required));
229 /* check the security descriptor first */
231 if ( (acc_granted&acc_required) == acc_required )
232 return NT_STATUS_OK;
234 /* give root a free pass */
236 if (geteuid() == sec_initial_uid()) {
238 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
239 debug, acc_granted, acc_required));
240 DEBUGADD(4,("but overwritten by euid == 0\n"));
242 return NT_STATUS_OK;
245 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
246 debug, acc_granted, acc_required));
248 return NT_STATUS_ACCESS_DENIED;
251 /*******************************************************************
252 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
253 ********************************************************************/
255 static void map_max_allowed_access(const NT_USER_TOKEN *token,
256 uint32_t *pacc_requested)
258 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
259 return;
261 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
263 /* At least try for generic read. */
264 *pacc_requested = GENERIC_READ_ACCESS;
266 /* root gets anything. */
267 if (geteuid() == sec_initial_uid()) {
268 *pacc_requested |= GENERIC_ALL_ACCESS;
269 return;
272 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
274 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
275 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
276 *pacc_requested |= GENERIC_ALL_ACCESS;
277 return;
280 /* Full access for DOMAIN\Domain Admins. */
281 if ( IS_DC ) {
282 DOM_SID domadmin_sid;
283 sid_copy( &domadmin_sid, get_global_sam_sid() );
284 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
285 if (is_sid_in_token(token, &domadmin_sid)) {
286 *pacc_requested |= GENERIC_ALL_ACCESS;
287 return;
290 /* TODO ! Check privileges. */
293 /*******************************************************************
294 Fetch or create a dispinfo struct.
295 ********************************************************************/
297 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
300 * We do a static cache for DISP_INFO's here. Explanation can be found
301 * in Jeremy's checkin message to r11793:
303 * Fix the SAMR cache so it works across completely insane
304 * client behaviour (ie.:
305 * open pipe/open SAMR handle/enumerate 0 - 1024
306 * close SAMR handle, close pipe.
307 * open pipe/open SAMR handle/enumerate 1024 - 2048...
308 * close SAMR handle, close pipe.
309 * And on ad-nausium. Amazing.... probably object-oriented
310 * client side programming in action yet again.
311 * This change should *massively* improve performance when
312 * enumerating users from an LDAP database.
313 * Jeremy.
315 * "Our" and the builtin domain are the only ones where we ever
316 * enumerate stuff, so just cache 2 entries.
319 static struct disp_info builtin_dispinfo;
320 static struct disp_info domain_dispinfo;
322 /* There are two cases to consider here:
323 1) The SID is a domain SID and we look for an equality match, or
324 2) This is an account SID and so we return the DISP_INFO* for our
325 domain */
327 if (psid == NULL) {
328 return NULL;
331 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
333 * Necessary only once, but it does not really hurt.
335 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
337 return &builtin_dispinfo;
340 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
342 * Necessary only once, but it does not really hurt.
344 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
346 return &domain_dispinfo;
349 return NULL;
352 /*******************************************************************
353 Create a samr_info struct.
354 ********************************************************************/
356 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
358 struct samr_info *info;
359 fstring sid_str;
360 TALLOC_CTX *mem_ctx;
362 if (psid) {
363 sid_to_fstring(sid_str, psid);
364 } else {
365 fstrcpy(sid_str,"(NULL)");
368 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
370 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
371 return NULL;
373 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
374 if (psid) {
375 sid_copy( &info->sid, psid);
376 info->builtin_domain = sid_check_is_builtin(psid);
377 } else {
378 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
379 info->builtin_domain = False;
381 info->mem_ctx = mem_ctx;
383 info->disp_info = get_samr_dispinfo_by_sid(psid);
385 return info;
388 /*******************************************************************
389 Function to free the per SID data.
390 ********************************************************************/
392 static void free_samr_cache(DISP_INFO *disp_info)
394 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
395 sid_string_dbg(&disp_info->sid)));
397 /* We need to become root here because the paged search might have to
398 * tell the LDAP server we're not interested in the rest anymore. */
400 become_root();
402 if (disp_info->users) {
403 DEBUG(10,("free_samr_cache: deleting users cache\n"));
404 pdb_search_destroy(disp_info->users);
405 disp_info->users = NULL;
407 if (disp_info->machines) {
408 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
409 pdb_search_destroy(disp_info->machines);
410 disp_info->machines = NULL;
412 if (disp_info->groups) {
413 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
414 pdb_search_destroy(disp_info->groups);
415 disp_info->groups = NULL;
417 if (disp_info->aliases) {
418 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
419 pdb_search_destroy(disp_info->aliases);
420 disp_info->aliases = NULL;
422 if (disp_info->enum_users) {
423 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
424 pdb_search_destroy(disp_info->enum_users);
425 disp_info->enum_users = NULL;
427 disp_info->enum_acb_mask = 0;
429 unbecome_root();
432 /*******************************************************************
433 Function to free the per handle data.
434 ********************************************************************/
436 static void free_samr_info(void *ptr)
438 struct samr_info *info=(struct samr_info *) ptr;
440 /* Only free the dispinfo cache if no one bothered to set up
441 a timeout. */
443 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
444 free_samr_cache(info->disp_info);
447 talloc_destroy(info->mem_ctx);
450 /*******************************************************************
451 Idle event handler. Throw away the disp info cache.
452 ********************************************************************/
454 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
455 struct timed_event *te,
456 const struct timeval *now,
457 void *private_data)
459 DISP_INFO *disp_info = (DISP_INFO *)private_data;
461 TALLOC_FREE(disp_info->cache_timeout_event);
463 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
464 "out\n"));
465 free_samr_cache(disp_info);
468 /*******************************************************************
469 Setup cache removal idle event handler.
470 ********************************************************************/
472 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
474 /* Remove any pending timeout and update. */
476 TALLOC_FREE(disp_info->cache_timeout_event);
478 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
479 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
480 (unsigned int)secs_fromnow ));
482 disp_info->cache_timeout_event = event_add_timed(
483 smbd_event_context(), NULL,
484 timeval_current_ofs(secs_fromnow, 0),
485 "disp_info_cache_idle_timeout_handler",
486 disp_info_cache_idle_timeout_handler, (void *)disp_info);
489 /*******************************************************************
490 Force flush any cache. We do this on any samr_set_xxx call.
491 We must also remove the timeout handler.
492 ********************************************************************/
494 static void force_flush_samr_cache(DISP_INFO *disp_info)
496 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
497 return;
500 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
501 TALLOC_FREE(disp_info->cache_timeout_event);
502 free_samr_cache(disp_info);
505 /*******************************************************************
506 Ensure password info is never given out. Paranioa... JRA.
507 ********************************************************************/
509 static void samr_clear_sam_passwd(struct samu *sam_pass)
512 if (!sam_pass)
513 return;
515 /* These now zero out the old password */
517 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
518 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
521 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
523 struct samr_displayentry *entry;
525 if (info->builtin_domain) {
526 /* No users in builtin. */
527 return 0;
530 if (info->users == NULL) {
531 info->users = pdb_search_users(acct_flags);
532 if (info->users == NULL) {
533 return 0;
536 /* Fetch the last possible entry, thus trigger an enumeration */
537 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
539 /* Ensure we cache this enumeration. */
540 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
542 return info->users->num_entries;
545 static uint32 count_sam_groups(struct disp_info *info)
547 struct samr_displayentry *entry;
549 if (info->builtin_domain) {
550 /* No groups in builtin. */
551 return 0;
554 if (info->groups == NULL) {
555 info->groups = pdb_search_groups();
556 if (info->groups == NULL) {
557 return 0;
560 /* Fetch the last possible entry, thus trigger an enumeration */
561 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
563 /* Ensure we cache this enumeration. */
564 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
566 return info->groups->num_entries;
569 static uint32 count_sam_aliases(struct disp_info *info)
571 struct samr_displayentry *entry;
573 if (info->aliases == NULL) {
574 info->aliases = pdb_search_aliases(&info->sid);
575 if (info->aliases == NULL) {
576 return 0;
579 /* Fetch the last possible entry, thus trigger an enumeration */
580 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
582 /* Ensure we cache this enumeration. */
583 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
585 return info->aliases->num_entries;
588 /*******************************************************************
589 _samr_Close
590 ********************************************************************/
592 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
594 if (!close_policy_hnd(p, r->in.handle)) {
595 return NT_STATUS_INVALID_HANDLE;
598 ZERO_STRUCTP(r->out.handle);
600 return NT_STATUS_OK;
603 /*******************************************************************
604 _samr_OpenDomain
605 ********************************************************************/
607 NTSTATUS _samr_OpenDomain(pipes_struct *p,
608 struct samr_OpenDomain *r)
610 struct samr_info *info;
611 SEC_DESC *psd = NULL;
612 uint32 acc_granted;
613 uint32 des_access = r->in.access_mask;
614 NTSTATUS status;
615 size_t sd_size;
616 SE_PRIV se_rights;
618 /* find the connection policy handle. */
620 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
621 return NT_STATUS_INVALID_HANDLE;
623 status = access_check_samr_function(info->acc_granted,
624 SA_RIGHT_SAM_OPEN_DOMAIN,
625 "_samr_OpenDomain" );
627 if ( !NT_STATUS_IS_OK(status) )
628 return status;
630 /*check if access can be granted as requested by client. */
631 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
633 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
634 se_map_generic( &des_access, &dom_generic_mapping );
636 se_priv_copy( &se_rights, &se_machine_account );
637 se_priv_add( &se_rights, &se_add_users );
639 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
640 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
641 &acc_granted, "_samr_OpenDomain" );
643 if ( !NT_STATUS_IS_OK(status) )
644 return status;
646 if (!sid_check_is_domain(r->in.sid) &&
647 !sid_check_is_builtin(r->in.sid)) {
648 return NT_STATUS_NO_SUCH_DOMAIN;
651 /* associate the domain SID with the (unique) handle. */
652 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
653 return NT_STATUS_NO_MEMORY;
654 info->acc_granted = acc_granted;
656 /* get a (unique) handle. open a policy on it. */
657 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
658 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
660 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
662 return NT_STATUS_OK;
665 /*******************************************************************
666 _samr_GetUserPwInfo
667 ********************************************************************/
669 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
670 struct samr_GetUserPwInfo *r)
672 struct samr_info *info = NULL;
673 enum lsa_SidType sid_type;
674 uint32_t min_password_length = 0;
675 uint32_t password_properties = 0;
676 bool ret = false;
677 NTSTATUS status;
679 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
681 /* find the policy handle. open a policy on it. */
682 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
683 return NT_STATUS_INVALID_HANDLE;
686 status = access_check_samr_function(info->acc_granted,
687 SAMR_USER_ACCESS_GET_ATTRIBUTES,
688 "_samr_GetUserPwInfo" );
689 if (!NT_STATUS_IS_OK(status)) {
690 return status;
693 if (!sid_check_is_in_our_domain(&info->sid)) {
694 return NT_STATUS_OBJECT_TYPE_MISMATCH;
697 become_root();
698 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
699 unbecome_root();
700 if (ret == false) {
701 return NT_STATUS_NO_SUCH_USER;
704 switch (sid_type) {
705 case SID_NAME_USER:
706 become_root();
707 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
708 &min_password_length);
709 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
710 &password_properties);
711 unbecome_root();
713 if (lp_check_password_script() && *lp_check_password_script()) {
714 password_properties |= DOMAIN_PASSWORD_COMPLEX;
717 break;
718 default:
719 break;
722 r->out.info->min_password_length = min_password_length;
723 r->out.info->password_properties = password_properties;
725 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
727 return NT_STATUS_OK;
730 /*******************************************************************
731 ********************************************************************/
733 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
734 DOM_SID *sid, uint32 *acc_granted,
735 DISP_INFO **ppdisp_info)
737 struct samr_info *info = NULL;
739 /* find the policy handle. open a policy on it. */
740 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
741 return False;
743 if (!info)
744 return False;
746 *sid = info->sid;
747 *acc_granted = info->acc_granted;
748 if (ppdisp_info) {
749 *ppdisp_info = info->disp_info;
752 return True;
755 /*******************************************************************
756 _samr_SetSecurity
757 ********************************************************************/
759 NTSTATUS _samr_SetSecurity(pipes_struct *p,
760 struct samr_SetSecurity *r)
762 DOM_SID pol_sid;
763 uint32 acc_granted, i;
764 SEC_ACL *dacl;
765 bool ret;
766 struct samu *sampass=NULL;
767 NTSTATUS status;
769 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
770 return NT_STATUS_INVALID_HANDLE;
772 if (!(sampass = samu_new( p->mem_ctx))) {
773 DEBUG(0,("No memory!\n"));
774 return NT_STATUS_NO_MEMORY;
777 /* get the user record */
778 become_root();
779 ret = pdb_getsampwsid(sampass, &pol_sid);
780 unbecome_root();
782 if (!ret) {
783 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
784 TALLOC_FREE(sampass);
785 return NT_STATUS_INVALID_HANDLE;
788 dacl = r->in.sdbuf->sd->dacl;
789 for (i=0; i < dacl->num_aces; i++) {
790 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
791 ret = pdb_set_pass_can_change(sampass,
792 (dacl->aces[i].access_mask &
793 SA_RIGHT_USER_CHANGE_PASSWORD) ?
794 True: False);
795 break;
799 if (!ret) {
800 TALLOC_FREE(sampass);
801 return NT_STATUS_ACCESS_DENIED;
804 status = access_check_samr_function(acc_granted,
805 SA_RIGHT_USER_SET_ATTRIBUTES,
806 "_samr_SetSecurity");
807 if (NT_STATUS_IS_OK(status)) {
808 become_root();
809 status = pdb_update_sam_account(sampass);
810 unbecome_root();
813 TALLOC_FREE(sampass);
815 return status;
818 /*******************************************************************
819 build correct perms based on policies and password times for _samr_query_sec_obj
820 *******************************************************************/
821 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
823 struct samu *sampass=NULL;
824 bool ret;
826 if ( !(sampass = samu_new( mem_ctx )) ) {
827 DEBUG(0,("No memory!\n"));
828 return False;
831 become_root();
832 ret = pdb_getsampwsid(sampass, user_sid);
833 unbecome_root();
835 if (ret == False) {
836 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
837 TALLOC_FREE(sampass);
838 return False;
841 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
843 if (pdb_get_pass_can_change(sampass)) {
844 TALLOC_FREE(sampass);
845 return True;
847 TALLOC_FREE(sampass);
848 return False;
852 /*******************************************************************
853 _samr_QuerySecurity
854 ********************************************************************/
856 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
857 struct samr_QuerySecurity *r)
859 NTSTATUS status;
860 DOM_SID pol_sid;
861 SEC_DESC * psd = NULL;
862 uint32 acc_granted;
863 size_t sd_size;
865 /* Get the SID. */
866 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
867 return NT_STATUS_INVALID_HANDLE;
869 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
870 sid_string_dbg(&pol_sid)));
872 status = access_check_samr_function(acc_granted,
873 STD_RIGHT_READ_CONTROL_ACCESS,
874 "_samr_QuerySecurity");
875 if (!NT_STATUS_IS_OK(status)) {
876 return status;
879 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
881 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
882 if (pol_sid.sid_rev_num == 0) {
883 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
884 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
885 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
886 /* check if it is our domain SID */
887 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
888 "with SID: %s\n", sid_string_dbg(&pol_sid)));
889 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
890 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
891 /* check if it is the Builtin Domain */
892 /* TODO: Builtin probably needs a different SD with restricted write access*/
893 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
894 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
895 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
896 } else if (sid_check_is_in_our_domain(&pol_sid) ||
897 sid_check_is_in_builtin(&pol_sid)) {
898 /* TODO: different SDs have to be generated for aliases groups and users.
899 Currently all three get a default user SD */
900 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
901 "with SID: %s\n", sid_string_dbg(&pol_sid)));
902 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
903 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
904 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
905 } else {
906 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
907 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
909 } else {
910 return NT_STATUS_OBJECT_TYPE_MISMATCH;
913 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
914 return NT_STATUS_NO_MEMORY;
916 return status;
919 /*******************************************************************
920 makes a SAM_ENTRY / UNISTR2* structure from a user list.
921 ********************************************************************/
923 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
924 struct samr_SamEntry **sam_pp,
925 uint32_t num_entries,
926 uint32_t start_idx,
927 struct samr_displayentry *entries)
929 uint32_t i;
930 struct samr_SamEntry *sam;
932 *sam_pp = NULL;
934 if (num_entries == 0) {
935 return NT_STATUS_OK;
938 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
939 if (sam == NULL) {
940 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
941 return NT_STATUS_NO_MEMORY;
944 for (i = 0; i < num_entries; i++) {
945 #if 0
947 * usrmgr expects a non-NULL terminated string with
948 * trust relationships
950 if (entries[i].acct_flags & ACB_DOMTRUST) {
951 init_unistr2(&uni_temp_name, entries[i].account_name,
952 UNI_FLAGS_NONE);
953 } else {
954 init_unistr2(&uni_temp_name, entries[i].account_name,
955 UNI_STR_TERMINATE);
957 #endif
958 init_lsa_String(&sam[i].name, entries[i].account_name);
959 sam[i].idx = entries[i].rid;
962 *sam_pp = sam;
964 return NT_STATUS_OK;
967 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
969 /*******************************************************************
970 _samr_EnumDomainUsers
971 ********************************************************************/
973 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
974 struct samr_EnumDomainUsers *r)
976 NTSTATUS status;
977 struct samr_info *info = NULL;
978 int num_account;
979 uint32 enum_context = *r->in.resume_handle;
980 enum remote_arch_types ra_type = get_remote_arch();
981 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
982 uint32 max_entries = max_sam_entries;
983 struct samr_displayentry *entries = NULL;
984 struct samr_SamArray *samr_array = NULL;
985 struct samr_SamEntry *samr_entries = NULL;
987 /* find the policy handle. open a policy on it. */
988 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
989 return NT_STATUS_INVALID_HANDLE;
991 status = access_check_samr_function(info->acc_granted,
992 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
993 "_samr_EnumDomainUsers");
994 if (!NT_STATUS_IS_OK(status)) {
995 return status;
998 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1000 if (info->builtin_domain) {
1001 /* No users in builtin. */
1002 *r->out.resume_handle = *r->in.resume_handle;
1003 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
1004 return status;
1007 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1008 if (!samr_array) {
1009 return NT_STATUS_NO_MEMORY;
1012 become_root();
1014 /* AS ROOT !!!! */
1016 if ((info->disp_info->enum_users != NULL) &&
1017 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1018 pdb_search_destroy(info->disp_info->enum_users);
1019 info->disp_info->enum_users = NULL;
1022 if (info->disp_info->enum_users == NULL) {
1023 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
1024 info->disp_info->enum_acb_mask = r->in.acct_flags;
1027 if (info->disp_info->enum_users == NULL) {
1028 /* END AS ROOT !!!! */
1029 unbecome_root();
1030 return NT_STATUS_ACCESS_DENIED;
1033 num_account = pdb_search_entries(info->disp_info->enum_users,
1034 enum_context, max_entries,
1035 &entries);
1037 /* END AS ROOT !!!! */
1039 unbecome_root();
1041 if (num_account == 0) {
1042 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1043 "total entries\n"));
1044 *r->out.resume_handle = *r->in.resume_handle;
1045 return NT_STATUS_OK;
1048 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1049 num_account, enum_context,
1050 entries);
1051 if (!NT_STATUS_IS_OK(status)) {
1052 return status;
1055 if (max_entries <= num_account) {
1056 status = STATUS_MORE_ENTRIES;
1057 } else {
1058 status = NT_STATUS_OK;
1061 /* Ensure we cache this enumeration. */
1062 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1064 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1066 samr_array->count = num_account;
1067 samr_array->entries = samr_entries;
1069 *r->out.resume_handle = *r->in.resume_handle + num_account;
1070 *r->out.sam = samr_array;
1071 *r->out.num_entries = num_account;
1073 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1075 return status;
1078 /*******************************************************************
1079 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1080 ********************************************************************/
1082 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1083 struct samr_SamEntry **sam_pp,
1084 uint32_t num_sam_entries,
1085 struct samr_displayentry *entries)
1087 struct samr_SamEntry *sam;
1088 uint32_t i;
1090 *sam_pp = NULL;
1092 if (num_sam_entries == 0) {
1093 return;
1096 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1097 if (sam == NULL) {
1098 return;
1101 for (i = 0; i < num_sam_entries; i++) {
1103 * JRA. I think this should include the null. TNG does not.
1105 init_lsa_String(&sam[i].name, entries[i].account_name);
1106 sam[i].idx = entries[i].rid;
1109 *sam_pp = sam;
1112 /*******************************************************************
1113 _samr_EnumDomainGroups
1114 ********************************************************************/
1116 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1117 struct samr_EnumDomainGroups *r)
1119 NTSTATUS status;
1120 struct samr_info *info = NULL;
1121 struct samr_displayentry *groups;
1122 uint32 num_groups;
1123 struct samr_SamArray *samr_array = NULL;
1124 struct samr_SamEntry *samr_entries = NULL;
1126 /* find the policy handle. open a policy on it. */
1127 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1128 return NT_STATUS_INVALID_HANDLE;
1130 status = access_check_samr_function(info->acc_granted,
1131 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1132 "_samr_EnumDomainGroups");
1133 if (!NT_STATUS_IS_OK(status)) {
1134 return status;
1137 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1139 if (info->builtin_domain) {
1140 /* No groups in builtin. */
1141 *r->out.resume_handle = *r->in.resume_handle;
1142 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1143 return status;
1146 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1147 if (!samr_array) {
1148 return NT_STATUS_NO_MEMORY;
1151 /* the domain group array is being allocated in the function below */
1153 become_root();
1155 if (info->disp_info->groups == NULL) {
1156 info->disp_info->groups = pdb_search_groups();
1158 if (info->disp_info->groups == NULL) {
1159 unbecome_root();
1160 return NT_STATUS_ACCESS_DENIED;
1164 num_groups = pdb_search_entries(info->disp_info->groups,
1165 *r->in.resume_handle,
1166 MAX_SAM_ENTRIES, &groups);
1167 unbecome_root();
1169 /* Ensure we cache this enumeration. */
1170 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1172 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1173 num_groups, groups);
1175 samr_array->count = num_groups;
1176 samr_array->entries = samr_entries;
1178 *r->out.sam = samr_array;
1179 *r->out.num_entries = num_groups;
1180 /* this was missing, IMHO:
1181 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1184 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1186 return status;
1189 /*******************************************************************
1190 _samr_EnumDomainAliases
1191 ********************************************************************/
1193 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1194 struct samr_EnumDomainAliases *r)
1196 NTSTATUS status;
1197 struct samr_info *info;
1198 struct samr_displayentry *aliases;
1199 uint32 num_aliases = 0;
1200 struct samr_SamArray *samr_array = NULL;
1201 struct samr_SamEntry *samr_entries = NULL;
1203 /* find the policy handle. open a policy on it. */
1204 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1205 return NT_STATUS_INVALID_HANDLE;
1207 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1208 sid_string_dbg(&info->sid)));
1210 status = access_check_samr_function(info->acc_granted,
1211 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1212 "_samr_EnumDomainAliases");
1213 if (!NT_STATUS_IS_OK(status)) {
1214 return status;
1217 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1218 if (!samr_array) {
1219 return NT_STATUS_NO_MEMORY;
1222 become_root();
1224 if (info->disp_info->aliases == NULL) {
1225 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1226 if (info->disp_info->aliases == NULL) {
1227 unbecome_root();
1228 return NT_STATUS_ACCESS_DENIED;
1232 num_aliases = pdb_search_entries(info->disp_info->aliases,
1233 *r->in.resume_handle,
1234 MAX_SAM_ENTRIES, &aliases);
1235 unbecome_root();
1237 /* Ensure we cache this enumeration. */
1238 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1240 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1241 num_aliases, aliases);
1243 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1245 samr_array->count = num_aliases;
1246 samr_array->entries = samr_entries;
1248 *r->out.sam = samr_array;
1249 *r->out.num_entries = num_aliases;
1250 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1252 return status;
1255 /*******************************************************************
1256 inits a samr_DispInfoGeneral structure.
1257 ********************************************************************/
1259 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1260 struct samr_DispInfoGeneral *r,
1261 uint32_t num_entries,
1262 uint32_t start_idx,
1263 struct samr_displayentry *entries)
1265 uint32 i;
1267 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1269 if (num_entries == 0) {
1270 return NT_STATUS_OK;
1273 r->count = num_entries;
1275 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1276 if (!r->entries) {
1277 return NT_STATUS_NO_MEMORY;
1280 for (i = 0; i < num_entries ; i++) {
1282 init_lsa_String(&r->entries[i].account_name,
1283 entries[i].account_name);
1285 init_lsa_String(&r->entries[i].description,
1286 entries[i].description);
1288 init_lsa_String(&r->entries[i].full_name,
1289 entries[i].fullname);
1291 r->entries[i].rid = entries[i].rid;
1292 r->entries[i].acct_flags = entries[i].acct_flags;
1293 r->entries[i].idx = start_idx+i+1;
1296 return NT_STATUS_OK;
1299 /*******************************************************************
1300 inits a samr_DispInfoFull structure.
1301 ********************************************************************/
1303 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1304 struct samr_DispInfoFull *r,
1305 uint32_t num_entries,
1306 uint32_t start_idx,
1307 struct samr_displayentry *entries)
1309 uint32_t i;
1311 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1313 if (num_entries == 0) {
1314 return NT_STATUS_OK;
1317 r->count = num_entries;
1319 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1320 if (!r->entries) {
1321 return NT_STATUS_NO_MEMORY;
1324 for (i = 0; i < num_entries ; i++) {
1326 init_lsa_String(&r->entries[i].account_name,
1327 entries[i].account_name);
1329 init_lsa_String(&r->entries[i].description,
1330 entries[i].description);
1332 r->entries[i].rid = entries[i].rid;
1333 r->entries[i].acct_flags = entries[i].acct_flags;
1334 r->entries[i].idx = start_idx+i+1;
1337 return NT_STATUS_OK;
1340 /*******************************************************************
1341 inits a samr_DispInfoFullGroups structure.
1342 ********************************************************************/
1344 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1345 struct samr_DispInfoFullGroups *r,
1346 uint32_t num_entries,
1347 uint32_t start_idx,
1348 struct samr_displayentry *entries)
1350 uint32_t i;
1352 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1354 if (num_entries == 0) {
1355 return NT_STATUS_OK;
1358 r->count = num_entries;
1360 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1361 if (!r->entries) {
1362 return NT_STATUS_NO_MEMORY;
1365 for (i = 0; i < num_entries ; i++) {
1367 init_lsa_String(&r->entries[i].account_name,
1368 entries[i].account_name);
1370 init_lsa_String(&r->entries[i].description,
1371 entries[i].description);
1373 r->entries[i].rid = entries[i].rid;
1374 r->entries[i].acct_flags = entries[i].acct_flags;
1375 r->entries[i].idx = start_idx+i+1;
1378 return NT_STATUS_OK;
1381 /*******************************************************************
1382 inits a samr_DispInfoAscii structure.
1383 ********************************************************************/
1385 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1386 struct samr_DispInfoAscii *r,
1387 uint32_t num_entries,
1388 uint32_t start_idx,
1389 struct samr_displayentry *entries)
1391 uint32_t i;
1393 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1395 if (num_entries == 0) {
1396 return NT_STATUS_OK;
1399 r->count = num_entries;
1401 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1402 if (!r->entries) {
1403 return NT_STATUS_NO_MEMORY;
1406 for (i = 0; i < num_entries ; i++) {
1408 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1409 entries[i].account_name);
1411 r->entries[i].idx = start_idx+i+1;
1414 return NT_STATUS_OK;
1417 /*******************************************************************
1418 inits a samr_DispInfoAscii structure.
1419 ********************************************************************/
1421 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1422 struct samr_DispInfoAscii *r,
1423 uint32_t num_entries,
1424 uint32_t start_idx,
1425 struct samr_displayentry *entries)
1427 uint32_t i;
1429 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1431 if (num_entries == 0) {
1432 return NT_STATUS_OK;
1435 r->count = num_entries;
1437 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1438 if (!r->entries) {
1439 return NT_STATUS_NO_MEMORY;
1442 for (i = 0; i < num_entries ; i++) {
1444 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1445 entries[i].account_name);
1447 r->entries[i].idx = start_idx+i+1;
1450 return NT_STATUS_OK;
1453 /*******************************************************************
1454 _samr_QueryDisplayInfo
1455 ********************************************************************/
1457 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1458 struct samr_QueryDisplayInfo *r)
1460 NTSTATUS status;
1461 struct samr_info *info = NULL;
1462 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1464 uint32 max_entries = r->in.max_entries;
1465 uint32 enum_context = r->in.start_idx;
1466 uint32 max_size = r->in.buf_size;
1468 union samr_DispInfo *disp_info = r->out.info;
1470 uint32 temp_size=0, total_data_size=0;
1471 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1472 uint32 num_account = 0;
1473 enum remote_arch_types ra_type = get_remote_arch();
1474 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1475 struct samr_displayentry *entries = NULL;
1477 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1479 /* find the policy handle. open a policy on it. */
1480 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1481 return NT_STATUS_INVALID_HANDLE;
1483 status = access_check_samr_function(info->acc_granted,
1484 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1485 "_samr_QueryDisplayInfo");
1486 if (!NT_STATUS_IS_OK(status)) {
1487 return status;
1491 * calculate how many entries we will return.
1492 * based on
1493 * - the number of entries the client asked
1494 * - our limit on that
1495 * - the starting point (enumeration context)
1496 * - the buffer size the client will accept
1500 * We are a lot more like W2K. Instead of reading the SAM
1501 * each time to find the records we need to send back,
1502 * we read it once and link that copy to the sam handle.
1503 * For large user list (over the MAX_SAM_ENTRIES)
1504 * it's a definitive win.
1505 * second point to notice: between enumerations
1506 * our sam is now the same as it's a snapshoot.
1507 * third point: got rid of the static SAM_USER_21 struct
1508 * no more intermediate.
1509 * con: it uses much more memory, as a full copy is stored
1510 * in memory.
1512 * If you want to change it, think twice and think
1513 * of the second point , that's really important.
1515 * JFM, 12/20/2001
1518 if ((r->in.level < 1) || (r->in.level > 5)) {
1519 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1520 (unsigned int)r->in.level ));
1521 return NT_STATUS_INVALID_INFO_CLASS;
1524 /* first limit the number of entries we will return */
1525 if(max_entries > max_sam_entries) {
1526 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1527 "entries, limiting to %d\n", max_entries,
1528 max_sam_entries));
1529 max_entries = max_sam_entries;
1532 /* calculate the size and limit on the number of entries we will
1533 * return */
1535 temp_size=max_entries*struct_size;
1537 if (temp_size>max_size) {
1538 max_entries=MIN((max_size/struct_size),max_entries);;
1539 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1540 "only %d entries\n", max_entries));
1543 become_root();
1545 /* THe following done as ROOT. Don't return without unbecome_root(). */
1547 switch (r->in.level) {
1548 case 0x1:
1549 case 0x4:
1550 if (info->disp_info->users == NULL) {
1551 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1552 if (info->disp_info->users == NULL) {
1553 unbecome_root();
1554 return NT_STATUS_ACCESS_DENIED;
1556 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1557 (unsigned int)enum_context ));
1558 } else {
1559 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1560 (unsigned int)enum_context ));
1563 num_account = pdb_search_entries(info->disp_info->users,
1564 enum_context, max_entries,
1565 &entries);
1566 break;
1567 case 0x2:
1568 if (info->disp_info->machines == NULL) {
1569 info->disp_info->machines =
1570 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1571 if (info->disp_info->machines == NULL) {
1572 unbecome_root();
1573 return NT_STATUS_ACCESS_DENIED;
1575 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1576 (unsigned int)enum_context ));
1577 } else {
1578 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1579 (unsigned int)enum_context ));
1582 num_account = pdb_search_entries(info->disp_info->machines,
1583 enum_context, max_entries,
1584 &entries);
1585 break;
1586 case 0x3:
1587 case 0x5:
1588 if (info->disp_info->groups == NULL) {
1589 info->disp_info->groups = pdb_search_groups();
1590 if (info->disp_info->groups == NULL) {
1591 unbecome_root();
1592 return NT_STATUS_ACCESS_DENIED;
1594 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1595 (unsigned int)enum_context ));
1596 } else {
1597 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1598 (unsigned int)enum_context ));
1601 num_account = pdb_search_entries(info->disp_info->groups,
1602 enum_context, max_entries,
1603 &entries);
1604 break;
1605 default:
1606 unbecome_root();
1607 smb_panic("info class changed");
1608 break;
1610 unbecome_root();
1613 /* Now create reply structure */
1614 switch (r->in.level) {
1615 case 0x1:
1616 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1617 num_account, enum_context,
1618 entries);
1619 break;
1620 case 0x2:
1621 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1622 num_account, enum_context,
1623 entries);
1624 break;
1625 case 0x3:
1626 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1627 num_account, enum_context,
1628 entries);
1629 break;
1630 case 0x4:
1631 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1632 num_account, enum_context,
1633 entries);
1634 break;
1635 case 0x5:
1636 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1637 num_account, enum_context,
1638 entries);
1639 break;
1640 default:
1641 smb_panic("info class changed");
1642 break;
1645 if (!NT_STATUS_IS_OK(disp_ret))
1646 return disp_ret;
1648 /* calculate the total size */
1649 total_data_size=num_account*struct_size;
1651 if (num_account) {
1652 status = STATUS_MORE_ENTRIES;
1653 } else {
1654 status = NT_STATUS_OK;
1657 /* Ensure we cache this enumeration. */
1658 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1660 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1662 *r->out.total_size = total_data_size;
1663 *r->out.returned_size = temp_size;
1665 return status;
1668 /****************************************************************
1669 _samr_QueryDisplayInfo2
1670 ****************************************************************/
1672 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1673 struct samr_QueryDisplayInfo2 *r)
1675 struct samr_QueryDisplayInfo q;
1677 q.in.domain_handle = r->in.domain_handle;
1678 q.in.level = r->in.level;
1679 q.in.start_idx = r->in.start_idx;
1680 q.in.max_entries = r->in.max_entries;
1681 q.in.buf_size = r->in.buf_size;
1683 q.out.total_size = r->out.total_size;
1684 q.out.returned_size = r->out.returned_size;
1685 q.out.info = r->out.info;
1687 return _samr_QueryDisplayInfo(p, &q);
1690 /****************************************************************
1691 _samr_QueryDisplayInfo3
1692 ****************************************************************/
1694 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1695 struct samr_QueryDisplayInfo3 *r)
1697 struct samr_QueryDisplayInfo q;
1699 q.in.domain_handle = r->in.domain_handle;
1700 q.in.level = r->in.level;
1701 q.in.start_idx = r->in.start_idx;
1702 q.in.max_entries = r->in.max_entries;
1703 q.in.buf_size = r->in.buf_size;
1705 q.out.total_size = r->out.total_size;
1706 q.out.returned_size = r->out.returned_size;
1707 q.out.info = r->out.info;
1709 return _samr_QueryDisplayInfo(p, &q);
1712 /*******************************************************************
1713 _samr_QueryAliasInfo
1714 ********************************************************************/
1716 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1717 struct samr_QueryAliasInfo *r)
1719 DOM_SID sid;
1720 struct acct_info info;
1721 uint32 acc_granted;
1722 NTSTATUS status;
1723 union samr_AliasInfo *alias_info = NULL;
1724 const char *alias_name = NULL;
1725 const char *alias_description = NULL;
1727 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1729 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1730 if (!alias_info) {
1731 return NT_STATUS_NO_MEMORY;
1734 /* find the policy handle. open a policy on it. */
1735 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1736 return NT_STATUS_INVALID_HANDLE;
1738 status = access_check_samr_function(acc_granted,
1739 SA_RIGHT_ALIAS_LOOKUP_INFO,
1740 "_samr_QueryAliasInfo");
1741 if (!NT_STATUS_IS_OK(status)) {
1742 return status;
1745 become_root();
1746 status = pdb_get_aliasinfo(&sid, &info);
1747 unbecome_root();
1749 if ( !NT_STATUS_IS_OK(status))
1750 return status;
1752 /* FIXME: info contains fstrings */
1753 alias_name = talloc_strdup(r, info.acct_name);
1754 alias_description = talloc_strdup(r, info.acct_desc);
1756 switch (r->in.level) {
1757 case ALIASINFOALL:
1758 init_samr_alias_info1(&alias_info->all,
1759 alias_name,
1761 alias_description);
1762 break;
1763 case ALIASINFODESCRIPTION:
1764 init_samr_alias_info3(&alias_info->description,
1765 alias_description);
1766 break;
1767 default:
1768 return NT_STATUS_INVALID_INFO_CLASS;
1771 *r->out.info = alias_info;
1773 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1775 return NT_STATUS_OK;
1778 #if 0
1779 /*******************************************************************
1780 samr_reply_lookup_ids
1781 ********************************************************************/
1783 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1785 uint32 rid[MAX_SAM_ENTRIES];
1786 int num_rids = q_u->num_sids1;
1788 r_u->status = NT_STATUS_OK;
1790 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1792 if (num_rids > MAX_SAM_ENTRIES) {
1793 num_rids = MAX_SAM_ENTRIES;
1794 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1797 #if 0
1798 int i;
1799 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1801 for (i = 0; i < num_rids && status == 0; i++)
1803 struct sam_passwd *sam_pass;
1804 fstring user_name;
1807 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1808 q_u->uni_user_name[i].uni_str_len));
1810 /* find the user account */
1811 become_root();
1812 sam_pass = get_smb21pwd_entry(user_name, 0);
1813 unbecome_root();
1815 if (sam_pass == NULL)
1817 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1818 rid[i] = 0;
1820 else
1822 rid[i] = sam_pass->user_rid;
1825 #endif
1827 num_rids = 1;
1828 rid[0] = BUILTIN_ALIAS_RID_USERS;
1830 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1832 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1834 return r_u->status;
1836 #endif
1838 /*******************************************************************
1839 _samr_LookupNames
1840 ********************************************************************/
1842 NTSTATUS _samr_LookupNames(pipes_struct *p,
1843 struct samr_LookupNames *r)
1845 NTSTATUS status;
1846 uint32 *rid;
1847 enum lsa_SidType *type;
1848 int i;
1849 int num_rids = r->in.num_names;
1850 DOM_SID pol_sid;
1851 uint32 acc_granted;
1852 struct samr_Ids rids, types;
1854 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1856 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1857 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1860 status = access_check_samr_function(acc_granted,
1861 0, /* Don't know the acc_bits yet */
1862 "_samr_LookupNames");
1863 if (!NT_STATUS_IS_OK(status)) {
1864 return status;
1867 if (num_rids > MAX_SAM_ENTRIES) {
1868 num_rids = MAX_SAM_ENTRIES;
1869 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1872 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1873 NT_STATUS_HAVE_NO_MEMORY(rid);
1875 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1876 NT_STATUS_HAVE_NO_MEMORY(type);
1878 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1879 sid_string_dbg(&pol_sid)));
1881 for (i = 0; i < num_rids; i++) {
1883 status = NT_STATUS_NONE_MAPPED;
1884 type[i] = SID_NAME_UNKNOWN;
1886 rid[i] = 0xffffffff;
1888 if (sid_check_is_builtin(&pol_sid)) {
1889 if (lookup_builtin_name(r->in.names[i].string,
1890 &rid[i]))
1892 type[i] = SID_NAME_ALIAS;
1894 } else {
1895 lookup_global_sam_name(r->in.names[i].string, 0,
1896 &rid[i], &type[i]);
1899 if (type[i] != SID_NAME_UNKNOWN) {
1900 status = NT_STATUS_OK;
1904 rids.count = num_rids;
1905 rids.ids = rid;
1907 types.count = num_rids;
1908 types.ids = type;
1910 *r->out.rids = rids;
1911 *r->out.types = types;
1913 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1915 return status;
1918 /*******************************************************************
1919 _samr_ChangePasswordUser2
1920 ********************************************************************/
1922 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1923 struct samr_ChangePasswordUser2 *r)
1925 NTSTATUS status;
1926 fstring user_name;
1927 fstring wks;
1929 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1931 fstrcpy(user_name, r->in.account->string);
1932 fstrcpy(wks, r->in.server->string);
1934 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1937 * Pass the user through the NT -> unix user mapping
1938 * function.
1941 (void)map_username(user_name);
1944 * UNIX username case mangling not required, pass_oem_change
1945 * is case insensitive.
1948 status = pass_oem_change(user_name,
1949 r->in.lm_password->data,
1950 r->in.lm_verifier->hash,
1951 r->in.nt_password->data,
1952 r->in.nt_verifier->hash,
1953 NULL);
1955 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1957 return status;
1960 /*******************************************************************
1961 _samr_ChangePasswordUser3
1962 ********************************************************************/
1964 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1965 struct samr_ChangePasswordUser3 *r)
1967 NTSTATUS status;
1968 fstring user_name;
1969 const char *wks = NULL;
1970 uint32 reject_reason;
1971 struct samr_DomInfo1 *dominfo = NULL;
1972 struct samr_ChangeReject *reject = NULL;
1974 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1976 fstrcpy(user_name, r->in.account->string);
1977 if (r->in.server && r->in.server->string) {
1978 wks = r->in.server->string;
1981 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1984 * Pass the user through the NT -> unix user mapping
1985 * function.
1988 (void)map_username(user_name);
1991 * UNIX username case mangling not required, pass_oem_change
1992 * is case insensitive.
1995 status = pass_oem_change(user_name,
1996 r->in.lm_password->data,
1997 r->in.lm_verifier->hash,
1998 r->in.nt_password->data,
1999 r->in.nt_verifier->hash,
2000 &reject_reason);
2002 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2003 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2005 uint32 min_pass_len,pass_hist,password_properties;
2006 time_t u_expire, u_min_age;
2007 NTTIME nt_expire, nt_min_age;
2008 uint32 account_policy_temp;
2010 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2011 if (!dominfo) {
2012 return NT_STATUS_NO_MEMORY;
2015 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2016 if (!reject) {
2017 return NT_STATUS_NO_MEMORY;
2020 become_root();
2022 /* AS ROOT !!! */
2024 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2025 min_pass_len = account_policy_temp;
2027 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2028 pass_hist = account_policy_temp;
2030 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2031 password_properties = account_policy_temp;
2033 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2034 u_expire = account_policy_temp;
2036 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2037 u_min_age = account_policy_temp;
2039 /* !AS ROOT */
2041 unbecome_root();
2043 unix_to_nt_time_abs(&nt_expire, u_expire);
2044 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2046 if (lp_check_password_script() && *lp_check_password_script()) {
2047 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2050 init_samr_DomInfo1(dominfo,
2051 min_pass_len,
2052 pass_hist,
2053 password_properties,
2054 u_expire,
2055 u_min_age);
2057 reject->reason = reject_reason;
2059 *r->out.dominfo = dominfo;
2060 *r->out.reject = reject;
2063 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2065 return status;
2068 /*******************************************************************
2069 makes a SAMR_R_LOOKUP_RIDS structure.
2070 ********************************************************************/
2072 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2073 const char **names,
2074 struct lsa_String **lsa_name_array_p)
2076 struct lsa_String *lsa_name_array = NULL;
2077 uint32_t i;
2079 *lsa_name_array_p = NULL;
2081 if (num_names != 0) {
2082 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2083 if (!lsa_name_array) {
2084 return false;
2088 for (i = 0; i < num_names; i++) {
2089 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2090 init_lsa_String(&lsa_name_array[i], names[i]);
2093 *lsa_name_array_p = lsa_name_array;
2095 return true;
2098 /*******************************************************************
2099 _samr_LookupRids
2100 ********************************************************************/
2102 NTSTATUS _samr_LookupRids(pipes_struct *p,
2103 struct samr_LookupRids *r)
2105 NTSTATUS status;
2106 const char **names;
2107 enum lsa_SidType *attrs = NULL;
2108 uint32 *wire_attrs = NULL;
2109 DOM_SID pol_sid;
2110 int num_rids = (int)r->in.num_rids;
2111 uint32 acc_granted;
2112 int i;
2113 struct lsa_Strings names_array;
2114 struct samr_Ids types_array;
2115 struct lsa_String *lsa_names = NULL;
2117 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2119 /* find the policy handle. open a policy on it. */
2120 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2121 return NT_STATUS_INVALID_HANDLE;
2123 status = access_check_samr_function(acc_granted,
2124 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
2125 "_samr__LookupRids");
2126 if (!NT_STATUS_IS_OK(status)) {
2127 return status;
2130 if (num_rids > 1000) {
2131 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2132 "to samba4 idl this is not possible\n", num_rids));
2133 return NT_STATUS_UNSUCCESSFUL;
2136 if (num_rids) {
2137 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2138 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2139 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2141 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2142 return NT_STATUS_NO_MEMORY;
2143 } else {
2144 names = NULL;
2145 attrs = NULL;
2146 wire_attrs = NULL;
2149 become_root(); /* lookup_sid can require root privs */
2150 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2151 names, attrs);
2152 unbecome_root();
2154 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2155 status = NT_STATUS_OK;
2158 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2159 &lsa_names)) {
2160 return NT_STATUS_NO_MEMORY;
2163 /* Convert from enum lsa_SidType to uint32 for wire format. */
2164 for (i = 0; i < num_rids; i++) {
2165 wire_attrs[i] = (uint32)attrs[i];
2168 names_array.count = num_rids;
2169 names_array.names = lsa_names;
2171 types_array.count = num_rids;
2172 types_array.ids = wire_attrs;
2174 *r->out.names = names_array;
2175 *r->out.types = types_array;
2177 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2179 return status;
2182 /*******************************************************************
2183 _samr_OpenUser
2184 ********************************************************************/
2186 NTSTATUS _samr_OpenUser(pipes_struct *p,
2187 struct samr_OpenUser *r)
2189 struct samu *sampass=NULL;
2190 DOM_SID sid;
2191 POLICY_HND domain_pol = *r->in.domain_handle;
2192 POLICY_HND *user_pol = r->out.user_handle;
2193 struct samr_info *info = NULL;
2194 SEC_DESC *psd = NULL;
2195 uint32 acc_granted;
2196 uint32 des_access = r->in.access_mask;
2197 size_t sd_size;
2198 bool ret;
2199 NTSTATUS nt_status;
2200 SE_PRIV se_rights;
2202 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2204 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2205 return NT_STATUS_INVALID_HANDLE;
2207 nt_status = access_check_samr_function(acc_granted,
2208 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2209 "_samr_OpenUser" );
2211 if ( !NT_STATUS_IS_OK(nt_status) )
2212 return nt_status;
2214 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2215 return NT_STATUS_NO_MEMORY;
2218 /* append the user's RID to it */
2220 if (!sid_append_rid(&sid, r->in.rid))
2221 return NT_STATUS_NO_SUCH_USER;
2223 /* check if access can be granted as requested by client. */
2225 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
2227 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2228 se_map_generic(&des_access, &usr_generic_mapping);
2230 se_priv_copy( &se_rights, &se_machine_account );
2231 se_priv_add( &se_rights, &se_add_users );
2233 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2234 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2235 &acc_granted, "_samr_OpenUser");
2237 if ( !NT_STATUS_IS_OK(nt_status) )
2238 return nt_status;
2240 become_root();
2241 ret=pdb_getsampwsid(sampass, &sid);
2242 unbecome_root();
2244 /* check that the SID exists in our domain. */
2245 if (ret == False) {
2246 return NT_STATUS_NO_SUCH_USER;
2249 TALLOC_FREE(sampass);
2251 /* associate the user's SID and access bits with the new handle. */
2252 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2253 return NT_STATUS_NO_MEMORY;
2254 info->acc_granted = acc_granted;
2256 /* get a (unique) handle. open a policy on it. */
2257 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2258 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2260 return NT_STATUS_OK;
2263 /*************************************************************************
2264 *************************************************************************/
2266 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2267 DATA_BLOB *blob,
2268 struct lsa_BinaryString **_r)
2270 struct lsa_BinaryString *r;
2272 if (!blob || !_r) {
2273 return NT_STATUS_INVALID_PARAMETER;
2276 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2277 if (!r) {
2278 return NT_STATUS_NO_MEMORY;
2281 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2282 if (!r->array) {
2283 return NT_STATUS_NO_MEMORY;
2285 memcpy(r->array, blob->data, blob->length);
2286 r->size = blob->length;
2287 r->length = blob->length;
2289 if (!r->array) {
2290 return NT_STATUS_NO_MEMORY;
2293 *_r = r;
2295 return NT_STATUS_OK;
2298 /*************************************************************************
2299 get_user_info_7. Safe. Only gives out account_name.
2300 *************************************************************************/
2302 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2303 struct samr_UserInfo7 *r,
2304 DOM_SID *user_sid)
2306 struct samu *smbpass=NULL;
2307 bool ret;
2308 const char *account_name = NULL;
2310 ZERO_STRUCTP(r);
2312 if ( !(smbpass = samu_new( mem_ctx )) ) {
2313 return NT_STATUS_NO_MEMORY;
2316 become_root();
2317 ret = pdb_getsampwsid(smbpass, user_sid);
2318 unbecome_root();
2320 if ( !ret ) {
2321 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2322 return NT_STATUS_NO_SUCH_USER;
2325 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2326 if (!account_name) {
2327 TALLOC_FREE(smbpass);
2328 return NT_STATUS_NO_MEMORY;
2330 TALLOC_FREE(smbpass);
2332 DEBUG(3,("User:[%s]\n", account_name));
2334 init_samr_user_info7(r, account_name);
2336 return NT_STATUS_OK;
2339 /*************************************************************************
2340 get_user_info_9. Only gives out primary group SID.
2341 *************************************************************************/
2343 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2344 struct samr_UserInfo9 *r,
2345 DOM_SID *user_sid)
2347 struct samu *smbpass=NULL;
2348 bool ret;
2350 ZERO_STRUCTP(r);
2352 if ( !(smbpass = samu_new( mem_ctx )) ) {
2353 return NT_STATUS_NO_MEMORY;
2356 become_root();
2357 ret = pdb_getsampwsid(smbpass, user_sid);
2358 unbecome_root();
2360 if (ret==False) {
2361 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2362 TALLOC_FREE(smbpass);
2363 return NT_STATUS_NO_SUCH_USER;
2366 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2368 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2370 TALLOC_FREE(smbpass);
2372 return NT_STATUS_OK;
2375 /*************************************************************************
2376 get_user_info_16. Safe. Only gives out acb bits.
2377 *************************************************************************/
2379 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2380 struct samr_UserInfo16 *r,
2381 DOM_SID *user_sid)
2383 struct samu *smbpass=NULL;
2384 bool ret;
2386 ZERO_STRUCTP(r);
2388 if ( !(smbpass = samu_new( mem_ctx )) ) {
2389 return NT_STATUS_NO_MEMORY;
2392 become_root();
2393 ret = pdb_getsampwsid(smbpass, user_sid);
2394 unbecome_root();
2396 if (ret==False) {
2397 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2398 TALLOC_FREE(smbpass);
2399 return NT_STATUS_NO_SUCH_USER;
2402 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2404 init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2406 TALLOC_FREE(smbpass);
2408 return NT_STATUS_OK;
2411 /*************************************************************************
2412 get_user_info_18. OK - this is the killer as it gives out password info.
2413 Ensure that this is only allowed on an encrypted connection with a root
2414 user. JRA.
2415 *************************************************************************/
2417 static NTSTATUS get_user_info_18(pipes_struct *p,
2418 TALLOC_CTX *mem_ctx,
2419 struct samr_UserInfo18 *r,
2420 DOM_SID *user_sid)
2422 struct samu *smbpass=NULL;
2423 bool ret;
2425 ZERO_STRUCTP(r);
2427 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2428 return NT_STATUS_ACCESS_DENIED;
2431 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2432 return NT_STATUS_ACCESS_DENIED;
2436 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2439 if ( !(smbpass = samu_new( mem_ctx )) ) {
2440 return NT_STATUS_NO_MEMORY;
2443 ret = pdb_getsampwsid(smbpass, user_sid);
2445 if (ret == False) {
2446 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2447 TALLOC_FREE(smbpass);
2448 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2451 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2453 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2454 TALLOC_FREE(smbpass);
2455 return NT_STATUS_ACCOUNT_DISABLED;
2458 init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2459 pdb_get_nt_passwd(smbpass));
2461 TALLOC_FREE(smbpass);
2463 return NT_STATUS_OK;
2466 /*************************************************************************
2467 get_user_info_20
2468 *************************************************************************/
2470 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2471 struct samr_UserInfo20 *r,
2472 DOM_SID *user_sid)
2474 struct samu *sampass=NULL;
2475 bool ret;
2476 const char *munged_dial = NULL;
2477 DATA_BLOB blob;
2478 NTSTATUS status;
2479 struct lsa_BinaryString *parameters = NULL;
2481 ZERO_STRUCTP(r);
2483 if ( !(sampass = samu_new( mem_ctx )) ) {
2484 return NT_STATUS_NO_MEMORY;
2487 become_root();
2488 ret = pdb_getsampwsid(sampass, user_sid);
2489 unbecome_root();
2491 if (ret == False) {
2492 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2493 TALLOC_FREE(sampass);
2494 return NT_STATUS_NO_SUCH_USER;
2497 munged_dial = pdb_get_munged_dial(sampass);
2499 samr_clear_sam_passwd(sampass);
2501 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2502 munged_dial, (int)strlen(munged_dial)));
2504 if (munged_dial) {
2505 blob = base64_decode_data_blob(munged_dial);
2506 } else {
2507 blob = data_blob_string_const("");
2510 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2511 data_blob_free(&blob);
2512 TALLOC_FREE(sampass);
2513 if (!NT_STATUS_IS_OK(status)) {
2514 return status;
2517 init_samr_user_info20(r, parameters);
2519 return NT_STATUS_OK;
2523 /*************************************************************************
2524 get_user_info_21
2525 *************************************************************************/
2527 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2528 struct samr_UserInfo21 *r,
2529 DOM_SID *user_sid,
2530 DOM_SID *domain_sid)
2532 NTSTATUS status;
2533 struct samu *pw = NULL;
2534 bool ret;
2535 const DOM_SID *sid_user, *sid_group;
2536 uint32_t rid, primary_gid;
2537 NTTIME last_logon, last_logoff, last_password_change,
2538 acct_expiry, allow_password_change, force_password_change;
2539 time_t must_change_time;
2540 uint8_t password_expired;
2541 const char *account_name, *full_name, *home_directory, *home_drive,
2542 *logon_script, *profile_path, *description,
2543 *workstations, *comment;
2544 struct samr_LogonHours logon_hours;
2545 struct lsa_BinaryString *parameters = NULL;
2546 const char *munged_dial = NULL;
2547 DATA_BLOB blob;
2549 ZERO_STRUCTP(r);
2551 if (!(pw = samu_new(mem_ctx))) {
2552 return NT_STATUS_NO_MEMORY;
2555 become_root();
2556 ret = pdb_getsampwsid(pw, user_sid);
2557 unbecome_root();
2559 if (ret == False) {
2560 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2561 TALLOC_FREE(pw);
2562 return NT_STATUS_NO_SUCH_USER;
2565 samr_clear_sam_passwd(pw);
2567 DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2569 sid_user = pdb_get_user_sid(pw);
2571 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2572 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2573 "the domain sid %s. Failing operation.\n",
2574 pdb_get_username(pw), sid_string_dbg(sid_user),
2575 sid_string_dbg(domain_sid)));
2576 TALLOC_FREE(pw);
2577 return NT_STATUS_UNSUCCESSFUL;
2580 become_root();
2581 sid_group = pdb_get_group_sid(pw);
2582 unbecome_root();
2584 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2585 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2586 "which conflicts with the domain sid %s. Failing operation.\n",
2587 pdb_get_username(pw), sid_string_dbg(sid_group),
2588 sid_string_dbg(domain_sid)));
2589 TALLOC_FREE(pw);
2590 return NT_STATUS_UNSUCCESSFUL;
2593 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2594 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2595 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2596 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2597 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2599 must_change_time = pdb_get_pass_must_change_time(pw);
2600 if (must_change_time == get_time_t_max()) {
2601 unix_to_nt_time_abs(&force_password_change, must_change_time);
2602 } else {
2603 unix_to_nt_time(&force_password_change, must_change_time);
2606 if (pdb_get_pass_must_change_time(pw) == 0) {
2607 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2608 } else {
2609 password_expired = 0;
2612 munged_dial = pdb_get_munged_dial(pw);
2613 if (munged_dial) {
2614 blob = base64_decode_data_blob(munged_dial);
2615 } else {
2616 blob = data_blob_string_const("");
2619 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2620 data_blob_free(&blob);
2621 if (!NT_STATUS_IS_OK(status)) {
2622 TALLOC_FREE(pw);
2623 return status;
2626 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2627 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2628 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2629 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2630 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2631 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2632 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2633 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2634 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2636 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2637 #if 0
2640 Look at a user on a real NT4 PDC with usrmgr, press
2641 'ok'. Then you will see that fields_present is set to
2642 0x08f827fa. Look at the user immediately after that again,
2643 and you will see that 0x00fffff is returned. This solves
2644 the problem that you get access denied after having looked
2645 at the user.
2646 -- Volker
2649 #endif
2651 init_samr_user_info21(r,
2652 last_logon,
2653 last_logoff,
2654 last_password_change,
2655 acct_expiry,
2656 allow_password_change,
2657 force_password_change,
2658 account_name,
2659 full_name,
2660 home_directory,
2661 home_drive,
2662 logon_script,
2663 profile_path,
2664 description,
2665 workstations,
2666 comment,
2667 parameters,
2668 rid,
2669 primary_gid,
2670 pdb_get_acct_ctrl(pw),
2671 pdb_build_fields_present(pw),
2672 logon_hours,
2673 pdb_get_bad_password_count(pw),
2674 pdb_get_logon_count(pw),
2675 0, /* country_code */
2676 0, /* code_page */
2677 0, /* nt_password_set */
2678 0, /* lm_password_set */
2679 password_expired);
2680 TALLOC_FREE(pw);
2682 return NT_STATUS_OK;
2685 /*******************************************************************
2686 _samr_QueryUserInfo
2687 ********************************************************************/
2689 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2690 struct samr_QueryUserInfo *r)
2692 NTSTATUS status;
2693 union samr_UserInfo *user_info = NULL;
2694 struct samr_info *info = NULL;
2695 DOM_SID domain_sid;
2696 uint32 rid;
2698 /* search for the handle */
2699 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2700 return NT_STATUS_INVALID_HANDLE;
2702 status = access_check_samr_function(info->acc_granted,
2703 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2704 "_samr_QueryUserInfo");
2705 if (!NT_STATUS_IS_OK(status)) {
2706 return status;
2709 domain_sid = info->sid;
2711 sid_split_rid(&domain_sid, &rid);
2713 if (!sid_check_is_in_our_domain(&info->sid))
2714 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2716 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2717 sid_string_dbg(&info->sid)));
2719 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2720 if (!user_info) {
2721 return NT_STATUS_NO_MEMORY;
2724 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2726 switch (r->in.level) {
2727 case 7:
2728 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2729 if (!NT_STATUS_IS_OK(status)) {
2730 return status;
2732 break;
2733 case 9:
2734 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2735 if (!NT_STATUS_IS_OK(status)) {
2736 return status;
2738 break;
2739 case 16:
2740 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2741 if (!NT_STATUS_IS_OK(status)) {
2742 return status;
2744 break;
2746 case 18:
2747 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2748 if (!NT_STATUS_IS_OK(status)) {
2749 return status;
2751 break;
2753 case 20:
2754 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2755 if (!NT_STATUS_IS_OK(status)) {
2756 return status;
2758 break;
2760 case 21:
2761 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2762 &info->sid, &domain_sid);
2763 if (!NT_STATUS_IS_OK(status)) {
2764 return status;
2766 break;
2768 default:
2769 return NT_STATUS_INVALID_INFO_CLASS;
2772 *r->out.info = user_info;
2774 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2776 return status;
2779 /*******************************************************************
2780 _samr_GetGroupsForUser
2781 ********************************************************************/
2783 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2784 struct samr_GetGroupsForUser *r)
2786 struct samu *sam_pass=NULL;
2787 DOM_SID sid;
2788 DOM_SID *sids;
2789 struct samr_RidWithAttribute dom_gid;
2790 struct samr_RidWithAttribute *gids = NULL;
2791 uint32 primary_group_rid;
2792 size_t num_groups = 0;
2793 gid_t *unix_gids;
2794 size_t i, num_gids;
2795 uint32 acc_granted;
2796 bool ret;
2797 NTSTATUS result;
2798 bool success = False;
2800 struct samr_RidWithAttributeArray *rids = NULL;
2803 * from the SID in the request:
2804 * we should send back the list of DOMAIN GROUPS
2805 * the user is a member of
2807 * and only the DOMAIN GROUPS
2808 * no ALIASES !!! neither aliases of the domain
2809 * nor aliases of the builtin SID
2811 * JFM, 12/2/2001
2814 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2816 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2817 if (!rids) {
2818 return NT_STATUS_NO_MEMORY;
2821 /* find the policy handle. open a policy on it. */
2822 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2823 return NT_STATUS_INVALID_HANDLE;
2825 result = access_check_samr_function(acc_granted,
2826 SA_RIGHT_USER_GET_GROUPS,
2827 "_samr_GetGroupsForUser");
2828 if (!NT_STATUS_IS_OK(result)) {
2829 return result;
2832 if (!sid_check_is_in_our_domain(&sid))
2833 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2835 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2836 return NT_STATUS_NO_MEMORY;
2839 become_root();
2840 ret = pdb_getsampwsid(sam_pass, &sid);
2841 unbecome_root();
2843 if (!ret) {
2844 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2845 sid_string_dbg(&sid)));
2846 return NT_STATUS_NO_SUCH_USER;
2849 sids = NULL;
2851 /* make both calls inside the root block */
2852 become_root();
2853 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2854 &sids, &unix_gids, &num_groups);
2855 if ( NT_STATUS_IS_OK(result) ) {
2856 success = sid_peek_check_rid(get_global_sam_sid(),
2857 pdb_get_group_sid(sam_pass),
2858 &primary_group_rid);
2860 unbecome_root();
2862 if (!NT_STATUS_IS_OK(result)) {
2863 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2864 sid_string_dbg(&sid)));
2865 return result;
2868 if ( !success ) {
2869 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2870 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2871 pdb_get_username(sam_pass)));
2872 TALLOC_FREE(sam_pass);
2873 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2876 gids = NULL;
2877 num_gids = 0;
2879 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2880 SE_GROUP_ENABLED);
2881 dom_gid.rid = primary_group_rid;
2882 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2884 for (i=0; i<num_groups; i++) {
2886 if (!sid_peek_check_rid(get_global_sam_sid(),
2887 &(sids[i]), &dom_gid.rid)) {
2888 DEBUG(10, ("Found sid %s not in our domain\n",
2889 sid_string_dbg(&sids[i])));
2890 continue;
2893 if (dom_gid.rid == primary_group_rid) {
2894 /* We added the primary group directly from the
2895 * sam_account. The other SIDs are unique from
2896 * enum_group_memberships */
2897 continue;
2900 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2903 rids->count = num_gids;
2904 rids->rids = gids;
2906 *r->out.rids = rids;
2908 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2910 return result;
2913 /*******************************************************************
2914 samr_QueryDomainInfo_internal
2915 ********************************************************************/
2917 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2918 pipes_struct *p,
2919 struct policy_handle *handle,
2920 uint32_t level,
2921 union samr_DomainInfo **dom_info_ptr)
2923 NTSTATUS status = NT_STATUS_OK;
2924 struct samr_info *info = NULL;
2925 union samr_DomainInfo *dom_info;
2926 uint32 min_pass_len,pass_hist,password_properties;
2927 time_t u_expire, u_min_age;
2928 NTTIME nt_expire, nt_min_age;
2930 time_t u_lock_duration, u_reset_time;
2931 NTTIME nt_lock_duration, nt_reset_time;
2932 uint32 lockout;
2933 time_t u_logout;
2934 NTTIME nt_logout;
2936 uint32 account_policy_temp;
2938 time_t seq_num;
2939 uint32 server_role;
2941 uint32 num_users=0, num_groups=0, num_aliases=0;
2943 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2945 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2946 if (!dom_info) {
2947 return NT_STATUS_NO_MEMORY;
2950 *dom_info_ptr = dom_info;
2952 /* find the policy handle. open a policy on it. */
2953 if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2954 return NT_STATUS_INVALID_HANDLE;
2957 status = access_check_samr_function(info->acc_granted,
2958 SA_RIGHT_SAM_OPEN_DOMAIN,
2959 "_samr_QueryDomainInfo_internal" );
2961 if ( !NT_STATUS_IS_OK(status) )
2962 return status;
2964 switch (level) {
2965 case 0x01:
2967 become_root();
2969 /* AS ROOT !!! */
2971 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2972 min_pass_len = account_policy_temp;
2974 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2975 pass_hist = account_policy_temp;
2977 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2978 password_properties = account_policy_temp;
2980 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2981 u_expire = account_policy_temp;
2983 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2984 u_min_age = account_policy_temp;
2986 /* !AS ROOT */
2988 unbecome_root();
2990 unix_to_nt_time_abs(&nt_expire, u_expire);
2991 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2993 if (lp_check_password_script() && *lp_check_password_script()) {
2994 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2997 init_samr_DomInfo1(&dom_info->info1,
2998 (uint16)min_pass_len,
2999 (uint16)pass_hist,
3000 password_properties,
3001 nt_expire,
3002 nt_min_age);
3003 break;
3004 case 0x02:
3006 become_root();
3008 /* AS ROOT !!! */
3010 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
3011 num_groups = count_sam_groups(info->disp_info);
3012 num_aliases = count_sam_aliases(info->disp_info);
3014 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
3015 u_logout = account_policy_temp;
3017 unix_to_nt_time_abs(&nt_logout, u_logout);
3019 if (!pdb_get_seq_num(&seq_num))
3020 seq_num = time(NULL);
3022 /* !AS ROOT */
3024 unbecome_root();
3026 server_role = ROLE_DOMAIN_PDC;
3027 if (lp_server_role() == ROLE_DOMAIN_BDC)
3028 server_role = ROLE_DOMAIN_BDC;
3030 init_samr_DomInfo2(&dom_info->info2,
3031 nt_logout,
3032 lp_serverstring(),
3033 lp_workgroup(),
3034 global_myname(),
3035 seq_num,
3037 server_role,
3039 num_users,
3040 num_groups,
3041 num_aliases);
3042 break;
3043 case 0x03:
3045 become_root();
3047 /* AS ROOT !!! */
3050 uint32 ul;
3051 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3052 u_logout = (time_t)ul;
3055 /* !AS ROOT */
3057 unbecome_root();
3059 unix_to_nt_time_abs(&nt_logout, u_logout);
3061 init_samr_DomInfo3(&dom_info->info3,
3062 nt_logout);
3064 break;
3065 case 0x04:
3066 init_samr_DomInfo4(&dom_info->info4,
3067 lp_serverstring());
3068 break;
3069 case 0x05:
3070 init_samr_DomInfo5(&dom_info->info5,
3071 get_global_sam_name());
3072 break;
3073 case 0x06:
3074 /* NT returns its own name when a PDC. win2k and later
3075 * only the name of the PDC if itself is a BDC (samba4
3076 * idl) */
3077 init_samr_DomInfo6(&dom_info->info6,
3078 global_myname());
3079 break;
3080 case 0x07:
3081 server_role = ROLE_DOMAIN_PDC;
3082 if (lp_server_role() == ROLE_DOMAIN_BDC)
3083 server_role = ROLE_DOMAIN_BDC;
3085 init_samr_DomInfo7(&dom_info->info7,
3086 server_role);
3087 break;
3088 case 0x08:
3090 become_root();
3092 /* AS ROOT !!! */
3094 if (!pdb_get_seq_num(&seq_num)) {
3095 seq_num = time(NULL);
3098 /* !AS ROOT */
3100 unbecome_root();
3102 init_samr_DomInfo8(&dom_info->info8,
3103 seq_num,
3105 break;
3106 case 0x0c:
3108 become_root();
3110 /* AS ROOT !!! */
3112 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3113 u_lock_duration = account_policy_temp;
3114 if (u_lock_duration != -1) {
3115 u_lock_duration *= 60;
3118 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3119 u_reset_time = account_policy_temp * 60;
3121 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3122 lockout = account_policy_temp;
3124 /* !AS ROOT */
3126 unbecome_root();
3128 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3129 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3131 init_samr_DomInfo12(&dom_info->info12,
3132 nt_lock_duration,
3133 nt_reset_time,
3134 (uint16)lockout);
3135 break;
3136 default:
3137 return NT_STATUS_INVALID_INFO_CLASS;
3140 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
3142 return status;
3145 /*******************************************************************
3146 _samr_QueryDomainInfo
3147 ********************************************************************/
3149 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3150 struct samr_QueryDomainInfo *r)
3152 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
3154 r->in.domain_handle,
3155 r->in.level,
3156 r->out.info);
3159 /* W2k3 seems to use the same check for all 3 objects that can be created via
3160 * SAMR, if you try to create for example "Dialup" as an alias it says
3161 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3162 * database. */
3164 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3166 enum lsa_SidType type;
3167 bool result;
3169 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3171 become_root();
3172 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3173 * whether the name already exists */
3174 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3175 NULL, NULL, NULL, &type);
3176 unbecome_root();
3178 if (!result) {
3179 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3180 return NT_STATUS_OK;
3183 DEBUG(5, ("trying to create %s, exists as %s\n",
3184 new_name, sid_type_lookup(type)));
3186 if (type == SID_NAME_DOM_GRP) {
3187 return NT_STATUS_GROUP_EXISTS;
3189 if (type == SID_NAME_ALIAS) {
3190 return NT_STATUS_ALIAS_EXISTS;
3193 /* Yes, the default is NT_STATUS_USER_EXISTS */
3194 return NT_STATUS_USER_EXISTS;
3197 /*******************************************************************
3198 _samr_CreateUser2
3199 ********************************************************************/
3201 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3202 struct samr_CreateUser2 *r)
3204 const char *account = NULL;
3205 DOM_SID sid;
3206 POLICY_HND dom_pol = *r->in.domain_handle;
3207 uint32_t acb_info = r->in.acct_flags;
3208 POLICY_HND *user_pol = r->out.user_handle;
3209 struct samr_info *info = NULL;
3210 NTSTATUS nt_status;
3211 uint32 acc_granted;
3212 SEC_DESC *psd;
3213 size_t sd_size;
3214 /* check this, when giving away 'add computer to domain' privs */
3215 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3216 bool can_add_account = False;
3217 SE_PRIV se_rights;
3218 DISP_INFO *disp_info = NULL;
3220 /* Get the domain SID stored in the domain policy */
3221 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3222 &disp_info))
3223 return NT_STATUS_INVALID_HANDLE;
3225 nt_status = access_check_samr_function(acc_granted,
3226 SA_RIGHT_DOMAIN_CREATE_USER,
3227 "_samr_CreateUser2");
3228 if (!NT_STATUS_IS_OK(nt_status)) {
3229 return nt_status;
3232 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3233 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3234 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3235 this parameter is not an account type */
3236 return NT_STATUS_INVALID_PARAMETER;
3239 account = r->in.account_name->string;
3240 if (account == NULL) {
3241 return NT_STATUS_NO_MEMORY;
3244 nt_status = can_create(p->mem_ctx, account);
3245 if (!NT_STATUS_IS_OK(nt_status)) {
3246 return nt_status;
3249 /* determine which user right we need to check based on the acb_info */
3251 if ( acb_info & ACB_WSTRUST )
3253 se_priv_copy( &se_rights, &se_machine_account );
3254 can_add_account = user_has_privileges(
3255 p->pipe_user.nt_user_token, &se_rights );
3257 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3258 account for domain trusts and changes the ACB flags later */
3259 else if ( acb_info & ACB_NORMAL &&
3260 (account[strlen(account)-1] != '$') )
3262 se_priv_copy( &se_rights, &se_add_users );
3263 can_add_account = user_has_privileges(
3264 p->pipe_user.nt_user_token, &se_rights );
3266 else /* implicit assumption of a BDC or domain trust account here
3267 * (we already check the flags earlier) */
3269 if ( lp_enable_privileges() ) {
3270 /* only Domain Admins can add a BDC or domain trust */
3271 se_priv_copy( &se_rights, &se_priv_none );
3272 can_add_account = nt_token_check_domain_rid(
3273 p->pipe_user.nt_user_token,
3274 DOMAIN_GROUP_RID_ADMINS );
3278 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3279 uidtoname(p->pipe_user.ut.uid),
3280 can_add_account ? "True":"False" ));
3282 /********** BEGIN Admin BLOCK **********/
3284 if ( can_add_account )
3285 become_root();
3287 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3288 r->out.rid);
3290 if ( can_add_account )
3291 unbecome_root();
3293 /********** END Admin BLOCK **********/
3295 /* now check for failure */
3297 if ( !NT_STATUS_IS_OK(nt_status) )
3298 return nt_status;
3300 /* Get the user's SID */
3302 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3304 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3306 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3307 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3308 se_map_generic(&des_access, &usr_generic_mapping);
3310 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3311 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3312 &acc_granted, "_samr_CreateUser2");
3314 if ( !NT_STATUS_IS_OK(nt_status) ) {
3315 return nt_status;
3318 /* associate the user's SID with the new handle. */
3319 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3320 return NT_STATUS_NO_MEMORY;
3323 ZERO_STRUCTP(info);
3324 info->sid = sid;
3325 info->acc_granted = acc_granted;
3327 /* get a (unique) handle. open a policy on it. */
3328 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3329 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3332 /* After a "set" ensure we have no cached display info. */
3333 force_flush_samr_cache(info->disp_info);
3335 *r->out.access_granted = acc_granted;
3337 return NT_STATUS_OK;
3340 /*******************************************************************
3341 _samr_Connect
3342 ********************************************************************/
3344 NTSTATUS _samr_Connect(pipes_struct *p,
3345 struct samr_Connect *r)
3347 struct samr_info *info = NULL;
3348 uint32 des_access = r->in.access_mask;
3350 /* Access check */
3352 if (!pipe_access_check(p)) {
3353 DEBUG(3, ("access denied to _samr_Connect\n"));
3354 return NT_STATUS_ACCESS_DENIED;
3357 /* set up the SAMR connect_anon response */
3359 /* associate the user's SID with the new handle. */
3360 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3361 return NT_STATUS_NO_MEMORY;
3363 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3364 was observed from a win98 client trying to enumerate users (when configured
3365 user level access control on shares) --jerry */
3367 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3369 se_map_generic( &des_access, &sam_generic_mapping );
3370 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3372 /* get a (unique) handle. open a policy on it. */
3373 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3374 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3376 return NT_STATUS_OK;
3379 /*******************************************************************
3380 _samr_Connect2
3381 ********************************************************************/
3383 NTSTATUS _samr_Connect2(pipes_struct *p,
3384 struct samr_Connect2 *r)
3386 struct samr_info *info = NULL;
3387 SEC_DESC *psd = NULL;
3388 uint32 acc_granted;
3389 uint32 des_access = r->in.access_mask;
3390 NTSTATUS nt_status;
3391 size_t sd_size;
3394 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3396 /* Access check */
3398 if (!pipe_access_check(p)) {
3399 DEBUG(3, ("access denied to _samr_Connect2\n"));
3400 return NT_STATUS_ACCESS_DENIED;
3403 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3405 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3406 se_map_generic(&des_access, &sam_generic_mapping);
3408 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3409 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3411 if ( !NT_STATUS_IS_OK(nt_status) )
3412 return nt_status;
3414 /* associate the user's SID and access granted with the new handle. */
3415 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3416 return NT_STATUS_NO_MEMORY;
3418 info->acc_granted = acc_granted;
3419 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3421 /* get a (unique) handle. open a policy on it. */
3422 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3423 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3425 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3427 return nt_status;
3430 /*******************************************************************
3431 _samr_Connect4
3432 ********************************************************************/
3434 NTSTATUS _samr_Connect4(pipes_struct *p,
3435 struct samr_Connect4 *r)
3437 struct samr_info *info = NULL;
3438 SEC_DESC *psd = NULL;
3439 uint32 acc_granted;
3440 uint32 des_access = r->in.access_mask;
3441 NTSTATUS nt_status;
3442 size_t sd_size;
3445 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3447 /* Access check */
3449 if (!pipe_access_check(p)) {
3450 DEBUG(3, ("access denied to samr_Connect4\n"));
3451 return NT_STATUS_ACCESS_DENIED;
3454 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3456 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3457 se_map_generic(&des_access, &sam_generic_mapping);
3459 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3460 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3462 if ( !NT_STATUS_IS_OK(nt_status) )
3463 return nt_status;
3465 /* associate the user's SID and access granted with the new handle. */
3466 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3467 return NT_STATUS_NO_MEMORY;
3469 info->acc_granted = acc_granted;
3470 info->status = r->in.access_mask; /* ??? */
3472 /* get a (unique) handle. open a policy on it. */
3473 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3474 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3476 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3478 return NT_STATUS_OK;
3481 /*******************************************************************
3482 _samr_Connect5
3483 ********************************************************************/
3485 NTSTATUS _samr_Connect5(pipes_struct *p,
3486 struct samr_Connect5 *r)
3488 struct samr_info *info = NULL;
3489 SEC_DESC *psd = NULL;
3490 uint32 acc_granted;
3491 uint32 des_access = r->in.access_mask;
3492 NTSTATUS nt_status;
3493 size_t sd_size;
3494 struct samr_ConnectInfo1 info1;
3496 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3498 /* Access check */
3500 if (!pipe_access_check(p)) {
3501 DEBUG(3, ("access denied to samr_Connect5\n"));
3502 return NT_STATUS_ACCESS_DENIED;
3505 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3507 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3508 se_map_generic(&des_access, &sam_generic_mapping);
3510 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3511 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3513 if ( !NT_STATUS_IS_OK(nt_status) )
3514 return nt_status;
3516 /* associate the user's SID and access granted with the new handle. */
3517 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3518 return NT_STATUS_NO_MEMORY;
3520 info->acc_granted = acc_granted;
3521 info->status = r->in.access_mask; /* ??? */
3523 /* get a (unique) handle. open a policy on it. */
3524 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3525 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3527 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3529 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3530 info1.unknown2 = 0;
3532 *r->out.level_out = 1;
3533 r->out.info_out->info1 = info1;
3535 return NT_STATUS_OK;
3538 /**********************************************************************
3539 _samr_LookupDomain
3540 **********************************************************************/
3542 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3543 struct samr_LookupDomain *r)
3545 NTSTATUS status = NT_STATUS_OK;
3546 struct samr_info *info;
3547 const char *domain_name;
3548 DOM_SID *sid = NULL;
3550 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3551 return NT_STATUS_INVALID_HANDLE;
3553 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3554 Reverted that change so we will work with RAS servers again */
3556 status = access_check_samr_function(info->acc_granted,
3557 SA_RIGHT_SAM_OPEN_DOMAIN,
3558 "_samr_LookupDomain");
3559 if (!NT_STATUS_IS_OK(status)) {
3560 return status;
3563 domain_name = r->in.domain_name->string;
3565 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3566 if (!sid) {
3567 return NT_STATUS_NO_MEMORY;
3570 if (strequal(domain_name, builtin_domain_name())) {
3571 sid_copy(sid, &global_sid_Builtin);
3572 } else {
3573 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3574 status = NT_STATUS_NO_SUCH_DOMAIN;
3578 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3579 sid_string_dbg(sid)));
3581 *r->out.sid = sid;
3583 return status;
3586 /**********************************************************************
3587 _samr_EnumDomains
3588 **********************************************************************/
3590 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3591 struct samr_EnumDomains *r)
3593 NTSTATUS status;
3594 struct samr_info *info;
3595 uint32_t num_entries = 2;
3596 struct samr_SamEntry *entry_array = NULL;
3597 struct samr_SamArray *sam;
3599 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3600 return NT_STATUS_INVALID_HANDLE;
3602 status = access_check_samr_function(info->acc_granted,
3603 SA_RIGHT_SAM_ENUM_DOMAINS,
3604 "_samr_EnumDomains");
3605 if (!NT_STATUS_IS_OK(status)) {
3606 return status;
3609 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3610 if (!sam) {
3611 return NT_STATUS_NO_MEMORY;
3614 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3615 struct samr_SamEntry,
3616 num_entries);
3617 if (!entry_array) {
3618 return NT_STATUS_NO_MEMORY;
3621 entry_array[0].idx = 0;
3622 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3624 entry_array[1].idx = 1;
3625 init_lsa_String(&entry_array[1].name, "Builtin");
3627 sam->count = num_entries;
3628 sam->entries = entry_array;
3630 *r->out.sam = sam;
3631 *r->out.num_entries = num_entries;
3633 return status;
3636 /*******************************************************************
3637 _samr_OpenAlias
3638 ********************************************************************/
3640 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3641 struct samr_OpenAlias *r)
3643 DOM_SID sid;
3644 POLICY_HND domain_pol = *r->in.domain_handle;
3645 uint32 alias_rid = r->in.rid;
3646 POLICY_HND *alias_pol = r->out.alias_handle;
3647 struct samr_info *info = NULL;
3648 SEC_DESC *psd = NULL;
3649 uint32 acc_granted;
3650 uint32 des_access = r->in.access_mask;
3651 size_t sd_size;
3652 NTSTATUS status;
3653 SE_PRIV se_rights;
3655 /* find the domain policy and get the SID / access bits stored in the domain policy */
3657 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3658 return NT_STATUS_INVALID_HANDLE;
3660 status = access_check_samr_function(acc_granted,
3661 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3662 "_samr_OpenAlias");
3664 if ( !NT_STATUS_IS_OK(status) )
3665 return status;
3667 /* append the alias' RID to it */
3669 if (!sid_append_rid(&sid, alias_rid))
3670 return NT_STATUS_NO_SUCH_ALIAS;
3672 /*check if access can be granted as requested by client. */
3674 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3676 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3677 se_map_generic(&des_access,&ali_generic_mapping);
3679 se_priv_copy( &se_rights, &se_add_users );
3682 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3683 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3684 &acc_granted, "_samr_OpenAlias");
3686 if ( !NT_STATUS_IS_OK(status) )
3687 return status;
3690 /* Check we actually have the requested alias */
3691 enum lsa_SidType type;
3692 bool result;
3693 gid_t gid;
3695 become_root();
3696 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3697 unbecome_root();
3699 if (!result || (type != SID_NAME_ALIAS)) {
3700 return NT_STATUS_NO_SUCH_ALIAS;
3703 /* make sure there is a mapping */
3705 if ( !sid_to_gid( &sid, &gid ) ) {
3706 return NT_STATUS_NO_SUCH_ALIAS;
3711 /* associate the alias SID with the new handle. */
3712 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3713 return NT_STATUS_NO_MEMORY;
3715 info->acc_granted = acc_granted;
3717 /* get a (unique) handle. open a policy on it. */
3718 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3719 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3721 return NT_STATUS_OK;
3724 /*******************************************************************
3725 set_user_info_7
3726 ********************************************************************/
3728 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3729 struct samr_UserInfo7 *id7,
3730 struct samu *pwd)
3732 NTSTATUS rc;
3734 if (id7 == NULL) {
3735 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3736 TALLOC_FREE(pwd);
3737 return NT_STATUS_ACCESS_DENIED;
3740 if (!id7->account_name.string) {
3741 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3742 TALLOC_FREE(pwd);
3743 return NT_STATUS_ACCESS_DENIED;
3746 /* check to see if the new username already exists. Note: we can't
3747 reliably lock all backends, so there is potentially the
3748 possibility that a user can be created in between this check and
3749 the rename. The rename should fail, but may not get the
3750 exact same failure status code. I think this is small enough
3751 of a window for this type of operation and the results are
3752 simply that the rename fails with a slightly different status
3753 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3755 rc = can_create(mem_ctx, id7->account_name.string);
3756 if (!NT_STATUS_IS_OK(rc)) {
3757 return rc;
3760 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3762 TALLOC_FREE(pwd);
3763 return rc;
3766 /*******************************************************************
3767 set_user_info_16
3768 ********************************************************************/
3770 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3771 struct samu *pwd)
3773 if (id16 == NULL) {
3774 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3775 TALLOC_FREE(pwd);
3776 return False;
3779 /* FIX ME: check if the value is really changed --metze */
3780 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3781 TALLOC_FREE(pwd);
3782 return False;
3785 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3786 TALLOC_FREE(pwd);
3787 return False;
3790 TALLOC_FREE(pwd);
3792 return True;
3795 /*******************************************************************
3796 set_user_info_18
3797 ********************************************************************/
3799 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3800 struct samu *pwd)
3802 if (id18 == NULL) {
3803 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3804 TALLOC_FREE(pwd);
3805 return False;
3808 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3809 TALLOC_FREE(pwd);
3810 return False;
3812 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3813 TALLOC_FREE(pwd);
3814 return False;
3816 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3817 TALLOC_FREE(pwd);
3818 return False;
3821 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3822 TALLOC_FREE(pwd);
3823 return False;
3826 TALLOC_FREE(pwd);
3827 return True;
3830 /*******************************************************************
3831 set_user_info_20
3832 ********************************************************************/
3834 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3835 struct samu *pwd)
3837 if (id20 == NULL) {
3838 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3839 return False;
3842 copy_id20_to_sam_passwd(pwd, id20);
3844 /* write the change out */
3845 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3846 TALLOC_FREE(pwd);
3847 return False;
3850 TALLOC_FREE(pwd);
3852 return True;
3855 /*******************************************************************
3856 set_user_info_21
3857 ********************************************************************/
3859 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3860 struct samr_UserInfo21 *id21,
3861 struct samu *pwd)
3863 NTSTATUS status;
3865 if (id21 == NULL) {
3866 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3867 return NT_STATUS_INVALID_PARAMETER;
3870 /* we need to separately check for an account rename first */
3872 if (id21->account_name.string &&
3873 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3876 /* check to see if the new username already exists. Note: we can't
3877 reliably lock all backends, so there is potentially the
3878 possibility that a user can be created in between this check and
3879 the rename. The rename should fail, but may not get the
3880 exact same failure status code. I think this is small enough
3881 of a window for this type of operation and the results are
3882 simply that the rename fails with a slightly different status
3883 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3885 status = can_create(mem_ctx, id21->account_name.string);
3886 if (!NT_STATUS_IS_OK(status)) {
3887 return status;
3890 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3892 if (!NT_STATUS_IS_OK(status)) {
3893 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3894 nt_errstr(status)));
3895 TALLOC_FREE(pwd);
3896 return status;
3899 /* set the new username so that later
3900 functions can work on the new account */
3901 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3904 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3907 * The funny part about the previous two calls is
3908 * that pwd still has the password hashes from the
3909 * passdb entry. These have not been updated from
3910 * id21. I don't know if they need to be set. --jerry
3913 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3914 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3915 if ( !NT_STATUS_IS_OK(status) ) {
3916 return status;
3920 /* Don't worry about writing out the user account since the
3921 primary group SID is generated solely from the user's Unix
3922 primary group. */
3924 /* write the change out */
3925 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3926 TALLOC_FREE(pwd);
3927 return status;
3930 TALLOC_FREE(pwd);
3932 return NT_STATUS_OK;
3935 /*******************************************************************
3936 set_user_info_23
3937 ********************************************************************/
3939 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3940 struct samr_UserInfo23 *id23,
3941 struct samu *pwd)
3943 char *plaintext_buf = NULL;
3944 uint32 len = 0;
3945 uint16 acct_ctrl;
3946 NTSTATUS status;
3948 if (id23 == NULL) {
3949 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3950 return NT_STATUS_INVALID_PARAMETER;
3953 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3954 pdb_get_username(pwd)));
3956 acct_ctrl = pdb_get_acct_ctrl(pwd);
3958 if (!decode_pw_buffer(mem_ctx,
3959 id23->password.data,
3960 &plaintext_buf,
3961 &len,
3962 STR_UNICODE)) {
3963 TALLOC_FREE(pwd);
3964 return NT_STATUS_INVALID_PARAMETER;
3967 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3968 TALLOC_FREE(pwd);
3969 return NT_STATUS_ACCESS_DENIED;
3972 copy_id23_to_sam_passwd(pwd, id23);
3974 /* if it's a trust account, don't update /etc/passwd */
3975 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3976 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3977 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3978 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3979 } else {
3980 /* update the UNIX password */
3981 if (lp_unix_password_sync() ) {
3982 struct passwd *passwd;
3983 if (pdb_get_username(pwd) == NULL) {
3984 DEBUG(1, ("chgpasswd: User without name???\n"));
3985 TALLOC_FREE(pwd);
3986 return NT_STATUS_ACCESS_DENIED;
3989 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3990 if (passwd == NULL) {
3991 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3994 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3995 TALLOC_FREE(pwd);
3996 return NT_STATUS_ACCESS_DENIED;
3998 TALLOC_FREE(passwd);
4002 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4004 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4005 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4006 pwd)))) {
4007 TALLOC_FREE(pwd);
4008 return status;
4011 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4012 TALLOC_FREE(pwd);
4013 return status;
4016 TALLOC_FREE(pwd);
4018 return NT_STATUS_OK;
4021 /*******************************************************************
4022 set_user_info_pw
4023 ********************************************************************/
4025 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
4026 int level)
4028 uint32 len = 0;
4029 char *plaintext_buf = NULL;
4030 uint32 acct_ctrl;
4031 time_t last_set_time;
4032 enum pdb_value_state last_set_state;
4034 DEBUG(5, ("Attempting administrator password change for user %s\n",
4035 pdb_get_username(pwd)));
4037 acct_ctrl = pdb_get_acct_ctrl(pwd);
4038 /* we need to know if it's expired, because this is an admin change, not a
4039 user change, so it's still expired when we're done */
4040 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
4041 last_set_time = pdb_get_pass_last_set_time(pwd);
4043 if (!decode_pw_buffer(talloc_tos(),
4044 pass,
4045 &plaintext_buf,
4046 &len,
4047 STR_UNICODE)) {
4048 TALLOC_FREE(pwd);
4049 return False;
4052 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4053 TALLOC_FREE(pwd);
4054 return False;
4057 /* if it's a trust account, don't update /etc/passwd */
4058 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4059 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4060 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4061 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4062 } else {
4063 /* update the UNIX password */
4064 if (lp_unix_password_sync()) {
4065 struct passwd *passwd;
4067 if (pdb_get_username(pwd) == NULL) {
4068 DEBUG(1, ("chgpasswd: User without name???\n"));
4069 TALLOC_FREE(pwd);
4070 return False;
4073 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4074 if (passwd == NULL) {
4075 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4078 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4079 TALLOC_FREE(pwd);
4080 return False;
4082 TALLOC_FREE(passwd);
4086 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4089 * A level 25 change does reset the pwdlastset field, a level 24
4090 * change does not. I know this is probably not the full story, but
4091 * it is needed to make XP join LDAP correctly, without it the later
4092 * auth2 check can fail with PWD_MUST_CHANGE.
4094 if (level != 25) {
4096 * restore last set time as this is an admin change, not a
4097 * user pw change
4099 pdb_set_pass_last_set_time (pwd, last_set_time,
4100 last_set_state);
4103 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4105 /* update the SAMBA password */
4106 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4107 TALLOC_FREE(pwd);
4108 return False;
4111 TALLOC_FREE(pwd);
4113 return True;
4116 /*******************************************************************
4117 set_user_info_25
4118 ********************************************************************/
4120 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4121 struct samr_UserInfo25 *id25,
4122 struct samu *pwd)
4124 NTSTATUS status;
4126 if (id25 == NULL) {
4127 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4128 return NT_STATUS_INVALID_PARAMETER;
4131 copy_id25_to_sam_passwd(pwd, id25);
4133 /* write the change out */
4134 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4135 TALLOC_FREE(pwd);
4136 return status;
4140 * We need to "pdb_update_sam_account" before the unix primary group
4141 * is set, because the idealx scripts would also change the
4142 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4143 * the delete explicit / add explicit, which would then fail to find
4144 * the previous primaryGroupSid value.
4147 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4148 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4149 if ( !NT_STATUS_IS_OK(status) ) {
4150 return status;
4154 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
4155 * hereafter! */
4157 return NT_STATUS_OK;
4160 /*******************************************************************
4161 samr_SetUserInfo_internal
4162 ********************************************************************/
4164 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
4165 pipes_struct *p,
4166 struct policy_handle *user_handle,
4167 uint16_t level,
4168 union samr_UserInfo *info)
4170 NTSTATUS status;
4171 struct samu *pwd = NULL;
4172 DOM_SID sid;
4173 POLICY_HND *pol = user_handle;
4174 uint16_t switch_value = level;
4175 uint32_t acc_granted;
4176 uint32_t acc_required;
4177 bool ret;
4178 bool has_enough_rights = False;
4179 uint32_t acb_info;
4180 DISP_INFO *disp_info = NULL;
4182 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4184 /* find the policy handle. open a policy on it. */
4185 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4186 return NT_STATUS_INVALID_HANDLE;
4189 /* This is tricky. A WinXP domain join sets
4190 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4191 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4192 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4193 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4194 we'll use the set from the WinXP join as the basis. */
4196 switch (switch_value) {
4197 case 18:
4198 case 24:
4199 case 25:
4200 case 26:
4201 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4202 break;
4203 default:
4204 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4205 SA_RIGHT_USER_SET_ATTRIBUTES |
4206 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4207 break;
4210 status = access_check_samr_function(acc_granted,
4211 acc_required,
4212 fn_name);
4213 if (!NT_STATUS_IS_OK(status)) {
4214 return status;
4217 DEBUG(5, ("%s: sid:%s, level:%d\n",
4218 fn_name, sid_string_dbg(&sid), switch_value));
4220 if (info == NULL) {
4221 DEBUG(5, ("%s: NULL info level\n", fn_name));
4222 return NT_STATUS_INVALID_INFO_CLASS;
4225 if (!(pwd = samu_new(NULL))) {
4226 return NT_STATUS_NO_MEMORY;
4229 become_root();
4230 ret = pdb_getsampwsid(pwd, &sid);
4231 unbecome_root();
4233 if (!ret) {
4234 TALLOC_FREE(pwd);
4235 return NT_STATUS_NO_SUCH_USER;
4238 /* deal with machine password changes differently from userinfo changes */
4239 /* check to see if we have the sufficient rights */
4241 acb_info = pdb_get_acct_ctrl(pwd);
4242 if (acb_info & ACB_WSTRUST)
4243 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4244 &se_machine_account);
4245 else if (acb_info & ACB_NORMAL)
4246 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4247 &se_add_users);
4248 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4249 if (lp_enable_privileges()) {
4250 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4251 DOMAIN_GROUP_RID_ADMINS);
4255 DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4256 fn_name,
4257 uidtoname(p->pipe_user.ut.uid),
4258 has_enough_rights ? "" : " not"));
4260 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4262 if (has_enough_rights) {
4263 become_root();
4266 /* ok! user info levels (lots: see MSDEV help), off we go... */
4268 switch (switch_value) {
4270 case 7:
4271 status = set_user_info_7(p->mem_ctx,
4272 &info->info7, pwd);
4273 break;
4275 case 16:
4276 if (!set_user_info_16(&info->info16, pwd)) {
4277 status = NT_STATUS_ACCESS_DENIED;
4279 break;
4281 case 18:
4282 /* Used by AS/U JRA. */
4283 if (!set_user_info_18(&info->info18, pwd)) {
4284 status = NT_STATUS_ACCESS_DENIED;
4286 break;
4288 case 20:
4289 if (!set_user_info_20(&info->info20, pwd)) {
4290 status = NT_STATUS_ACCESS_DENIED;
4292 break;
4294 case 21:
4295 status = set_user_info_21(p->mem_ctx,
4296 &info->info21, pwd);
4297 break;
4299 case 23:
4300 if (!p->session_key.length) {
4301 status = NT_STATUS_NO_USER_SESSION_KEY;
4303 SamOEMhashBlob(info->info23.password.data, 516,
4304 &p->session_key);
4306 dump_data(100, info->info23.password.data, 516);
4308 status = set_user_info_23(p->mem_ctx,
4309 &info->info23, pwd);
4310 break;
4312 case 24:
4313 if (!p->session_key.length) {
4314 status = NT_STATUS_NO_USER_SESSION_KEY;
4316 SamOEMhashBlob(info->info24.password.data,
4317 516,
4318 &p->session_key);
4320 dump_data(100, info->info24.password.data, 516);
4322 if (!set_user_info_pw(info->info24.password.data, pwd,
4323 switch_value)) {
4324 status = NT_STATUS_ACCESS_DENIED;
4326 break;
4328 case 25:
4329 if (!p->session_key.length) {
4330 status = NT_STATUS_NO_USER_SESSION_KEY;
4332 encode_or_decode_arc4_passwd_buffer(info->info25.password.data,
4333 &p->session_key);
4335 dump_data(100, info->info25.password.data, 532);
4337 status = set_user_info_25(p->mem_ctx,
4338 &info->info25, pwd);
4339 if (!NT_STATUS_IS_OK(status)) {
4340 goto done;
4342 if (!set_user_info_pw(info->info25.password.data, pwd,
4343 switch_value)) {
4344 status = NT_STATUS_ACCESS_DENIED;
4346 break;
4348 case 26:
4349 if (!p->session_key.length) {
4350 status = NT_STATUS_NO_USER_SESSION_KEY;
4352 encode_or_decode_arc4_passwd_buffer(info->info26.password.data,
4353 &p->session_key);
4355 dump_data(100, info->info26.password.data, 516);
4357 if (!set_user_info_pw(info->info26.password.data, pwd,
4358 switch_value)) {
4359 status = NT_STATUS_ACCESS_DENIED;
4361 break;
4363 default:
4364 status = NT_STATUS_INVALID_INFO_CLASS;
4367 done:
4369 if (has_enough_rights) {
4370 unbecome_root();
4373 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4375 if (NT_STATUS_IS_OK(status)) {
4376 force_flush_samr_cache(disp_info);
4379 return status;
4382 /*******************************************************************
4383 _samr_SetUserInfo
4384 ********************************************************************/
4386 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4387 struct samr_SetUserInfo *r)
4389 return samr_SetUserInfo_internal("_samr_SetUserInfo",
4391 r->in.user_handle,
4392 r->in.level,
4393 r->in.info);
4396 /*******************************************************************
4397 _samr_SetUserInfo2
4398 ********************************************************************/
4400 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4401 struct samr_SetUserInfo2 *r)
4403 return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4405 r->in.user_handle,
4406 r->in.level,
4407 r->in.info);
4410 /*********************************************************************
4411 _samr_GetAliasMembership
4412 *********************************************************************/
4414 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4415 struct samr_GetAliasMembership *r)
4417 size_t num_alias_rids;
4418 uint32 *alias_rids;
4419 struct samr_info *info = NULL;
4420 size_t i;
4422 NTSTATUS ntstatus1;
4423 NTSTATUS ntstatus2;
4425 DOM_SID *members;
4427 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4429 /* find the policy handle. open a policy on it. */
4430 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4431 return NT_STATUS_INVALID_HANDLE;
4433 ntstatus1 = access_check_samr_function(info->acc_granted,
4434 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4435 "_samr_GetAliasMembership");
4436 ntstatus2 = access_check_samr_function(info->acc_granted,
4437 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4438 "_samr_GetAliasMembership");
4440 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4441 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4442 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4443 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4447 if (!sid_check_is_domain(&info->sid) &&
4448 !sid_check_is_builtin(&info->sid))
4449 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4451 if (r->in.sids->num_sids) {
4452 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4454 if (members == NULL)
4455 return NT_STATUS_NO_MEMORY;
4456 } else {
4457 members = NULL;
4460 for (i=0; i<r->in.sids->num_sids; i++)
4461 sid_copy(&members[i], r->in.sids->sids[i].sid);
4463 alias_rids = NULL;
4464 num_alias_rids = 0;
4466 become_root();
4467 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4468 r->in.sids->num_sids,
4469 &alias_rids, &num_alias_rids);
4470 unbecome_root();
4472 if (!NT_STATUS_IS_OK(ntstatus1)) {
4473 return ntstatus1;
4476 r->out.rids->count = num_alias_rids;
4477 r->out.rids->ids = alias_rids;
4479 return NT_STATUS_OK;
4482 /*********************************************************************
4483 _samr_GetMembersInAlias
4484 *********************************************************************/
4486 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4487 struct samr_GetMembersInAlias *r)
4489 NTSTATUS status;
4490 size_t i;
4491 size_t num_sids = 0;
4492 struct lsa_SidPtr *sids = NULL;
4493 DOM_SID *pdb_sids = NULL;
4495 DOM_SID alias_sid;
4497 uint32 acc_granted;
4499 /* find the policy handle. open a policy on it. */
4500 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4501 return NT_STATUS_INVALID_HANDLE;
4503 status = access_check_samr_function(acc_granted,
4504 SA_RIGHT_ALIAS_GET_MEMBERS,
4505 "_samr_GetMembersInAlias");
4506 if (!NT_STATUS_IS_OK(status)) {
4507 return status;
4510 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4512 become_root();
4513 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4514 unbecome_root();
4516 if (!NT_STATUS_IS_OK(status)) {
4517 return status;
4520 if (num_sids) {
4521 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4522 if (sids == NULL) {
4523 TALLOC_FREE(pdb_sids);
4524 return NT_STATUS_NO_MEMORY;
4528 for (i = 0; i < num_sids; i++) {
4529 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4530 if (!sids[i].sid) {
4531 TALLOC_FREE(pdb_sids);
4532 return NT_STATUS_NO_MEMORY;
4536 r->out.sids->num_sids = num_sids;
4537 r->out.sids->sids = sids;
4539 TALLOC_FREE(pdb_sids);
4541 return NT_STATUS_OK;
4544 /*********************************************************************
4545 _samr_QueryGroupMember
4546 *********************************************************************/
4548 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4549 struct samr_QueryGroupMember *r)
4551 DOM_SID group_sid;
4552 size_t i, num_members;
4554 uint32 *rid=NULL;
4555 uint32 *attr=NULL;
4557 uint32 acc_granted;
4559 NTSTATUS status;
4560 struct samr_RidTypeArray *rids = NULL;
4562 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4563 if (!rids) {
4564 return NT_STATUS_NO_MEMORY;
4567 /* find the policy handle. open a policy on it. */
4568 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4569 return NT_STATUS_INVALID_HANDLE;
4571 status = access_check_samr_function(acc_granted,
4572 SA_RIGHT_GROUP_GET_MEMBERS,
4573 "_samr_QueryGroupMember");
4574 if (!NT_STATUS_IS_OK(status)) {
4575 return status;
4578 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4580 if (!sid_check_is_in_our_domain(&group_sid)) {
4581 DEBUG(3, ("sid %s is not in our domain\n",
4582 sid_string_dbg(&group_sid)));
4583 return NT_STATUS_NO_SUCH_GROUP;
4586 DEBUG(10, ("lookup on Domain SID\n"));
4588 become_root();
4589 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4590 &rid, &num_members);
4591 unbecome_root();
4593 if (!NT_STATUS_IS_OK(status))
4594 return status;
4596 if (num_members) {
4597 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4598 if (attr == NULL) {
4599 return NT_STATUS_NO_MEMORY;
4601 } else {
4602 attr = NULL;
4605 for (i=0; i<num_members; i++)
4606 attr[i] = SID_NAME_USER;
4608 rids->count = num_members;
4609 rids->types = attr;
4610 rids->rids = rid;
4612 *r->out.rids = rids;
4614 return NT_STATUS_OK;
4617 /*********************************************************************
4618 _samr_AddAliasMember
4619 *********************************************************************/
4621 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4622 struct samr_AddAliasMember *r)
4624 DOM_SID alias_sid;
4625 uint32 acc_granted;
4626 SE_PRIV se_rights;
4627 bool can_add_accounts;
4628 NTSTATUS status;
4629 DISP_INFO *disp_info = NULL;
4631 /* Find the policy handle. Open a policy on it. */
4632 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4633 return NT_STATUS_INVALID_HANDLE;
4635 status = access_check_samr_function(acc_granted,
4636 SA_RIGHT_ALIAS_ADD_MEMBER,
4637 "_samr_AddAliasMember");
4638 if (!NT_STATUS_IS_OK(status)) {
4639 return status;
4642 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4644 se_priv_copy( &se_rights, &se_add_users );
4645 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4647 /******** BEGIN SeAddUsers BLOCK *********/
4649 if ( can_add_accounts )
4650 become_root();
4652 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4654 if ( can_add_accounts )
4655 unbecome_root();
4657 /******** END SeAddUsers BLOCK *********/
4659 if (NT_STATUS_IS_OK(status)) {
4660 force_flush_samr_cache(disp_info);
4663 return status;
4666 /*********************************************************************
4667 _samr_DeleteAliasMember
4668 *********************************************************************/
4670 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4671 struct samr_DeleteAliasMember *r)
4673 DOM_SID alias_sid;
4674 uint32 acc_granted;
4675 SE_PRIV se_rights;
4676 bool can_add_accounts;
4677 NTSTATUS status;
4678 DISP_INFO *disp_info = NULL;
4680 /* Find the policy handle. Open a policy on it. */
4681 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4682 return NT_STATUS_INVALID_HANDLE;
4684 status = access_check_samr_function(acc_granted,
4685 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4686 "_samr_DeleteAliasMember");
4687 if (!NT_STATUS_IS_OK(status)) {
4688 return status;
4691 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4692 sid_string_dbg(&alias_sid)));
4694 se_priv_copy( &se_rights, &se_add_users );
4695 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4697 /******** BEGIN SeAddUsers BLOCK *********/
4699 if ( can_add_accounts )
4700 become_root();
4702 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4704 if ( can_add_accounts )
4705 unbecome_root();
4707 /******** END SeAddUsers BLOCK *********/
4709 if (NT_STATUS_IS_OK(status)) {
4710 force_flush_samr_cache(disp_info);
4713 return status;
4716 /*********************************************************************
4717 _samr_AddGroupMember
4718 *********************************************************************/
4720 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4721 struct samr_AddGroupMember *r)
4723 NTSTATUS status;
4724 DOM_SID group_sid;
4725 uint32 group_rid;
4726 uint32 acc_granted;
4727 SE_PRIV se_rights;
4728 bool can_add_accounts;
4729 DISP_INFO *disp_info = NULL;
4731 /* Find the policy handle. Open a policy on it. */
4732 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4733 return NT_STATUS_INVALID_HANDLE;
4735 status = access_check_samr_function(acc_granted,
4736 SA_RIGHT_GROUP_ADD_MEMBER,
4737 "_samr_AddGroupMember");
4738 if (!NT_STATUS_IS_OK(status)) {
4739 return status;
4742 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4744 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4745 &group_rid)) {
4746 return NT_STATUS_INVALID_HANDLE;
4749 se_priv_copy( &se_rights, &se_add_users );
4750 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4752 /******** BEGIN SeAddUsers BLOCK *********/
4754 if ( can_add_accounts )
4755 become_root();
4757 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4759 if ( can_add_accounts )
4760 unbecome_root();
4762 /******** END SeAddUsers BLOCK *********/
4764 force_flush_samr_cache(disp_info);
4766 return status;
4769 /*********************************************************************
4770 _samr_DeleteGroupMember
4771 *********************************************************************/
4773 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4774 struct samr_DeleteGroupMember *r)
4777 NTSTATUS status;
4778 DOM_SID group_sid;
4779 uint32 group_rid;
4780 uint32 acc_granted;
4781 SE_PRIV se_rights;
4782 bool can_add_accounts;
4783 DISP_INFO *disp_info = NULL;
4786 * delete the group member named r->in.rid
4787 * who is a member of the sid associated with the handle
4788 * the rid is a user's rid as the group is a domain group.
4791 /* Find the policy handle. Open a policy on it. */
4792 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4793 return NT_STATUS_INVALID_HANDLE;
4795 status = access_check_samr_function(acc_granted,
4796 SA_RIGHT_GROUP_REMOVE_MEMBER,
4797 "_samr_DeleteGroupMember");
4798 if (!NT_STATUS_IS_OK(status)) {
4799 return status;
4802 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4803 &group_rid)) {
4804 return NT_STATUS_INVALID_HANDLE;
4807 se_priv_copy( &se_rights, &se_add_users );
4808 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4810 /******** BEGIN SeAddUsers BLOCK *********/
4812 if ( can_add_accounts )
4813 become_root();
4815 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4817 if ( can_add_accounts )
4818 unbecome_root();
4820 /******** END SeAddUsers BLOCK *********/
4822 force_flush_samr_cache(disp_info);
4824 return status;
4827 /*********************************************************************
4828 _samr_DeleteUser
4829 *********************************************************************/
4831 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4832 struct samr_DeleteUser *r)
4834 NTSTATUS status;
4835 DOM_SID user_sid;
4836 struct samu *sam_pass=NULL;
4837 uint32 acc_granted;
4838 bool can_add_accounts;
4839 uint32 acb_info;
4840 DISP_INFO *disp_info = NULL;
4841 bool ret;
4843 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4845 /* Find the policy handle. Open a policy on it. */
4846 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4847 return NT_STATUS_INVALID_HANDLE;
4849 status = access_check_samr_function(acc_granted,
4850 STD_RIGHT_DELETE_ACCESS,
4851 "_samr_DeleteUser");
4852 if (!NT_STATUS_IS_OK(status)) {
4853 return status;
4856 if (!sid_check_is_in_our_domain(&user_sid))
4857 return NT_STATUS_CANNOT_DELETE;
4859 /* check if the user exists before trying to delete */
4860 if ( !(sam_pass = samu_new( NULL )) ) {
4861 return NT_STATUS_NO_MEMORY;
4864 become_root();
4865 ret = pdb_getsampwsid(sam_pass, &user_sid);
4866 unbecome_root();
4868 if( !ret ) {
4869 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4870 sid_string_dbg(&user_sid)));
4871 TALLOC_FREE(sam_pass);
4872 return NT_STATUS_NO_SUCH_USER;
4875 acb_info = pdb_get_acct_ctrl(sam_pass);
4877 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4878 if ( acb_info & ACB_WSTRUST ) {
4879 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4880 } else {
4881 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4884 /******** BEGIN SeAddUsers BLOCK *********/
4886 if ( can_add_accounts )
4887 become_root();
4889 status = pdb_delete_user(p->mem_ctx, sam_pass);
4891 if ( can_add_accounts )
4892 unbecome_root();
4894 /******** END SeAddUsers BLOCK *********/
4896 if ( !NT_STATUS_IS_OK(status) ) {
4897 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4898 "user %s: %s.\n", pdb_get_username(sam_pass),
4899 nt_errstr(status)));
4900 TALLOC_FREE(sam_pass);
4901 return status;
4905 TALLOC_FREE(sam_pass);
4907 if (!close_policy_hnd(p, r->in.user_handle))
4908 return NT_STATUS_OBJECT_NAME_INVALID;
4910 force_flush_samr_cache(disp_info);
4912 return NT_STATUS_OK;
4915 /*********************************************************************
4916 _samr_DeleteDomainGroup
4917 *********************************************************************/
4919 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4920 struct samr_DeleteDomainGroup *r)
4922 NTSTATUS status;
4923 DOM_SID group_sid;
4924 uint32 group_rid;
4925 uint32 acc_granted;
4926 SE_PRIV se_rights;
4927 bool can_add_accounts;
4928 DISP_INFO *disp_info = NULL;
4930 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4932 /* Find the policy handle. Open a policy on it. */
4933 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4934 return NT_STATUS_INVALID_HANDLE;
4936 status = access_check_samr_function(acc_granted,
4937 STD_RIGHT_DELETE_ACCESS,
4938 "_samr_DeleteDomainGroup");
4939 if (!NT_STATUS_IS_OK(status)) {
4940 return status;
4943 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4945 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4946 &group_rid)) {
4947 return NT_STATUS_NO_SUCH_GROUP;
4950 se_priv_copy( &se_rights, &se_add_users );
4951 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4953 /******** BEGIN SeAddUsers BLOCK *********/
4955 if ( can_add_accounts )
4956 become_root();
4958 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4960 if ( can_add_accounts )
4961 unbecome_root();
4963 /******** END SeAddUsers BLOCK *********/
4965 if ( !NT_STATUS_IS_OK(status) ) {
4966 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4967 "entry for group %s: %s\n",
4968 sid_string_dbg(&group_sid),
4969 nt_errstr(status)));
4970 return status;
4973 if (!close_policy_hnd(p, r->in.group_handle))
4974 return NT_STATUS_OBJECT_NAME_INVALID;
4976 force_flush_samr_cache(disp_info);
4978 return NT_STATUS_OK;
4981 /*********************************************************************
4982 _samr_DeleteDomAlias
4983 *********************************************************************/
4985 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4986 struct samr_DeleteDomAlias *r)
4988 DOM_SID alias_sid;
4989 uint32 acc_granted;
4990 SE_PRIV se_rights;
4991 bool can_add_accounts;
4992 NTSTATUS status;
4993 DISP_INFO *disp_info = NULL;
4995 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4997 /* Find the policy handle. Open a policy on it. */
4998 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4999 return NT_STATUS_INVALID_HANDLE;
5001 /* copy the handle to the outgoing reply */
5003 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
5005 status = access_check_samr_function(acc_granted,
5006 STD_RIGHT_DELETE_ACCESS,
5007 "_samr_DeleteDomAlias");
5008 if (!NT_STATUS_IS_OK(status)) {
5009 return status;
5012 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5014 /* Don't let Windows delete builtin groups */
5016 if ( sid_check_is_in_builtin( &alias_sid ) ) {
5017 return NT_STATUS_SPECIAL_ACCOUNT;
5020 if (!sid_check_is_in_our_domain(&alias_sid))
5021 return NT_STATUS_NO_SUCH_ALIAS;
5023 DEBUG(10, ("lookup on Local SID\n"));
5025 se_priv_copy( &se_rights, &se_add_users );
5026 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5028 /******** BEGIN SeAddUsers BLOCK *********/
5030 if ( can_add_accounts )
5031 become_root();
5033 /* Have passdb delete the alias */
5034 status = pdb_delete_alias(&alias_sid);
5036 if ( can_add_accounts )
5037 unbecome_root();
5039 /******** END SeAddUsers BLOCK *********/
5041 if ( !NT_STATUS_IS_OK(status))
5042 return status;
5044 if (!close_policy_hnd(p, r->in.alias_handle))
5045 return NT_STATUS_OBJECT_NAME_INVALID;
5047 force_flush_samr_cache(disp_info);
5049 return NT_STATUS_OK;
5052 /*********************************************************************
5053 _samr_CreateDomainGroup
5054 *********************************************************************/
5056 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5057 struct samr_CreateDomainGroup *r)
5060 NTSTATUS status;
5061 DOM_SID dom_sid;
5062 DOM_SID info_sid;
5063 const char *name;
5064 struct samr_info *info;
5065 uint32 acc_granted;
5066 SE_PRIV se_rights;
5067 bool can_add_accounts;
5068 DISP_INFO *disp_info = NULL;
5070 /* Find the policy handle. Open a policy on it. */
5071 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5072 return NT_STATUS_INVALID_HANDLE;
5074 status = access_check_samr_function(acc_granted,
5075 SA_RIGHT_DOMAIN_CREATE_GROUP,
5076 "_samr_CreateDomainGroup");
5077 if (!NT_STATUS_IS_OK(status)) {
5078 return status;
5081 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5082 return NT_STATUS_ACCESS_DENIED;
5084 name = r->in.name->string;
5085 if (name == NULL) {
5086 return NT_STATUS_NO_MEMORY;
5089 status = can_create(p->mem_ctx, name);
5090 if (!NT_STATUS_IS_OK(status)) {
5091 return status;
5094 se_priv_copy( &se_rights, &se_add_users );
5095 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5097 /******** BEGIN SeAddUsers BLOCK *********/
5099 if ( can_add_accounts )
5100 become_root();
5102 /* check that we successfully create the UNIX group */
5104 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5106 if ( can_add_accounts )
5107 unbecome_root();
5109 /******** END SeAddUsers BLOCK *********/
5111 /* check if we should bail out here */
5113 if ( !NT_STATUS_IS_OK(status) )
5114 return status;
5116 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5118 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5119 return NT_STATUS_NO_MEMORY;
5121 /* they created it; let the user do what he wants with it */
5123 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5125 /* get a (unique) handle. open a policy on it. */
5126 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5127 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5129 force_flush_samr_cache(disp_info);
5131 return NT_STATUS_OK;
5134 /*********************************************************************
5135 _samr_CreateDomAlias
5136 *********************************************************************/
5138 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5139 struct samr_CreateDomAlias *r)
5141 DOM_SID dom_sid;
5142 DOM_SID info_sid;
5143 const char *name = NULL;
5144 struct samr_info *info;
5145 uint32 acc_granted;
5146 gid_t gid;
5147 NTSTATUS result;
5148 SE_PRIV se_rights;
5149 bool can_add_accounts;
5150 DISP_INFO *disp_info = NULL;
5152 /* Find the policy handle. Open a policy on it. */
5153 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5154 return NT_STATUS_INVALID_HANDLE;
5156 result = access_check_samr_function(acc_granted,
5157 SA_RIGHT_DOMAIN_CREATE_ALIAS,
5158 "_samr_CreateDomAlias");
5159 if (!NT_STATUS_IS_OK(result)) {
5160 return result;
5163 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5164 return NT_STATUS_ACCESS_DENIED;
5166 name = r->in.alias_name->string;
5168 se_priv_copy( &se_rights, &se_add_users );
5169 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5171 result = can_create(p->mem_ctx, name);
5172 if (!NT_STATUS_IS_OK(result)) {
5173 return result;
5176 /******** BEGIN SeAddUsers BLOCK *********/
5178 if ( can_add_accounts )
5179 become_root();
5181 /* Have passdb create the alias */
5182 result = pdb_create_alias(name, r->out.rid);
5184 if ( can_add_accounts )
5185 unbecome_root();
5187 /******** END SeAddUsers BLOCK *********/
5189 if (!NT_STATUS_IS_OK(result)) {
5190 DEBUG(10, ("pdb_create_alias failed: %s\n",
5191 nt_errstr(result)));
5192 return result;
5195 sid_copy(&info_sid, get_global_sam_sid());
5196 sid_append_rid(&info_sid, *r->out.rid);
5198 if (!sid_to_gid(&info_sid, &gid)) {
5199 DEBUG(10, ("Could not find alias just created\n"));
5200 return NT_STATUS_ACCESS_DENIED;
5203 /* check if the group has been successfully created */
5204 if ( getgrgid(gid) == NULL ) {
5205 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5206 gid));
5207 return NT_STATUS_ACCESS_DENIED;
5210 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5211 return NT_STATUS_NO_MEMORY;
5213 /* they created it; let the user do what he wants with it */
5215 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5217 /* get a (unique) handle. open a policy on it. */
5218 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5219 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5221 force_flush_samr_cache(disp_info);
5223 return NT_STATUS_OK;
5226 /*********************************************************************
5227 _samr_QueryGroupInfo
5228 *********************************************************************/
5230 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5231 struct samr_QueryGroupInfo *r)
5233 NTSTATUS status;
5234 DOM_SID group_sid;
5235 GROUP_MAP map;
5236 union samr_GroupInfo *info = NULL;
5237 uint32 acc_granted;
5238 bool ret;
5239 uint32_t attributes = SE_GROUP_MANDATORY |
5240 SE_GROUP_ENABLED_BY_DEFAULT |
5241 SE_GROUP_ENABLED;
5242 const char *group_name = NULL;
5243 const char *group_description = NULL;
5245 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5246 return NT_STATUS_INVALID_HANDLE;
5248 status = access_check_samr_function(acc_granted,
5249 SA_RIGHT_GROUP_LOOKUP_INFO,
5250 "_samr_QueryGroupInfo");
5251 if (!NT_STATUS_IS_OK(status)) {
5252 return status;
5255 become_root();
5256 ret = get_domain_group_from_sid(group_sid, &map);
5257 unbecome_root();
5258 if (!ret)
5259 return NT_STATUS_INVALID_HANDLE;
5261 /* FIXME: map contains fstrings */
5262 group_name = talloc_strdup(r, map.nt_name);
5263 group_description = talloc_strdup(r, map.comment);
5265 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5266 if (!info) {
5267 return NT_STATUS_NO_MEMORY;
5270 switch (r->in.level) {
5271 case 1: {
5272 uint32 *members;
5273 size_t num_members;
5275 become_root();
5276 status = pdb_enum_group_members(
5277 p->mem_ctx, &group_sid, &members, &num_members);
5278 unbecome_root();
5280 if (!NT_STATUS_IS_OK(status)) {
5281 return status;
5284 init_samr_group_info1(&info->all,
5285 group_name,
5286 attributes,
5287 num_members,
5288 group_description);
5289 break;
5291 case 2:
5292 init_samr_group_info2(&info->name,
5293 group_name);
5294 break;
5295 case 3:
5296 init_samr_group_info3(&info->attributes,
5297 attributes);
5298 break;
5299 case 4:
5300 init_samr_group_info4(&info->description,
5301 group_description);
5302 break;
5303 case 5: {
5305 uint32 *members;
5306 size_t num_members;
5310 become_root();
5311 status = pdb_enum_group_members(
5312 p->mem_ctx, &group_sid, &members, &num_members);
5313 unbecome_root();
5315 if (!NT_STATUS_IS_OK(status)) {
5316 return status;
5319 init_samr_group_info5(&info->all2,
5320 group_name,
5321 attributes,
5322 0, /* num_members - in w2k3 this is always 0 */
5323 group_description);
5325 break;
5327 default:
5328 return NT_STATUS_INVALID_INFO_CLASS;
5331 *r->out.info = info;
5333 return NT_STATUS_OK;
5336 /*********************************************************************
5337 _samr_SetGroupInfo
5338 *********************************************************************/
5340 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5341 struct samr_SetGroupInfo *r)
5343 DOM_SID group_sid;
5344 GROUP_MAP map;
5345 uint32 acc_granted;
5346 NTSTATUS status;
5347 bool ret;
5348 bool can_mod_accounts;
5349 DISP_INFO *disp_info = NULL;
5351 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5352 return NT_STATUS_INVALID_HANDLE;
5354 status = access_check_samr_function(acc_granted,
5355 SA_RIGHT_GROUP_SET_INFO,
5356 "_samr_SetGroupInfo");
5357 if (!NT_STATUS_IS_OK(status)) {
5358 return status;
5361 become_root();
5362 ret = get_domain_group_from_sid(group_sid, &map);
5363 unbecome_root();
5364 if (!ret)
5365 return NT_STATUS_NO_SUCH_GROUP;
5367 switch (r->in.level) {
5368 case 1:
5369 fstrcpy(map.comment, r->in.info->all.description.string);
5370 break;
5371 case 4:
5372 fstrcpy(map.comment, r->in.info->description.string);
5373 break;
5374 default:
5375 return NT_STATUS_INVALID_INFO_CLASS;
5378 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5380 /******** BEGIN SeAddUsers BLOCK *********/
5382 if ( can_mod_accounts )
5383 become_root();
5385 status = pdb_update_group_mapping_entry(&map);
5387 if ( can_mod_accounts )
5388 unbecome_root();
5390 /******** End SeAddUsers BLOCK *********/
5392 if (NT_STATUS_IS_OK(status)) {
5393 force_flush_samr_cache(disp_info);
5396 return status;
5399 /*********************************************************************
5400 _samr_SetAliasInfo
5401 *********************************************************************/
5403 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5404 struct samr_SetAliasInfo *r)
5406 DOM_SID group_sid;
5407 struct acct_info info;
5408 uint32 acc_granted;
5409 bool can_mod_accounts;
5410 NTSTATUS status;
5411 DISP_INFO *disp_info = NULL;
5413 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5414 return NT_STATUS_INVALID_HANDLE;
5416 status = access_check_samr_function(acc_granted,
5417 SA_RIGHT_ALIAS_SET_INFO,
5418 "_samr_SetAliasInfo");
5419 if (!NT_STATUS_IS_OK(status)) {
5420 return status;
5423 /* get the current group information */
5425 become_root();
5426 status = pdb_get_aliasinfo( &group_sid, &info );
5427 unbecome_root();
5429 if ( !NT_STATUS_IS_OK(status))
5430 return status;
5432 switch (r->in.level) {
5433 case ALIASINFONAME:
5435 fstring group_name;
5437 /* We currently do not support renaming groups in the
5438 the BUILTIN domain. Refer to util_builtin.c to understand
5439 why. The eventually needs to be fixed to be like Windows
5440 where you can rename builtin groups, just not delete them */
5442 if ( sid_check_is_in_builtin( &group_sid ) ) {
5443 return NT_STATUS_SPECIAL_ACCOUNT;
5446 /* There has to be a valid name (and it has to be different) */
5448 if ( !r->in.info->name.string )
5449 return NT_STATUS_INVALID_PARAMETER;
5451 /* If the name is the same just reply "ok". Yes this
5452 doesn't allow you to change the case of a group name. */
5454 if ( strequal( r->in.info->name.string, info.acct_name ) )
5455 return NT_STATUS_OK;
5457 fstrcpy( info.acct_name, r->in.info->name.string);
5459 /* make sure the name doesn't already exist as a user
5460 or local group */
5462 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5463 status = can_create( p->mem_ctx, group_name );
5464 if ( !NT_STATUS_IS_OK( status ) )
5465 return status;
5466 break;
5468 case ALIASINFODESCRIPTION:
5469 if (r->in.info->description.string) {
5470 fstrcpy(info.acct_desc,
5471 r->in.info->description.string);
5472 } else {
5473 fstrcpy( info.acct_desc, "" );
5475 break;
5476 default:
5477 return NT_STATUS_INVALID_INFO_CLASS;
5480 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5482 /******** BEGIN SeAddUsers BLOCK *********/
5484 if ( can_mod_accounts )
5485 become_root();
5487 status = pdb_set_aliasinfo( &group_sid, &info );
5489 if ( can_mod_accounts )
5490 unbecome_root();
5492 /******** End SeAddUsers BLOCK *********/
5494 if (NT_STATUS_IS_OK(status))
5495 force_flush_samr_cache(disp_info);
5497 return status;
5500 /****************************************************************
5501 _samr_GetDomPwInfo
5502 ****************************************************************/
5504 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5505 struct samr_GetDomPwInfo *r)
5507 uint32_t min_password_length = 0;
5508 uint32_t password_properties = 0;
5510 /* Perform access check. Since this rpc does not require a
5511 policy handle it will not be caught by the access checks on
5512 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5514 if (!pipe_access_check(p)) {
5515 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5516 return NT_STATUS_ACCESS_DENIED;
5519 become_root();
5520 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5521 &min_password_length);
5522 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5523 &password_properties);
5524 unbecome_root();
5526 if (lp_check_password_script() && *lp_check_password_script()) {
5527 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5530 r->out.info->min_password_length = min_password_length;
5531 r->out.info->password_properties = password_properties;
5533 return NT_STATUS_OK;
5536 /*********************************************************************
5537 _samr_OpenGroup
5538 *********************************************************************/
5540 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5541 struct samr_OpenGroup *r)
5544 DOM_SID sid;
5545 DOM_SID info_sid;
5546 GROUP_MAP map;
5547 struct samr_info *info;
5548 SEC_DESC *psd = NULL;
5549 uint32 acc_granted;
5550 uint32 des_access = r->in.access_mask;
5551 size_t sd_size;
5552 NTSTATUS status;
5553 fstring sid_string;
5554 bool ret;
5555 SE_PRIV se_rights;
5557 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5558 return NT_STATUS_INVALID_HANDLE;
5560 status = access_check_samr_function(acc_granted,
5561 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5562 "_samr_OpenGroup");
5564 if ( !NT_STATUS_IS_OK(status) )
5565 return status;
5567 /*check if access can be granted as requested by client. */
5568 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
5570 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5571 se_map_generic(&des_access,&grp_generic_mapping);
5573 se_priv_copy( &se_rights, &se_add_users );
5575 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5576 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5577 &acc_granted, "_samr_OpenGroup");
5579 if ( !NT_STATUS_IS_OK(status) )
5580 return status;
5582 /* this should not be hard-coded like this */
5584 if (!sid_equal(&sid, get_global_sam_sid()))
5585 return NT_STATUS_ACCESS_DENIED;
5587 sid_copy(&info_sid, get_global_sam_sid());
5588 sid_append_rid(&info_sid, r->in.rid);
5589 sid_to_fstring(sid_string, &info_sid);
5591 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5592 return NT_STATUS_NO_MEMORY;
5594 info->acc_granted = acc_granted;
5596 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5598 /* check if that group really exists */
5599 become_root();
5600 ret = get_domain_group_from_sid(info->sid, &map);
5601 unbecome_root();
5602 if (!ret)
5603 return NT_STATUS_NO_SUCH_GROUP;
5605 /* get a (unique) handle. open a policy on it. */
5606 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5607 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5609 return NT_STATUS_OK;
5612 /*********************************************************************
5613 _samr_RemoveMemberFromForeignDomain
5614 *********************************************************************/
5616 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5617 struct samr_RemoveMemberFromForeignDomain *r)
5619 DOM_SID delete_sid, domain_sid;
5620 uint32 acc_granted;
5621 NTSTATUS result;
5622 DISP_INFO *disp_info = NULL;
5624 sid_copy( &delete_sid, r->in.sid );
5626 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5627 sid_string_dbg(&delete_sid)));
5629 /* Find the policy handle. Open a policy on it. */
5631 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5632 &acc_granted, &disp_info))
5633 return NT_STATUS_INVALID_HANDLE;
5635 result = access_check_samr_function(acc_granted,
5636 STD_RIGHT_DELETE_ACCESS,
5637 "_samr_RemoveMemberFromForeignDomain");
5639 if (!NT_STATUS_IS_OK(result))
5640 return result;
5642 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5643 sid_string_dbg(&domain_sid)));
5645 /* we can only delete a user from a group since we don't have
5646 nested groups anyways. So in the latter case, just say OK */
5648 /* TODO: The above comment nowadays is bogus. Since we have nested
5649 * groups now, and aliases members are never reported out of the unix
5650 * group membership, the "just say OK" makes this call a no-op. For
5651 * us. This needs fixing however. */
5653 /* I've only ever seen this in the wild when deleting a user from
5654 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5655 * is the user about to be deleted. I very much suspect this is the
5656 * only application of this call. To verify this, let people report
5657 * other cases. */
5659 if (!sid_check_is_builtin(&domain_sid)) {
5660 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5661 "global_sam_sid() = %s\n",
5662 sid_string_dbg(&domain_sid),
5663 sid_string_dbg(get_global_sam_sid())));
5664 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5665 return NT_STATUS_OK;
5668 force_flush_samr_cache(disp_info);
5670 result = NT_STATUS_OK;
5672 return result;
5675 /*******************************************************************
5676 _samr_QueryDomainInfo2
5677 ********************************************************************/
5679 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5680 struct samr_QueryDomainInfo2 *r)
5682 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5684 r->in.domain_handle,
5685 r->in.level,
5686 r->out.info);
5689 /*******************************************************************
5690 _samr_SetDomainInfo
5691 ********************************************************************/
5693 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5694 struct samr_SetDomainInfo *r)
5696 struct samr_info *info = NULL;
5697 time_t u_expire, u_min_age;
5698 time_t u_logout;
5699 time_t u_lock_duration, u_reset_time;
5700 NTSTATUS result;
5702 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5704 /* find the policy handle. open a policy on it. */
5705 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5706 return NT_STATUS_INVALID_HANDLE;
5708 /* We do have different access bits for info
5709 * levels here, but we're really just looking for
5710 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5711 * this maps to different specific bits. So
5712 * assume if we have SA_RIGHT_DOMAIN_SET_INFO_1
5713 * set we are ok. */
5715 result = access_check_samr_function(info->acc_granted,
5716 SA_RIGHT_DOMAIN_SET_INFO_1,
5717 "_samr_SetDomainInfo");
5719 if (!NT_STATUS_IS_OK(result))
5720 return result;
5722 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5724 switch (r->in.level) {
5725 case 0x01:
5726 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5727 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5728 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5729 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5730 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5731 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5732 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5733 break;
5734 case 0x02:
5735 break;
5736 case 0x03:
5737 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5738 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5739 break;
5740 case 0x05:
5741 break;
5742 case 0x06:
5743 break;
5744 case 0x07:
5745 break;
5746 case 0x0c:
5747 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5748 if (u_lock_duration != -1)
5749 u_lock_duration /= 60;
5751 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5753 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5754 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5755 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5756 break;
5757 default:
5758 return NT_STATUS_INVALID_INFO_CLASS;
5761 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5763 return NT_STATUS_OK;
5766 /****************************************************************
5767 _samr_GetDisplayEnumerationIndex
5768 ****************************************************************/
5770 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5771 struct samr_GetDisplayEnumerationIndex *r)
5773 struct samr_info *info = NULL;
5774 uint32_t max_entries = (uint32_t) -1;
5775 uint32_t enum_context = 0;
5776 int i;
5777 uint32_t num_account = 0;
5778 struct samr_displayentry *entries = NULL;
5779 NTSTATUS status;
5781 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5783 /* find the policy handle. open a policy on it. */
5784 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5785 return NT_STATUS_INVALID_HANDLE;
5788 status = access_check_samr_function(info->acc_granted,
5789 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
5790 "_samr_GetDisplayEnumerationIndex");
5791 if (!NT_STATUS_IS_OK(status)) {
5792 return status;
5795 if ((r->in.level < 1) || (r->in.level > 3)) {
5796 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5797 "Unknown info level (%u)\n",
5798 r->in.level));
5799 return NT_STATUS_INVALID_INFO_CLASS;
5802 become_root();
5804 /* The following done as ROOT. Don't return without unbecome_root(). */
5806 switch (r->in.level) {
5807 case 1:
5808 if (info->disp_info->users == NULL) {
5809 info->disp_info->users = pdb_search_users(ACB_NORMAL);
5810 if (info->disp_info->users == NULL) {
5811 unbecome_root();
5812 return NT_STATUS_ACCESS_DENIED;
5814 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5815 "starting user enumeration at index %u\n",
5816 (unsigned int)enum_context));
5817 } else {
5818 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5819 "using cached user enumeration at index %u\n",
5820 (unsigned int)enum_context));
5822 num_account = pdb_search_entries(info->disp_info->users,
5823 enum_context, max_entries,
5824 &entries);
5825 break;
5826 case 2:
5827 if (info->disp_info->machines == NULL) {
5828 info->disp_info->machines =
5829 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5830 if (info->disp_info->machines == NULL) {
5831 unbecome_root();
5832 return NT_STATUS_ACCESS_DENIED;
5834 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5835 "starting machine enumeration at index %u\n",
5836 (unsigned int)enum_context));
5837 } else {
5838 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5839 "using cached machine enumeration at index %u\n",
5840 (unsigned int)enum_context));
5842 num_account = pdb_search_entries(info->disp_info->machines,
5843 enum_context, max_entries,
5844 &entries);
5845 break;
5846 case 3:
5847 if (info->disp_info->groups == NULL) {
5848 info->disp_info->groups = pdb_search_groups();
5849 if (info->disp_info->groups == NULL) {
5850 unbecome_root();
5851 return NT_STATUS_ACCESS_DENIED;
5853 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5854 "starting group enumeration at index %u\n",
5855 (unsigned int)enum_context));
5856 } else {
5857 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5858 "using cached group enumeration at index %u\n",
5859 (unsigned int)enum_context));
5861 num_account = pdb_search_entries(info->disp_info->groups,
5862 enum_context, max_entries,
5863 &entries);
5864 break;
5865 default:
5866 unbecome_root();
5867 smb_panic("info class changed");
5868 break;
5871 unbecome_root();
5873 /* Ensure we cache this enumeration. */
5874 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5876 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5877 r->in.name->string));
5879 for (i=0; i<num_account; i++) {
5880 if (strequal(entries[i].account_name, r->in.name->string)) {
5881 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5882 "found %s at idx %d\n",
5883 r->in.name->string, i));
5884 *r->out.idx = i;
5885 return NT_STATUS_OK;
5889 /* assuming account_name lives at the very end */
5890 *r->out.idx = num_account;
5892 return NT_STATUS_NO_MORE_ENTRIES;
5895 /****************************************************************
5896 _samr_GetDisplayEnumerationIndex2
5897 ****************************************************************/
5899 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5900 struct samr_GetDisplayEnumerationIndex2 *r)
5902 struct samr_GetDisplayEnumerationIndex q;
5904 q.in.domain_handle = r->in.domain_handle;
5905 q.in.level = r->in.level;
5906 q.in.name = r->in.name;
5908 q.out.idx = r->out.idx;
5910 return _samr_GetDisplayEnumerationIndex(p, &q);
5913 /****************************************************************
5914 ****************************************************************/
5916 NTSTATUS _samr_Shutdown(pipes_struct *p,
5917 struct samr_Shutdown *r)
5919 p->rng_fault_state = true;
5920 return NT_STATUS_NOT_IMPLEMENTED;
5923 /****************************************************************
5924 ****************************************************************/
5926 NTSTATUS _samr_CreateUser(pipes_struct *p,
5927 struct samr_CreateUser *r)
5929 p->rng_fault_state = true;
5930 return NT_STATUS_NOT_IMPLEMENTED;
5933 /****************************************************************
5934 ****************************************************************/
5936 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5937 struct samr_SetMemberAttributesOfGroup *r)
5939 p->rng_fault_state = true;
5940 return NT_STATUS_NOT_IMPLEMENTED;
5943 /****************************************************************
5944 ****************************************************************/
5946 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5947 struct samr_ChangePasswordUser *r)
5949 p->rng_fault_state = true;
5950 return NT_STATUS_NOT_IMPLEMENTED;
5953 /****************************************************************
5954 ****************************************************************/
5956 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5957 struct samr_TestPrivateFunctionsDomain *r)
5959 p->rng_fault_state = true;
5960 return NT_STATUS_NOT_IMPLEMENTED;
5963 /****************************************************************
5964 ****************************************************************/
5966 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5967 struct samr_TestPrivateFunctionsUser *r)
5969 p->rng_fault_state = true;
5970 return NT_STATUS_NOT_IMPLEMENTED;
5973 /****************************************************************
5974 ****************************************************************/
5976 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5977 struct samr_QueryUserInfo2 *r)
5979 p->rng_fault_state = true;
5980 return NT_STATUS_NOT_IMPLEMENTED;
5983 /****************************************************************
5984 ****************************************************************/
5986 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5987 struct samr_AddMultipleMembersToAlias *r)
5989 p->rng_fault_state = true;
5990 return NT_STATUS_NOT_IMPLEMENTED;
5993 /****************************************************************
5994 ****************************************************************/
5996 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5997 struct samr_RemoveMultipleMembersFromAlias *r)
5999 p->rng_fault_state = true;
6000 return NT_STATUS_NOT_IMPLEMENTED;
6003 /****************************************************************
6004 ****************************************************************/
6006 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
6007 struct samr_OemChangePasswordUser2 *r)
6009 p->rng_fault_state = true;
6010 return NT_STATUS_NOT_IMPLEMENTED;
6013 /****************************************************************
6014 ****************************************************************/
6016 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6017 struct samr_SetBootKeyInformation *r)
6019 p->rng_fault_state = true;
6020 return NT_STATUS_NOT_IMPLEMENTED;
6023 /****************************************************************
6024 ****************************************************************/
6026 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6027 struct samr_GetBootKeyInformation *r)
6029 p->rng_fault_state = true;
6030 return NT_STATUS_NOT_IMPLEMENTED;
6033 /****************************************************************
6034 ****************************************************************/
6036 NTSTATUS _samr_Connect3(pipes_struct *p,
6037 struct samr_Connect3 *r)
6039 p->rng_fault_state = true;
6040 return NT_STATUS_NOT_IMPLEMENTED;
6043 /****************************************************************
6044 ****************************************************************/
6046 NTSTATUS _samr_RidToSid(pipes_struct *p,
6047 struct samr_RidToSid *r)
6049 p->rng_fault_state = true;
6050 return NT_STATUS_NOT_IMPLEMENTED;
6053 /****************************************************************
6054 ****************************************************************/
6056 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6057 struct samr_SetDsrmPassword *r)
6059 p->rng_fault_state = true;
6060 return NT_STATUS_NOT_IMPLEMENTED;
6063 /****************************************************************
6064 ****************************************************************/
6066 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6067 struct samr_ValidatePassword *r)
6069 p->rng_fault_state = true;
6070 return NT_STATUS_NOT_IMPLEMENTED;