s3-samr-server: remove unused historic code.
[Samba.git] / source / rpc_server / srv_samr_nt.c
blob2c27f309a78bb17255955e325229f24149887438
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
34 #include "includes.h"
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
42 SAMR_USER_ACCESS_SET_LOC_COM)
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 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 & ~SAMR_USER_ACCESS_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 size_t i = 0;
118 SEC_ACL *psa = NULL;
120 /* basic access for Everyone */
122 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
123 map->generic_execute | map->generic_read, 0);
125 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
127 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
128 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
129 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
130 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
132 /* Add Full Access for Domain Admins if we are a DC */
134 if ( IS_DC ) {
135 sid_copy( &domadmin_sid, get_global_sam_sid() );
136 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
137 init_sec_ace(&ace[i++], &domadmin_sid,
138 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
141 /* if we have a sid, give it some special access */
143 if ( sid ) {
144 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
147 /* create the security descriptor */
149 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
150 return NT_STATUS_NO_MEMORY;
152 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
153 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
154 psa, sd_size)) == NULL)
155 return NT_STATUS_NO_MEMORY;
157 return NT_STATUS_OK;
160 /*******************************************************************
161 Checks if access to an object should be granted, and returns that
162 level of access for further checks.
163 ********************************************************************/
165 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
166 SE_PRIV *rights, uint32 rights_mask,
167 uint32 des_access, uint32 *acc_granted,
168 const char *debug )
170 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
171 uint32 saved_mask = 0;
173 /* check privileges; certain SAM access bits should be overridden
174 by privileges (mostly having to do with creating/modifying/deleting
175 users and groups) */
177 if ( rights && user_has_any_privilege( token, rights ) ) {
179 saved_mask = (des_access & rights_mask);
180 des_access &= ~saved_mask;
182 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
183 rights_mask));
187 /* check the security descriptor first */
189 status = se_access_check(psd, token, des_access, acc_granted);
190 if (NT_STATUS_IS_OK(status)) {
191 goto done;
194 /* give root a free pass */
196 if ( geteuid() == sec_initial_uid() ) {
198 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
199 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
201 *acc_granted = des_access;
203 status = NT_STATUS_OK;
204 goto done;
208 done:
209 /* add in any bits saved during the privilege check (only
210 matters is status is ok) */
212 *acc_granted |= rights_mask;
214 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
215 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
216 des_access, *acc_granted));
218 return status;
221 /*******************************************************************
222 Checks if access to a function can be granted
223 ********************************************************************/
225 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
227 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
228 debug, acc_granted, acc_required));
230 /* check the security descriptor first */
232 if ( (acc_granted&acc_required) == acc_required )
233 return NT_STATUS_OK;
235 /* give root a free pass */
237 if (geteuid() == sec_initial_uid()) {
239 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
240 debug, acc_granted, acc_required));
241 DEBUGADD(4,("but overwritten by euid == 0\n"));
243 return NT_STATUS_OK;
246 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
247 debug, acc_granted, acc_required));
249 return NT_STATUS_ACCESS_DENIED;
252 /*******************************************************************
253 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
254 ********************************************************************/
256 static void map_max_allowed_access(const NT_USER_TOKEN *token,
257 uint32_t *pacc_requested)
259 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
260 return;
262 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
264 /* At least try for generic read. */
265 *pacc_requested = GENERIC_READ_ACCESS;
267 /* root gets anything. */
268 if (geteuid() == sec_initial_uid()) {
269 *pacc_requested |= GENERIC_ALL_ACCESS;
270 return;
273 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
275 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
276 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
277 *pacc_requested |= GENERIC_ALL_ACCESS;
278 return;
281 /* Full access for DOMAIN\Domain Admins. */
282 if ( IS_DC ) {
283 DOM_SID domadmin_sid;
284 sid_copy( &domadmin_sid, get_global_sam_sid() );
285 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
286 if (is_sid_in_token(token, &domadmin_sid)) {
287 *pacc_requested |= GENERIC_ALL_ACCESS;
288 return;
291 /* TODO ! Check privileges. */
294 /*******************************************************************
295 Fetch or create a dispinfo struct.
296 ********************************************************************/
298 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
301 * We do a static cache for DISP_INFO's here. Explanation can be found
302 * in Jeremy's checkin message to r11793:
304 * Fix the SAMR cache so it works across completely insane
305 * client behaviour (ie.:
306 * open pipe/open SAMR handle/enumerate 0 - 1024
307 * close SAMR handle, close pipe.
308 * open pipe/open SAMR handle/enumerate 1024 - 2048...
309 * close SAMR handle, close pipe.
310 * And on ad-nausium. Amazing.... probably object-oriented
311 * client side programming in action yet again.
312 * This change should *massively* improve performance when
313 * enumerating users from an LDAP database.
314 * Jeremy.
316 * "Our" and the builtin domain are the only ones where we ever
317 * enumerate stuff, so just cache 2 entries.
320 static struct disp_info builtin_dispinfo;
321 static struct disp_info domain_dispinfo;
323 /* There are two cases to consider here:
324 1) The SID is a domain SID and we look for an equality match, or
325 2) This is an account SID and so we return the DISP_INFO* for our
326 domain */
328 if (psid == NULL) {
329 return NULL;
332 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
334 * Necessary only once, but it does not really hurt.
336 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
338 return &builtin_dispinfo;
341 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
343 * Necessary only once, but it does not really hurt.
345 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
347 return &domain_dispinfo;
350 return NULL;
353 /*******************************************************************
354 Create a samr_info struct.
355 ********************************************************************/
357 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
359 struct samr_info *info;
360 fstring sid_str;
361 TALLOC_CTX *mem_ctx;
363 if (psid) {
364 sid_to_fstring(sid_str, psid);
365 } else {
366 fstrcpy(sid_str,"(NULL)");
369 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
371 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
372 return NULL;
374 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
375 if (psid) {
376 sid_copy( &info->sid, psid);
377 info->builtin_domain = sid_check_is_builtin(psid);
378 } else {
379 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
380 info->builtin_domain = False;
382 info->mem_ctx = mem_ctx;
384 info->disp_info = get_samr_dispinfo_by_sid(psid);
386 return info;
389 /*******************************************************************
390 Function to free the per SID data.
391 ********************************************************************/
393 static void free_samr_cache(DISP_INFO *disp_info)
395 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
396 sid_string_dbg(&disp_info->sid)));
398 /* We need to become root here because the paged search might have to
399 * tell the LDAP server we're not interested in the rest anymore. */
401 become_root();
403 if (disp_info->users) {
404 DEBUG(10,("free_samr_cache: deleting users cache\n"));
405 pdb_search_destroy(disp_info->users);
406 disp_info->users = NULL;
408 if (disp_info->machines) {
409 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
410 pdb_search_destroy(disp_info->machines);
411 disp_info->machines = NULL;
413 if (disp_info->groups) {
414 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
415 pdb_search_destroy(disp_info->groups);
416 disp_info->groups = NULL;
418 if (disp_info->aliases) {
419 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
420 pdb_search_destroy(disp_info->aliases);
421 disp_info->aliases = NULL;
423 if (disp_info->enum_users) {
424 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
425 pdb_search_destroy(disp_info->enum_users);
426 disp_info->enum_users = NULL;
428 disp_info->enum_acb_mask = 0;
430 unbecome_root();
433 /*******************************************************************
434 Function to free the per handle data.
435 ********************************************************************/
437 static void free_samr_info(void *ptr)
439 struct samr_info *info=(struct samr_info *) ptr;
441 /* Only free the dispinfo cache if no one bothered to set up
442 a timeout. */
444 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
445 free_samr_cache(info->disp_info);
448 talloc_destroy(info->mem_ctx);
451 /*******************************************************************
452 Idle event handler. Throw away the disp info cache.
453 ********************************************************************/
455 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
456 struct timed_event *te,
457 const struct timeval *now,
458 void *private_data)
460 DISP_INFO *disp_info = (DISP_INFO *)private_data;
462 TALLOC_FREE(disp_info->cache_timeout_event);
464 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
465 "out\n"));
466 free_samr_cache(disp_info);
469 /*******************************************************************
470 Setup cache removal idle event handler.
471 ********************************************************************/
473 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
475 /* Remove any pending timeout and update. */
477 TALLOC_FREE(disp_info->cache_timeout_event);
479 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
480 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
481 (unsigned int)secs_fromnow ));
483 disp_info->cache_timeout_event = event_add_timed(
484 smbd_event_context(), NULL,
485 timeval_current_ofs(secs_fromnow, 0),
486 "disp_info_cache_idle_timeout_handler",
487 disp_info_cache_idle_timeout_handler, (void *)disp_info);
490 /*******************************************************************
491 Force flush any cache. We do this on any samr_set_xxx call.
492 We must also remove the timeout handler.
493 ********************************************************************/
495 static void force_flush_samr_cache(DISP_INFO *disp_info)
497 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
498 return;
501 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
502 TALLOC_FREE(disp_info->cache_timeout_event);
503 free_samr_cache(disp_info);
506 /*******************************************************************
507 Ensure password info is never given out. Paranioa... JRA.
508 ********************************************************************/
510 static void samr_clear_sam_passwd(struct samu *sam_pass)
513 if (!sam_pass)
514 return;
516 /* These now zero out the old password */
518 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
519 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
522 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
524 struct samr_displayentry *entry;
526 if (info->builtin_domain) {
527 /* No users in builtin. */
528 return 0;
531 if (info->users == NULL) {
532 info->users = pdb_search_users(acct_flags);
533 if (info->users == NULL) {
534 return 0;
537 /* Fetch the last possible entry, thus trigger an enumeration */
538 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
540 /* Ensure we cache this enumeration. */
541 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
543 return info->users->num_entries;
546 static uint32 count_sam_groups(struct disp_info *info)
548 struct samr_displayentry *entry;
550 if (info->builtin_domain) {
551 /* No groups in builtin. */
552 return 0;
555 if (info->groups == NULL) {
556 info->groups = pdb_search_groups();
557 if (info->groups == NULL) {
558 return 0;
561 /* Fetch the last possible entry, thus trigger an enumeration */
562 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
564 /* Ensure we cache this enumeration. */
565 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
567 return info->groups->num_entries;
570 static uint32 count_sam_aliases(struct disp_info *info)
572 struct samr_displayentry *entry;
574 if (info->aliases == NULL) {
575 info->aliases = pdb_search_aliases(&info->sid);
576 if (info->aliases == NULL) {
577 return 0;
580 /* Fetch the last possible entry, thus trigger an enumeration */
581 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
583 /* Ensure we cache this enumeration. */
584 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
586 return info->aliases->num_entries;
589 /*******************************************************************
590 _samr_Close
591 ********************************************************************/
593 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
595 if (!close_policy_hnd(p, r->in.handle)) {
596 return NT_STATUS_INVALID_HANDLE;
599 ZERO_STRUCTP(r->out.handle);
601 return NT_STATUS_OK;
604 /*******************************************************************
605 _samr_OpenDomain
606 ********************************************************************/
608 NTSTATUS _samr_OpenDomain(pipes_struct *p,
609 struct samr_OpenDomain *r)
611 struct samr_info *info;
612 SEC_DESC *psd = NULL;
613 uint32 acc_granted;
614 uint32 des_access = r->in.access_mask;
615 NTSTATUS status;
616 size_t sd_size;
617 SE_PRIV se_rights;
619 /* find the connection policy handle. */
621 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
622 return NT_STATUS_INVALID_HANDLE;
624 status = access_check_samr_function(info->acc_granted,
625 SAMR_ACCESS_OPEN_DOMAIN,
626 "_samr_OpenDomain" );
628 if ( !NT_STATUS_IS_OK(status) )
629 return status;
631 /*check if access can be granted as requested by client. */
632 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
634 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
635 se_map_generic( &des_access, &dom_generic_mapping );
637 se_priv_copy( &se_rights, &se_machine_account );
638 se_priv_add( &se_rights, &se_add_users );
640 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
641 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
642 &acc_granted, "_samr_OpenDomain" );
644 if ( !NT_STATUS_IS_OK(status) )
645 return status;
647 if (!sid_check_is_domain(r->in.sid) &&
648 !sid_check_is_builtin(r->in.sid)) {
649 return NT_STATUS_NO_SUCH_DOMAIN;
652 /* associate the domain SID with the (unique) handle. */
653 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
654 return NT_STATUS_NO_MEMORY;
655 info->acc_granted = acc_granted;
657 /* get a (unique) handle. open a policy on it. */
658 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
659 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
661 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
663 return NT_STATUS_OK;
666 /*******************************************************************
667 _samr_GetUserPwInfo
668 ********************************************************************/
670 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
671 struct samr_GetUserPwInfo *r)
673 struct samr_info *info = NULL;
674 enum lsa_SidType sid_type;
675 uint32_t min_password_length = 0;
676 uint32_t password_properties = 0;
677 bool ret = false;
678 NTSTATUS status;
680 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
682 /* find the policy handle. open a policy on it. */
683 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
684 return NT_STATUS_INVALID_HANDLE;
687 status = access_check_samr_function(info->acc_granted,
688 SAMR_USER_ACCESS_GET_ATTRIBUTES,
689 "_samr_GetUserPwInfo" );
690 if (!NT_STATUS_IS_OK(status)) {
691 return status;
694 if (!sid_check_is_in_our_domain(&info->sid)) {
695 return NT_STATUS_OBJECT_TYPE_MISMATCH;
698 become_root();
699 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
700 unbecome_root();
701 if (ret == false) {
702 return NT_STATUS_NO_SUCH_USER;
705 switch (sid_type) {
706 case SID_NAME_USER:
707 become_root();
708 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
709 &min_password_length);
710 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
711 &password_properties);
712 unbecome_root();
714 if (lp_check_password_script() && *lp_check_password_script()) {
715 password_properties |= DOMAIN_PASSWORD_COMPLEX;
718 break;
719 default:
720 break;
723 r->out.info->min_password_length = min_password_length;
724 r->out.info->password_properties = password_properties;
726 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
728 return NT_STATUS_OK;
731 /*******************************************************************
732 ********************************************************************/
734 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
735 DOM_SID *sid, uint32 *acc_granted,
736 DISP_INFO **ppdisp_info)
738 struct samr_info *info = NULL;
740 /* find the policy handle. open a policy on it. */
741 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
742 return False;
744 if (!info)
745 return False;
747 *sid = info->sid;
748 *acc_granted = info->acc_granted;
749 if (ppdisp_info) {
750 *ppdisp_info = info->disp_info;
753 return True;
756 /*******************************************************************
757 _samr_SetSecurity
758 ********************************************************************/
760 NTSTATUS _samr_SetSecurity(pipes_struct *p,
761 struct samr_SetSecurity *r)
763 DOM_SID pol_sid;
764 uint32 acc_granted, i;
765 SEC_ACL *dacl;
766 bool ret;
767 struct samu *sampass=NULL;
768 NTSTATUS status;
770 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
771 return NT_STATUS_INVALID_HANDLE;
773 if (!(sampass = samu_new( p->mem_ctx))) {
774 DEBUG(0,("No memory!\n"));
775 return NT_STATUS_NO_MEMORY;
778 /* get the user record */
779 become_root();
780 ret = pdb_getsampwsid(sampass, &pol_sid);
781 unbecome_root();
783 if (!ret) {
784 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
785 TALLOC_FREE(sampass);
786 return NT_STATUS_INVALID_HANDLE;
789 dacl = r->in.sdbuf->sd->dacl;
790 for (i=0; i < dacl->num_aces; i++) {
791 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
792 ret = pdb_set_pass_can_change(sampass,
793 (dacl->aces[i].access_mask &
794 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
795 True: False);
796 break;
800 if (!ret) {
801 TALLOC_FREE(sampass);
802 return NT_STATUS_ACCESS_DENIED;
805 status = access_check_samr_function(acc_granted,
806 SAMR_USER_ACCESS_SET_ATTRIBUTES,
807 "_samr_SetSecurity");
808 if (NT_STATUS_IS_OK(status)) {
809 become_root();
810 status = pdb_update_sam_account(sampass);
811 unbecome_root();
814 TALLOC_FREE(sampass);
816 return status;
819 /*******************************************************************
820 build correct perms based on policies and password times for _samr_query_sec_obj
821 *******************************************************************/
822 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
824 struct samu *sampass=NULL;
825 bool ret;
827 if ( !(sampass = samu_new( mem_ctx )) ) {
828 DEBUG(0,("No memory!\n"));
829 return False;
832 become_root();
833 ret = pdb_getsampwsid(sampass, user_sid);
834 unbecome_root();
836 if (ret == False) {
837 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
838 TALLOC_FREE(sampass);
839 return False;
842 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
844 if (pdb_get_pass_can_change(sampass)) {
845 TALLOC_FREE(sampass);
846 return True;
848 TALLOC_FREE(sampass);
849 return False;
853 /*******************************************************************
854 _samr_QuerySecurity
855 ********************************************************************/
857 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
858 struct samr_QuerySecurity *r)
860 NTSTATUS status;
861 DOM_SID pol_sid;
862 SEC_DESC * psd = NULL;
863 uint32 acc_granted;
864 size_t sd_size;
866 /* Get the SID. */
867 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
868 return NT_STATUS_INVALID_HANDLE;
870 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
871 sid_string_dbg(&pol_sid)));
873 status = access_check_samr_function(acc_granted,
874 STD_RIGHT_READ_CONTROL_ACCESS,
875 "_samr_QuerySecurity");
876 if (!NT_STATUS_IS_OK(status)) {
877 return status;
880 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
882 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
883 if (pol_sid.sid_rev_num == 0) {
884 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
885 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
886 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
887 /* check if it is our domain SID */
888 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
889 "with SID: %s\n", sid_string_dbg(&pol_sid)));
890 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
891 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
892 /* check if it is the Builtin Domain */
893 /* TODO: Builtin probably needs a different SD with restricted write access*/
894 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
895 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
896 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
897 } else if (sid_check_is_in_our_domain(&pol_sid) ||
898 sid_check_is_in_builtin(&pol_sid)) {
899 /* TODO: different SDs have to be generated for aliases groups and users.
900 Currently all three get a default user SD */
901 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
902 "with SID: %s\n", sid_string_dbg(&pol_sid)));
903 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
904 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
905 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
906 } else {
907 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
908 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
910 } else {
911 return NT_STATUS_OBJECT_TYPE_MISMATCH;
914 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
915 return NT_STATUS_NO_MEMORY;
917 return status;
920 /*******************************************************************
921 makes a SAM_ENTRY / UNISTR2* structure from a user list.
922 ********************************************************************/
924 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
925 struct samr_SamEntry **sam_pp,
926 uint32_t num_entries,
927 uint32_t start_idx,
928 struct samr_displayentry *entries)
930 uint32_t i;
931 struct samr_SamEntry *sam;
933 *sam_pp = NULL;
935 if (num_entries == 0) {
936 return NT_STATUS_OK;
939 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
940 if (sam == NULL) {
941 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
942 return NT_STATUS_NO_MEMORY;
945 for (i = 0; i < num_entries; i++) {
946 #if 0
948 * usrmgr expects a non-NULL terminated string with
949 * trust relationships
951 if (entries[i].acct_flags & ACB_DOMTRUST) {
952 init_unistr2(&uni_temp_name, entries[i].account_name,
953 UNI_FLAGS_NONE);
954 } else {
955 init_unistr2(&uni_temp_name, entries[i].account_name,
956 UNI_STR_TERMINATE);
958 #endif
959 init_lsa_String(&sam[i].name, entries[i].account_name);
960 sam[i].idx = entries[i].rid;
963 *sam_pp = sam;
965 return NT_STATUS_OK;
968 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
970 /*******************************************************************
971 _samr_EnumDomainUsers
972 ********************************************************************/
974 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
975 struct samr_EnumDomainUsers *r)
977 NTSTATUS status;
978 struct samr_info *info = NULL;
979 int num_account;
980 uint32 enum_context = *r->in.resume_handle;
981 enum remote_arch_types ra_type = get_remote_arch();
982 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
983 uint32 max_entries = max_sam_entries;
984 struct samr_displayentry *entries = NULL;
985 struct samr_SamArray *samr_array = NULL;
986 struct samr_SamEntry *samr_entries = NULL;
988 /* find the policy handle. open a policy on it. */
989 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
990 return NT_STATUS_INVALID_HANDLE;
992 status = access_check_samr_function(info->acc_granted,
993 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
994 "_samr_EnumDomainUsers");
995 if (!NT_STATUS_IS_OK(status)) {
996 return status;
999 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1001 if (info->builtin_domain) {
1002 /* No users in builtin. */
1003 *r->out.resume_handle = *r->in.resume_handle;
1004 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
1005 return status;
1008 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1009 if (!samr_array) {
1010 return NT_STATUS_NO_MEMORY;
1012 *r->out.sam = samr_array;
1014 become_root();
1016 /* AS ROOT !!!! */
1018 if ((info->disp_info->enum_users != NULL) &&
1019 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1020 pdb_search_destroy(info->disp_info->enum_users);
1021 info->disp_info->enum_users = NULL;
1024 if (info->disp_info->enum_users == NULL) {
1025 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
1026 info->disp_info->enum_acb_mask = r->in.acct_flags;
1029 if (info->disp_info->enum_users == NULL) {
1030 /* END AS ROOT !!!! */
1031 unbecome_root();
1032 return NT_STATUS_ACCESS_DENIED;
1035 num_account = pdb_search_entries(info->disp_info->enum_users,
1036 enum_context, max_entries,
1037 &entries);
1039 /* END AS ROOT !!!! */
1041 unbecome_root();
1043 if (num_account == 0) {
1044 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1045 "total entries\n"));
1046 *r->out.resume_handle = *r->in.resume_handle;
1047 return NT_STATUS_OK;
1050 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1051 num_account, enum_context,
1052 entries);
1053 if (!NT_STATUS_IS_OK(status)) {
1054 return status;
1057 if (max_entries <= num_account) {
1058 status = STATUS_MORE_ENTRIES;
1059 } else {
1060 status = NT_STATUS_OK;
1063 /* Ensure we cache this enumeration. */
1064 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1066 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1068 samr_array->count = num_account;
1069 samr_array->entries = samr_entries;
1071 *r->out.resume_handle = *r->in.resume_handle + num_account;
1072 *r->out.num_entries = num_account;
1074 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1076 return status;
1079 /*******************************************************************
1080 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1081 ********************************************************************/
1083 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1084 struct samr_SamEntry **sam_pp,
1085 uint32_t num_sam_entries,
1086 struct samr_displayentry *entries)
1088 struct samr_SamEntry *sam;
1089 uint32_t i;
1091 *sam_pp = NULL;
1093 if (num_sam_entries == 0) {
1094 return;
1097 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1098 if (sam == NULL) {
1099 return;
1102 for (i = 0; i < num_sam_entries; i++) {
1104 * JRA. I think this should include the null. TNG does not.
1106 init_lsa_String(&sam[i].name, entries[i].account_name);
1107 sam[i].idx = entries[i].rid;
1110 *sam_pp = sam;
1113 /*******************************************************************
1114 _samr_EnumDomainGroups
1115 ********************************************************************/
1117 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1118 struct samr_EnumDomainGroups *r)
1120 NTSTATUS status;
1121 struct samr_info *info = NULL;
1122 struct samr_displayentry *groups;
1123 uint32 num_groups;
1124 struct samr_SamArray *samr_array = NULL;
1125 struct samr_SamEntry *samr_entries = NULL;
1127 /* find the policy handle. open a policy on it. */
1128 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1129 return NT_STATUS_INVALID_HANDLE;
1131 status = access_check_samr_function(info->acc_granted,
1132 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1133 "_samr_EnumDomainGroups");
1134 if (!NT_STATUS_IS_OK(status)) {
1135 return status;
1138 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1140 if (info->builtin_domain) {
1141 /* No groups in builtin. */
1142 *r->out.resume_handle = *r->in.resume_handle;
1143 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1144 return status;
1147 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1148 if (!samr_array) {
1149 return NT_STATUS_NO_MEMORY;
1152 /* the domain group array is being allocated in the function below */
1154 become_root();
1156 if (info->disp_info->groups == NULL) {
1157 info->disp_info->groups = pdb_search_groups();
1159 if (info->disp_info->groups == NULL) {
1160 unbecome_root();
1161 return NT_STATUS_ACCESS_DENIED;
1165 num_groups = pdb_search_entries(info->disp_info->groups,
1166 *r->in.resume_handle,
1167 MAX_SAM_ENTRIES, &groups);
1168 unbecome_root();
1170 /* Ensure we cache this enumeration. */
1171 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1173 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1174 num_groups, groups);
1176 samr_array->count = num_groups;
1177 samr_array->entries = samr_entries;
1179 *r->out.sam = samr_array;
1180 *r->out.num_entries = num_groups;
1181 /* this was missing, IMHO:
1182 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1185 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1187 return status;
1190 /*******************************************************************
1191 _samr_EnumDomainAliases
1192 ********************************************************************/
1194 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1195 struct samr_EnumDomainAliases *r)
1197 NTSTATUS status;
1198 struct samr_info *info;
1199 struct samr_displayentry *aliases;
1200 uint32 num_aliases = 0;
1201 struct samr_SamArray *samr_array = NULL;
1202 struct samr_SamEntry *samr_entries = NULL;
1204 /* find the policy handle. open a policy on it. */
1205 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1206 return NT_STATUS_INVALID_HANDLE;
1208 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1209 sid_string_dbg(&info->sid)));
1211 status = access_check_samr_function(info->acc_granted,
1212 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1213 "_samr_EnumDomainAliases");
1214 if (!NT_STATUS_IS_OK(status)) {
1215 return status;
1218 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1219 if (!samr_array) {
1220 return NT_STATUS_NO_MEMORY;
1223 become_root();
1225 if (info->disp_info->aliases == NULL) {
1226 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1227 if (info->disp_info->aliases == NULL) {
1228 unbecome_root();
1229 return NT_STATUS_ACCESS_DENIED;
1233 num_aliases = pdb_search_entries(info->disp_info->aliases,
1234 *r->in.resume_handle,
1235 MAX_SAM_ENTRIES, &aliases);
1236 unbecome_root();
1238 /* Ensure we cache this enumeration. */
1239 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1241 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1242 num_aliases, aliases);
1244 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1246 samr_array->count = num_aliases;
1247 samr_array->entries = samr_entries;
1249 *r->out.sam = samr_array;
1250 *r->out.num_entries = num_aliases;
1251 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1253 return status;
1256 /*******************************************************************
1257 inits a samr_DispInfoGeneral structure.
1258 ********************************************************************/
1260 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1261 struct samr_DispInfoGeneral *r,
1262 uint32_t num_entries,
1263 uint32_t start_idx,
1264 struct samr_displayentry *entries)
1266 uint32 i;
1268 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1270 if (num_entries == 0) {
1271 return NT_STATUS_OK;
1274 r->count = num_entries;
1276 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1277 if (!r->entries) {
1278 return NT_STATUS_NO_MEMORY;
1281 for (i = 0; i < num_entries ; i++) {
1283 init_lsa_String(&r->entries[i].account_name,
1284 entries[i].account_name);
1286 init_lsa_String(&r->entries[i].description,
1287 entries[i].description);
1289 init_lsa_String(&r->entries[i].full_name,
1290 entries[i].fullname);
1292 r->entries[i].rid = entries[i].rid;
1293 r->entries[i].acct_flags = entries[i].acct_flags;
1294 r->entries[i].idx = start_idx+i+1;
1297 return NT_STATUS_OK;
1300 /*******************************************************************
1301 inits a samr_DispInfoFull structure.
1302 ********************************************************************/
1304 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1305 struct samr_DispInfoFull *r,
1306 uint32_t num_entries,
1307 uint32_t start_idx,
1308 struct samr_displayentry *entries)
1310 uint32_t i;
1312 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1314 if (num_entries == 0) {
1315 return NT_STATUS_OK;
1318 r->count = num_entries;
1320 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1321 if (!r->entries) {
1322 return NT_STATUS_NO_MEMORY;
1325 for (i = 0; i < num_entries ; i++) {
1327 init_lsa_String(&r->entries[i].account_name,
1328 entries[i].account_name);
1330 init_lsa_String(&r->entries[i].description,
1331 entries[i].description);
1333 r->entries[i].rid = entries[i].rid;
1334 r->entries[i].acct_flags = entries[i].acct_flags;
1335 r->entries[i].idx = start_idx+i+1;
1338 return NT_STATUS_OK;
1341 /*******************************************************************
1342 inits a samr_DispInfoFullGroups structure.
1343 ********************************************************************/
1345 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1346 struct samr_DispInfoFullGroups *r,
1347 uint32_t num_entries,
1348 uint32_t start_idx,
1349 struct samr_displayentry *entries)
1351 uint32_t i;
1353 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1355 if (num_entries == 0) {
1356 return NT_STATUS_OK;
1359 r->count = num_entries;
1361 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1362 if (!r->entries) {
1363 return NT_STATUS_NO_MEMORY;
1366 for (i = 0; i < num_entries ; i++) {
1368 init_lsa_String(&r->entries[i].account_name,
1369 entries[i].account_name);
1371 init_lsa_String(&r->entries[i].description,
1372 entries[i].description);
1374 r->entries[i].rid = entries[i].rid;
1375 r->entries[i].acct_flags = entries[i].acct_flags;
1376 r->entries[i].idx = start_idx+i+1;
1379 return NT_STATUS_OK;
1382 /*******************************************************************
1383 inits a samr_DispInfoAscii structure.
1384 ********************************************************************/
1386 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1387 struct samr_DispInfoAscii *r,
1388 uint32_t num_entries,
1389 uint32_t start_idx,
1390 struct samr_displayentry *entries)
1392 uint32_t i;
1394 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1396 if (num_entries == 0) {
1397 return NT_STATUS_OK;
1400 r->count = num_entries;
1402 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1403 if (!r->entries) {
1404 return NT_STATUS_NO_MEMORY;
1407 for (i = 0; i < num_entries ; i++) {
1409 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1410 entries[i].account_name);
1412 r->entries[i].idx = start_idx+i+1;
1415 return NT_STATUS_OK;
1418 /*******************************************************************
1419 inits a samr_DispInfoAscii structure.
1420 ********************************************************************/
1422 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1423 struct samr_DispInfoAscii *r,
1424 uint32_t num_entries,
1425 uint32_t start_idx,
1426 struct samr_displayentry *entries)
1428 uint32_t i;
1430 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1432 if (num_entries == 0) {
1433 return NT_STATUS_OK;
1436 r->count = num_entries;
1438 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1439 if (!r->entries) {
1440 return NT_STATUS_NO_MEMORY;
1443 for (i = 0; i < num_entries ; i++) {
1445 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1446 entries[i].account_name);
1448 r->entries[i].idx = start_idx+i+1;
1451 return NT_STATUS_OK;
1454 /*******************************************************************
1455 _samr_QueryDisplayInfo
1456 ********************************************************************/
1458 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1459 struct samr_QueryDisplayInfo *r)
1461 NTSTATUS status;
1462 struct samr_info *info = NULL;
1463 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1465 uint32 max_entries = r->in.max_entries;
1466 uint32 enum_context = r->in.start_idx;
1467 uint32 max_size = r->in.buf_size;
1469 union samr_DispInfo *disp_info = r->out.info;
1471 uint32 temp_size=0, total_data_size=0;
1472 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1473 uint32 num_account = 0;
1474 enum remote_arch_types ra_type = get_remote_arch();
1475 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1476 struct samr_displayentry *entries = NULL;
1478 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1480 /* find the policy handle. open a policy on it. */
1481 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1482 return NT_STATUS_INVALID_HANDLE;
1484 if (info->builtin_domain) {
1485 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1486 return NT_STATUS_OK;
1489 status = access_check_samr_function(info->acc_granted,
1490 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1491 "_samr_QueryDisplayInfo");
1492 if (!NT_STATUS_IS_OK(status)) {
1493 return status;
1497 * calculate how many entries we will return.
1498 * based on
1499 * - the number of entries the client asked
1500 * - our limit on that
1501 * - the starting point (enumeration context)
1502 * - the buffer size the client will accept
1506 * We are a lot more like W2K. Instead of reading the SAM
1507 * each time to find the records we need to send back,
1508 * we read it once and link that copy to the sam handle.
1509 * For large user list (over the MAX_SAM_ENTRIES)
1510 * it's a definitive win.
1511 * second point to notice: between enumerations
1512 * our sam is now the same as it's a snapshoot.
1513 * third point: got rid of the static SAM_USER_21 struct
1514 * no more intermediate.
1515 * con: it uses much more memory, as a full copy is stored
1516 * in memory.
1518 * If you want to change it, think twice and think
1519 * of the second point , that's really important.
1521 * JFM, 12/20/2001
1524 if ((r->in.level < 1) || (r->in.level > 5)) {
1525 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1526 (unsigned int)r->in.level ));
1527 return NT_STATUS_INVALID_INFO_CLASS;
1530 /* first limit the number of entries we will return */
1531 if(max_entries > max_sam_entries) {
1532 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1533 "entries, limiting to %d\n", max_entries,
1534 max_sam_entries));
1535 max_entries = max_sam_entries;
1538 /* calculate the size and limit on the number of entries we will
1539 * return */
1541 temp_size=max_entries*struct_size;
1543 if (temp_size>max_size) {
1544 max_entries=MIN((max_size/struct_size),max_entries);;
1545 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1546 "only %d entries\n", max_entries));
1549 become_root();
1551 /* THe following done as ROOT. Don't return without unbecome_root(). */
1553 switch (r->in.level) {
1554 case 0x1:
1555 case 0x4:
1556 if (info->disp_info->users == NULL) {
1557 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1558 if (info->disp_info->users == NULL) {
1559 unbecome_root();
1560 return NT_STATUS_ACCESS_DENIED;
1562 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1563 (unsigned int)enum_context ));
1564 } else {
1565 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1566 (unsigned int)enum_context ));
1569 num_account = pdb_search_entries(info->disp_info->users,
1570 enum_context, max_entries,
1571 &entries);
1572 break;
1573 case 0x2:
1574 if (info->disp_info->machines == NULL) {
1575 info->disp_info->machines =
1576 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1577 if (info->disp_info->machines == NULL) {
1578 unbecome_root();
1579 return NT_STATUS_ACCESS_DENIED;
1581 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1582 (unsigned int)enum_context ));
1583 } else {
1584 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1585 (unsigned int)enum_context ));
1588 num_account = pdb_search_entries(info->disp_info->machines,
1589 enum_context, max_entries,
1590 &entries);
1591 break;
1592 case 0x3:
1593 case 0x5:
1594 if (info->disp_info->groups == NULL) {
1595 info->disp_info->groups = pdb_search_groups();
1596 if (info->disp_info->groups == NULL) {
1597 unbecome_root();
1598 return NT_STATUS_ACCESS_DENIED;
1600 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1601 (unsigned int)enum_context ));
1602 } else {
1603 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1604 (unsigned int)enum_context ));
1607 num_account = pdb_search_entries(info->disp_info->groups,
1608 enum_context, max_entries,
1609 &entries);
1610 break;
1611 default:
1612 unbecome_root();
1613 smb_panic("info class changed");
1614 break;
1616 unbecome_root();
1619 /* Now create reply structure */
1620 switch (r->in.level) {
1621 case 0x1:
1622 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1623 num_account, enum_context,
1624 entries);
1625 break;
1626 case 0x2:
1627 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1628 num_account, enum_context,
1629 entries);
1630 break;
1631 case 0x3:
1632 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1633 num_account, enum_context,
1634 entries);
1635 break;
1636 case 0x4:
1637 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1638 num_account, enum_context,
1639 entries);
1640 break;
1641 case 0x5:
1642 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1643 num_account, enum_context,
1644 entries);
1645 break;
1646 default:
1647 smb_panic("info class changed");
1648 break;
1651 if (!NT_STATUS_IS_OK(disp_ret))
1652 return disp_ret;
1654 /* calculate the total size */
1655 total_data_size=num_account*struct_size;
1657 if (max_entries <= num_account) {
1658 status = STATUS_MORE_ENTRIES;
1659 } else {
1660 status = NT_STATUS_OK;
1663 /* Ensure we cache this enumeration. */
1664 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1666 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1668 *r->out.total_size = total_data_size;
1669 *r->out.returned_size = temp_size;
1671 return status;
1674 /****************************************************************
1675 _samr_QueryDisplayInfo2
1676 ****************************************************************/
1678 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1679 struct samr_QueryDisplayInfo2 *r)
1681 struct samr_QueryDisplayInfo q;
1683 q.in.domain_handle = r->in.domain_handle;
1684 q.in.level = r->in.level;
1685 q.in.start_idx = r->in.start_idx;
1686 q.in.max_entries = r->in.max_entries;
1687 q.in.buf_size = r->in.buf_size;
1689 q.out.total_size = r->out.total_size;
1690 q.out.returned_size = r->out.returned_size;
1691 q.out.info = r->out.info;
1693 return _samr_QueryDisplayInfo(p, &q);
1696 /****************************************************************
1697 _samr_QueryDisplayInfo3
1698 ****************************************************************/
1700 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1701 struct samr_QueryDisplayInfo3 *r)
1703 struct samr_QueryDisplayInfo q;
1705 q.in.domain_handle = r->in.domain_handle;
1706 q.in.level = r->in.level;
1707 q.in.start_idx = r->in.start_idx;
1708 q.in.max_entries = r->in.max_entries;
1709 q.in.buf_size = r->in.buf_size;
1711 q.out.total_size = r->out.total_size;
1712 q.out.returned_size = r->out.returned_size;
1713 q.out.info = r->out.info;
1715 return _samr_QueryDisplayInfo(p, &q);
1718 /*******************************************************************
1719 _samr_QueryAliasInfo
1720 ********************************************************************/
1722 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1723 struct samr_QueryAliasInfo *r)
1725 DOM_SID sid;
1726 struct acct_info info;
1727 uint32 acc_granted;
1728 NTSTATUS status;
1729 union samr_AliasInfo *alias_info = NULL;
1730 const char *alias_name = NULL;
1731 const char *alias_description = NULL;
1733 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1735 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1736 if (!alias_info) {
1737 return NT_STATUS_NO_MEMORY;
1740 /* find the policy handle. open a policy on it. */
1741 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1742 return NT_STATUS_INVALID_HANDLE;
1744 status = access_check_samr_function(acc_granted,
1745 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1746 "_samr_QueryAliasInfo");
1747 if (!NT_STATUS_IS_OK(status)) {
1748 return status;
1751 become_root();
1752 status = pdb_get_aliasinfo(&sid, &info);
1753 unbecome_root();
1755 if ( !NT_STATUS_IS_OK(status))
1756 return status;
1758 /* FIXME: info contains fstrings */
1759 alias_name = talloc_strdup(r, info.acct_name);
1760 alias_description = talloc_strdup(r, info.acct_desc);
1762 switch (r->in.level) {
1763 case ALIASINFOALL:
1764 init_samr_alias_info1(&alias_info->all,
1765 alias_name,
1767 alias_description);
1768 break;
1769 case ALIASINFODESCRIPTION:
1770 init_samr_alias_info3(&alias_info->description,
1771 alias_description);
1772 break;
1773 default:
1774 return NT_STATUS_INVALID_INFO_CLASS;
1777 *r->out.info = alias_info;
1779 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1781 return NT_STATUS_OK;
1784 /*******************************************************************
1785 _samr_LookupNames
1786 ********************************************************************/
1788 NTSTATUS _samr_LookupNames(pipes_struct *p,
1789 struct samr_LookupNames *r)
1791 NTSTATUS status;
1792 uint32 *rid;
1793 enum lsa_SidType *type;
1794 int i;
1795 int num_rids = r->in.num_names;
1796 DOM_SID pol_sid;
1797 uint32 acc_granted;
1798 struct samr_Ids rids, types;
1799 uint32_t num_mapped = 0;
1801 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1803 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1804 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1807 status = access_check_samr_function(acc_granted,
1808 0, /* Don't know the acc_bits yet */
1809 "_samr_LookupNames");
1810 if (!NT_STATUS_IS_OK(status)) {
1811 return status;
1814 if (num_rids > MAX_SAM_ENTRIES) {
1815 num_rids = MAX_SAM_ENTRIES;
1816 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1819 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1820 NT_STATUS_HAVE_NO_MEMORY(rid);
1822 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1823 NT_STATUS_HAVE_NO_MEMORY(type);
1825 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1826 sid_string_dbg(&pol_sid)));
1828 for (i = 0; i < num_rids; i++) {
1830 status = NT_STATUS_NONE_MAPPED;
1831 type[i] = SID_NAME_UNKNOWN;
1833 rid[i] = 0xffffffff;
1835 if (sid_check_is_builtin(&pol_sid)) {
1836 if (lookup_builtin_name(r->in.names[i].string,
1837 &rid[i]))
1839 type[i] = SID_NAME_ALIAS;
1841 } else {
1842 lookup_global_sam_name(r->in.names[i].string, 0,
1843 &rid[i], &type[i]);
1846 if (type[i] != SID_NAME_UNKNOWN) {
1847 num_mapped++;
1851 if (num_mapped == num_rids) {
1852 status = NT_STATUS_OK;
1853 } else if (num_mapped == 0) {
1854 status = NT_STATUS_NONE_MAPPED;
1855 } else {
1856 status = STATUS_SOME_UNMAPPED;
1859 rids.count = num_rids;
1860 rids.ids = rid;
1862 types.count = num_rids;
1863 types.ids = type;
1865 *r->out.rids = rids;
1866 *r->out.types = types;
1868 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1870 return status;
1873 /*******************************************************************
1874 _samr_ChangePasswordUser2
1875 ********************************************************************/
1877 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1878 struct samr_ChangePasswordUser2 *r)
1880 NTSTATUS status;
1881 fstring user_name;
1882 fstring wks;
1884 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1886 fstrcpy(user_name, r->in.account->string);
1887 fstrcpy(wks, r->in.server->string);
1889 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1892 * Pass the user through the NT -> unix user mapping
1893 * function.
1896 (void)map_username(user_name);
1899 * UNIX username case mangling not required, pass_oem_change
1900 * is case insensitive.
1903 status = pass_oem_change(user_name,
1904 r->in.lm_password->data,
1905 r->in.lm_verifier->hash,
1906 r->in.nt_password->data,
1907 r->in.nt_verifier->hash,
1908 NULL);
1910 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1912 return status;
1915 /*******************************************************************
1916 _samr_ChangePasswordUser3
1917 ********************************************************************/
1919 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1920 struct samr_ChangePasswordUser3 *r)
1922 NTSTATUS status;
1923 fstring user_name;
1924 const char *wks = NULL;
1925 uint32 reject_reason;
1926 struct samr_DomInfo1 *dominfo = NULL;
1927 struct samr_ChangeReject *reject = NULL;
1929 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1931 fstrcpy(user_name, r->in.account->string);
1932 if (r->in.server && r->in.server->string) {
1933 wks = r->in.server->string;
1936 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1939 * Pass the user through the NT -> unix user mapping
1940 * function.
1943 (void)map_username(user_name);
1946 * UNIX username case mangling not required, pass_oem_change
1947 * is case insensitive.
1950 status = pass_oem_change(user_name,
1951 r->in.lm_password->data,
1952 r->in.lm_verifier->hash,
1953 r->in.nt_password->data,
1954 r->in.nt_verifier->hash,
1955 &reject_reason);
1957 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1958 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1960 uint32 min_pass_len,pass_hist,password_properties;
1961 time_t u_expire, u_min_age;
1962 NTTIME nt_expire, nt_min_age;
1963 uint32 account_policy_temp;
1965 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1966 if (!dominfo) {
1967 return NT_STATUS_NO_MEMORY;
1970 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1971 if (!reject) {
1972 return NT_STATUS_NO_MEMORY;
1975 become_root();
1977 /* AS ROOT !!! */
1979 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1980 min_pass_len = account_policy_temp;
1982 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1983 pass_hist = account_policy_temp;
1985 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1986 password_properties = account_policy_temp;
1988 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1989 u_expire = account_policy_temp;
1991 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1992 u_min_age = account_policy_temp;
1994 /* !AS ROOT */
1996 unbecome_root();
1998 unix_to_nt_time_abs(&nt_expire, u_expire);
1999 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2001 if (lp_check_password_script() && *lp_check_password_script()) {
2002 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2005 init_samr_DomInfo1(dominfo,
2006 min_pass_len,
2007 pass_hist,
2008 password_properties,
2009 u_expire,
2010 u_min_age);
2012 reject->reason = reject_reason;
2014 *r->out.dominfo = dominfo;
2015 *r->out.reject = reject;
2018 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2020 return status;
2023 /*******************************************************************
2024 makes a SAMR_R_LOOKUP_RIDS structure.
2025 ********************************************************************/
2027 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2028 const char **names,
2029 struct lsa_String **lsa_name_array_p)
2031 struct lsa_String *lsa_name_array = NULL;
2032 uint32_t i;
2034 *lsa_name_array_p = NULL;
2036 if (num_names != 0) {
2037 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2038 if (!lsa_name_array) {
2039 return false;
2043 for (i = 0; i < num_names; i++) {
2044 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2045 init_lsa_String(&lsa_name_array[i], names[i]);
2048 *lsa_name_array_p = lsa_name_array;
2050 return true;
2053 /*******************************************************************
2054 _samr_LookupRids
2055 ********************************************************************/
2057 NTSTATUS _samr_LookupRids(pipes_struct *p,
2058 struct samr_LookupRids *r)
2060 NTSTATUS status;
2061 const char **names;
2062 enum lsa_SidType *attrs = NULL;
2063 uint32 *wire_attrs = NULL;
2064 DOM_SID pol_sid;
2065 int num_rids = (int)r->in.num_rids;
2066 uint32 acc_granted;
2067 int i;
2068 struct lsa_Strings names_array;
2069 struct samr_Ids types_array;
2070 struct lsa_String *lsa_names = NULL;
2072 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2074 /* find the policy handle. open a policy on it. */
2075 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2076 return NT_STATUS_INVALID_HANDLE;
2078 status = access_check_samr_function(acc_granted,
2079 0, /* Don't know the acc_bits yet */
2080 "_samr_LookupRids");
2081 if (!NT_STATUS_IS_OK(status)) {
2082 return status;
2085 if (num_rids > 1000) {
2086 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2087 "to samba4 idl this is not possible\n", num_rids));
2088 return NT_STATUS_UNSUCCESSFUL;
2091 if (num_rids) {
2092 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2093 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2094 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2096 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2097 return NT_STATUS_NO_MEMORY;
2098 } else {
2099 names = NULL;
2100 attrs = NULL;
2101 wire_attrs = NULL;
2104 become_root(); /* lookup_sid can require root privs */
2105 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2106 names, attrs);
2107 unbecome_root();
2109 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2110 status = NT_STATUS_OK;
2113 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2114 &lsa_names)) {
2115 return NT_STATUS_NO_MEMORY;
2118 /* Convert from enum lsa_SidType to uint32 for wire format. */
2119 for (i = 0; i < num_rids; i++) {
2120 wire_attrs[i] = (uint32)attrs[i];
2123 names_array.count = num_rids;
2124 names_array.names = lsa_names;
2126 types_array.count = num_rids;
2127 types_array.ids = wire_attrs;
2129 *r->out.names = names_array;
2130 *r->out.types = types_array;
2132 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2134 return status;
2137 /*******************************************************************
2138 _samr_OpenUser
2139 ********************************************************************/
2141 NTSTATUS _samr_OpenUser(pipes_struct *p,
2142 struct samr_OpenUser *r)
2144 struct samu *sampass=NULL;
2145 DOM_SID sid;
2146 POLICY_HND domain_pol = *r->in.domain_handle;
2147 POLICY_HND *user_pol = r->out.user_handle;
2148 struct samr_info *info = NULL;
2149 SEC_DESC *psd = NULL;
2150 uint32 acc_granted;
2151 uint32 des_access = r->in.access_mask;
2152 size_t sd_size;
2153 bool ret;
2154 NTSTATUS nt_status;
2155 SE_PRIV se_rights;
2157 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2159 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2160 return NT_STATUS_INVALID_HANDLE;
2162 nt_status = access_check_samr_function(acc_granted,
2163 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2164 "_samr_OpenUser" );
2166 if ( !NT_STATUS_IS_OK(nt_status) )
2167 return nt_status;
2169 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2170 return NT_STATUS_NO_MEMORY;
2173 /* append the user's RID to it */
2175 if (!sid_append_rid(&sid, r->in.rid))
2176 return NT_STATUS_NO_SUCH_USER;
2178 /* check if access can be granted as requested by client. */
2180 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
2182 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2183 se_map_generic(&des_access, &usr_generic_mapping);
2185 se_priv_copy( &se_rights, &se_machine_account );
2186 se_priv_add( &se_rights, &se_add_users );
2188 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2189 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2190 &acc_granted, "_samr_OpenUser");
2192 if ( !NT_STATUS_IS_OK(nt_status) )
2193 return nt_status;
2195 become_root();
2196 ret=pdb_getsampwsid(sampass, &sid);
2197 unbecome_root();
2199 /* check that the SID exists in our domain. */
2200 if (ret == False) {
2201 return NT_STATUS_NO_SUCH_USER;
2204 TALLOC_FREE(sampass);
2206 /* associate the user's SID and access bits with the new handle. */
2207 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2208 return NT_STATUS_NO_MEMORY;
2209 info->acc_granted = acc_granted;
2211 /* get a (unique) handle. open a policy on it. */
2212 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2213 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2215 return NT_STATUS_OK;
2218 /*************************************************************************
2219 *************************************************************************/
2221 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2222 DATA_BLOB *blob,
2223 struct lsa_BinaryString **_r)
2225 struct lsa_BinaryString *r;
2227 if (!blob || !_r) {
2228 return NT_STATUS_INVALID_PARAMETER;
2231 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2232 if (!r) {
2233 return NT_STATUS_NO_MEMORY;
2236 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2237 if (!r->array) {
2238 return NT_STATUS_NO_MEMORY;
2240 memcpy(r->array, blob->data, blob->length);
2241 r->size = blob->length;
2242 r->length = blob->length;
2244 if (!r->array) {
2245 return NT_STATUS_NO_MEMORY;
2248 *_r = r;
2250 return NT_STATUS_OK;
2253 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2254 struct samr_UserInfo5 *r,
2255 struct samu *pw,
2256 DOM_SID *domain_sid)
2258 const DOM_SID *sid_user, *sid_group;
2259 uint32_t rid, primary_gid;
2260 NTTIME last_logon, last_logoff, last_password_change,
2261 acct_expiry;
2262 const char *account_name, *full_name, *home_directory, *home_drive,
2263 *logon_script, *profile_path, *description,
2264 *workstations, *comment;
2265 struct samr_LogonHours logon_hours;
2267 ZERO_STRUCTP(r);
2269 sid_user = pdb_get_user_sid(pw);
2271 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2272 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2273 "the domain sid %s. Failing operation.\n",
2274 pdb_get_username(pw), sid_string_dbg(sid_user),
2275 sid_string_dbg(domain_sid)));
2276 return NT_STATUS_UNSUCCESSFUL;
2279 become_root();
2280 sid_group = pdb_get_group_sid(pw);
2281 unbecome_root();
2283 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2284 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2285 "which conflicts with the domain sid %s. Failing operation.\n",
2286 pdb_get_username(pw), sid_string_dbg(sid_group),
2287 sid_string_dbg(domain_sid)));
2288 return NT_STATUS_UNSUCCESSFUL;
2291 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2292 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2293 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2294 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2296 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2297 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2298 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2299 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2300 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2301 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2302 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2303 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2304 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2306 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2308 init_samr_user_info5(r,
2309 account_name,
2310 full_name,
2311 rid,
2312 primary_gid,
2313 home_directory,
2314 home_drive,
2315 logon_script,
2316 profile_path,
2317 description,
2318 workstations,
2319 last_logon,
2320 last_logoff,
2321 logon_hours,
2322 pdb_get_bad_password_count(pw),
2323 pdb_get_logon_count(pw),
2324 last_password_change,
2325 acct_expiry,
2326 pdb_get_acct_ctrl(pw));
2328 return NT_STATUS_OK;
2331 /*************************************************************************
2332 get_user_info_7. Safe. Only gives out account_name.
2333 *************************************************************************/
2335 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2336 struct samr_UserInfo7 *r,
2337 struct samu *smbpass)
2339 const char *account_name = NULL;
2341 ZERO_STRUCTP(r);
2343 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2344 if (!account_name) {
2345 return NT_STATUS_NO_MEMORY;
2348 init_samr_user_info7(r, account_name);
2350 return NT_STATUS_OK;
2353 /*************************************************************************
2354 get_user_info_9. Only gives out primary group SID.
2355 *************************************************************************/
2357 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2358 struct samr_UserInfo9 *r,
2359 struct samu *smbpass)
2361 ZERO_STRUCTP(r);
2363 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2365 return NT_STATUS_OK;
2368 /*************************************************************************
2369 get_user_info_16. Safe. Only gives out acb bits.
2370 *************************************************************************/
2372 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2373 struct samr_UserInfo16 *r,
2374 struct samu *smbpass)
2376 ZERO_STRUCTP(r);
2378 init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2380 return NT_STATUS_OK;
2383 /*************************************************************************
2384 get_user_info_18. OK - this is the killer as it gives out password info.
2385 Ensure that this is only allowed on an encrypted connection with a root
2386 user. JRA.
2387 *************************************************************************/
2389 static NTSTATUS get_user_info_18(pipes_struct *p,
2390 TALLOC_CTX *mem_ctx,
2391 struct samr_UserInfo18 *r,
2392 DOM_SID *user_sid)
2394 struct samu *smbpass=NULL;
2395 bool ret;
2397 ZERO_STRUCTP(r);
2399 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2400 return NT_STATUS_ACCESS_DENIED;
2403 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2404 return NT_STATUS_ACCESS_DENIED;
2408 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2411 if ( !(smbpass = samu_new( mem_ctx )) ) {
2412 return NT_STATUS_NO_MEMORY;
2415 ret = pdb_getsampwsid(smbpass, user_sid);
2417 if (ret == False) {
2418 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2419 TALLOC_FREE(smbpass);
2420 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2423 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2425 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2426 TALLOC_FREE(smbpass);
2427 return NT_STATUS_ACCOUNT_DISABLED;
2430 init_samr_user_info18(r,
2431 pdb_get_lanman_passwd(smbpass),
2432 pdb_get_nt_passwd(smbpass),
2433 0 /* FIXME */);
2435 TALLOC_FREE(smbpass);
2437 return NT_STATUS_OK;
2440 /*************************************************************************
2441 get_user_info_20
2442 *************************************************************************/
2444 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2445 struct samr_UserInfo20 *r,
2446 struct samu *sampass)
2448 const char *munged_dial = NULL;
2449 DATA_BLOB blob;
2450 NTSTATUS status;
2451 struct lsa_BinaryString *parameters = NULL;
2453 ZERO_STRUCTP(r);
2455 munged_dial = pdb_get_munged_dial(sampass);
2457 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2458 munged_dial, (int)strlen(munged_dial)));
2460 if (munged_dial) {
2461 blob = base64_decode_data_blob(munged_dial);
2462 } else {
2463 blob = data_blob_string_const("");
2466 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2467 data_blob_free(&blob);
2468 if (!NT_STATUS_IS_OK(status)) {
2469 return status;
2472 init_samr_user_info20(r, parameters);
2474 return NT_STATUS_OK;
2478 /*************************************************************************
2479 get_user_info_21
2480 *************************************************************************/
2482 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2483 struct samr_UserInfo21 *r,
2484 struct samu *pw,
2485 DOM_SID *domain_sid)
2487 NTSTATUS status;
2488 const DOM_SID *sid_user, *sid_group;
2489 uint32_t rid, primary_gid;
2490 NTTIME last_logon, last_logoff, last_password_change,
2491 acct_expiry, allow_password_change, force_password_change;
2492 time_t must_change_time;
2493 uint8_t password_expired;
2494 const char *account_name, *full_name, *home_directory, *home_drive,
2495 *logon_script, *profile_path, *description,
2496 *workstations, *comment;
2497 struct samr_LogonHours logon_hours;
2498 struct lsa_BinaryString *parameters = NULL;
2499 const char *munged_dial = NULL;
2500 DATA_BLOB blob;
2502 ZERO_STRUCTP(r);
2504 sid_user = pdb_get_user_sid(pw);
2506 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2507 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2508 "the domain sid %s. Failing operation.\n",
2509 pdb_get_username(pw), sid_string_dbg(sid_user),
2510 sid_string_dbg(domain_sid)));
2511 return NT_STATUS_UNSUCCESSFUL;
2514 become_root();
2515 sid_group = pdb_get_group_sid(pw);
2516 unbecome_root();
2518 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2519 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2520 "which conflicts with the domain sid %s. Failing operation.\n",
2521 pdb_get_username(pw), sid_string_dbg(sid_group),
2522 sid_string_dbg(domain_sid)));
2523 return NT_STATUS_UNSUCCESSFUL;
2526 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2527 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2528 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2529 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2530 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2532 must_change_time = pdb_get_pass_must_change_time(pw);
2533 if (must_change_time == get_time_t_max()) {
2534 unix_to_nt_time_abs(&force_password_change, must_change_time);
2535 } else {
2536 unix_to_nt_time(&force_password_change, must_change_time);
2539 if (pdb_get_pass_must_change_time(pw) == 0) {
2540 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2541 } else {
2542 password_expired = 0;
2545 munged_dial = pdb_get_munged_dial(pw);
2546 if (munged_dial) {
2547 blob = base64_decode_data_blob(munged_dial);
2548 } else {
2549 blob = data_blob_string_const("");
2552 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2553 data_blob_free(&blob);
2554 if (!NT_STATUS_IS_OK(status)) {
2555 return status;
2558 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2559 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2560 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2561 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2562 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2563 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2564 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2565 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2566 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2568 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2569 #if 0
2572 Look at a user on a real NT4 PDC with usrmgr, press
2573 'ok'. Then you will see that fields_present is set to
2574 0x08f827fa. Look at the user immediately after that again,
2575 and you will see that 0x00fffff is returned. This solves
2576 the problem that you get access denied after having looked
2577 at the user.
2578 -- Volker
2581 #endif
2583 init_samr_user_info21(r,
2584 last_logon,
2585 last_logoff,
2586 last_password_change,
2587 acct_expiry,
2588 allow_password_change,
2589 force_password_change,
2590 account_name,
2591 full_name,
2592 home_directory,
2593 home_drive,
2594 logon_script,
2595 profile_path,
2596 description,
2597 workstations,
2598 comment,
2599 parameters,
2600 rid,
2601 primary_gid,
2602 pdb_get_acct_ctrl(pw),
2603 pdb_build_fields_present(pw),
2604 logon_hours,
2605 pdb_get_bad_password_count(pw),
2606 pdb_get_logon_count(pw),
2607 0, /* country_code */
2608 0, /* code_page */
2609 0, /* lm_password_set */
2610 0, /* nt_password_set */
2611 password_expired);
2613 return NT_STATUS_OK;
2616 /*******************************************************************
2617 _samr_QueryUserInfo
2618 ********************************************************************/
2620 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2621 struct samr_QueryUserInfo *r)
2623 NTSTATUS status;
2624 union samr_UserInfo *user_info = NULL;
2625 struct samr_info *info = NULL;
2626 DOM_SID domain_sid;
2627 uint32 rid;
2628 bool ret = false;
2629 struct samu *pwd = NULL;
2631 /* search for the handle */
2632 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2633 return NT_STATUS_INVALID_HANDLE;
2635 status = access_check_samr_function(info->acc_granted,
2636 SAMR_USER_ACCESS_GET_ATTRIBUTES,
2637 "_samr_QueryUserInfo");
2638 if (!NT_STATUS_IS_OK(status)) {
2639 return status;
2642 domain_sid = info->sid;
2644 sid_split_rid(&domain_sid, &rid);
2646 if (!sid_check_is_in_our_domain(&info->sid))
2647 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2649 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2650 sid_string_dbg(&info->sid)));
2652 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2653 if (!user_info) {
2654 return NT_STATUS_NO_MEMORY;
2657 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2659 if (!(pwd = samu_new(p->mem_ctx))) {
2660 return NT_STATUS_NO_MEMORY;
2663 become_root();
2664 ret = pdb_getsampwsid(pwd, &info->sid);
2665 unbecome_root();
2667 if (ret == false) {
2668 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2669 TALLOC_FREE(pwd);
2670 return NT_STATUS_NO_SUCH_USER;
2673 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2675 samr_clear_sam_passwd(pwd);
2677 switch (r->in.level) {
2678 case 5:
2679 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2680 break;
2681 case 7:
2682 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2683 break;
2684 case 9:
2685 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2686 break;
2687 case 16:
2688 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2689 break;
2690 case 18:
2691 /* level 18 is special */
2692 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2693 break;
2694 case 20:
2695 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
2696 break;
2697 case 21:
2698 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
2699 break;
2700 default:
2701 status = NT_STATUS_INVALID_INFO_CLASS;
2702 break;
2705 TALLOC_FREE(pwd);
2707 *r->out.info = user_info;
2709 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2711 return status;
2714 /****************************************************************
2715 ****************************************************************/
2717 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2718 struct samr_QueryUserInfo2 *r)
2720 struct samr_QueryUserInfo u;
2722 u.in.user_handle = r->in.user_handle;
2723 u.in.level = r->in.level;
2724 u.out.info = r->out.info;
2726 return _samr_QueryUserInfo(p, &u);
2729 /*******************************************************************
2730 _samr_GetGroupsForUser
2731 ********************************************************************/
2733 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2734 struct samr_GetGroupsForUser *r)
2736 struct samu *sam_pass=NULL;
2737 DOM_SID sid;
2738 DOM_SID *sids;
2739 struct samr_RidWithAttribute dom_gid;
2740 struct samr_RidWithAttribute *gids = NULL;
2741 uint32 primary_group_rid;
2742 size_t num_groups = 0;
2743 gid_t *unix_gids;
2744 size_t i, num_gids;
2745 uint32 acc_granted;
2746 bool ret;
2747 NTSTATUS result;
2748 bool success = False;
2750 struct samr_RidWithAttributeArray *rids = NULL;
2753 * from the SID in the request:
2754 * we should send back the list of DOMAIN GROUPS
2755 * the user is a member of
2757 * and only the DOMAIN GROUPS
2758 * no ALIASES !!! neither aliases of the domain
2759 * nor aliases of the builtin SID
2761 * JFM, 12/2/2001
2764 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2766 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2767 if (!rids) {
2768 return NT_STATUS_NO_MEMORY;
2771 /* find the policy handle. open a policy on it. */
2772 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2773 return NT_STATUS_INVALID_HANDLE;
2775 result = access_check_samr_function(acc_granted,
2776 SAMR_USER_ACCESS_GET_GROUPS,
2777 "_samr_GetGroupsForUser");
2778 if (!NT_STATUS_IS_OK(result)) {
2779 return result;
2782 if (!sid_check_is_in_our_domain(&sid))
2783 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2785 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2786 return NT_STATUS_NO_MEMORY;
2789 become_root();
2790 ret = pdb_getsampwsid(sam_pass, &sid);
2791 unbecome_root();
2793 if (!ret) {
2794 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2795 sid_string_dbg(&sid)));
2796 return NT_STATUS_NO_SUCH_USER;
2799 sids = NULL;
2801 /* make both calls inside the root block */
2802 become_root();
2803 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2804 &sids, &unix_gids, &num_groups);
2805 if ( NT_STATUS_IS_OK(result) ) {
2806 success = sid_peek_check_rid(get_global_sam_sid(),
2807 pdb_get_group_sid(sam_pass),
2808 &primary_group_rid);
2810 unbecome_root();
2812 if (!NT_STATUS_IS_OK(result)) {
2813 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2814 sid_string_dbg(&sid)));
2815 return result;
2818 if ( !success ) {
2819 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2820 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2821 pdb_get_username(sam_pass)));
2822 TALLOC_FREE(sam_pass);
2823 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2826 gids = NULL;
2827 num_gids = 0;
2829 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2830 SE_GROUP_ENABLED);
2831 dom_gid.rid = primary_group_rid;
2832 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2834 for (i=0; i<num_groups; i++) {
2836 if (!sid_peek_check_rid(get_global_sam_sid(),
2837 &(sids[i]), &dom_gid.rid)) {
2838 DEBUG(10, ("Found sid %s not in our domain\n",
2839 sid_string_dbg(&sids[i])));
2840 continue;
2843 if (dom_gid.rid == primary_group_rid) {
2844 /* We added the primary group directly from the
2845 * sam_account. The other SIDs are unique from
2846 * enum_group_memberships */
2847 continue;
2850 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2853 rids->count = num_gids;
2854 rids->rids = gids;
2856 *r->out.rids = rids;
2858 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2860 return result;
2863 /*******************************************************************
2864 _samr_QueryDomainInfo
2865 ********************************************************************/
2867 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2868 struct samr_QueryDomainInfo *r)
2870 NTSTATUS status = NT_STATUS_OK;
2871 struct samr_info *info = NULL;
2872 union samr_DomainInfo *dom_info;
2873 uint32 min_pass_len,pass_hist,password_properties;
2874 time_t u_expire, u_min_age;
2875 NTTIME nt_expire, nt_min_age;
2877 time_t u_lock_duration, u_reset_time;
2878 NTTIME nt_lock_duration, nt_reset_time;
2879 uint32 lockout;
2880 time_t u_logout;
2881 NTTIME nt_logout;
2883 uint32 account_policy_temp;
2885 time_t seq_num;
2886 uint32 server_role;
2888 uint32 num_users=0, num_groups=0, num_aliases=0;
2890 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2892 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2893 if (!dom_info) {
2894 return NT_STATUS_NO_MEMORY;
2897 /* find the policy handle. open a policy on it. */
2898 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
2899 return NT_STATUS_INVALID_HANDLE;
2902 status = access_check_samr_function(info->acc_granted,
2903 SAMR_ACCESS_OPEN_DOMAIN,
2904 "_samr_QueryDomainInfo" );
2906 if ( !NT_STATUS_IS_OK(status) )
2907 return status;
2909 switch (r->in.level) {
2910 case 0x01:
2912 become_root();
2914 /* AS ROOT !!! */
2916 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2917 min_pass_len = account_policy_temp;
2919 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2920 pass_hist = account_policy_temp;
2922 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2923 password_properties = account_policy_temp;
2925 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2926 u_expire = account_policy_temp;
2928 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2929 u_min_age = account_policy_temp;
2931 /* !AS ROOT */
2933 unbecome_root();
2935 unix_to_nt_time_abs(&nt_expire, u_expire);
2936 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2938 if (lp_check_password_script() && *lp_check_password_script()) {
2939 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2942 init_samr_DomInfo1(&dom_info->info1,
2943 (uint16)min_pass_len,
2944 (uint16)pass_hist,
2945 password_properties,
2946 nt_expire,
2947 nt_min_age);
2948 break;
2949 case 0x02:
2951 become_root();
2953 /* AS ROOT !!! */
2955 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2956 num_groups = count_sam_groups(info->disp_info);
2957 num_aliases = count_sam_aliases(info->disp_info);
2959 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2960 u_logout = account_policy_temp;
2962 unix_to_nt_time_abs(&nt_logout, u_logout);
2964 if (!pdb_get_seq_num(&seq_num))
2965 seq_num = time(NULL);
2967 /* !AS ROOT */
2969 unbecome_root();
2971 server_role = ROLE_DOMAIN_PDC;
2972 if (lp_server_role() == ROLE_DOMAIN_BDC)
2973 server_role = ROLE_DOMAIN_BDC;
2975 init_samr_DomInfo2(&dom_info->info2,
2976 nt_logout,
2977 lp_serverstring(),
2978 lp_workgroup(),
2979 global_myname(),
2980 seq_num,
2982 server_role,
2984 num_users,
2985 num_groups,
2986 num_aliases);
2987 break;
2988 case 0x03:
2990 become_root();
2992 /* AS ROOT !!! */
2995 uint32 ul;
2996 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2997 u_logout = (time_t)ul;
3000 /* !AS ROOT */
3002 unbecome_root();
3004 unix_to_nt_time_abs(&nt_logout, u_logout);
3006 init_samr_DomInfo3(&dom_info->info3,
3007 nt_logout);
3009 break;
3010 case 0x04:
3011 init_samr_DomInfo4(&dom_info->info4,
3012 lp_serverstring());
3013 break;
3014 case 0x05:
3015 init_samr_DomInfo5(&dom_info->info5,
3016 get_global_sam_name());
3017 break;
3018 case 0x06:
3019 /* NT returns its own name when a PDC. win2k and later
3020 * only the name of the PDC if itself is a BDC (samba4
3021 * idl) */
3022 init_samr_DomInfo6(&dom_info->info6,
3023 global_myname());
3024 break;
3025 case 0x07:
3026 server_role = ROLE_DOMAIN_PDC;
3027 if (lp_server_role() == ROLE_DOMAIN_BDC)
3028 server_role = ROLE_DOMAIN_BDC;
3030 init_samr_DomInfo7(&dom_info->info7,
3031 server_role);
3032 break;
3033 case 0x08:
3035 become_root();
3037 /* AS ROOT !!! */
3039 if (!pdb_get_seq_num(&seq_num)) {
3040 seq_num = time(NULL);
3043 /* !AS ROOT */
3045 unbecome_root();
3047 init_samr_DomInfo8(&dom_info->info8,
3048 seq_num,
3050 break;
3051 case 0x0c:
3053 become_root();
3055 /* AS ROOT !!! */
3057 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3058 u_lock_duration = account_policy_temp;
3059 if (u_lock_duration != -1) {
3060 u_lock_duration *= 60;
3063 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3064 u_reset_time = account_policy_temp * 60;
3066 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3067 lockout = account_policy_temp;
3069 /* !AS ROOT */
3071 unbecome_root();
3073 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3074 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3076 init_samr_DomInfo12(&dom_info->info12,
3077 nt_lock_duration,
3078 nt_reset_time,
3079 (uint16)lockout);
3080 break;
3081 default:
3082 return NT_STATUS_INVALID_INFO_CLASS;
3085 *r->out.info = dom_info;
3087 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3089 return status;
3092 /* W2k3 seems to use the same check for all 3 objects that can be created via
3093 * SAMR, if you try to create for example "Dialup" as an alias it says
3094 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3095 * database. */
3097 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3099 enum lsa_SidType type;
3100 bool result;
3102 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3104 become_root();
3105 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3106 * whether the name already exists */
3107 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3108 NULL, NULL, NULL, &type);
3109 unbecome_root();
3111 if (!result) {
3112 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3113 return NT_STATUS_OK;
3116 DEBUG(5, ("trying to create %s, exists as %s\n",
3117 new_name, sid_type_lookup(type)));
3119 if (type == SID_NAME_DOM_GRP) {
3120 return NT_STATUS_GROUP_EXISTS;
3122 if (type == SID_NAME_ALIAS) {
3123 return NT_STATUS_ALIAS_EXISTS;
3126 /* Yes, the default is NT_STATUS_USER_EXISTS */
3127 return NT_STATUS_USER_EXISTS;
3130 /*******************************************************************
3131 _samr_CreateUser2
3132 ********************************************************************/
3134 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3135 struct samr_CreateUser2 *r)
3137 const char *account = NULL;
3138 DOM_SID sid;
3139 POLICY_HND dom_pol = *r->in.domain_handle;
3140 uint32_t acb_info = r->in.acct_flags;
3141 POLICY_HND *user_pol = r->out.user_handle;
3142 struct samr_info *info = NULL;
3143 NTSTATUS nt_status;
3144 uint32 acc_granted;
3145 SEC_DESC *psd;
3146 size_t sd_size;
3147 /* check this, when giving away 'add computer to domain' privs */
3148 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3149 bool can_add_account = False;
3150 SE_PRIV se_rights;
3151 DISP_INFO *disp_info = NULL;
3153 /* Get the domain SID stored in the domain policy */
3154 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3155 &disp_info))
3156 return NT_STATUS_INVALID_HANDLE;
3158 if (disp_info->builtin_domain) {
3159 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3160 return NT_STATUS_ACCESS_DENIED;
3163 nt_status = access_check_samr_function(acc_granted,
3164 SAMR_DOMAIN_ACCESS_CREATE_USER,
3165 "_samr_CreateUser2");
3166 if (!NT_STATUS_IS_OK(nt_status)) {
3167 return nt_status;
3170 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3171 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3172 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3173 this parameter is not an account type */
3174 return NT_STATUS_INVALID_PARAMETER;
3177 account = r->in.account_name->string;
3178 if (account == NULL) {
3179 return NT_STATUS_NO_MEMORY;
3182 nt_status = can_create(p->mem_ctx, account);
3183 if (!NT_STATUS_IS_OK(nt_status)) {
3184 return nt_status;
3187 /* determine which user right we need to check based on the acb_info */
3189 if ( acb_info & ACB_WSTRUST )
3191 se_priv_copy( &se_rights, &se_machine_account );
3192 can_add_account = user_has_privileges(
3193 p->pipe_user.nt_user_token, &se_rights );
3195 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3196 account for domain trusts and changes the ACB flags later */
3197 else if ( acb_info & ACB_NORMAL &&
3198 (account[strlen(account)-1] != '$') )
3200 se_priv_copy( &se_rights, &se_add_users );
3201 can_add_account = user_has_privileges(
3202 p->pipe_user.nt_user_token, &se_rights );
3204 else /* implicit assumption of a BDC or domain trust account here
3205 * (we already check the flags earlier) */
3207 if ( lp_enable_privileges() ) {
3208 /* only Domain Admins can add a BDC or domain trust */
3209 se_priv_copy( &se_rights, &se_priv_none );
3210 can_add_account = nt_token_check_domain_rid(
3211 p->pipe_user.nt_user_token,
3212 DOMAIN_GROUP_RID_ADMINS );
3216 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3217 uidtoname(p->pipe_user.ut.uid),
3218 can_add_account ? "True":"False" ));
3220 /********** BEGIN Admin BLOCK **********/
3222 if ( can_add_account )
3223 become_root();
3225 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3226 r->out.rid);
3228 if ( can_add_account )
3229 unbecome_root();
3231 /********** END Admin BLOCK **********/
3233 /* now check for failure */
3235 if ( !NT_STATUS_IS_OK(nt_status) )
3236 return nt_status;
3238 /* Get the user's SID */
3240 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3242 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3244 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3245 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3246 se_map_generic(&des_access, &usr_generic_mapping);
3248 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3249 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3250 &acc_granted, "_samr_CreateUser2");
3252 if ( !NT_STATUS_IS_OK(nt_status) ) {
3253 return nt_status;
3256 /* associate the user's SID with the new handle. */
3257 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3258 return NT_STATUS_NO_MEMORY;
3261 ZERO_STRUCTP(info);
3262 info->sid = sid;
3263 info->acc_granted = acc_granted;
3265 /* get a (unique) handle. open a policy on it. */
3266 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3267 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3270 /* After a "set" ensure we have no cached display info. */
3271 force_flush_samr_cache(info->disp_info);
3273 *r->out.access_granted = acc_granted;
3275 return NT_STATUS_OK;
3278 /****************************************************************
3279 ****************************************************************/
3281 NTSTATUS _samr_CreateUser(pipes_struct *p,
3282 struct samr_CreateUser *r)
3284 struct samr_CreateUser2 c;
3285 uint32_t access_granted;
3287 c.in.domain_handle = r->in.domain_handle;
3288 c.in.account_name = r->in.account_name;
3289 c.in.acct_flags = ACB_NORMAL;
3290 c.in.access_mask = r->in.access_mask;
3291 c.out.user_handle = r->out.user_handle;
3292 c.out.access_granted = &access_granted;
3293 c.out.rid = r->out.rid;
3295 return _samr_CreateUser2(p, &c);
3298 /*******************************************************************
3299 _samr_Connect
3300 ********************************************************************/
3302 NTSTATUS _samr_Connect(pipes_struct *p,
3303 struct samr_Connect *r)
3305 struct samr_info *info = NULL;
3306 uint32 des_access = r->in.access_mask;
3308 /* Access check */
3310 if (!pipe_access_check(p)) {
3311 DEBUG(3, ("access denied to _samr_Connect\n"));
3312 return NT_STATUS_ACCESS_DENIED;
3315 /* set up the SAMR connect_anon response */
3317 /* associate the user's SID with the new handle. */
3318 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3319 return NT_STATUS_NO_MEMORY;
3321 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3322 was observed from a win98 client trying to enumerate users (when configured
3323 user level access control on shares) --jerry */
3325 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3327 se_map_generic( &des_access, &sam_generic_mapping );
3328 info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN);
3330 /* get a (unique) handle. open a policy on it. */
3331 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3332 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3334 return NT_STATUS_OK;
3337 /*******************************************************************
3338 _samr_Connect2
3339 ********************************************************************/
3341 NTSTATUS _samr_Connect2(pipes_struct *p,
3342 struct samr_Connect2 *r)
3344 struct samr_info *info = NULL;
3345 SEC_DESC *psd = NULL;
3346 uint32 acc_granted;
3347 uint32 des_access = r->in.access_mask;
3348 NTSTATUS nt_status;
3349 size_t sd_size;
3350 const char *fn = "_samr_Connect2";
3352 switch (p->hdr_req.opnum) {
3353 case NDR_SAMR_CONNECT2:
3354 fn = "_samr_Connect2";
3355 break;
3356 case NDR_SAMR_CONNECT4:
3357 fn = "_samr_Connect4";
3358 break;
3359 case NDR_SAMR_CONNECT5:
3360 fn = "_samr_Connect5";
3361 break;
3364 DEBUG(5,("%s: %d\n", fn, __LINE__));
3366 /* Access check */
3368 if (!pipe_access_check(p)) {
3369 DEBUG(3, ("access denied to %s\n", fn));
3370 return NT_STATUS_ACCESS_DENIED;
3373 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3375 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3376 se_map_generic(&des_access, &sam_generic_mapping);
3378 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3379 NULL, 0, des_access, &acc_granted, fn);
3381 if ( !NT_STATUS_IS_OK(nt_status) )
3382 return nt_status;
3384 /* associate the user's SID and access granted with the new handle. */
3385 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3386 return NT_STATUS_NO_MEMORY;
3388 info->acc_granted = acc_granted;
3389 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3391 /* get a (unique) handle. open a policy on it. */
3392 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3393 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3395 DEBUG(5,("%s: %d\n", fn, __LINE__));
3397 return nt_status;
3400 /*******************************************************************
3401 _samr_Connect4
3402 ********************************************************************/
3404 NTSTATUS _samr_Connect4(pipes_struct *p,
3405 struct samr_Connect4 *r)
3407 struct samr_Connect2 c;
3409 c.in.system_name = r->in.system_name;
3410 c.in.access_mask = r->in.access_mask;
3411 c.out.connect_handle = r->out.connect_handle;
3413 return _samr_Connect2(p, &c);
3416 /*******************************************************************
3417 _samr_Connect5
3418 ********************************************************************/
3420 NTSTATUS _samr_Connect5(pipes_struct *p,
3421 struct samr_Connect5 *r)
3423 NTSTATUS status;
3424 struct samr_Connect2 c;
3425 struct samr_ConnectInfo1 info1;
3427 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3428 info1.unknown2 = 0;
3430 c.in.system_name = r->in.system_name;
3431 c.in.access_mask = r->in.access_mask;
3432 c.out.connect_handle = r->out.connect_handle;
3434 status = _samr_Connect2(p, &c);
3435 if (!NT_STATUS_IS_OK(status)) {
3436 return status;
3439 *r->out.level_out = 1;
3440 r->out.info_out->info1 = info1;
3442 return NT_STATUS_OK;
3445 /**********************************************************************
3446 _samr_LookupDomain
3447 **********************************************************************/
3449 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3450 struct samr_LookupDomain *r)
3452 NTSTATUS status = NT_STATUS_OK;
3453 struct samr_info *info;
3454 const char *domain_name;
3455 DOM_SID *sid = NULL;
3457 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3458 return NT_STATUS_INVALID_HANDLE;
3460 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3461 Reverted that change so we will work with RAS servers again */
3463 status = access_check_samr_function(info->acc_granted,
3464 SAMR_ACCESS_OPEN_DOMAIN,
3465 "_samr_LookupDomain");
3466 if (!NT_STATUS_IS_OK(status)) {
3467 return status;
3470 domain_name = r->in.domain_name->string;
3471 if (!domain_name) {
3472 return NT_STATUS_INVALID_PARAMETER;
3475 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3476 if (!sid) {
3477 return NT_STATUS_NO_MEMORY;
3480 if (strequal(domain_name, builtin_domain_name())) {
3481 sid_copy(sid, &global_sid_Builtin);
3482 } else {
3483 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3484 status = NT_STATUS_NO_SUCH_DOMAIN;
3488 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3489 sid_string_dbg(sid)));
3491 *r->out.sid = sid;
3493 return status;
3496 /**********************************************************************
3497 _samr_EnumDomains
3498 **********************************************************************/
3500 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3501 struct samr_EnumDomains *r)
3503 NTSTATUS status;
3504 struct samr_info *info;
3505 uint32_t num_entries = 2;
3506 struct samr_SamEntry *entry_array = NULL;
3507 struct samr_SamArray *sam;
3509 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3510 return NT_STATUS_INVALID_HANDLE;
3512 status = access_check_samr_function(info->acc_granted,
3513 SAMR_ACCESS_ENUM_DOMAINS,
3514 "_samr_EnumDomains");
3515 if (!NT_STATUS_IS_OK(status)) {
3516 return status;
3519 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3520 if (!sam) {
3521 return NT_STATUS_NO_MEMORY;
3524 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3525 struct samr_SamEntry,
3526 num_entries);
3527 if (!entry_array) {
3528 return NT_STATUS_NO_MEMORY;
3531 entry_array[0].idx = 0;
3532 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3534 entry_array[1].idx = 1;
3535 init_lsa_String(&entry_array[1].name, "Builtin");
3537 sam->count = num_entries;
3538 sam->entries = entry_array;
3540 *r->out.sam = sam;
3541 *r->out.num_entries = num_entries;
3543 return status;
3546 /*******************************************************************
3547 _samr_OpenAlias
3548 ********************************************************************/
3550 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3551 struct samr_OpenAlias *r)
3553 DOM_SID sid;
3554 POLICY_HND domain_pol = *r->in.domain_handle;
3555 uint32 alias_rid = r->in.rid;
3556 POLICY_HND *alias_pol = r->out.alias_handle;
3557 struct samr_info *info = NULL;
3558 SEC_DESC *psd = NULL;
3559 uint32 acc_granted;
3560 uint32 des_access = r->in.access_mask;
3561 size_t sd_size;
3562 NTSTATUS status;
3563 SE_PRIV se_rights;
3565 /* find the domain policy and get the SID / access bits stored in the domain policy */
3567 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3568 return NT_STATUS_INVALID_HANDLE;
3570 status = access_check_samr_function(acc_granted,
3571 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3572 "_samr_OpenAlias");
3574 if ( !NT_STATUS_IS_OK(status) )
3575 return status;
3577 /* append the alias' RID to it */
3579 if (!sid_append_rid(&sid, alias_rid))
3580 return NT_STATUS_NO_SUCH_ALIAS;
3582 /*check if access can be granted as requested by client. */
3584 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3586 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3587 se_map_generic(&des_access,&ali_generic_mapping);
3589 se_priv_copy( &se_rights, &se_add_users );
3592 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3593 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3594 &acc_granted, "_samr_OpenAlias");
3596 if ( !NT_STATUS_IS_OK(status) )
3597 return status;
3600 /* Check we actually have the requested alias */
3601 enum lsa_SidType type;
3602 bool result;
3603 gid_t gid;
3605 become_root();
3606 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3607 unbecome_root();
3609 if (!result || (type != SID_NAME_ALIAS)) {
3610 return NT_STATUS_NO_SUCH_ALIAS;
3613 /* make sure there is a mapping */
3615 if ( !sid_to_gid( &sid, &gid ) ) {
3616 return NT_STATUS_NO_SUCH_ALIAS;
3621 /* associate the alias SID with the new handle. */
3622 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3623 return NT_STATUS_NO_MEMORY;
3625 info->acc_granted = acc_granted;
3627 /* get a (unique) handle. open a policy on it. */
3628 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3629 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3631 return NT_STATUS_OK;
3634 /*******************************************************************
3635 set_user_info_7
3636 ********************************************************************/
3638 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3639 struct samr_UserInfo7 *id7,
3640 struct samu *pwd)
3642 NTSTATUS rc;
3644 if (id7 == NULL) {
3645 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3646 return NT_STATUS_ACCESS_DENIED;
3649 if (!id7->account_name.string) {
3650 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3651 return NT_STATUS_ACCESS_DENIED;
3654 /* check to see if the new username already exists. Note: we can't
3655 reliably lock all backends, so there is potentially the
3656 possibility that a user can be created in between this check and
3657 the rename. The rename should fail, but may not get the
3658 exact same failure status code. I think this is small enough
3659 of a window for this type of operation and the results are
3660 simply that the rename fails with a slightly different status
3661 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3663 rc = can_create(mem_ctx, id7->account_name.string);
3664 if (!NT_STATUS_IS_OK(rc)) {
3665 return rc;
3668 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3670 return rc;
3673 /*******************************************************************
3674 set_user_info_16
3675 ********************************************************************/
3677 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3678 struct samu *pwd)
3680 if (id16 == NULL) {
3681 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3682 return False;
3685 /* FIX ME: check if the value is really changed --metze */
3686 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3687 return False;
3690 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3691 return False;
3694 return True;
3697 /*******************************************************************
3698 set_user_info_18
3699 ********************************************************************/
3701 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
3702 TALLOC_CTX *mem_ctx,
3703 DATA_BLOB *session_key,
3704 struct samu *pwd)
3706 if (id18 == NULL) {
3707 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3708 return NT_STATUS_INVALID_PARAMETER;
3711 if (id18->nt_pwd_active || id18->lm_pwd_active) {
3712 if (!session_key->length) {
3713 return NT_STATUS_NO_USER_SESSION_KEY;
3717 if (id18->nt_pwd_active) {
3719 DATA_BLOB in, out;
3721 in = data_blob_const(id18->nt_pwd.hash, 16);
3722 out = data_blob_talloc_zero(mem_ctx, 16);
3724 sess_crypt_blob(&out, &in, session_key, false);
3726 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
3727 return NT_STATUS_ACCESS_DENIED;
3730 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3733 if (id18->lm_pwd_active) {
3735 DATA_BLOB in, out;
3737 in = data_blob_const(id18->lm_pwd.hash, 16);
3738 out = data_blob_talloc_zero(mem_ctx, 16);
3740 sess_crypt_blob(&out, &in, session_key, false);
3742 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
3743 return NT_STATUS_ACCESS_DENIED;
3746 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3749 if (id18->password_expired) {
3750 pdb_set_pass_last_set_time(pwd, 0, PDB_CHANGED);
3751 } else {
3752 /* FIXME */
3753 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3756 return pdb_update_sam_account(pwd);
3759 /*******************************************************************
3760 set_user_info_20
3761 ********************************************************************/
3763 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3764 struct samu *pwd)
3766 if (id20 == NULL) {
3767 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3768 return False;
3771 copy_id20_to_sam_passwd(pwd, id20);
3773 /* write the change out */
3774 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3775 return False;
3778 return True;
3781 /*******************************************************************
3782 set_user_info_21
3783 ********************************************************************/
3785 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3786 struct samr_UserInfo21 *id21,
3787 struct samu *pwd)
3789 NTSTATUS status;
3791 if (id21 == NULL) {
3792 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3793 return NT_STATUS_INVALID_PARAMETER;
3796 if (id21->fields_present == 0) {
3797 return NT_STATUS_INVALID_PARAMETER;
3800 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3801 return NT_STATUS_ACCESS_DENIED;
3804 /* we need to separately check for an account rename first */
3806 if (id21->account_name.string &&
3807 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3810 /* check to see if the new username already exists. Note: we can't
3811 reliably lock all backends, so there is potentially the
3812 possibility that a user can be created in between this check and
3813 the rename. The rename should fail, but may not get the
3814 exact same failure status code. I think this is small enough
3815 of a window for this type of operation and the results are
3816 simply that the rename fails with a slightly different status
3817 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3819 status = can_create(mem_ctx, id21->account_name.string);
3820 if (!NT_STATUS_IS_OK(status)) {
3821 return status;
3824 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3826 if (!NT_STATUS_IS_OK(status)) {
3827 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3828 nt_errstr(status)));
3829 return status;
3832 /* set the new username so that later
3833 functions can work on the new account */
3834 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3837 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3840 * The funny part about the previous two calls is
3841 * that pwd still has the password hashes from the
3842 * passdb entry. These have not been updated from
3843 * id21. I don't know if they need to be set. --jerry
3846 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3847 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3848 if ( !NT_STATUS_IS_OK(status) ) {
3849 return status;
3853 /* Don't worry about writing out the user account since the
3854 primary group SID is generated solely from the user's Unix
3855 primary group. */
3857 /* write the change out */
3858 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3859 return status;
3862 return NT_STATUS_OK;
3865 /*******************************************************************
3866 set_user_info_23
3867 ********************************************************************/
3869 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3870 struct samr_UserInfo23 *id23,
3871 struct samu *pwd)
3873 char *plaintext_buf = NULL;
3874 uint32 len = 0;
3875 uint32_t acct_ctrl;
3876 NTSTATUS status;
3878 if (id23 == NULL) {
3879 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3880 return NT_STATUS_INVALID_PARAMETER;
3883 if (id23->info.fields_present == 0) {
3884 return NT_STATUS_INVALID_PARAMETER;
3887 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3888 return NT_STATUS_ACCESS_DENIED;
3891 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3892 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
3894 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3895 pdb_get_username(pwd)));
3897 if (!decode_pw_buffer(mem_ctx,
3898 id23->password.data,
3899 &plaintext_buf,
3900 &len,
3901 STR_UNICODE)) {
3902 return NT_STATUS_WRONG_PASSWORD;
3905 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3906 return NT_STATUS_ACCESS_DENIED;
3910 copy_id23_to_sam_passwd(pwd, id23);
3912 acct_ctrl = pdb_get_acct_ctrl(pwd);
3914 /* if it's a trust account, don't update /etc/passwd */
3915 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3916 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3917 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3918 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3919 } else if (plaintext_buf) {
3920 /* update the UNIX password */
3921 if (lp_unix_password_sync() ) {
3922 struct passwd *passwd;
3923 if (pdb_get_username(pwd) == NULL) {
3924 DEBUG(1, ("chgpasswd: User without name???\n"));
3925 return NT_STATUS_ACCESS_DENIED;
3928 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3929 if (passwd == NULL) {
3930 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3933 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3934 return NT_STATUS_ACCESS_DENIED;
3936 TALLOC_FREE(passwd);
3940 if (plaintext_buf) {
3941 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3944 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3945 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3946 pwd)))) {
3947 return status;
3950 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3951 return status;
3954 return NT_STATUS_OK;
3957 /*******************************************************************
3958 set_user_info_pw
3959 ********************************************************************/
3961 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
3962 int level)
3964 uint32 len = 0;
3965 char *plaintext_buf = NULL;
3966 uint32 acct_ctrl;
3967 time_t last_set_time;
3968 enum pdb_value_state last_set_state;
3970 DEBUG(5, ("Attempting administrator password change for user %s\n",
3971 pdb_get_username(pwd)));
3973 acct_ctrl = pdb_get_acct_ctrl(pwd);
3974 /* we need to know if it's expired, because this is an admin change, not a
3975 user change, so it's still expired when we're done */
3976 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3977 last_set_time = pdb_get_pass_last_set_time(pwd);
3979 if (!decode_pw_buffer(talloc_tos(),
3980 pass,
3981 &plaintext_buf,
3982 &len,
3983 STR_UNICODE)) {
3984 return False;
3987 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3988 return False;
3991 /* if it's a trust account, don't update /etc/passwd */
3992 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3993 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3994 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3995 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3996 } else {
3997 /* update the UNIX password */
3998 if (lp_unix_password_sync()) {
3999 struct passwd *passwd;
4001 if (pdb_get_username(pwd) == NULL) {
4002 DEBUG(1, ("chgpasswd: User without name???\n"));
4003 return False;
4006 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4007 if (passwd == NULL) {
4008 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4011 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4012 return False;
4014 TALLOC_FREE(passwd);
4018 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4021 * A level 25 change does reset the pwdlastset field, a level 24
4022 * change does not. I know this is probably not the full story, but
4023 * it is needed to make XP join LDAP correctly, without it the later
4024 * auth2 check can fail with PWD_MUST_CHANGE.
4026 if (level != 25) {
4028 * restore last set time as this is an admin change, not a
4029 * user pw change
4031 pdb_set_pass_last_set_time (pwd, last_set_time,
4032 last_set_state);
4035 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4037 /* update the SAMBA password */
4038 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4039 return False;
4042 return True;
4045 /*******************************************************************
4046 set_user_info_25
4047 ********************************************************************/
4049 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4050 struct samr_UserInfo25 *id25,
4051 struct samu *pwd)
4053 NTSTATUS status;
4055 if (id25 == NULL) {
4056 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4057 return NT_STATUS_INVALID_PARAMETER;
4060 if (id25->info.fields_present == 0) {
4061 return NT_STATUS_INVALID_PARAMETER;
4064 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4065 return NT_STATUS_ACCESS_DENIED;
4068 copy_id25_to_sam_passwd(pwd, id25);
4070 /* write the change out */
4071 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4072 return status;
4076 * We need to "pdb_update_sam_account" before the unix primary group
4077 * is set, because the idealx scripts would also change the
4078 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4079 * the delete explicit / add explicit, which would then fail to find
4080 * the previous primaryGroupSid value.
4083 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4084 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4085 if ( !NT_STATUS_IS_OK(status) ) {
4086 return status;
4090 return NT_STATUS_OK;
4093 /*******************************************************************
4094 samr_SetUserInfo
4095 ********************************************************************/
4097 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4098 struct samr_SetUserInfo *r)
4100 NTSTATUS status;
4101 struct samu *pwd = NULL;
4102 DOM_SID sid;
4103 POLICY_HND *pol = r->in.user_handle;
4104 union samr_UserInfo *info = r->in.info;
4105 uint16_t switch_value = r->in.level;
4106 uint32_t acc_granted;
4107 uint32_t acc_required;
4108 bool ret;
4109 bool has_enough_rights = False;
4110 uint32_t acb_info;
4111 DISP_INFO *disp_info = NULL;
4113 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4115 /* find the policy handle. open a policy on it. */
4116 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4117 return NT_STATUS_INVALID_HANDLE;
4120 /* This is tricky. A WinXP domain join sets
4121 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4122 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4123 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4124 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4125 we'll use the set from the WinXP join as the basis. */
4127 switch (switch_value) {
4128 case 18:
4129 case 24:
4130 case 25:
4131 case 26:
4132 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4133 break;
4134 default:
4135 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4136 SAMR_USER_ACCESS_SET_ATTRIBUTES |
4137 SAMR_USER_ACCESS_GET_ATTRIBUTES;
4138 break;
4141 status = access_check_samr_function(acc_granted,
4142 acc_required,
4143 "_samr_SetUserInfo");
4144 if (!NT_STATUS_IS_OK(status)) {
4145 return status;
4148 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4149 sid_string_dbg(&sid), switch_value));
4151 if (info == NULL) {
4152 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4153 return NT_STATUS_INVALID_INFO_CLASS;
4156 if (!(pwd = samu_new(NULL))) {
4157 return NT_STATUS_NO_MEMORY;
4160 become_root();
4161 ret = pdb_getsampwsid(pwd, &sid);
4162 unbecome_root();
4164 if (!ret) {
4165 TALLOC_FREE(pwd);
4166 return NT_STATUS_NO_SUCH_USER;
4169 /* deal with machine password changes differently from userinfo changes */
4170 /* check to see if we have the sufficient rights */
4172 acb_info = pdb_get_acct_ctrl(pwd);
4173 if (acb_info & ACB_WSTRUST)
4174 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4175 &se_machine_account);
4176 else if (acb_info & ACB_NORMAL)
4177 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4178 &se_add_users);
4179 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4180 if (lp_enable_privileges()) {
4181 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4182 DOMAIN_GROUP_RID_ADMINS);
4186 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4187 uidtoname(p->pipe_user.ut.uid),
4188 has_enough_rights ? "" : " not"));
4190 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4192 if (has_enough_rights) {
4193 become_root();
4196 /* ok! user info levels (lots: see MSDEV help), off we go... */
4198 switch (switch_value) {
4200 case 7:
4201 status = set_user_info_7(p->mem_ctx,
4202 &info->info7, pwd);
4203 break;
4205 case 16:
4206 if (!set_user_info_16(&info->info16, pwd)) {
4207 status = NT_STATUS_ACCESS_DENIED;
4209 break;
4211 case 18:
4212 /* Used by AS/U JRA. */
4213 status = set_user_info_18(&info->info18,
4214 p->mem_ctx,
4215 &p->server_info->user_session_key,
4216 pwd);
4217 break;
4219 case 20:
4220 if (!set_user_info_20(&info->info20, pwd)) {
4221 status = NT_STATUS_ACCESS_DENIED;
4223 break;
4225 case 21:
4226 status = set_user_info_21(p->mem_ctx,
4227 &info->info21, pwd);
4228 break;
4230 case 23:
4231 if (!p->server_info->user_session_key.length) {
4232 status = NT_STATUS_NO_USER_SESSION_KEY;
4234 SamOEMhashBlob(info->info23.password.data, 516,
4235 &p->server_info->user_session_key);
4237 dump_data(100, info->info23.password.data, 516);
4239 status = set_user_info_23(p->mem_ctx,
4240 &info->info23, pwd);
4241 break;
4243 case 24:
4244 if (!p->server_info->user_session_key.length) {
4245 status = NT_STATUS_NO_USER_SESSION_KEY;
4247 SamOEMhashBlob(info->info24.password.data,
4248 516,
4249 &p->server_info->user_session_key);
4251 dump_data(100, info->info24.password.data, 516);
4253 if (!set_user_info_pw(info->info24.password.data, pwd,
4254 switch_value)) {
4255 status = NT_STATUS_WRONG_PASSWORD;
4257 break;
4259 case 25:
4260 if (!p->server_info->user_session_key.length) {
4261 status = NT_STATUS_NO_USER_SESSION_KEY;
4263 encode_or_decode_arc4_passwd_buffer(
4264 info->info25.password.data,
4265 &p->server_info->user_session_key);
4267 dump_data(100, info->info25.password.data, 532);
4269 status = set_user_info_25(p->mem_ctx,
4270 &info->info25, pwd);
4271 if (!NT_STATUS_IS_OK(status)) {
4272 goto done;
4274 if (!set_user_info_pw(info->info25.password.data, pwd,
4275 switch_value)) {
4276 status = NT_STATUS_WRONG_PASSWORD;
4278 break;
4280 case 26:
4281 if (!p->server_info->user_session_key.length) {
4282 status = NT_STATUS_NO_USER_SESSION_KEY;
4284 encode_or_decode_arc4_passwd_buffer(
4285 info->info26.password.data,
4286 &p->server_info->user_session_key);
4288 dump_data(100, info->info26.password.data, 516);
4290 if (!set_user_info_pw(info->info26.password.data, pwd,
4291 switch_value)) {
4292 status = NT_STATUS_WRONG_PASSWORD;
4294 break;
4296 default:
4297 status = NT_STATUS_INVALID_INFO_CLASS;
4300 done:
4302 TALLOC_FREE(pwd);
4304 if (has_enough_rights) {
4305 unbecome_root();
4308 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4310 if (NT_STATUS_IS_OK(status)) {
4311 force_flush_samr_cache(disp_info);
4314 return status;
4317 /*******************************************************************
4318 _samr_SetUserInfo2
4319 ********************************************************************/
4321 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4322 struct samr_SetUserInfo2 *r)
4324 struct samr_SetUserInfo q;
4326 q.in.user_handle = r->in.user_handle;
4327 q.in.level = r->in.level;
4328 q.in.info = r->in.info;
4330 return _samr_SetUserInfo(p, &q);
4333 /*********************************************************************
4334 _samr_GetAliasMembership
4335 *********************************************************************/
4337 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4338 struct samr_GetAliasMembership *r)
4340 size_t num_alias_rids;
4341 uint32 *alias_rids;
4342 struct samr_info *info = NULL;
4343 size_t i;
4345 NTSTATUS ntstatus1;
4346 NTSTATUS ntstatus2;
4348 DOM_SID *members;
4350 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4352 /* find the policy handle. open a policy on it. */
4353 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4354 return NT_STATUS_INVALID_HANDLE;
4356 ntstatus1 = access_check_samr_function(info->acc_granted,
4357 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
4358 "_samr_GetAliasMembership");
4359 ntstatus2 = access_check_samr_function(info->acc_granted,
4360 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4361 "_samr_GetAliasMembership");
4363 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4364 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4365 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4366 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4370 if (!sid_check_is_domain(&info->sid) &&
4371 !sid_check_is_builtin(&info->sid))
4372 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4374 if (r->in.sids->num_sids) {
4375 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4377 if (members == NULL)
4378 return NT_STATUS_NO_MEMORY;
4379 } else {
4380 members = NULL;
4383 for (i=0; i<r->in.sids->num_sids; i++)
4384 sid_copy(&members[i], r->in.sids->sids[i].sid);
4386 alias_rids = NULL;
4387 num_alias_rids = 0;
4389 become_root();
4390 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4391 r->in.sids->num_sids,
4392 &alias_rids, &num_alias_rids);
4393 unbecome_root();
4395 if (!NT_STATUS_IS_OK(ntstatus1)) {
4396 return ntstatus1;
4399 r->out.rids->count = num_alias_rids;
4400 r->out.rids->ids = alias_rids;
4402 return NT_STATUS_OK;
4405 /*********************************************************************
4406 _samr_GetMembersInAlias
4407 *********************************************************************/
4409 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4410 struct samr_GetMembersInAlias *r)
4412 NTSTATUS status;
4413 size_t i;
4414 size_t num_sids = 0;
4415 struct lsa_SidPtr *sids = NULL;
4416 DOM_SID *pdb_sids = NULL;
4418 DOM_SID alias_sid;
4420 uint32 acc_granted;
4422 /* find the policy handle. open a policy on it. */
4423 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4424 return NT_STATUS_INVALID_HANDLE;
4426 status = access_check_samr_function(acc_granted,
4427 SAMR_ALIAS_ACCESS_GET_MEMBERS,
4428 "_samr_GetMembersInAlias");
4429 if (!NT_STATUS_IS_OK(status)) {
4430 return status;
4433 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4435 become_root();
4436 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4437 unbecome_root();
4439 if (!NT_STATUS_IS_OK(status)) {
4440 return status;
4443 if (num_sids) {
4444 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4445 if (sids == NULL) {
4446 TALLOC_FREE(pdb_sids);
4447 return NT_STATUS_NO_MEMORY;
4451 for (i = 0; i < num_sids; i++) {
4452 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4453 if (!sids[i].sid) {
4454 TALLOC_FREE(pdb_sids);
4455 return NT_STATUS_NO_MEMORY;
4459 r->out.sids->num_sids = num_sids;
4460 r->out.sids->sids = sids;
4462 TALLOC_FREE(pdb_sids);
4464 return NT_STATUS_OK;
4467 /*********************************************************************
4468 _samr_QueryGroupMember
4469 *********************************************************************/
4471 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4472 struct samr_QueryGroupMember *r)
4474 DOM_SID group_sid;
4475 size_t i, num_members;
4477 uint32 *rid=NULL;
4478 uint32 *attr=NULL;
4480 uint32 acc_granted;
4482 NTSTATUS status;
4483 struct samr_RidTypeArray *rids = NULL;
4485 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4486 if (!rids) {
4487 return NT_STATUS_NO_MEMORY;
4490 /* find the policy handle. open a policy on it. */
4491 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4492 return NT_STATUS_INVALID_HANDLE;
4494 status = access_check_samr_function(acc_granted,
4495 SAMR_GROUP_ACCESS_GET_MEMBERS,
4496 "_samr_QueryGroupMember");
4497 if (!NT_STATUS_IS_OK(status)) {
4498 return status;
4501 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4503 if (!sid_check_is_in_our_domain(&group_sid)) {
4504 DEBUG(3, ("sid %s is not in our domain\n",
4505 sid_string_dbg(&group_sid)));
4506 return NT_STATUS_NO_SUCH_GROUP;
4509 DEBUG(10, ("lookup on Domain SID\n"));
4511 become_root();
4512 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4513 &rid, &num_members);
4514 unbecome_root();
4516 if (!NT_STATUS_IS_OK(status))
4517 return status;
4519 if (num_members) {
4520 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4521 if (attr == NULL) {
4522 return NT_STATUS_NO_MEMORY;
4524 } else {
4525 attr = NULL;
4528 for (i=0; i<num_members; i++)
4529 attr[i] = SID_NAME_USER;
4531 rids->count = num_members;
4532 rids->types = attr;
4533 rids->rids = rid;
4535 *r->out.rids = rids;
4537 return NT_STATUS_OK;
4540 /*********************************************************************
4541 _samr_AddAliasMember
4542 *********************************************************************/
4544 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4545 struct samr_AddAliasMember *r)
4547 DOM_SID alias_sid;
4548 uint32 acc_granted;
4549 SE_PRIV se_rights;
4550 bool can_add_accounts;
4551 NTSTATUS status;
4552 DISP_INFO *disp_info = NULL;
4554 /* Find the policy handle. Open a policy on it. */
4555 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4556 return NT_STATUS_INVALID_HANDLE;
4558 status = access_check_samr_function(acc_granted,
4559 SAMR_ALIAS_ACCESS_ADD_MEMBER,
4560 "_samr_AddAliasMember");
4561 if (!NT_STATUS_IS_OK(status)) {
4562 return status;
4565 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4567 se_priv_copy( &se_rights, &se_add_users );
4568 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4570 /******** BEGIN SeAddUsers BLOCK *********/
4572 if ( can_add_accounts )
4573 become_root();
4575 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4577 if ( can_add_accounts )
4578 unbecome_root();
4580 /******** END SeAddUsers BLOCK *********/
4582 if (NT_STATUS_IS_OK(status)) {
4583 force_flush_samr_cache(disp_info);
4586 return status;
4589 /*********************************************************************
4590 _samr_DeleteAliasMember
4591 *********************************************************************/
4593 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4594 struct samr_DeleteAliasMember *r)
4596 DOM_SID alias_sid;
4597 uint32 acc_granted;
4598 SE_PRIV se_rights;
4599 bool can_add_accounts;
4600 NTSTATUS status;
4601 DISP_INFO *disp_info = NULL;
4603 /* Find the policy handle. Open a policy on it. */
4604 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4605 return NT_STATUS_INVALID_HANDLE;
4607 status = access_check_samr_function(acc_granted,
4608 SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
4609 "_samr_DeleteAliasMember");
4610 if (!NT_STATUS_IS_OK(status)) {
4611 return status;
4614 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4615 sid_string_dbg(&alias_sid)));
4617 se_priv_copy( &se_rights, &se_add_users );
4618 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4620 /******** BEGIN SeAddUsers BLOCK *********/
4622 if ( can_add_accounts )
4623 become_root();
4625 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4627 if ( can_add_accounts )
4628 unbecome_root();
4630 /******** END SeAddUsers BLOCK *********/
4632 if (NT_STATUS_IS_OK(status)) {
4633 force_flush_samr_cache(disp_info);
4636 return status;
4639 /*********************************************************************
4640 _samr_AddGroupMember
4641 *********************************************************************/
4643 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4644 struct samr_AddGroupMember *r)
4646 NTSTATUS status;
4647 DOM_SID group_sid;
4648 uint32 group_rid;
4649 uint32 acc_granted;
4650 SE_PRIV se_rights;
4651 bool can_add_accounts;
4652 DISP_INFO *disp_info = NULL;
4654 /* Find the policy handle. Open a policy on it. */
4655 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4656 return NT_STATUS_INVALID_HANDLE;
4658 status = access_check_samr_function(acc_granted,
4659 SAMR_GROUP_ACCESS_ADD_MEMBER,
4660 "_samr_AddGroupMember");
4661 if (!NT_STATUS_IS_OK(status)) {
4662 return status;
4665 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4667 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4668 &group_rid)) {
4669 return NT_STATUS_INVALID_HANDLE;
4672 se_priv_copy( &se_rights, &se_add_users );
4673 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4675 /******** BEGIN SeAddUsers BLOCK *********/
4677 if ( can_add_accounts )
4678 become_root();
4680 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4682 if ( can_add_accounts )
4683 unbecome_root();
4685 /******** END SeAddUsers BLOCK *********/
4687 force_flush_samr_cache(disp_info);
4689 return status;
4692 /*********************************************************************
4693 _samr_DeleteGroupMember
4694 *********************************************************************/
4696 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4697 struct samr_DeleteGroupMember *r)
4700 NTSTATUS status;
4701 DOM_SID group_sid;
4702 uint32 group_rid;
4703 uint32 acc_granted;
4704 SE_PRIV se_rights;
4705 bool can_add_accounts;
4706 DISP_INFO *disp_info = NULL;
4709 * delete the group member named r->in.rid
4710 * who is a member of the sid associated with the handle
4711 * the rid is a user's rid as the group is a domain group.
4714 /* Find the policy handle. Open a policy on it. */
4715 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4716 return NT_STATUS_INVALID_HANDLE;
4718 status = access_check_samr_function(acc_granted,
4719 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
4720 "_samr_DeleteGroupMember");
4721 if (!NT_STATUS_IS_OK(status)) {
4722 return status;
4725 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4726 &group_rid)) {
4727 return NT_STATUS_INVALID_HANDLE;
4730 se_priv_copy( &se_rights, &se_add_users );
4731 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4733 /******** BEGIN SeAddUsers BLOCK *********/
4735 if ( can_add_accounts )
4736 become_root();
4738 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4740 if ( can_add_accounts )
4741 unbecome_root();
4743 /******** END SeAddUsers BLOCK *********/
4745 force_flush_samr_cache(disp_info);
4747 return status;
4750 /*********************************************************************
4751 _samr_DeleteUser
4752 *********************************************************************/
4754 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4755 struct samr_DeleteUser *r)
4757 NTSTATUS status;
4758 DOM_SID user_sid;
4759 struct samu *sam_pass=NULL;
4760 uint32 acc_granted;
4761 bool can_add_accounts;
4762 uint32 acb_info;
4763 DISP_INFO *disp_info = NULL;
4764 bool ret;
4766 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4768 /* Find the policy handle. Open a policy on it. */
4769 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4770 return NT_STATUS_INVALID_HANDLE;
4772 status = access_check_samr_function(acc_granted,
4773 STD_RIGHT_DELETE_ACCESS,
4774 "_samr_DeleteUser");
4775 if (!NT_STATUS_IS_OK(status)) {
4776 return status;
4779 if (!sid_check_is_in_our_domain(&user_sid))
4780 return NT_STATUS_CANNOT_DELETE;
4782 /* check if the user exists before trying to delete */
4783 if ( !(sam_pass = samu_new( NULL )) ) {
4784 return NT_STATUS_NO_MEMORY;
4787 become_root();
4788 ret = pdb_getsampwsid(sam_pass, &user_sid);
4789 unbecome_root();
4791 if( !ret ) {
4792 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4793 sid_string_dbg(&user_sid)));
4794 TALLOC_FREE(sam_pass);
4795 return NT_STATUS_NO_SUCH_USER;
4798 acb_info = pdb_get_acct_ctrl(sam_pass);
4800 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4801 if ( acb_info & ACB_WSTRUST ) {
4802 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4803 } else {
4804 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4807 /******** BEGIN SeAddUsers BLOCK *********/
4809 if ( can_add_accounts )
4810 become_root();
4812 status = pdb_delete_user(p->mem_ctx, sam_pass);
4814 if ( can_add_accounts )
4815 unbecome_root();
4817 /******** END SeAddUsers BLOCK *********/
4819 if ( !NT_STATUS_IS_OK(status) ) {
4820 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4821 "user %s: %s.\n", pdb_get_username(sam_pass),
4822 nt_errstr(status)));
4823 TALLOC_FREE(sam_pass);
4824 return status;
4828 TALLOC_FREE(sam_pass);
4830 if (!close_policy_hnd(p, r->in.user_handle))
4831 return NT_STATUS_OBJECT_NAME_INVALID;
4833 ZERO_STRUCTP(r->out.user_handle);
4835 force_flush_samr_cache(disp_info);
4837 return NT_STATUS_OK;
4840 /*********************************************************************
4841 _samr_DeleteDomainGroup
4842 *********************************************************************/
4844 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4845 struct samr_DeleteDomainGroup *r)
4847 NTSTATUS status;
4848 DOM_SID group_sid;
4849 uint32 group_rid;
4850 uint32 acc_granted;
4851 SE_PRIV se_rights;
4852 bool can_add_accounts;
4853 DISP_INFO *disp_info = NULL;
4855 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4857 /* Find the policy handle. Open a policy on it. */
4858 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4859 return NT_STATUS_INVALID_HANDLE;
4861 status = access_check_samr_function(acc_granted,
4862 STD_RIGHT_DELETE_ACCESS,
4863 "_samr_DeleteDomainGroup");
4864 if (!NT_STATUS_IS_OK(status)) {
4865 return status;
4868 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4870 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4871 &group_rid)) {
4872 return NT_STATUS_NO_SUCH_GROUP;
4875 se_priv_copy( &se_rights, &se_add_users );
4876 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4878 /******** BEGIN SeAddUsers BLOCK *********/
4880 if ( can_add_accounts )
4881 become_root();
4883 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4885 if ( can_add_accounts )
4886 unbecome_root();
4888 /******** END SeAddUsers BLOCK *********/
4890 if ( !NT_STATUS_IS_OK(status) ) {
4891 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4892 "entry for group %s: %s\n",
4893 sid_string_dbg(&group_sid),
4894 nt_errstr(status)));
4895 return status;
4898 if (!close_policy_hnd(p, r->in.group_handle))
4899 return NT_STATUS_OBJECT_NAME_INVALID;
4901 force_flush_samr_cache(disp_info);
4903 return NT_STATUS_OK;
4906 /*********************************************************************
4907 _samr_DeleteDomAlias
4908 *********************************************************************/
4910 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4911 struct samr_DeleteDomAlias *r)
4913 DOM_SID alias_sid;
4914 uint32 acc_granted;
4915 SE_PRIV se_rights;
4916 bool can_add_accounts;
4917 NTSTATUS status;
4918 DISP_INFO *disp_info = NULL;
4920 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4922 /* Find the policy handle. Open a policy on it. */
4923 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4924 return NT_STATUS_INVALID_HANDLE;
4926 /* copy the handle to the outgoing reply */
4928 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4930 status = access_check_samr_function(acc_granted,
4931 STD_RIGHT_DELETE_ACCESS,
4932 "_samr_DeleteDomAlias");
4933 if (!NT_STATUS_IS_OK(status)) {
4934 return status;
4937 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4939 /* Don't let Windows delete builtin groups */
4941 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4942 return NT_STATUS_SPECIAL_ACCOUNT;
4945 if (!sid_check_is_in_our_domain(&alias_sid))
4946 return NT_STATUS_NO_SUCH_ALIAS;
4948 DEBUG(10, ("lookup on Local SID\n"));
4950 se_priv_copy( &se_rights, &se_add_users );
4951 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4953 /******** BEGIN SeAddUsers BLOCK *********/
4955 if ( can_add_accounts )
4956 become_root();
4958 /* Have passdb delete the alias */
4959 status = pdb_delete_alias(&alias_sid);
4961 if ( can_add_accounts )
4962 unbecome_root();
4964 /******** END SeAddUsers BLOCK *********/
4966 if ( !NT_STATUS_IS_OK(status))
4967 return status;
4969 if (!close_policy_hnd(p, r->in.alias_handle))
4970 return NT_STATUS_OBJECT_NAME_INVALID;
4972 force_flush_samr_cache(disp_info);
4974 return NT_STATUS_OK;
4977 /*********************************************************************
4978 _samr_CreateDomainGroup
4979 *********************************************************************/
4981 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4982 struct samr_CreateDomainGroup *r)
4985 NTSTATUS status;
4986 DOM_SID dom_sid;
4987 DOM_SID info_sid;
4988 const char *name;
4989 struct samr_info *info;
4990 uint32 acc_granted;
4991 SE_PRIV se_rights;
4992 bool can_add_accounts;
4993 DISP_INFO *disp_info = NULL;
4995 /* Find the policy handle. Open a policy on it. */
4996 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4997 return NT_STATUS_INVALID_HANDLE;
4999 status = access_check_samr_function(acc_granted,
5000 SAMR_DOMAIN_ACCESS_CREATE_GROUP,
5001 "_samr_CreateDomainGroup");
5002 if (!NT_STATUS_IS_OK(status)) {
5003 return status;
5006 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5007 return NT_STATUS_ACCESS_DENIED;
5009 name = r->in.name->string;
5010 if (name == NULL) {
5011 return NT_STATUS_NO_MEMORY;
5014 status = can_create(p->mem_ctx, name);
5015 if (!NT_STATUS_IS_OK(status)) {
5016 return status;
5019 se_priv_copy( &se_rights, &se_add_users );
5020 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5022 /******** BEGIN SeAddUsers BLOCK *********/
5024 if ( can_add_accounts )
5025 become_root();
5027 /* check that we successfully create the UNIX group */
5029 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5031 if ( can_add_accounts )
5032 unbecome_root();
5034 /******** END SeAddUsers BLOCK *********/
5036 /* check if we should bail out here */
5038 if ( !NT_STATUS_IS_OK(status) )
5039 return status;
5041 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5043 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5044 return NT_STATUS_NO_MEMORY;
5046 /* they created it; let the user do what he wants with it */
5048 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5050 /* get a (unique) handle. open a policy on it. */
5051 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5052 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5054 force_flush_samr_cache(disp_info);
5056 return NT_STATUS_OK;
5059 /*********************************************************************
5060 _samr_CreateDomAlias
5061 *********************************************************************/
5063 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5064 struct samr_CreateDomAlias *r)
5066 DOM_SID dom_sid;
5067 DOM_SID info_sid;
5068 const char *name = NULL;
5069 struct samr_info *info;
5070 uint32 acc_granted;
5071 gid_t gid;
5072 NTSTATUS result;
5073 SE_PRIV se_rights;
5074 bool can_add_accounts;
5075 DISP_INFO *disp_info = NULL;
5077 /* Find the policy handle. Open a policy on it. */
5078 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5079 return NT_STATUS_INVALID_HANDLE;
5081 result = access_check_samr_function(acc_granted,
5082 SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
5083 "_samr_CreateDomAlias");
5084 if (!NT_STATUS_IS_OK(result)) {
5085 return result;
5088 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5089 return NT_STATUS_ACCESS_DENIED;
5091 name = r->in.alias_name->string;
5093 se_priv_copy( &se_rights, &se_add_users );
5094 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5096 result = can_create(p->mem_ctx, name);
5097 if (!NT_STATUS_IS_OK(result)) {
5098 return result;
5101 /******** BEGIN SeAddUsers BLOCK *********/
5103 if ( can_add_accounts )
5104 become_root();
5106 /* Have passdb create the alias */
5107 result = pdb_create_alias(name, r->out.rid);
5109 if ( can_add_accounts )
5110 unbecome_root();
5112 /******** END SeAddUsers BLOCK *********/
5114 if (!NT_STATUS_IS_OK(result)) {
5115 DEBUG(10, ("pdb_create_alias failed: %s\n",
5116 nt_errstr(result)));
5117 return result;
5120 sid_copy(&info_sid, get_global_sam_sid());
5121 sid_append_rid(&info_sid, *r->out.rid);
5123 if (!sid_to_gid(&info_sid, &gid)) {
5124 DEBUG(10, ("Could not find alias just created\n"));
5125 return NT_STATUS_ACCESS_DENIED;
5128 /* check if the group has been successfully created */
5129 if ( getgrgid(gid) == NULL ) {
5130 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5131 gid));
5132 return NT_STATUS_ACCESS_DENIED;
5135 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5136 return NT_STATUS_NO_MEMORY;
5138 /* they created it; let the user do what he wants with it */
5140 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5142 /* get a (unique) handle. open a policy on it. */
5143 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5144 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5146 force_flush_samr_cache(disp_info);
5148 return NT_STATUS_OK;
5151 /*********************************************************************
5152 _samr_QueryGroupInfo
5153 *********************************************************************/
5155 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5156 struct samr_QueryGroupInfo *r)
5158 NTSTATUS status;
5159 DOM_SID group_sid;
5160 GROUP_MAP map;
5161 union samr_GroupInfo *info = NULL;
5162 uint32 acc_granted;
5163 bool ret;
5164 uint32_t attributes = SE_GROUP_MANDATORY |
5165 SE_GROUP_ENABLED_BY_DEFAULT |
5166 SE_GROUP_ENABLED;
5167 const char *group_name = NULL;
5168 const char *group_description = NULL;
5170 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5171 return NT_STATUS_INVALID_HANDLE;
5173 status = access_check_samr_function(acc_granted,
5174 SAMR_GROUP_ACCESS_LOOKUP_INFO,
5175 "_samr_QueryGroupInfo");
5176 if (!NT_STATUS_IS_OK(status)) {
5177 return status;
5180 become_root();
5181 ret = get_domain_group_from_sid(group_sid, &map);
5182 unbecome_root();
5183 if (!ret)
5184 return NT_STATUS_INVALID_HANDLE;
5186 /* FIXME: map contains fstrings */
5187 group_name = talloc_strdup(r, map.nt_name);
5188 group_description = talloc_strdup(r, map.comment);
5190 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5191 if (!info) {
5192 return NT_STATUS_NO_MEMORY;
5195 switch (r->in.level) {
5196 case 1: {
5197 uint32 *members;
5198 size_t num_members;
5200 become_root();
5201 status = pdb_enum_group_members(
5202 p->mem_ctx, &group_sid, &members, &num_members);
5203 unbecome_root();
5205 if (!NT_STATUS_IS_OK(status)) {
5206 return status;
5209 init_samr_group_info1(&info->all,
5210 group_name,
5211 attributes,
5212 num_members,
5213 group_description);
5214 break;
5216 case 2:
5217 init_samr_group_info2(&info->name,
5218 group_name);
5219 break;
5220 case 3:
5221 init_samr_group_info3(&info->attributes,
5222 attributes);
5223 break;
5224 case 4:
5225 init_samr_group_info4(&info->description,
5226 group_description);
5227 break;
5228 case 5: {
5230 uint32 *members;
5231 size_t num_members;
5235 become_root();
5236 status = pdb_enum_group_members(
5237 p->mem_ctx, &group_sid, &members, &num_members);
5238 unbecome_root();
5240 if (!NT_STATUS_IS_OK(status)) {
5241 return status;
5244 init_samr_group_info5(&info->all2,
5245 group_name,
5246 attributes,
5247 0, /* num_members - in w2k3 this is always 0 */
5248 group_description);
5250 break;
5252 default:
5253 return NT_STATUS_INVALID_INFO_CLASS;
5256 *r->out.info = info;
5258 return NT_STATUS_OK;
5261 /*********************************************************************
5262 _samr_SetGroupInfo
5263 *********************************************************************/
5265 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5266 struct samr_SetGroupInfo *r)
5268 DOM_SID group_sid;
5269 GROUP_MAP map;
5270 uint32 acc_granted;
5271 NTSTATUS status;
5272 bool ret;
5273 bool can_mod_accounts;
5274 DISP_INFO *disp_info = NULL;
5276 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5277 return NT_STATUS_INVALID_HANDLE;
5279 status = access_check_samr_function(acc_granted,
5280 SAMR_GROUP_ACCESS_SET_INFO,
5281 "_samr_SetGroupInfo");
5282 if (!NT_STATUS_IS_OK(status)) {
5283 return status;
5286 become_root();
5287 ret = get_domain_group_from_sid(group_sid, &map);
5288 unbecome_root();
5289 if (!ret)
5290 return NT_STATUS_NO_SUCH_GROUP;
5292 switch (r->in.level) {
5293 case 1:
5294 fstrcpy(map.comment, r->in.info->all.description.string);
5295 break;
5296 case 4:
5297 fstrcpy(map.comment, r->in.info->description.string);
5298 break;
5299 default:
5300 return NT_STATUS_INVALID_INFO_CLASS;
5303 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5305 /******** BEGIN SeAddUsers BLOCK *********/
5307 if ( can_mod_accounts )
5308 become_root();
5310 status = pdb_update_group_mapping_entry(&map);
5312 if ( can_mod_accounts )
5313 unbecome_root();
5315 /******** End SeAddUsers BLOCK *********/
5317 if (NT_STATUS_IS_OK(status)) {
5318 force_flush_samr_cache(disp_info);
5321 return status;
5324 /*********************************************************************
5325 _samr_SetAliasInfo
5326 *********************************************************************/
5328 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5329 struct samr_SetAliasInfo *r)
5331 DOM_SID group_sid;
5332 struct acct_info info;
5333 uint32 acc_granted;
5334 bool can_mod_accounts;
5335 NTSTATUS status;
5336 DISP_INFO *disp_info = NULL;
5338 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5339 return NT_STATUS_INVALID_HANDLE;
5341 status = access_check_samr_function(acc_granted,
5342 SAMR_ALIAS_ACCESS_SET_INFO,
5343 "_samr_SetAliasInfo");
5344 if (!NT_STATUS_IS_OK(status)) {
5345 return status;
5348 /* get the current group information */
5350 become_root();
5351 status = pdb_get_aliasinfo( &group_sid, &info );
5352 unbecome_root();
5354 if ( !NT_STATUS_IS_OK(status))
5355 return status;
5357 switch (r->in.level) {
5358 case ALIASINFONAME:
5360 fstring group_name;
5362 /* We currently do not support renaming groups in the
5363 the BUILTIN domain. Refer to util_builtin.c to understand
5364 why. The eventually needs to be fixed to be like Windows
5365 where you can rename builtin groups, just not delete them */
5367 if ( sid_check_is_in_builtin( &group_sid ) ) {
5368 return NT_STATUS_SPECIAL_ACCOUNT;
5371 /* There has to be a valid name (and it has to be different) */
5373 if ( !r->in.info->name.string )
5374 return NT_STATUS_INVALID_PARAMETER;
5376 /* If the name is the same just reply "ok". Yes this
5377 doesn't allow you to change the case of a group name. */
5379 if ( strequal( r->in.info->name.string, info.acct_name ) )
5380 return NT_STATUS_OK;
5382 fstrcpy( info.acct_name, r->in.info->name.string);
5384 /* make sure the name doesn't already exist as a user
5385 or local group */
5387 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5388 status = can_create( p->mem_ctx, group_name );
5389 if ( !NT_STATUS_IS_OK( status ) )
5390 return status;
5391 break;
5393 case ALIASINFODESCRIPTION:
5394 if (r->in.info->description.string) {
5395 fstrcpy(info.acct_desc,
5396 r->in.info->description.string);
5397 } else {
5398 fstrcpy( info.acct_desc, "" );
5400 break;
5401 default:
5402 return NT_STATUS_INVALID_INFO_CLASS;
5405 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5407 /******** BEGIN SeAddUsers BLOCK *********/
5409 if ( can_mod_accounts )
5410 become_root();
5412 status = pdb_set_aliasinfo( &group_sid, &info );
5414 if ( can_mod_accounts )
5415 unbecome_root();
5417 /******** End SeAddUsers BLOCK *********/
5419 if (NT_STATUS_IS_OK(status))
5420 force_flush_samr_cache(disp_info);
5422 return status;
5425 /****************************************************************
5426 _samr_GetDomPwInfo
5427 ****************************************************************/
5429 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5430 struct samr_GetDomPwInfo *r)
5432 uint32_t min_password_length = 0;
5433 uint32_t password_properties = 0;
5435 /* Perform access check. Since this rpc does not require a
5436 policy handle it will not be caught by the access checks on
5437 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5439 if (!pipe_access_check(p)) {
5440 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5441 return NT_STATUS_ACCESS_DENIED;
5444 become_root();
5445 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5446 &min_password_length);
5447 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5448 &password_properties);
5449 unbecome_root();
5451 if (lp_check_password_script() && *lp_check_password_script()) {
5452 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5455 r->out.info->min_password_length = min_password_length;
5456 r->out.info->password_properties = password_properties;
5458 return NT_STATUS_OK;
5461 /*********************************************************************
5462 _samr_OpenGroup
5463 *********************************************************************/
5465 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5466 struct samr_OpenGroup *r)
5469 DOM_SID sid;
5470 DOM_SID info_sid;
5471 GROUP_MAP map;
5472 struct samr_info *info;
5473 SEC_DESC *psd = NULL;
5474 uint32 acc_granted;
5475 uint32 des_access = r->in.access_mask;
5476 size_t sd_size;
5477 NTSTATUS status;
5478 fstring sid_string;
5479 bool ret;
5480 SE_PRIV se_rights;
5482 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5483 return NT_STATUS_INVALID_HANDLE;
5485 status = access_check_samr_function(acc_granted,
5486 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
5487 "_samr_OpenGroup");
5489 if ( !NT_STATUS_IS_OK(status) )
5490 return status;
5492 /*check if access can be granted as requested by client. */
5493 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
5495 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5496 se_map_generic(&des_access,&grp_generic_mapping);
5498 se_priv_copy( &se_rights, &se_add_users );
5500 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5501 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5502 &acc_granted, "_samr_OpenGroup");
5504 if ( !NT_STATUS_IS_OK(status) )
5505 return status;
5507 /* this should not be hard-coded like this */
5509 if (!sid_equal(&sid, get_global_sam_sid()))
5510 return NT_STATUS_ACCESS_DENIED;
5512 sid_copy(&info_sid, get_global_sam_sid());
5513 sid_append_rid(&info_sid, r->in.rid);
5514 sid_to_fstring(sid_string, &info_sid);
5516 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5517 return NT_STATUS_NO_MEMORY;
5519 info->acc_granted = acc_granted;
5521 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5523 /* check if that group really exists */
5524 become_root();
5525 ret = get_domain_group_from_sid(info->sid, &map);
5526 unbecome_root();
5527 if (!ret)
5528 return NT_STATUS_NO_SUCH_GROUP;
5530 /* get a (unique) handle. open a policy on it. */
5531 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5532 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5534 return NT_STATUS_OK;
5537 /*********************************************************************
5538 _samr_RemoveMemberFromForeignDomain
5539 *********************************************************************/
5541 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5542 struct samr_RemoveMemberFromForeignDomain *r)
5544 DOM_SID delete_sid, domain_sid;
5545 uint32 acc_granted;
5546 NTSTATUS result;
5547 DISP_INFO *disp_info = NULL;
5549 sid_copy( &delete_sid, r->in.sid );
5551 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5552 sid_string_dbg(&delete_sid)));
5554 /* Find the policy handle. Open a policy on it. */
5556 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5557 &acc_granted, &disp_info))
5558 return NT_STATUS_INVALID_HANDLE;
5560 result = access_check_samr_function(acc_granted,
5561 STD_RIGHT_DELETE_ACCESS,
5562 "_samr_RemoveMemberFromForeignDomain");
5564 if (!NT_STATUS_IS_OK(result))
5565 return result;
5567 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5568 sid_string_dbg(&domain_sid)));
5570 /* we can only delete a user from a group since we don't have
5571 nested groups anyways. So in the latter case, just say OK */
5573 /* TODO: The above comment nowadays is bogus. Since we have nested
5574 * groups now, and aliases members are never reported out of the unix
5575 * group membership, the "just say OK" makes this call a no-op. For
5576 * us. This needs fixing however. */
5578 /* I've only ever seen this in the wild when deleting a user from
5579 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5580 * is the user about to be deleted. I very much suspect this is the
5581 * only application of this call. To verify this, let people report
5582 * other cases. */
5584 if (!sid_check_is_builtin(&domain_sid)) {
5585 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5586 "global_sam_sid() = %s\n",
5587 sid_string_dbg(&domain_sid),
5588 sid_string_dbg(get_global_sam_sid())));
5589 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5590 return NT_STATUS_OK;
5593 force_flush_samr_cache(disp_info);
5595 result = NT_STATUS_OK;
5597 return result;
5600 /*******************************************************************
5601 _samr_QueryDomainInfo2
5602 ********************************************************************/
5604 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5605 struct samr_QueryDomainInfo2 *r)
5607 struct samr_QueryDomainInfo q;
5609 q.in.domain_handle = r->in.domain_handle;
5610 q.in.level = r->in.level;
5612 q.out.info = r->out.info;
5614 return _samr_QueryDomainInfo(p, &q);
5617 /*******************************************************************
5618 _samr_SetDomainInfo
5619 ********************************************************************/
5621 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5622 struct samr_SetDomainInfo *r)
5624 struct samr_info *info = NULL;
5625 time_t u_expire, u_min_age;
5626 time_t u_logout;
5627 time_t u_lock_duration, u_reset_time;
5628 NTSTATUS result;
5630 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5632 /* find the policy handle. open a policy on it. */
5633 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5634 return NT_STATUS_INVALID_HANDLE;
5636 /* We do have different access bits for info
5637 * levels here, but we're really just looking for
5638 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5639 * this maps to different specific bits. So
5640 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
5641 * set we are ok. */
5643 result = access_check_samr_function(info->acc_granted,
5644 SAMR_DOMAIN_ACCESS_SET_INFO_1,
5645 "_samr_SetDomainInfo");
5647 if (!NT_STATUS_IS_OK(result))
5648 return result;
5650 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5652 switch (r->in.level) {
5653 case 0x01:
5654 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5655 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5656 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5657 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5658 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5659 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5660 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5661 break;
5662 case 0x02:
5663 break;
5664 case 0x03:
5665 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5666 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5667 break;
5668 case 0x05:
5669 break;
5670 case 0x06:
5671 break;
5672 case 0x07:
5673 break;
5674 case 0x0c:
5675 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5676 if (u_lock_duration != -1)
5677 u_lock_duration /= 60;
5679 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5681 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5682 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5683 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5684 break;
5685 default:
5686 return NT_STATUS_INVALID_INFO_CLASS;
5689 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5691 return NT_STATUS_OK;
5694 /****************************************************************
5695 _samr_GetDisplayEnumerationIndex
5696 ****************************************************************/
5698 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5699 struct samr_GetDisplayEnumerationIndex *r)
5701 struct samr_info *info = NULL;
5702 uint32_t max_entries = (uint32_t) -1;
5703 uint32_t enum_context = 0;
5704 int i;
5705 uint32_t num_account = 0;
5706 struct samr_displayentry *entries = NULL;
5707 NTSTATUS status;
5709 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5711 /* find the policy handle. open a policy on it. */
5712 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5713 return NT_STATUS_INVALID_HANDLE;
5716 status = access_check_samr_function(info->acc_granted,
5717 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
5718 "_samr_GetDisplayEnumerationIndex");
5719 if (!NT_STATUS_IS_OK(status)) {
5720 return status;
5723 if ((r->in.level < 1) || (r->in.level > 3)) {
5724 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5725 "Unknown info level (%u)\n",
5726 r->in.level));
5727 return NT_STATUS_INVALID_INFO_CLASS;
5730 become_root();
5732 /* The following done as ROOT. Don't return without unbecome_root(). */
5734 switch (r->in.level) {
5735 case 1:
5736 if (info->disp_info->users == NULL) {
5737 info->disp_info->users = pdb_search_users(ACB_NORMAL);
5738 if (info->disp_info->users == NULL) {
5739 unbecome_root();
5740 return NT_STATUS_ACCESS_DENIED;
5742 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5743 "starting user enumeration at index %u\n",
5744 (unsigned int)enum_context));
5745 } else {
5746 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5747 "using cached user enumeration at index %u\n",
5748 (unsigned int)enum_context));
5750 num_account = pdb_search_entries(info->disp_info->users,
5751 enum_context, max_entries,
5752 &entries);
5753 break;
5754 case 2:
5755 if (info->disp_info->machines == NULL) {
5756 info->disp_info->machines =
5757 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5758 if (info->disp_info->machines == NULL) {
5759 unbecome_root();
5760 return NT_STATUS_ACCESS_DENIED;
5762 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5763 "starting machine enumeration at index %u\n",
5764 (unsigned int)enum_context));
5765 } else {
5766 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5767 "using cached machine enumeration at index %u\n",
5768 (unsigned int)enum_context));
5770 num_account = pdb_search_entries(info->disp_info->machines,
5771 enum_context, max_entries,
5772 &entries);
5773 break;
5774 case 3:
5775 if (info->disp_info->groups == NULL) {
5776 info->disp_info->groups = pdb_search_groups();
5777 if (info->disp_info->groups == NULL) {
5778 unbecome_root();
5779 return NT_STATUS_ACCESS_DENIED;
5781 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5782 "starting group enumeration at index %u\n",
5783 (unsigned int)enum_context));
5784 } else {
5785 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5786 "using cached group enumeration at index %u\n",
5787 (unsigned int)enum_context));
5789 num_account = pdb_search_entries(info->disp_info->groups,
5790 enum_context, max_entries,
5791 &entries);
5792 break;
5793 default:
5794 unbecome_root();
5795 smb_panic("info class changed");
5796 break;
5799 unbecome_root();
5801 /* Ensure we cache this enumeration. */
5802 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5804 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5805 r->in.name->string));
5807 for (i=0; i<num_account; i++) {
5808 if (strequal(entries[i].account_name, r->in.name->string)) {
5809 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5810 "found %s at idx %d\n",
5811 r->in.name->string, i));
5812 *r->out.idx = i;
5813 return NT_STATUS_OK;
5817 /* assuming account_name lives at the very end */
5818 *r->out.idx = num_account;
5820 return NT_STATUS_NO_MORE_ENTRIES;
5823 /****************************************************************
5824 _samr_GetDisplayEnumerationIndex2
5825 ****************************************************************/
5827 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5828 struct samr_GetDisplayEnumerationIndex2 *r)
5830 struct samr_GetDisplayEnumerationIndex q;
5832 q.in.domain_handle = r->in.domain_handle;
5833 q.in.level = r->in.level;
5834 q.in.name = r->in.name;
5836 q.out.idx = r->out.idx;
5838 return _samr_GetDisplayEnumerationIndex(p, &q);
5841 /****************************************************************
5842 ****************************************************************/
5844 NTSTATUS _samr_Shutdown(pipes_struct *p,
5845 struct samr_Shutdown *r)
5847 p->rng_fault_state = true;
5848 return NT_STATUS_NOT_IMPLEMENTED;
5851 /****************************************************************
5852 ****************************************************************/
5854 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5855 struct samr_SetMemberAttributesOfGroup *r)
5857 p->rng_fault_state = true;
5858 return NT_STATUS_NOT_IMPLEMENTED;
5861 /****************************************************************
5862 ****************************************************************/
5864 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5865 struct samr_ChangePasswordUser *r)
5867 p->rng_fault_state = true;
5868 return NT_STATUS_NOT_IMPLEMENTED;
5871 /****************************************************************
5872 ****************************************************************/
5874 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5875 struct samr_TestPrivateFunctionsDomain *r)
5877 p->rng_fault_state = true;
5878 return NT_STATUS_NOT_IMPLEMENTED;
5881 /****************************************************************
5882 ****************************************************************/
5884 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5885 struct samr_TestPrivateFunctionsUser *r)
5887 p->rng_fault_state = true;
5888 return NT_STATUS_NOT_IMPLEMENTED;
5891 /****************************************************************
5892 ****************************************************************/
5894 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5895 struct samr_AddMultipleMembersToAlias *r)
5897 p->rng_fault_state = true;
5898 return NT_STATUS_NOT_IMPLEMENTED;
5901 /****************************************************************
5902 ****************************************************************/
5904 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5905 struct samr_RemoveMultipleMembersFromAlias *r)
5907 p->rng_fault_state = true;
5908 return NT_STATUS_NOT_IMPLEMENTED;
5911 /****************************************************************
5912 ****************************************************************/
5914 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5915 struct samr_OemChangePasswordUser2 *r)
5917 p->rng_fault_state = true;
5918 return NT_STATUS_NOT_IMPLEMENTED;
5921 /****************************************************************
5922 ****************************************************************/
5924 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5925 struct samr_SetBootKeyInformation *r)
5927 p->rng_fault_state = true;
5928 return NT_STATUS_NOT_IMPLEMENTED;
5931 /****************************************************************
5932 ****************************************************************/
5934 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5935 struct samr_GetBootKeyInformation *r)
5937 p->rng_fault_state = true;
5938 return NT_STATUS_NOT_IMPLEMENTED;
5941 /****************************************************************
5942 ****************************************************************/
5944 NTSTATUS _samr_Connect3(pipes_struct *p,
5945 struct samr_Connect3 *r)
5947 p->rng_fault_state = true;
5948 return NT_STATUS_NOT_IMPLEMENTED;
5951 /****************************************************************
5952 ****************************************************************/
5954 NTSTATUS _samr_RidToSid(pipes_struct *p,
5955 struct samr_RidToSid *r)
5957 p->rng_fault_state = true;
5958 return NT_STATUS_NOT_IMPLEMENTED;
5961 /****************************************************************
5962 ****************************************************************/
5964 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5965 struct samr_SetDsrmPassword *r)
5967 p->rng_fault_state = true;
5968 return NT_STATUS_NOT_IMPLEMENTED;
5971 /****************************************************************
5972 ****************************************************************/
5974 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5975 struct samr_ValidatePassword *r)
5977 p->rng_fault_state = true;
5978 return NT_STATUS_NOT_IMPLEMENTED;