Fix bug #6089 - Winbind samr_OpenDomain not possible with Samba 3.2.6+
[Samba.git] / source / rpc_server / srv_samr_nt.c
blobf14c53b20a3875013fa108f24f4dbfa27cae996f
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 /*check if access can be granted as requested by client. */
624 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
626 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
627 se_map_generic( &des_access, &dom_generic_mapping );
629 se_priv_copy( &se_rights, &se_machine_account );
630 se_priv_add( &se_rights, &se_add_users );
632 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
633 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
634 &acc_granted, "_samr_OpenDomain" );
636 if ( !NT_STATUS_IS_OK(status) )
637 return status;
639 if (!sid_check_is_domain(r->in.sid) &&
640 !sid_check_is_builtin(r->in.sid)) {
641 return NT_STATUS_NO_SUCH_DOMAIN;
644 /* associate the domain SID with the (unique) handle. */
645 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
646 return NT_STATUS_NO_MEMORY;
647 info->acc_granted = acc_granted;
649 /* get a (unique) handle. open a policy on it. */
650 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
651 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
653 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
655 return NT_STATUS_OK;
658 /*******************************************************************
659 _samr_GetUserPwInfo
660 ********************************************************************/
662 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
663 struct samr_GetUserPwInfo *r)
665 struct samr_info *info = NULL;
666 enum lsa_SidType sid_type;
667 uint32_t min_password_length = 0;
668 uint32_t password_properties = 0;
669 bool ret = false;
670 NTSTATUS status;
672 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
674 /* find the policy handle. open a policy on it. */
675 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
676 return NT_STATUS_INVALID_HANDLE;
679 status = access_check_samr_function(info->acc_granted,
680 SAMR_USER_ACCESS_GET_ATTRIBUTES,
681 "_samr_GetUserPwInfo" );
682 if (!NT_STATUS_IS_OK(status)) {
683 return status;
686 if (!sid_check_is_in_our_domain(&info->sid)) {
687 return NT_STATUS_OBJECT_TYPE_MISMATCH;
690 become_root();
691 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
692 unbecome_root();
693 if (ret == false) {
694 return NT_STATUS_NO_SUCH_USER;
697 switch (sid_type) {
698 case SID_NAME_USER:
699 become_root();
700 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
701 &min_password_length);
702 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
703 &password_properties);
704 unbecome_root();
706 if (lp_check_password_script() && *lp_check_password_script()) {
707 password_properties |= DOMAIN_PASSWORD_COMPLEX;
710 break;
711 default:
712 break;
715 r->out.info->min_password_length = min_password_length;
716 r->out.info->password_properties = password_properties;
718 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
720 return NT_STATUS_OK;
723 /*******************************************************************
724 ********************************************************************/
726 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
727 DOM_SID *sid, uint32 *acc_granted,
728 DISP_INFO **ppdisp_info)
730 struct samr_info *info = NULL;
732 /* find the policy handle. open a policy on it. */
733 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
734 return False;
736 if (!info)
737 return False;
739 *sid = info->sid;
740 *acc_granted = info->acc_granted;
741 if (ppdisp_info) {
742 *ppdisp_info = info->disp_info;
745 return True;
748 /*******************************************************************
749 _samr_SetSecurity
750 ********************************************************************/
752 NTSTATUS _samr_SetSecurity(pipes_struct *p,
753 struct samr_SetSecurity *r)
755 DOM_SID pol_sid;
756 uint32 acc_granted, i;
757 SEC_ACL *dacl;
758 bool ret;
759 struct samu *sampass=NULL;
760 NTSTATUS status;
762 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
763 return NT_STATUS_INVALID_HANDLE;
765 if (!(sampass = samu_new( p->mem_ctx))) {
766 DEBUG(0,("No memory!\n"));
767 return NT_STATUS_NO_MEMORY;
770 /* get the user record */
771 become_root();
772 ret = pdb_getsampwsid(sampass, &pol_sid);
773 unbecome_root();
775 if (!ret) {
776 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
777 TALLOC_FREE(sampass);
778 return NT_STATUS_INVALID_HANDLE;
781 dacl = r->in.sdbuf->sd->dacl;
782 for (i=0; i < dacl->num_aces; i++) {
783 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
784 ret = pdb_set_pass_can_change(sampass,
785 (dacl->aces[i].access_mask &
786 SA_RIGHT_USER_CHANGE_PASSWORD) ?
787 True: False);
788 break;
792 if (!ret) {
793 TALLOC_FREE(sampass);
794 return NT_STATUS_ACCESS_DENIED;
797 status = access_check_samr_function(acc_granted,
798 SA_RIGHT_USER_SET_ATTRIBUTES,
799 "_samr_SetSecurity");
800 if (NT_STATUS_IS_OK(status)) {
801 become_root();
802 status = pdb_update_sam_account(sampass);
803 unbecome_root();
806 TALLOC_FREE(sampass);
808 return status;
811 /*******************************************************************
812 build correct perms based on policies and password times for _samr_query_sec_obj
813 *******************************************************************/
814 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
816 struct samu *sampass=NULL;
817 bool ret;
819 if ( !(sampass = samu_new( mem_ctx )) ) {
820 DEBUG(0,("No memory!\n"));
821 return False;
824 become_root();
825 ret = pdb_getsampwsid(sampass, user_sid);
826 unbecome_root();
828 if (ret == False) {
829 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
830 TALLOC_FREE(sampass);
831 return False;
834 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
836 if (pdb_get_pass_can_change(sampass)) {
837 TALLOC_FREE(sampass);
838 return True;
840 TALLOC_FREE(sampass);
841 return False;
845 /*******************************************************************
846 _samr_QuerySecurity
847 ********************************************************************/
849 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
850 struct samr_QuerySecurity *r)
852 NTSTATUS status;
853 DOM_SID pol_sid;
854 SEC_DESC * psd = NULL;
855 uint32 acc_granted;
856 size_t sd_size;
858 /* Get the SID. */
859 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
860 return NT_STATUS_INVALID_HANDLE;
862 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
863 sid_string_dbg(&pol_sid)));
865 status = access_check_samr_function(acc_granted,
866 STD_RIGHT_READ_CONTROL_ACCESS,
867 "_samr_QuerySecurity");
868 if (!NT_STATUS_IS_OK(status)) {
869 return status;
872 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
874 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
875 if (pol_sid.sid_rev_num == 0) {
876 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
877 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
878 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
879 /* check if it is our domain SID */
880 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
881 "with SID: %s\n", sid_string_dbg(&pol_sid)));
882 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
883 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
884 /* check if it is the Builtin Domain */
885 /* TODO: Builtin probably needs a different SD with restricted write access*/
886 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
887 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
888 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
889 } else if (sid_check_is_in_our_domain(&pol_sid) ||
890 sid_check_is_in_builtin(&pol_sid)) {
891 /* TODO: different SDs have to be generated for aliases groups and users.
892 Currently all three get a default user SD */
893 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
894 "with SID: %s\n", sid_string_dbg(&pol_sid)));
895 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
896 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
897 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
898 } else {
899 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
900 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
902 } else {
903 return NT_STATUS_OBJECT_TYPE_MISMATCH;
906 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
907 return NT_STATUS_NO_MEMORY;
909 return status;
912 /*******************************************************************
913 makes a SAM_ENTRY / UNISTR2* structure from a user list.
914 ********************************************************************/
916 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
917 struct samr_SamEntry **sam_pp,
918 uint32_t num_entries,
919 uint32_t start_idx,
920 struct samr_displayentry *entries)
922 uint32_t i;
923 struct samr_SamEntry *sam;
925 *sam_pp = NULL;
927 if (num_entries == 0) {
928 return NT_STATUS_OK;
931 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
932 if (sam == NULL) {
933 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
934 return NT_STATUS_NO_MEMORY;
937 for (i = 0; i < num_entries; i++) {
938 #if 0
940 * usrmgr expects a non-NULL terminated string with
941 * trust relationships
943 if (entries[i].acct_flags & ACB_DOMTRUST) {
944 init_unistr2(&uni_temp_name, entries[i].account_name,
945 UNI_FLAGS_NONE);
946 } else {
947 init_unistr2(&uni_temp_name, entries[i].account_name,
948 UNI_STR_TERMINATE);
950 #endif
951 init_lsa_String(&sam[i].name, entries[i].account_name);
952 sam[i].idx = entries[i].rid;
955 *sam_pp = sam;
957 return NT_STATUS_OK;
960 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
962 /*******************************************************************
963 _samr_EnumDomainUsers
964 ********************************************************************/
966 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
967 struct samr_EnumDomainUsers *r)
969 NTSTATUS status;
970 struct samr_info *info = NULL;
971 int num_account;
972 uint32 enum_context = *r->in.resume_handle;
973 enum remote_arch_types ra_type = get_remote_arch();
974 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
975 uint32 max_entries = max_sam_entries;
976 struct samr_displayentry *entries = NULL;
977 struct samr_SamArray *samr_array = NULL;
978 struct samr_SamEntry *samr_entries = NULL;
980 /* find the policy handle. open a policy on it. */
981 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
982 return NT_STATUS_INVALID_HANDLE;
984 status = access_check_samr_function(info->acc_granted,
985 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
986 "_samr_EnumDomainUsers");
987 if (!NT_STATUS_IS_OK(status)) {
988 return status;
991 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
993 if (info->builtin_domain) {
994 /* No users in builtin. */
995 *r->out.resume_handle = *r->in.resume_handle;
996 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
997 return status;
1000 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1001 if (!samr_array) {
1002 return NT_STATUS_NO_MEMORY;
1005 become_root();
1007 /* AS ROOT !!!! */
1009 if ((info->disp_info->enum_users != NULL) &&
1010 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1011 pdb_search_destroy(info->disp_info->enum_users);
1012 info->disp_info->enum_users = NULL;
1015 if (info->disp_info->enum_users == NULL) {
1016 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
1017 info->disp_info->enum_acb_mask = r->in.acct_flags;
1020 if (info->disp_info->enum_users == NULL) {
1021 /* END AS ROOT !!!! */
1022 unbecome_root();
1023 return NT_STATUS_ACCESS_DENIED;
1026 num_account = pdb_search_entries(info->disp_info->enum_users,
1027 enum_context, max_entries,
1028 &entries);
1030 /* END AS ROOT !!!! */
1032 unbecome_root();
1034 if (num_account == 0) {
1035 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1036 "total entries\n"));
1037 *r->out.resume_handle = *r->in.resume_handle;
1038 return NT_STATUS_OK;
1041 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1042 num_account, enum_context,
1043 entries);
1044 if (!NT_STATUS_IS_OK(status)) {
1045 return status;
1048 if (max_entries <= num_account) {
1049 status = STATUS_MORE_ENTRIES;
1050 } else {
1051 status = NT_STATUS_OK;
1054 /* Ensure we cache this enumeration. */
1055 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1057 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1059 samr_array->count = num_account;
1060 samr_array->entries = samr_entries;
1062 *r->out.resume_handle = *r->in.resume_handle + num_account;
1063 *r->out.sam = samr_array;
1064 *r->out.num_entries = num_account;
1066 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1068 return status;
1071 /*******************************************************************
1072 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1073 ********************************************************************/
1075 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1076 struct samr_SamEntry **sam_pp,
1077 uint32_t num_sam_entries,
1078 struct samr_displayentry *entries)
1080 struct samr_SamEntry *sam;
1081 uint32_t i;
1083 *sam_pp = NULL;
1085 if (num_sam_entries == 0) {
1086 return;
1089 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1090 if (sam == NULL) {
1091 return;
1094 for (i = 0; i < num_sam_entries; i++) {
1096 * JRA. I think this should include the null. TNG does not.
1098 init_lsa_String(&sam[i].name, entries[i].account_name);
1099 sam[i].idx = entries[i].rid;
1102 *sam_pp = sam;
1105 /*******************************************************************
1106 _samr_EnumDomainGroups
1107 ********************************************************************/
1109 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1110 struct samr_EnumDomainGroups *r)
1112 NTSTATUS status;
1113 struct samr_info *info = NULL;
1114 struct samr_displayentry *groups;
1115 uint32 num_groups;
1116 struct samr_SamArray *samr_array = NULL;
1117 struct samr_SamEntry *samr_entries = NULL;
1119 /* find the policy handle. open a policy on it. */
1120 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1121 return NT_STATUS_INVALID_HANDLE;
1123 status = access_check_samr_function(info->acc_granted,
1124 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1125 "_samr_EnumDomainGroups");
1126 if (!NT_STATUS_IS_OK(status)) {
1127 return status;
1130 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1132 if (info->builtin_domain) {
1133 /* No groups in builtin. */
1134 *r->out.resume_handle = *r->in.resume_handle;
1135 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1136 return status;
1139 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1140 if (!samr_array) {
1141 return NT_STATUS_NO_MEMORY;
1144 /* the domain group array is being allocated in the function below */
1146 become_root();
1148 if (info->disp_info->groups == NULL) {
1149 info->disp_info->groups = pdb_search_groups();
1151 if (info->disp_info->groups == NULL) {
1152 unbecome_root();
1153 return NT_STATUS_ACCESS_DENIED;
1157 num_groups = pdb_search_entries(info->disp_info->groups,
1158 *r->in.resume_handle,
1159 MAX_SAM_ENTRIES, &groups);
1160 unbecome_root();
1162 /* Ensure we cache this enumeration. */
1163 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1165 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1166 num_groups, groups);
1168 samr_array->count = num_groups;
1169 samr_array->entries = samr_entries;
1171 *r->out.sam = samr_array;
1172 *r->out.num_entries = num_groups;
1173 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1175 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1177 return status;
1180 /*******************************************************************
1181 _samr_EnumDomainAliases
1182 ********************************************************************/
1184 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1185 struct samr_EnumDomainAliases *r)
1187 NTSTATUS status;
1188 struct samr_info *info;
1189 struct samr_displayentry *aliases;
1190 uint32 num_aliases = 0;
1191 struct samr_SamArray *samr_array = NULL;
1192 struct samr_SamEntry *samr_entries = NULL;
1194 /* find the policy handle. open a policy on it. */
1195 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1196 return NT_STATUS_INVALID_HANDLE;
1198 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1199 sid_string_dbg(&info->sid)));
1201 status = access_check_samr_function(info->acc_granted,
1202 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1203 "_samr_EnumDomainAliases");
1204 if (!NT_STATUS_IS_OK(status)) {
1205 return status;
1208 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1209 if (!samr_array) {
1210 return NT_STATUS_NO_MEMORY;
1213 become_root();
1215 if (info->disp_info->aliases == NULL) {
1216 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1217 if (info->disp_info->aliases == NULL) {
1218 unbecome_root();
1219 return NT_STATUS_ACCESS_DENIED;
1223 num_aliases = pdb_search_entries(info->disp_info->aliases,
1224 *r->in.resume_handle,
1225 MAX_SAM_ENTRIES, &aliases);
1226 unbecome_root();
1228 /* Ensure we cache this enumeration. */
1229 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1231 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1232 num_aliases, aliases);
1234 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1236 samr_array->count = num_aliases;
1237 samr_array->entries = samr_entries;
1239 *r->out.sam = samr_array;
1240 *r->out.num_entries = num_aliases;
1241 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1243 return status;
1246 /*******************************************************************
1247 inits a samr_DispInfoGeneral structure.
1248 ********************************************************************/
1250 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1251 struct samr_DispInfoGeneral *r,
1252 uint32_t num_entries,
1253 uint32_t start_idx,
1254 struct samr_displayentry *entries)
1256 uint32 i;
1258 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1260 if (num_entries == 0) {
1261 return NT_STATUS_OK;
1264 r->count = num_entries;
1266 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1267 if (!r->entries) {
1268 return NT_STATUS_NO_MEMORY;
1271 for (i = 0; i < num_entries ; i++) {
1273 init_lsa_String(&r->entries[i].account_name,
1274 entries[i].account_name);
1276 init_lsa_String(&r->entries[i].description,
1277 entries[i].description);
1279 init_lsa_String(&r->entries[i].full_name,
1280 entries[i].fullname);
1282 r->entries[i].rid = entries[i].rid;
1283 r->entries[i].acct_flags = entries[i].acct_flags;
1284 r->entries[i].idx = start_idx+i+1;
1287 return NT_STATUS_OK;
1290 /*******************************************************************
1291 inits a samr_DispInfoFull structure.
1292 ********************************************************************/
1294 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1295 struct samr_DispInfoFull *r,
1296 uint32_t num_entries,
1297 uint32_t start_idx,
1298 struct samr_displayentry *entries)
1300 uint32_t i;
1302 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1304 if (num_entries == 0) {
1305 return NT_STATUS_OK;
1308 r->count = num_entries;
1310 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1311 if (!r->entries) {
1312 return NT_STATUS_NO_MEMORY;
1315 for (i = 0; i < num_entries ; i++) {
1317 init_lsa_String(&r->entries[i].account_name,
1318 entries[i].account_name);
1320 init_lsa_String(&r->entries[i].description,
1321 entries[i].description);
1323 r->entries[i].rid = entries[i].rid;
1324 r->entries[i].acct_flags = entries[i].acct_flags;
1325 r->entries[i].idx = start_idx+i+1;
1328 return NT_STATUS_OK;
1331 /*******************************************************************
1332 inits a samr_DispInfoFullGroups structure.
1333 ********************************************************************/
1335 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1336 struct samr_DispInfoFullGroups *r,
1337 uint32_t num_entries,
1338 uint32_t start_idx,
1339 struct samr_displayentry *entries)
1341 uint32_t i;
1343 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1345 if (num_entries == 0) {
1346 return NT_STATUS_OK;
1349 r->count = num_entries;
1351 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1352 if (!r->entries) {
1353 return NT_STATUS_NO_MEMORY;
1356 for (i = 0; i < num_entries ; i++) {
1358 init_lsa_String(&r->entries[i].account_name,
1359 entries[i].account_name);
1361 init_lsa_String(&r->entries[i].description,
1362 entries[i].description);
1364 r->entries[i].rid = entries[i].rid;
1365 r->entries[i].acct_flags = entries[i].acct_flags;
1366 r->entries[i].idx = start_idx+i+1;
1369 return NT_STATUS_OK;
1372 /*******************************************************************
1373 inits a samr_DispInfoAscii structure.
1374 ********************************************************************/
1376 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1377 struct samr_DispInfoAscii *r,
1378 uint32_t num_entries,
1379 uint32_t start_idx,
1380 struct samr_displayentry *entries)
1382 uint32_t i;
1384 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1386 if (num_entries == 0) {
1387 return NT_STATUS_OK;
1390 r->count = num_entries;
1392 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1393 if (!r->entries) {
1394 return NT_STATUS_NO_MEMORY;
1397 for (i = 0; i < num_entries ; i++) {
1399 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1400 entries[i].account_name);
1402 r->entries[i].idx = start_idx+i+1;
1405 return NT_STATUS_OK;
1408 /*******************************************************************
1409 inits a samr_DispInfoAscii structure.
1410 ********************************************************************/
1412 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1413 struct samr_DispInfoAscii *r,
1414 uint32_t num_entries,
1415 uint32_t start_idx,
1416 struct samr_displayentry *entries)
1418 uint32_t i;
1420 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1422 if (num_entries == 0) {
1423 return NT_STATUS_OK;
1426 r->count = num_entries;
1428 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1429 if (!r->entries) {
1430 return NT_STATUS_NO_MEMORY;
1433 for (i = 0; i < num_entries ; i++) {
1435 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1436 entries[i].account_name);
1438 r->entries[i].idx = start_idx+i+1;
1441 return NT_STATUS_OK;
1444 /*******************************************************************
1445 _samr_QueryDisplayInfo
1446 ********************************************************************/
1448 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1449 struct samr_QueryDisplayInfo *r)
1451 NTSTATUS status;
1452 struct samr_info *info = NULL;
1453 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1455 uint32 max_entries = r->in.max_entries;
1456 uint32 enum_context = r->in.start_idx;
1457 uint32 max_size = r->in.buf_size;
1459 union samr_DispInfo *disp_info = r->out.info;
1461 uint32 temp_size=0, total_data_size=0;
1462 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1463 uint32 num_account = 0;
1464 enum remote_arch_types ra_type = get_remote_arch();
1465 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1466 struct samr_displayentry *entries = NULL;
1468 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1470 /* find the policy handle. open a policy on it. */
1471 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1472 return NT_STATUS_INVALID_HANDLE;
1474 status = access_check_samr_function(info->acc_granted,
1475 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1476 "_samr_QueryDisplayInfo");
1477 if (!NT_STATUS_IS_OK(status)) {
1478 return status;
1482 * calculate how many entries we will return.
1483 * based on
1484 * - the number of entries the client asked
1485 * - our limit on that
1486 * - the starting point (enumeration context)
1487 * - the buffer size the client will accept
1491 * We are a lot more like W2K. Instead of reading the SAM
1492 * each time to find the records we need to send back,
1493 * we read it once and link that copy to the sam handle.
1494 * For large user list (over the MAX_SAM_ENTRIES)
1495 * it's a definitive win.
1496 * second point to notice: between enumerations
1497 * our sam is now the same as it's a snapshoot.
1498 * third point: got rid of the static SAM_USER_21 struct
1499 * no more intermediate.
1500 * con: it uses much more memory, as a full copy is stored
1501 * in memory.
1503 * If you want to change it, think twice and think
1504 * of the second point , that's really important.
1506 * JFM, 12/20/2001
1509 if ((r->in.level < 1) || (r->in.level > 5)) {
1510 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1511 (unsigned int)r->in.level ));
1512 return NT_STATUS_INVALID_INFO_CLASS;
1515 /* first limit the number of entries we will return */
1516 if(max_entries > max_sam_entries) {
1517 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1518 "entries, limiting to %d\n", max_entries,
1519 max_sam_entries));
1520 max_entries = max_sam_entries;
1523 /* calculate the size and limit on the number of entries we will
1524 * return */
1526 temp_size=max_entries*struct_size;
1528 if (temp_size>max_size) {
1529 max_entries=MIN((max_size/struct_size),max_entries);;
1530 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1531 "only %d entries\n", max_entries));
1534 become_root();
1536 /* THe following done as ROOT. Don't return without unbecome_root(). */
1538 switch (r->in.level) {
1539 case 0x1:
1540 case 0x4:
1541 if (info->disp_info->users == NULL) {
1542 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1543 if (info->disp_info->users == NULL) {
1544 unbecome_root();
1545 return NT_STATUS_ACCESS_DENIED;
1547 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1548 (unsigned int)enum_context ));
1549 } else {
1550 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1551 (unsigned int)enum_context ));
1554 num_account = pdb_search_entries(info->disp_info->users,
1555 enum_context, max_entries,
1556 &entries);
1557 break;
1558 case 0x2:
1559 if (info->disp_info->machines == NULL) {
1560 info->disp_info->machines =
1561 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1562 if (info->disp_info->machines == NULL) {
1563 unbecome_root();
1564 return NT_STATUS_ACCESS_DENIED;
1566 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1567 (unsigned int)enum_context ));
1568 } else {
1569 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1570 (unsigned int)enum_context ));
1573 num_account = pdb_search_entries(info->disp_info->machines,
1574 enum_context, max_entries,
1575 &entries);
1576 break;
1577 case 0x3:
1578 case 0x5:
1579 if (info->disp_info->groups == NULL) {
1580 info->disp_info->groups = pdb_search_groups();
1581 if (info->disp_info->groups == NULL) {
1582 unbecome_root();
1583 return NT_STATUS_ACCESS_DENIED;
1585 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1586 (unsigned int)enum_context ));
1587 } else {
1588 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1589 (unsigned int)enum_context ));
1592 num_account = pdb_search_entries(info->disp_info->groups,
1593 enum_context, max_entries,
1594 &entries);
1595 break;
1596 default:
1597 unbecome_root();
1598 smb_panic("info class changed");
1599 break;
1601 unbecome_root();
1604 /* Now create reply structure */
1605 switch (r->in.level) {
1606 case 0x1:
1607 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1608 num_account, enum_context,
1609 entries);
1610 break;
1611 case 0x2:
1612 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1613 num_account, enum_context,
1614 entries);
1615 break;
1616 case 0x3:
1617 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1618 num_account, enum_context,
1619 entries);
1620 break;
1621 case 0x4:
1622 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1623 num_account, enum_context,
1624 entries);
1625 break;
1626 case 0x5:
1627 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1628 num_account, enum_context,
1629 entries);
1630 break;
1631 default:
1632 smb_panic("info class changed");
1633 break;
1636 if (!NT_STATUS_IS_OK(disp_ret))
1637 return disp_ret;
1639 /* calculate the total size */
1640 total_data_size=num_account*struct_size;
1642 if (max_entries <= num_account) {
1643 status = STATUS_MORE_ENTRIES;
1644 } else {
1645 status = NT_STATUS_OK;
1648 /* Ensure we cache this enumeration. */
1649 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1651 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1653 *r->out.total_size = total_data_size;
1654 *r->out.returned_size = temp_size;
1656 return status;
1659 /****************************************************************
1660 _samr_QueryDisplayInfo2
1661 ****************************************************************/
1663 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1664 struct samr_QueryDisplayInfo2 *r)
1666 struct samr_QueryDisplayInfo q;
1668 q.in.domain_handle = r->in.domain_handle;
1669 q.in.level = r->in.level;
1670 q.in.start_idx = r->in.start_idx;
1671 q.in.max_entries = r->in.max_entries;
1672 q.in.buf_size = r->in.buf_size;
1674 q.out.total_size = r->out.total_size;
1675 q.out.returned_size = r->out.returned_size;
1676 q.out.info = r->out.info;
1678 return _samr_QueryDisplayInfo(p, &q);
1681 /****************************************************************
1682 _samr_QueryDisplayInfo3
1683 ****************************************************************/
1685 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1686 struct samr_QueryDisplayInfo3 *r)
1688 struct samr_QueryDisplayInfo q;
1690 q.in.domain_handle = r->in.domain_handle;
1691 q.in.level = r->in.level;
1692 q.in.start_idx = r->in.start_idx;
1693 q.in.max_entries = r->in.max_entries;
1694 q.in.buf_size = r->in.buf_size;
1696 q.out.total_size = r->out.total_size;
1697 q.out.returned_size = r->out.returned_size;
1698 q.out.info = r->out.info;
1700 return _samr_QueryDisplayInfo(p, &q);
1703 /*******************************************************************
1704 _samr_QueryAliasInfo
1705 ********************************************************************/
1707 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1708 struct samr_QueryAliasInfo *r)
1710 DOM_SID sid;
1711 struct acct_info info;
1712 uint32 acc_granted;
1713 NTSTATUS status;
1714 union samr_AliasInfo *alias_info = NULL;
1715 const char *alias_name = NULL;
1716 const char *alias_description = NULL;
1718 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1720 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1721 if (!alias_info) {
1722 return NT_STATUS_NO_MEMORY;
1725 /* find the policy handle. open a policy on it. */
1726 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1727 return NT_STATUS_INVALID_HANDLE;
1729 status = access_check_samr_function(acc_granted,
1730 SA_RIGHT_ALIAS_LOOKUP_INFO,
1731 "_samr_QueryAliasInfo");
1732 if (!NT_STATUS_IS_OK(status)) {
1733 return status;
1736 become_root();
1737 status = pdb_get_aliasinfo(&sid, &info);
1738 unbecome_root();
1740 if ( !NT_STATUS_IS_OK(status))
1741 return status;
1743 /* FIXME: info contains fstrings */
1744 alias_name = talloc_strdup(r, info.acct_name);
1745 alias_description = talloc_strdup(r, info.acct_desc);
1747 switch (r->in.level) {
1748 case ALIASINFOALL:
1749 init_samr_alias_info1(&alias_info->all,
1750 alias_name,
1752 alias_description);
1753 break;
1754 case ALIASINFODESCRIPTION:
1755 init_samr_alias_info3(&alias_info->description,
1756 alias_description);
1757 break;
1758 default:
1759 return NT_STATUS_INVALID_INFO_CLASS;
1762 *r->out.info = alias_info;
1764 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1766 return NT_STATUS_OK;
1769 #if 0
1770 /*******************************************************************
1771 samr_reply_lookup_ids
1772 ********************************************************************/
1774 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1776 uint32 rid[MAX_SAM_ENTRIES];
1777 int num_rids = q_u->num_sids1;
1779 r_u->status = NT_STATUS_OK;
1781 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1783 if (num_rids > MAX_SAM_ENTRIES) {
1784 num_rids = MAX_SAM_ENTRIES;
1785 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1788 #if 0
1789 int i;
1790 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1792 for (i = 0; i < num_rids && status == 0; i++)
1794 struct sam_passwd *sam_pass;
1795 fstring user_name;
1798 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1799 q_u->uni_user_name[i].uni_str_len));
1801 /* find the user account */
1802 become_root();
1803 sam_pass = get_smb21pwd_entry(user_name, 0);
1804 unbecome_root();
1806 if (sam_pass == NULL)
1808 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1809 rid[i] = 0;
1811 else
1813 rid[i] = sam_pass->user_rid;
1816 #endif
1818 num_rids = 1;
1819 rid[0] = BUILTIN_ALIAS_RID_USERS;
1821 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1823 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1825 return r_u->status;
1827 #endif
1829 /*******************************************************************
1830 _samr_LookupNames
1831 ********************************************************************/
1833 NTSTATUS _samr_LookupNames(pipes_struct *p,
1834 struct samr_LookupNames *r)
1836 NTSTATUS status;
1837 uint32 *rid;
1838 enum lsa_SidType *type;
1839 int i;
1840 int num_rids = r->in.num_names;
1841 DOM_SID pol_sid;
1842 uint32 acc_granted;
1843 struct samr_Ids rids, types;
1844 uint32_t num_mapped = 0;
1846 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1848 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1849 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1852 status = access_check_samr_function(acc_granted,
1853 0, /* Don't know the acc_bits yet */
1854 "_samr_LookupNames");
1855 if (!NT_STATUS_IS_OK(status)) {
1856 return status;
1859 if (num_rids > MAX_SAM_ENTRIES) {
1860 num_rids = MAX_SAM_ENTRIES;
1861 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1864 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1865 NT_STATUS_HAVE_NO_MEMORY(rid);
1867 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1868 NT_STATUS_HAVE_NO_MEMORY(type);
1870 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1871 sid_string_dbg(&pol_sid)));
1873 for (i = 0; i < num_rids; i++) {
1875 status = NT_STATUS_NONE_MAPPED;
1876 type[i] = SID_NAME_UNKNOWN;
1878 rid[i] = 0xffffffff;
1880 if (sid_check_is_builtin(&pol_sid)) {
1881 if (lookup_builtin_name(r->in.names[i].string,
1882 &rid[i]))
1884 type[i] = SID_NAME_ALIAS;
1886 } else {
1887 lookup_global_sam_name(r->in.names[i].string, 0,
1888 &rid[i], &type[i]);
1891 if (type[i] != SID_NAME_UNKNOWN) {
1892 num_mapped++;
1896 if (num_mapped == num_rids) {
1897 status = NT_STATUS_OK;
1898 } else if (num_mapped == 0) {
1899 status = NT_STATUS_NONE_MAPPED;
1900 } else {
1901 status = STATUS_SOME_UNMAPPED;
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 0, /* Don't know the acc_bits yet */
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 SAMR_USER_ACCESS_GET_ATTRIBUTES,
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
2915 ********************************************************************/
2917 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2918 struct samr_QueryDomainInfo *r)
2920 NTSTATUS status = NT_STATUS_OK;
2921 struct samr_info *info = NULL;
2922 union samr_DomainInfo *dom_info;
2923 uint32 min_pass_len,pass_hist,password_properties;
2924 time_t u_expire, u_min_age;
2925 NTTIME nt_expire, nt_min_age;
2927 time_t u_lock_duration, u_reset_time;
2928 NTTIME nt_lock_duration, nt_reset_time;
2929 uint32 lockout;
2930 time_t u_logout;
2931 NTTIME nt_logout;
2933 uint32 account_policy_temp;
2935 time_t seq_num;
2936 uint32 server_role;
2938 uint32 num_users=0, num_groups=0, num_aliases=0;
2940 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2942 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2943 if (!dom_info) {
2944 return NT_STATUS_NO_MEMORY;
2947 /* find the policy handle. open a policy on it. */
2948 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
2949 return NT_STATUS_INVALID_HANDLE;
2952 status = access_check_samr_function(info->acc_granted,
2953 SA_RIGHT_SAM_LOOKUP_DOMAIN,
2954 "_samr_QueryDomainInfo" );
2956 if ( !NT_STATUS_IS_OK(status) )
2957 return status;
2959 switch (r->in.level) {
2960 case 0x01:
2962 become_root();
2964 /* AS ROOT !!! */
2966 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2967 min_pass_len = account_policy_temp;
2969 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2970 pass_hist = account_policy_temp;
2972 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2973 password_properties = account_policy_temp;
2975 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2976 u_expire = account_policy_temp;
2978 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2979 u_min_age = account_policy_temp;
2981 /* !AS ROOT */
2983 unbecome_root();
2985 unix_to_nt_time_abs(&nt_expire, u_expire);
2986 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2988 if (lp_check_password_script() && *lp_check_password_script()) {
2989 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2992 init_samr_DomInfo1(&dom_info->info1,
2993 (uint16)min_pass_len,
2994 (uint16)pass_hist,
2995 password_properties,
2996 nt_expire,
2997 nt_min_age);
2998 break;
2999 case 0x02:
3001 become_root();
3003 /* AS ROOT !!! */
3005 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
3006 num_groups = count_sam_groups(info->disp_info);
3007 num_aliases = count_sam_aliases(info->disp_info);
3009 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
3010 u_logout = account_policy_temp;
3012 unix_to_nt_time_abs(&nt_logout, u_logout);
3014 if (!pdb_get_seq_num(&seq_num))
3015 seq_num = time(NULL);
3017 /* !AS ROOT */
3019 unbecome_root();
3021 server_role = ROLE_DOMAIN_PDC;
3022 if (lp_server_role() == ROLE_DOMAIN_BDC)
3023 server_role = ROLE_DOMAIN_BDC;
3025 init_samr_DomInfo2(&dom_info->info2,
3026 nt_logout,
3027 lp_serverstring(),
3028 lp_workgroup(),
3029 global_myname(),
3030 seq_num,
3032 server_role,
3034 num_users,
3035 num_groups,
3036 num_aliases);
3037 break;
3038 case 0x03:
3040 become_root();
3042 /* AS ROOT !!! */
3045 uint32 ul;
3046 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3047 u_logout = (time_t)ul;
3050 /* !AS ROOT */
3052 unbecome_root();
3054 unix_to_nt_time_abs(&nt_logout, u_logout);
3056 init_samr_DomInfo3(&dom_info->info3,
3057 nt_logout);
3059 break;
3060 case 0x04:
3061 init_samr_DomInfo4(&dom_info->info4,
3062 lp_serverstring());
3063 break;
3064 case 0x05:
3065 init_samr_DomInfo5(&dom_info->info5,
3066 get_global_sam_name());
3067 break;
3068 case 0x06:
3069 /* NT returns its own name when a PDC. win2k and later
3070 * only the name of the PDC if itself is a BDC (samba4
3071 * idl) */
3072 init_samr_DomInfo6(&dom_info->info6,
3073 global_myname());
3074 break;
3075 case 0x07:
3076 server_role = ROLE_DOMAIN_PDC;
3077 if (lp_server_role() == ROLE_DOMAIN_BDC)
3078 server_role = ROLE_DOMAIN_BDC;
3080 init_samr_DomInfo7(&dom_info->info7,
3081 server_role);
3082 break;
3083 case 0x08:
3085 become_root();
3087 /* AS ROOT !!! */
3089 if (!pdb_get_seq_num(&seq_num)) {
3090 seq_num = time(NULL);
3093 /* !AS ROOT */
3095 unbecome_root();
3097 init_samr_DomInfo8(&dom_info->info8,
3098 seq_num,
3100 break;
3101 case 0x0c:
3103 become_root();
3105 /* AS ROOT !!! */
3107 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3108 u_lock_duration = account_policy_temp;
3109 if (u_lock_duration != -1) {
3110 u_lock_duration *= 60;
3113 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3114 u_reset_time = account_policy_temp * 60;
3116 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3117 lockout = account_policy_temp;
3119 /* !AS ROOT */
3121 unbecome_root();
3123 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3124 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3126 init_samr_DomInfo12(&dom_info->info12,
3127 nt_lock_duration,
3128 nt_reset_time,
3129 (uint16)lockout);
3130 break;
3131 default:
3132 return NT_STATUS_INVALID_INFO_CLASS;
3135 *r->out.info = dom_info;
3137 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3139 return status;
3142 /* W2k3 seems to use the same check for all 3 objects that can be created via
3143 * SAMR, if you try to create for example "Dialup" as an alias it says
3144 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3145 * database. */
3147 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3149 enum lsa_SidType type;
3150 bool result;
3152 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3154 become_root();
3155 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3156 * whether the name already exists */
3157 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3158 NULL, NULL, NULL, &type);
3159 unbecome_root();
3161 if (!result) {
3162 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3163 return NT_STATUS_OK;
3166 DEBUG(5, ("trying to create %s, exists as %s\n",
3167 new_name, sid_type_lookup(type)));
3169 if (type == SID_NAME_DOM_GRP) {
3170 return NT_STATUS_GROUP_EXISTS;
3172 if (type == SID_NAME_ALIAS) {
3173 return NT_STATUS_ALIAS_EXISTS;
3176 /* Yes, the default is NT_STATUS_USER_EXISTS */
3177 return NT_STATUS_USER_EXISTS;
3180 /*******************************************************************
3181 _samr_CreateUser2
3182 ********************************************************************/
3184 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3185 struct samr_CreateUser2 *r)
3187 const char *account = NULL;
3188 DOM_SID sid;
3189 POLICY_HND dom_pol = *r->in.domain_handle;
3190 uint32_t acb_info = r->in.acct_flags;
3191 POLICY_HND *user_pol = r->out.user_handle;
3192 struct samr_info *info = NULL;
3193 NTSTATUS nt_status;
3194 uint32 acc_granted;
3195 SEC_DESC *psd;
3196 size_t sd_size;
3197 /* check this, when giving away 'add computer to domain' privs */
3198 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3199 bool can_add_account = False;
3200 SE_PRIV se_rights;
3201 DISP_INFO *disp_info = NULL;
3203 /* Get the domain SID stored in the domain policy */
3204 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3205 &disp_info))
3206 return NT_STATUS_INVALID_HANDLE;
3208 nt_status = access_check_samr_function(acc_granted,
3209 SA_RIGHT_DOMAIN_CREATE_USER,
3210 "_samr_CreateUser2");
3211 if (!NT_STATUS_IS_OK(nt_status)) {
3212 return nt_status;
3215 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3216 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3217 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3218 this parameter is not an account type */
3219 return NT_STATUS_INVALID_PARAMETER;
3222 account = r->in.account_name->string;
3223 if (account == NULL) {
3224 return NT_STATUS_NO_MEMORY;
3227 nt_status = can_create(p->mem_ctx, account);
3228 if (!NT_STATUS_IS_OK(nt_status)) {
3229 return nt_status;
3232 /* determine which user right we need to check based on the acb_info */
3234 if ( acb_info & ACB_WSTRUST )
3236 se_priv_copy( &se_rights, &se_machine_account );
3237 can_add_account = user_has_privileges(
3238 p->pipe_user.nt_user_token, &se_rights );
3240 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3241 account for domain trusts and changes the ACB flags later */
3242 else if ( acb_info & ACB_NORMAL &&
3243 (account[strlen(account)-1] != '$') )
3245 se_priv_copy( &se_rights, &se_add_users );
3246 can_add_account = user_has_privileges(
3247 p->pipe_user.nt_user_token, &se_rights );
3249 else /* implicit assumption of a BDC or domain trust account here
3250 * (we already check the flags earlier) */
3252 if ( lp_enable_privileges() ) {
3253 /* only Domain Admins can add a BDC or domain trust */
3254 se_priv_copy( &se_rights, &se_priv_none );
3255 can_add_account = nt_token_check_domain_rid(
3256 p->pipe_user.nt_user_token,
3257 DOMAIN_GROUP_RID_ADMINS );
3261 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3262 uidtoname(p->pipe_user.ut.uid),
3263 can_add_account ? "True":"False" ));
3265 /********** BEGIN Admin BLOCK **********/
3267 if ( can_add_account )
3268 become_root();
3270 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3271 r->out.rid);
3273 if ( can_add_account )
3274 unbecome_root();
3276 /********** END Admin BLOCK **********/
3278 /* now check for failure */
3280 if ( !NT_STATUS_IS_OK(nt_status) )
3281 return nt_status;
3283 /* Get the user's SID */
3285 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3287 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3289 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3290 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3291 se_map_generic(&des_access, &usr_generic_mapping);
3293 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3294 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3295 &acc_granted, "_samr_CreateUser2");
3297 if ( !NT_STATUS_IS_OK(nt_status) ) {
3298 return nt_status;
3301 /* associate the user's SID with the new handle. */
3302 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3303 return NT_STATUS_NO_MEMORY;
3306 ZERO_STRUCTP(info);
3307 info->sid = sid;
3308 info->acc_granted = acc_granted;
3310 /* get a (unique) handle. open a policy on it. */
3311 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3312 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3315 /* After a "set" ensure we have no cached display info. */
3316 force_flush_samr_cache(info->disp_info);
3318 *r->out.access_granted = acc_granted;
3320 return NT_STATUS_OK;
3323 /*******************************************************************
3324 _samr_Connect
3325 ********************************************************************/
3327 NTSTATUS _samr_Connect(pipes_struct *p,
3328 struct samr_Connect *r)
3330 struct samr_info *info = NULL;
3331 uint32 des_access = r->in.access_mask;
3333 /* Access check */
3335 if (!pipe_access_check(p)) {
3336 DEBUG(3, ("access denied to _samr_Connect\n"));
3337 return NT_STATUS_ACCESS_DENIED;
3340 /* set up the SAMR connect_anon response */
3342 /* associate the user's SID with the new handle. */
3343 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3344 return NT_STATUS_NO_MEMORY;
3346 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3347 was observed from a win98 client trying to enumerate users (when configured
3348 user level access control on shares) --jerry */
3350 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3352 se_map_generic( &des_access, &sam_generic_mapping );
3353 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_LOOKUP_DOMAIN);
3355 /* get a (unique) handle. open a policy on it. */
3356 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3357 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3359 return NT_STATUS_OK;
3362 /*******************************************************************
3363 _samr_Connect2
3364 ********************************************************************/
3366 NTSTATUS _samr_Connect2(pipes_struct *p,
3367 struct samr_Connect2 *r)
3369 struct samr_info *info = NULL;
3370 SEC_DESC *psd = NULL;
3371 uint32 acc_granted;
3372 uint32 des_access = r->in.access_mask;
3373 NTSTATUS nt_status;
3374 size_t sd_size;
3377 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3379 /* Access check */
3381 if (!pipe_access_check(p)) {
3382 DEBUG(3, ("access denied to _samr_Connect2\n"));
3383 return NT_STATUS_ACCESS_DENIED;
3386 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3388 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3389 se_map_generic(&des_access, &sam_generic_mapping);
3391 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3392 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3394 if ( !NT_STATUS_IS_OK(nt_status) )
3395 return nt_status;
3397 /* associate the user's SID and access granted with the new handle. */
3398 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3399 return NT_STATUS_NO_MEMORY;
3401 info->acc_granted = acc_granted;
3402 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3404 /* get a (unique) handle. open a policy on it. */
3405 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3406 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3408 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3410 return nt_status;
3413 /*******************************************************************
3414 _samr_Connect4
3415 ********************************************************************/
3417 NTSTATUS _samr_Connect4(pipes_struct *p,
3418 struct samr_Connect4 *r)
3420 struct samr_info *info = NULL;
3421 SEC_DESC *psd = NULL;
3422 uint32 acc_granted;
3423 uint32 des_access = r->in.access_mask;
3424 NTSTATUS nt_status;
3425 size_t sd_size;
3428 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3430 /* Access check */
3432 if (!pipe_access_check(p)) {
3433 DEBUG(3, ("access denied to samr_Connect4\n"));
3434 return NT_STATUS_ACCESS_DENIED;
3437 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3439 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3440 se_map_generic(&des_access, &sam_generic_mapping);
3442 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3443 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3445 if ( !NT_STATUS_IS_OK(nt_status) )
3446 return nt_status;
3448 /* associate the user's SID and access granted with the new handle. */
3449 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3450 return NT_STATUS_NO_MEMORY;
3452 info->acc_granted = acc_granted;
3453 info->status = r->in.access_mask; /* ??? */
3455 /* get a (unique) handle. open a policy on it. */
3456 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3457 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3459 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3461 return NT_STATUS_OK;
3464 /*******************************************************************
3465 _samr_Connect5
3466 ********************************************************************/
3468 NTSTATUS _samr_Connect5(pipes_struct *p,
3469 struct samr_Connect5 *r)
3471 struct samr_info *info = NULL;
3472 SEC_DESC *psd = NULL;
3473 uint32 acc_granted;
3474 uint32 des_access = r->in.access_mask;
3475 NTSTATUS nt_status;
3476 size_t sd_size;
3477 struct samr_ConnectInfo1 info1;
3479 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3481 /* Access check */
3483 if (!pipe_access_check(p)) {
3484 DEBUG(3, ("access denied to samr_Connect5\n"));
3485 return NT_STATUS_ACCESS_DENIED;
3488 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3490 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3491 se_map_generic(&des_access, &sam_generic_mapping);
3493 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3494 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3496 if ( !NT_STATUS_IS_OK(nt_status) )
3497 return nt_status;
3499 /* associate the user's SID and access granted with the new handle. */
3500 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3501 return NT_STATUS_NO_MEMORY;
3503 info->acc_granted = acc_granted;
3504 info->status = r->in.access_mask; /* ??? */
3506 /* get a (unique) handle. open a policy on it. */
3507 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3508 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3510 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3512 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3513 info1.unknown2 = 0;
3515 *r->out.level_out = 1;
3516 r->out.info_out->info1 = info1;
3518 return NT_STATUS_OK;
3521 /**********************************************************************
3522 _samr_LookupDomain
3523 **********************************************************************/
3525 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3526 struct samr_LookupDomain *r)
3528 NTSTATUS status = NT_STATUS_OK;
3529 struct samr_info *info;
3530 const char *domain_name;
3531 DOM_SID *sid = NULL;
3533 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3534 return NT_STATUS_INVALID_HANDLE;
3536 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3537 Reverted that change so we will work with RAS servers again */
3539 status = access_check_samr_function(info->acc_granted,
3540 SA_RIGHT_SAM_LOOKUP_DOMAIN,
3541 "_samr_LookupDomain");
3542 if (!NT_STATUS_IS_OK(status)) {
3543 return status;
3546 domain_name = r->in.domain_name->string;
3548 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3549 if (!sid) {
3550 return NT_STATUS_NO_MEMORY;
3553 if (strequal(domain_name, builtin_domain_name())) {
3554 sid_copy(sid, &global_sid_Builtin);
3555 } else {
3556 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3557 status = NT_STATUS_NO_SUCH_DOMAIN;
3561 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3562 sid_string_dbg(sid)));
3564 *r->out.sid = sid;
3566 return status;
3569 /**********************************************************************
3570 _samr_EnumDomains
3571 **********************************************************************/
3573 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3574 struct samr_EnumDomains *r)
3576 NTSTATUS status;
3577 struct samr_info *info;
3578 uint32_t num_entries = 2;
3579 struct samr_SamEntry *entry_array = NULL;
3580 struct samr_SamArray *sam;
3582 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3583 return NT_STATUS_INVALID_HANDLE;
3585 status = access_check_samr_function(info->acc_granted,
3586 SA_RIGHT_SAM_ENUM_DOMAINS,
3587 "_samr_EnumDomains");
3588 if (!NT_STATUS_IS_OK(status)) {
3589 return status;
3592 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3593 if (!sam) {
3594 return NT_STATUS_NO_MEMORY;
3597 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3598 struct samr_SamEntry,
3599 num_entries);
3600 if (!entry_array) {
3601 return NT_STATUS_NO_MEMORY;
3604 entry_array[0].idx = 0;
3605 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3607 entry_array[1].idx = 1;
3608 init_lsa_String(&entry_array[1].name, "Builtin");
3610 sam->count = num_entries;
3611 sam->entries = entry_array;
3613 *r->out.sam = sam;
3614 *r->out.num_entries = num_entries;
3616 return status;
3619 /*******************************************************************
3620 _samr_OpenAlias
3621 ********************************************************************/
3623 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3624 struct samr_OpenAlias *r)
3626 DOM_SID sid;
3627 POLICY_HND domain_pol = *r->in.domain_handle;
3628 uint32 alias_rid = r->in.rid;
3629 POLICY_HND *alias_pol = r->out.alias_handle;
3630 struct samr_info *info = NULL;
3631 SEC_DESC *psd = NULL;
3632 uint32 acc_granted;
3633 uint32 des_access = r->in.access_mask;
3634 size_t sd_size;
3635 NTSTATUS status;
3636 SE_PRIV se_rights;
3638 /* find the domain policy and get the SID / access bits stored in the domain policy */
3640 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3641 return NT_STATUS_INVALID_HANDLE;
3643 status = access_check_samr_function(acc_granted,
3644 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3645 "_samr_OpenAlias");
3647 if ( !NT_STATUS_IS_OK(status) )
3648 return status;
3650 /* append the alias' RID to it */
3652 if (!sid_append_rid(&sid, alias_rid))
3653 return NT_STATUS_NO_SUCH_ALIAS;
3655 /*check if access can be granted as requested by client. */
3657 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3659 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3660 se_map_generic(&des_access,&ali_generic_mapping);
3662 se_priv_copy( &se_rights, &se_add_users );
3665 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3666 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3667 &acc_granted, "_samr_OpenAlias");
3669 if ( !NT_STATUS_IS_OK(status) )
3670 return status;
3673 /* Check we actually have the requested alias */
3674 enum lsa_SidType type;
3675 bool result;
3676 gid_t gid;
3678 become_root();
3679 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3680 unbecome_root();
3682 if (!result || (type != SID_NAME_ALIAS)) {
3683 return NT_STATUS_NO_SUCH_ALIAS;
3686 /* make sure there is a mapping */
3688 if ( !sid_to_gid( &sid, &gid ) ) {
3689 return NT_STATUS_NO_SUCH_ALIAS;
3694 /* associate the alias SID with the new handle. */
3695 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3696 return NT_STATUS_NO_MEMORY;
3698 info->acc_granted = acc_granted;
3700 /* get a (unique) handle. open a policy on it. */
3701 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3702 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3704 return NT_STATUS_OK;
3707 /*******************************************************************
3708 set_user_info_7
3709 ********************************************************************/
3711 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3712 struct samr_UserInfo7 *id7,
3713 struct samu *pwd)
3715 NTSTATUS rc;
3717 if (id7 == NULL) {
3718 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3719 TALLOC_FREE(pwd);
3720 return NT_STATUS_ACCESS_DENIED;
3723 if (!id7->account_name.string) {
3724 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3725 TALLOC_FREE(pwd);
3726 return NT_STATUS_ACCESS_DENIED;
3729 /* check to see if the new username already exists. Note: we can't
3730 reliably lock all backends, so there is potentially the
3731 possibility that a user can be created in between this check and
3732 the rename. The rename should fail, but may not get the
3733 exact same failure status code. I think this is small enough
3734 of a window for this type of operation and the results are
3735 simply that the rename fails with a slightly different status
3736 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3738 rc = can_create(mem_ctx, id7->account_name.string);
3739 if (!NT_STATUS_IS_OK(rc)) {
3740 return rc;
3743 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3745 TALLOC_FREE(pwd);
3746 return rc;
3749 /*******************************************************************
3750 set_user_info_16
3751 ********************************************************************/
3753 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3754 struct samu *pwd)
3756 if (id16 == NULL) {
3757 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3758 TALLOC_FREE(pwd);
3759 return False;
3762 /* FIX ME: check if the value is really changed --metze */
3763 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3764 TALLOC_FREE(pwd);
3765 return False;
3768 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3769 TALLOC_FREE(pwd);
3770 return False;
3773 TALLOC_FREE(pwd);
3775 return True;
3778 /*******************************************************************
3779 set_user_info_18
3780 ********************************************************************/
3782 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3783 struct samu *pwd)
3785 if (id18 == NULL) {
3786 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3787 TALLOC_FREE(pwd);
3788 return False;
3791 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3792 TALLOC_FREE(pwd);
3793 return False;
3795 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3796 TALLOC_FREE(pwd);
3797 return False;
3799 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3800 TALLOC_FREE(pwd);
3801 return False;
3804 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3805 TALLOC_FREE(pwd);
3806 return False;
3809 TALLOC_FREE(pwd);
3810 return True;
3813 /*******************************************************************
3814 set_user_info_20
3815 ********************************************************************/
3817 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3818 struct samu *pwd)
3820 if (id20 == NULL) {
3821 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3822 return False;
3825 copy_id20_to_sam_passwd(pwd, id20);
3827 /* write the change out */
3828 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3829 TALLOC_FREE(pwd);
3830 return False;
3833 TALLOC_FREE(pwd);
3835 return True;
3838 /*******************************************************************
3839 set_user_info_21
3840 ********************************************************************/
3842 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3843 struct samr_UserInfo21 *id21,
3844 struct samu *pwd)
3846 NTSTATUS status;
3848 if (id21 == NULL) {
3849 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3850 return NT_STATUS_INVALID_PARAMETER;
3853 /* we need to separately check for an account rename first */
3855 if (id21->account_name.string &&
3856 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3859 /* check to see if the new username already exists. Note: we can't
3860 reliably lock all backends, so there is potentially the
3861 possibility that a user can be created in between this check and
3862 the rename. The rename should fail, but may not get the
3863 exact same failure status code. I think this is small enough
3864 of a window for this type of operation and the results are
3865 simply that the rename fails with a slightly different status
3866 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3868 status = can_create(mem_ctx, id21->account_name.string);
3869 if (!NT_STATUS_IS_OK(status)) {
3870 return status;
3873 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3875 if (!NT_STATUS_IS_OK(status)) {
3876 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3877 nt_errstr(status)));
3878 TALLOC_FREE(pwd);
3879 return status;
3882 /* set the new username so that later
3883 functions can work on the new account */
3884 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3887 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3890 * The funny part about the previous two calls is
3891 * that pwd still has the password hashes from the
3892 * passdb entry. These have not been updated from
3893 * id21. I don't know if they need to be set. --jerry
3896 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3897 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3898 if ( !NT_STATUS_IS_OK(status) ) {
3899 return status;
3903 /* Don't worry about writing out the user account since the
3904 primary group SID is generated solely from the user's Unix
3905 primary group. */
3907 /* write the change out */
3908 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3909 TALLOC_FREE(pwd);
3910 return status;
3913 TALLOC_FREE(pwd);
3915 return NT_STATUS_OK;
3918 /*******************************************************************
3919 set_user_info_23
3920 ********************************************************************/
3922 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3923 struct samr_UserInfo23 *id23,
3924 struct samu *pwd)
3926 char *plaintext_buf = NULL;
3927 uint32 len = 0;
3928 uint16 acct_ctrl;
3929 NTSTATUS status;
3931 if (id23 == NULL) {
3932 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3933 return NT_STATUS_INVALID_PARAMETER;
3936 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3937 pdb_get_username(pwd)));
3939 acct_ctrl = pdb_get_acct_ctrl(pwd);
3941 if (!decode_pw_buffer(mem_ctx,
3942 id23->password.data,
3943 &plaintext_buf,
3944 &len,
3945 STR_UNICODE)) {
3946 TALLOC_FREE(pwd);
3947 return NT_STATUS_INVALID_PARAMETER;
3950 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3951 TALLOC_FREE(pwd);
3952 return NT_STATUS_ACCESS_DENIED;
3955 copy_id23_to_sam_passwd(pwd, id23);
3957 /* if it's a trust account, don't update /etc/passwd */
3958 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3959 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3960 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3961 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3962 } else {
3963 /* update the UNIX password */
3964 if (lp_unix_password_sync() ) {
3965 struct passwd *passwd;
3966 if (pdb_get_username(pwd) == NULL) {
3967 DEBUG(1, ("chgpasswd: User without name???\n"));
3968 TALLOC_FREE(pwd);
3969 return NT_STATUS_ACCESS_DENIED;
3972 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3973 if (passwd == NULL) {
3974 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3977 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3978 TALLOC_FREE(pwd);
3979 return NT_STATUS_ACCESS_DENIED;
3981 TALLOC_FREE(passwd);
3985 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3987 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3988 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3989 pwd)))) {
3990 TALLOC_FREE(pwd);
3991 return status;
3994 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3995 TALLOC_FREE(pwd);
3996 return status;
3999 TALLOC_FREE(pwd);
4001 return NT_STATUS_OK;
4004 /*******************************************************************
4005 set_user_info_pw
4006 ********************************************************************/
4008 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
4009 int level)
4011 uint32 len = 0;
4012 char *plaintext_buf = NULL;
4013 uint32 acct_ctrl;
4014 time_t last_set_time;
4015 enum pdb_value_state last_set_state;
4017 DEBUG(5, ("Attempting administrator password change for user %s\n",
4018 pdb_get_username(pwd)));
4020 acct_ctrl = pdb_get_acct_ctrl(pwd);
4021 /* we need to know if it's expired, because this is an admin change, not a
4022 user change, so it's still expired when we're done */
4023 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
4024 last_set_time = pdb_get_pass_last_set_time(pwd);
4026 if (!decode_pw_buffer(talloc_tos(),
4027 pass,
4028 &plaintext_buf,
4029 &len,
4030 STR_UNICODE)) {
4031 TALLOC_FREE(pwd);
4032 return False;
4035 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4036 TALLOC_FREE(pwd);
4037 return False;
4040 /* if it's a trust account, don't update /etc/passwd */
4041 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4042 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4043 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4044 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4045 } else {
4046 /* update the UNIX password */
4047 if (lp_unix_password_sync()) {
4048 struct passwd *passwd;
4050 if (pdb_get_username(pwd) == NULL) {
4051 DEBUG(1, ("chgpasswd: User without name???\n"));
4052 TALLOC_FREE(pwd);
4053 return False;
4056 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4057 if (passwd == NULL) {
4058 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4061 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4062 TALLOC_FREE(pwd);
4063 return False;
4065 TALLOC_FREE(passwd);
4069 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4072 * A level 25 change does reset the pwdlastset field, a level 24
4073 * change does not. I know this is probably not the full story, but
4074 * it is needed to make XP join LDAP correctly, without it the later
4075 * auth2 check can fail with PWD_MUST_CHANGE.
4077 if (level != 25) {
4079 * restore last set time as this is an admin change, not a
4080 * user pw change
4082 pdb_set_pass_last_set_time (pwd, last_set_time,
4083 last_set_state);
4086 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4088 /* update the SAMBA password */
4089 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4090 TALLOC_FREE(pwd);
4091 return False;
4094 TALLOC_FREE(pwd);
4096 return True;
4099 /*******************************************************************
4100 set_user_info_25
4101 ********************************************************************/
4103 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4104 struct samr_UserInfo25 *id25,
4105 struct samu *pwd)
4107 NTSTATUS status;
4109 if (id25 == NULL) {
4110 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4111 return NT_STATUS_INVALID_PARAMETER;
4114 copy_id25_to_sam_passwd(pwd, id25);
4116 /* write the change out */
4117 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4118 TALLOC_FREE(pwd);
4119 return status;
4123 * We need to "pdb_update_sam_account" before the unix primary group
4124 * is set, because the idealx scripts would also change the
4125 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4126 * the delete explicit / add explicit, which would then fail to find
4127 * the previous primaryGroupSid value.
4130 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4131 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4132 if ( !NT_STATUS_IS_OK(status) ) {
4133 return status;
4137 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
4138 * hereafter! */
4140 return NT_STATUS_OK;
4143 /*******************************************************************
4144 samr_SetUserInfo
4145 ********************************************************************/
4147 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4148 struct samr_SetUserInfo *r)
4150 NTSTATUS status;
4151 struct samu *pwd = NULL;
4152 DOM_SID sid;
4153 POLICY_HND *pol = r->in.user_handle;
4154 union samr_UserInfo *info = r->in.info;
4155 uint16_t switch_value = r->in.level;
4156 uint32_t acc_granted;
4157 uint32_t acc_required;
4158 bool ret;
4159 bool has_enough_rights = False;
4160 uint32_t acb_info;
4161 DISP_INFO *disp_info = NULL;
4163 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4165 /* find the policy handle. open a policy on it. */
4166 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4167 return NT_STATUS_INVALID_HANDLE;
4170 /* This is tricky. A WinXP domain join sets
4171 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4172 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4173 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4174 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4175 we'll use the set from the WinXP join as the basis. */
4177 switch (switch_value) {
4178 case 18:
4179 case 24:
4180 case 25:
4181 case 26:
4182 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4183 break;
4184 default:
4185 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4186 SA_RIGHT_USER_SET_ATTRIBUTES |
4187 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4188 break;
4191 status = access_check_samr_function(acc_granted,
4192 acc_required,
4193 "_samr_SetUserInfo");
4194 if (!NT_STATUS_IS_OK(status)) {
4195 return status;
4198 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4199 sid_string_dbg(&sid), switch_value));
4201 if (info == NULL) {
4202 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4203 return NT_STATUS_INVALID_INFO_CLASS;
4206 if (!(pwd = samu_new(NULL))) {
4207 return NT_STATUS_NO_MEMORY;
4210 become_root();
4211 ret = pdb_getsampwsid(pwd, &sid);
4212 unbecome_root();
4214 if (!ret) {
4215 TALLOC_FREE(pwd);
4216 return NT_STATUS_NO_SUCH_USER;
4219 /* deal with machine password changes differently from userinfo changes */
4220 /* check to see if we have the sufficient rights */
4222 acb_info = pdb_get_acct_ctrl(pwd);
4223 if (acb_info & ACB_WSTRUST)
4224 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4225 &se_machine_account);
4226 else if (acb_info & ACB_NORMAL)
4227 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4228 &se_add_users);
4229 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4230 if (lp_enable_privileges()) {
4231 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4232 DOMAIN_GROUP_RID_ADMINS);
4236 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4237 uidtoname(p->pipe_user.ut.uid),
4238 has_enough_rights ? "" : " not"));
4240 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4242 if (has_enough_rights) {
4243 become_root();
4246 /* ok! user info levels (lots: see MSDEV help), off we go... */
4248 switch (switch_value) {
4250 case 7:
4251 status = set_user_info_7(p->mem_ctx,
4252 &info->info7, pwd);
4253 break;
4255 case 16:
4256 if (!set_user_info_16(&info->info16, pwd)) {
4257 status = NT_STATUS_ACCESS_DENIED;
4259 break;
4261 case 18:
4262 /* Used by AS/U JRA. */
4263 if (!set_user_info_18(&info->info18, pwd)) {
4264 status = NT_STATUS_ACCESS_DENIED;
4266 break;
4268 case 20:
4269 if (!set_user_info_20(&info->info20, pwd)) {
4270 status = NT_STATUS_ACCESS_DENIED;
4272 break;
4274 case 21:
4275 status = set_user_info_21(p->mem_ctx,
4276 &info->info21, pwd);
4277 break;
4279 case 23:
4280 if (!p->session_key.length) {
4281 status = NT_STATUS_NO_USER_SESSION_KEY;
4283 SamOEMhashBlob(info->info23.password.data, 516,
4284 &p->session_key);
4286 dump_data(100, info->info23.password.data, 516);
4288 status = set_user_info_23(p->mem_ctx,
4289 &info->info23, pwd);
4290 break;
4292 case 24:
4293 if (!p->session_key.length) {
4294 status = NT_STATUS_NO_USER_SESSION_KEY;
4296 SamOEMhashBlob(info->info24.password.data,
4297 516,
4298 &p->session_key);
4300 dump_data(100, info->info24.password.data, 516);
4302 if (!set_user_info_pw(info->info24.password.data, pwd,
4303 switch_value)) {
4304 status = NT_STATUS_ACCESS_DENIED;
4306 break;
4308 case 25:
4309 if (!p->session_key.length) {
4310 status = NT_STATUS_NO_USER_SESSION_KEY;
4312 encode_or_decode_arc4_passwd_buffer(info->info25.password.data,
4313 &p->session_key);
4315 dump_data(100, info->info25.password.data, 532);
4317 status = set_user_info_25(p->mem_ctx,
4318 &info->info25, pwd);
4319 if (!NT_STATUS_IS_OK(status)) {
4320 goto done;
4322 if (!set_user_info_pw(info->info25.password.data, pwd,
4323 switch_value)) {
4324 status = NT_STATUS_ACCESS_DENIED;
4326 break;
4328 case 26:
4329 if (!p->session_key.length) {
4330 status = NT_STATUS_NO_USER_SESSION_KEY;
4332 encode_or_decode_arc4_passwd_buffer(info->info26.password.data,
4333 &p->session_key);
4335 dump_data(100, info->info26.password.data, 516);
4337 if (!set_user_info_pw(info->info26.password.data, pwd,
4338 switch_value)) {
4339 status = NT_STATUS_ACCESS_DENIED;
4341 break;
4343 default:
4344 status = NT_STATUS_INVALID_INFO_CLASS;
4347 done:
4349 if (has_enough_rights) {
4350 unbecome_root();
4353 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4355 if (NT_STATUS_IS_OK(status)) {
4356 force_flush_samr_cache(disp_info);
4359 return status;
4362 /*******************************************************************
4363 _samr_SetUserInfo2
4364 ********************************************************************/
4366 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4367 struct samr_SetUserInfo2 *r)
4369 struct samr_SetUserInfo q;
4371 q.in.user_handle = r->in.user_handle;
4372 q.in.level = r->in.level;
4373 q.in.info = r->in.info;
4375 return _samr_SetUserInfo(p, &q);
4378 /*********************************************************************
4379 _samr_GetAliasMembership
4380 *********************************************************************/
4382 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4383 struct samr_GetAliasMembership *r)
4385 size_t num_alias_rids;
4386 uint32 *alias_rids;
4387 struct samr_info *info = NULL;
4388 size_t i;
4390 NTSTATUS ntstatus1;
4391 NTSTATUS ntstatus2;
4393 DOM_SID *members;
4395 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4397 /* find the policy handle. open a policy on it. */
4398 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4399 return NT_STATUS_INVALID_HANDLE;
4401 ntstatus1 = access_check_samr_function(info->acc_granted,
4402 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4403 "_samr_GetAliasMembership");
4404 ntstatus2 = access_check_samr_function(info->acc_granted,
4405 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4406 "_samr_GetAliasMembership");
4408 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4409 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4410 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4411 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4415 if (!sid_check_is_domain(&info->sid) &&
4416 !sid_check_is_builtin(&info->sid))
4417 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4419 if (r->in.sids->num_sids) {
4420 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4422 if (members == NULL)
4423 return NT_STATUS_NO_MEMORY;
4424 } else {
4425 members = NULL;
4428 for (i=0; i<r->in.sids->num_sids; i++)
4429 sid_copy(&members[i], r->in.sids->sids[i].sid);
4431 alias_rids = NULL;
4432 num_alias_rids = 0;
4434 become_root();
4435 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4436 r->in.sids->num_sids,
4437 &alias_rids, &num_alias_rids);
4438 unbecome_root();
4440 if (!NT_STATUS_IS_OK(ntstatus1)) {
4441 return ntstatus1;
4444 r->out.rids->count = num_alias_rids;
4445 r->out.rids->ids = alias_rids;
4447 return NT_STATUS_OK;
4450 /*********************************************************************
4451 _samr_GetMembersInAlias
4452 *********************************************************************/
4454 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4455 struct samr_GetMembersInAlias *r)
4457 NTSTATUS status;
4458 size_t i;
4459 size_t num_sids = 0;
4460 struct lsa_SidPtr *sids = NULL;
4461 DOM_SID *pdb_sids = NULL;
4463 DOM_SID alias_sid;
4465 uint32 acc_granted;
4467 /* find the policy handle. open a policy on it. */
4468 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4469 return NT_STATUS_INVALID_HANDLE;
4471 status = access_check_samr_function(acc_granted,
4472 SA_RIGHT_ALIAS_GET_MEMBERS,
4473 "_samr_GetMembersInAlias");
4474 if (!NT_STATUS_IS_OK(status)) {
4475 return status;
4478 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4480 become_root();
4481 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4482 unbecome_root();
4484 if (!NT_STATUS_IS_OK(status)) {
4485 return status;
4488 if (num_sids) {
4489 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4490 if (sids == NULL) {
4491 TALLOC_FREE(pdb_sids);
4492 return NT_STATUS_NO_MEMORY;
4496 for (i = 0; i < num_sids; i++) {
4497 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4498 if (!sids[i].sid) {
4499 TALLOC_FREE(pdb_sids);
4500 return NT_STATUS_NO_MEMORY;
4504 r->out.sids->num_sids = num_sids;
4505 r->out.sids->sids = sids;
4507 TALLOC_FREE(pdb_sids);
4509 return NT_STATUS_OK;
4512 /*********************************************************************
4513 _samr_QueryGroupMember
4514 *********************************************************************/
4516 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4517 struct samr_QueryGroupMember *r)
4519 DOM_SID group_sid;
4520 size_t i, num_members;
4522 uint32 *rid=NULL;
4523 uint32 *attr=NULL;
4525 uint32 acc_granted;
4527 NTSTATUS status;
4528 struct samr_RidTypeArray *rids = NULL;
4530 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4531 if (!rids) {
4532 return NT_STATUS_NO_MEMORY;
4535 /* find the policy handle. open a policy on it. */
4536 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4537 return NT_STATUS_INVALID_HANDLE;
4539 status = access_check_samr_function(acc_granted,
4540 SA_RIGHT_GROUP_GET_MEMBERS,
4541 "_samr_QueryGroupMember");
4542 if (!NT_STATUS_IS_OK(status)) {
4543 return status;
4546 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4548 if (!sid_check_is_in_our_domain(&group_sid)) {
4549 DEBUG(3, ("sid %s is not in our domain\n",
4550 sid_string_dbg(&group_sid)));
4551 return NT_STATUS_NO_SUCH_GROUP;
4554 DEBUG(10, ("lookup on Domain SID\n"));
4556 become_root();
4557 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4558 &rid, &num_members);
4559 unbecome_root();
4561 if (!NT_STATUS_IS_OK(status))
4562 return status;
4564 if (num_members) {
4565 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4566 if (attr == NULL) {
4567 return NT_STATUS_NO_MEMORY;
4569 } else {
4570 attr = NULL;
4573 for (i=0; i<num_members; i++)
4574 attr[i] = SID_NAME_USER;
4576 rids->count = num_members;
4577 rids->types = attr;
4578 rids->rids = rid;
4580 *r->out.rids = rids;
4582 return NT_STATUS_OK;
4585 /*********************************************************************
4586 _samr_AddAliasMember
4587 *********************************************************************/
4589 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4590 struct samr_AddAliasMember *r)
4592 DOM_SID alias_sid;
4593 uint32 acc_granted;
4594 SE_PRIV se_rights;
4595 bool can_add_accounts;
4596 NTSTATUS status;
4597 DISP_INFO *disp_info = NULL;
4599 /* Find the policy handle. Open a policy on it. */
4600 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4601 return NT_STATUS_INVALID_HANDLE;
4603 status = access_check_samr_function(acc_granted,
4604 SA_RIGHT_ALIAS_ADD_MEMBER,
4605 "_samr_AddAliasMember");
4606 if (!NT_STATUS_IS_OK(status)) {
4607 return status;
4610 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4612 se_priv_copy( &se_rights, &se_add_users );
4613 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4615 /******** BEGIN SeAddUsers BLOCK *********/
4617 if ( can_add_accounts )
4618 become_root();
4620 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4622 if ( can_add_accounts )
4623 unbecome_root();
4625 /******** END SeAddUsers BLOCK *********/
4627 if (NT_STATUS_IS_OK(status)) {
4628 force_flush_samr_cache(disp_info);
4631 return status;
4634 /*********************************************************************
4635 _samr_DeleteAliasMember
4636 *********************************************************************/
4638 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4639 struct samr_DeleteAliasMember *r)
4641 DOM_SID alias_sid;
4642 uint32 acc_granted;
4643 SE_PRIV se_rights;
4644 bool can_add_accounts;
4645 NTSTATUS status;
4646 DISP_INFO *disp_info = NULL;
4648 /* Find the policy handle. Open a policy on it. */
4649 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4650 return NT_STATUS_INVALID_HANDLE;
4652 status = access_check_samr_function(acc_granted,
4653 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4654 "_samr_DeleteAliasMember");
4655 if (!NT_STATUS_IS_OK(status)) {
4656 return status;
4659 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4660 sid_string_dbg(&alias_sid)));
4662 se_priv_copy( &se_rights, &se_add_users );
4663 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4665 /******** BEGIN SeAddUsers BLOCK *********/
4667 if ( can_add_accounts )
4668 become_root();
4670 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4672 if ( can_add_accounts )
4673 unbecome_root();
4675 /******** END SeAddUsers BLOCK *********/
4677 if (NT_STATUS_IS_OK(status)) {
4678 force_flush_samr_cache(disp_info);
4681 return status;
4684 /*********************************************************************
4685 _samr_AddGroupMember
4686 *********************************************************************/
4688 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4689 struct samr_AddGroupMember *r)
4691 NTSTATUS status;
4692 DOM_SID group_sid;
4693 uint32 group_rid;
4694 uint32 acc_granted;
4695 SE_PRIV se_rights;
4696 bool can_add_accounts;
4697 DISP_INFO *disp_info = NULL;
4699 /* Find the policy handle. Open a policy on it. */
4700 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4701 return NT_STATUS_INVALID_HANDLE;
4703 status = access_check_samr_function(acc_granted,
4704 SA_RIGHT_GROUP_ADD_MEMBER,
4705 "_samr_AddGroupMember");
4706 if (!NT_STATUS_IS_OK(status)) {
4707 return status;
4710 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4712 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4713 &group_rid)) {
4714 return NT_STATUS_INVALID_HANDLE;
4717 se_priv_copy( &se_rights, &se_add_users );
4718 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4720 /******** BEGIN SeAddUsers BLOCK *********/
4722 if ( can_add_accounts )
4723 become_root();
4725 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4727 if ( can_add_accounts )
4728 unbecome_root();
4730 /******** END SeAddUsers BLOCK *********/
4732 force_flush_samr_cache(disp_info);
4734 return status;
4737 /*********************************************************************
4738 _samr_DeleteGroupMember
4739 *********************************************************************/
4741 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4742 struct samr_DeleteGroupMember *r)
4745 NTSTATUS status;
4746 DOM_SID group_sid;
4747 uint32 group_rid;
4748 uint32 acc_granted;
4749 SE_PRIV se_rights;
4750 bool can_add_accounts;
4751 DISP_INFO *disp_info = NULL;
4754 * delete the group member named r->in.rid
4755 * who is a member of the sid associated with the handle
4756 * the rid is a user's rid as the group is a domain group.
4759 /* Find the policy handle. Open a policy on it. */
4760 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4761 return NT_STATUS_INVALID_HANDLE;
4763 status = access_check_samr_function(acc_granted,
4764 SA_RIGHT_GROUP_REMOVE_MEMBER,
4765 "_samr_DeleteGroupMember");
4766 if (!NT_STATUS_IS_OK(status)) {
4767 return status;
4770 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4771 &group_rid)) {
4772 return NT_STATUS_INVALID_HANDLE;
4775 se_priv_copy( &se_rights, &se_add_users );
4776 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4778 /******** BEGIN SeAddUsers BLOCK *********/
4780 if ( can_add_accounts )
4781 become_root();
4783 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4785 if ( can_add_accounts )
4786 unbecome_root();
4788 /******** END SeAddUsers BLOCK *********/
4790 force_flush_samr_cache(disp_info);
4792 return status;
4795 /*********************************************************************
4796 _samr_DeleteUser
4797 *********************************************************************/
4799 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4800 struct samr_DeleteUser *r)
4802 NTSTATUS status;
4803 DOM_SID user_sid;
4804 struct samu *sam_pass=NULL;
4805 uint32 acc_granted;
4806 bool can_add_accounts;
4807 uint32 acb_info;
4808 DISP_INFO *disp_info = NULL;
4809 bool ret;
4811 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4813 /* Find the policy handle. Open a policy on it. */
4814 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4815 return NT_STATUS_INVALID_HANDLE;
4817 status = access_check_samr_function(acc_granted,
4818 STD_RIGHT_DELETE_ACCESS,
4819 "_samr_DeleteUser");
4820 if (!NT_STATUS_IS_OK(status)) {
4821 return status;
4824 if (!sid_check_is_in_our_domain(&user_sid))
4825 return NT_STATUS_CANNOT_DELETE;
4827 /* check if the user exists before trying to delete */
4828 if ( !(sam_pass = samu_new( NULL )) ) {
4829 return NT_STATUS_NO_MEMORY;
4832 become_root();
4833 ret = pdb_getsampwsid(sam_pass, &user_sid);
4834 unbecome_root();
4836 if( !ret ) {
4837 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4838 sid_string_dbg(&user_sid)));
4839 TALLOC_FREE(sam_pass);
4840 return NT_STATUS_NO_SUCH_USER;
4843 acb_info = pdb_get_acct_ctrl(sam_pass);
4845 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4846 if ( acb_info & ACB_WSTRUST ) {
4847 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4848 } else {
4849 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4852 /******** BEGIN SeAddUsers BLOCK *********/
4854 if ( can_add_accounts )
4855 become_root();
4857 status = pdb_delete_user(p->mem_ctx, sam_pass);
4859 if ( can_add_accounts )
4860 unbecome_root();
4862 /******** END SeAddUsers BLOCK *********/
4864 if ( !NT_STATUS_IS_OK(status) ) {
4865 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4866 "user %s: %s.\n", pdb_get_username(sam_pass),
4867 nt_errstr(status)));
4868 TALLOC_FREE(sam_pass);
4869 return status;
4873 TALLOC_FREE(sam_pass);
4875 if (!close_policy_hnd(p, r->in.user_handle))
4876 return NT_STATUS_OBJECT_NAME_INVALID;
4878 ZERO_STRUCTP(r->out.user_handle);
4880 force_flush_samr_cache(disp_info);
4882 return NT_STATUS_OK;
4885 /*********************************************************************
4886 _samr_DeleteDomainGroup
4887 *********************************************************************/
4889 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4890 struct samr_DeleteDomainGroup *r)
4892 NTSTATUS status;
4893 DOM_SID group_sid;
4894 uint32 group_rid;
4895 uint32 acc_granted;
4896 SE_PRIV se_rights;
4897 bool can_add_accounts;
4898 DISP_INFO *disp_info = NULL;
4900 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4902 /* Find the policy handle. Open a policy on it. */
4903 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4904 return NT_STATUS_INVALID_HANDLE;
4906 status = access_check_samr_function(acc_granted,
4907 STD_RIGHT_DELETE_ACCESS,
4908 "_samr_DeleteDomainGroup");
4909 if (!NT_STATUS_IS_OK(status)) {
4910 return status;
4913 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4915 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4916 &group_rid)) {
4917 return NT_STATUS_NO_SUCH_GROUP;
4920 se_priv_copy( &se_rights, &se_add_users );
4921 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4923 /******** BEGIN SeAddUsers BLOCK *********/
4925 if ( can_add_accounts )
4926 become_root();
4928 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4930 if ( can_add_accounts )
4931 unbecome_root();
4933 /******** END SeAddUsers BLOCK *********/
4935 if ( !NT_STATUS_IS_OK(status) ) {
4936 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4937 "entry for group %s: %s\n",
4938 sid_string_dbg(&group_sid),
4939 nt_errstr(status)));
4940 return status;
4943 if (!close_policy_hnd(p, r->in.group_handle))
4944 return NT_STATUS_OBJECT_NAME_INVALID;
4946 force_flush_samr_cache(disp_info);
4948 return NT_STATUS_OK;
4951 /*********************************************************************
4952 _samr_DeleteDomAlias
4953 *********************************************************************/
4955 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4956 struct samr_DeleteDomAlias *r)
4958 DOM_SID alias_sid;
4959 uint32 acc_granted;
4960 SE_PRIV se_rights;
4961 bool can_add_accounts;
4962 NTSTATUS status;
4963 DISP_INFO *disp_info = NULL;
4965 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4967 /* Find the policy handle. Open a policy on it. */
4968 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4969 return NT_STATUS_INVALID_HANDLE;
4971 /* copy the handle to the outgoing reply */
4973 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4975 status = access_check_samr_function(acc_granted,
4976 STD_RIGHT_DELETE_ACCESS,
4977 "_samr_DeleteDomAlias");
4978 if (!NT_STATUS_IS_OK(status)) {
4979 return status;
4982 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4984 /* Don't let Windows delete builtin groups */
4986 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4987 return NT_STATUS_SPECIAL_ACCOUNT;
4990 if (!sid_check_is_in_our_domain(&alias_sid))
4991 return NT_STATUS_NO_SUCH_ALIAS;
4993 DEBUG(10, ("lookup on Local SID\n"));
4995 se_priv_copy( &se_rights, &se_add_users );
4996 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4998 /******** BEGIN SeAddUsers BLOCK *********/
5000 if ( can_add_accounts )
5001 become_root();
5003 /* Have passdb delete the alias */
5004 status = pdb_delete_alias(&alias_sid);
5006 if ( can_add_accounts )
5007 unbecome_root();
5009 /******** END SeAddUsers BLOCK *********/
5011 if ( !NT_STATUS_IS_OK(status))
5012 return status;
5014 if (!close_policy_hnd(p, r->in.alias_handle))
5015 return NT_STATUS_OBJECT_NAME_INVALID;
5017 force_flush_samr_cache(disp_info);
5019 return NT_STATUS_OK;
5022 /*********************************************************************
5023 _samr_CreateDomainGroup
5024 *********************************************************************/
5026 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5027 struct samr_CreateDomainGroup *r)
5030 NTSTATUS status;
5031 DOM_SID dom_sid;
5032 DOM_SID info_sid;
5033 const char *name;
5034 struct samr_info *info;
5035 uint32 acc_granted;
5036 SE_PRIV se_rights;
5037 bool can_add_accounts;
5038 DISP_INFO *disp_info = NULL;
5040 /* Find the policy handle. Open a policy on it. */
5041 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5042 return NT_STATUS_INVALID_HANDLE;
5044 status = access_check_samr_function(acc_granted,
5045 SA_RIGHT_DOMAIN_CREATE_GROUP,
5046 "_samr_CreateDomainGroup");
5047 if (!NT_STATUS_IS_OK(status)) {
5048 return status;
5051 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5052 return NT_STATUS_ACCESS_DENIED;
5054 name = r->in.name->string;
5055 if (name == NULL) {
5056 return NT_STATUS_NO_MEMORY;
5059 status = can_create(p->mem_ctx, name);
5060 if (!NT_STATUS_IS_OK(status)) {
5061 return status;
5064 se_priv_copy( &se_rights, &se_add_users );
5065 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5067 /******** BEGIN SeAddUsers BLOCK *********/
5069 if ( can_add_accounts )
5070 become_root();
5072 /* check that we successfully create the UNIX group */
5074 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5076 if ( can_add_accounts )
5077 unbecome_root();
5079 /******** END SeAddUsers BLOCK *********/
5081 /* check if we should bail out here */
5083 if ( !NT_STATUS_IS_OK(status) )
5084 return status;
5086 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5088 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5089 return NT_STATUS_NO_MEMORY;
5091 /* they created it; let the user do what he wants with it */
5093 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5095 /* get a (unique) handle. open a policy on it. */
5096 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5097 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5099 force_flush_samr_cache(disp_info);
5101 return NT_STATUS_OK;
5104 /*********************************************************************
5105 _samr_CreateDomAlias
5106 *********************************************************************/
5108 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5109 struct samr_CreateDomAlias *r)
5111 DOM_SID dom_sid;
5112 DOM_SID info_sid;
5113 const char *name = NULL;
5114 struct samr_info *info;
5115 uint32 acc_granted;
5116 gid_t gid;
5117 NTSTATUS result;
5118 SE_PRIV se_rights;
5119 bool can_add_accounts;
5120 DISP_INFO *disp_info = NULL;
5122 /* Find the policy handle. Open a policy on it. */
5123 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5124 return NT_STATUS_INVALID_HANDLE;
5126 result = access_check_samr_function(acc_granted,
5127 SA_RIGHT_DOMAIN_CREATE_ALIAS,
5128 "_samr_CreateDomAlias");
5129 if (!NT_STATUS_IS_OK(result)) {
5130 return result;
5133 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5134 return NT_STATUS_ACCESS_DENIED;
5136 name = r->in.alias_name->string;
5138 se_priv_copy( &se_rights, &se_add_users );
5139 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5141 result = can_create(p->mem_ctx, name);
5142 if (!NT_STATUS_IS_OK(result)) {
5143 return result;
5146 /******** BEGIN SeAddUsers BLOCK *********/
5148 if ( can_add_accounts )
5149 become_root();
5151 /* Have passdb create the alias */
5152 result = pdb_create_alias(name, r->out.rid);
5154 if ( can_add_accounts )
5155 unbecome_root();
5157 /******** END SeAddUsers BLOCK *********/
5159 if (!NT_STATUS_IS_OK(result)) {
5160 DEBUG(10, ("pdb_create_alias failed: %s\n",
5161 nt_errstr(result)));
5162 return result;
5165 sid_copy(&info_sid, get_global_sam_sid());
5166 sid_append_rid(&info_sid, *r->out.rid);
5168 if (!sid_to_gid(&info_sid, &gid)) {
5169 DEBUG(10, ("Could not find alias just created\n"));
5170 return NT_STATUS_ACCESS_DENIED;
5173 /* check if the group has been successfully created */
5174 if ( getgrgid(gid) == NULL ) {
5175 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5176 gid));
5177 return NT_STATUS_ACCESS_DENIED;
5180 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5181 return NT_STATUS_NO_MEMORY;
5183 /* they created it; let the user do what he wants with it */
5185 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5187 /* get a (unique) handle. open a policy on it. */
5188 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5189 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5191 force_flush_samr_cache(disp_info);
5193 return NT_STATUS_OK;
5196 /*********************************************************************
5197 _samr_QueryGroupInfo
5198 *********************************************************************/
5200 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5201 struct samr_QueryGroupInfo *r)
5203 NTSTATUS status;
5204 DOM_SID group_sid;
5205 GROUP_MAP map;
5206 union samr_GroupInfo *info = NULL;
5207 uint32 acc_granted;
5208 bool ret;
5209 uint32_t attributes = SE_GROUP_MANDATORY |
5210 SE_GROUP_ENABLED_BY_DEFAULT |
5211 SE_GROUP_ENABLED;
5212 const char *group_name = NULL;
5213 const char *group_description = NULL;
5215 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5216 return NT_STATUS_INVALID_HANDLE;
5218 status = access_check_samr_function(acc_granted,
5219 SA_RIGHT_GROUP_LOOKUP_INFO,
5220 "_samr_QueryGroupInfo");
5221 if (!NT_STATUS_IS_OK(status)) {
5222 return status;
5225 become_root();
5226 ret = get_domain_group_from_sid(group_sid, &map);
5227 unbecome_root();
5228 if (!ret)
5229 return NT_STATUS_INVALID_HANDLE;
5231 /* FIXME: map contains fstrings */
5232 group_name = talloc_strdup(r, map.nt_name);
5233 group_description = talloc_strdup(r, map.comment);
5235 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5236 if (!info) {
5237 return NT_STATUS_NO_MEMORY;
5240 switch (r->in.level) {
5241 case 1: {
5242 uint32 *members;
5243 size_t num_members;
5245 become_root();
5246 status = pdb_enum_group_members(
5247 p->mem_ctx, &group_sid, &members, &num_members);
5248 unbecome_root();
5250 if (!NT_STATUS_IS_OK(status)) {
5251 return status;
5254 init_samr_group_info1(&info->all,
5255 group_name,
5256 attributes,
5257 num_members,
5258 group_description);
5259 break;
5261 case 2:
5262 init_samr_group_info2(&info->name,
5263 group_name);
5264 break;
5265 case 3:
5266 init_samr_group_info3(&info->attributes,
5267 attributes);
5268 break;
5269 case 4:
5270 init_samr_group_info4(&info->description,
5271 group_description);
5272 break;
5273 case 5: {
5275 uint32 *members;
5276 size_t num_members;
5280 become_root();
5281 status = pdb_enum_group_members(
5282 p->mem_ctx, &group_sid, &members, &num_members);
5283 unbecome_root();
5285 if (!NT_STATUS_IS_OK(status)) {
5286 return status;
5289 init_samr_group_info5(&info->all2,
5290 group_name,
5291 attributes,
5292 0, /* num_members - in w2k3 this is always 0 */
5293 group_description);
5295 break;
5297 default:
5298 return NT_STATUS_INVALID_INFO_CLASS;
5301 *r->out.info = info;
5303 return NT_STATUS_OK;
5306 /*********************************************************************
5307 _samr_SetGroupInfo
5308 *********************************************************************/
5310 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5311 struct samr_SetGroupInfo *r)
5313 DOM_SID group_sid;
5314 GROUP_MAP map;
5315 uint32 acc_granted;
5316 NTSTATUS status;
5317 bool ret;
5318 bool can_mod_accounts;
5319 DISP_INFO *disp_info = NULL;
5321 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5322 return NT_STATUS_INVALID_HANDLE;
5324 status = access_check_samr_function(acc_granted,
5325 SA_RIGHT_GROUP_SET_INFO,
5326 "_samr_SetGroupInfo");
5327 if (!NT_STATUS_IS_OK(status)) {
5328 return status;
5331 become_root();
5332 ret = get_domain_group_from_sid(group_sid, &map);
5333 unbecome_root();
5334 if (!ret)
5335 return NT_STATUS_NO_SUCH_GROUP;
5337 switch (r->in.level) {
5338 case 1:
5339 fstrcpy(map.comment, r->in.info->all.description.string);
5340 break;
5341 case 4:
5342 fstrcpy(map.comment, r->in.info->description.string);
5343 break;
5344 default:
5345 return NT_STATUS_INVALID_INFO_CLASS;
5348 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5350 /******** BEGIN SeAddUsers BLOCK *********/
5352 if ( can_mod_accounts )
5353 become_root();
5355 status = pdb_update_group_mapping_entry(&map);
5357 if ( can_mod_accounts )
5358 unbecome_root();
5360 /******** End SeAddUsers BLOCK *********/
5362 if (NT_STATUS_IS_OK(status)) {
5363 force_flush_samr_cache(disp_info);
5366 return status;
5369 /*********************************************************************
5370 _samr_SetAliasInfo
5371 *********************************************************************/
5373 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5374 struct samr_SetAliasInfo *r)
5376 DOM_SID group_sid;
5377 struct acct_info info;
5378 uint32 acc_granted;
5379 bool can_mod_accounts;
5380 NTSTATUS status;
5381 DISP_INFO *disp_info = NULL;
5383 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5384 return NT_STATUS_INVALID_HANDLE;
5386 status = access_check_samr_function(acc_granted,
5387 SA_RIGHT_ALIAS_SET_INFO,
5388 "_samr_SetAliasInfo");
5389 if (!NT_STATUS_IS_OK(status)) {
5390 return status;
5393 /* get the current group information */
5395 become_root();
5396 status = pdb_get_aliasinfo( &group_sid, &info );
5397 unbecome_root();
5399 if ( !NT_STATUS_IS_OK(status))
5400 return status;
5402 switch (r->in.level) {
5403 case ALIASINFONAME:
5405 fstring group_name;
5407 /* We currently do not support renaming groups in the
5408 the BUILTIN domain. Refer to util_builtin.c to understand
5409 why. The eventually needs to be fixed to be like Windows
5410 where you can rename builtin groups, just not delete them */
5412 if ( sid_check_is_in_builtin( &group_sid ) ) {
5413 return NT_STATUS_SPECIAL_ACCOUNT;
5416 /* There has to be a valid name (and it has to be different) */
5418 if ( !r->in.info->name.string )
5419 return NT_STATUS_INVALID_PARAMETER;
5421 /* If the name is the same just reply "ok". Yes this
5422 doesn't allow you to change the case of a group name. */
5424 if ( strequal( r->in.info->name.string, info.acct_name ) )
5425 return NT_STATUS_OK;
5427 fstrcpy( info.acct_name, r->in.info->name.string);
5429 /* make sure the name doesn't already exist as a user
5430 or local group */
5432 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5433 status = can_create( p->mem_ctx, group_name );
5434 if ( !NT_STATUS_IS_OK( status ) )
5435 return status;
5436 break;
5438 case ALIASINFODESCRIPTION:
5439 if (r->in.info->description.string) {
5440 fstrcpy(info.acct_desc,
5441 r->in.info->description.string);
5442 } else {
5443 fstrcpy( info.acct_desc, "" );
5445 break;
5446 default:
5447 return NT_STATUS_INVALID_INFO_CLASS;
5450 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5452 /******** BEGIN SeAddUsers BLOCK *********/
5454 if ( can_mod_accounts )
5455 become_root();
5457 status = pdb_set_aliasinfo( &group_sid, &info );
5459 if ( can_mod_accounts )
5460 unbecome_root();
5462 /******** End SeAddUsers BLOCK *********/
5464 if (NT_STATUS_IS_OK(status))
5465 force_flush_samr_cache(disp_info);
5467 return status;
5470 /****************************************************************
5471 _samr_GetDomPwInfo
5472 ****************************************************************/
5474 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5475 struct samr_GetDomPwInfo *r)
5477 uint32_t min_password_length = 0;
5478 uint32_t password_properties = 0;
5480 /* Perform access check. Since this rpc does not require a
5481 policy handle it will not be caught by the access checks on
5482 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5484 if (!pipe_access_check(p)) {
5485 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5486 return NT_STATUS_ACCESS_DENIED;
5489 become_root();
5490 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5491 &min_password_length);
5492 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5493 &password_properties);
5494 unbecome_root();
5496 if (lp_check_password_script() && *lp_check_password_script()) {
5497 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5500 r->out.info->min_password_length = min_password_length;
5501 r->out.info->password_properties = password_properties;
5503 return NT_STATUS_OK;
5506 /*********************************************************************
5507 _samr_OpenGroup
5508 *********************************************************************/
5510 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5511 struct samr_OpenGroup *r)
5514 DOM_SID sid;
5515 DOM_SID info_sid;
5516 GROUP_MAP map;
5517 struct samr_info *info;
5518 SEC_DESC *psd = NULL;
5519 uint32 acc_granted;
5520 uint32 des_access = r->in.access_mask;
5521 size_t sd_size;
5522 NTSTATUS status;
5523 fstring sid_string;
5524 bool ret;
5525 SE_PRIV se_rights;
5527 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5528 return NT_STATUS_INVALID_HANDLE;
5530 status = access_check_samr_function(acc_granted,
5531 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5532 "_samr_OpenGroup");
5534 if ( !NT_STATUS_IS_OK(status) )
5535 return status;
5537 /*check if access can be granted as requested by client. */
5538 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
5540 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5541 se_map_generic(&des_access,&grp_generic_mapping);
5543 se_priv_copy( &se_rights, &se_add_users );
5545 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5546 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5547 &acc_granted, "_samr_OpenGroup");
5549 if ( !NT_STATUS_IS_OK(status) )
5550 return status;
5552 /* this should not be hard-coded like this */
5554 if (!sid_equal(&sid, get_global_sam_sid()))
5555 return NT_STATUS_ACCESS_DENIED;
5557 sid_copy(&info_sid, get_global_sam_sid());
5558 sid_append_rid(&info_sid, r->in.rid);
5559 sid_to_fstring(sid_string, &info_sid);
5561 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5562 return NT_STATUS_NO_MEMORY;
5564 info->acc_granted = acc_granted;
5566 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5568 /* check if that group really exists */
5569 become_root();
5570 ret = get_domain_group_from_sid(info->sid, &map);
5571 unbecome_root();
5572 if (!ret)
5573 return NT_STATUS_NO_SUCH_GROUP;
5575 /* get a (unique) handle. open a policy on it. */
5576 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5577 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5579 return NT_STATUS_OK;
5582 /*********************************************************************
5583 _samr_RemoveMemberFromForeignDomain
5584 *********************************************************************/
5586 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5587 struct samr_RemoveMemberFromForeignDomain *r)
5589 DOM_SID delete_sid, domain_sid;
5590 uint32 acc_granted;
5591 NTSTATUS result;
5592 DISP_INFO *disp_info = NULL;
5594 sid_copy( &delete_sid, r->in.sid );
5596 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5597 sid_string_dbg(&delete_sid)));
5599 /* Find the policy handle. Open a policy on it. */
5601 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5602 &acc_granted, &disp_info))
5603 return NT_STATUS_INVALID_HANDLE;
5605 result = access_check_samr_function(acc_granted,
5606 STD_RIGHT_DELETE_ACCESS,
5607 "_samr_RemoveMemberFromForeignDomain");
5609 if (!NT_STATUS_IS_OK(result))
5610 return result;
5612 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5613 sid_string_dbg(&domain_sid)));
5615 /* we can only delete a user from a group since we don't have
5616 nested groups anyways. So in the latter case, just say OK */
5618 /* TODO: The above comment nowadays is bogus. Since we have nested
5619 * groups now, and aliases members are never reported out of the unix
5620 * group membership, the "just say OK" makes this call a no-op. For
5621 * us. This needs fixing however. */
5623 /* I've only ever seen this in the wild when deleting a user from
5624 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5625 * is the user about to be deleted. I very much suspect this is the
5626 * only application of this call. To verify this, let people report
5627 * other cases. */
5629 if (!sid_check_is_builtin(&domain_sid)) {
5630 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5631 "global_sam_sid() = %s\n",
5632 sid_string_dbg(&domain_sid),
5633 sid_string_dbg(get_global_sam_sid())));
5634 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5635 return NT_STATUS_OK;
5638 force_flush_samr_cache(disp_info);
5640 result = NT_STATUS_OK;
5642 return result;
5645 /*******************************************************************
5646 _samr_QueryDomainInfo2
5647 ********************************************************************/
5649 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5650 struct samr_QueryDomainInfo2 *r)
5652 struct samr_QueryDomainInfo q;
5654 q.in.domain_handle = r->in.domain_handle;
5655 q.in.level = r->in.level;
5657 q.out.info = r->out.info;
5659 return _samr_QueryDomainInfo(p, &q);
5662 /*******************************************************************
5663 _samr_SetDomainInfo
5664 ********************************************************************/
5666 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5667 struct samr_SetDomainInfo *r)
5669 struct samr_info *info = NULL;
5670 time_t u_expire, u_min_age;
5671 time_t u_logout;
5672 time_t u_lock_duration, u_reset_time;
5673 NTSTATUS result;
5675 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5677 /* find the policy handle. open a policy on it. */
5678 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5679 return NT_STATUS_INVALID_HANDLE;
5681 /* We do have different access bits for info
5682 * levels here, but we're really just looking for
5683 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5684 * this maps to different specific bits. So
5685 * assume if we have SA_RIGHT_DOMAIN_SET_INFO_1
5686 * set we are ok. */
5688 result = access_check_samr_function(info->acc_granted,
5689 SA_RIGHT_DOMAIN_SET_INFO_1,
5690 "_samr_SetDomainInfo");
5692 if (!NT_STATUS_IS_OK(result))
5693 return result;
5695 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5697 switch (r->in.level) {
5698 case 0x01:
5699 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5700 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5701 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5702 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5703 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5704 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5705 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5706 break;
5707 case 0x02:
5708 break;
5709 case 0x03:
5710 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5711 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5712 break;
5713 case 0x05:
5714 break;
5715 case 0x06:
5716 break;
5717 case 0x07:
5718 break;
5719 case 0x0c:
5720 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5721 if (u_lock_duration != -1)
5722 u_lock_duration /= 60;
5724 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5726 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5727 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5728 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5729 break;
5730 default:
5731 return NT_STATUS_INVALID_INFO_CLASS;
5734 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5736 return NT_STATUS_OK;
5739 /****************************************************************
5740 _samr_GetDisplayEnumerationIndex
5741 ****************************************************************/
5743 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5744 struct samr_GetDisplayEnumerationIndex *r)
5746 struct samr_info *info = NULL;
5747 uint32_t max_entries = (uint32_t) -1;
5748 uint32_t enum_context = 0;
5749 int i;
5750 uint32_t num_account = 0;
5751 struct samr_displayentry *entries = NULL;
5752 NTSTATUS status;
5754 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5756 /* find the policy handle. open a policy on it. */
5757 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5758 return NT_STATUS_INVALID_HANDLE;
5761 status = access_check_samr_function(info->acc_granted,
5762 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
5763 "_samr_GetDisplayEnumerationIndex");
5764 if (!NT_STATUS_IS_OK(status)) {
5765 return status;
5768 if ((r->in.level < 1) || (r->in.level > 3)) {
5769 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5770 "Unknown info level (%u)\n",
5771 r->in.level));
5772 return NT_STATUS_INVALID_INFO_CLASS;
5775 become_root();
5777 /* The following done as ROOT. Don't return without unbecome_root(). */
5779 switch (r->in.level) {
5780 case 1:
5781 if (info->disp_info->users == NULL) {
5782 info->disp_info->users = pdb_search_users(ACB_NORMAL);
5783 if (info->disp_info->users == NULL) {
5784 unbecome_root();
5785 return NT_STATUS_ACCESS_DENIED;
5787 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5788 "starting user enumeration at index %u\n",
5789 (unsigned int)enum_context));
5790 } else {
5791 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5792 "using cached user enumeration at index %u\n",
5793 (unsigned int)enum_context));
5795 num_account = pdb_search_entries(info->disp_info->users,
5796 enum_context, max_entries,
5797 &entries);
5798 break;
5799 case 2:
5800 if (info->disp_info->machines == NULL) {
5801 info->disp_info->machines =
5802 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5803 if (info->disp_info->machines == NULL) {
5804 unbecome_root();
5805 return NT_STATUS_ACCESS_DENIED;
5807 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5808 "starting machine enumeration at index %u\n",
5809 (unsigned int)enum_context));
5810 } else {
5811 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5812 "using cached machine enumeration at index %u\n",
5813 (unsigned int)enum_context));
5815 num_account = pdb_search_entries(info->disp_info->machines,
5816 enum_context, max_entries,
5817 &entries);
5818 break;
5819 case 3:
5820 if (info->disp_info->groups == NULL) {
5821 info->disp_info->groups = pdb_search_groups();
5822 if (info->disp_info->groups == NULL) {
5823 unbecome_root();
5824 return NT_STATUS_ACCESS_DENIED;
5826 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5827 "starting group enumeration at index %u\n",
5828 (unsigned int)enum_context));
5829 } else {
5830 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5831 "using cached group enumeration at index %u\n",
5832 (unsigned int)enum_context));
5834 num_account = pdb_search_entries(info->disp_info->groups,
5835 enum_context, max_entries,
5836 &entries);
5837 break;
5838 default:
5839 unbecome_root();
5840 smb_panic("info class changed");
5841 break;
5844 unbecome_root();
5846 /* Ensure we cache this enumeration. */
5847 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5849 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5850 r->in.name->string));
5852 for (i=0; i<num_account; i++) {
5853 if (strequal(entries[i].account_name, r->in.name->string)) {
5854 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5855 "found %s at idx %d\n",
5856 r->in.name->string, i));
5857 *r->out.idx = i;
5858 return NT_STATUS_OK;
5862 /* assuming account_name lives at the very end */
5863 *r->out.idx = num_account;
5865 return NT_STATUS_NO_MORE_ENTRIES;
5868 /****************************************************************
5869 _samr_GetDisplayEnumerationIndex2
5870 ****************************************************************/
5872 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5873 struct samr_GetDisplayEnumerationIndex2 *r)
5875 struct samr_GetDisplayEnumerationIndex q;
5877 q.in.domain_handle = r->in.domain_handle;
5878 q.in.level = r->in.level;
5879 q.in.name = r->in.name;
5881 q.out.idx = r->out.idx;
5883 return _samr_GetDisplayEnumerationIndex(p, &q);
5886 /****************************************************************
5887 ****************************************************************/
5889 NTSTATUS _samr_Shutdown(pipes_struct *p,
5890 struct samr_Shutdown *r)
5892 p->rng_fault_state = true;
5893 return NT_STATUS_NOT_IMPLEMENTED;
5896 /****************************************************************
5897 ****************************************************************/
5899 NTSTATUS _samr_CreateUser(pipes_struct *p,
5900 struct samr_CreateUser *r)
5902 p->rng_fault_state = true;
5903 return NT_STATUS_NOT_IMPLEMENTED;
5906 /****************************************************************
5907 ****************************************************************/
5909 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5910 struct samr_SetMemberAttributesOfGroup *r)
5912 p->rng_fault_state = true;
5913 return NT_STATUS_NOT_IMPLEMENTED;
5916 /****************************************************************
5917 ****************************************************************/
5919 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5920 struct samr_ChangePasswordUser *r)
5922 p->rng_fault_state = true;
5923 return NT_STATUS_NOT_IMPLEMENTED;
5926 /****************************************************************
5927 ****************************************************************/
5929 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5930 struct samr_TestPrivateFunctionsDomain *r)
5932 p->rng_fault_state = true;
5933 return NT_STATUS_NOT_IMPLEMENTED;
5936 /****************************************************************
5937 ****************************************************************/
5939 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5940 struct samr_TestPrivateFunctionsUser *r)
5942 p->rng_fault_state = true;
5943 return NT_STATUS_NOT_IMPLEMENTED;
5946 /****************************************************************
5947 ****************************************************************/
5949 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5950 struct samr_QueryUserInfo2 *r)
5952 p->rng_fault_state = true;
5953 return NT_STATUS_NOT_IMPLEMENTED;
5956 /****************************************************************
5957 ****************************************************************/
5959 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5960 struct samr_AddMultipleMembersToAlias *r)
5962 p->rng_fault_state = true;
5963 return NT_STATUS_NOT_IMPLEMENTED;
5966 /****************************************************************
5967 ****************************************************************/
5969 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5970 struct samr_RemoveMultipleMembersFromAlias *r)
5972 p->rng_fault_state = true;
5973 return NT_STATUS_NOT_IMPLEMENTED;
5976 /****************************************************************
5977 ****************************************************************/
5979 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5980 struct samr_OemChangePasswordUser2 *r)
5982 p->rng_fault_state = true;
5983 return NT_STATUS_NOT_IMPLEMENTED;
5986 /****************************************************************
5987 ****************************************************************/
5989 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5990 struct samr_SetBootKeyInformation *r)
5992 p->rng_fault_state = true;
5993 return NT_STATUS_NOT_IMPLEMENTED;
5996 /****************************************************************
5997 ****************************************************************/
5999 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6000 struct samr_GetBootKeyInformation *r)
6002 p->rng_fault_state = true;
6003 return NT_STATUS_NOT_IMPLEMENTED;
6006 /****************************************************************
6007 ****************************************************************/
6009 NTSTATUS _samr_Connect3(pipes_struct *p,
6010 struct samr_Connect3 *r)
6012 p->rng_fault_state = true;
6013 return NT_STATUS_NOT_IMPLEMENTED;
6016 /****************************************************************
6017 ****************************************************************/
6019 NTSTATUS _samr_RidToSid(pipes_struct *p,
6020 struct samr_RidToSid *r)
6022 p->rng_fault_state = true;
6023 return NT_STATUS_NOT_IMPLEMENTED;
6026 /****************************************************************
6027 ****************************************************************/
6029 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6030 struct samr_SetDsrmPassword *r)
6032 p->rng_fault_state = true;
6033 return NT_STATUS_NOT_IMPLEMENTED;
6036 /****************************************************************
6037 ****************************************************************/
6039 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6040 struct samr_ValidatePassword *r)
6042 p->rng_fault_state = true;
6043 return NT_STATUS_NOT_IMPLEMENTED;