s3-samr-server: _samr_DeleteUser needs to wipe out the user_handle on success.
[Samba/bb.git] / source / rpc_server / srv_samr_nt.c
blob86e5d839c2ffb1dfa12fd03ca67d447b68382453
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
34 #include "includes.h"
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SA_RIGHT_USER_CHANGE_PASSWORD | \
42 SA_RIGHT_USER_SET_LOC_COM )
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 typedef struct disp_info {
49 DOM_SID sid; /* identify which domain this is. */
50 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
51 struct pdb_search *users; /* querydispinfo 1 and 4 */
52 struct pdb_search *machines; /* querydispinfo 2 */
53 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
54 struct pdb_search *aliases; /* enumaliases */
56 uint16 enum_acb_mask;
57 struct pdb_search *enum_users; /* enumusers with a mask */
59 struct timed_event *cache_timeout_event; /* cache idle timeout
60 * handler. */
61 } DISP_INFO;
63 /* We keep a static list of these by SID as modern clients close down
64 all resources between each request in a complete enumeration. */
66 struct samr_info {
67 /* for use by the \PIPE\samr policy */
68 DOM_SID sid;
69 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
70 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
71 uint32 acc_granted;
72 DISP_INFO *disp_info;
73 TALLOC_CTX *mem_ctx;
76 static const struct generic_mapping sam_generic_mapping = {
77 GENERIC_RIGHTS_SAM_READ,
78 GENERIC_RIGHTS_SAM_WRITE,
79 GENERIC_RIGHTS_SAM_EXECUTE,
80 GENERIC_RIGHTS_SAM_ALL_ACCESS};
81 static const struct generic_mapping dom_generic_mapping = {
82 GENERIC_RIGHTS_DOMAIN_READ,
83 GENERIC_RIGHTS_DOMAIN_WRITE,
84 GENERIC_RIGHTS_DOMAIN_EXECUTE,
85 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
86 static const struct generic_mapping usr_generic_mapping = {
87 GENERIC_RIGHTS_USER_READ,
88 GENERIC_RIGHTS_USER_WRITE,
89 GENERIC_RIGHTS_USER_EXECUTE,
90 GENERIC_RIGHTS_USER_ALL_ACCESS};
91 static const struct generic_mapping usr_nopwchange_generic_mapping = {
92 GENERIC_RIGHTS_USER_READ,
93 GENERIC_RIGHTS_USER_WRITE,
94 GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
95 GENERIC_RIGHTS_USER_ALL_ACCESS};
96 static const struct generic_mapping grp_generic_mapping = {
97 GENERIC_RIGHTS_GROUP_READ,
98 GENERIC_RIGHTS_GROUP_WRITE,
99 GENERIC_RIGHTS_GROUP_EXECUTE,
100 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
101 static const struct generic_mapping ali_generic_mapping = {
102 GENERIC_RIGHTS_ALIAS_READ,
103 GENERIC_RIGHTS_ALIAS_WRITE,
104 GENERIC_RIGHTS_ALIAS_EXECUTE,
105 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
107 /*******************************************************************
108 *******************************************************************/
110 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
111 const struct generic_mapping *map,
112 DOM_SID *sid, uint32 sid_access )
114 DOM_SID domadmin_sid;
115 SEC_ACE ace[5]; /* at most 5 entries */
116 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 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
190 goto done;
192 /* give root a free pass */
194 if ( geteuid() == sec_initial_uid() ) {
196 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
197 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
199 *acc_granted = des_access;
201 status = NT_STATUS_OK;
202 goto done;
206 done:
207 /* add in any bits saved during the privilege check (only
208 matters is status is ok) */
210 *acc_granted |= rights_mask;
212 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
213 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
214 des_access, *acc_granted));
216 return status;
219 /*******************************************************************
220 Checks if access to a function can be granted
221 ********************************************************************/
223 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
225 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
226 debug, acc_granted, acc_required));
228 /* check the security descriptor first */
230 if ( (acc_granted&acc_required) == acc_required )
231 return NT_STATUS_OK;
233 /* give root a free pass */
235 if (geteuid() == sec_initial_uid()) {
237 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
238 debug, acc_granted, acc_required));
239 DEBUGADD(4,("but overwritten by euid == 0\n"));
241 return NT_STATUS_OK;
244 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
245 debug, acc_granted, acc_required));
247 return NT_STATUS_ACCESS_DENIED;
250 /*******************************************************************
251 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
252 ********************************************************************/
254 static void map_max_allowed_access(const NT_USER_TOKEN *token,
255 uint32_t *pacc_requested)
257 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
258 return;
260 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
262 /* At least try for generic read. */
263 *pacc_requested = GENERIC_READ_ACCESS;
265 /* root gets anything. */
266 if (geteuid() == sec_initial_uid()) {
267 *pacc_requested |= GENERIC_ALL_ACCESS;
268 return;
271 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
273 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
274 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
275 *pacc_requested |= GENERIC_ALL_ACCESS;
276 return;
279 /* Full access for DOMAIN\Domain Admins. */
280 if ( IS_DC ) {
281 DOM_SID domadmin_sid;
282 sid_copy( &domadmin_sid, get_global_sam_sid() );
283 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
284 if (is_sid_in_token(token, &domadmin_sid)) {
285 *pacc_requested |= GENERIC_ALL_ACCESS;
286 return;
289 /* TODO ! Check privileges. */
292 /*******************************************************************
293 Fetch or create a dispinfo struct.
294 ********************************************************************/
296 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
299 * We do a static cache for DISP_INFO's here. Explanation can be found
300 * in Jeremy's checkin message to r11793:
302 * Fix the SAMR cache so it works across completely insane
303 * client behaviour (ie.:
304 * open pipe/open SAMR handle/enumerate 0 - 1024
305 * close SAMR handle, close pipe.
306 * open pipe/open SAMR handle/enumerate 1024 - 2048...
307 * close SAMR handle, close pipe.
308 * And on ad-nausium. Amazing.... probably object-oriented
309 * client side programming in action yet again.
310 * This change should *massively* improve performance when
311 * enumerating users from an LDAP database.
312 * Jeremy.
314 * "Our" and the builtin domain are the only ones where we ever
315 * enumerate stuff, so just cache 2 entries.
318 static struct disp_info builtin_dispinfo;
319 static struct disp_info domain_dispinfo;
321 /* There are two cases to consider here:
322 1) The SID is a domain SID and we look for an equality match, or
323 2) This is an account SID and so we return the DISP_INFO* for our
324 domain */
326 if (psid == NULL) {
327 return NULL;
330 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
332 * Necessary only once, but it does not really hurt.
334 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
336 return &builtin_dispinfo;
339 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
341 * Necessary only once, but it does not really hurt.
343 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
345 return &domain_dispinfo;
348 return NULL;
351 /*******************************************************************
352 Create a samr_info struct.
353 ********************************************************************/
355 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
357 struct samr_info *info;
358 fstring sid_str;
359 TALLOC_CTX *mem_ctx;
361 if (psid) {
362 sid_to_fstring(sid_str, psid);
363 } else {
364 fstrcpy(sid_str,"(NULL)");
367 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
369 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
370 return NULL;
372 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
373 if (psid) {
374 sid_copy( &info->sid, psid);
375 info->builtin_domain = sid_check_is_builtin(psid);
376 } else {
377 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
378 info->builtin_domain = False;
380 info->mem_ctx = mem_ctx;
382 info->disp_info = get_samr_dispinfo_by_sid(psid);
384 return info;
387 /*******************************************************************
388 Function to free the per SID data.
389 ********************************************************************/
391 static void free_samr_cache(DISP_INFO *disp_info)
393 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
394 sid_string_dbg(&disp_info->sid)));
396 /* We need to become root here because the paged search might have to
397 * tell the LDAP server we're not interested in the rest anymore. */
399 become_root();
401 if (disp_info->users) {
402 DEBUG(10,("free_samr_cache: deleting users cache\n"));
403 pdb_search_destroy(disp_info->users);
404 disp_info->users = NULL;
406 if (disp_info->machines) {
407 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
408 pdb_search_destroy(disp_info->machines);
409 disp_info->machines = NULL;
411 if (disp_info->groups) {
412 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
413 pdb_search_destroy(disp_info->groups);
414 disp_info->groups = NULL;
416 if (disp_info->aliases) {
417 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
418 pdb_search_destroy(disp_info->aliases);
419 disp_info->aliases = NULL;
421 if (disp_info->enum_users) {
422 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
423 pdb_search_destroy(disp_info->enum_users);
424 disp_info->enum_users = NULL;
426 disp_info->enum_acb_mask = 0;
428 unbecome_root();
431 /*******************************************************************
432 Function to free the per handle data.
433 ********************************************************************/
435 static void free_samr_info(void *ptr)
437 struct samr_info *info=(struct samr_info *) ptr;
439 /* Only free the dispinfo cache if no one bothered to set up
440 a timeout. */
442 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
443 free_samr_cache(info->disp_info);
446 talloc_destroy(info->mem_ctx);
449 /*******************************************************************
450 Idle event handler. Throw away the disp info cache.
451 ********************************************************************/
453 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
454 struct timed_event *te,
455 const struct timeval *now,
456 void *private_data)
458 DISP_INFO *disp_info = (DISP_INFO *)private_data;
460 TALLOC_FREE(disp_info->cache_timeout_event);
462 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
463 "out\n"));
464 free_samr_cache(disp_info);
467 /*******************************************************************
468 Setup cache removal idle event handler.
469 ********************************************************************/
471 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
473 /* Remove any pending timeout and update. */
475 TALLOC_FREE(disp_info->cache_timeout_event);
477 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
478 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
479 (unsigned int)secs_fromnow ));
481 disp_info->cache_timeout_event = event_add_timed(
482 smbd_event_context(), NULL,
483 timeval_current_ofs(secs_fromnow, 0),
484 "disp_info_cache_idle_timeout_handler",
485 disp_info_cache_idle_timeout_handler, (void *)disp_info);
488 /*******************************************************************
489 Force flush any cache. We do this on any samr_set_xxx call.
490 We must also remove the timeout handler.
491 ********************************************************************/
493 static void force_flush_samr_cache(DISP_INFO *disp_info)
495 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
496 return;
499 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
500 TALLOC_FREE(disp_info->cache_timeout_event);
501 free_samr_cache(disp_info);
504 /*******************************************************************
505 Ensure password info is never given out. Paranioa... JRA.
506 ********************************************************************/
508 static void samr_clear_sam_passwd(struct samu *sam_pass)
511 if (!sam_pass)
512 return;
514 /* These now zero out the old password */
516 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
517 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
520 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
522 struct samr_displayentry *entry;
524 if (info->builtin_domain) {
525 /* No users in builtin. */
526 return 0;
529 if (info->users == NULL) {
530 info->users = pdb_search_users(acct_flags);
531 if (info->users == NULL) {
532 return 0;
535 /* Fetch the last possible entry, thus trigger an enumeration */
536 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
538 /* Ensure we cache this enumeration. */
539 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
541 return info->users->num_entries;
544 static uint32 count_sam_groups(struct disp_info *info)
546 struct samr_displayentry *entry;
548 if (info->builtin_domain) {
549 /* No groups in builtin. */
550 return 0;
553 if (info->groups == NULL) {
554 info->groups = pdb_search_groups();
555 if (info->groups == NULL) {
556 return 0;
559 /* Fetch the last possible entry, thus trigger an enumeration */
560 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
562 /* Ensure we cache this enumeration. */
563 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
565 return info->groups->num_entries;
568 static uint32 count_sam_aliases(struct disp_info *info)
570 struct samr_displayentry *entry;
572 if (info->aliases == NULL) {
573 info->aliases = pdb_search_aliases(&info->sid);
574 if (info->aliases == NULL) {
575 return 0;
578 /* Fetch the last possible entry, thus trigger an enumeration */
579 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
581 /* Ensure we cache this enumeration. */
582 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
584 return info->aliases->num_entries;
587 /*******************************************************************
588 _samr_Close
589 ********************************************************************/
591 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
593 if (!close_policy_hnd(p, r->in.handle)) {
594 return NT_STATUS_INVALID_HANDLE;
597 ZERO_STRUCTP(r->out.handle);
599 return NT_STATUS_OK;
602 /*******************************************************************
603 _samr_OpenDomain
604 ********************************************************************/
606 NTSTATUS _samr_OpenDomain(pipes_struct *p,
607 struct samr_OpenDomain *r)
609 struct samr_info *info;
610 SEC_DESC *psd = NULL;
611 uint32 acc_granted;
612 uint32 des_access = r->in.access_mask;
613 NTSTATUS status;
614 size_t sd_size;
615 SE_PRIV se_rights;
617 /* find the connection policy handle. */
619 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
620 return NT_STATUS_INVALID_HANDLE;
622 status = access_check_samr_function(info->acc_granted,
623 SA_RIGHT_SAM_OPEN_DOMAIN,
624 "_samr_OpenDomain" );
626 if ( !NT_STATUS_IS_OK(status) )
627 return status;
629 /*check if access can be granted as requested by client. */
630 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
632 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
633 se_map_generic( &des_access, &dom_generic_mapping );
635 se_priv_copy( &se_rights, &se_machine_account );
636 se_priv_add( &se_rights, &se_add_users );
638 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
639 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
640 &acc_granted, "_samr_OpenDomain" );
642 if ( !NT_STATUS_IS_OK(status) )
643 return status;
645 if (!sid_check_is_domain(r->in.sid) &&
646 !sid_check_is_builtin(r->in.sid)) {
647 return NT_STATUS_NO_SUCH_DOMAIN;
650 /* associate the domain SID with the (unique) handle. */
651 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
652 return NT_STATUS_NO_MEMORY;
653 info->acc_granted = acc_granted;
655 /* get a (unique) handle. open a policy on it. */
656 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
657 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
659 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
661 return NT_STATUS_OK;
664 /*******************************************************************
665 _samr_GetUserPwInfo
666 ********************************************************************/
668 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
669 struct samr_GetUserPwInfo *r)
671 struct samr_info *info = NULL;
672 enum lsa_SidType sid_type;
673 uint32_t min_password_length = 0;
674 uint32_t password_properties = 0;
675 bool ret = false;
676 NTSTATUS status;
678 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
680 /* find the policy handle. open a policy on it. */
681 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
682 return NT_STATUS_INVALID_HANDLE;
685 status = access_check_samr_function(info->acc_granted,
686 SAMR_USER_ACCESS_GET_ATTRIBUTES,
687 "_samr_GetUserPwInfo" );
688 if (!NT_STATUS_IS_OK(status)) {
689 return status;
692 if (!sid_check_is_in_our_domain(&info->sid)) {
693 return NT_STATUS_OBJECT_TYPE_MISMATCH;
696 become_root();
697 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
698 unbecome_root();
699 if (ret == false) {
700 return NT_STATUS_NO_SUCH_USER;
703 switch (sid_type) {
704 case SID_NAME_USER:
705 become_root();
706 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
707 &min_password_length);
708 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
709 &password_properties);
710 unbecome_root();
712 if (lp_check_password_script() && *lp_check_password_script()) {
713 password_properties |= DOMAIN_PASSWORD_COMPLEX;
716 break;
717 default:
718 break;
721 r->out.info->min_password_length = min_password_length;
722 r->out.info->password_properties = password_properties;
724 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
726 return NT_STATUS_OK;
729 /*******************************************************************
730 ********************************************************************/
732 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
733 DOM_SID *sid, uint32 *acc_granted,
734 DISP_INFO **ppdisp_info)
736 struct samr_info *info = NULL;
738 /* find the policy handle. open a policy on it. */
739 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
740 return False;
742 if (!info)
743 return False;
745 *sid = info->sid;
746 *acc_granted = info->acc_granted;
747 if (ppdisp_info) {
748 *ppdisp_info = info->disp_info;
751 return True;
754 /*******************************************************************
755 _samr_SetSecurity
756 ********************************************************************/
758 NTSTATUS _samr_SetSecurity(pipes_struct *p,
759 struct samr_SetSecurity *r)
761 DOM_SID pol_sid;
762 uint32 acc_granted, i;
763 SEC_ACL *dacl;
764 bool ret;
765 struct samu *sampass=NULL;
766 NTSTATUS status;
768 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
769 return NT_STATUS_INVALID_HANDLE;
771 if (!(sampass = samu_new( p->mem_ctx))) {
772 DEBUG(0,("No memory!\n"));
773 return NT_STATUS_NO_MEMORY;
776 /* get the user record */
777 become_root();
778 ret = pdb_getsampwsid(sampass, &pol_sid);
779 unbecome_root();
781 if (!ret) {
782 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
783 TALLOC_FREE(sampass);
784 return NT_STATUS_INVALID_HANDLE;
787 dacl = r->in.sdbuf->sd->dacl;
788 for (i=0; i < dacl->num_aces; i++) {
789 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
790 ret = pdb_set_pass_can_change(sampass,
791 (dacl->aces[i].access_mask &
792 SA_RIGHT_USER_CHANGE_PASSWORD) ?
793 True: False);
794 break;
798 if (!ret) {
799 TALLOC_FREE(sampass);
800 return NT_STATUS_ACCESS_DENIED;
803 status = access_check_samr_function(acc_granted,
804 SA_RIGHT_USER_SET_ATTRIBUTES,
805 "_samr_SetSecurity");
806 if (NT_STATUS_IS_OK(status)) {
807 become_root();
808 status = pdb_update_sam_account(sampass);
809 unbecome_root();
812 TALLOC_FREE(sampass);
814 return status;
817 /*******************************************************************
818 build correct perms based on policies and password times for _samr_query_sec_obj
819 *******************************************************************/
820 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
822 struct samu *sampass=NULL;
823 bool ret;
825 if ( !(sampass = samu_new( mem_ctx )) ) {
826 DEBUG(0,("No memory!\n"));
827 return False;
830 become_root();
831 ret = pdb_getsampwsid(sampass, user_sid);
832 unbecome_root();
834 if (ret == False) {
835 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
836 TALLOC_FREE(sampass);
837 return False;
840 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
842 if (pdb_get_pass_can_change(sampass)) {
843 TALLOC_FREE(sampass);
844 return True;
846 TALLOC_FREE(sampass);
847 return False;
851 /*******************************************************************
852 _samr_QuerySecurity
853 ********************************************************************/
855 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
856 struct samr_QuerySecurity *r)
858 NTSTATUS status;
859 DOM_SID pol_sid;
860 SEC_DESC * psd = NULL;
861 uint32 acc_granted;
862 size_t sd_size;
864 /* Get the SID. */
865 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
866 return NT_STATUS_INVALID_HANDLE;
868 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
869 sid_string_dbg(&pol_sid)));
871 status = access_check_samr_function(acc_granted,
872 STD_RIGHT_READ_CONTROL_ACCESS,
873 "_samr_QuerySecurity");
874 if (!NT_STATUS_IS_OK(status)) {
875 return status;
878 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
880 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
881 if (pol_sid.sid_rev_num == 0) {
882 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
883 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
884 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
885 /* check if it is our domain SID */
886 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
887 "with SID: %s\n", sid_string_dbg(&pol_sid)));
888 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
889 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
890 /* check if it is the Builtin Domain */
891 /* TODO: Builtin probably needs a different SD with restricted write access*/
892 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
893 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
894 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
895 } else if (sid_check_is_in_our_domain(&pol_sid) ||
896 sid_check_is_in_builtin(&pol_sid)) {
897 /* TODO: different SDs have to be generated for aliases groups and users.
898 Currently all three get a default user SD */
899 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
900 "with SID: %s\n", sid_string_dbg(&pol_sid)));
901 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
902 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
903 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
904 } else {
905 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
906 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
908 } else {
909 return NT_STATUS_OBJECT_TYPE_MISMATCH;
912 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
913 return NT_STATUS_NO_MEMORY;
915 return status;
918 /*******************************************************************
919 makes a SAM_ENTRY / UNISTR2* structure from a user list.
920 ********************************************************************/
922 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
923 struct samr_SamEntry **sam_pp,
924 uint32_t num_entries,
925 uint32_t start_idx,
926 struct samr_displayentry *entries)
928 uint32_t i;
929 struct samr_SamEntry *sam;
931 *sam_pp = NULL;
933 if (num_entries == 0) {
934 return NT_STATUS_OK;
937 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
938 if (sam == NULL) {
939 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
940 return NT_STATUS_NO_MEMORY;
943 for (i = 0; i < num_entries; i++) {
944 #if 0
946 * usrmgr expects a non-NULL terminated string with
947 * trust relationships
949 if (entries[i].acct_flags & ACB_DOMTRUST) {
950 init_unistr2(&uni_temp_name, entries[i].account_name,
951 UNI_FLAGS_NONE);
952 } else {
953 init_unistr2(&uni_temp_name, entries[i].account_name,
954 UNI_STR_TERMINATE);
956 #endif
957 init_lsa_String(&sam[i].name, entries[i].account_name);
958 sam[i].idx = entries[i].rid;
961 *sam_pp = sam;
963 return NT_STATUS_OK;
966 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
968 /*******************************************************************
969 _samr_EnumDomainUsers
970 ********************************************************************/
972 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
973 struct samr_EnumDomainUsers *r)
975 NTSTATUS status;
976 struct samr_info *info = NULL;
977 int num_account;
978 uint32 enum_context = *r->in.resume_handle;
979 enum remote_arch_types ra_type = get_remote_arch();
980 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
981 uint32 max_entries = max_sam_entries;
982 struct samr_displayentry *entries = NULL;
983 struct samr_SamArray *samr_array = NULL;
984 struct samr_SamEntry *samr_entries = NULL;
986 /* find the policy handle. open a policy on it. */
987 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
988 return NT_STATUS_INVALID_HANDLE;
990 status = access_check_samr_function(info->acc_granted,
991 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
992 "_samr_EnumDomainUsers");
993 if (!NT_STATUS_IS_OK(status)) {
994 return status;
997 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
999 if (info->builtin_domain) {
1000 /* No users in builtin. */
1001 *r->out.resume_handle = *r->in.resume_handle;
1002 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
1003 return status;
1006 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1007 if (!samr_array) {
1008 return NT_STATUS_NO_MEMORY;
1011 become_root();
1013 /* AS ROOT !!!! */
1015 if ((info->disp_info->enum_users != NULL) &&
1016 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1017 pdb_search_destroy(info->disp_info->enum_users);
1018 info->disp_info->enum_users = NULL;
1021 if (info->disp_info->enum_users == NULL) {
1022 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
1023 info->disp_info->enum_acb_mask = r->in.acct_flags;
1026 if (info->disp_info->enum_users == NULL) {
1027 /* END AS ROOT !!!! */
1028 unbecome_root();
1029 return NT_STATUS_ACCESS_DENIED;
1032 num_account = pdb_search_entries(info->disp_info->enum_users,
1033 enum_context, max_entries,
1034 &entries);
1036 /* END AS ROOT !!!! */
1038 unbecome_root();
1040 if (num_account == 0) {
1041 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1042 "total entries\n"));
1043 *r->out.resume_handle = *r->in.resume_handle;
1044 return NT_STATUS_OK;
1047 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1048 num_account, enum_context,
1049 entries);
1050 if (!NT_STATUS_IS_OK(status)) {
1051 return status;
1054 if (max_entries <= num_account) {
1055 status = STATUS_MORE_ENTRIES;
1056 } else {
1057 status = NT_STATUS_OK;
1060 /* Ensure we cache this enumeration. */
1061 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1063 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1065 samr_array->count = num_account;
1066 samr_array->entries = samr_entries;
1068 *r->out.resume_handle = *r->in.resume_handle + num_account;
1069 *r->out.sam = samr_array;
1070 *r->out.num_entries = num_account;
1072 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1074 return status;
1077 /*******************************************************************
1078 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1079 ********************************************************************/
1081 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1082 struct samr_SamEntry **sam_pp,
1083 uint32_t num_sam_entries,
1084 struct samr_displayentry *entries)
1086 struct samr_SamEntry *sam;
1087 uint32_t i;
1089 *sam_pp = NULL;
1091 if (num_sam_entries == 0) {
1092 return;
1095 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1096 if (sam == NULL) {
1097 return;
1100 for (i = 0; i < num_sam_entries; i++) {
1102 * JRA. I think this should include the null. TNG does not.
1104 init_lsa_String(&sam[i].name, entries[i].account_name);
1105 sam[i].idx = entries[i].rid;
1108 *sam_pp = sam;
1111 /*******************************************************************
1112 _samr_EnumDomainGroups
1113 ********************************************************************/
1115 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1116 struct samr_EnumDomainGroups *r)
1118 NTSTATUS status;
1119 struct samr_info *info = NULL;
1120 struct samr_displayentry *groups;
1121 uint32 num_groups;
1122 struct samr_SamArray *samr_array = NULL;
1123 struct samr_SamEntry *samr_entries = NULL;
1125 /* find the policy handle. open a policy on it. */
1126 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1127 return NT_STATUS_INVALID_HANDLE;
1129 status = access_check_samr_function(info->acc_granted,
1130 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1131 "_samr_EnumDomainGroups");
1132 if (!NT_STATUS_IS_OK(status)) {
1133 return status;
1136 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1138 if (info->builtin_domain) {
1139 /* No groups in builtin. */
1140 *r->out.resume_handle = *r->in.resume_handle;
1141 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1142 return status;
1145 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1146 if (!samr_array) {
1147 return NT_STATUS_NO_MEMORY;
1150 /* the domain group array is being allocated in the function below */
1152 become_root();
1154 if (info->disp_info->groups == NULL) {
1155 info->disp_info->groups = pdb_search_groups();
1157 if (info->disp_info->groups == NULL) {
1158 unbecome_root();
1159 return NT_STATUS_ACCESS_DENIED;
1163 num_groups = pdb_search_entries(info->disp_info->groups,
1164 *r->in.resume_handle,
1165 MAX_SAM_ENTRIES, &groups);
1166 unbecome_root();
1168 /* Ensure we cache this enumeration. */
1169 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1171 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1172 num_groups, groups);
1174 samr_array->count = num_groups;
1175 samr_array->entries = samr_entries;
1177 *r->out.sam = samr_array;
1178 *r->out.num_entries = num_groups;
1179 /* this was missing, IMHO:
1180 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1183 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1185 return status;
1188 /*******************************************************************
1189 _samr_EnumDomainAliases
1190 ********************************************************************/
1192 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1193 struct samr_EnumDomainAliases *r)
1195 NTSTATUS status;
1196 struct samr_info *info;
1197 struct samr_displayentry *aliases;
1198 uint32 num_aliases = 0;
1199 struct samr_SamArray *samr_array = NULL;
1200 struct samr_SamEntry *samr_entries = NULL;
1202 /* find the policy handle. open a policy on it. */
1203 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1204 return NT_STATUS_INVALID_HANDLE;
1206 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1207 sid_string_dbg(&info->sid)));
1209 status = access_check_samr_function(info->acc_granted,
1210 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1211 "_samr_EnumDomainAliases");
1212 if (!NT_STATUS_IS_OK(status)) {
1213 return status;
1216 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1217 if (!samr_array) {
1218 return NT_STATUS_NO_MEMORY;
1221 become_root();
1223 if (info->disp_info->aliases == NULL) {
1224 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1225 if (info->disp_info->aliases == NULL) {
1226 unbecome_root();
1227 return NT_STATUS_ACCESS_DENIED;
1231 num_aliases = pdb_search_entries(info->disp_info->aliases,
1232 *r->in.resume_handle,
1233 MAX_SAM_ENTRIES, &aliases);
1234 unbecome_root();
1236 /* Ensure we cache this enumeration. */
1237 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1239 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1240 num_aliases, aliases);
1242 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1244 samr_array->count = num_aliases;
1245 samr_array->entries = samr_entries;
1247 *r->out.sam = samr_array;
1248 *r->out.num_entries = num_aliases;
1249 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1251 return status;
1254 /*******************************************************************
1255 inits a samr_DispInfoGeneral structure.
1256 ********************************************************************/
1258 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1259 struct samr_DispInfoGeneral *r,
1260 uint32_t num_entries,
1261 uint32_t start_idx,
1262 struct samr_displayentry *entries)
1264 uint32 i;
1266 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1268 if (num_entries == 0) {
1269 return NT_STATUS_OK;
1272 r->count = num_entries;
1274 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1275 if (!r->entries) {
1276 return NT_STATUS_NO_MEMORY;
1279 for (i = 0; i < num_entries ; i++) {
1281 init_lsa_String(&r->entries[i].account_name,
1282 entries[i].account_name);
1284 init_lsa_String(&r->entries[i].description,
1285 entries[i].description);
1287 init_lsa_String(&r->entries[i].full_name,
1288 entries[i].fullname);
1290 r->entries[i].rid = entries[i].rid;
1291 r->entries[i].acct_flags = entries[i].acct_flags;
1292 r->entries[i].idx = start_idx+i+1;
1295 return NT_STATUS_OK;
1298 /*******************************************************************
1299 inits a samr_DispInfoFull structure.
1300 ********************************************************************/
1302 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1303 struct samr_DispInfoFull *r,
1304 uint32_t num_entries,
1305 uint32_t start_idx,
1306 struct samr_displayentry *entries)
1308 uint32_t i;
1310 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1312 if (num_entries == 0) {
1313 return NT_STATUS_OK;
1316 r->count = num_entries;
1318 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1319 if (!r->entries) {
1320 return NT_STATUS_NO_MEMORY;
1323 for (i = 0; i < num_entries ; i++) {
1325 init_lsa_String(&r->entries[i].account_name,
1326 entries[i].account_name);
1328 init_lsa_String(&r->entries[i].description,
1329 entries[i].description);
1331 r->entries[i].rid = entries[i].rid;
1332 r->entries[i].acct_flags = entries[i].acct_flags;
1333 r->entries[i].idx = start_idx+i+1;
1336 return NT_STATUS_OK;
1339 /*******************************************************************
1340 inits a samr_DispInfoFullGroups structure.
1341 ********************************************************************/
1343 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1344 struct samr_DispInfoFullGroups *r,
1345 uint32_t num_entries,
1346 uint32_t start_idx,
1347 struct samr_displayentry *entries)
1349 uint32_t i;
1351 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1353 if (num_entries == 0) {
1354 return NT_STATUS_OK;
1357 r->count = num_entries;
1359 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1360 if (!r->entries) {
1361 return NT_STATUS_NO_MEMORY;
1364 for (i = 0; i < num_entries ; i++) {
1366 init_lsa_String(&r->entries[i].account_name,
1367 entries[i].account_name);
1369 init_lsa_String(&r->entries[i].description,
1370 entries[i].description);
1372 r->entries[i].rid = entries[i].rid;
1373 r->entries[i].acct_flags = entries[i].acct_flags;
1374 r->entries[i].idx = start_idx+i+1;
1377 return NT_STATUS_OK;
1380 /*******************************************************************
1381 inits a samr_DispInfoAscii structure.
1382 ********************************************************************/
1384 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1385 struct samr_DispInfoAscii *r,
1386 uint32_t num_entries,
1387 uint32_t start_idx,
1388 struct samr_displayentry *entries)
1390 uint32_t i;
1392 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1394 if (num_entries == 0) {
1395 return NT_STATUS_OK;
1398 r->count = num_entries;
1400 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1401 if (!r->entries) {
1402 return NT_STATUS_NO_MEMORY;
1405 for (i = 0; i < num_entries ; i++) {
1407 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1408 entries[i].account_name);
1410 r->entries[i].idx = start_idx+i+1;
1413 return NT_STATUS_OK;
1416 /*******************************************************************
1417 inits a samr_DispInfoAscii structure.
1418 ********************************************************************/
1420 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1421 struct samr_DispInfoAscii *r,
1422 uint32_t num_entries,
1423 uint32_t start_idx,
1424 struct samr_displayentry *entries)
1426 uint32_t i;
1428 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1430 if (num_entries == 0) {
1431 return NT_STATUS_OK;
1434 r->count = num_entries;
1436 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1437 if (!r->entries) {
1438 return NT_STATUS_NO_MEMORY;
1441 for (i = 0; i < num_entries ; i++) {
1443 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1444 entries[i].account_name);
1446 r->entries[i].idx = start_idx+i+1;
1449 return NT_STATUS_OK;
1452 /*******************************************************************
1453 _samr_QueryDisplayInfo
1454 ********************************************************************/
1456 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1457 struct samr_QueryDisplayInfo *r)
1459 NTSTATUS status;
1460 struct samr_info *info = NULL;
1461 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1463 uint32 max_entries = r->in.max_entries;
1464 uint32 enum_context = r->in.start_idx;
1465 uint32 max_size = r->in.buf_size;
1467 union samr_DispInfo *disp_info = r->out.info;
1469 uint32 temp_size=0, total_data_size=0;
1470 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1471 uint32 num_account = 0;
1472 enum remote_arch_types ra_type = get_remote_arch();
1473 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1474 struct samr_displayentry *entries = NULL;
1476 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1478 /* find the policy handle. open a policy on it. */
1479 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1480 return NT_STATUS_INVALID_HANDLE;
1482 status = access_check_samr_function(info->acc_granted,
1483 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1484 "_samr_QueryDisplayInfo");
1485 if (!NT_STATUS_IS_OK(status)) {
1486 return status;
1490 * calculate how many entries we will return.
1491 * based on
1492 * - the number of entries the client asked
1493 * - our limit on that
1494 * - the starting point (enumeration context)
1495 * - the buffer size the client will accept
1499 * We are a lot more like W2K. Instead of reading the SAM
1500 * each time to find the records we need to send back,
1501 * we read it once and link that copy to the sam handle.
1502 * For large user list (over the MAX_SAM_ENTRIES)
1503 * it's a definitive win.
1504 * second point to notice: between enumerations
1505 * our sam is now the same as it's a snapshoot.
1506 * third point: got rid of the static SAM_USER_21 struct
1507 * no more intermediate.
1508 * con: it uses much more memory, as a full copy is stored
1509 * in memory.
1511 * If you want to change it, think twice and think
1512 * of the second point , that's really important.
1514 * JFM, 12/20/2001
1517 if ((r->in.level < 1) || (r->in.level > 5)) {
1518 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1519 (unsigned int)r->in.level ));
1520 return NT_STATUS_INVALID_INFO_CLASS;
1523 /* first limit the number of entries we will return */
1524 if(max_entries > max_sam_entries) {
1525 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1526 "entries, limiting to %d\n", max_entries,
1527 max_sam_entries));
1528 max_entries = max_sam_entries;
1531 /* calculate the size and limit on the number of entries we will
1532 * return */
1534 temp_size=max_entries*struct_size;
1536 if (temp_size>max_size) {
1537 max_entries=MIN((max_size/struct_size),max_entries);;
1538 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1539 "only %d entries\n", max_entries));
1542 become_root();
1544 /* THe following done as ROOT. Don't return without unbecome_root(). */
1546 switch (r->in.level) {
1547 case 0x1:
1548 case 0x4:
1549 if (info->disp_info->users == NULL) {
1550 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1551 if (info->disp_info->users == NULL) {
1552 unbecome_root();
1553 return NT_STATUS_ACCESS_DENIED;
1555 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1556 (unsigned int)enum_context ));
1557 } else {
1558 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1559 (unsigned int)enum_context ));
1562 num_account = pdb_search_entries(info->disp_info->users,
1563 enum_context, max_entries,
1564 &entries);
1565 break;
1566 case 0x2:
1567 if (info->disp_info->machines == NULL) {
1568 info->disp_info->machines =
1569 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1570 if (info->disp_info->machines == NULL) {
1571 unbecome_root();
1572 return NT_STATUS_ACCESS_DENIED;
1574 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1575 (unsigned int)enum_context ));
1576 } else {
1577 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1578 (unsigned int)enum_context ));
1581 num_account = pdb_search_entries(info->disp_info->machines,
1582 enum_context, max_entries,
1583 &entries);
1584 break;
1585 case 0x3:
1586 case 0x5:
1587 if (info->disp_info->groups == NULL) {
1588 info->disp_info->groups = pdb_search_groups();
1589 if (info->disp_info->groups == NULL) {
1590 unbecome_root();
1591 return NT_STATUS_ACCESS_DENIED;
1593 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1594 (unsigned int)enum_context ));
1595 } else {
1596 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1597 (unsigned int)enum_context ));
1600 num_account = pdb_search_entries(info->disp_info->groups,
1601 enum_context, max_entries,
1602 &entries);
1603 break;
1604 default:
1605 unbecome_root();
1606 smb_panic("info class changed");
1607 break;
1609 unbecome_root();
1612 /* Now create reply structure */
1613 switch (r->in.level) {
1614 case 0x1:
1615 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1616 num_account, enum_context,
1617 entries);
1618 break;
1619 case 0x2:
1620 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1621 num_account, enum_context,
1622 entries);
1623 break;
1624 case 0x3:
1625 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1626 num_account, enum_context,
1627 entries);
1628 break;
1629 case 0x4:
1630 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1631 num_account, enum_context,
1632 entries);
1633 break;
1634 case 0x5:
1635 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1636 num_account, enum_context,
1637 entries);
1638 break;
1639 default:
1640 smb_panic("info class changed");
1641 break;
1644 if (!NT_STATUS_IS_OK(disp_ret))
1645 return disp_ret;
1647 /* calculate the total size */
1648 total_data_size=num_account*struct_size;
1650 if (num_account) {
1651 status = STATUS_MORE_ENTRIES;
1652 } else {
1653 status = NT_STATUS_OK;
1656 /* Ensure we cache this enumeration. */
1657 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1659 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1661 *r->out.total_size = total_data_size;
1662 *r->out.returned_size = temp_size;
1664 return status;
1667 /****************************************************************
1668 _samr_QueryDisplayInfo2
1669 ****************************************************************/
1671 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1672 struct samr_QueryDisplayInfo2 *r)
1674 struct samr_QueryDisplayInfo q;
1676 q.in.domain_handle = r->in.domain_handle;
1677 q.in.level = r->in.level;
1678 q.in.start_idx = r->in.start_idx;
1679 q.in.max_entries = r->in.max_entries;
1680 q.in.buf_size = r->in.buf_size;
1682 q.out.total_size = r->out.total_size;
1683 q.out.returned_size = r->out.returned_size;
1684 q.out.info = r->out.info;
1686 return _samr_QueryDisplayInfo(p, &q);
1689 /****************************************************************
1690 _samr_QueryDisplayInfo3
1691 ****************************************************************/
1693 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1694 struct samr_QueryDisplayInfo3 *r)
1696 struct samr_QueryDisplayInfo q;
1698 q.in.domain_handle = r->in.domain_handle;
1699 q.in.level = r->in.level;
1700 q.in.start_idx = r->in.start_idx;
1701 q.in.max_entries = r->in.max_entries;
1702 q.in.buf_size = r->in.buf_size;
1704 q.out.total_size = r->out.total_size;
1705 q.out.returned_size = r->out.returned_size;
1706 q.out.info = r->out.info;
1708 return _samr_QueryDisplayInfo(p, &q);
1711 /*******************************************************************
1712 _samr_QueryAliasInfo
1713 ********************************************************************/
1715 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1716 struct samr_QueryAliasInfo *r)
1718 DOM_SID sid;
1719 struct acct_info info;
1720 uint32 acc_granted;
1721 NTSTATUS status;
1722 union samr_AliasInfo *alias_info = NULL;
1723 const char *alias_name = NULL;
1724 const char *alias_description = NULL;
1726 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1728 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1729 if (!alias_info) {
1730 return NT_STATUS_NO_MEMORY;
1733 /* find the policy handle. open a policy on it. */
1734 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1735 return NT_STATUS_INVALID_HANDLE;
1737 status = access_check_samr_function(acc_granted,
1738 SA_RIGHT_ALIAS_LOOKUP_INFO,
1739 "_samr_QueryAliasInfo");
1740 if (!NT_STATUS_IS_OK(status)) {
1741 return status;
1744 become_root();
1745 status = pdb_get_aliasinfo(&sid, &info);
1746 unbecome_root();
1748 if ( !NT_STATUS_IS_OK(status))
1749 return status;
1751 /* FIXME: info contains fstrings */
1752 alias_name = talloc_strdup(r, info.acct_name);
1753 alias_description = talloc_strdup(r, info.acct_desc);
1755 switch (r->in.level) {
1756 case ALIASINFOALL:
1757 init_samr_alias_info1(&alias_info->all,
1758 alias_name,
1760 alias_description);
1761 break;
1762 case ALIASINFODESCRIPTION:
1763 init_samr_alias_info3(&alias_info->description,
1764 alias_description);
1765 break;
1766 default:
1767 return NT_STATUS_INVALID_INFO_CLASS;
1770 *r->out.info = alias_info;
1772 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1774 return NT_STATUS_OK;
1777 #if 0
1778 /*******************************************************************
1779 samr_reply_lookup_ids
1780 ********************************************************************/
1782 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1784 uint32 rid[MAX_SAM_ENTRIES];
1785 int num_rids = q_u->num_sids1;
1787 r_u->status = NT_STATUS_OK;
1789 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1791 if (num_rids > MAX_SAM_ENTRIES) {
1792 num_rids = MAX_SAM_ENTRIES;
1793 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1796 #if 0
1797 int i;
1798 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1800 for (i = 0; i < num_rids && status == 0; i++)
1802 struct sam_passwd *sam_pass;
1803 fstring user_name;
1806 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1807 q_u->uni_user_name[i].uni_str_len));
1809 /* find the user account */
1810 become_root();
1811 sam_pass = get_smb21pwd_entry(user_name, 0);
1812 unbecome_root();
1814 if (sam_pass == NULL)
1816 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1817 rid[i] = 0;
1819 else
1821 rid[i] = sam_pass->user_rid;
1824 #endif
1826 num_rids = 1;
1827 rid[0] = BUILTIN_ALIAS_RID_USERS;
1829 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1831 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1833 return r_u->status;
1835 #endif
1837 /*******************************************************************
1838 _samr_LookupNames
1839 ********************************************************************/
1841 NTSTATUS _samr_LookupNames(pipes_struct *p,
1842 struct samr_LookupNames *r)
1844 NTSTATUS status;
1845 uint32 *rid;
1846 enum lsa_SidType *type;
1847 int i;
1848 int num_rids = r->in.num_names;
1849 DOM_SID pol_sid;
1850 uint32 acc_granted;
1851 struct samr_Ids rids, types;
1853 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1855 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1856 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1859 status = access_check_samr_function(acc_granted,
1860 0, /* Don't know the acc_bits yet */
1861 "_samr_LookupNames");
1862 if (!NT_STATUS_IS_OK(status)) {
1863 return status;
1866 if (num_rids > MAX_SAM_ENTRIES) {
1867 num_rids = MAX_SAM_ENTRIES;
1868 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1871 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1872 NT_STATUS_HAVE_NO_MEMORY(rid);
1874 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1875 NT_STATUS_HAVE_NO_MEMORY(type);
1877 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1878 sid_string_dbg(&pol_sid)));
1880 for (i = 0; i < num_rids; i++) {
1882 status = NT_STATUS_NONE_MAPPED;
1883 type[i] = SID_NAME_UNKNOWN;
1885 rid[i] = 0xffffffff;
1887 if (sid_check_is_builtin(&pol_sid)) {
1888 if (lookup_builtin_name(r->in.names[i].string,
1889 &rid[i]))
1891 type[i] = SID_NAME_ALIAS;
1893 } else {
1894 lookup_global_sam_name(r->in.names[i].string, 0,
1895 &rid[i], &type[i]);
1898 if (type[i] != SID_NAME_UNKNOWN) {
1899 status = NT_STATUS_OK;
1903 rids.count = num_rids;
1904 rids.ids = rid;
1906 types.count = num_rids;
1907 types.ids = type;
1909 *r->out.rids = rids;
1910 *r->out.types = types;
1912 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1914 return status;
1917 /*******************************************************************
1918 _samr_ChangePasswordUser2
1919 ********************************************************************/
1921 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1922 struct samr_ChangePasswordUser2 *r)
1924 NTSTATUS status;
1925 fstring user_name;
1926 fstring wks;
1928 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1930 fstrcpy(user_name, r->in.account->string);
1931 fstrcpy(wks, r->in.server->string);
1933 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1936 * Pass the user through the NT -> unix user mapping
1937 * function.
1940 (void)map_username(user_name);
1943 * UNIX username case mangling not required, pass_oem_change
1944 * is case insensitive.
1947 status = pass_oem_change(user_name,
1948 r->in.lm_password->data,
1949 r->in.lm_verifier->hash,
1950 r->in.nt_password->data,
1951 r->in.nt_verifier->hash,
1952 NULL);
1954 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1956 return status;
1959 /*******************************************************************
1960 _samr_ChangePasswordUser3
1961 ********************************************************************/
1963 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1964 struct samr_ChangePasswordUser3 *r)
1966 NTSTATUS status;
1967 fstring user_name;
1968 const char *wks = NULL;
1969 uint32 reject_reason;
1970 struct samr_DomInfo1 *dominfo = NULL;
1971 struct samr_ChangeReject *reject = NULL;
1973 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1975 fstrcpy(user_name, r->in.account->string);
1976 if (r->in.server && r->in.server->string) {
1977 wks = r->in.server->string;
1980 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1983 * Pass the user through the NT -> unix user mapping
1984 * function.
1987 (void)map_username(user_name);
1990 * UNIX username case mangling not required, pass_oem_change
1991 * is case insensitive.
1994 status = pass_oem_change(user_name,
1995 r->in.lm_password->data,
1996 r->in.lm_verifier->hash,
1997 r->in.nt_password->data,
1998 r->in.nt_verifier->hash,
1999 &reject_reason);
2001 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2002 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2004 uint32 min_pass_len,pass_hist,password_properties;
2005 time_t u_expire, u_min_age;
2006 NTTIME nt_expire, nt_min_age;
2007 uint32 account_policy_temp;
2009 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2010 if (!dominfo) {
2011 return NT_STATUS_NO_MEMORY;
2014 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2015 if (!reject) {
2016 return NT_STATUS_NO_MEMORY;
2019 become_root();
2021 /* AS ROOT !!! */
2023 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2024 min_pass_len = account_policy_temp;
2026 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2027 pass_hist = account_policy_temp;
2029 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2030 password_properties = account_policy_temp;
2032 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2033 u_expire = account_policy_temp;
2035 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2036 u_min_age = account_policy_temp;
2038 /* !AS ROOT */
2040 unbecome_root();
2042 unix_to_nt_time_abs(&nt_expire, u_expire);
2043 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2045 if (lp_check_password_script() && *lp_check_password_script()) {
2046 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2049 init_samr_DomInfo1(dominfo,
2050 min_pass_len,
2051 pass_hist,
2052 password_properties,
2053 u_expire,
2054 u_min_age);
2056 reject->reason = reject_reason;
2058 *r->out.dominfo = dominfo;
2059 *r->out.reject = reject;
2062 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2064 return status;
2067 /*******************************************************************
2068 makes a SAMR_R_LOOKUP_RIDS structure.
2069 ********************************************************************/
2071 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2072 const char **names,
2073 struct lsa_String **lsa_name_array_p)
2075 struct lsa_String *lsa_name_array = NULL;
2076 uint32_t i;
2078 *lsa_name_array_p = NULL;
2080 if (num_names != 0) {
2081 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2082 if (!lsa_name_array) {
2083 return false;
2087 for (i = 0; i < num_names; i++) {
2088 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2089 init_lsa_String(&lsa_name_array[i], names[i]);
2092 *lsa_name_array_p = lsa_name_array;
2094 return true;
2097 /*******************************************************************
2098 _samr_LookupRids
2099 ********************************************************************/
2101 NTSTATUS _samr_LookupRids(pipes_struct *p,
2102 struct samr_LookupRids *r)
2104 NTSTATUS status;
2105 const char **names;
2106 enum lsa_SidType *attrs = NULL;
2107 uint32 *wire_attrs = NULL;
2108 DOM_SID pol_sid;
2109 int num_rids = (int)r->in.num_rids;
2110 uint32 acc_granted;
2111 int i;
2112 struct lsa_Strings names_array;
2113 struct samr_Ids types_array;
2114 struct lsa_String *lsa_names = NULL;
2116 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2118 /* find the policy handle. open a policy on it. */
2119 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2120 return NT_STATUS_INVALID_HANDLE;
2122 status = access_check_samr_function(acc_granted,
2123 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
2124 "_samr__LookupRids");
2125 if (!NT_STATUS_IS_OK(status)) {
2126 return status;
2129 if (num_rids > 1000) {
2130 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2131 "to samba4 idl this is not possible\n", num_rids));
2132 return NT_STATUS_UNSUCCESSFUL;
2135 if (num_rids) {
2136 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2137 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2138 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2140 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2141 return NT_STATUS_NO_MEMORY;
2142 } else {
2143 names = NULL;
2144 attrs = NULL;
2145 wire_attrs = NULL;
2148 become_root(); /* lookup_sid can require root privs */
2149 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2150 names, attrs);
2151 unbecome_root();
2153 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2154 status = NT_STATUS_OK;
2157 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2158 &lsa_names)) {
2159 return NT_STATUS_NO_MEMORY;
2162 /* Convert from enum lsa_SidType to uint32 for wire format. */
2163 for (i = 0; i < num_rids; i++) {
2164 wire_attrs[i] = (uint32)attrs[i];
2167 names_array.count = num_rids;
2168 names_array.names = lsa_names;
2170 types_array.count = num_rids;
2171 types_array.ids = wire_attrs;
2173 *r->out.names = names_array;
2174 *r->out.types = types_array;
2176 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2178 return status;
2181 /*******************************************************************
2182 _samr_OpenUser
2183 ********************************************************************/
2185 NTSTATUS _samr_OpenUser(pipes_struct *p,
2186 struct samr_OpenUser *r)
2188 struct samu *sampass=NULL;
2189 DOM_SID sid;
2190 POLICY_HND domain_pol = *r->in.domain_handle;
2191 POLICY_HND *user_pol = r->out.user_handle;
2192 struct samr_info *info = NULL;
2193 SEC_DESC *psd = NULL;
2194 uint32 acc_granted;
2195 uint32 des_access = r->in.access_mask;
2196 size_t sd_size;
2197 bool ret;
2198 NTSTATUS nt_status;
2199 SE_PRIV se_rights;
2201 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2203 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2204 return NT_STATUS_INVALID_HANDLE;
2206 nt_status = access_check_samr_function(acc_granted,
2207 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2208 "_samr_OpenUser" );
2210 if ( !NT_STATUS_IS_OK(nt_status) )
2211 return nt_status;
2213 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2214 return NT_STATUS_NO_MEMORY;
2217 /* append the user's RID to it */
2219 if (!sid_append_rid(&sid, r->in.rid))
2220 return NT_STATUS_NO_SUCH_USER;
2222 /* check if access can be granted as requested by client. */
2224 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
2226 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2227 se_map_generic(&des_access, &usr_generic_mapping);
2229 se_priv_copy( &se_rights, &se_machine_account );
2230 se_priv_add( &se_rights, &se_add_users );
2232 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2233 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2234 &acc_granted, "_samr_OpenUser");
2236 if ( !NT_STATUS_IS_OK(nt_status) )
2237 return nt_status;
2239 become_root();
2240 ret=pdb_getsampwsid(sampass, &sid);
2241 unbecome_root();
2243 /* check that the SID exists in our domain. */
2244 if (ret == False) {
2245 return NT_STATUS_NO_SUCH_USER;
2248 TALLOC_FREE(sampass);
2250 /* associate the user's SID and access bits with the new handle. */
2251 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2252 return NT_STATUS_NO_MEMORY;
2253 info->acc_granted = acc_granted;
2255 /* get a (unique) handle. open a policy on it. */
2256 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2257 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2259 return NT_STATUS_OK;
2262 /*************************************************************************
2263 *************************************************************************/
2265 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2266 DATA_BLOB *blob,
2267 struct lsa_BinaryString **_r)
2269 struct lsa_BinaryString *r;
2271 if (!blob || !_r) {
2272 return NT_STATUS_INVALID_PARAMETER;
2275 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2276 if (!r) {
2277 return NT_STATUS_NO_MEMORY;
2280 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2281 if (!r->array) {
2282 return NT_STATUS_NO_MEMORY;
2284 memcpy(r->array, blob->data, blob->length);
2285 r->size = blob->length;
2286 r->length = blob->length;
2288 if (!r->array) {
2289 return NT_STATUS_NO_MEMORY;
2292 *_r = r;
2294 return NT_STATUS_OK;
2297 /*************************************************************************
2298 get_user_info_7. Safe. Only gives out account_name.
2299 *************************************************************************/
2301 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2302 struct samr_UserInfo7 *r,
2303 DOM_SID *user_sid)
2305 struct samu *smbpass=NULL;
2306 bool ret;
2307 const char *account_name = NULL;
2309 ZERO_STRUCTP(r);
2311 if ( !(smbpass = samu_new( mem_ctx )) ) {
2312 return NT_STATUS_NO_MEMORY;
2315 become_root();
2316 ret = pdb_getsampwsid(smbpass, user_sid);
2317 unbecome_root();
2319 if ( !ret ) {
2320 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2321 return NT_STATUS_NO_SUCH_USER;
2324 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2325 if (!account_name) {
2326 TALLOC_FREE(smbpass);
2327 return NT_STATUS_NO_MEMORY;
2329 TALLOC_FREE(smbpass);
2331 DEBUG(3,("User:[%s]\n", account_name));
2333 init_samr_user_info7(r, account_name);
2335 return NT_STATUS_OK;
2338 /*************************************************************************
2339 get_user_info_9. Only gives out primary group SID.
2340 *************************************************************************/
2342 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2343 struct samr_UserInfo9 *r,
2344 DOM_SID *user_sid)
2346 struct samu *smbpass=NULL;
2347 bool ret;
2349 ZERO_STRUCTP(r);
2351 if ( !(smbpass = samu_new( mem_ctx )) ) {
2352 return NT_STATUS_NO_MEMORY;
2355 become_root();
2356 ret = pdb_getsampwsid(smbpass, user_sid);
2357 unbecome_root();
2359 if (ret==False) {
2360 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2361 TALLOC_FREE(smbpass);
2362 return NT_STATUS_NO_SUCH_USER;
2365 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2367 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2369 TALLOC_FREE(smbpass);
2371 return NT_STATUS_OK;
2374 /*************************************************************************
2375 get_user_info_16. Safe. Only gives out acb bits.
2376 *************************************************************************/
2378 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2379 struct samr_UserInfo16 *r,
2380 DOM_SID *user_sid)
2382 struct samu *smbpass=NULL;
2383 bool ret;
2385 ZERO_STRUCTP(r);
2387 if ( !(smbpass = samu_new( mem_ctx )) ) {
2388 return NT_STATUS_NO_MEMORY;
2391 become_root();
2392 ret = pdb_getsampwsid(smbpass, user_sid);
2393 unbecome_root();
2395 if (ret==False) {
2396 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2397 TALLOC_FREE(smbpass);
2398 return NT_STATUS_NO_SUCH_USER;
2401 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2403 init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2405 TALLOC_FREE(smbpass);
2407 return NT_STATUS_OK;
2410 /*************************************************************************
2411 get_user_info_18. OK - this is the killer as it gives out password info.
2412 Ensure that this is only allowed on an encrypted connection with a root
2413 user. JRA.
2414 *************************************************************************/
2416 static NTSTATUS get_user_info_18(pipes_struct *p,
2417 TALLOC_CTX *mem_ctx,
2418 struct samr_UserInfo18 *r,
2419 DOM_SID *user_sid)
2421 struct samu *smbpass=NULL;
2422 bool ret;
2424 ZERO_STRUCTP(r);
2426 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2427 return NT_STATUS_ACCESS_DENIED;
2430 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2431 return NT_STATUS_ACCESS_DENIED;
2435 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2438 if ( !(smbpass = samu_new( mem_ctx )) ) {
2439 return NT_STATUS_NO_MEMORY;
2442 ret = pdb_getsampwsid(smbpass, user_sid);
2444 if (ret == False) {
2445 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2446 TALLOC_FREE(smbpass);
2447 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2450 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2452 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2453 TALLOC_FREE(smbpass);
2454 return NT_STATUS_ACCOUNT_DISABLED;
2457 init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2458 pdb_get_nt_passwd(smbpass));
2460 TALLOC_FREE(smbpass);
2462 return NT_STATUS_OK;
2465 /*************************************************************************
2466 get_user_info_20
2467 *************************************************************************/
2469 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2470 struct samr_UserInfo20 *r,
2471 DOM_SID *user_sid)
2473 struct samu *sampass=NULL;
2474 bool ret;
2475 const char *munged_dial = NULL;
2476 DATA_BLOB blob;
2477 NTSTATUS status;
2478 struct lsa_BinaryString *parameters = NULL;
2480 ZERO_STRUCTP(r);
2482 if ( !(sampass = samu_new( mem_ctx )) ) {
2483 return NT_STATUS_NO_MEMORY;
2486 become_root();
2487 ret = pdb_getsampwsid(sampass, user_sid);
2488 unbecome_root();
2490 if (ret == False) {
2491 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2492 TALLOC_FREE(sampass);
2493 return NT_STATUS_NO_SUCH_USER;
2496 munged_dial = pdb_get_munged_dial(sampass);
2498 samr_clear_sam_passwd(sampass);
2500 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2501 munged_dial, (int)strlen(munged_dial)));
2503 if (munged_dial) {
2504 blob = base64_decode_data_blob(munged_dial);
2505 } else {
2506 blob = data_blob_string_const("");
2509 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2510 data_blob_free(&blob);
2511 TALLOC_FREE(sampass);
2512 if (!NT_STATUS_IS_OK(status)) {
2513 return status;
2516 init_samr_user_info20(r, parameters);
2518 return NT_STATUS_OK;
2522 /*************************************************************************
2523 get_user_info_21
2524 *************************************************************************/
2526 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2527 struct samr_UserInfo21 *r,
2528 DOM_SID *user_sid,
2529 DOM_SID *domain_sid)
2531 NTSTATUS status;
2532 struct samu *pw = NULL;
2533 bool ret;
2534 const DOM_SID *sid_user, *sid_group;
2535 uint32_t rid, primary_gid;
2536 NTTIME last_logon, last_logoff, last_password_change,
2537 acct_expiry, allow_password_change, force_password_change;
2538 time_t must_change_time;
2539 uint8_t password_expired;
2540 const char *account_name, *full_name, *home_directory, *home_drive,
2541 *logon_script, *profile_path, *description,
2542 *workstations, *comment;
2543 struct samr_LogonHours logon_hours;
2544 struct lsa_BinaryString *parameters = NULL;
2545 const char *munged_dial = NULL;
2546 DATA_BLOB blob;
2548 ZERO_STRUCTP(r);
2550 if (!(pw = samu_new(mem_ctx))) {
2551 return NT_STATUS_NO_MEMORY;
2554 become_root();
2555 ret = pdb_getsampwsid(pw, user_sid);
2556 unbecome_root();
2558 if (ret == False) {
2559 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2560 TALLOC_FREE(pw);
2561 return NT_STATUS_NO_SUCH_USER;
2564 samr_clear_sam_passwd(pw);
2566 DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2568 sid_user = pdb_get_user_sid(pw);
2570 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2571 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2572 "the domain sid %s. Failing operation.\n",
2573 pdb_get_username(pw), sid_string_dbg(sid_user),
2574 sid_string_dbg(domain_sid)));
2575 TALLOC_FREE(pw);
2576 return NT_STATUS_UNSUCCESSFUL;
2579 become_root();
2580 sid_group = pdb_get_group_sid(pw);
2581 unbecome_root();
2583 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2584 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2585 "which conflicts with the domain sid %s. Failing operation.\n",
2586 pdb_get_username(pw), sid_string_dbg(sid_group),
2587 sid_string_dbg(domain_sid)));
2588 TALLOC_FREE(pw);
2589 return NT_STATUS_UNSUCCESSFUL;
2592 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2593 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2594 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2595 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2596 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2598 must_change_time = pdb_get_pass_must_change_time(pw);
2599 if (must_change_time == get_time_t_max()) {
2600 unix_to_nt_time_abs(&force_password_change, must_change_time);
2601 } else {
2602 unix_to_nt_time(&force_password_change, must_change_time);
2605 if (pdb_get_pass_must_change_time(pw) == 0) {
2606 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2607 } else {
2608 password_expired = 0;
2611 munged_dial = pdb_get_munged_dial(pw);
2612 if (munged_dial) {
2613 blob = base64_decode_data_blob(munged_dial);
2614 } else {
2615 blob = data_blob_string_const("");
2618 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2619 data_blob_free(&blob);
2620 if (!NT_STATUS_IS_OK(status)) {
2621 TALLOC_FREE(pw);
2622 return status;
2625 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2626 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2627 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2628 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2629 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2630 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2631 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2632 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2633 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2635 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2636 #if 0
2639 Look at a user on a real NT4 PDC with usrmgr, press
2640 'ok'. Then you will see that fields_present is set to
2641 0x08f827fa. Look at the user immediately after that again,
2642 and you will see that 0x00fffff is returned. This solves
2643 the problem that you get access denied after having looked
2644 at the user.
2645 -- Volker
2648 #endif
2650 init_samr_user_info21(r,
2651 last_logon,
2652 last_logoff,
2653 last_password_change,
2654 acct_expiry,
2655 allow_password_change,
2656 force_password_change,
2657 account_name,
2658 full_name,
2659 home_directory,
2660 home_drive,
2661 logon_script,
2662 profile_path,
2663 description,
2664 workstations,
2665 comment,
2666 parameters,
2667 rid,
2668 primary_gid,
2669 pdb_get_acct_ctrl(pw),
2670 pdb_build_fields_present(pw),
2671 logon_hours,
2672 pdb_get_bad_password_count(pw),
2673 pdb_get_logon_count(pw),
2674 0, /* country_code */
2675 0, /* code_page */
2676 0, /* nt_password_set */
2677 0, /* lm_password_set */
2678 password_expired);
2679 TALLOC_FREE(pw);
2681 return NT_STATUS_OK;
2684 /*******************************************************************
2685 _samr_QueryUserInfo
2686 ********************************************************************/
2688 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2689 struct samr_QueryUserInfo *r)
2691 NTSTATUS status;
2692 union samr_UserInfo *user_info = NULL;
2693 struct samr_info *info = NULL;
2694 DOM_SID domain_sid;
2695 uint32 rid;
2697 /* search for the handle */
2698 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2699 return NT_STATUS_INVALID_HANDLE;
2701 status = access_check_samr_function(info->acc_granted,
2702 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2703 "_samr_QueryUserInfo");
2704 if (!NT_STATUS_IS_OK(status)) {
2705 return status;
2708 domain_sid = info->sid;
2710 sid_split_rid(&domain_sid, &rid);
2712 if (!sid_check_is_in_our_domain(&info->sid))
2713 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2715 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2716 sid_string_dbg(&info->sid)));
2718 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2719 if (!user_info) {
2720 return NT_STATUS_NO_MEMORY;
2723 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2725 switch (r->in.level) {
2726 case 7:
2727 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2728 if (!NT_STATUS_IS_OK(status)) {
2729 return status;
2731 break;
2732 case 9:
2733 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2734 if (!NT_STATUS_IS_OK(status)) {
2735 return status;
2737 break;
2738 case 16:
2739 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2740 if (!NT_STATUS_IS_OK(status)) {
2741 return status;
2743 break;
2745 case 18:
2746 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2747 if (!NT_STATUS_IS_OK(status)) {
2748 return status;
2750 break;
2752 case 20:
2753 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2754 if (!NT_STATUS_IS_OK(status)) {
2755 return status;
2757 break;
2759 case 21:
2760 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2761 &info->sid, &domain_sid);
2762 if (!NT_STATUS_IS_OK(status)) {
2763 return status;
2765 break;
2767 default:
2768 return NT_STATUS_INVALID_INFO_CLASS;
2771 *r->out.info = user_info;
2773 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2775 return status;
2778 /*******************************************************************
2779 _samr_GetGroupsForUser
2780 ********************************************************************/
2782 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2783 struct samr_GetGroupsForUser *r)
2785 struct samu *sam_pass=NULL;
2786 DOM_SID sid;
2787 DOM_SID *sids;
2788 struct samr_RidWithAttribute dom_gid;
2789 struct samr_RidWithAttribute *gids = NULL;
2790 uint32 primary_group_rid;
2791 size_t num_groups = 0;
2792 gid_t *unix_gids;
2793 size_t i, num_gids;
2794 uint32 acc_granted;
2795 bool ret;
2796 NTSTATUS result;
2797 bool success = False;
2799 struct samr_RidWithAttributeArray *rids = NULL;
2802 * from the SID in the request:
2803 * we should send back the list of DOMAIN GROUPS
2804 * the user is a member of
2806 * and only the DOMAIN GROUPS
2807 * no ALIASES !!! neither aliases of the domain
2808 * nor aliases of the builtin SID
2810 * JFM, 12/2/2001
2813 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2815 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2816 if (!rids) {
2817 return NT_STATUS_NO_MEMORY;
2820 /* find the policy handle. open a policy on it. */
2821 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2822 return NT_STATUS_INVALID_HANDLE;
2824 result = access_check_samr_function(acc_granted,
2825 SA_RIGHT_USER_GET_GROUPS,
2826 "_samr_GetGroupsForUser");
2827 if (!NT_STATUS_IS_OK(result)) {
2828 return result;
2831 if (!sid_check_is_in_our_domain(&sid))
2832 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2834 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2835 return NT_STATUS_NO_MEMORY;
2838 become_root();
2839 ret = pdb_getsampwsid(sam_pass, &sid);
2840 unbecome_root();
2842 if (!ret) {
2843 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2844 sid_string_dbg(&sid)));
2845 return NT_STATUS_NO_SUCH_USER;
2848 sids = NULL;
2850 /* make both calls inside the root block */
2851 become_root();
2852 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2853 &sids, &unix_gids, &num_groups);
2854 if ( NT_STATUS_IS_OK(result) ) {
2855 success = sid_peek_check_rid(get_global_sam_sid(),
2856 pdb_get_group_sid(sam_pass),
2857 &primary_group_rid);
2859 unbecome_root();
2861 if (!NT_STATUS_IS_OK(result)) {
2862 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2863 sid_string_dbg(&sid)));
2864 return result;
2867 if ( !success ) {
2868 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2869 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2870 pdb_get_username(sam_pass)));
2871 TALLOC_FREE(sam_pass);
2872 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2875 gids = NULL;
2876 num_gids = 0;
2878 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2879 SE_GROUP_ENABLED);
2880 dom_gid.rid = primary_group_rid;
2881 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2883 for (i=0; i<num_groups; i++) {
2885 if (!sid_peek_check_rid(get_global_sam_sid(),
2886 &(sids[i]), &dom_gid.rid)) {
2887 DEBUG(10, ("Found sid %s not in our domain\n",
2888 sid_string_dbg(&sids[i])));
2889 continue;
2892 if (dom_gid.rid == primary_group_rid) {
2893 /* We added the primary group directly from the
2894 * sam_account. The other SIDs are unique from
2895 * enum_group_memberships */
2896 continue;
2899 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2902 rids->count = num_gids;
2903 rids->rids = gids;
2905 *r->out.rids = rids;
2907 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2909 return result;
2912 /*******************************************************************
2913 samr_QueryDomainInfo_internal
2914 ********************************************************************/
2916 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2917 pipes_struct *p,
2918 struct policy_handle *handle,
2919 uint32_t level,
2920 union samr_DomainInfo **dom_info_ptr)
2922 NTSTATUS status = NT_STATUS_OK;
2923 struct samr_info *info = NULL;
2924 union samr_DomainInfo *dom_info;
2925 uint32 min_pass_len,pass_hist,password_properties;
2926 time_t u_expire, u_min_age;
2927 NTTIME nt_expire, nt_min_age;
2929 time_t u_lock_duration, u_reset_time;
2930 NTTIME nt_lock_duration, nt_reset_time;
2931 uint32 lockout;
2932 time_t u_logout;
2933 NTTIME nt_logout;
2935 uint32 account_policy_temp;
2937 time_t seq_num;
2938 uint32 server_role;
2940 uint32 num_users=0, num_groups=0, num_aliases=0;
2942 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2944 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2945 if (!dom_info) {
2946 return NT_STATUS_NO_MEMORY;
2949 *dom_info_ptr = dom_info;
2951 /* find the policy handle. open a policy on it. */
2952 if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2953 return NT_STATUS_INVALID_HANDLE;
2956 status = access_check_samr_function(info->acc_granted,
2957 SA_RIGHT_SAM_OPEN_DOMAIN,
2958 "_samr_QueryDomainInfo_internal" );
2960 if ( !NT_STATUS_IS_OK(status) )
2961 return status;
2963 switch (level) {
2964 case 0x01:
2966 become_root();
2968 /* AS ROOT !!! */
2970 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2971 min_pass_len = account_policy_temp;
2973 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2974 pass_hist = account_policy_temp;
2976 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2977 password_properties = account_policy_temp;
2979 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2980 u_expire = account_policy_temp;
2982 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2983 u_min_age = account_policy_temp;
2985 /* !AS ROOT */
2987 unbecome_root();
2989 unix_to_nt_time_abs(&nt_expire, u_expire);
2990 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2992 if (lp_check_password_script() && *lp_check_password_script()) {
2993 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2996 init_samr_DomInfo1(&dom_info->info1,
2997 (uint16)min_pass_len,
2998 (uint16)pass_hist,
2999 password_properties,
3000 nt_expire,
3001 nt_min_age);
3002 break;
3003 case 0x02:
3005 become_root();
3007 /* AS ROOT !!! */
3009 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
3010 num_groups = count_sam_groups(info->disp_info);
3011 num_aliases = count_sam_aliases(info->disp_info);
3013 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
3014 u_logout = account_policy_temp;
3016 unix_to_nt_time_abs(&nt_logout, u_logout);
3018 if (!pdb_get_seq_num(&seq_num))
3019 seq_num = time(NULL);
3021 /* !AS ROOT */
3023 unbecome_root();
3025 server_role = ROLE_DOMAIN_PDC;
3026 if (lp_server_role() == ROLE_DOMAIN_BDC)
3027 server_role = ROLE_DOMAIN_BDC;
3029 init_samr_DomInfo2(&dom_info->info2,
3030 nt_logout,
3031 lp_serverstring(),
3032 lp_workgroup(),
3033 global_myname(),
3034 seq_num,
3036 server_role,
3038 num_users,
3039 num_groups,
3040 num_aliases);
3041 break;
3042 case 0x03:
3044 become_root();
3046 /* AS ROOT !!! */
3049 uint32 ul;
3050 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3051 u_logout = (time_t)ul;
3054 /* !AS ROOT */
3056 unbecome_root();
3058 unix_to_nt_time_abs(&nt_logout, u_logout);
3060 init_samr_DomInfo3(&dom_info->info3,
3061 nt_logout);
3063 break;
3064 case 0x04:
3065 init_samr_DomInfo4(&dom_info->info4,
3066 lp_serverstring());
3067 break;
3068 case 0x05:
3069 init_samr_DomInfo5(&dom_info->info5,
3070 get_global_sam_name());
3071 break;
3072 case 0x06:
3073 /* NT returns its own name when a PDC. win2k and later
3074 * only the name of the PDC if itself is a BDC (samba4
3075 * idl) */
3076 init_samr_DomInfo6(&dom_info->info6,
3077 global_myname());
3078 break;
3079 case 0x07:
3080 server_role = ROLE_DOMAIN_PDC;
3081 if (lp_server_role() == ROLE_DOMAIN_BDC)
3082 server_role = ROLE_DOMAIN_BDC;
3084 init_samr_DomInfo7(&dom_info->info7,
3085 server_role);
3086 break;
3087 case 0x08:
3089 become_root();
3091 /* AS ROOT !!! */
3093 if (!pdb_get_seq_num(&seq_num)) {
3094 seq_num = time(NULL);
3097 /* !AS ROOT */
3099 unbecome_root();
3101 init_samr_DomInfo8(&dom_info->info8,
3102 seq_num,
3104 break;
3105 case 0x0c:
3107 become_root();
3109 /* AS ROOT !!! */
3111 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3112 u_lock_duration = account_policy_temp;
3113 if (u_lock_duration != -1) {
3114 u_lock_duration *= 60;
3117 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3118 u_reset_time = account_policy_temp * 60;
3120 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3121 lockout = account_policy_temp;
3123 /* !AS ROOT */
3125 unbecome_root();
3127 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3128 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3130 init_samr_DomInfo12(&dom_info->info12,
3131 nt_lock_duration,
3132 nt_reset_time,
3133 (uint16)lockout);
3134 break;
3135 default:
3136 return NT_STATUS_INVALID_INFO_CLASS;
3139 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
3141 return status;
3144 /*******************************************************************
3145 _samr_QueryDomainInfo
3146 ********************************************************************/
3148 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3149 struct samr_QueryDomainInfo *r)
3151 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
3153 r->in.domain_handle,
3154 r->in.level,
3155 r->out.info);
3158 /* W2k3 seems to use the same check for all 3 objects that can be created via
3159 * SAMR, if you try to create for example "Dialup" as an alias it says
3160 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3161 * database. */
3163 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3165 enum lsa_SidType type;
3166 bool result;
3168 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3170 become_root();
3171 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3172 * whether the name already exists */
3173 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3174 NULL, NULL, NULL, &type);
3175 unbecome_root();
3177 if (!result) {
3178 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3179 return NT_STATUS_OK;
3182 DEBUG(5, ("trying to create %s, exists as %s\n",
3183 new_name, sid_type_lookup(type)));
3185 if (type == SID_NAME_DOM_GRP) {
3186 return NT_STATUS_GROUP_EXISTS;
3188 if (type == SID_NAME_ALIAS) {
3189 return NT_STATUS_ALIAS_EXISTS;
3192 /* Yes, the default is NT_STATUS_USER_EXISTS */
3193 return NT_STATUS_USER_EXISTS;
3196 /*******************************************************************
3197 _samr_CreateUser2
3198 ********************************************************************/
3200 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3201 struct samr_CreateUser2 *r)
3203 const char *account = NULL;
3204 DOM_SID sid;
3205 POLICY_HND dom_pol = *r->in.domain_handle;
3206 uint32_t acb_info = r->in.acct_flags;
3207 POLICY_HND *user_pol = r->out.user_handle;
3208 struct samr_info *info = NULL;
3209 NTSTATUS nt_status;
3210 uint32 acc_granted;
3211 SEC_DESC *psd;
3212 size_t sd_size;
3213 /* check this, when giving away 'add computer to domain' privs */
3214 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3215 bool can_add_account = False;
3216 SE_PRIV se_rights;
3217 DISP_INFO *disp_info = NULL;
3219 /* Get the domain SID stored in the domain policy */
3220 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3221 &disp_info))
3222 return NT_STATUS_INVALID_HANDLE;
3224 nt_status = access_check_samr_function(acc_granted,
3225 SA_RIGHT_DOMAIN_CREATE_USER,
3226 "_samr_CreateUser2");
3227 if (!NT_STATUS_IS_OK(nt_status)) {
3228 return nt_status;
3231 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3232 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3233 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3234 this parameter is not an account type */
3235 return NT_STATUS_INVALID_PARAMETER;
3238 account = r->in.account_name->string;
3239 if (account == NULL) {
3240 return NT_STATUS_NO_MEMORY;
3243 nt_status = can_create(p->mem_ctx, account);
3244 if (!NT_STATUS_IS_OK(nt_status)) {
3245 return nt_status;
3248 /* determine which user right we need to check based on the acb_info */
3250 if ( acb_info & ACB_WSTRUST )
3252 se_priv_copy( &se_rights, &se_machine_account );
3253 can_add_account = user_has_privileges(
3254 p->pipe_user.nt_user_token, &se_rights );
3256 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3257 account for domain trusts and changes the ACB flags later */
3258 else if ( acb_info & ACB_NORMAL &&
3259 (account[strlen(account)-1] != '$') )
3261 se_priv_copy( &se_rights, &se_add_users );
3262 can_add_account = user_has_privileges(
3263 p->pipe_user.nt_user_token, &se_rights );
3265 else /* implicit assumption of a BDC or domain trust account here
3266 * (we already check the flags earlier) */
3268 if ( lp_enable_privileges() ) {
3269 /* only Domain Admins can add a BDC or domain trust */
3270 se_priv_copy( &se_rights, &se_priv_none );
3271 can_add_account = nt_token_check_domain_rid(
3272 p->pipe_user.nt_user_token,
3273 DOMAIN_GROUP_RID_ADMINS );
3277 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3278 uidtoname(p->pipe_user.ut.uid),
3279 can_add_account ? "True":"False" ));
3281 /********** BEGIN Admin BLOCK **********/
3283 if ( can_add_account )
3284 become_root();
3286 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3287 r->out.rid);
3289 if ( can_add_account )
3290 unbecome_root();
3292 /********** END Admin BLOCK **********/
3294 /* now check for failure */
3296 if ( !NT_STATUS_IS_OK(nt_status) )
3297 return nt_status;
3299 /* Get the user's SID */
3301 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3303 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3305 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3306 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3307 se_map_generic(&des_access, &usr_generic_mapping);
3309 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3310 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3311 &acc_granted, "_samr_CreateUser2");
3313 if ( !NT_STATUS_IS_OK(nt_status) ) {
3314 return nt_status;
3317 /* associate the user's SID with the new handle. */
3318 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3319 return NT_STATUS_NO_MEMORY;
3322 ZERO_STRUCTP(info);
3323 info->sid = sid;
3324 info->acc_granted = acc_granted;
3326 /* get a (unique) handle. open a policy on it. */
3327 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3328 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3331 /* After a "set" ensure we have no cached display info. */
3332 force_flush_samr_cache(info->disp_info);
3334 *r->out.access_granted = acc_granted;
3336 return NT_STATUS_OK;
3339 /*******************************************************************
3340 _samr_Connect
3341 ********************************************************************/
3343 NTSTATUS _samr_Connect(pipes_struct *p,
3344 struct samr_Connect *r)
3346 struct samr_info *info = NULL;
3347 uint32 des_access = r->in.access_mask;
3349 /* Access check */
3351 if (!pipe_access_check(p)) {
3352 DEBUG(3, ("access denied to _samr_Connect\n"));
3353 return NT_STATUS_ACCESS_DENIED;
3356 /* set up the SAMR connect_anon response */
3358 /* associate the user's SID with the new handle. */
3359 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3360 return NT_STATUS_NO_MEMORY;
3362 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3363 was observed from a win98 client trying to enumerate users (when configured
3364 user level access control on shares) --jerry */
3366 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3368 se_map_generic( &des_access, &sam_generic_mapping );
3369 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3371 /* get a (unique) handle. open a policy on it. */
3372 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3373 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3375 return NT_STATUS_OK;
3378 /*******************************************************************
3379 _samr_Connect2
3380 ********************************************************************/
3382 NTSTATUS _samr_Connect2(pipes_struct *p,
3383 struct samr_Connect2 *r)
3385 struct samr_info *info = NULL;
3386 SEC_DESC *psd = NULL;
3387 uint32 acc_granted;
3388 uint32 des_access = r->in.access_mask;
3389 NTSTATUS nt_status;
3390 size_t sd_size;
3393 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3395 /* Access check */
3397 if (!pipe_access_check(p)) {
3398 DEBUG(3, ("access denied to _samr_Connect2\n"));
3399 return NT_STATUS_ACCESS_DENIED;
3402 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3404 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3405 se_map_generic(&des_access, &sam_generic_mapping);
3407 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3408 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3410 if ( !NT_STATUS_IS_OK(nt_status) )
3411 return nt_status;
3413 /* associate the user's SID and access granted with the new handle. */
3414 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3415 return NT_STATUS_NO_MEMORY;
3417 info->acc_granted = acc_granted;
3418 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3420 /* get a (unique) handle. open a policy on it. */
3421 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3422 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3424 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3426 return nt_status;
3429 /*******************************************************************
3430 _samr_Connect4
3431 ********************************************************************/
3433 NTSTATUS _samr_Connect4(pipes_struct *p,
3434 struct samr_Connect4 *r)
3436 struct samr_info *info = NULL;
3437 SEC_DESC *psd = NULL;
3438 uint32 acc_granted;
3439 uint32 des_access = r->in.access_mask;
3440 NTSTATUS nt_status;
3441 size_t sd_size;
3444 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3446 /* Access check */
3448 if (!pipe_access_check(p)) {
3449 DEBUG(3, ("access denied to samr_Connect4\n"));
3450 return NT_STATUS_ACCESS_DENIED;
3453 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3455 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3456 se_map_generic(&des_access, &sam_generic_mapping);
3458 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3459 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3461 if ( !NT_STATUS_IS_OK(nt_status) )
3462 return nt_status;
3464 /* associate the user's SID and access granted with the new handle. */
3465 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3466 return NT_STATUS_NO_MEMORY;
3468 info->acc_granted = acc_granted;
3469 info->status = r->in.access_mask; /* ??? */
3471 /* get a (unique) handle. open a policy on it. */
3472 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3473 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3475 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3477 return NT_STATUS_OK;
3480 /*******************************************************************
3481 _samr_Connect5
3482 ********************************************************************/
3484 NTSTATUS _samr_Connect5(pipes_struct *p,
3485 struct samr_Connect5 *r)
3487 struct samr_info *info = NULL;
3488 SEC_DESC *psd = NULL;
3489 uint32 acc_granted;
3490 uint32 des_access = r->in.access_mask;
3491 NTSTATUS nt_status;
3492 size_t sd_size;
3493 struct samr_ConnectInfo1 info1;
3495 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3497 /* Access check */
3499 if (!pipe_access_check(p)) {
3500 DEBUG(3, ("access denied to samr_Connect5\n"));
3501 return NT_STATUS_ACCESS_DENIED;
3504 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3506 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3507 se_map_generic(&des_access, &sam_generic_mapping);
3509 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3510 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3512 if ( !NT_STATUS_IS_OK(nt_status) )
3513 return nt_status;
3515 /* associate the user's SID and access granted with the new handle. */
3516 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3517 return NT_STATUS_NO_MEMORY;
3519 info->acc_granted = acc_granted;
3520 info->status = r->in.access_mask; /* ??? */
3522 /* get a (unique) handle. open a policy on it. */
3523 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3524 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3526 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3528 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3529 info1.unknown2 = 0;
3531 *r->out.level_out = 1;
3532 r->out.info_out->info1 = info1;
3534 return NT_STATUS_OK;
3537 /**********************************************************************
3538 _samr_LookupDomain
3539 **********************************************************************/
3541 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3542 struct samr_LookupDomain *r)
3544 NTSTATUS status = NT_STATUS_OK;
3545 struct samr_info *info;
3546 const char *domain_name;
3547 DOM_SID *sid = NULL;
3549 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3550 return NT_STATUS_INVALID_HANDLE;
3552 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3553 Reverted that change so we will work with RAS servers again */
3555 status = access_check_samr_function(info->acc_granted,
3556 SA_RIGHT_SAM_OPEN_DOMAIN,
3557 "_samr_LookupDomain");
3558 if (!NT_STATUS_IS_OK(status)) {
3559 return status;
3562 domain_name = r->in.domain_name->string;
3564 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3565 if (!sid) {
3566 return NT_STATUS_NO_MEMORY;
3569 if (strequal(domain_name, builtin_domain_name())) {
3570 sid_copy(sid, &global_sid_Builtin);
3571 } else {
3572 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3573 status = NT_STATUS_NO_SUCH_DOMAIN;
3577 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3578 sid_string_dbg(sid)));
3580 *r->out.sid = sid;
3582 return status;
3585 /**********************************************************************
3586 _samr_EnumDomains
3587 **********************************************************************/
3589 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3590 struct samr_EnumDomains *r)
3592 NTSTATUS status;
3593 struct samr_info *info;
3594 uint32_t num_entries = 2;
3595 struct samr_SamEntry *entry_array = NULL;
3596 struct samr_SamArray *sam;
3598 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3599 return NT_STATUS_INVALID_HANDLE;
3601 status = access_check_samr_function(info->acc_granted,
3602 SA_RIGHT_SAM_ENUM_DOMAINS,
3603 "_samr_EnumDomains");
3604 if (!NT_STATUS_IS_OK(status)) {
3605 return status;
3608 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3609 if (!sam) {
3610 return NT_STATUS_NO_MEMORY;
3613 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3614 struct samr_SamEntry,
3615 num_entries);
3616 if (!entry_array) {
3617 return NT_STATUS_NO_MEMORY;
3620 entry_array[0].idx = 0;
3621 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3623 entry_array[1].idx = 1;
3624 init_lsa_String(&entry_array[1].name, "Builtin");
3626 sam->count = num_entries;
3627 sam->entries = entry_array;
3629 *r->out.sam = sam;
3630 *r->out.num_entries = num_entries;
3632 return status;
3635 /*******************************************************************
3636 _samr_OpenAlias
3637 ********************************************************************/
3639 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3640 struct samr_OpenAlias *r)
3642 DOM_SID sid;
3643 POLICY_HND domain_pol = *r->in.domain_handle;
3644 uint32 alias_rid = r->in.rid;
3645 POLICY_HND *alias_pol = r->out.alias_handle;
3646 struct samr_info *info = NULL;
3647 SEC_DESC *psd = NULL;
3648 uint32 acc_granted;
3649 uint32 des_access = r->in.access_mask;
3650 size_t sd_size;
3651 NTSTATUS status;
3652 SE_PRIV se_rights;
3654 /* find the domain policy and get the SID / access bits stored in the domain policy */
3656 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3657 return NT_STATUS_INVALID_HANDLE;
3659 status = access_check_samr_function(acc_granted,
3660 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3661 "_samr_OpenAlias");
3663 if ( !NT_STATUS_IS_OK(status) )
3664 return status;
3666 /* append the alias' RID to it */
3668 if (!sid_append_rid(&sid, alias_rid))
3669 return NT_STATUS_NO_SUCH_ALIAS;
3671 /*check if access can be granted as requested by client. */
3673 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3675 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3676 se_map_generic(&des_access,&ali_generic_mapping);
3678 se_priv_copy( &se_rights, &se_add_users );
3681 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3682 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3683 &acc_granted, "_samr_OpenAlias");
3685 if ( !NT_STATUS_IS_OK(status) )
3686 return status;
3689 /* Check we actually have the requested alias */
3690 enum lsa_SidType type;
3691 bool result;
3692 gid_t gid;
3694 become_root();
3695 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3696 unbecome_root();
3698 if (!result || (type != SID_NAME_ALIAS)) {
3699 return NT_STATUS_NO_SUCH_ALIAS;
3702 /* make sure there is a mapping */
3704 if ( !sid_to_gid( &sid, &gid ) ) {
3705 return NT_STATUS_NO_SUCH_ALIAS;
3710 /* associate the alias SID with the new handle. */
3711 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3712 return NT_STATUS_NO_MEMORY;
3714 info->acc_granted = acc_granted;
3716 /* get a (unique) handle. open a policy on it. */
3717 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3718 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3720 return NT_STATUS_OK;
3723 /*******************************************************************
3724 set_user_info_7
3725 ********************************************************************/
3727 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3728 struct samr_UserInfo7 *id7,
3729 struct samu *pwd)
3731 NTSTATUS rc;
3733 if (id7 == NULL) {
3734 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3735 TALLOC_FREE(pwd);
3736 return NT_STATUS_ACCESS_DENIED;
3739 if (!id7->account_name.string) {
3740 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3741 TALLOC_FREE(pwd);
3742 return NT_STATUS_ACCESS_DENIED;
3745 /* check to see if the new username already exists. Note: we can't
3746 reliably lock all backends, so there is potentially the
3747 possibility that a user can be created in between this check and
3748 the rename. The rename should fail, but may not get the
3749 exact same failure status code. I think this is small enough
3750 of a window for this type of operation and the results are
3751 simply that the rename fails with a slightly different status
3752 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3754 rc = can_create(mem_ctx, id7->account_name.string);
3755 if (!NT_STATUS_IS_OK(rc)) {
3756 return rc;
3759 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3761 TALLOC_FREE(pwd);
3762 return rc;
3765 /*******************************************************************
3766 set_user_info_16
3767 ********************************************************************/
3769 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3770 struct samu *pwd)
3772 if (id16 == NULL) {
3773 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3774 TALLOC_FREE(pwd);
3775 return False;
3778 /* FIX ME: check if the value is really changed --metze */
3779 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3780 TALLOC_FREE(pwd);
3781 return False;
3784 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3785 TALLOC_FREE(pwd);
3786 return False;
3789 TALLOC_FREE(pwd);
3791 return True;
3794 /*******************************************************************
3795 set_user_info_18
3796 ********************************************************************/
3798 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3799 struct samu *pwd)
3801 if (id18 == NULL) {
3802 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3803 TALLOC_FREE(pwd);
3804 return False;
3807 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3808 TALLOC_FREE(pwd);
3809 return False;
3811 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3812 TALLOC_FREE(pwd);
3813 return False;
3815 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3816 TALLOC_FREE(pwd);
3817 return False;
3820 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3821 TALLOC_FREE(pwd);
3822 return False;
3825 TALLOC_FREE(pwd);
3826 return True;
3829 /*******************************************************************
3830 set_user_info_20
3831 ********************************************************************/
3833 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3834 struct samu *pwd)
3836 if (id20 == NULL) {
3837 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3838 return False;
3841 copy_id20_to_sam_passwd(pwd, id20);
3843 /* write the change out */
3844 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3845 TALLOC_FREE(pwd);
3846 return False;
3849 TALLOC_FREE(pwd);
3851 return True;
3854 /*******************************************************************
3855 set_user_info_21
3856 ********************************************************************/
3858 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3859 struct samr_UserInfo21 *id21,
3860 struct samu *pwd)
3862 NTSTATUS status;
3864 if (id21 == NULL) {
3865 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3866 return NT_STATUS_INVALID_PARAMETER;
3869 /* we need to separately check for an account rename first */
3871 if (id21->account_name.string &&
3872 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3875 /* check to see if the new username already exists. Note: we can't
3876 reliably lock all backends, so there is potentially the
3877 possibility that a user can be created in between this check and
3878 the rename. The rename should fail, but may not get the
3879 exact same failure status code. I think this is small enough
3880 of a window for this type of operation and the results are
3881 simply that the rename fails with a slightly different status
3882 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3884 status = can_create(mem_ctx, id21->account_name.string);
3885 if (!NT_STATUS_IS_OK(status)) {
3886 return status;
3889 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3891 if (!NT_STATUS_IS_OK(status)) {
3892 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3893 nt_errstr(status)));
3894 TALLOC_FREE(pwd);
3895 return status;
3898 /* set the new username so that later
3899 functions can work on the new account */
3900 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3903 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3906 * The funny part about the previous two calls is
3907 * that pwd still has the password hashes from the
3908 * passdb entry. These have not been updated from
3909 * id21. I don't know if they need to be set. --jerry
3912 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3913 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3914 if ( !NT_STATUS_IS_OK(status) ) {
3915 return status;
3919 /* Don't worry about writing out the user account since the
3920 primary group SID is generated solely from the user's Unix
3921 primary group. */
3923 /* write the change out */
3924 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3925 TALLOC_FREE(pwd);
3926 return status;
3929 TALLOC_FREE(pwd);
3931 return NT_STATUS_OK;
3934 /*******************************************************************
3935 set_user_info_23
3936 ********************************************************************/
3938 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3939 struct samr_UserInfo23 *id23,
3940 struct samu *pwd)
3942 char *plaintext_buf = NULL;
3943 uint32 len = 0;
3944 uint16 acct_ctrl;
3945 NTSTATUS status;
3947 if (id23 == NULL) {
3948 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3949 return NT_STATUS_INVALID_PARAMETER;
3952 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3953 pdb_get_username(pwd)));
3955 acct_ctrl = pdb_get_acct_ctrl(pwd);
3957 if (!decode_pw_buffer(mem_ctx,
3958 id23->password.data,
3959 &plaintext_buf,
3960 &len,
3961 STR_UNICODE)) {
3962 TALLOC_FREE(pwd);
3963 return NT_STATUS_INVALID_PARAMETER;
3966 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3967 TALLOC_FREE(pwd);
3968 return NT_STATUS_ACCESS_DENIED;
3971 copy_id23_to_sam_passwd(pwd, id23);
3973 /* if it's a trust account, don't update /etc/passwd */
3974 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3975 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3976 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3977 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3978 } else {
3979 /* update the UNIX password */
3980 if (lp_unix_password_sync() ) {
3981 struct passwd *passwd;
3982 if (pdb_get_username(pwd) == NULL) {
3983 DEBUG(1, ("chgpasswd: User without name???\n"));
3984 TALLOC_FREE(pwd);
3985 return NT_STATUS_ACCESS_DENIED;
3988 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3989 if (passwd == NULL) {
3990 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3993 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3994 TALLOC_FREE(pwd);
3995 return NT_STATUS_ACCESS_DENIED;
3997 TALLOC_FREE(passwd);
4001 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4003 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4004 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4005 pwd)))) {
4006 TALLOC_FREE(pwd);
4007 return status;
4010 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4011 TALLOC_FREE(pwd);
4012 return status;
4015 TALLOC_FREE(pwd);
4017 return NT_STATUS_OK;
4020 /*******************************************************************
4021 set_user_info_pw
4022 ********************************************************************/
4024 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
4025 int level)
4027 uint32 len = 0;
4028 char *plaintext_buf = NULL;
4029 uint32 acct_ctrl;
4030 time_t last_set_time;
4031 enum pdb_value_state last_set_state;
4033 DEBUG(5, ("Attempting administrator password change for user %s\n",
4034 pdb_get_username(pwd)));
4036 acct_ctrl = pdb_get_acct_ctrl(pwd);
4037 /* we need to know if it's expired, because this is an admin change, not a
4038 user change, so it's still expired when we're done */
4039 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
4040 last_set_time = pdb_get_pass_last_set_time(pwd);
4042 if (!decode_pw_buffer(talloc_tos(),
4043 pass,
4044 &plaintext_buf,
4045 &len,
4046 STR_UNICODE)) {
4047 TALLOC_FREE(pwd);
4048 return False;
4051 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4052 TALLOC_FREE(pwd);
4053 return False;
4056 /* if it's a trust account, don't update /etc/passwd */
4057 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4058 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4059 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4060 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4061 } else {
4062 /* update the UNIX password */
4063 if (lp_unix_password_sync()) {
4064 struct passwd *passwd;
4066 if (pdb_get_username(pwd) == NULL) {
4067 DEBUG(1, ("chgpasswd: User without name???\n"));
4068 TALLOC_FREE(pwd);
4069 return False;
4072 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4073 if (passwd == NULL) {
4074 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4077 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4078 TALLOC_FREE(pwd);
4079 return False;
4081 TALLOC_FREE(passwd);
4085 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4088 * A level 25 change does reset the pwdlastset field, a level 24
4089 * change does not. I know this is probably not the full story, but
4090 * it is needed to make XP join LDAP correctly, without it the later
4091 * auth2 check can fail with PWD_MUST_CHANGE.
4093 if (level != 25) {
4095 * restore last set time as this is an admin change, not a
4096 * user pw change
4098 pdb_set_pass_last_set_time (pwd, last_set_time,
4099 last_set_state);
4102 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4104 /* update the SAMBA password */
4105 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4106 TALLOC_FREE(pwd);
4107 return False;
4110 TALLOC_FREE(pwd);
4112 return True;
4115 /*******************************************************************
4116 set_user_info_25
4117 ********************************************************************/
4119 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4120 struct samr_UserInfo25 *id25,
4121 struct samu *pwd)
4123 NTSTATUS status;
4125 if (id25 == NULL) {
4126 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4127 return NT_STATUS_INVALID_PARAMETER;
4130 copy_id25_to_sam_passwd(pwd, id25);
4132 /* write the change out */
4133 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4134 TALLOC_FREE(pwd);
4135 return status;
4139 * We need to "pdb_update_sam_account" before the unix primary group
4140 * is set, because the idealx scripts would also change the
4141 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4142 * the delete explicit / add explicit, which would then fail to find
4143 * the previous primaryGroupSid value.
4146 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4147 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4148 if ( !NT_STATUS_IS_OK(status) ) {
4149 return status;
4153 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
4154 * hereafter! */
4156 return NT_STATUS_OK;
4159 /*******************************************************************
4160 samr_SetUserInfo_internal
4161 ********************************************************************/
4163 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
4164 pipes_struct *p,
4165 struct policy_handle *user_handle,
4166 uint16_t level,
4167 union samr_UserInfo *info)
4169 NTSTATUS status;
4170 struct samu *pwd = NULL;
4171 DOM_SID sid;
4172 POLICY_HND *pol = user_handle;
4173 uint16_t switch_value = level;
4174 uint32_t acc_granted;
4175 uint32_t acc_required;
4176 bool ret;
4177 bool has_enough_rights = False;
4178 uint32_t acb_info;
4179 DISP_INFO *disp_info = NULL;
4181 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4183 /* find the policy handle. open a policy on it. */
4184 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4185 return NT_STATUS_INVALID_HANDLE;
4188 /* This is tricky. A WinXP domain join sets
4189 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4190 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4191 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4192 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4193 we'll use the set from the WinXP join as the basis. */
4195 switch (switch_value) {
4196 case 18:
4197 case 24:
4198 case 25:
4199 case 26:
4200 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4201 break;
4202 default:
4203 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4204 SA_RIGHT_USER_SET_ATTRIBUTES |
4205 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4206 break;
4209 status = access_check_samr_function(acc_granted,
4210 acc_required,
4211 fn_name);
4212 if (!NT_STATUS_IS_OK(status)) {
4213 return status;
4216 DEBUG(5, ("%s: sid:%s, level:%d\n",
4217 fn_name, sid_string_dbg(&sid), switch_value));
4219 if (info == NULL) {
4220 DEBUG(5, ("%s: NULL info level\n", fn_name));
4221 return NT_STATUS_INVALID_INFO_CLASS;
4224 if (!(pwd = samu_new(NULL))) {
4225 return NT_STATUS_NO_MEMORY;
4228 become_root();
4229 ret = pdb_getsampwsid(pwd, &sid);
4230 unbecome_root();
4232 if (!ret) {
4233 TALLOC_FREE(pwd);
4234 return NT_STATUS_NO_SUCH_USER;
4237 /* deal with machine password changes differently from userinfo changes */
4238 /* check to see if we have the sufficient rights */
4240 acb_info = pdb_get_acct_ctrl(pwd);
4241 if (acb_info & ACB_WSTRUST)
4242 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4243 &se_machine_account);
4244 else if (acb_info & ACB_NORMAL)
4245 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4246 &se_add_users);
4247 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4248 if (lp_enable_privileges()) {
4249 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4250 DOMAIN_GROUP_RID_ADMINS);
4254 DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4255 fn_name,
4256 uidtoname(p->pipe_user.ut.uid),
4257 has_enough_rights ? "" : " not"));
4259 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4261 if (has_enough_rights) {
4262 become_root();
4265 /* ok! user info levels (lots: see MSDEV help), off we go... */
4267 switch (switch_value) {
4269 case 7:
4270 status = set_user_info_7(p->mem_ctx,
4271 &info->info7, pwd);
4272 break;
4274 case 16:
4275 if (!set_user_info_16(&info->info16, pwd)) {
4276 status = NT_STATUS_ACCESS_DENIED;
4278 break;
4280 case 18:
4281 /* Used by AS/U JRA. */
4282 if (!set_user_info_18(&info->info18, pwd)) {
4283 status = NT_STATUS_ACCESS_DENIED;
4285 break;
4287 case 20:
4288 if (!set_user_info_20(&info->info20, pwd)) {
4289 status = NT_STATUS_ACCESS_DENIED;
4291 break;
4293 case 21:
4294 status = set_user_info_21(p->mem_ctx,
4295 &info->info21, pwd);
4296 break;
4298 case 23:
4299 if (!p->server_info->user_session_key.length) {
4300 status = NT_STATUS_NO_USER_SESSION_KEY;
4302 SamOEMhashBlob(info->info23.password.data, 516,
4303 &p->server_info->user_session_key);
4305 dump_data(100, info->info23.password.data, 516);
4307 status = set_user_info_23(p->mem_ctx,
4308 &info->info23, pwd);
4309 break;
4311 case 24:
4312 if (!p->server_info->user_session_key.length) {
4313 status = NT_STATUS_NO_USER_SESSION_KEY;
4315 SamOEMhashBlob(info->info24.password.data,
4316 516,
4317 &p->server_info->user_session_key);
4319 dump_data(100, info->info24.password.data, 516);
4321 if (!set_user_info_pw(info->info24.password.data, pwd,
4322 switch_value)) {
4323 status = NT_STATUS_ACCESS_DENIED;
4325 break;
4327 case 25:
4328 if (!p->server_info->user_session_key.length) {
4329 status = NT_STATUS_NO_USER_SESSION_KEY;
4331 encode_or_decode_arc4_passwd_buffer(
4332 info->info25.password.data,
4333 &p->server_info->user_session_key);
4335 dump_data(100, info->info25.password.data, 532);
4337 status = set_user_info_25(p->mem_ctx,
4338 &info->info25, pwd);
4339 if (!NT_STATUS_IS_OK(status)) {
4340 goto done;
4342 if (!set_user_info_pw(info->info25.password.data, pwd,
4343 switch_value)) {
4344 status = NT_STATUS_ACCESS_DENIED;
4346 break;
4348 case 26:
4349 if (!p->server_info->user_session_key.length) {
4350 status = NT_STATUS_NO_USER_SESSION_KEY;
4352 encode_or_decode_arc4_passwd_buffer(
4353 info->info26.password.data,
4354 &p->server_info->user_session_key);
4356 dump_data(100, info->info26.password.data, 516);
4358 if (!set_user_info_pw(info->info26.password.data, pwd,
4359 switch_value)) {
4360 status = NT_STATUS_ACCESS_DENIED;
4362 break;
4364 default:
4365 status = NT_STATUS_INVALID_INFO_CLASS;
4368 done:
4370 if (has_enough_rights) {
4371 unbecome_root();
4374 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4376 if (NT_STATUS_IS_OK(status)) {
4377 force_flush_samr_cache(disp_info);
4380 return status;
4383 /*******************************************************************
4384 _samr_SetUserInfo
4385 ********************************************************************/
4387 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4388 struct samr_SetUserInfo *r)
4390 return samr_SetUserInfo_internal("_samr_SetUserInfo",
4392 r->in.user_handle,
4393 r->in.level,
4394 r->in.info);
4397 /*******************************************************************
4398 _samr_SetUserInfo2
4399 ********************************************************************/
4401 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4402 struct samr_SetUserInfo2 *r)
4404 return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4406 r->in.user_handle,
4407 r->in.level,
4408 r->in.info);
4411 /*********************************************************************
4412 _samr_GetAliasMembership
4413 *********************************************************************/
4415 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4416 struct samr_GetAliasMembership *r)
4418 size_t num_alias_rids;
4419 uint32 *alias_rids;
4420 struct samr_info *info = NULL;
4421 size_t i;
4423 NTSTATUS ntstatus1;
4424 NTSTATUS ntstatus2;
4426 DOM_SID *members;
4428 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4430 /* find the policy handle. open a policy on it. */
4431 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4432 return NT_STATUS_INVALID_HANDLE;
4434 ntstatus1 = access_check_samr_function(info->acc_granted,
4435 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4436 "_samr_GetAliasMembership");
4437 ntstatus2 = access_check_samr_function(info->acc_granted,
4438 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4439 "_samr_GetAliasMembership");
4441 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4442 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4443 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4444 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4448 if (!sid_check_is_domain(&info->sid) &&
4449 !sid_check_is_builtin(&info->sid))
4450 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4452 if (r->in.sids->num_sids) {
4453 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4455 if (members == NULL)
4456 return NT_STATUS_NO_MEMORY;
4457 } else {
4458 members = NULL;
4461 for (i=0; i<r->in.sids->num_sids; i++)
4462 sid_copy(&members[i], r->in.sids->sids[i].sid);
4464 alias_rids = NULL;
4465 num_alias_rids = 0;
4467 become_root();
4468 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4469 r->in.sids->num_sids,
4470 &alias_rids, &num_alias_rids);
4471 unbecome_root();
4473 if (!NT_STATUS_IS_OK(ntstatus1)) {
4474 return ntstatus1;
4477 r->out.rids->count = num_alias_rids;
4478 r->out.rids->ids = alias_rids;
4480 return NT_STATUS_OK;
4483 /*********************************************************************
4484 _samr_GetMembersInAlias
4485 *********************************************************************/
4487 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4488 struct samr_GetMembersInAlias *r)
4490 NTSTATUS status;
4491 size_t i;
4492 size_t num_sids = 0;
4493 struct lsa_SidPtr *sids = NULL;
4494 DOM_SID *pdb_sids = NULL;
4496 DOM_SID alias_sid;
4498 uint32 acc_granted;
4500 /* find the policy handle. open a policy on it. */
4501 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4502 return NT_STATUS_INVALID_HANDLE;
4504 status = access_check_samr_function(acc_granted,
4505 SA_RIGHT_ALIAS_GET_MEMBERS,
4506 "_samr_GetMembersInAlias");
4507 if (!NT_STATUS_IS_OK(status)) {
4508 return status;
4511 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4513 become_root();
4514 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4515 unbecome_root();
4517 if (!NT_STATUS_IS_OK(status)) {
4518 return status;
4521 if (num_sids) {
4522 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4523 if (sids == NULL) {
4524 TALLOC_FREE(pdb_sids);
4525 return NT_STATUS_NO_MEMORY;
4529 for (i = 0; i < num_sids; i++) {
4530 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4531 if (!sids[i].sid) {
4532 TALLOC_FREE(pdb_sids);
4533 return NT_STATUS_NO_MEMORY;
4537 r->out.sids->num_sids = num_sids;
4538 r->out.sids->sids = sids;
4540 TALLOC_FREE(pdb_sids);
4542 return NT_STATUS_OK;
4545 /*********************************************************************
4546 _samr_QueryGroupMember
4547 *********************************************************************/
4549 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4550 struct samr_QueryGroupMember *r)
4552 DOM_SID group_sid;
4553 size_t i, num_members;
4555 uint32 *rid=NULL;
4556 uint32 *attr=NULL;
4558 uint32 acc_granted;
4560 NTSTATUS status;
4561 struct samr_RidTypeArray *rids = NULL;
4563 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4564 if (!rids) {
4565 return NT_STATUS_NO_MEMORY;
4568 /* find the policy handle. open a policy on it. */
4569 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4570 return NT_STATUS_INVALID_HANDLE;
4572 status = access_check_samr_function(acc_granted,
4573 SA_RIGHT_GROUP_GET_MEMBERS,
4574 "_samr_QueryGroupMember");
4575 if (!NT_STATUS_IS_OK(status)) {
4576 return status;
4579 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4581 if (!sid_check_is_in_our_domain(&group_sid)) {
4582 DEBUG(3, ("sid %s is not in our domain\n",
4583 sid_string_dbg(&group_sid)));
4584 return NT_STATUS_NO_SUCH_GROUP;
4587 DEBUG(10, ("lookup on Domain SID\n"));
4589 become_root();
4590 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4591 &rid, &num_members);
4592 unbecome_root();
4594 if (!NT_STATUS_IS_OK(status))
4595 return status;
4597 if (num_members) {
4598 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4599 if (attr == NULL) {
4600 return NT_STATUS_NO_MEMORY;
4602 } else {
4603 attr = NULL;
4606 for (i=0; i<num_members; i++)
4607 attr[i] = SID_NAME_USER;
4609 rids->count = num_members;
4610 rids->types = attr;
4611 rids->rids = rid;
4613 *r->out.rids = rids;
4615 return NT_STATUS_OK;
4618 /*********************************************************************
4619 _samr_AddAliasMember
4620 *********************************************************************/
4622 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4623 struct samr_AddAliasMember *r)
4625 DOM_SID alias_sid;
4626 uint32 acc_granted;
4627 SE_PRIV se_rights;
4628 bool can_add_accounts;
4629 NTSTATUS status;
4630 DISP_INFO *disp_info = NULL;
4632 /* Find the policy handle. Open a policy on it. */
4633 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4634 return NT_STATUS_INVALID_HANDLE;
4636 status = access_check_samr_function(acc_granted,
4637 SA_RIGHT_ALIAS_ADD_MEMBER,
4638 "_samr_AddAliasMember");
4639 if (!NT_STATUS_IS_OK(status)) {
4640 return status;
4643 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4645 se_priv_copy( &se_rights, &se_add_users );
4646 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4648 /******** BEGIN SeAddUsers BLOCK *********/
4650 if ( can_add_accounts )
4651 become_root();
4653 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4655 if ( can_add_accounts )
4656 unbecome_root();
4658 /******** END SeAddUsers BLOCK *********/
4660 if (NT_STATUS_IS_OK(status)) {
4661 force_flush_samr_cache(disp_info);
4664 return status;
4667 /*********************************************************************
4668 _samr_DeleteAliasMember
4669 *********************************************************************/
4671 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4672 struct samr_DeleteAliasMember *r)
4674 DOM_SID alias_sid;
4675 uint32 acc_granted;
4676 SE_PRIV se_rights;
4677 bool can_add_accounts;
4678 NTSTATUS status;
4679 DISP_INFO *disp_info = NULL;
4681 /* Find the policy handle. Open a policy on it. */
4682 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4683 return NT_STATUS_INVALID_HANDLE;
4685 status = access_check_samr_function(acc_granted,
4686 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4687 "_samr_DeleteAliasMember");
4688 if (!NT_STATUS_IS_OK(status)) {
4689 return status;
4692 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4693 sid_string_dbg(&alias_sid)));
4695 se_priv_copy( &se_rights, &se_add_users );
4696 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4698 /******** BEGIN SeAddUsers BLOCK *********/
4700 if ( can_add_accounts )
4701 become_root();
4703 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4705 if ( can_add_accounts )
4706 unbecome_root();
4708 /******** END SeAddUsers BLOCK *********/
4710 if (NT_STATUS_IS_OK(status)) {
4711 force_flush_samr_cache(disp_info);
4714 return status;
4717 /*********************************************************************
4718 _samr_AddGroupMember
4719 *********************************************************************/
4721 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4722 struct samr_AddGroupMember *r)
4724 NTSTATUS status;
4725 DOM_SID group_sid;
4726 uint32 group_rid;
4727 uint32 acc_granted;
4728 SE_PRIV se_rights;
4729 bool can_add_accounts;
4730 DISP_INFO *disp_info = NULL;
4732 /* Find the policy handle. Open a policy on it. */
4733 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4734 return NT_STATUS_INVALID_HANDLE;
4736 status = access_check_samr_function(acc_granted,
4737 SA_RIGHT_GROUP_ADD_MEMBER,
4738 "_samr_AddGroupMember");
4739 if (!NT_STATUS_IS_OK(status)) {
4740 return status;
4743 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4745 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4746 &group_rid)) {
4747 return NT_STATUS_INVALID_HANDLE;
4750 se_priv_copy( &se_rights, &se_add_users );
4751 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4753 /******** BEGIN SeAddUsers BLOCK *********/
4755 if ( can_add_accounts )
4756 become_root();
4758 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4760 if ( can_add_accounts )
4761 unbecome_root();
4763 /******** END SeAddUsers BLOCK *********/
4765 force_flush_samr_cache(disp_info);
4767 return status;
4770 /*********************************************************************
4771 _samr_DeleteGroupMember
4772 *********************************************************************/
4774 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4775 struct samr_DeleteGroupMember *r)
4778 NTSTATUS status;
4779 DOM_SID group_sid;
4780 uint32 group_rid;
4781 uint32 acc_granted;
4782 SE_PRIV se_rights;
4783 bool can_add_accounts;
4784 DISP_INFO *disp_info = NULL;
4787 * delete the group member named r->in.rid
4788 * who is a member of the sid associated with the handle
4789 * the rid is a user's rid as the group is a domain group.
4792 /* Find the policy handle. Open a policy on it. */
4793 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4794 return NT_STATUS_INVALID_HANDLE;
4796 status = access_check_samr_function(acc_granted,
4797 SA_RIGHT_GROUP_REMOVE_MEMBER,
4798 "_samr_DeleteGroupMember");
4799 if (!NT_STATUS_IS_OK(status)) {
4800 return status;
4803 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4804 &group_rid)) {
4805 return NT_STATUS_INVALID_HANDLE;
4808 se_priv_copy( &se_rights, &se_add_users );
4809 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4811 /******** BEGIN SeAddUsers BLOCK *********/
4813 if ( can_add_accounts )
4814 become_root();
4816 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4818 if ( can_add_accounts )
4819 unbecome_root();
4821 /******** END SeAddUsers BLOCK *********/
4823 force_flush_samr_cache(disp_info);
4825 return status;
4828 /*********************************************************************
4829 _samr_DeleteUser
4830 *********************************************************************/
4832 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4833 struct samr_DeleteUser *r)
4835 NTSTATUS status;
4836 DOM_SID user_sid;
4837 struct samu *sam_pass=NULL;
4838 uint32 acc_granted;
4839 bool can_add_accounts;
4840 uint32 acb_info;
4841 DISP_INFO *disp_info = NULL;
4842 bool ret;
4844 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4846 /* Find the policy handle. Open a policy on it. */
4847 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4848 return NT_STATUS_INVALID_HANDLE;
4850 status = access_check_samr_function(acc_granted,
4851 STD_RIGHT_DELETE_ACCESS,
4852 "_samr_DeleteUser");
4853 if (!NT_STATUS_IS_OK(status)) {
4854 return status;
4857 if (!sid_check_is_in_our_domain(&user_sid))
4858 return NT_STATUS_CANNOT_DELETE;
4860 /* check if the user exists before trying to delete */
4861 if ( !(sam_pass = samu_new( NULL )) ) {
4862 return NT_STATUS_NO_MEMORY;
4865 become_root();
4866 ret = pdb_getsampwsid(sam_pass, &user_sid);
4867 unbecome_root();
4869 if( !ret ) {
4870 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4871 sid_string_dbg(&user_sid)));
4872 TALLOC_FREE(sam_pass);
4873 return NT_STATUS_NO_SUCH_USER;
4876 acb_info = pdb_get_acct_ctrl(sam_pass);
4878 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4879 if ( acb_info & ACB_WSTRUST ) {
4880 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4881 } else {
4882 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4885 /******** BEGIN SeAddUsers BLOCK *********/
4887 if ( can_add_accounts )
4888 become_root();
4890 status = pdb_delete_user(p->mem_ctx, sam_pass);
4892 if ( can_add_accounts )
4893 unbecome_root();
4895 /******** END SeAddUsers BLOCK *********/
4897 if ( !NT_STATUS_IS_OK(status) ) {
4898 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4899 "user %s: %s.\n", pdb_get_username(sam_pass),
4900 nt_errstr(status)));
4901 TALLOC_FREE(sam_pass);
4902 return status;
4906 TALLOC_FREE(sam_pass);
4908 if (!close_policy_hnd(p, r->in.user_handle))
4909 return NT_STATUS_OBJECT_NAME_INVALID;
4911 ZERO_STRUCTP(r->out.user_handle);
4913 force_flush_samr_cache(disp_info);
4915 return NT_STATUS_OK;
4918 /*********************************************************************
4919 _samr_DeleteDomainGroup
4920 *********************************************************************/
4922 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4923 struct samr_DeleteDomainGroup *r)
4925 NTSTATUS status;
4926 DOM_SID group_sid;
4927 uint32 group_rid;
4928 uint32 acc_granted;
4929 SE_PRIV se_rights;
4930 bool can_add_accounts;
4931 DISP_INFO *disp_info = NULL;
4933 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4935 /* Find the policy handle. Open a policy on it. */
4936 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4937 return NT_STATUS_INVALID_HANDLE;
4939 status = access_check_samr_function(acc_granted,
4940 STD_RIGHT_DELETE_ACCESS,
4941 "_samr_DeleteDomainGroup");
4942 if (!NT_STATUS_IS_OK(status)) {
4943 return status;
4946 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4948 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4949 &group_rid)) {
4950 return NT_STATUS_NO_SUCH_GROUP;
4953 se_priv_copy( &se_rights, &se_add_users );
4954 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4956 /******** BEGIN SeAddUsers BLOCK *********/
4958 if ( can_add_accounts )
4959 become_root();
4961 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4963 if ( can_add_accounts )
4964 unbecome_root();
4966 /******** END SeAddUsers BLOCK *********/
4968 if ( !NT_STATUS_IS_OK(status) ) {
4969 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4970 "entry for group %s: %s\n",
4971 sid_string_dbg(&group_sid),
4972 nt_errstr(status)));
4973 return status;
4976 if (!close_policy_hnd(p, r->in.group_handle))
4977 return NT_STATUS_OBJECT_NAME_INVALID;
4979 force_flush_samr_cache(disp_info);
4981 return NT_STATUS_OK;
4984 /*********************************************************************
4985 _samr_DeleteDomAlias
4986 *********************************************************************/
4988 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4989 struct samr_DeleteDomAlias *r)
4991 DOM_SID alias_sid;
4992 uint32 acc_granted;
4993 SE_PRIV se_rights;
4994 bool can_add_accounts;
4995 NTSTATUS status;
4996 DISP_INFO *disp_info = NULL;
4998 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5000 /* Find the policy handle. Open a policy on it. */
5001 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5002 return NT_STATUS_INVALID_HANDLE;
5004 /* copy the handle to the outgoing reply */
5006 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
5008 status = access_check_samr_function(acc_granted,
5009 STD_RIGHT_DELETE_ACCESS,
5010 "_samr_DeleteDomAlias");
5011 if (!NT_STATUS_IS_OK(status)) {
5012 return status;
5015 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5017 /* Don't let Windows delete builtin groups */
5019 if ( sid_check_is_in_builtin( &alias_sid ) ) {
5020 return NT_STATUS_SPECIAL_ACCOUNT;
5023 if (!sid_check_is_in_our_domain(&alias_sid))
5024 return NT_STATUS_NO_SUCH_ALIAS;
5026 DEBUG(10, ("lookup on Local SID\n"));
5028 se_priv_copy( &se_rights, &se_add_users );
5029 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5031 /******** BEGIN SeAddUsers BLOCK *********/
5033 if ( can_add_accounts )
5034 become_root();
5036 /* Have passdb delete the alias */
5037 status = pdb_delete_alias(&alias_sid);
5039 if ( can_add_accounts )
5040 unbecome_root();
5042 /******** END SeAddUsers BLOCK *********/
5044 if ( !NT_STATUS_IS_OK(status))
5045 return status;
5047 if (!close_policy_hnd(p, r->in.alias_handle))
5048 return NT_STATUS_OBJECT_NAME_INVALID;
5050 force_flush_samr_cache(disp_info);
5052 return NT_STATUS_OK;
5055 /*********************************************************************
5056 _samr_CreateDomainGroup
5057 *********************************************************************/
5059 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5060 struct samr_CreateDomainGroup *r)
5063 NTSTATUS status;
5064 DOM_SID dom_sid;
5065 DOM_SID info_sid;
5066 const char *name;
5067 struct samr_info *info;
5068 uint32 acc_granted;
5069 SE_PRIV se_rights;
5070 bool can_add_accounts;
5071 DISP_INFO *disp_info = NULL;
5073 /* Find the policy handle. Open a policy on it. */
5074 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5075 return NT_STATUS_INVALID_HANDLE;
5077 status = access_check_samr_function(acc_granted,
5078 SA_RIGHT_DOMAIN_CREATE_GROUP,
5079 "_samr_CreateDomainGroup");
5080 if (!NT_STATUS_IS_OK(status)) {
5081 return status;
5084 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5085 return NT_STATUS_ACCESS_DENIED;
5087 name = r->in.name->string;
5088 if (name == NULL) {
5089 return NT_STATUS_NO_MEMORY;
5092 status = can_create(p->mem_ctx, name);
5093 if (!NT_STATUS_IS_OK(status)) {
5094 return status;
5097 se_priv_copy( &se_rights, &se_add_users );
5098 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5100 /******** BEGIN SeAddUsers BLOCK *********/
5102 if ( can_add_accounts )
5103 become_root();
5105 /* check that we successfully create the UNIX group */
5107 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5109 if ( can_add_accounts )
5110 unbecome_root();
5112 /******** END SeAddUsers BLOCK *********/
5114 /* check if we should bail out here */
5116 if ( !NT_STATUS_IS_OK(status) )
5117 return status;
5119 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5121 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5122 return NT_STATUS_NO_MEMORY;
5124 /* they created it; let the user do what he wants with it */
5126 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5128 /* get a (unique) handle. open a policy on it. */
5129 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5130 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5132 force_flush_samr_cache(disp_info);
5134 return NT_STATUS_OK;
5137 /*********************************************************************
5138 _samr_CreateDomAlias
5139 *********************************************************************/
5141 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5142 struct samr_CreateDomAlias *r)
5144 DOM_SID dom_sid;
5145 DOM_SID info_sid;
5146 const char *name = NULL;
5147 struct samr_info *info;
5148 uint32 acc_granted;
5149 gid_t gid;
5150 NTSTATUS result;
5151 SE_PRIV se_rights;
5152 bool can_add_accounts;
5153 DISP_INFO *disp_info = NULL;
5155 /* Find the policy handle. Open a policy on it. */
5156 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5157 return NT_STATUS_INVALID_HANDLE;
5159 result = access_check_samr_function(acc_granted,
5160 SA_RIGHT_DOMAIN_CREATE_ALIAS,
5161 "_samr_CreateDomAlias");
5162 if (!NT_STATUS_IS_OK(result)) {
5163 return result;
5166 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5167 return NT_STATUS_ACCESS_DENIED;
5169 name = r->in.alias_name->string;
5171 se_priv_copy( &se_rights, &se_add_users );
5172 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5174 result = can_create(p->mem_ctx, name);
5175 if (!NT_STATUS_IS_OK(result)) {
5176 return result;
5179 /******** BEGIN SeAddUsers BLOCK *********/
5181 if ( can_add_accounts )
5182 become_root();
5184 /* Have passdb create the alias */
5185 result = pdb_create_alias(name, r->out.rid);
5187 if ( can_add_accounts )
5188 unbecome_root();
5190 /******** END SeAddUsers BLOCK *********/
5192 if (!NT_STATUS_IS_OK(result)) {
5193 DEBUG(10, ("pdb_create_alias failed: %s\n",
5194 nt_errstr(result)));
5195 return result;
5198 sid_copy(&info_sid, get_global_sam_sid());
5199 sid_append_rid(&info_sid, *r->out.rid);
5201 if (!sid_to_gid(&info_sid, &gid)) {
5202 DEBUG(10, ("Could not find alias just created\n"));
5203 return NT_STATUS_ACCESS_DENIED;
5206 /* check if the group has been successfully created */
5207 if ( getgrgid(gid) == NULL ) {
5208 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5209 gid));
5210 return NT_STATUS_ACCESS_DENIED;
5213 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5214 return NT_STATUS_NO_MEMORY;
5216 /* they created it; let the user do what he wants with it */
5218 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5220 /* get a (unique) handle. open a policy on it. */
5221 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5222 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5224 force_flush_samr_cache(disp_info);
5226 return NT_STATUS_OK;
5229 /*********************************************************************
5230 _samr_QueryGroupInfo
5231 *********************************************************************/
5233 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5234 struct samr_QueryGroupInfo *r)
5236 NTSTATUS status;
5237 DOM_SID group_sid;
5238 GROUP_MAP map;
5239 union samr_GroupInfo *info = NULL;
5240 uint32 acc_granted;
5241 bool ret;
5242 uint32_t attributes = SE_GROUP_MANDATORY |
5243 SE_GROUP_ENABLED_BY_DEFAULT |
5244 SE_GROUP_ENABLED;
5245 const char *group_name = NULL;
5246 const char *group_description = NULL;
5248 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5249 return NT_STATUS_INVALID_HANDLE;
5251 status = access_check_samr_function(acc_granted,
5252 SA_RIGHT_GROUP_LOOKUP_INFO,
5253 "_samr_QueryGroupInfo");
5254 if (!NT_STATUS_IS_OK(status)) {
5255 return status;
5258 become_root();
5259 ret = get_domain_group_from_sid(group_sid, &map);
5260 unbecome_root();
5261 if (!ret)
5262 return NT_STATUS_INVALID_HANDLE;
5264 /* FIXME: map contains fstrings */
5265 group_name = talloc_strdup(r, map.nt_name);
5266 group_description = talloc_strdup(r, map.comment);
5268 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5269 if (!info) {
5270 return NT_STATUS_NO_MEMORY;
5273 switch (r->in.level) {
5274 case 1: {
5275 uint32 *members;
5276 size_t num_members;
5278 become_root();
5279 status = pdb_enum_group_members(
5280 p->mem_ctx, &group_sid, &members, &num_members);
5281 unbecome_root();
5283 if (!NT_STATUS_IS_OK(status)) {
5284 return status;
5287 init_samr_group_info1(&info->all,
5288 group_name,
5289 attributes,
5290 num_members,
5291 group_description);
5292 break;
5294 case 2:
5295 init_samr_group_info2(&info->name,
5296 group_name);
5297 break;
5298 case 3:
5299 init_samr_group_info3(&info->attributes,
5300 attributes);
5301 break;
5302 case 4:
5303 init_samr_group_info4(&info->description,
5304 group_description);
5305 break;
5306 case 5: {
5308 uint32 *members;
5309 size_t num_members;
5313 become_root();
5314 status = pdb_enum_group_members(
5315 p->mem_ctx, &group_sid, &members, &num_members);
5316 unbecome_root();
5318 if (!NT_STATUS_IS_OK(status)) {
5319 return status;
5322 init_samr_group_info5(&info->all2,
5323 group_name,
5324 attributes,
5325 0, /* num_members - in w2k3 this is always 0 */
5326 group_description);
5328 break;
5330 default:
5331 return NT_STATUS_INVALID_INFO_CLASS;
5334 *r->out.info = info;
5336 return NT_STATUS_OK;
5339 /*********************************************************************
5340 _samr_SetGroupInfo
5341 *********************************************************************/
5343 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5344 struct samr_SetGroupInfo *r)
5346 DOM_SID group_sid;
5347 GROUP_MAP map;
5348 uint32 acc_granted;
5349 NTSTATUS status;
5350 bool ret;
5351 bool can_mod_accounts;
5352 DISP_INFO *disp_info = NULL;
5354 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5355 return NT_STATUS_INVALID_HANDLE;
5357 status = access_check_samr_function(acc_granted,
5358 SA_RIGHT_GROUP_SET_INFO,
5359 "_samr_SetGroupInfo");
5360 if (!NT_STATUS_IS_OK(status)) {
5361 return status;
5364 become_root();
5365 ret = get_domain_group_from_sid(group_sid, &map);
5366 unbecome_root();
5367 if (!ret)
5368 return NT_STATUS_NO_SUCH_GROUP;
5370 switch (r->in.level) {
5371 case 1:
5372 fstrcpy(map.comment, r->in.info->all.description.string);
5373 break;
5374 case 4:
5375 fstrcpy(map.comment, r->in.info->description.string);
5376 break;
5377 default:
5378 return NT_STATUS_INVALID_INFO_CLASS;
5381 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5383 /******** BEGIN SeAddUsers BLOCK *********/
5385 if ( can_mod_accounts )
5386 become_root();
5388 status = pdb_update_group_mapping_entry(&map);
5390 if ( can_mod_accounts )
5391 unbecome_root();
5393 /******** End SeAddUsers BLOCK *********/
5395 if (NT_STATUS_IS_OK(status)) {
5396 force_flush_samr_cache(disp_info);
5399 return status;
5402 /*********************************************************************
5403 _samr_SetAliasInfo
5404 *********************************************************************/
5406 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5407 struct samr_SetAliasInfo *r)
5409 DOM_SID group_sid;
5410 struct acct_info info;
5411 uint32 acc_granted;
5412 bool can_mod_accounts;
5413 NTSTATUS status;
5414 DISP_INFO *disp_info = NULL;
5416 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5417 return NT_STATUS_INVALID_HANDLE;
5419 status = access_check_samr_function(acc_granted,
5420 SA_RIGHT_ALIAS_SET_INFO,
5421 "_samr_SetAliasInfo");
5422 if (!NT_STATUS_IS_OK(status)) {
5423 return status;
5426 /* get the current group information */
5428 become_root();
5429 status = pdb_get_aliasinfo( &group_sid, &info );
5430 unbecome_root();
5432 if ( !NT_STATUS_IS_OK(status))
5433 return status;
5435 switch (r->in.level) {
5436 case ALIASINFONAME:
5438 fstring group_name;
5440 /* We currently do not support renaming groups in the
5441 the BUILTIN domain. Refer to util_builtin.c to understand
5442 why. The eventually needs to be fixed to be like Windows
5443 where you can rename builtin groups, just not delete them */
5445 if ( sid_check_is_in_builtin( &group_sid ) ) {
5446 return NT_STATUS_SPECIAL_ACCOUNT;
5449 /* There has to be a valid name (and it has to be different) */
5451 if ( !r->in.info->name.string )
5452 return NT_STATUS_INVALID_PARAMETER;
5454 /* If the name is the same just reply "ok". Yes this
5455 doesn't allow you to change the case of a group name. */
5457 if ( strequal( r->in.info->name.string, info.acct_name ) )
5458 return NT_STATUS_OK;
5460 fstrcpy( info.acct_name, r->in.info->name.string);
5462 /* make sure the name doesn't already exist as a user
5463 or local group */
5465 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5466 status = can_create( p->mem_ctx, group_name );
5467 if ( !NT_STATUS_IS_OK( status ) )
5468 return status;
5469 break;
5471 case ALIASINFODESCRIPTION:
5472 if (r->in.info->description.string) {
5473 fstrcpy(info.acct_desc,
5474 r->in.info->description.string);
5475 } else {
5476 fstrcpy( info.acct_desc, "" );
5478 break;
5479 default:
5480 return NT_STATUS_INVALID_INFO_CLASS;
5483 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5485 /******** BEGIN SeAddUsers BLOCK *********/
5487 if ( can_mod_accounts )
5488 become_root();
5490 status = pdb_set_aliasinfo( &group_sid, &info );
5492 if ( can_mod_accounts )
5493 unbecome_root();
5495 /******** End SeAddUsers BLOCK *********/
5497 if (NT_STATUS_IS_OK(status))
5498 force_flush_samr_cache(disp_info);
5500 return status;
5503 /****************************************************************
5504 _samr_GetDomPwInfo
5505 ****************************************************************/
5507 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5508 struct samr_GetDomPwInfo *r)
5510 uint32_t min_password_length = 0;
5511 uint32_t password_properties = 0;
5513 /* Perform access check. Since this rpc does not require a
5514 policy handle it will not be caught by the access checks on
5515 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5517 if (!pipe_access_check(p)) {
5518 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5519 return NT_STATUS_ACCESS_DENIED;
5522 become_root();
5523 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5524 &min_password_length);
5525 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5526 &password_properties);
5527 unbecome_root();
5529 if (lp_check_password_script() && *lp_check_password_script()) {
5530 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5533 r->out.info->min_password_length = min_password_length;
5534 r->out.info->password_properties = password_properties;
5536 return NT_STATUS_OK;
5539 /*********************************************************************
5540 _samr_OpenGroup
5541 *********************************************************************/
5543 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5544 struct samr_OpenGroup *r)
5547 DOM_SID sid;
5548 DOM_SID info_sid;
5549 GROUP_MAP map;
5550 struct samr_info *info;
5551 SEC_DESC *psd = NULL;
5552 uint32 acc_granted;
5553 uint32 des_access = r->in.access_mask;
5554 size_t sd_size;
5555 NTSTATUS status;
5556 fstring sid_string;
5557 bool ret;
5558 SE_PRIV se_rights;
5560 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5561 return NT_STATUS_INVALID_HANDLE;
5563 status = access_check_samr_function(acc_granted,
5564 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5565 "_samr_OpenGroup");
5567 if ( !NT_STATUS_IS_OK(status) )
5568 return status;
5570 /*check if access can be granted as requested by client. */
5571 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
5573 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5574 se_map_generic(&des_access,&grp_generic_mapping);
5576 se_priv_copy( &se_rights, &se_add_users );
5578 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5579 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5580 &acc_granted, "_samr_OpenGroup");
5582 if ( !NT_STATUS_IS_OK(status) )
5583 return status;
5585 /* this should not be hard-coded like this */
5587 if (!sid_equal(&sid, get_global_sam_sid()))
5588 return NT_STATUS_ACCESS_DENIED;
5590 sid_copy(&info_sid, get_global_sam_sid());
5591 sid_append_rid(&info_sid, r->in.rid);
5592 sid_to_fstring(sid_string, &info_sid);
5594 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5595 return NT_STATUS_NO_MEMORY;
5597 info->acc_granted = acc_granted;
5599 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5601 /* check if that group really exists */
5602 become_root();
5603 ret = get_domain_group_from_sid(info->sid, &map);
5604 unbecome_root();
5605 if (!ret)
5606 return NT_STATUS_NO_SUCH_GROUP;
5608 /* get a (unique) handle. open a policy on it. */
5609 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5610 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5612 return NT_STATUS_OK;
5615 /*********************************************************************
5616 _samr_RemoveMemberFromForeignDomain
5617 *********************************************************************/
5619 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5620 struct samr_RemoveMemberFromForeignDomain *r)
5622 DOM_SID delete_sid, domain_sid;
5623 uint32 acc_granted;
5624 NTSTATUS result;
5625 DISP_INFO *disp_info = NULL;
5627 sid_copy( &delete_sid, r->in.sid );
5629 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5630 sid_string_dbg(&delete_sid)));
5632 /* Find the policy handle. Open a policy on it. */
5634 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5635 &acc_granted, &disp_info))
5636 return NT_STATUS_INVALID_HANDLE;
5638 result = access_check_samr_function(acc_granted,
5639 STD_RIGHT_DELETE_ACCESS,
5640 "_samr_RemoveMemberFromForeignDomain");
5642 if (!NT_STATUS_IS_OK(result))
5643 return result;
5645 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5646 sid_string_dbg(&domain_sid)));
5648 /* we can only delete a user from a group since we don't have
5649 nested groups anyways. So in the latter case, just say OK */
5651 /* TODO: The above comment nowadays is bogus. Since we have nested
5652 * groups now, and aliases members are never reported out of the unix
5653 * group membership, the "just say OK" makes this call a no-op. For
5654 * us. This needs fixing however. */
5656 /* I've only ever seen this in the wild when deleting a user from
5657 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5658 * is the user about to be deleted. I very much suspect this is the
5659 * only application of this call. To verify this, let people report
5660 * other cases. */
5662 if (!sid_check_is_builtin(&domain_sid)) {
5663 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5664 "global_sam_sid() = %s\n",
5665 sid_string_dbg(&domain_sid),
5666 sid_string_dbg(get_global_sam_sid())));
5667 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5668 return NT_STATUS_OK;
5671 force_flush_samr_cache(disp_info);
5673 result = NT_STATUS_OK;
5675 return result;
5678 /*******************************************************************
5679 _samr_QueryDomainInfo2
5680 ********************************************************************/
5682 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5683 struct samr_QueryDomainInfo2 *r)
5685 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5687 r->in.domain_handle,
5688 r->in.level,
5689 r->out.info);
5692 /*******************************************************************
5693 _samr_SetDomainInfo
5694 ********************************************************************/
5696 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5697 struct samr_SetDomainInfo *r)
5699 struct samr_info *info = NULL;
5700 time_t u_expire, u_min_age;
5701 time_t u_logout;
5702 time_t u_lock_duration, u_reset_time;
5703 NTSTATUS result;
5705 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5707 /* find the policy handle. open a policy on it. */
5708 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5709 return NT_STATUS_INVALID_HANDLE;
5711 /* We do have different access bits for info
5712 * levels here, but we're really just looking for
5713 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5714 * this maps to different specific bits. So
5715 * assume if we have SA_RIGHT_DOMAIN_SET_INFO_1
5716 * set we are ok. */
5718 result = access_check_samr_function(info->acc_granted,
5719 SA_RIGHT_DOMAIN_SET_INFO_1,
5720 "_samr_SetDomainInfo");
5722 if (!NT_STATUS_IS_OK(result))
5723 return result;
5725 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5727 switch (r->in.level) {
5728 case 0x01:
5729 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5730 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5731 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5732 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5733 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5734 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5735 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5736 break;
5737 case 0x02:
5738 break;
5739 case 0x03:
5740 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5741 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5742 break;
5743 case 0x05:
5744 break;
5745 case 0x06:
5746 break;
5747 case 0x07:
5748 break;
5749 case 0x0c:
5750 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5751 if (u_lock_duration != -1)
5752 u_lock_duration /= 60;
5754 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5756 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5757 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5758 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5759 break;
5760 default:
5761 return NT_STATUS_INVALID_INFO_CLASS;
5764 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5766 return NT_STATUS_OK;
5769 /****************************************************************
5770 _samr_GetDisplayEnumerationIndex
5771 ****************************************************************/
5773 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5774 struct samr_GetDisplayEnumerationIndex *r)
5776 struct samr_info *info = NULL;
5777 uint32_t max_entries = (uint32_t) -1;
5778 uint32_t enum_context = 0;
5779 int i;
5780 uint32_t num_account = 0;
5781 struct samr_displayentry *entries = NULL;
5782 NTSTATUS status;
5784 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5786 /* find the policy handle. open a policy on it. */
5787 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5788 return NT_STATUS_INVALID_HANDLE;
5791 status = access_check_samr_function(info->acc_granted,
5792 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
5793 "_samr_GetDisplayEnumerationIndex");
5794 if (!NT_STATUS_IS_OK(status)) {
5795 return status;
5798 if ((r->in.level < 1) || (r->in.level > 3)) {
5799 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5800 "Unknown info level (%u)\n",
5801 r->in.level));
5802 return NT_STATUS_INVALID_INFO_CLASS;
5805 become_root();
5807 /* The following done as ROOT. Don't return without unbecome_root(). */
5809 switch (r->in.level) {
5810 case 1:
5811 if (info->disp_info->users == NULL) {
5812 info->disp_info->users = pdb_search_users(ACB_NORMAL);
5813 if (info->disp_info->users == NULL) {
5814 unbecome_root();
5815 return NT_STATUS_ACCESS_DENIED;
5817 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5818 "starting user enumeration at index %u\n",
5819 (unsigned int)enum_context));
5820 } else {
5821 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5822 "using cached user enumeration at index %u\n",
5823 (unsigned int)enum_context));
5825 num_account = pdb_search_entries(info->disp_info->users,
5826 enum_context, max_entries,
5827 &entries);
5828 break;
5829 case 2:
5830 if (info->disp_info->machines == NULL) {
5831 info->disp_info->machines =
5832 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5833 if (info->disp_info->machines == NULL) {
5834 unbecome_root();
5835 return NT_STATUS_ACCESS_DENIED;
5837 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5838 "starting machine enumeration at index %u\n",
5839 (unsigned int)enum_context));
5840 } else {
5841 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5842 "using cached machine enumeration at index %u\n",
5843 (unsigned int)enum_context));
5845 num_account = pdb_search_entries(info->disp_info->machines,
5846 enum_context, max_entries,
5847 &entries);
5848 break;
5849 case 3:
5850 if (info->disp_info->groups == NULL) {
5851 info->disp_info->groups = pdb_search_groups();
5852 if (info->disp_info->groups == NULL) {
5853 unbecome_root();
5854 return NT_STATUS_ACCESS_DENIED;
5856 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5857 "starting group enumeration at index %u\n",
5858 (unsigned int)enum_context));
5859 } else {
5860 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5861 "using cached group enumeration at index %u\n",
5862 (unsigned int)enum_context));
5864 num_account = pdb_search_entries(info->disp_info->groups,
5865 enum_context, max_entries,
5866 &entries);
5867 break;
5868 default:
5869 unbecome_root();
5870 smb_panic("info class changed");
5871 break;
5874 unbecome_root();
5876 /* Ensure we cache this enumeration. */
5877 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5879 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5880 r->in.name->string));
5882 for (i=0; i<num_account; i++) {
5883 if (strequal(entries[i].account_name, r->in.name->string)) {
5884 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5885 "found %s at idx %d\n",
5886 r->in.name->string, i));
5887 *r->out.idx = i;
5888 return NT_STATUS_OK;
5892 /* assuming account_name lives at the very end */
5893 *r->out.idx = num_account;
5895 return NT_STATUS_NO_MORE_ENTRIES;
5898 /****************************************************************
5899 _samr_GetDisplayEnumerationIndex2
5900 ****************************************************************/
5902 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5903 struct samr_GetDisplayEnumerationIndex2 *r)
5905 struct samr_GetDisplayEnumerationIndex q;
5907 q.in.domain_handle = r->in.domain_handle;
5908 q.in.level = r->in.level;
5909 q.in.name = r->in.name;
5911 q.out.idx = r->out.idx;
5913 return _samr_GetDisplayEnumerationIndex(p, &q);
5916 /****************************************************************
5917 ****************************************************************/
5919 NTSTATUS _samr_Shutdown(pipes_struct *p,
5920 struct samr_Shutdown *r)
5922 p->rng_fault_state = true;
5923 return NT_STATUS_NOT_IMPLEMENTED;
5926 /****************************************************************
5927 ****************************************************************/
5929 NTSTATUS _samr_CreateUser(pipes_struct *p,
5930 struct samr_CreateUser *r)
5932 p->rng_fault_state = true;
5933 return NT_STATUS_NOT_IMPLEMENTED;
5936 /****************************************************************
5937 ****************************************************************/
5939 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5940 struct samr_SetMemberAttributesOfGroup *r)
5942 p->rng_fault_state = true;
5943 return NT_STATUS_NOT_IMPLEMENTED;
5946 /****************************************************************
5947 ****************************************************************/
5949 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5950 struct samr_ChangePasswordUser *r)
5952 p->rng_fault_state = true;
5953 return NT_STATUS_NOT_IMPLEMENTED;
5956 /****************************************************************
5957 ****************************************************************/
5959 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5960 struct samr_TestPrivateFunctionsDomain *r)
5962 p->rng_fault_state = true;
5963 return NT_STATUS_NOT_IMPLEMENTED;
5966 /****************************************************************
5967 ****************************************************************/
5969 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5970 struct samr_TestPrivateFunctionsUser *r)
5972 p->rng_fault_state = true;
5973 return NT_STATUS_NOT_IMPLEMENTED;
5976 /****************************************************************
5977 ****************************************************************/
5979 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5980 struct samr_QueryUserInfo2 *r)
5982 p->rng_fault_state = true;
5983 return NT_STATUS_NOT_IMPLEMENTED;
5986 /****************************************************************
5987 ****************************************************************/
5989 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5990 struct samr_AddMultipleMembersToAlias *r)
5992 p->rng_fault_state = true;
5993 return NT_STATUS_NOT_IMPLEMENTED;
5996 /****************************************************************
5997 ****************************************************************/
5999 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6000 struct samr_RemoveMultipleMembersFromAlias *r)
6002 p->rng_fault_state = true;
6003 return NT_STATUS_NOT_IMPLEMENTED;
6006 /****************************************************************
6007 ****************************************************************/
6009 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
6010 struct samr_OemChangePasswordUser2 *r)
6012 p->rng_fault_state = true;
6013 return NT_STATUS_NOT_IMPLEMENTED;
6016 /****************************************************************
6017 ****************************************************************/
6019 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6020 struct samr_SetBootKeyInformation *r)
6022 p->rng_fault_state = true;
6023 return NT_STATUS_NOT_IMPLEMENTED;
6026 /****************************************************************
6027 ****************************************************************/
6029 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6030 struct samr_GetBootKeyInformation *r)
6032 p->rng_fault_state = true;
6033 return NT_STATUS_NOT_IMPLEMENTED;
6036 /****************************************************************
6037 ****************************************************************/
6039 NTSTATUS _samr_Connect3(pipes_struct *p,
6040 struct samr_Connect3 *r)
6042 p->rng_fault_state = true;
6043 return NT_STATUS_NOT_IMPLEMENTED;
6046 /****************************************************************
6047 ****************************************************************/
6049 NTSTATUS _samr_RidToSid(pipes_struct *p,
6050 struct samr_RidToSid *r)
6052 p->rng_fault_state = true;
6053 return NT_STATUS_NOT_IMPLEMENTED;
6056 /****************************************************************
6057 ****************************************************************/
6059 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6060 struct samr_SetDsrmPassword *r)
6062 p->rng_fault_state = true;
6063 return NT_STATUS_NOT_IMPLEMENTED;
6066 /****************************************************************
6067 ****************************************************************/
6069 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6070 struct samr_ValidatePassword *r)
6072 p->rng_fault_state = true;
6073 return NT_STATUS_NOT_IMPLEMENTED;