Fix SAMR server for winbindd access. Ensure we allow MAX_ACCESS to be mapped to what...
[Samba.git] / source / rpc_server / srv_samr_nt.c
blob92a198dd3b8dd3ec6058a478aa1faa72076e8d3c
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
34 #include "includes.h"
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SA_RIGHT_USER_CHANGE_PASSWORD | \
42 SA_RIGHT_USER_SET_LOC_COM )
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 typedef struct disp_info {
49 DOM_SID sid; /* identify which domain this is. */
50 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
51 struct pdb_search *users; /* querydispinfo 1 and 4 */
52 struct pdb_search *machines; /* querydispinfo 2 */
53 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
54 struct pdb_search *aliases; /* enumaliases */
56 uint16 enum_acb_mask;
57 struct pdb_search *enum_users; /* enumusers with a mask */
59 struct timed_event *cache_timeout_event; /* cache idle timeout
60 * handler. */
61 } DISP_INFO;
63 /* We keep a static list of these by SID as modern clients close down
64 all resources between each request in a complete enumeration. */
66 struct samr_info {
67 /* for use by the \PIPE\samr policy */
68 DOM_SID sid;
69 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
70 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
71 uint32 acc_granted;
72 DISP_INFO *disp_info;
73 TALLOC_CTX *mem_ctx;
76 static const struct generic_mapping sam_generic_mapping = {
77 GENERIC_RIGHTS_SAM_READ,
78 GENERIC_RIGHTS_SAM_WRITE,
79 GENERIC_RIGHTS_SAM_EXECUTE,
80 GENERIC_RIGHTS_SAM_ALL_ACCESS};
81 static const struct generic_mapping dom_generic_mapping = {
82 GENERIC_RIGHTS_DOMAIN_READ,
83 GENERIC_RIGHTS_DOMAIN_WRITE,
84 GENERIC_RIGHTS_DOMAIN_EXECUTE,
85 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
86 static const struct generic_mapping usr_generic_mapping = {
87 GENERIC_RIGHTS_USER_READ,
88 GENERIC_RIGHTS_USER_WRITE,
89 GENERIC_RIGHTS_USER_EXECUTE,
90 GENERIC_RIGHTS_USER_ALL_ACCESS};
91 static const struct generic_mapping usr_nopwchange_generic_mapping = {
92 GENERIC_RIGHTS_USER_READ,
93 GENERIC_RIGHTS_USER_WRITE,
94 GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
95 GENERIC_RIGHTS_USER_ALL_ACCESS};
96 static const struct generic_mapping grp_generic_mapping = {
97 GENERIC_RIGHTS_GROUP_READ,
98 GENERIC_RIGHTS_GROUP_WRITE,
99 GENERIC_RIGHTS_GROUP_EXECUTE,
100 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
101 static const struct generic_mapping ali_generic_mapping = {
102 GENERIC_RIGHTS_ALIAS_READ,
103 GENERIC_RIGHTS_ALIAS_WRITE,
104 GENERIC_RIGHTS_ALIAS_EXECUTE,
105 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
107 /*******************************************************************
108 *******************************************************************/
110 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
111 const struct generic_mapping *map,
112 DOM_SID *sid, uint32 sid_access )
114 DOM_SID domadmin_sid;
115 SEC_ACE ace[5]; /* at most 5 entries */
116 SEC_ACCESS mask;
117 size_t i = 0;
119 SEC_ACL *psa = NULL;
121 /* basic access for Everyone */
123 init_sec_access(&mask, map->generic_execute | map->generic_read );
124 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
126 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
128 init_sec_access(&mask, map->generic_all);
130 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
131 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
133 /* Add Full Access for Domain Admins if we are a DC */
135 if ( IS_DC ) {
136 sid_copy( &domadmin_sid, get_global_sam_sid() );
137 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
138 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
141 /* if we have a sid, give it some special access */
143 if ( sid ) {
144 init_sec_access( &mask, sid_access );
145 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
148 /* create the security descriptor */
150 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
151 return NT_STATUS_NO_MEMORY;
153 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
154 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
155 psa, sd_size)) == NULL)
156 return NT_STATUS_NO_MEMORY;
158 return NT_STATUS_OK;
161 /*******************************************************************
162 Checks if access to an object should be granted, and returns that
163 level of access for further checks.
164 ********************************************************************/
166 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
167 SE_PRIV *rights, uint32 rights_mask,
168 uint32 des_access, uint32 *acc_granted,
169 const char *debug )
171 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
172 uint32 saved_mask = 0;
174 /* check privileges; certain SAM access bits should be overridden
175 by privileges (mostly having to do with creating/modifying/deleting
176 users and groups) */
178 if ( rights && user_has_any_privilege( token, rights ) ) {
180 saved_mask = (des_access & rights_mask);
181 des_access &= ~saved_mask;
183 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
184 rights_mask));
188 /* check the security descriptor first */
190 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
191 goto done;
193 /* give root a free pass */
195 if ( geteuid() == sec_initial_uid() ) {
197 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
198 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
200 *acc_granted = des_access;
202 status = NT_STATUS_OK;
203 goto done;
207 done:
208 /* add in any bits saved during the privilege check (only
209 matters is status is ok) */
211 *acc_granted |= rights_mask;
213 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
214 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
215 des_access, *acc_granted));
217 return status;
220 /*******************************************************************
221 Checks if access to a function can be granted
222 ********************************************************************/
224 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
226 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
227 debug, acc_granted, acc_required));
229 /* check the security descriptor first */
231 if ( (acc_granted&acc_required) == acc_required )
232 return NT_STATUS_OK;
234 /* give root a free pass */
236 if (geteuid() == sec_initial_uid()) {
238 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
239 debug, acc_granted, acc_required));
240 DEBUGADD(4,("but overwritten by euid == 0\n"));
242 return NT_STATUS_OK;
245 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
246 debug, acc_granted, acc_required));
248 return NT_STATUS_ACCESS_DENIED;
251 /*******************************************************************
252 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
253 ********************************************************************/
255 static void map_max_allowed_access(const NT_USER_TOKEN *token,
256 uint32_t *pacc_requested)
258 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
259 return;
261 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
263 /* At least try for generic read|execute - Everyone gets that. */
264 *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
266 /* root gets anything. */
267 if (geteuid() == sec_initial_uid()) {
268 *pacc_requested |= GENERIC_ALL_ACCESS;
269 return;
272 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
274 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
275 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
276 *pacc_requested |= GENERIC_ALL_ACCESS;
277 return;
280 /* Full access for DOMAIN\Domain Admins. */
281 if ( IS_DC ) {
282 DOM_SID domadmin_sid;
283 sid_copy( &domadmin_sid, get_global_sam_sid() );
284 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
285 if (is_sid_in_token(token, &domadmin_sid)) {
286 *pacc_requested |= GENERIC_ALL_ACCESS;
287 return;
290 /* TODO ! Check privileges. */
293 /*******************************************************************
294 Fetch or create a dispinfo struct.
295 ********************************************************************/
297 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
300 * We do a static cache for DISP_INFO's here. Explanation can be found
301 * in Jeremy's checkin message to r11793:
303 * Fix the SAMR cache so it works across completely insane
304 * client behaviour (ie.:
305 * open pipe/open SAMR handle/enumerate 0 - 1024
306 * close SAMR handle, close pipe.
307 * open pipe/open SAMR handle/enumerate 1024 - 2048...
308 * close SAMR handle, close pipe.
309 * And on ad-nausium. Amazing.... probably object-oriented
310 * client side programming in action yet again.
311 * This change should *massively* improve performance when
312 * enumerating users from an LDAP database.
313 * Jeremy.
315 * "Our" and the builtin domain are the only ones where we ever
316 * enumerate stuff, so just cache 2 entries.
319 static struct disp_info builtin_dispinfo;
320 static struct disp_info domain_dispinfo;
322 /* There are two cases to consider here:
323 1) The SID is a domain SID and we look for an equality match, or
324 2) This is an account SID and so we return the DISP_INFO* for our
325 domain */
327 if (psid == NULL) {
328 return NULL;
331 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
333 * Necessary only once, but it does not really hurt.
335 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
337 return &builtin_dispinfo;
340 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
342 * Necessary only once, but it does not really hurt.
344 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
346 return &domain_dispinfo;
349 return NULL;
352 /*******************************************************************
353 Create a samr_info struct.
354 ********************************************************************/
356 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
358 struct samr_info *info;
359 fstring sid_str;
360 TALLOC_CTX *mem_ctx;
362 if (psid) {
363 sid_to_fstring(sid_str, psid);
364 } else {
365 fstrcpy(sid_str,"(NULL)");
368 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
370 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
371 return NULL;
373 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
374 if (psid) {
375 sid_copy( &info->sid, psid);
376 info->builtin_domain = sid_check_is_builtin(psid);
377 } else {
378 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
379 info->builtin_domain = False;
381 info->mem_ctx = mem_ctx;
383 info->disp_info = get_samr_dispinfo_by_sid(psid);
385 return info;
388 /*******************************************************************
389 Function to free the per SID data.
390 ********************************************************************/
392 static void free_samr_cache(DISP_INFO *disp_info)
394 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
395 sid_string_dbg(&disp_info->sid)));
397 /* We need to become root here because the paged search might have to
398 * tell the LDAP server we're not interested in the rest anymore. */
400 become_root();
402 if (disp_info->users) {
403 DEBUG(10,("free_samr_cache: deleting users cache\n"));
404 pdb_search_destroy(disp_info->users);
405 disp_info->users = NULL;
407 if (disp_info->machines) {
408 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
409 pdb_search_destroy(disp_info->machines);
410 disp_info->machines = NULL;
412 if (disp_info->groups) {
413 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
414 pdb_search_destroy(disp_info->groups);
415 disp_info->groups = NULL;
417 if (disp_info->aliases) {
418 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
419 pdb_search_destroy(disp_info->aliases);
420 disp_info->aliases = NULL;
422 if (disp_info->enum_users) {
423 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
424 pdb_search_destroy(disp_info->enum_users);
425 disp_info->enum_users = NULL;
427 disp_info->enum_acb_mask = 0;
429 unbecome_root();
432 /*******************************************************************
433 Function to free the per handle data.
434 ********************************************************************/
436 static void free_samr_info(void *ptr)
438 struct samr_info *info=(struct samr_info *) ptr;
440 /* Only free the dispinfo cache if no one bothered to set up
441 a timeout. */
443 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
444 free_samr_cache(info->disp_info);
447 talloc_destroy(info->mem_ctx);
450 /*******************************************************************
451 Idle event handler. Throw away the disp info cache.
452 ********************************************************************/
454 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
455 struct timed_event *te,
456 const struct timeval *now,
457 void *private_data)
459 DISP_INFO *disp_info = (DISP_INFO *)private_data;
461 TALLOC_FREE(disp_info->cache_timeout_event);
463 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
464 "out\n"));
465 free_samr_cache(disp_info);
468 /*******************************************************************
469 Setup cache removal idle event handler.
470 ********************************************************************/
472 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
474 /* Remove any pending timeout and update. */
476 TALLOC_FREE(disp_info->cache_timeout_event);
478 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
479 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
480 (unsigned int)secs_fromnow ));
482 disp_info->cache_timeout_event = event_add_timed(
483 smbd_event_context(), NULL,
484 timeval_current_ofs(secs_fromnow, 0),
485 "disp_info_cache_idle_timeout_handler",
486 disp_info_cache_idle_timeout_handler, (void *)disp_info);
489 /*******************************************************************
490 Force flush any cache. We do this on any samr_set_xxx call.
491 We must also remove the timeout handler.
492 ********************************************************************/
494 static void force_flush_samr_cache(DISP_INFO *disp_info)
496 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
497 return;
500 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
501 TALLOC_FREE(disp_info->cache_timeout_event);
502 free_samr_cache(disp_info);
505 /*******************************************************************
506 Ensure password info is never given out. Paranioa... JRA.
507 ********************************************************************/
509 static void samr_clear_sam_passwd(struct samu *sam_pass)
512 if (!sam_pass)
513 return;
515 /* These now zero out the old password */
517 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
518 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
521 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
523 struct samr_displayentry *entry;
525 if (info->builtin_domain) {
526 /* No users in builtin. */
527 return 0;
530 if (info->users == NULL) {
531 info->users = pdb_search_users(acct_flags);
532 if (info->users == NULL) {
533 return 0;
536 /* Fetch the last possible entry, thus trigger an enumeration */
537 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
539 /* Ensure we cache this enumeration. */
540 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
542 return info->users->num_entries;
545 static uint32 count_sam_groups(struct disp_info *info)
547 struct samr_displayentry *entry;
549 if (info->builtin_domain) {
550 /* No groups in builtin. */
551 return 0;
554 if (info->groups == NULL) {
555 info->groups = pdb_search_groups();
556 if (info->groups == NULL) {
557 return 0;
560 /* Fetch the last possible entry, thus trigger an enumeration */
561 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
563 /* Ensure we cache this enumeration. */
564 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
566 return info->groups->num_entries;
569 static uint32 count_sam_aliases(struct disp_info *info)
571 struct samr_displayentry *entry;
573 if (info->aliases == NULL) {
574 info->aliases = pdb_search_aliases(&info->sid);
575 if (info->aliases == NULL) {
576 return 0;
579 /* Fetch the last possible entry, thus trigger an enumeration */
580 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
582 /* Ensure we cache this enumeration. */
583 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
585 return info->aliases->num_entries;
588 /*******************************************************************
589 _samr_Close
590 ********************************************************************/
592 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
594 if (!close_policy_hnd(p, r->in.handle)) {
595 return NT_STATUS_INVALID_HANDLE;
598 ZERO_STRUCTP(r->out.handle);
600 return NT_STATUS_OK;
603 /*******************************************************************
604 _samr_OpenDomain
605 ********************************************************************/
607 NTSTATUS _samr_OpenDomain(pipes_struct *p,
608 struct samr_OpenDomain *r)
610 struct samr_info *info;
611 SEC_DESC *psd = NULL;
612 uint32 acc_granted;
613 uint32 des_access = r->in.access_mask;
614 NTSTATUS status;
615 size_t sd_size;
616 SE_PRIV se_rights;
618 /* find the connection policy handle. */
620 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
621 return NT_STATUS_INVALID_HANDLE;
623 /*check if access can be granted as requested by client. */
624 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
626 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
627 se_map_generic( &des_access, &dom_generic_mapping );
629 se_priv_copy( &se_rights, &se_machine_account );
630 se_priv_add( &se_rights, &se_add_users );
632 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
633 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
634 &acc_granted, "_samr_OpenDomain" );
636 if ( !NT_STATUS_IS_OK(status) )
637 return status;
639 if (!sid_check_is_domain(r->in.sid) &&
640 !sid_check_is_builtin(r->in.sid)) {
641 return NT_STATUS_NO_SUCH_DOMAIN;
644 /* associate the domain SID with the (unique) handle. */
645 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
646 return NT_STATUS_NO_MEMORY;
647 info->acc_granted = acc_granted;
649 /* get a (unique) handle. open a policy on it. */
650 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
651 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
653 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
655 return NT_STATUS_OK;
658 /*******************************************************************
659 _samr_GetUserPwInfo
660 ********************************************************************/
662 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
663 struct samr_GetUserPwInfo *r)
665 struct samr_info *info = NULL;
666 enum lsa_SidType sid_type;
667 uint32_t min_password_length = 0;
668 uint32_t password_properties = 0;
669 bool ret = false;
670 NTSTATUS status;
672 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
674 /* find the policy handle. open a policy on it. */
675 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
676 return NT_STATUS_INVALID_HANDLE;
679 status = access_check_samr_function(info->acc_granted,
680 SAMR_USER_ACCESS_GET_ATTRIBUTES,
681 "_samr_GetUserPwInfo" );
682 if (!NT_STATUS_IS_OK(status)) {
683 return status;
686 if (!sid_check_is_in_our_domain(&info->sid)) {
687 return NT_STATUS_OBJECT_TYPE_MISMATCH;
690 become_root();
691 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
692 unbecome_root();
693 if (ret == false) {
694 return NT_STATUS_NO_SUCH_USER;
697 switch (sid_type) {
698 case SID_NAME_USER:
699 become_root();
700 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
701 &min_password_length);
702 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
703 &password_properties);
704 unbecome_root();
706 if (lp_check_password_script() && *lp_check_password_script()) {
707 password_properties |= DOMAIN_PASSWORD_COMPLEX;
710 break;
711 default:
712 break;
715 r->out.info->min_password_length = min_password_length;
716 r->out.info->password_properties = password_properties;
718 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
720 return NT_STATUS_OK;
723 /*******************************************************************
724 ********************************************************************/
726 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
727 DOM_SID *sid, uint32 *acc_granted,
728 DISP_INFO **ppdisp_info)
730 struct samr_info *info = NULL;
732 /* find the policy handle. open a policy on it. */
733 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
734 return False;
736 if (!info)
737 return False;
739 *sid = info->sid;
740 *acc_granted = info->acc_granted;
741 if (ppdisp_info) {
742 *ppdisp_info = info->disp_info;
745 return True;
748 /*******************************************************************
749 _samr_SetSecurity
750 ********************************************************************/
752 NTSTATUS _samr_SetSecurity(pipes_struct *p,
753 struct samr_SetSecurity *r)
755 DOM_SID pol_sid;
756 uint32 acc_granted, i;
757 SEC_ACL *dacl;
758 bool ret;
759 struct samu *sampass=NULL;
760 NTSTATUS status;
762 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
763 return NT_STATUS_INVALID_HANDLE;
765 if (!(sampass = samu_new( p->mem_ctx))) {
766 DEBUG(0,("No memory!\n"));
767 return NT_STATUS_NO_MEMORY;
770 /* get the user record */
771 become_root();
772 ret = pdb_getsampwsid(sampass, &pol_sid);
773 unbecome_root();
775 if (!ret) {
776 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
777 TALLOC_FREE(sampass);
778 return NT_STATUS_INVALID_HANDLE;
781 dacl = r->in.sdbuf->sd->dacl;
782 for (i=0; i < dacl->num_aces; i++) {
783 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
784 ret = pdb_set_pass_can_change(sampass,
785 (dacl->aces[i].access_mask &
786 SA_RIGHT_USER_CHANGE_PASSWORD) ?
787 True: False);
788 break;
792 if (!ret) {
793 TALLOC_FREE(sampass);
794 return NT_STATUS_ACCESS_DENIED;
797 status = access_check_samr_function(acc_granted,
798 SA_RIGHT_USER_SET_ATTRIBUTES,
799 "_samr_SetSecurity");
800 if (NT_STATUS_IS_OK(status)) {
801 become_root();
802 status = pdb_update_sam_account(sampass);
803 unbecome_root();
806 TALLOC_FREE(sampass);
808 return status;
811 /*******************************************************************
812 build correct perms based on policies and password times for _samr_query_sec_obj
813 *******************************************************************/
814 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
816 struct samu *sampass=NULL;
817 bool ret;
819 if ( !(sampass = samu_new( mem_ctx )) ) {
820 DEBUG(0,("No memory!\n"));
821 return False;
824 become_root();
825 ret = pdb_getsampwsid(sampass, user_sid);
826 unbecome_root();
828 if (ret == False) {
829 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
830 TALLOC_FREE(sampass);
831 return False;
834 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
836 if (pdb_get_pass_can_change(sampass)) {
837 TALLOC_FREE(sampass);
838 return True;
840 TALLOC_FREE(sampass);
841 return False;
845 /*******************************************************************
846 _samr_QuerySecurity
847 ********************************************************************/
849 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
850 struct samr_QuerySecurity *r)
852 NTSTATUS status;
853 DOM_SID pol_sid;
854 SEC_DESC * psd = NULL;
855 uint32 acc_granted;
856 size_t sd_size;
858 /* Get the SID. */
859 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
860 return NT_STATUS_INVALID_HANDLE;
862 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
863 sid_string_dbg(&pol_sid)));
865 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
867 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
868 if (pol_sid.sid_rev_num == 0) {
869 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
870 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
871 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
872 /* check if it is our domain SID */
873 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
874 "with SID: %s\n", sid_string_dbg(&pol_sid)));
875 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
876 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
877 /* check if it is the Builtin Domain */
878 /* TODO: Builtin probably needs a different SD with restricted write access*/
879 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
880 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
881 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
882 } else if (sid_check_is_in_our_domain(&pol_sid) ||
883 sid_check_is_in_builtin(&pol_sid)) {
884 /* TODO: different SDs have to be generated for aliases groups and users.
885 Currently all three get a default user SD */
886 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
887 "with SID: %s\n", sid_string_dbg(&pol_sid)));
888 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
889 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
890 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
891 } else {
892 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
893 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
895 } else {
896 return NT_STATUS_OBJECT_TYPE_MISMATCH;
899 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
900 return NT_STATUS_NO_MEMORY;
902 return status;
905 /*******************************************************************
906 makes a SAM_ENTRY / UNISTR2* structure from a user list.
907 ********************************************************************/
909 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
910 struct samr_SamEntry **sam_pp,
911 uint32_t num_entries,
912 uint32_t start_idx,
913 struct samr_displayentry *entries)
915 uint32_t i;
916 struct samr_SamEntry *sam;
918 *sam_pp = NULL;
920 if (num_entries == 0) {
921 return NT_STATUS_OK;
924 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
925 if (sam == NULL) {
926 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
927 return NT_STATUS_NO_MEMORY;
930 for (i = 0; i < num_entries; i++) {
931 #if 0
933 * usrmgr expects a non-NULL terminated string with
934 * trust relationships
936 if (entries[i].acct_flags & ACB_DOMTRUST) {
937 init_unistr2(&uni_temp_name, entries[i].account_name,
938 UNI_FLAGS_NONE);
939 } else {
940 init_unistr2(&uni_temp_name, entries[i].account_name,
941 UNI_STR_TERMINATE);
943 #endif
944 init_lsa_String(&sam[i].name, entries[i].account_name);
945 sam[i].idx = entries[i].rid;
948 *sam_pp = sam;
950 return NT_STATUS_OK;
953 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
955 /*******************************************************************
956 _samr_EnumDomainUsers
957 ********************************************************************/
959 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
960 struct samr_EnumDomainUsers *r)
962 NTSTATUS status;
963 struct samr_info *info = NULL;
964 int num_account;
965 uint32 enum_context = *r->in.resume_handle;
966 enum remote_arch_types ra_type = get_remote_arch();
967 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
968 uint32 max_entries = max_sam_entries;
969 struct samr_displayentry *entries = NULL;
970 struct samr_SamArray *samr_array = NULL;
971 struct samr_SamEntry *samr_entries = NULL;
973 /* find the policy handle. open a policy on it. */
974 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
975 return NT_STATUS_INVALID_HANDLE;
977 status = access_check_samr_function(info->acc_granted,
978 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
979 "_samr_EnumDomainUsers");
980 if (!NT_STATUS_IS_OK(status)) {
981 return status;
984 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
986 if (info->builtin_domain) {
987 /* No users in builtin. */
988 *r->out.resume_handle = *r->in.resume_handle;
989 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
990 return status;
993 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
994 if (!samr_array) {
995 return NT_STATUS_NO_MEMORY;
998 become_root();
1000 /* AS ROOT !!!! */
1002 if ((info->disp_info->enum_users != NULL) &&
1003 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1004 pdb_search_destroy(info->disp_info->enum_users);
1005 info->disp_info->enum_users = NULL;
1008 if (info->disp_info->enum_users == NULL) {
1009 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
1010 info->disp_info->enum_acb_mask = r->in.acct_flags;
1013 if (info->disp_info->enum_users == NULL) {
1014 /* END AS ROOT !!!! */
1015 unbecome_root();
1016 return NT_STATUS_ACCESS_DENIED;
1019 num_account = pdb_search_entries(info->disp_info->enum_users,
1020 enum_context, max_entries,
1021 &entries);
1023 /* END AS ROOT !!!! */
1025 unbecome_root();
1027 if (num_account == 0) {
1028 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1029 "total entries\n"));
1030 *r->out.resume_handle = *r->in.resume_handle;
1031 return NT_STATUS_OK;
1034 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1035 num_account, enum_context,
1036 entries);
1037 if (!NT_STATUS_IS_OK(status)) {
1038 return status;
1041 if (max_entries <= num_account) {
1042 status = STATUS_MORE_ENTRIES;
1043 } else {
1044 status = NT_STATUS_OK;
1047 /* Ensure we cache this enumeration. */
1048 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1050 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1052 samr_array->count = num_account;
1053 samr_array->entries = samr_entries;
1055 *r->out.resume_handle = *r->in.resume_handle + num_account;
1056 *r->out.sam = samr_array;
1057 *r->out.num_entries = num_account;
1059 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1061 return status;
1064 /*******************************************************************
1065 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1066 ********************************************************************/
1068 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1069 struct samr_SamEntry **sam_pp,
1070 uint32_t num_sam_entries,
1071 struct samr_displayentry *entries)
1073 struct samr_SamEntry *sam;
1074 uint32_t i;
1076 *sam_pp = NULL;
1078 if (num_sam_entries == 0) {
1079 return;
1082 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1083 if (sam == NULL) {
1084 return;
1087 for (i = 0; i < num_sam_entries; i++) {
1089 * JRA. I think this should include the null. TNG does not.
1091 init_lsa_String(&sam[i].name, entries[i].account_name);
1092 sam[i].idx = entries[i].rid;
1095 *sam_pp = sam;
1098 /*******************************************************************
1099 _samr_EnumDomainGroups
1100 ********************************************************************/
1102 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1103 struct samr_EnumDomainGroups *r)
1105 NTSTATUS status;
1106 struct samr_info *info = NULL;
1107 struct samr_displayentry *groups;
1108 uint32 num_groups;
1109 struct samr_SamArray *samr_array = NULL;
1110 struct samr_SamEntry *samr_entries = NULL;
1112 /* find the policy handle. open a policy on it. */
1113 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1114 return NT_STATUS_INVALID_HANDLE;
1116 status = access_check_samr_function(info->acc_granted,
1117 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1118 "_samr_EnumDomainGroups");
1119 if (!NT_STATUS_IS_OK(status)) {
1120 return status;
1123 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1125 if (info->builtin_domain) {
1126 /* No groups in builtin. */
1127 *r->out.resume_handle = *r->in.resume_handle;
1128 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1129 return status;
1132 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1133 if (!samr_array) {
1134 return NT_STATUS_NO_MEMORY;
1137 /* the domain group array is being allocated in the function below */
1139 become_root();
1141 if (info->disp_info->groups == NULL) {
1142 info->disp_info->groups = pdb_search_groups();
1144 if (info->disp_info->groups == NULL) {
1145 unbecome_root();
1146 return NT_STATUS_ACCESS_DENIED;
1150 num_groups = pdb_search_entries(info->disp_info->groups,
1151 *r->in.resume_handle,
1152 MAX_SAM_ENTRIES, &groups);
1153 unbecome_root();
1155 /* Ensure we cache this enumeration. */
1156 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1158 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1159 num_groups, groups);
1161 if (MAX_SAM_ENTRIES <= num_groups) {
1162 status = STATUS_MORE_ENTRIES;
1163 } else {
1164 status = NT_STATUS_OK;
1167 samr_array->count = num_groups;
1168 samr_array->entries = samr_entries;
1170 *r->out.sam = samr_array;
1171 *r->out.num_entries = num_groups;
1172 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1174 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1176 return status;
1179 /*******************************************************************
1180 _samr_EnumDomainAliases
1181 ********************************************************************/
1183 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1184 struct samr_EnumDomainAliases *r)
1186 NTSTATUS status;
1187 struct samr_info *info;
1188 struct samr_displayentry *aliases;
1189 uint32 num_aliases = 0;
1190 struct samr_SamArray *samr_array = NULL;
1191 struct samr_SamEntry *samr_entries = NULL;
1193 /* find the policy handle. open a policy on it. */
1194 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1195 return NT_STATUS_INVALID_HANDLE;
1197 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1198 sid_string_dbg(&info->sid)));
1200 status = access_check_samr_function(info->acc_granted,
1201 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1202 "_samr_EnumDomainAliases");
1203 if (!NT_STATUS_IS_OK(status)) {
1204 return status;
1207 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1208 if (!samr_array) {
1209 return NT_STATUS_NO_MEMORY;
1212 become_root();
1214 if (info->disp_info->aliases == NULL) {
1215 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1216 if (info->disp_info->aliases == NULL) {
1217 unbecome_root();
1218 return NT_STATUS_ACCESS_DENIED;
1222 num_aliases = pdb_search_entries(info->disp_info->aliases,
1223 *r->in.resume_handle,
1224 MAX_SAM_ENTRIES, &aliases);
1225 unbecome_root();
1227 /* Ensure we cache this enumeration. */
1228 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1230 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1231 num_aliases, aliases);
1233 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1235 if (MAX_SAM_ENTRIES <= num_aliases) {
1236 status = STATUS_MORE_ENTRIES;
1237 } else {
1238 status = NT_STATUS_OK;
1241 samr_array->count = num_aliases;
1242 samr_array->entries = samr_entries;
1244 *r->out.sam = samr_array;
1245 *r->out.num_entries = num_aliases;
1246 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1248 return status;
1251 /*******************************************************************
1252 inits a samr_DispInfoGeneral structure.
1253 ********************************************************************/
1255 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1256 struct samr_DispInfoGeneral *r,
1257 uint32_t num_entries,
1258 uint32_t start_idx,
1259 struct samr_displayentry *entries)
1261 uint32 i;
1263 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1265 if (num_entries == 0) {
1266 return NT_STATUS_OK;
1269 r->count = num_entries;
1271 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1272 if (!r->entries) {
1273 return NT_STATUS_NO_MEMORY;
1276 for (i = 0; i < num_entries ; i++) {
1278 init_lsa_String(&r->entries[i].account_name,
1279 entries[i].account_name);
1281 init_lsa_String(&r->entries[i].description,
1282 entries[i].description);
1284 init_lsa_String(&r->entries[i].full_name,
1285 entries[i].fullname);
1287 r->entries[i].rid = entries[i].rid;
1288 r->entries[i].acct_flags = entries[i].acct_flags;
1289 r->entries[i].idx = start_idx+i+1;
1292 return NT_STATUS_OK;
1295 /*******************************************************************
1296 inits a samr_DispInfoFull structure.
1297 ********************************************************************/
1299 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1300 struct samr_DispInfoFull *r,
1301 uint32_t num_entries,
1302 uint32_t start_idx,
1303 struct samr_displayentry *entries)
1305 uint32_t i;
1307 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1309 if (num_entries == 0) {
1310 return NT_STATUS_OK;
1313 r->count = num_entries;
1315 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1316 if (!r->entries) {
1317 return NT_STATUS_NO_MEMORY;
1320 for (i = 0; i < num_entries ; i++) {
1322 init_lsa_String(&r->entries[i].account_name,
1323 entries[i].account_name);
1325 init_lsa_String(&r->entries[i].description,
1326 entries[i].description);
1328 r->entries[i].rid = entries[i].rid;
1329 r->entries[i].acct_flags = entries[i].acct_flags;
1330 r->entries[i].idx = start_idx+i+1;
1333 return NT_STATUS_OK;
1336 /*******************************************************************
1337 inits a samr_DispInfoFullGroups structure.
1338 ********************************************************************/
1340 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1341 struct samr_DispInfoFullGroups *r,
1342 uint32_t num_entries,
1343 uint32_t start_idx,
1344 struct samr_displayentry *entries)
1346 uint32_t i;
1348 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1350 if (num_entries == 0) {
1351 return NT_STATUS_OK;
1354 r->count = num_entries;
1356 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1357 if (!r->entries) {
1358 return NT_STATUS_NO_MEMORY;
1361 for (i = 0; i < num_entries ; i++) {
1363 init_lsa_String(&r->entries[i].account_name,
1364 entries[i].account_name);
1366 init_lsa_String(&r->entries[i].description,
1367 entries[i].description);
1369 r->entries[i].rid = entries[i].rid;
1370 r->entries[i].acct_flags = entries[i].acct_flags;
1371 r->entries[i].idx = start_idx+i+1;
1374 return NT_STATUS_OK;
1377 /*******************************************************************
1378 inits a samr_DispInfoAscii structure.
1379 ********************************************************************/
1381 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1382 struct samr_DispInfoAscii *r,
1383 uint32_t num_entries,
1384 uint32_t start_idx,
1385 struct samr_displayentry *entries)
1387 uint32_t i;
1389 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1391 if (num_entries == 0) {
1392 return NT_STATUS_OK;
1395 r->count = num_entries;
1397 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1398 if (!r->entries) {
1399 return NT_STATUS_NO_MEMORY;
1402 for (i = 0; i < num_entries ; i++) {
1404 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1405 entries[i].account_name);
1407 r->entries[i].idx = start_idx+i+1;
1410 return NT_STATUS_OK;
1413 /*******************************************************************
1414 inits a samr_DispInfoAscii structure.
1415 ********************************************************************/
1417 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1418 struct samr_DispInfoAscii *r,
1419 uint32_t num_entries,
1420 uint32_t start_idx,
1421 struct samr_displayentry *entries)
1423 uint32_t i;
1425 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1427 if (num_entries == 0) {
1428 return NT_STATUS_OK;
1431 r->count = num_entries;
1433 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1434 if (!r->entries) {
1435 return NT_STATUS_NO_MEMORY;
1438 for (i = 0; i < num_entries ; i++) {
1440 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1441 entries[i].account_name);
1443 r->entries[i].idx = start_idx+i+1;
1446 return NT_STATUS_OK;
1449 /*******************************************************************
1450 _samr_QueryDisplayInfo
1451 ********************************************************************/
1453 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1454 struct samr_QueryDisplayInfo *r)
1456 NTSTATUS status;
1457 struct samr_info *info = NULL;
1458 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1460 uint32 max_entries = r->in.max_entries;
1461 uint32 enum_context = r->in.start_idx;
1462 uint32 max_size = r->in.buf_size;
1464 union samr_DispInfo *disp_info = r->out.info;
1466 uint32 temp_size=0, total_data_size=0;
1467 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1468 uint32 num_account = 0;
1469 enum remote_arch_types ra_type = get_remote_arch();
1470 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1471 struct samr_displayentry *entries = NULL;
1473 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1475 /* find the policy handle. open a policy on it. */
1476 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1477 return NT_STATUS_INVALID_HANDLE;
1480 * calculate how many entries we will return.
1481 * based on
1482 * - the number of entries the client asked
1483 * - our limit on that
1484 * - the starting point (enumeration context)
1485 * - the buffer size the client will accept
1489 * We are a lot more like W2K. Instead of reading the SAM
1490 * each time to find the records we need to send back,
1491 * we read it once and link that copy to the sam handle.
1492 * For large user list (over the MAX_SAM_ENTRIES)
1493 * it's a definitive win.
1494 * second point to notice: between enumerations
1495 * our sam is now the same as it's a snapshoot.
1496 * third point: got rid of the static SAM_USER_21 struct
1497 * no more intermediate.
1498 * con: it uses much more memory, as a full copy is stored
1499 * in memory.
1501 * If you want to change it, think twice and think
1502 * of the second point , that's really important.
1504 * JFM, 12/20/2001
1507 if ((r->in.level < 1) || (r->in.level > 5)) {
1508 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1509 (unsigned int)r->in.level ));
1510 return NT_STATUS_INVALID_INFO_CLASS;
1513 /* first limit the number of entries we will return */
1514 if(max_entries > max_sam_entries) {
1515 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1516 "entries, limiting to %d\n", max_entries,
1517 max_sam_entries));
1518 max_entries = max_sam_entries;
1521 /* calculate the size and limit on the number of entries we will
1522 * return */
1524 temp_size=max_entries*struct_size;
1526 if (temp_size>max_size) {
1527 max_entries=MIN((max_size/struct_size),max_entries);;
1528 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1529 "only %d entries\n", max_entries));
1532 become_root();
1534 /* THe following done as ROOT. Don't return without unbecome_root(). */
1536 switch (r->in.level) {
1537 case 0x1:
1538 case 0x4:
1539 if (info->disp_info->users == NULL) {
1540 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1541 if (info->disp_info->users == NULL) {
1542 unbecome_root();
1543 return NT_STATUS_ACCESS_DENIED;
1545 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1546 (unsigned int)enum_context ));
1547 } else {
1548 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1549 (unsigned int)enum_context ));
1552 num_account = pdb_search_entries(info->disp_info->users,
1553 enum_context, max_entries,
1554 &entries);
1555 break;
1556 case 0x2:
1557 if (info->disp_info->machines == NULL) {
1558 info->disp_info->machines =
1559 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1560 if (info->disp_info->machines == NULL) {
1561 unbecome_root();
1562 return NT_STATUS_ACCESS_DENIED;
1564 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1565 (unsigned int)enum_context ));
1566 } else {
1567 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1568 (unsigned int)enum_context ));
1571 num_account = pdb_search_entries(info->disp_info->machines,
1572 enum_context, max_entries,
1573 &entries);
1574 break;
1575 case 0x3:
1576 case 0x5:
1577 if (info->disp_info->groups == NULL) {
1578 info->disp_info->groups = pdb_search_groups();
1579 if (info->disp_info->groups == NULL) {
1580 unbecome_root();
1581 return NT_STATUS_ACCESS_DENIED;
1583 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1584 (unsigned int)enum_context ));
1585 } else {
1586 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1587 (unsigned int)enum_context ));
1590 num_account = pdb_search_entries(info->disp_info->groups,
1591 enum_context, max_entries,
1592 &entries);
1593 break;
1594 default:
1595 unbecome_root();
1596 smb_panic("info class changed");
1597 break;
1599 unbecome_root();
1602 /* Now create reply structure */
1603 switch (r->in.level) {
1604 case 0x1:
1605 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1606 num_account, enum_context,
1607 entries);
1608 break;
1609 case 0x2:
1610 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1611 num_account, enum_context,
1612 entries);
1613 break;
1614 case 0x3:
1615 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1616 num_account, enum_context,
1617 entries);
1618 break;
1619 case 0x4:
1620 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1621 num_account, enum_context,
1622 entries);
1623 break;
1624 case 0x5:
1625 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1626 num_account, enum_context,
1627 entries);
1628 break;
1629 default:
1630 smb_panic("info class changed");
1631 break;
1634 if (!NT_STATUS_IS_OK(disp_ret))
1635 return disp_ret;
1637 /* calculate the total size */
1638 total_data_size=num_account*struct_size;
1640 if (max_entries <= num_account) {
1641 status = STATUS_MORE_ENTRIES;
1642 } else {
1643 status = NT_STATUS_OK;
1646 /* Ensure we cache this enumeration. */
1647 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1649 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1651 *r->out.total_size = total_data_size;
1652 *r->out.returned_size = temp_size;
1654 return status;
1657 /****************************************************************
1658 _samr_QueryDisplayInfo2
1659 ****************************************************************/
1661 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1662 struct samr_QueryDisplayInfo2 *r)
1664 struct samr_QueryDisplayInfo q;
1666 q.in.domain_handle = r->in.domain_handle;
1667 q.in.level = r->in.level;
1668 q.in.start_idx = r->in.start_idx;
1669 q.in.max_entries = r->in.max_entries;
1670 q.in.buf_size = r->in.buf_size;
1672 q.out.total_size = r->out.total_size;
1673 q.out.returned_size = r->out.returned_size;
1674 q.out.info = r->out.info;
1676 return _samr_QueryDisplayInfo(p, &q);
1679 /****************************************************************
1680 _samr_QueryDisplayInfo3
1681 ****************************************************************/
1683 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1684 struct samr_QueryDisplayInfo3 *r)
1686 struct samr_QueryDisplayInfo q;
1688 q.in.domain_handle = r->in.domain_handle;
1689 q.in.level = r->in.level;
1690 q.in.start_idx = r->in.start_idx;
1691 q.in.max_entries = r->in.max_entries;
1692 q.in.buf_size = r->in.buf_size;
1694 q.out.total_size = r->out.total_size;
1695 q.out.returned_size = r->out.returned_size;
1696 q.out.info = r->out.info;
1698 return _samr_QueryDisplayInfo(p, &q);
1701 /*******************************************************************
1702 _samr_QueryAliasInfo
1703 ********************************************************************/
1705 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1706 struct samr_QueryAliasInfo *r)
1708 DOM_SID sid;
1709 struct acct_info info;
1710 uint32 acc_granted;
1711 NTSTATUS status;
1712 union samr_AliasInfo *alias_info = NULL;
1713 const char *alias_name = NULL;
1714 const char *alias_description = NULL;
1716 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1718 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1719 if (!alias_info) {
1720 return NT_STATUS_NO_MEMORY;
1723 /* find the policy handle. open a policy on it. */
1724 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1725 return NT_STATUS_INVALID_HANDLE;
1727 status = access_check_samr_function(acc_granted,
1728 SA_RIGHT_ALIAS_LOOKUP_INFO,
1729 "_samr_QueryAliasInfo");
1730 if (!NT_STATUS_IS_OK(status)) {
1731 return status;
1734 become_root();
1735 status = pdb_get_aliasinfo(&sid, &info);
1736 unbecome_root();
1738 if ( !NT_STATUS_IS_OK(status))
1739 return status;
1741 /* FIXME: info contains fstrings */
1742 alias_name = talloc_strdup(r, info.acct_name);
1743 alias_description = talloc_strdup(r, info.acct_desc);
1745 switch (r->in.level) {
1746 case ALIASINFOALL:
1747 init_samr_alias_info1(&alias_info->all,
1748 alias_name,
1750 alias_description);
1751 break;
1752 case ALIASINFODESCRIPTION:
1753 init_samr_alias_info3(&alias_info->description,
1754 alias_description);
1755 break;
1756 default:
1757 return NT_STATUS_INVALID_INFO_CLASS;
1760 *r->out.info = alias_info;
1762 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1764 return NT_STATUS_OK;
1767 #if 0
1768 /*******************************************************************
1769 samr_reply_lookup_ids
1770 ********************************************************************/
1772 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1774 uint32 rid[MAX_SAM_ENTRIES];
1775 int num_rids = q_u->num_sids1;
1777 r_u->status = NT_STATUS_OK;
1779 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1781 if (num_rids > MAX_SAM_ENTRIES) {
1782 num_rids = MAX_SAM_ENTRIES;
1783 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1786 #if 0
1787 int i;
1788 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1790 for (i = 0; i < num_rids && status == 0; i++)
1792 struct sam_passwd *sam_pass;
1793 fstring user_name;
1796 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1797 q_u->uni_user_name[i].uni_str_len));
1799 /* find the user account */
1800 become_root();
1801 sam_pass = get_smb21pwd_entry(user_name, 0);
1802 unbecome_root();
1804 if (sam_pass == NULL)
1806 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1807 rid[i] = 0;
1809 else
1811 rid[i] = sam_pass->user_rid;
1814 #endif
1816 num_rids = 1;
1817 rid[0] = BUILTIN_ALIAS_RID_USERS;
1819 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1821 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1823 return r_u->status;
1825 #endif
1827 /*******************************************************************
1828 _samr_LookupNames
1829 ********************************************************************/
1831 NTSTATUS _samr_LookupNames(pipes_struct *p,
1832 struct samr_LookupNames *r)
1834 NTSTATUS status;
1835 uint32 *rid;
1836 enum lsa_SidType *type;
1837 int i;
1838 int num_rids = r->in.num_names;
1839 DOM_SID pol_sid;
1840 uint32 acc_granted;
1841 struct samr_Ids rids, types;
1842 uint32_t num_mapped = 0;
1844 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1846 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1847 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1850 status = access_check_samr_function(acc_granted,
1851 0, /* Don't know the acc_bits yet */
1852 "_samr_LookupNames");
1853 if (!NT_STATUS_IS_OK(status)) {
1854 return status;
1857 if (num_rids > MAX_SAM_ENTRIES) {
1858 num_rids = MAX_SAM_ENTRIES;
1859 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1862 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1863 NT_STATUS_HAVE_NO_MEMORY(rid);
1865 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1866 NT_STATUS_HAVE_NO_MEMORY(type);
1868 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1869 sid_string_dbg(&pol_sid)));
1871 for (i = 0; i < num_rids; i++) {
1873 status = NT_STATUS_NONE_MAPPED;
1874 type[i] = SID_NAME_UNKNOWN;
1876 rid[i] = 0xffffffff;
1878 if (sid_check_is_builtin(&pol_sid)) {
1879 if (lookup_builtin_name(r->in.names[i].string,
1880 &rid[i]))
1882 type[i] = SID_NAME_ALIAS;
1884 } else {
1885 lookup_global_sam_name(r->in.names[i].string, 0,
1886 &rid[i], &type[i]);
1889 if (type[i] != SID_NAME_UNKNOWN) {
1890 num_mapped++;
1894 if (num_mapped == num_rids) {
1895 status = NT_STATUS_OK;
1896 } else if (num_mapped == 0) {
1897 status = NT_STATUS_NONE_MAPPED;
1898 } else {
1899 status = STATUS_SOME_UNMAPPED;
1902 rids.count = num_rids;
1903 rids.ids = rid;
1905 types.count = num_rids;
1906 types.ids = type;
1908 *r->out.rids = rids;
1909 *r->out.types = types;
1911 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1913 return status;
1916 /*******************************************************************
1917 _samr_ChangePasswordUser2
1918 ********************************************************************/
1920 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1921 struct samr_ChangePasswordUser2 *r)
1923 NTSTATUS status;
1924 fstring user_name;
1925 fstring wks;
1927 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1929 fstrcpy(user_name, r->in.account->string);
1930 fstrcpy(wks, r->in.server->string);
1932 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1935 * Pass the user through the NT -> unix user mapping
1936 * function.
1939 (void)map_username(user_name);
1942 * UNIX username case mangling not required, pass_oem_change
1943 * is case insensitive.
1946 status = pass_oem_change(user_name,
1947 r->in.lm_password->data,
1948 r->in.lm_verifier->hash,
1949 r->in.nt_password->data,
1950 r->in.nt_verifier->hash,
1951 NULL);
1953 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1955 return status;
1958 /*******************************************************************
1959 _samr_ChangePasswordUser3
1960 ********************************************************************/
1962 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1963 struct samr_ChangePasswordUser3 *r)
1965 NTSTATUS status;
1966 fstring user_name;
1967 const char *wks = NULL;
1968 uint32 reject_reason;
1969 struct samr_DomInfo1 *dominfo = NULL;
1970 struct samr_ChangeReject *reject = NULL;
1972 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1974 fstrcpy(user_name, r->in.account->string);
1975 if (r->in.server && r->in.server->string) {
1976 wks = r->in.server->string;
1979 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1982 * Pass the user through the NT -> unix user mapping
1983 * function.
1986 (void)map_username(user_name);
1989 * UNIX username case mangling not required, pass_oem_change
1990 * is case insensitive.
1993 status = pass_oem_change(user_name,
1994 r->in.lm_password->data,
1995 r->in.lm_verifier->hash,
1996 r->in.nt_password->data,
1997 r->in.nt_verifier->hash,
1998 &reject_reason);
2000 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2001 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2003 uint32 min_pass_len,pass_hist,password_properties;
2004 time_t u_expire, u_min_age;
2005 NTTIME nt_expire, nt_min_age;
2006 uint32 account_policy_temp;
2008 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2009 if (!dominfo) {
2010 return NT_STATUS_NO_MEMORY;
2013 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2014 if (!reject) {
2015 return NT_STATUS_NO_MEMORY;
2018 become_root();
2020 /* AS ROOT !!! */
2022 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2023 min_pass_len = account_policy_temp;
2025 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2026 pass_hist = account_policy_temp;
2028 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2029 password_properties = account_policy_temp;
2031 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2032 u_expire = account_policy_temp;
2034 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2035 u_min_age = account_policy_temp;
2037 /* !AS ROOT */
2039 unbecome_root();
2041 unix_to_nt_time_abs(&nt_expire, u_expire);
2042 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2044 if (lp_check_password_script() && *lp_check_password_script()) {
2045 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2048 init_samr_DomInfo1(dominfo,
2049 min_pass_len,
2050 pass_hist,
2051 password_properties,
2052 u_expire,
2053 u_min_age);
2055 reject->reason = reject_reason;
2057 *r->out.dominfo = dominfo;
2058 *r->out.reject = reject;
2061 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2063 return status;
2066 /*******************************************************************
2067 makes a SAMR_R_LOOKUP_RIDS structure.
2068 ********************************************************************/
2070 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2071 const char **names,
2072 struct lsa_String **lsa_name_array_p)
2074 struct lsa_String *lsa_name_array = NULL;
2075 uint32_t i;
2077 *lsa_name_array_p = NULL;
2079 if (num_names != 0) {
2080 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2081 if (!lsa_name_array) {
2082 return false;
2086 for (i = 0; i < num_names; i++) {
2087 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2088 init_lsa_String(&lsa_name_array[i], names[i]);
2091 *lsa_name_array_p = lsa_name_array;
2093 return true;
2096 /*******************************************************************
2097 _samr_LookupRids
2098 ********************************************************************/
2100 NTSTATUS _samr_LookupRids(pipes_struct *p,
2101 struct samr_LookupRids *r)
2103 NTSTATUS status;
2104 const char **names;
2105 enum lsa_SidType *attrs = NULL;
2106 uint32 *wire_attrs = NULL;
2107 DOM_SID pol_sid;
2108 int num_rids = (int)r->in.num_rids;
2109 uint32 acc_granted;
2110 int i;
2111 struct lsa_Strings names_array;
2112 struct samr_Ids types_array;
2113 struct lsa_String *lsa_names = NULL;
2115 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2117 /* find the policy handle. open a policy on it. */
2118 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2119 return NT_STATUS_INVALID_HANDLE;
2121 if (num_rids > 1000) {
2122 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2123 "to samba4 idl this is not possible\n", num_rids));
2124 return NT_STATUS_UNSUCCESSFUL;
2127 if (num_rids) {
2128 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2129 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2130 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2132 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2133 return NT_STATUS_NO_MEMORY;
2134 } else {
2135 names = NULL;
2136 attrs = NULL;
2137 wire_attrs = NULL;
2140 become_root(); /* lookup_sid can require root privs */
2141 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2142 names, attrs);
2143 unbecome_root();
2145 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2146 status = NT_STATUS_OK;
2149 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2150 &lsa_names)) {
2151 return NT_STATUS_NO_MEMORY;
2154 /* Convert from enum lsa_SidType to uint32 for wire format. */
2155 for (i = 0; i < num_rids; i++) {
2156 wire_attrs[i] = (uint32)attrs[i];
2159 names_array.count = num_rids;
2160 names_array.names = lsa_names;
2162 types_array.count = num_rids;
2163 types_array.ids = wire_attrs;
2165 *r->out.names = names_array;
2166 *r->out.types = types_array;
2168 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2170 return status;
2173 /*******************************************************************
2174 _samr_OpenUser
2175 ********************************************************************/
2177 NTSTATUS _samr_OpenUser(pipes_struct *p,
2178 struct samr_OpenUser *r)
2180 struct samu *sampass=NULL;
2181 DOM_SID sid;
2182 POLICY_HND domain_pol = *r->in.domain_handle;
2183 POLICY_HND *user_pol = r->out.user_handle;
2184 struct samr_info *info = NULL;
2185 SEC_DESC *psd = NULL;
2186 uint32 acc_granted;
2187 uint32 des_access = r->in.access_mask;
2188 size_t sd_size;
2189 bool ret;
2190 NTSTATUS nt_status;
2191 SE_PRIV se_rights;
2193 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2195 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2196 return NT_STATUS_INVALID_HANDLE;
2198 nt_status = access_check_samr_function(acc_granted,
2199 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2200 "_samr_OpenUser" );
2202 if ( !NT_STATUS_IS_OK(nt_status) )
2203 return nt_status;
2205 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2206 return NT_STATUS_NO_MEMORY;
2209 /* append the user's RID to it */
2211 if (!sid_append_rid(&sid, r->in.rid))
2212 return NT_STATUS_NO_SUCH_USER;
2214 /* check if access can be granted as requested by client. */
2216 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
2218 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2219 se_map_generic(&des_access, &usr_generic_mapping);
2221 se_priv_copy( &se_rights, &se_machine_account );
2222 se_priv_add( &se_rights, &se_add_users );
2224 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2225 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2226 &acc_granted, "_samr_OpenUser");
2228 if ( !NT_STATUS_IS_OK(nt_status) )
2229 return nt_status;
2231 become_root();
2232 ret=pdb_getsampwsid(sampass, &sid);
2233 unbecome_root();
2235 /* check that the SID exists in our domain. */
2236 if (ret == False) {
2237 return NT_STATUS_NO_SUCH_USER;
2240 TALLOC_FREE(sampass);
2242 /* associate the user's SID and access bits with the new handle. */
2243 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2244 return NT_STATUS_NO_MEMORY;
2245 info->acc_granted = acc_granted;
2247 /* get a (unique) handle. open a policy on it. */
2248 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2249 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2251 return NT_STATUS_OK;
2254 /*************************************************************************
2255 *************************************************************************/
2257 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2258 DATA_BLOB *blob,
2259 struct lsa_BinaryString **_r)
2261 struct lsa_BinaryString *r;
2263 if (!blob || !_r) {
2264 return NT_STATUS_INVALID_PARAMETER;
2267 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2268 if (!r) {
2269 return NT_STATUS_NO_MEMORY;
2272 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2273 if (!r->array) {
2274 return NT_STATUS_NO_MEMORY;
2276 memcpy(r->array, blob->data, blob->length);
2277 r->size = blob->length;
2278 r->length = blob->length;
2280 if (!r->array) {
2281 return NT_STATUS_NO_MEMORY;
2284 *_r = r;
2286 return NT_STATUS_OK;
2289 /*************************************************************************
2290 get_user_info_7. Safe. Only gives out account_name.
2291 *************************************************************************/
2293 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2294 struct samr_UserInfo7 *r,
2295 DOM_SID *user_sid)
2297 struct samu *smbpass=NULL;
2298 bool ret;
2299 const char *account_name = NULL;
2301 ZERO_STRUCTP(r);
2303 if ( !(smbpass = samu_new( mem_ctx )) ) {
2304 return NT_STATUS_NO_MEMORY;
2307 become_root();
2308 ret = pdb_getsampwsid(smbpass, user_sid);
2309 unbecome_root();
2311 if ( !ret ) {
2312 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2313 return NT_STATUS_NO_SUCH_USER;
2316 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2317 if (!account_name) {
2318 TALLOC_FREE(smbpass);
2319 return NT_STATUS_NO_MEMORY;
2321 TALLOC_FREE(smbpass);
2323 DEBUG(3,("User:[%s]\n", account_name));
2325 init_samr_user_info7(r, account_name);
2327 return NT_STATUS_OK;
2330 /*************************************************************************
2331 get_user_info_9. Only gives out primary group SID.
2332 *************************************************************************/
2334 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2335 struct samr_UserInfo9 *r,
2336 DOM_SID *user_sid)
2338 struct samu *smbpass=NULL;
2339 bool ret;
2341 ZERO_STRUCTP(r);
2343 if ( !(smbpass = samu_new( mem_ctx )) ) {
2344 return NT_STATUS_NO_MEMORY;
2347 become_root();
2348 ret = pdb_getsampwsid(smbpass, user_sid);
2349 unbecome_root();
2351 if (ret==False) {
2352 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2353 TALLOC_FREE(smbpass);
2354 return NT_STATUS_NO_SUCH_USER;
2357 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2359 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2361 TALLOC_FREE(smbpass);
2363 return NT_STATUS_OK;
2366 /*************************************************************************
2367 get_user_info_16. Safe. Only gives out acb bits.
2368 *************************************************************************/
2370 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2371 struct samr_UserInfo16 *r,
2372 DOM_SID *user_sid)
2374 struct samu *smbpass=NULL;
2375 bool ret;
2377 ZERO_STRUCTP(r);
2379 if ( !(smbpass = samu_new( mem_ctx )) ) {
2380 return NT_STATUS_NO_MEMORY;
2383 become_root();
2384 ret = pdb_getsampwsid(smbpass, user_sid);
2385 unbecome_root();
2387 if (ret==False) {
2388 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2389 TALLOC_FREE(smbpass);
2390 return NT_STATUS_NO_SUCH_USER;
2393 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2395 init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2397 TALLOC_FREE(smbpass);
2399 return NT_STATUS_OK;
2402 /*************************************************************************
2403 get_user_info_18. OK - this is the killer as it gives out password info.
2404 Ensure that this is only allowed on an encrypted connection with a root
2405 user. JRA.
2406 *************************************************************************/
2408 static NTSTATUS get_user_info_18(pipes_struct *p,
2409 TALLOC_CTX *mem_ctx,
2410 struct samr_UserInfo18 *r,
2411 DOM_SID *user_sid)
2413 struct samu *smbpass=NULL;
2414 bool ret;
2416 ZERO_STRUCTP(r);
2418 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2419 return NT_STATUS_ACCESS_DENIED;
2422 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2423 return NT_STATUS_ACCESS_DENIED;
2427 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2430 if ( !(smbpass = samu_new( mem_ctx )) ) {
2431 return NT_STATUS_NO_MEMORY;
2434 ret = pdb_getsampwsid(smbpass, user_sid);
2436 if (ret == False) {
2437 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2438 TALLOC_FREE(smbpass);
2439 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2442 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2444 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2445 TALLOC_FREE(smbpass);
2446 return NT_STATUS_ACCOUNT_DISABLED;
2449 init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2450 pdb_get_nt_passwd(smbpass));
2452 TALLOC_FREE(smbpass);
2454 return NT_STATUS_OK;
2457 /*************************************************************************
2458 get_user_info_20
2459 *************************************************************************/
2461 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2462 struct samr_UserInfo20 *r,
2463 DOM_SID *user_sid)
2465 struct samu *sampass=NULL;
2466 bool ret;
2467 const char *munged_dial = NULL;
2468 DATA_BLOB blob;
2469 NTSTATUS status;
2470 struct lsa_BinaryString *parameters = NULL;
2472 ZERO_STRUCTP(r);
2474 if ( !(sampass = samu_new( mem_ctx )) ) {
2475 return NT_STATUS_NO_MEMORY;
2478 become_root();
2479 ret = pdb_getsampwsid(sampass, user_sid);
2480 unbecome_root();
2482 if (ret == False) {
2483 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2484 TALLOC_FREE(sampass);
2485 return NT_STATUS_NO_SUCH_USER;
2488 munged_dial = pdb_get_munged_dial(sampass);
2490 samr_clear_sam_passwd(sampass);
2492 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2493 munged_dial, (int)strlen(munged_dial)));
2495 if (munged_dial) {
2496 blob = base64_decode_data_blob(munged_dial);
2497 } else {
2498 blob = data_blob_string_const("");
2501 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2502 data_blob_free(&blob);
2503 TALLOC_FREE(sampass);
2504 if (!NT_STATUS_IS_OK(status)) {
2505 return status;
2508 init_samr_user_info20(r, parameters);
2510 return NT_STATUS_OK;
2514 /*************************************************************************
2515 get_user_info_21
2516 *************************************************************************/
2518 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2519 struct samr_UserInfo21 *r,
2520 DOM_SID *user_sid,
2521 DOM_SID *domain_sid)
2523 NTSTATUS status;
2524 struct samu *pw = NULL;
2525 bool ret;
2526 const DOM_SID *sid_user, *sid_group;
2527 uint32_t rid, primary_gid;
2528 NTTIME last_logon, last_logoff, last_password_change,
2529 acct_expiry, allow_password_change, force_password_change;
2530 time_t must_change_time;
2531 uint8_t password_expired;
2532 const char *account_name, *full_name, *home_directory, *home_drive,
2533 *logon_script, *profile_path, *description,
2534 *workstations, *comment;
2535 struct samr_LogonHours logon_hours;
2536 struct lsa_BinaryString *parameters = NULL;
2537 const char *munged_dial = NULL;
2538 DATA_BLOB blob;
2540 ZERO_STRUCTP(r);
2542 if (!(pw = samu_new(mem_ctx))) {
2543 return NT_STATUS_NO_MEMORY;
2546 become_root();
2547 ret = pdb_getsampwsid(pw, user_sid);
2548 unbecome_root();
2550 if (ret == False) {
2551 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2552 TALLOC_FREE(pw);
2553 return NT_STATUS_NO_SUCH_USER;
2556 samr_clear_sam_passwd(pw);
2558 DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2560 sid_user = pdb_get_user_sid(pw);
2562 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2563 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2564 "the domain sid %s. Failing operation.\n",
2565 pdb_get_username(pw), sid_string_dbg(sid_user),
2566 sid_string_dbg(domain_sid)));
2567 TALLOC_FREE(pw);
2568 return NT_STATUS_UNSUCCESSFUL;
2571 become_root();
2572 sid_group = pdb_get_group_sid(pw);
2573 unbecome_root();
2575 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2576 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2577 "which conflicts with the domain sid %s. Failing operation.\n",
2578 pdb_get_username(pw), sid_string_dbg(sid_group),
2579 sid_string_dbg(domain_sid)));
2580 TALLOC_FREE(pw);
2581 return NT_STATUS_UNSUCCESSFUL;
2584 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2585 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2586 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2587 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2588 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2590 must_change_time = pdb_get_pass_must_change_time(pw);
2591 if (must_change_time == get_time_t_max()) {
2592 unix_to_nt_time_abs(&force_password_change, must_change_time);
2593 } else {
2594 unix_to_nt_time(&force_password_change, must_change_time);
2597 if (pdb_get_pass_must_change_time(pw) == 0) {
2598 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2599 } else {
2600 password_expired = 0;
2603 munged_dial = pdb_get_munged_dial(pw);
2604 if (munged_dial) {
2605 blob = base64_decode_data_blob(munged_dial);
2606 } else {
2607 blob = data_blob_string_const("");
2610 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2611 data_blob_free(&blob);
2612 if (!NT_STATUS_IS_OK(status)) {
2613 TALLOC_FREE(pw);
2614 return status;
2617 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2618 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2619 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2620 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2621 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2622 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2623 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2624 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2625 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2627 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2628 #if 0
2631 Look at a user on a real NT4 PDC with usrmgr, press
2632 'ok'. Then you will see that fields_present is set to
2633 0x08f827fa. Look at the user immediately after that again,
2634 and you will see that 0x00fffff is returned. This solves
2635 the problem that you get access denied after having looked
2636 at the user.
2637 -- Volker
2640 #endif
2642 init_samr_user_info21(r,
2643 last_logon,
2644 last_logoff,
2645 last_password_change,
2646 acct_expiry,
2647 allow_password_change,
2648 force_password_change,
2649 account_name,
2650 full_name,
2651 home_directory,
2652 home_drive,
2653 logon_script,
2654 profile_path,
2655 description,
2656 workstations,
2657 comment,
2658 parameters,
2659 rid,
2660 primary_gid,
2661 pdb_get_acct_ctrl(pw),
2662 pdb_build_fields_present(pw),
2663 logon_hours,
2664 pdb_get_bad_password_count(pw),
2665 pdb_get_logon_count(pw),
2666 0, /* country_code */
2667 0, /* code_page */
2668 0, /* nt_password_set */
2669 0, /* lm_password_set */
2670 password_expired);
2671 TALLOC_FREE(pw);
2673 return NT_STATUS_OK;
2676 /*******************************************************************
2677 _samr_QueryUserInfo
2678 ********************************************************************/
2680 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2681 struct samr_QueryUserInfo *r)
2683 NTSTATUS status;
2684 union samr_UserInfo *user_info = NULL;
2685 struct samr_info *info = NULL;
2686 DOM_SID domain_sid;
2687 uint32 rid;
2689 /* search for the handle */
2690 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2691 return NT_STATUS_INVALID_HANDLE;
2693 domain_sid = info->sid;
2695 sid_split_rid(&domain_sid, &rid);
2697 if (!sid_check_is_in_our_domain(&info->sid))
2698 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2700 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2701 sid_string_dbg(&info->sid)));
2703 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2704 if (!user_info) {
2705 return NT_STATUS_NO_MEMORY;
2708 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2710 switch (r->in.level) {
2711 case 7:
2712 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2713 if (!NT_STATUS_IS_OK(status)) {
2714 return status;
2716 break;
2717 case 9:
2718 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2719 if (!NT_STATUS_IS_OK(status)) {
2720 return status;
2722 break;
2723 case 16:
2724 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2725 if (!NT_STATUS_IS_OK(status)) {
2726 return status;
2728 break;
2730 case 18:
2731 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2732 if (!NT_STATUS_IS_OK(status)) {
2733 return status;
2735 break;
2737 case 20:
2738 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2739 if (!NT_STATUS_IS_OK(status)) {
2740 return status;
2742 break;
2744 case 21:
2745 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2746 &info->sid, &domain_sid);
2747 if (!NT_STATUS_IS_OK(status)) {
2748 return status;
2750 break;
2752 default:
2753 return NT_STATUS_INVALID_INFO_CLASS;
2756 *r->out.info = user_info;
2758 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2760 return status;
2763 /*******************************************************************
2764 _samr_GetGroupsForUser
2765 ********************************************************************/
2767 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2768 struct samr_GetGroupsForUser *r)
2770 struct samu *sam_pass=NULL;
2771 DOM_SID sid;
2772 DOM_SID *sids;
2773 struct samr_RidWithAttribute dom_gid;
2774 struct samr_RidWithAttribute *gids = NULL;
2775 uint32 primary_group_rid;
2776 size_t num_groups = 0;
2777 gid_t *unix_gids;
2778 size_t i, num_gids;
2779 uint32 acc_granted;
2780 bool ret;
2781 NTSTATUS result;
2782 bool success = False;
2784 struct samr_RidWithAttributeArray *rids = NULL;
2787 * from the SID in the request:
2788 * we should send back the list of DOMAIN GROUPS
2789 * the user is a member of
2791 * and only the DOMAIN GROUPS
2792 * no ALIASES !!! neither aliases of the domain
2793 * nor aliases of the builtin SID
2795 * JFM, 12/2/2001
2798 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2800 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2801 if (!rids) {
2802 return NT_STATUS_NO_MEMORY;
2805 /* find the policy handle. open a policy on it. */
2806 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2807 return NT_STATUS_INVALID_HANDLE;
2809 result = access_check_samr_function(acc_granted,
2810 SA_RIGHT_USER_GET_GROUPS,
2811 "_samr_GetGroupsForUser");
2812 if (!NT_STATUS_IS_OK(result)) {
2813 return result;
2816 if (!sid_check_is_in_our_domain(&sid))
2817 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2819 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2820 return NT_STATUS_NO_MEMORY;
2823 become_root();
2824 ret = pdb_getsampwsid(sam_pass, &sid);
2825 unbecome_root();
2827 if (!ret) {
2828 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2829 sid_string_dbg(&sid)));
2830 return NT_STATUS_NO_SUCH_USER;
2833 sids = NULL;
2835 /* make both calls inside the root block */
2836 become_root();
2837 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2838 &sids, &unix_gids, &num_groups);
2839 if ( NT_STATUS_IS_OK(result) ) {
2840 success = sid_peek_check_rid(get_global_sam_sid(),
2841 pdb_get_group_sid(sam_pass),
2842 &primary_group_rid);
2844 unbecome_root();
2846 if (!NT_STATUS_IS_OK(result)) {
2847 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2848 sid_string_dbg(&sid)));
2849 return result;
2852 if ( !success ) {
2853 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2854 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2855 pdb_get_username(sam_pass)));
2856 TALLOC_FREE(sam_pass);
2857 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2860 gids = NULL;
2861 num_gids = 0;
2863 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2864 SE_GROUP_ENABLED);
2865 dom_gid.rid = primary_group_rid;
2866 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2868 for (i=0; i<num_groups; i++) {
2870 if (!sid_peek_check_rid(get_global_sam_sid(),
2871 &(sids[i]), &dom_gid.rid)) {
2872 DEBUG(10, ("Found sid %s not in our domain\n",
2873 sid_string_dbg(&sids[i])));
2874 continue;
2877 if (dom_gid.rid == primary_group_rid) {
2878 /* We added the primary group directly from the
2879 * sam_account. The other SIDs are unique from
2880 * enum_group_memberships */
2881 continue;
2884 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2887 rids->count = num_gids;
2888 rids->rids = gids;
2890 *r->out.rids = rids;
2892 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2894 return result;
2897 /*******************************************************************
2898 _samr_QueryDomainInfo
2899 ********************************************************************/
2901 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2902 struct samr_QueryDomainInfo *r)
2904 NTSTATUS status = NT_STATUS_OK;
2905 struct samr_info *info = NULL;
2906 union samr_DomainInfo *dom_info;
2907 uint32 min_pass_len,pass_hist,password_properties;
2908 time_t u_expire, u_min_age;
2909 NTTIME nt_expire, nt_min_age;
2911 time_t u_lock_duration, u_reset_time;
2912 NTTIME nt_lock_duration, nt_reset_time;
2913 uint32 lockout;
2914 time_t u_logout;
2915 NTTIME nt_logout;
2917 uint32 account_policy_temp;
2919 time_t seq_num;
2920 uint32 server_role;
2922 uint32 num_users=0, num_groups=0, num_aliases=0;
2924 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2926 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2927 if (!dom_info) {
2928 return NT_STATUS_NO_MEMORY;
2931 /* find the policy handle. open a policy on it. */
2932 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
2933 return NT_STATUS_INVALID_HANDLE;
2936 switch (r->in.level) {
2937 case 0x01:
2939 become_root();
2941 /* AS ROOT !!! */
2943 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2944 min_pass_len = account_policy_temp;
2946 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2947 pass_hist = account_policy_temp;
2949 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2950 password_properties = account_policy_temp;
2952 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2953 u_expire = account_policy_temp;
2955 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2956 u_min_age = account_policy_temp;
2958 /* !AS ROOT */
2960 unbecome_root();
2962 unix_to_nt_time_abs(&nt_expire, u_expire);
2963 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2965 if (lp_check_password_script() && *lp_check_password_script()) {
2966 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2969 init_samr_DomInfo1(&dom_info->info1,
2970 (uint16)min_pass_len,
2971 (uint16)pass_hist,
2972 password_properties,
2973 nt_expire,
2974 nt_min_age);
2975 break;
2976 case 0x02:
2978 become_root();
2980 /* AS ROOT !!! */
2982 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2983 num_groups = count_sam_groups(info->disp_info);
2984 num_aliases = count_sam_aliases(info->disp_info);
2986 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2987 u_logout = account_policy_temp;
2989 unix_to_nt_time_abs(&nt_logout, u_logout);
2991 if (!pdb_get_seq_num(&seq_num))
2992 seq_num = time(NULL);
2994 /* !AS ROOT */
2996 unbecome_root();
2998 server_role = ROLE_DOMAIN_PDC;
2999 if (lp_server_role() == ROLE_DOMAIN_BDC)
3000 server_role = ROLE_DOMAIN_BDC;
3002 init_samr_DomInfo2(&dom_info->info2,
3003 nt_logout,
3004 lp_serverstring(),
3005 lp_workgroup(),
3006 global_myname(),
3007 seq_num,
3009 server_role,
3011 num_users,
3012 num_groups,
3013 num_aliases);
3014 break;
3015 case 0x03:
3017 become_root();
3019 /* AS ROOT !!! */
3022 uint32 ul;
3023 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3024 u_logout = (time_t)ul;
3027 /* !AS ROOT */
3029 unbecome_root();
3031 unix_to_nt_time_abs(&nt_logout, u_logout);
3033 init_samr_DomInfo3(&dom_info->info3,
3034 nt_logout);
3036 break;
3037 case 0x04:
3038 init_samr_DomInfo4(&dom_info->info4,
3039 lp_serverstring());
3040 break;
3041 case 0x05:
3042 init_samr_DomInfo5(&dom_info->info5,
3043 get_global_sam_name());
3044 break;
3045 case 0x06:
3046 /* NT returns its own name when a PDC. win2k and later
3047 * only the name of the PDC if itself is a BDC (samba4
3048 * idl) */
3049 init_samr_DomInfo6(&dom_info->info6,
3050 global_myname());
3051 break;
3052 case 0x07:
3053 server_role = ROLE_DOMAIN_PDC;
3054 if (lp_server_role() == ROLE_DOMAIN_BDC)
3055 server_role = ROLE_DOMAIN_BDC;
3057 init_samr_DomInfo7(&dom_info->info7,
3058 server_role);
3059 break;
3060 case 0x08:
3062 become_root();
3064 /* AS ROOT !!! */
3066 if (!pdb_get_seq_num(&seq_num)) {
3067 seq_num = time(NULL);
3070 /* !AS ROOT */
3072 unbecome_root();
3074 init_samr_DomInfo8(&dom_info->info8,
3075 seq_num,
3077 break;
3078 case 0x0c:
3080 become_root();
3082 /* AS ROOT !!! */
3084 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3085 u_lock_duration = account_policy_temp;
3086 if (u_lock_duration != -1) {
3087 u_lock_duration *= 60;
3090 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3091 u_reset_time = account_policy_temp * 60;
3093 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3094 lockout = account_policy_temp;
3096 /* !AS ROOT */
3098 unbecome_root();
3100 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3101 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3103 init_samr_DomInfo12(&dom_info->info12,
3104 nt_lock_duration,
3105 nt_reset_time,
3106 (uint16)lockout);
3107 break;
3108 default:
3109 return NT_STATUS_INVALID_INFO_CLASS;
3112 *r->out.info = dom_info;
3114 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3116 return status;
3119 /* W2k3 seems to use the same check for all 3 objects that can be created via
3120 * SAMR, if you try to create for example "Dialup" as an alias it says
3121 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3122 * database. */
3124 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3126 enum lsa_SidType type;
3127 bool result;
3129 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3131 become_root();
3132 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3133 * whether the name already exists */
3134 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3135 NULL, NULL, NULL, &type);
3136 unbecome_root();
3138 if (!result) {
3139 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3140 return NT_STATUS_OK;
3143 DEBUG(5, ("trying to create %s, exists as %s\n",
3144 new_name, sid_type_lookup(type)));
3146 if (type == SID_NAME_DOM_GRP) {
3147 return NT_STATUS_GROUP_EXISTS;
3149 if (type == SID_NAME_ALIAS) {
3150 return NT_STATUS_ALIAS_EXISTS;
3153 /* Yes, the default is NT_STATUS_USER_EXISTS */
3154 return NT_STATUS_USER_EXISTS;
3157 /*******************************************************************
3158 _samr_CreateUser2
3159 ********************************************************************/
3161 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3162 struct samr_CreateUser2 *r)
3164 const char *account = NULL;
3165 DOM_SID sid;
3166 POLICY_HND dom_pol = *r->in.domain_handle;
3167 uint32_t acb_info = r->in.acct_flags;
3168 POLICY_HND *user_pol = r->out.user_handle;
3169 struct samr_info *info = NULL;
3170 NTSTATUS nt_status;
3171 uint32 acc_granted;
3172 SEC_DESC *psd;
3173 size_t sd_size;
3174 /* check this, when giving away 'add computer to domain' privs */
3175 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3176 bool can_add_account = False;
3177 SE_PRIV se_rights;
3178 DISP_INFO *disp_info = NULL;
3180 /* Get the domain SID stored in the domain policy */
3181 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3182 &disp_info))
3183 return NT_STATUS_INVALID_HANDLE;
3185 nt_status = access_check_samr_function(acc_granted,
3186 SA_RIGHT_DOMAIN_CREATE_USER,
3187 "_samr_CreateUser2");
3188 if (!NT_STATUS_IS_OK(nt_status)) {
3189 return nt_status;
3192 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3193 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3194 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3195 this parameter is not an account type */
3196 return NT_STATUS_INVALID_PARAMETER;
3199 account = r->in.account_name->string;
3200 if (account == NULL) {
3201 return NT_STATUS_NO_MEMORY;
3204 nt_status = can_create(p->mem_ctx, account);
3205 if (!NT_STATUS_IS_OK(nt_status)) {
3206 return nt_status;
3209 /* determine which user right we need to check based on the acb_info */
3211 if ( acb_info & ACB_WSTRUST )
3213 se_priv_copy( &se_rights, &se_machine_account );
3214 can_add_account = user_has_privileges(
3215 p->pipe_user.nt_user_token, &se_rights );
3217 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3218 account for domain trusts and changes the ACB flags later */
3219 else if ( acb_info & ACB_NORMAL &&
3220 (account[strlen(account)-1] != '$') )
3222 se_priv_copy( &se_rights, &se_add_users );
3223 can_add_account = user_has_privileges(
3224 p->pipe_user.nt_user_token, &se_rights );
3226 else /* implicit assumption of a BDC or domain trust account here
3227 * (we already check the flags earlier) */
3229 if ( lp_enable_privileges() ) {
3230 /* only Domain Admins can add a BDC or domain trust */
3231 se_priv_copy( &se_rights, &se_priv_none );
3232 can_add_account = nt_token_check_domain_rid(
3233 p->pipe_user.nt_user_token,
3234 DOMAIN_GROUP_RID_ADMINS );
3238 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3239 uidtoname(p->pipe_user.ut.uid),
3240 can_add_account ? "True":"False" ));
3242 /********** BEGIN Admin BLOCK **********/
3244 if ( can_add_account )
3245 become_root();
3247 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3248 r->out.rid);
3250 if ( can_add_account )
3251 unbecome_root();
3253 /********** END Admin BLOCK **********/
3255 /* now check for failure */
3257 if ( !NT_STATUS_IS_OK(nt_status) )
3258 return nt_status;
3260 /* Get the user's SID */
3262 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3264 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3266 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3267 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3268 se_map_generic(&des_access, &usr_generic_mapping);
3270 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3271 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3272 &acc_granted, "_samr_CreateUser2");
3274 if ( !NT_STATUS_IS_OK(nt_status) ) {
3275 return nt_status;
3278 /* associate the user's SID with the new handle. */
3279 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3280 return NT_STATUS_NO_MEMORY;
3283 ZERO_STRUCTP(info);
3284 info->sid = sid;
3285 info->acc_granted = acc_granted;
3287 /* get a (unique) handle. open a policy on it. */
3288 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3289 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3292 /* After a "set" ensure we have no cached display info. */
3293 force_flush_samr_cache(info->disp_info);
3295 *r->out.access_granted = acc_granted;
3297 return NT_STATUS_OK;
3300 /*******************************************************************
3301 _samr_Connect
3302 ********************************************************************/
3304 NTSTATUS _samr_Connect(pipes_struct *p,
3305 struct samr_Connect *r)
3307 struct samr_info *info = NULL;
3308 uint32 des_access = r->in.access_mask;
3310 /* Access check */
3312 if (!pipe_access_check(p)) {
3313 DEBUG(3, ("access denied to _samr_Connect\n"));
3314 return NT_STATUS_ACCESS_DENIED;
3317 /* set up the SAMR connect_anon response */
3319 /* associate the user's SID with the new handle. */
3320 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3321 return NT_STATUS_NO_MEMORY;
3323 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3324 was observed from a win98 client trying to enumerate users (when configured
3325 user level access control on shares) --jerry */
3327 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3329 se_map_generic( &des_access, &sam_generic_mapping );
3330 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_LOOKUP_DOMAIN);
3332 /* get a (unique) handle. open a policy on it. */
3333 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3334 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3336 return NT_STATUS_OK;
3339 /*******************************************************************
3340 _samr_Connect2
3341 ********************************************************************/
3343 NTSTATUS _samr_Connect2(pipes_struct *p,
3344 struct samr_Connect2 *r)
3346 struct samr_info *info = NULL;
3347 SEC_DESC *psd = NULL;
3348 uint32 acc_granted;
3349 uint32 des_access = r->in.access_mask;
3350 NTSTATUS nt_status;
3351 size_t sd_size;
3354 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3356 /* Access check */
3358 if (!pipe_access_check(p)) {
3359 DEBUG(3, ("access denied to _samr_Connect2\n"));
3360 return NT_STATUS_ACCESS_DENIED;
3363 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3365 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3366 se_map_generic(&des_access, &sam_generic_mapping);
3368 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3369 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3371 if ( !NT_STATUS_IS_OK(nt_status) )
3372 return nt_status;
3374 /* associate the user's SID and access granted with the new handle. */
3375 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3376 return NT_STATUS_NO_MEMORY;
3378 info->acc_granted = acc_granted;
3379 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3381 /* get a (unique) handle. open a policy on it. */
3382 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3383 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3385 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3387 return nt_status;
3390 /*******************************************************************
3391 _samr_Connect4
3392 ********************************************************************/
3394 NTSTATUS _samr_Connect4(pipes_struct *p,
3395 struct samr_Connect4 *r)
3397 struct samr_info *info = NULL;
3398 SEC_DESC *psd = NULL;
3399 uint32 acc_granted;
3400 uint32 des_access = r->in.access_mask;
3401 NTSTATUS nt_status;
3402 size_t sd_size;
3405 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3407 /* Access check */
3409 if (!pipe_access_check(p)) {
3410 DEBUG(3, ("access denied to samr_Connect4\n"));
3411 return NT_STATUS_ACCESS_DENIED;
3414 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3416 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3417 se_map_generic(&des_access, &sam_generic_mapping);
3419 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3420 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3422 if ( !NT_STATUS_IS_OK(nt_status) )
3423 return nt_status;
3425 /* associate the user's SID and access granted with the new handle. */
3426 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3427 return NT_STATUS_NO_MEMORY;
3429 info->acc_granted = acc_granted;
3430 info->status = r->in.access_mask; /* ??? */
3432 /* get a (unique) handle. open a policy on it. */
3433 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3434 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3436 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3438 return NT_STATUS_OK;
3441 /*******************************************************************
3442 _samr_Connect5
3443 ********************************************************************/
3445 NTSTATUS _samr_Connect5(pipes_struct *p,
3446 struct samr_Connect5 *r)
3448 struct samr_info *info = NULL;
3449 SEC_DESC *psd = NULL;
3450 uint32 acc_granted;
3451 uint32 des_access = r->in.access_mask;
3452 NTSTATUS nt_status;
3453 size_t sd_size;
3454 struct samr_ConnectInfo1 info1;
3456 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3458 /* Access check */
3460 if (!pipe_access_check(p)) {
3461 DEBUG(3, ("access denied to samr_Connect5\n"));
3462 return NT_STATUS_ACCESS_DENIED;
3465 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3467 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3468 se_map_generic(&des_access, &sam_generic_mapping);
3470 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3471 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3473 if ( !NT_STATUS_IS_OK(nt_status) )
3474 return nt_status;
3476 /* associate the user's SID and access granted with the new handle. */
3477 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3478 return NT_STATUS_NO_MEMORY;
3480 info->acc_granted = acc_granted;
3481 info->status = r->in.access_mask; /* ??? */
3483 /* get a (unique) handle. open a policy on it. */
3484 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3485 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3487 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3489 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3490 info1.unknown2 = 0;
3492 *r->out.level_out = 1;
3493 r->out.info_out->info1 = info1;
3495 return NT_STATUS_OK;
3498 /**********************************************************************
3499 _samr_LookupDomain
3500 **********************************************************************/
3502 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3503 struct samr_LookupDomain *r)
3505 NTSTATUS status = NT_STATUS_OK;
3506 struct samr_info *info;
3507 const char *domain_name;
3508 DOM_SID *sid = NULL;
3510 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3511 return NT_STATUS_INVALID_HANDLE;
3513 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3514 Reverted that change so we will work with RAS servers again */
3516 status = access_check_samr_function(info->acc_granted,
3517 SA_RIGHT_SAM_LOOKUP_DOMAIN,
3518 "_samr_LookupDomain");
3519 if (!NT_STATUS_IS_OK(status)) {
3520 return status;
3523 domain_name = r->in.domain_name->string;
3525 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3526 if (!sid) {
3527 return NT_STATUS_NO_MEMORY;
3530 if (strequal(domain_name, builtin_domain_name())) {
3531 sid_copy(sid, &global_sid_Builtin);
3532 } else {
3533 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3534 status = NT_STATUS_NO_SUCH_DOMAIN;
3538 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3539 sid_string_dbg(sid)));
3541 *r->out.sid = sid;
3543 return status;
3546 /**********************************************************************
3547 _samr_EnumDomains
3548 **********************************************************************/
3550 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3551 struct samr_EnumDomains *r)
3553 NTSTATUS status;
3554 struct samr_info *info;
3555 uint32_t num_entries = 2;
3556 struct samr_SamEntry *entry_array = NULL;
3557 struct samr_SamArray *sam;
3559 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3560 return NT_STATUS_INVALID_HANDLE;
3562 status = access_check_samr_function(info->acc_granted,
3563 SA_RIGHT_SAM_ENUM_DOMAINS,
3564 "_samr_EnumDomains");
3565 if (!NT_STATUS_IS_OK(status)) {
3566 return status;
3569 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3570 if (!sam) {
3571 return NT_STATUS_NO_MEMORY;
3574 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3575 struct samr_SamEntry,
3576 num_entries);
3577 if (!entry_array) {
3578 return NT_STATUS_NO_MEMORY;
3581 entry_array[0].idx = 0;
3582 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3584 entry_array[1].idx = 1;
3585 init_lsa_String(&entry_array[1].name, "Builtin");
3587 sam->count = num_entries;
3588 sam->entries = entry_array;
3590 *r->out.sam = sam;
3591 *r->out.num_entries = num_entries;
3593 return status;
3596 /*******************************************************************
3597 _samr_OpenAlias
3598 ********************************************************************/
3600 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3601 struct samr_OpenAlias *r)
3603 DOM_SID sid;
3604 POLICY_HND domain_pol = *r->in.domain_handle;
3605 uint32 alias_rid = r->in.rid;
3606 POLICY_HND *alias_pol = r->out.alias_handle;
3607 struct samr_info *info = NULL;
3608 SEC_DESC *psd = NULL;
3609 uint32 acc_granted;
3610 uint32 des_access = r->in.access_mask;
3611 size_t sd_size;
3612 NTSTATUS status;
3613 SE_PRIV se_rights;
3615 /* find the domain policy and get the SID / access bits stored in the domain policy */
3617 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3618 return NT_STATUS_INVALID_HANDLE;
3620 status = access_check_samr_function(acc_granted,
3621 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3622 "_samr_OpenAlias");
3624 if ( !NT_STATUS_IS_OK(status) )
3625 return status;
3627 /* append the alias' RID to it */
3629 if (!sid_append_rid(&sid, alias_rid))
3630 return NT_STATUS_NO_SUCH_ALIAS;
3632 /*check if access can be granted as requested by client. */
3634 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
3636 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3637 se_map_generic(&des_access,&ali_generic_mapping);
3639 se_priv_copy( &se_rights, &se_add_users );
3642 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3643 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3644 &acc_granted, "_samr_OpenAlias");
3646 if ( !NT_STATUS_IS_OK(status) )
3647 return status;
3650 /* Check we actually have the requested alias */
3651 enum lsa_SidType type;
3652 bool result;
3653 gid_t gid;
3655 become_root();
3656 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3657 unbecome_root();
3659 if (!result || (type != SID_NAME_ALIAS)) {
3660 return NT_STATUS_NO_SUCH_ALIAS;
3663 /* make sure there is a mapping */
3665 if ( !sid_to_gid( &sid, &gid ) ) {
3666 return NT_STATUS_NO_SUCH_ALIAS;
3671 /* associate the alias SID with the new handle. */
3672 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3673 return NT_STATUS_NO_MEMORY;
3675 info->acc_granted = acc_granted;
3677 /* get a (unique) handle. open a policy on it. */
3678 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3679 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3681 return NT_STATUS_OK;
3684 /*******************************************************************
3685 set_user_info_7
3686 ********************************************************************/
3688 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3689 struct samr_UserInfo7 *id7,
3690 struct samu *pwd)
3692 NTSTATUS rc;
3694 if (id7 == NULL) {
3695 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3696 TALLOC_FREE(pwd);
3697 return NT_STATUS_ACCESS_DENIED;
3700 if (!id7->account_name.string) {
3701 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3702 TALLOC_FREE(pwd);
3703 return NT_STATUS_ACCESS_DENIED;
3706 /* check to see if the new username already exists. Note: we can't
3707 reliably lock all backends, so there is potentially the
3708 possibility that a user can be created in between this check and
3709 the rename. The rename should fail, but may not get the
3710 exact same failure status code. I think this is small enough
3711 of a window for this type of operation and the results are
3712 simply that the rename fails with a slightly different status
3713 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3715 rc = can_create(mem_ctx, id7->account_name.string);
3716 if (!NT_STATUS_IS_OK(rc)) {
3717 return rc;
3720 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3722 TALLOC_FREE(pwd);
3723 return rc;
3726 /*******************************************************************
3727 set_user_info_16
3728 ********************************************************************/
3730 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3731 struct samu *pwd)
3733 if (id16 == NULL) {
3734 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3735 TALLOC_FREE(pwd);
3736 return False;
3739 /* FIX ME: check if the value is really changed --metze */
3740 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3741 TALLOC_FREE(pwd);
3742 return False;
3745 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3746 TALLOC_FREE(pwd);
3747 return False;
3750 TALLOC_FREE(pwd);
3752 return True;
3755 /*******************************************************************
3756 set_user_info_18
3757 ********************************************************************/
3759 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3760 struct samu *pwd)
3762 if (id18 == NULL) {
3763 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3764 TALLOC_FREE(pwd);
3765 return False;
3768 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3769 TALLOC_FREE(pwd);
3770 return False;
3772 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3773 TALLOC_FREE(pwd);
3774 return False;
3776 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3777 TALLOC_FREE(pwd);
3778 return False;
3781 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3782 TALLOC_FREE(pwd);
3783 return False;
3786 TALLOC_FREE(pwd);
3787 return True;
3790 /*******************************************************************
3791 set_user_info_20
3792 ********************************************************************/
3794 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3795 struct samu *pwd)
3797 if (id20 == NULL) {
3798 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3799 return False;
3802 copy_id20_to_sam_passwd(pwd, id20);
3804 /* write the change out */
3805 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3806 TALLOC_FREE(pwd);
3807 return False;
3810 TALLOC_FREE(pwd);
3812 return True;
3815 /*******************************************************************
3816 set_user_info_21
3817 ********************************************************************/
3819 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3820 struct samr_UserInfo21 *id21,
3821 struct samu *pwd)
3823 NTSTATUS status;
3825 if (id21 == NULL) {
3826 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3827 return NT_STATUS_INVALID_PARAMETER;
3830 /* we need to separately check for an account rename first */
3832 if (id21->account_name.string &&
3833 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3836 /* check to see if the new username already exists. Note: we can't
3837 reliably lock all backends, so there is potentially the
3838 possibility that a user can be created in between this check and
3839 the rename. The rename should fail, but may not get the
3840 exact same failure status code. I think this is small enough
3841 of a window for this type of operation and the results are
3842 simply that the rename fails with a slightly different status
3843 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3845 status = can_create(mem_ctx, id21->account_name.string);
3846 if (!NT_STATUS_IS_OK(status)) {
3847 return status;
3850 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3852 if (!NT_STATUS_IS_OK(status)) {
3853 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3854 nt_errstr(status)));
3855 TALLOC_FREE(pwd);
3856 return status;
3859 /* set the new username so that later
3860 functions can work on the new account */
3861 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3864 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3867 * The funny part about the previous two calls is
3868 * that pwd still has the password hashes from the
3869 * passdb entry. These have not been updated from
3870 * id21. I don't know if they need to be set. --jerry
3873 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3874 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3875 if ( !NT_STATUS_IS_OK(status) ) {
3876 return status;
3880 /* Don't worry about writing out the user account since the
3881 primary group SID is generated solely from the user's Unix
3882 primary group. */
3884 /* write the change out */
3885 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3886 TALLOC_FREE(pwd);
3887 return status;
3890 TALLOC_FREE(pwd);
3892 return NT_STATUS_OK;
3895 /*******************************************************************
3896 set_user_info_23
3897 ********************************************************************/
3899 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3900 struct samr_UserInfo23 *id23,
3901 struct samu *pwd)
3903 char *plaintext_buf = NULL;
3904 uint32 len = 0;
3905 uint16 acct_ctrl;
3906 NTSTATUS status;
3908 if (id23 == NULL) {
3909 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3910 return NT_STATUS_INVALID_PARAMETER;
3913 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3914 pdb_get_username(pwd)));
3916 acct_ctrl = pdb_get_acct_ctrl(pwd);
3918 if (!decode_pw_buffer(mem_ctx,
3919 id23->password.data,
3920 &plaintext_buf,
3921 &len,
3922 STR_UNICODE)) {
3923 TALLOC_FREE(pwd);
3924 return NT_STATUS_INVALID_PARAMETER;
3927 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3928 TALLOC_FREE(pwd);
3929 return NT_STATUS_ACCESS_DENIED;
3932 copy_id23_to_sam_passwd(pwd, id23);
3934 /* if it's a trust account, don't update /etc/passwd */
3935 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3936 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3937 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3938 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3939 } else {
3940 /* update the UNIX password */
3941 if (lp_unix_password_sync() ) {
3942 struct passwd *passwd;
3943 if (pdb_get_username(pwd) == NULL) {
3944 DEBUG(1, ("chgpasswd: User without name???\n"));
3945 TALLOC_FREE(pwd);
3946 return NT_STATUS_ACCESS_DENIED;
3949 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3950 if (passwd == NULL) {
3951 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3954 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3955 TALLOC_FREE(pwd);
3956 return NT_STATUS_ACCESS_DENIED;
3958 TALLOC_FREE(passwd);
3962 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3964 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3965 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3966 pwd)))) {
3967 TALLOC_FREE(pwd);
3968 return status;
3971 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3972 TALLOC_FREE(pwd);
3973 return status;
3976 TALLOC_FREE(pwd);
3978 return NT_STATUS_OK;
3981 /*******************************************************************
3982 set_user_info_pw
3983 ********************************************************************/
3985 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
3986 int level)
3988 uint32 len = 0;
3989 char *plaintext_buf = NULL;
3990 uint32 acct_ctrl;
3991 time_t last_set_time;
3992 enum pdb_value_state last_set_state;
3994 DEBUG(5, ("Attempting administrator password change for user %s\n",
3995 pdb_get_username(pwd)));
3997 acct_ctrl = pdb_get_acct_ctrl(pwd);
3998 /* we need to know if it's expired, because this is an admin change, not a
3999 user change, so it's still expired when we're done */
4000 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
4001 last_set_time = pdb_get_pass_last_set_time(pwd);
4003 if (!decode_pw_buffer(talloc_tos(),
4004 pass,
4005 &plaintext_buf,
4006 &len,
4007 STR_UNICODE)) {
4008 TALLOC_FREE(pwd);
4009 return False;
4012 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4013 TALLOC_FREE(pwd);
4014 return False;
4017 /* if it's a trust account, don't update /etc/passwd */
4018 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4019 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4020 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4021 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4022 } else {
4023 /* update the UNIX password */
4024 if (lp_unix_password_sync()) {
4025 struct passwd *passwd;
4027 if (pdb_get_username(pwd) == NULL) {
4028 DEBUG(1, ("chgpasswd: User without name???\n"));
4029 TALLOC_FREE(pwd);
4030 return False;
4033 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4034 if (passwd == NULL) {
4035 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4038 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4039 TALLOC_FREE(pwd);
4040 return False;
4042 TALLOC_FREE(passwd);
4046 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4049 * A level 25 change does reset the pwdlastset field, a level 24
4050 * change does not. I know this is probably not the full story, but
4051 * it is needed to make XP join LDAP correctly, without it the later
4052 * auth2 check can fail with PWD_MUST_CHANGE.
4054 if (level != 25) {
4056 * restore last set time as this is an admin change, not a
4057 * user pw change
4059 pdb_set_pass_last_set_time (pwd, last_set_time,
4060 last_set_state);
4063 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4065 /* update the SAMBA password */
4066 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4067 TALLOC_FREE(pwd);
4068 return False;
4071 TALLOC_FREE(pwd);
4073 return True;
4076 /*******************************************************************
4077 set_user_info_25
4078 ********************************************************************/
4080 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4081 struct samr_UserInfo25 *id25,
4082 struct samu *pwd)
4084 NTSTATUS status;
4086 if (id25 == NULL) {
4087 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4088 return NT_STATUS_INVALID_PARAMETER;
4091 copy_id25_to_sam_passwd(pwd, id25);
4093 /* write the change out */
4094 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4095 TALLOC_FREE(pwd);
4096 return status;
4100 * We need to "pdb_update_sam_account" before the unix primary group
4101 * is set, because the idealx scripts would also change the
4102 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4103 * the delete explicit / add explicit, which would then fail to find
4104 * the previous primaryGroupSid value.
4107 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4108 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4109 if ( !NT_STATUS_IS_OK(status) ) {
4110 return status;
4114 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
4115 * hereafter! */
4117 return NT_STATUS_OK;
4120 /*******************************************************************
4121 samr_SetUserInfo
4122 ********************************************************************/
4124 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4125 struct samr_SetUserInfo *r)
4127 NTSTATUS status;
4128 struct samu *pwd = NULL;
4129 DOM_SID sid;
4130 POLICY_HND *pol = r->in.user_handle;
4131 union samr_UserInfo *info = r->in.info;
4132 uint16_t switch_value = r->in.level;
4133 uint32_t acc_granted;
4134 uint32_t acc_required;
4135 bool ret;
4136 bool has_enough_rights = False;
4137 uint32_t acb_info;
4138 DISP_INFO *disp_info = NULL;
4140 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4142 /* find the policy handle. open a policy on it. */
4143 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4144 return NT_STATUS_INVALID_HANDLE;
4147 /* This is tricky. A WinXP domain join sets
4148 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4149 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4150 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4151 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4152 we'll use the set from the WinXP join as the basis. */
4154 switch (switch_value) {
4155 case 18:
4156 case 24:
4157 case 25:
4158 case 26:
4159 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4160 break;
4161 default:
4162 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4163 SA_RIGHT_USER_SET_ATTRIBUTES |
4164 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4165 break;
4168 status = access_check_samr_function(acc_granted,
4169 acc_required,
4170 "_samr_SetUserInfo");
4171 if (!NT_STATUS_IS_OK(status)) {
4172 return status;
4175 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4176 sid_string_dbg(&sid), switch_value));
4178 if (info == NULL) {
4179 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4180 return NT_STATUS_INVALID_INFO_CLASS;
4183 if (!(pwd = samu_new(NULL))) {
4184 return NT_STATUS_NO_MEMORY;
4187 become_root();
4188 ret = pdb_getsampwsid(pwd, &sid);
4189 unbecome_root();
4191 if (!ret) {
4192 TALLOC_FREE(pwd);
4193 return NT_STATUS_NO_SUCH_USER;
4196 /* deal with machine password changes differently from userinfo changes */
4197 /* check to see if we have the sufficient rights */
4199 acb_info = pdb_get_acct_ctrl(pwd);
4200 if (acb_info & ACB_WSTRUST)
4201 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4202 &se_machine_account);
4203 else if (acb_info & ACB_NORMAL)
4204 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4205 &se_add_users);
4206 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4207 if (lp_enable_privileges()) {
4208 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4209 DOMAIN_GROUP_RID_ADMINS);
4213 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4214 uidtoname(p->pipe_user.ut.uid),
4215 has_enough_rights ? "" : " not"));
4217 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4219 if (has_enough_rights) {
4220 become_root();
4223 /* ok! user info levels (lots: see MSDEV help), off we go... */
4225 switch (switch_value) {
4227 case 7:
4228 status = set_user_info_7(p->mem_ctx,
4229 &info->info7, pwd);
4230 break;
4232 case 16:
4233 if (!set_user_info_16(&info->info16, pwd)) {
4234 status = NT_STATUS_ACCESS_DENIED;
4236 break;
4238 case 18:
4239 /* Used by AS/U JRA. */
4240 if (!set_user_info_18(&info->info18, pwd)) {
4241 status = NT_STATUS_ACCESS_DENIED;
4243 break;
4245 case 20:
4246 if (!set_user_info_20(&info->info20, pwd)) {
4247 status = NT_STATUS_ACCESS_DENIED;
4249 break;
4251 case 21:
4252 status = set_user_info_21(p->mem_ctx,
4253 &info->info21, pwd);
4254 break;
4256 case 23:
4257 if (!p->session_key.length) {
4258 status = NT_STATUS_NO_USER_SESSION_KEY;
4260 SamOEMhashBlob(info->info23.password.data, 516,
4261 &p->session_key);
4263 dump_data(100, info->info23.password.data, 516);
4265 status = set_user_info_23(p->mem_ctx,
4266 &info->info23, pwd);
4267 break;
4269 case 24:
4270 if (!p->session_key.length) {
4271 status = NT_STATUS_NO_USER_SESSION_KEY;
4273 SamOEMhashBlob(info->info24.password.data,
4274 516,
4275 &p->session_key);
4277 dump_data(100, info->info24.password.data, 516);
4279 if (!set_user_info_pw(info->info24.password.data, pwd,
4280 switch_value)) {
4281 status = NT_STATUS_ACCESS_DENIED;
4283 break;
4285 case 25:
4286 if (!p->session_key.length) {
4287 status = NT_STATUS_NO_USER_SESSION_KEY;
4289 encode_or_decode_arc4_passwd_buffer(info->info25.password.data,
4290 &p->session_key);
4292 dump_data(100, info->info25.password.data, 532);
4294 status = set_user_info_25(p->mem_ctx,
4295 &info->info25, pwd);
4296 if (!NT_STATUS_IS_OK(status)) {
4297 goto done;
4299 if (!set_user_info_pw(info->info25.password.data, pwd,
4300 switch_value)) {
4301 status = NT_STATUS_ACCESS_DENIED;
4303 break;
4305 case 26:
4306 if (!p->session_key.length) {
4307 status = NT_STATUS_NO_USER_SESSION_KEY;
4309 encode_or_decode_arc4_passwd_buffer(info->info26.password.data,
4310 &p->session_key);
4312 dump_data(100, info->info26.password.data, 516);
4314 if (!set_user_info_pw(info->info26.password.data, pwd,
4315 switch_value)) {
4316 status = NT_STATUS_ACCESS_DENIED;
4318 break;
4320 default:
4321 status = NT_STATUS_INVALID_INFO_CLASS;
4324 done:
4326 if (has_enough_rights) {
4327 unbecome_root();
4330 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4332 if (NT_STATUS_IS_OK(status)) {
4333 force_flush_samr_cache(disp_info);
4336 return status;
4339 /*******************************************************************
4340 _samr_SetUserInfo2
4341 ********************************************************************/
4343 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4344 struct samr_SetUserInfo2 *r)
4346 struct samr_SetUserInfo q;
4348 q.in.user_handle = r->in.user_handle;
4349 q.in.level = r->in.level;
4350 q.in.info = r->in.info;
4352 return _samr_SetUserInfo(p, &q);
4355 /*********************************************************************
4356 _samr_GetAliasMembership
4357 *********************************************************************/
4359 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4360 struct samr_GetAliasMembership *r)
4362 size_t num_alias_rids;
4363 uint32 *alias_rids;
4364 struct samr_info *info = NULL;
4365 size_t i;
4367 NTSTATUS ntstatus1;
4368 NTSTATUS ntstatus2;
4370 DOM_SID *members;
4372 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4374 /* find the policy handle. open a policy on it. */
4375 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4376 return NT_STATUS_INVALID_HANDLE;
4378 ntstatus1 = access_check_samr_function(info->acc_granted,
4379 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4380 "_samr_GetAliasMembership");
4381 ntstatus2 = access_check_samr_function(info->acc_granted,
4382 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4383 "_samr_GetAliasMembership");
4385 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4386 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4387 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4388 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4392 if (!sid_check_is_domain(&info->sid) &&
4393 !sid_check_is_builtin(&info->sid))
4394 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4396 if (r->in.sids->num_sids) {
4397 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4399 if (members == NULL)
4400 return NT_STATUS_NO_MEMORY;
4401 } else {
4402 members = NULL;
4405 for (i=0; i<r->in.sids->num_sids; i++)
4406 sid_copy(&members[i], r->in.sids->sids[i].sid);
4408 alias_rids = NULL;
4409 num_alias_rids = 0;
4411 become_root();
4412 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4413 r->in.sids->num_sids,
4414 &alias_rids, &num_alias_rids);
4415 unbecome_root();
4417 if (!NT_STATUS_IS_OK(ntstatus1)) {
4418 return ntstatus1;
4421 r->out.rids->count = num_alias_rids;
4422 r->out.rids->ids = alias_rids;
4424 return NT_STATUS_OK;
4427 /*********************************************************************
4428 _samr_GetMembersInAlias
4429 *********************************************************************/
4431 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4432 struct samr_GetMembersInAlias *r)
4434 NTSTATUS status;
4435 size_t i;
4436 size_t num_sids = 0;
4437 struct lsa_SidPtr *sids = NULL;
4438 DOM_SID *pdb_sids = NULL;
4440 DOM_SID alias_sid;
4442 uint32 acc_granted;
4444 /* find the policy handle. open a policy on it. */
4445 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4446 return NT_STATUS_INVALID_HANDLE;
4448 status = access_check_samr_function(acc_granted,
4449 SA_RIGHT_ALIAS_GET_MEMBERS,
4450 "_samr_GetMembersInAlias");
4451 if (!NT_STATUS_IS_OK(status)) {
4452 return status;
4455 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4457 become_root();
4458 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4459 unbecome_root();
4461 if (!NT_STATUS_IS_OK(status)) {
4462 return status;
4465 if (num_sids) {
4466 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4467 if (sids == NULL) {
4468 TALLOC_FREE(pdb_sids);
4469 return NT_STATUS_NO_MEMORY;
4473 for (i = 0; i < num_sids; i++) {
4474 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4475 if (!sids[i].sid) {
4476 TALLOC_FREE(pdb_sids);
4477 return NT_STATUS_NO_MEMORY;
4481 r->out.sids->num_sids = num_sids;
4482 r->out.sids->sids = sids;
4484 TALLOC_FREE(pdb_sids);
4486 return NT_STATUS_OK;
4489 /*********************************************************************
4490 _samr_QueryGroupMember
4491 *********************************************************************/
4493 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4494 struct samr_QueryGroupMember *r)
4496 DOM_SID group_sid;
4497 size_t i, num_members;
4499 uint32 *rid=NULL;
4500 uint32 *attr=NULL;
4502 uint32 acc_granted;
4504 NTSTATUS status;
4505 struct samr_RidTypeArray *rids = NULL;
4507 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4508 if (!rids) {
4509 return NT_STATUS_NO_MEMORY;
4512 /* find the policy handle. open a policy on it. */
4513 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4514 return NT_STATUS_INVALID_HANDLE;
4516 status = access_check_samr_function(acc_granted,
4517 SA_RIGHT_GROUP_GET_MEMBERS,
4518 "_samr_QueryGroupMember");
4519 if (!NT_STATUS_IS_OK(status)) {
4520 return status;
4523 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4525 if (!sid_check_is_in_our_domain(&group_sid)) {
4526 DEBUG(3, ("sid %s is not in our domain\n",
4527 sid_string_dbg(&group_sid)));
4528 return NT_STATUS_NO_SUCH_GROUP;
4531 DEBUG(10, ("lookup on Domain SID\n"));
4533 become_root();
4534 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4535 &rid, &num_members);
4536 unbecome_root();
4538 if (!NT_STATUS_IS_OK(status))
4539 return status;
4541 if (num_members) {
4542 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4543 if (attr == NULL) {
4544 return NT_STATUS_NO_MEMORY;
4546 } else {
4547 attr = NULL;
4550 for (i=0; i<num_members; i++)
4551 attr[i] = SID_NAME_USER;
4553 rids->count = num_members;
4554 rids->types = attr;
4555 rids->rids = rid;
4557 *r->out.rids = rids;
4559 return NT_STATUS_OK;
4562 /*********************************************************************
4563 _samr_AddAliasMember
4564 *********************************************************************/
4566 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4567 struct samr_AddAliasMember *r)
4569 DOM_SID alias_sid;
4570 uint32 acc_granted;
4571 SE_PRIV se_rights;
4572 bool can_add_accounts;
4573 NTSTATUS status;
4574 DISP_INFO *disp_info = NULL;
4576 /* Find the policy handle. Open a policy on it. */
4577 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4578 return NT_STATUS_INVALID_HANDLE;
4580 status = access_check_samr_function(acc_granted,
4581 SA_RIGHT_ALIAS_ADD_MEMBER,
4582 "_samr_AddAliasMember");
4583 if (!NT_STATUS_IS_OK(status)) {
4584 return status;
4587 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4589 se_priv_copy( &se_rights, &se_add_users );
4590 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4592 /******** BEGIN SeAddUsers BLOCK *********/
4594 if ( can_add_accounts )
4595 become_root();
4597 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4599 if ( can_add_accounts )
4600 unbecome_root();
4602 /******** END SeAddUsers BLOCK *********/
4604 if (NT_STATUS_IS_OK(status)) {
4605 force_flush_samr_cache(disp_info);
4608 return status;
4611 /*********************************************************************
4612 _samr_DeleteAliasMember
4613 *********************************************************************/
4615 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4616 struct samr_DeleteAliasMember *r)
4618 DOM_SID alias_sid;
4619 uint32 acc_granted;
4620 SE_PRIV se_rights;
4621 bool can_add_accounts;
4622 NTSTATUS status;
4623 DISP_INFO *disp_info = NULL;
4625 /* Find the policy handle. Open a policy on it. */
4626 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4627 return NT_STATUS_INVALID_HANDLE;
4629 status = access_check_samr_function(acc_granted,
4630 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4631 "_samr_DeleteAliasMember");
4632 if (!NT_STATUS_IS_OK(status)) {
4633 return status;
4636 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4637 sid_string_dbg(&alias_sid)));
4639 se_priv_copy( &se_rights, &se_add_users );
4640 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4642 /******** BEGIN SeAddUsers BLOCK *********/
4644 if ( can_add_accounts )
4645 become_root();
4647 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4649 if ( can_add_accounts )
4650 unbecome_root();
4652 /******** END SeAddUsers BLOCK *********/
4654 if (NT_STATUS_IS_OK(status)) {
4655 force_flush_samr_cache(disp_info);
4658 return status;
4661 /*********************************************************************
4662 _samr_AddGroupMember
4663 *********************************************************************/
4665 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4666 struct samr_AddGroupMember *r)
4668 NTSTATUS status;
4669 DOM_SID group_sid;
4670 uint32 group_rid;
4671 uint32 acc_granted;
4672 SE_PRIV se_rights;
4673 bool can_add_accounts;
4674 DISP_INFO *disp_info = NULL;
4676 /* Find the policy handle. Open a policy on it. */
4677 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4678 return NT_STATUS_INVALID_HANDLE;
4680 status = access_check_samr_function(acc_granted,
4681 SA_RIGHT_GROUP_ADD_MEMBER,
4682 "_samr_AddGroupMember");
4683 if (!NT_STATUS_IS_OK(status)) {
4684 return status;
4687 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4689 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4690 &group_rid)) {
4691 return NT_STATUS_INVALID_HANDLE;
4694 se_priv_copy( &se_rights, &se_add_users );
4695 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4697 /******** BEGIN SeAddUsers BLOCK *********/
4699 if ( can_add_accounts )
4700 become_root();
4702 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4704 if ( can_add_accounts )
4705 unbecome_root();
4707 /******** END SeAddUsers BLOCK *********/
4709 force_flush_samr_cache(disp_info);
4711 return status;
4714 /*********************************************************************
4715 _samr_DeleteGroupMember
4716 *********************************************************************/
4718 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4719 struct samr_DeleteGroupMember *r)
4722 NTSTATUS status;
4723 DOM_SID group_sid;
4724 uint32 group_rid;
4725 uint32 acc_granted;
4726 SE_PRIV se_rights;
4727 bool can_add_accounts;
4728 DISP_INFO *disp_info = NULL;
4731 * delete the group member named r->in.rid
4732 * who is a member of the sid associated with the handle
4733 * the rid is a user's rid as the group is a domain group.
4736 /* Find the policy handle. Open a policy on it. */
4737 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4738 return NT_STATUS_INVALID_HANDLE;
4740 status = access_check_samr_function(acc_granted,
4741 SA_RIGHT_GROUP_REMOVE_MEMBER,
4742 "_samr_DeleteGroupMember");
4743 if (!NT_STATUS_IS_OK(status)) {
4744 return status;
4747 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4748 &group_rid)) {
4749 return NT_STATUS_INVALID_HANDLE;
4752 se_priv_copy( &se_rights, &se_add_users );
4753 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4755 /******** BEGIN SeAddUsers BLOCK *********/
4757 if ( can_add_accounts )
4758 become_root();
4760 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4762 if ( can_add_accounts )
4763 unbecome_root();
4765 /******** END SeAddUsers BLOCK *********/
4767 force_flush_samr_cache(disp_info);
4769 return status;
4772 /*********************************************************************
4773 _samr_DeleteUser
4774 *********************************************************************/
4776 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4777 struct samr_DeleteUser *r)
4779 NTSTATUS status;
4780 DOM_SID user_sid;
4781 struct samu *sam_pass=NULL;
4782 uint32 acc_granted;
4783 bool can_add_accounts;
4784 uint32 acb_info;
4785 DISP_INFO *disp_info = NULL;
4786 bool ret;
4788 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4790 /* Find the policy handle. Open a policy on it. */
4791 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4792 return NT_STATUS_INVALID_HANDLE;
4794 status = access_check_samr_function(acc_granted,
4795 STD_RIGHT_DELETE_ACCESS,
4796 "_samr_DeleteUser");
4797 if (!NT_STATUS_IS_OK(status)) {
4798 return status;
4801 if (!sid_check_is_in_our_domain(&user_sid))
4802 return NT_STATUS_CANNOT_DELETE;
4804 /* check if the user exists before trying to delete */
4805 if ( !(sam_pass = samu_new( NULL )) ) {
4806 return NT_STATUS_NO_MEMORY;
4809 become_root();
4810 ret = pdb_getsampwsid(sam_pass, &user_sid);
4811 unbecome_root();
4813 if( !ret ) {
4814 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4815 sid_string_dbg(&user_sid)));
4816 TALLOC_FREE(sam_pass);
4817 return NT_STATUS_NO_SUCH_USER;
4820 acb_info = pdb_get_acct_ctrl(sam_pass);
4822 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4823 if ( acb_info & ACB_WSTRUST ) {
4824 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4825 } else {
4826 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4829 /******** BEGIN SeAddUsers BLOCK *********/
4831 if ( can_add_accounts )
4832 become_root();
4834 status = pdb_delete_user(p->mem_ctx, sam_pass);
4836 if ( can_add_accounts )
4837 unbecome_root();
4839 /******** END SeAddUsers BLOCK *********/
4841 if ( !NT_STATUS_IS_OK(status) ) {
4842 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4843 "user %s: %s.\n", pdb_get_username(sam_pass),
4844 nt_errstr(status)));
4845 TALLOC_FREE(sam_pass);
4846 return status;
4850 TALLOC_FREE(sam_pass);
4852 if (!close_policy_hnd(p, r->in.user_handle))
4853 return NT_STATUS_OBJECT_NAME_INVALID;
4855 ZERO_STRUCTP(r->out.user_handle);
4857 force_flush_samr_cache(disp_info);
4859 return NT_STATUS_OK;
4862 /*********************************************************************
4863 _samr_DeleteDomainGroup
4864 *********************************************************************/
4866 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4867 struct samr_DeleteDomainGroup *r)
4869 NTSTATUS status;
4870 DOM_SID group_sid;
4871 uint32 group_rid;
4872 uint32 acc_granted;
4873 SE_PRIV se_rights;
4874 bool can_add_accounts;
4875 DISP_INFO *disp_info = NULL;
4877 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4879 /* Find the policy handle. Open a policy on it. */
4880 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4881 return NT_STATUS_INVALID_HANDLE;
4883 status = access_check_samr_function(acc_granted,
4884 STD_RIGHT_DELETE_ACCESS,
4885 "_samr_DeleteDomainGroup");
4886 if (!NT_STATUS_IS_OK(status)) {
4887 return status;
4890 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4892 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4893 &group_rid)) {
4894 return NT_STATUS_NO_SUCH_GROUP;
4897 se_priv_copy( &se_rights, &se_add_users );
4898 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4900 /******** BEGIN SeAddUsers BLOCK *********/
4902 if ( can_add_accounts )
4903 become_root();
4905 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4907 if ( can_add_accounts )
4908 unbecome_root();
4910 /******** END SeAddUsers BLOCK *********/
4912 if ( !NT_STATUS_IS_OK(status) ) {
4913 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4914 "entry for group %s: %s\n",
4915 sid_string_dbg(&group_sid),
4916 nt_errstr(status)));
4917 return status;
4920 if (!close_policy_hnd(p, r->in.group_handle))
4921 return NT_STATUS_OBJECT_NAME_INVALID;
4923 force_flush_samr_cache(disp_info);
4925 return NT_STATUS_OK;
4928 /*********************************************************************
4929 _samr_DeleteDomAlias
4930 *********************************************************************/
4932 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4933 struct samr_DeleteDomAlias *r)
4935 DOM_SID alias_sid;
4936 uint32 acc_granted;
4937 SE_PRIV se_rights;
4938 bool can_add_accounts;
4939 NTSTATUS status;
4940 DISP_INFO *disp_info = NULL;
4942 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4944 /* Find the policy handle. Open a policy on it. */
4945 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4946 return NT_STATUS_INVALID_HANDLE;
4948 /* copy the handle to the outgoing reply */
4950 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4952 status = access_check_samr_function(acc_granted,
4953 STD_RIGHT_DELETE_ACCESS,
4954 "_samr_DeleteDomAlias");
4955 if (!NT_STATUS_IS_OK(status)) {
4956 return status;
4959 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4961 /* Don't let Windows delete builtin groups */
4963 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4964 return NT_STATUS_SPECIAL_ACCOUNT;
4967 if (!sid_check_is_in_our_domain(&alias_sid))
4968 return NT_STATUS_NO_SUCH_ALIAS;
4970 DEBUG(10, ("lookup on Local SID\n"));
4972 se_priv_copy( &se_rights, &se_add_users );
4973 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4975 /******** BEGIN SeAddUsers BLOCK *********/
4977 if ( can_add_accounts )
4978 become_root();
4980 /* Have passdb delete the alias */
4981 status = pdb_delete_alias(&alias_sid);
4983 if ( can_add_accounts )
4984 unbecome_root();
4986 /******** END SeAddUsers BLOCK *********/
4988 if ( !NT_STATUS_IS_OK(status))
4989 return status;
4991 if (!close_policy_hnd(p, r->in.alias_handle))
4992 return NT_STATUS_OBJECT_NAME_INVALID;
4994 force_flush_samr_cache(disp_info);
4996 return NT_STATUS_OK;
4999 /*********************************************************************
5000 _samr_CreateDomainGroup
5001 *********************************************************************/
5003 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5004 struct samr_CreateDomainGroup *r)
5007 NTSTATUS status;
5008 DOM_SID dom_sid;
5009 DOM_SID info_sid;
5010 const char *name;
5011 struct samr_info *info;
5012 uint32 acc_granted;
5013 SE_PRIV se_rights;
5014 bool can_add_accounts;
5015 DISP_INFO *disp_info = NULL;
5017 /* Find the policy handle. Open a policy on it. */
5018 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5019 return NT_STATUS_INVALID_HANDLE;
5021 status = access_check_samr_function(acc_granted,
5022 SA_RIGHT_DOMAIN_CREATE_GROUP,
5023 "_samr_CreateDomainGroup");
5024 if (!NT_STATUS_IS_OK(status)) {
5025 return status;
5028 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5029 return NT_STATUS_ACCESS_DENIED;
5031 name = r->in.name->string;
5032 if (name == NULL) {
5033 return NT_STATUS_NO_MEMORY;
5036 status = can_create(p->mem_ctx, name);
5037 if (!NT_STATUS_IS_OK(status)) {
5038 return status;
5041 se_priv_copy( &se_rights, &se_add_users );
5042 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5044 /******** BEGIN SeAddUsers BLOCK *********/
5046 if ( can_add_accounts )
5047 become_root();
5049 /* check that we successfully create the UNIX group */
5051 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5053 if ( can_add_accounts )
5054 unbecome_root();
5056 /******** END SeAddUsers BLOCK *********/
5058 /* check if we should bail out here */
5060 if ( !NT_STATUS_IS_OK(status) )
5061 return status;
5063 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5065 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5066 return NT_STATUS_NO_MEMORY;
5068 /* they created it; let the user do what he wants with it */
5070 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5072 /* get a (unique) handle. open a policy on it. */
5073 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5074 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5076 force_flush_samr_cache(disp_info);
5078 return NT_STATUS_OK;
5081 /*********************************************************************
5082 _samr_CreateDomAlias
5083 *********************************************************************/
5085 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5086 struct samr_CreateDomAlias *r)
5088 DOM_SID dom_sid;
5089 DOM_SID info_sid;
5090 const char *name = NULL;
5091 struct samr_info *info;
5092 uint32 acc_granted;
5093 gid_t gid;
5094 NTSTATUS result;
5095 SE_PRIV se_rights;
5096 bool can_add_accounts;
5097 DISP_INFO *disp_info = NULL;
5099 /* Find the policy handle. Open a policy on it. */
5100 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5101 return NT_STATUS_INVALID_HANDLE;
5103 result = access_check_samr_function(acc_granted,
5104 SA_RIGHT_DOMAIN_CREATE_ALIAS,
5105 "_samr_CreateDomAlias");
5106 if (!NT_STATUS_IS_OK(result)) {
5107 return result;
5110 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5111 return NT_STATUS_ACCESS_DENIED;
5113 name = r->in.alias_name->string;
5115 se_priv_copy( &se_rights, &se_add_users );
5116 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5118 result = can_create(p->mem_ctx, name);
5119 if (!NT_STATUS_IS_OK(result)) {
5120 return result;
5123 /******** BEGIN SeAddUsers BLOCK *********/
5125 if ( can_add_accounts )
5126 become_root();
5128 /* Have passdb create the alias */
5129 result = pdb_create_alias(name, r->out.rid);
5131 if ( can_add_accounts )
5132 unbecome_root();
5134 /******** END SeAddUsers BLOCK *********/
5136 if (!NT_STATUS_IS_OK(result)) {
5137 DEBUG(10, ("pdb_create_alias failed: %s\n",
5138 nt_errstr(result)));
5139 return result;
5142 sid_copy(&info_sid, get_global_sam_sid());
5143 sid_append_rid(&info_sid, *r->out.rid);
5145 if (!sid_to_gid(&info_sid, &gid)) {
5146 DEBUG(10, ("Could not find alias just created\n"));
5147 return NT_STATUS_ACCESS_DENIED;
5150 /* check if the group has been successfully created */
5151 if ( getgrgid(gid) == NULL ) {
5152 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5153 gid));
5154 return NT_STATUS_ACCESS_DENIED;
5157 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5158 return NT_STATUS_NO_MEMORY;
5160 /* they created it; let the user do what he wants with it */
5162 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5164 /* get a (unique) handle. open a policy on it. */
5165 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5166 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5168 force_flush_samr_cache(disp_info);
5170 return NT_STATUS_OK;
5173 /*********************************************************************
5174 _samr_QueryGroupInfo
5175 *********************************************************************/
5177 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5178 struct samr_QueryGroupInfo *r)
5180 NTSTATUS status;
5181 DOM_SID group_sid;
5182 GROUP_MAP map;
5183 union samr_GroupInfo *info = NULL;
5184 uint32 acc_granted;
5185 bool ret;
5186 uint32_t attributes = SE_GROUP_MANDATORY |
5187 SE_GROUP_ENABLED_BY_DEFAULT |
5188 SE_GROUP_ENABLED;
5189 const char *group_name = NULL;
5190 const char *group_description = NULL;
5192 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5193 return NT_STATUS_INVALID_HANDLE;
5195 status = access_check_samr_function(acc_granted,
5196 SA_RIGHT_GROUP_LOOKUP_INFO,
5197 "_samr_QueryGroupInfo");
5198 if (!NT_STATUS_IS_OK(status)) {
5199 return status;
5202 become_root();
5203 ret = get_domain_group_from_sid(group_sid, &map);
5204 unbecome_root();
5205 if (!ret)
5206 return NT_STATUS_INVALID_HANDLE;
5208 /* FIXME: map contains fstrings */
5209 group_name = talloc_strdup(r, map.nt_name);
5210 group_description = talloc_strdup(r, map.comment);
5212 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5213 if (!info) {
5214 return NT_STATUS_NO_MEMORY;
5217 switch (r->in.level) {
5218 case 1: {
5219 uint32 *members;
5220 size_t num_members;
5222 become_root();
5223 status = pdb_enum_group_members(
5224 p->mem_ctx, &group_sid, &members, &num_members);
5225 unbecome_root();
5227 if (!NT_STATUS_IS_OK(status)) {
5228 return status;
5231 init_samr_group_info1(&info->all,
5232 group_name,
5233 attributes,
5234 num_members,
5235 group_description);
5236 break;
5238 case 2:
5239 init_samr_group_info2(&info->name,
5240 group_name);
5241 break;
5242 case 3:
5243 init_samr_group_info3(&info->attributes,
5244 attributes);
5245 break;
5246 case 4:
5247 init_samr_group_info4(&info->description,
5248 group_description);
5249 break;
5250 case 5: {
5252 uint32 *members;
5253 size_t num_members;
5257 become_root();
5258 status = pdb_enum_group_members(
5259 p->mem_ctx, &group_sid, &members, &num_members);
5260 unbecome_root();
5262 if (!NT_STATUS_IS_OK(status)) {
5263 return status;
5266 init_samr_group_info5(&info->all2,
5267 group_name,
5268 attributes,
5269 0, /* num_members - in w2k3 this is always 0 */
5270 group_description);
5272 break;
5274 default:
5275 return NT_STATUS_INVALID_INFO_CLASS;
5278 *r->out.info = info;
5280 return NT_STATUS_OK;
5283 /*********************************************************************
5284 _samr_SetGroupInfo
5285 *********************************************************************/
5287 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5288 struct samr_SetGroupInfo *r)
5290 DOM_SID group_sid;
5291 GROUP_MAP map;
5292 uint32 acc_granted;
5293 NTSTATUS status;
5294 bool ret;
5295 bool can_mod_accounts;
5296 DISP_INFO *disp_info = NULL;
5298 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5299 return NT_STATUS_INVALID_HANDLE;
5301 status = access_check_samr_function(acc_granted,
5302 SA_RIGHT_GROUP_SET_INFO,
5303 "_samr_SetGroupInfo");
5304 if (!NT_STATUS_IS_OK(status)) {
5305 return status;
5308 become_root();
5309 ret = get_domain_group_from_sid(group_sid, &map);
5310 unbecome_root();
5311 if (!ret)
5312 return NT_STATUS_NO_SUCH_GROUP;
5314 switch (r->in.level) {
5315 case 1:
5316 fstrcpy(map.comment, r->in.info->all.description.string);
5317 break;
5318 case 4:
5319 fstrcpy(map.comment, r->in.info->description.string);
5320 break;
5321 default:
5322 return NT_STATUS_INVALID_INFO_CLASS;
5325 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5327 /******** BEGIN SeAddUsers BLOCK *********/
5329 if ( can_mod_accounts )
5330 become_root();
5332 status = pdb_update_group_mapping_entry(&map);
5334 if ( can_mod_accounts )
5335 unbecome_root();
5337 /******** End SeAddUsers BLOCK *********/
5339 if (NT_STATUS_IS_OK(status)) {
5340 force_flush_samr_cache(disp_info);
5343 return status;
5346 /*********************************************************************
5347 _samr_SetAliasInfo
5348 *********************************************************************/
5350 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5351 struct samr_SetAliasInfo *r)
5353 DOM_SID group_sid;
5354 struct acct_info info;
5355 uint32 acc_granted;
5356 bool can_mod_accounts;
5357 NTSTATUS status;
5358 DISP_INFO *disp_info = NULL;
5360 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5361 return NT_STATUS_INVALID_HANDLE;
5363 status = access_check_samr_function(acc_granted,
5364 SA_RIGHT_ALIAS_SET_INFO,
5365 "_samr_SetAliasInfo");
5366 if (!NT_STATUS_IS_OK(status)) {
5367 return status;
5370 /* get the current group information */
5372 become_root();
5373 status = pdb_get_aliasinfo( &group_sid, &info );
5374 unbecome_root();
5376 if ( !NT_STATUS_IS_OK(status))
5377 return status;
5379 switch (r->in.level) {
5380 case ALIASINFONAME:
5382 fstring group_name;
5384 /* We currently do not support renaming groups in the
5385 the BUILTIN domain. Refer to util_builtin.c to understand
5386 why. The eventually needs to be fixed to be like Windows
5387 where you can rename builtin groups, just not delete them */
5389 if ( sid_check_is_in_builtin( &group_sid ) ) {
5390 return NT_STATUS_SPECIAL_ACCOUNT;
5393 /* There has to be a valid name (and it has to be different) */
5395 if ( !r->in.info->name.string )
5396 return NT_STATUS_INVALID_PARAMETER;
5398 /* If the name is the same just reply "ok". Yes this
5399 doesn't allow you to change the case of a group name. */
5401 if ( strequal( r->in.info->name.string, info.acct_name ) )
5402 return NT_STATUS_OK;
5404 fstrcpy( info.acct_name, r->in.info->name.string);
5406 /* make sure the name doesn't already exist as a user
5407 or local group */
5409 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5410 status = can_create( p->mem_ctx, group_name );
5411 if ( !NT_STATUS_IS_OK( status ) )
5412 return status;
5413 break;
5415 case ALIASINFODESCRIPTION:
5416 if (r->in.info->description.string) {
5417 fstrcpy(info.acct_desc,
5418 r->in.info->description.string);
5419 } else {
5420 fstrcpy( info.acct_desc, "" );
5422 break;
5423 default:
5424 return NT_STATUS_INVALID_INFO_CLASS;
5427 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5429 /******** BEGIN SeAddUsers BLOCK *********/
5431 if ( can_mod_accounts )
5432 become_root();
5434 status = pdb_set_aliasinfo( &group_sid, &info );
5436 if ( can_mod_accounts )
5437 unbecome_root();
5439 /******** End SeAddUsers BLOCK *********/
5441 if (NT_STATUS_IS_OK(status))
5442 force_flush_samr_cache(disp_info);
5444 return status;
5447 /****************************************************************
5448 _samr_GetDomPwInfo
5449 ****************************************************************/
5451 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5452 struct samr_GetDomPwInfo *r)
5454 uint32_t min_password_length = 0;
5455 uint32_t password_properties = 0;
5457 /* Perform access check. Since this rpc does not require a
5458 policy handle it will not be caught by the access checks on
5459 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5461 if (!pipe_access_check(p)) {
5462 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5463 return NT_STATUS_ACCESS_DENIED;
5466 become_root();
5467 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5468 &min_password_length);
5469 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5470 &password_properties);
5471 unbecome_root();
5473 if (lp_check_password_script() && *lp_check_password_script()) {
5474 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5477 r->out.info->min_password_length = min_password_length;
5478 r->out.info->password_properties = password_properties;
5480 return NT_STATUS_OK;
5483 /*********************************************************************
5484 _samr_OpenGroup
5485 *********************************************************************/
5487 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5488 struct samr_OpenGroup *r)
5491 DOM_SID sid;
5492 DOM_SID info_sid;
5493 GROUP_MAP map;
5494 struct samr_info *info;
5495 SEC_DESC *psd = NULL;
5496 uint32 acc_granted;
5497 uint32 des_access = r->in.access_mask;
5498 size_t sd_size;
5499 NTSTATUS status;
5500 fstring sid_string;
5501 bool ret;
5502 SE_PRIV se_rights;
5504 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5505 return NT_STATUS_INVALID_HANDLE;
5507 status = access_check_samr_function(acc_granted,
5508 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5509 "_samr_OpenGroup");
5511 if ( !NT_STATUS_IS_OK(status) )
5512 return status;
5514 /*check if access can be granted as requested by client. */
5515 map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
5517 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5518 se_map_generic(&des_access,&grp_generic_mapping);
5520 se_priv_copy( &se_rights, &se_add_users );
5522 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5523 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5524 &acc_granted, "_samr_OpenGroup");
5526 if ( !NT_STATUS_IS_OK(status) )
5527 return status;
5529 /* this should not be hard-coded like this */
5531 if (!sid_equal(&sid, get_global_sam_sid()))
5532 return NT_STATUS_ACCESS_DENIED;
5534 sid_copy(&info_sid, get_global_sam_sid());
5535 sid_append_rid(&info_sid, r->in.rid);
5536 sid_to_fstring(sid_string, &info_sid);
5538 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5539 return NT_STATUS_NO_MEMORY;
5541 info->acc_granted = acc_granted;
5543 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5545 /* check if that group really exists */
5546 become_root();
5547 ret = get_domain_group_from_sid(info->sid, &map);
5548 unbecome_root();
5549 if (!ret)
5550 return NT_STATUS_NO_SUCH_GROUP;
5552 /* get a (unique) handle. open a policy on it. */
5553 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5554 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5556 return NT_STATUS_OK;
5559 /*********************************************************************
5560 _samr_RemoveMemberFromForeignDomain
5561 *********************************************************************/
5563 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5564 struct samr_RemoveMemberFromForeignDomain *r)
5566 DOM_SID delete_sid, domain_sid;
5567 uint32 acc_granted;
5568 NTSTATUS result;
5569 DISP_INFO *disp_info = NULL;
5571 sid_copy( &delete_sid, r->in.sid );
5573 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5574 sid_string_dbg(&delete_sid)));
5576 /* Find the policy handle. Open a policy on it. */
5578 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5579 &acc_granted, &disp_info))
5580 return NT_STATUS_INVALID_HANDLE;
5582 result = access_check_samr_function(acc_granted,
5583 STD_RIGHT_DELETE_ACCESS,
5584 "_samr_RemoveMemberFromForeignDomain");
5586 if (!NT_STATUS_IS_OK(result))
5587 return result;
5589 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5590 sid_string_dbg(&domain_sid)));
5592 /* we can only delete a user from a group since we don't have
5593 nested groups anyways. So in the latter case, just say OK */
5595 /* TODO: The above comment nowadays is bogus. Since we have nested
5596 * groups now, and aliases members are never reported out of the unix
5597 * group membership, the "just say OK" makes this call a no-op. For
5598 * us. This needs fixing however. */
5600 /* I've only ever seen this in the wild when deleting a user from
5601 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5602 * is the user about to be deleted. I very much suspect this is the
5603 * only application of this call. To verify this, let people report
5604 * other cases. */
5606 if (!sid_check_is_builtin(&domain_sid)) {
5607 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5608 "global_sam_sid() = %s\n",
5609 sid_string_dbg(&domain_sid),
5610 sid_string_dbg(get_global_sam_sid())));
5611 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5612 return NT_STATUS_OK;
5615 force_flush_samr_cache(disp_info);
5617 result = NT_STATUS_OK;
5619 return result;
5622 /*******************************************************************
5623 _samr_QueryDomainInfo2
5624 ********************************************************************/
5626 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5627 struct samr_QueryDomainInfo2 *r)
5629 struct samr_QueryDomainInfo q;
5631 q.in.domain_handle = r->in.domain_handle;
5632 q.in.level = r->in.level;
5634 q.out.info = r->out.info;
5636 return _samr_QueryDomainInfo(p, &q);
5639 /*******************************************************************
5640 _samr_SetDomainInfo
5641 ********************************************************************/
5643 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5644 struct samr_SetDomainInfo *r)
5646 struct samr_info *info = NULL;
5647 time_t u_expire, u_min_age;
5648 time_t u_logout;
5649 time_t u_lock_duration, u_reset_time;
5651 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5653 /* find the policy handle. open a policy on it. */
5654 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5655 return NT_STATUS_INVALID_HANDLE;
5657 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5659 switch (r->in.level) {
5660 case 0x01:
5661 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5662 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5663 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5664 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5665 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5666 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5667 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5668 break;
5669 case 0x02:
5670 break;
5671 case 0x03:
5672 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5673 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5674 break;
5675 case 0x05:
5676 break;
5677 case 0x06:
5678 break;
5679 case 0x07:
5680 break;
5681 case 0x0c:
5682 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5683 if (u_lock_duration != -1)
5684 u_lock_duration /= 60;
5686 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5688 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5689 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5690 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5691 break;
5692 default:
5693 return NT_STATUS_INVALID_INFO_CLASS;
5696 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5698 return NT_STATUS_OK;
5701 /****************************************************************
5702 _samr_GetDisplayEnumerationIndex
5703 ****************************************************************/
5705 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5706 struct samr_GetDisplayEnumerationIndex *r)
5708 struct samr_info *info = NULL;
5709 uint32_t max_entries = (uint32_t) -1;
5710 uint32_t enum_context = 0;
5711 int i;
5712 uint32_t num_account = 0;
5713 struct samr_displayentry *entries = NULL;
5715 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5717 /* find the policy handle. open a policy on it. */
5718 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5719 return NT_STATUS_INVALID_HANDLE;
5722 if ((r->in.level < 1) || (r->in.level > 3)) {
5723 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5724 "Unknown info level (%u)\n",
5725 r->in.level));
5726 return NT_STATUS_INVALID_INFO_CLASS;
5729 become_root();
5731 /* The following done as ROOT. Don't return without unbecome_root(). */
5733 switch (r->in.level) {
5734 case 1:
5735 if (info->disp_info->users == NULL) {
5736 info->disp_info->users = pdb_search_users(ACB_NORMAL);
5737 if (info->disp_info->users == NULL) {
5738 unbecome_root();
5739 return NT_STATUS_ACCESS_DENIED;
5741 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5742 "starting user enumeration at index %u\n",
5743 (unsigned int)enum_context));
5744 } else {
5745 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5746 "using cached user enumeration at index %u\n",
5747 (unsigned int)enum_context));
5749 num_account = pdb_search_entries(info->disp_info->users,
5750 enum_context, max_entries,
5751 &entries);
5752 break;
5753 case 2:
5754 if (info->disp_info->machines == NULL) {
5755 info->disp_info->machines =
5756 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5757 if (info->disp_info->machines == NULL) {
5758 unbecome_root();
5759 return NT_STATUS_ACCESS_DENIED;
5761 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5762 "starting machine enumeration at index %u\n",
5763 (unsigned int)enum_context));
5764 } else {
5765 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5766 "using cached machine enumeration at index %u\n",
5767 (unsigned int)enum_context));
5769 num_account = pdb_search_entries(info->disp_info->machines,
5770 enum_context, max_entries,
5771 &entries);
5772 break;
5773 case 3:
5774 if (info->disp_info->groups == NULL) {
5775 info->disp_info->groups = pdb_search_groups();
5776 if (info->disp_info->groups == NULL) {
5777 unbecome_root();
5778 return NT_STATUS_ACCESS_DENIED;
5780 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5781 "starting group enumeration at index %u\n",
5782 (unsigned int)enum_context));
5783 } else {
5784 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5785 "using cached group enumeration at index %u\n",
5786 (unsigned int)enum_context));
5788 num_account = pdb_search_entries(info->disp_info->groups,
5789 enum_context, max_entries,
5790 &entries);
5791 break;
5792 default:
5793 unbecome_root();
5794 smb_panic("info class changed");
5795 break;
5798 unbecome_root();
5800 /* Ensure we cache this enumeration. */
5801 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5803 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5804 r->in.name->string));
5806 for (i=0; i<num_account; i++) {
5807 if (strequal(entries[i].account_name, r->in.name->string)) {
5808 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5809 "found %s at idx %d\n",
5810 r->in.name->string, i));
5811 *r->out.idx = i;
5812 return NT_STATUS_OK;
5816 /* assuming account_name lives at the very end */
5817 *r->out.idx = num_account;
5819 return NT_STATUS_NO_MORE_ENTRIES;
5822 /****************************************************************
5823 _samr_GetDisplayEnumerationIndex2
5824 ****************************************************************/
5826 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5827 struct samr_GetDisplayEnumerationIndex2 *r)
5829 struct samr_GetDisplayEnumerationIndex q;
5831 q.in.domain_handle = r->in.domain_handle;
5832 q.in.level = r->in.level;
5833 q.in.name = r->in.name;
5835 q.out.idx = r->out.idx;
5837 return _samr_GetDisplayEnumerationIndex(p, &q);
5840 /****************************************************************
5841 ****************************************************************/
5843 NTSTATUS _samr_Shutdown(pipes_struct *p,
5844 struct samr_Shutdown *r)
5846 p->rng_fault_state = true;
5847 return NT_STATUS_NOT_IMPLEMENTED;
5850 /****************************************************************
5851 ****************************************************************/
5853 NTSTATUS _samr_CreateUser(pipes_struct *p,
5854 struct samr_CreateUser *r)
5856 p->rng_fault_state = true;
5857 return NT_STATUS_NOT_IMPLEMENTED;
5860 /****************************************************************
5861 ****************************************************************/
5863 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5864 struct samr_SetMemberAttributesOfGroup *r)
5866 p->rng_fault_state = true;
5867 return NT_STATUS_NOT_IMPLEMENTED;
5870 /****************************************************************
5871 ****************************************************************/
5873 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5874 struct samr_ChangePasswordUser *r)
5876 p->rng_fault_state = true;
5877 return NT_STATUS_NOT_IMPLEMENTED;
5880 /****************************************************************
5881 ****************************************************************/
5883 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5884 struct samr_TestPrivateFunctionsDomain *r)
5886 p->rng_fault_state = true;
5887 return NT_STATUS_NOT_IMPLEMENTED;
5890 /****************************************************************
5891 ****************************************************************/
5893 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5894 struct samr_TestPrivateFunctionsUser *r)
5896 p->rng_fault_state = true;
5897 return NT_STATUS_NOT_IMPLEMENTED;
5900 /****************************************************************
5901 ****************************************************************/
5903 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5904 struct samr_QueryUserInfo2 *r)
5906 p->rng_fault_state = true;
5907 return NT_STATUS_NOT_IMPLEMENTED;
5910 /****************************************************************
5911 ****************************************************************/
5913 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5914 struct samr_AddMultipleMembersToAlias *r)
5916 p->rng_fault_state = true;
5917 return NT_STATUS_NOT_IMPLEMENTED;
5920 /****************************************************************
5921 ****************************************************************/
5923 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5924 struct samr_RemoveMultipleMembersFromAlias *r)
5926 p->rng_fault_state = true;
5927 return NT_STATUS_NOT_IMPLEMENTED;
5930 /****************************************************************
5931 ****************************************************************/
5933 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5934 struct samr_OemChangePasswordUser2 *r)
5936 p->rng_fault_state = true;
5937 return NT_STATUS_NOT_IMPLEMENTED;
5940 /****************************************************************
5941 ****************************************************************/
5943 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5944 struct samr_SetBootKeyInformation *r)
5946 p->rng_fault_state = true;
5947 return NT_STATUS_NOT_IMPLEMENTED;
5950 /****************************************************************
5951 ****************************************************************/
5953 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5954 struct samr_GetBootKeyInformation *r)
5956 p->rng_fault_state = true;
5957 return NT_STATUS_NOT_IMPLEMENTED;
5960 /****************************************************************
5961 ****************************************************************/
5963 NTSTATUS _samr_Connect3(pipes_struct *p,
5964 struct samr_Connect3 *r)
5966 p->rng_fault_state = true;
5967 return NT_STATUS_NOT_IMPLEMENTED;
5970 /****************************************************************
5971 ****************************************************************/
5973 NTSTATUS _samr_RidToSid(pipes_struct *p,
5974 struct samr_RidToSid *r)
5976 p->rng_fault_state = true;
5977 return NT_STATUS_NOT_IMPLEMENTED;
5980 /****************************************************************
5981 ****************************************************************/
5983 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5984 struct samr_SetDsrmPassword *r)
5986 p->rng_fault_state = true;
5987 return NT_STATUS_NOT_IMPLEMENTED;
5990 /****************************************************************
5991 ****************************************************************/
5993 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5994 struct samr_ValidatePassword *r)
5996 p->rng_fault_state = true;
5997 return NT_STATUS_NOT_IMPLEMENTED;