s3-samr: Let _samr_TestPrivateFunctionsDomain() return NT_STATUS_NOT_SUPPORTED to...
[Samba/gbeck.git] / source3 / rpc_server / srv_samr_nt.c
blobc22cd1c8af7d7bae4690b58dcbfc3ca4edf6628f
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
34 #include "includes.h"
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
42 SAMR_USER_ACCESS_SET_LOC_COM)
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
49 #define MAX_SAM_ENTRIES_W95 50
51 typedef struct disp_info {
52 DOM_SID sid; /* identify which domain this is. */
53 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
54 struct pdb_search *users; /* querydispinfo 1 and 4 */
55 struct pdb_search *machines; /* querydispinfo 2 */
56 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
57 struct pdb_search *aliases; /* enumaliases */
59 uint16 enum_acb_mask;
60 struct pdb_search *enum_users; /* enumusers with a mask */
62 struct timed_event *cache_timeout_event; /* cache idle timeout
63 * handler. */
64 } DISP_INFO;
66 /* We keep a static list of these by SID as modern clients close down
67 all resources between each request in a complete enumeration. */
69 struct samr_info {
70 /* for use by the \PIPE\samr policy */
71 DOM_SID sid;
72 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
73 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
74 uint32 acc_granted;
75 DISP_INFO *disp_info;
78 static const struct generic_mapping sam_generic_mapping = {
79 GENERIC_RIGHTS_SAM_READ,
80 GENERIC_RIGHTS_SAM_WRITE,
81 GENERIC_RIGHTS_SAM_EXECUTE,
82 GENERIC_RIGHTS_SAM_ALL_ACCESS};
83 static const struct generic_mapping dom_generic_mapping = {
84 GENERIC_RIGHTS_DOMAIN_READ,
85 GENERIC_RIGHTS_DOMAIN_WRITE,
86 GENERIC_RIGHTS_DOMAIN_EXECUTE,
87 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
88 static const struct generic_mapping usr_generic_mapping = {
89 GENERIC_RIGHTS_USER_READ,
90 GENERIC_RIGHTS_USER_WRITE,
91 GENERIC_RIGHTS_USER_EXECUTE,
92 GENERIC_RIGHTS_USER_ALL_ACCESS};
93 static const struct generic_mapping usr_nopwchange_generic_mapping = {
94 GENERIC_RIGHTS_USER_READ,
95 GENERIC_RIGHTS_USER_WRITE,
96 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
97 GENERIC_RIGHTS_USER_ALL_ACCESS};
98 static const struct generic_mapping grp_generic_mapping = {
99 GENERIC_RIGHTS_GROUP_READ,
100 GENERIC_RIGHTS_GROUP_WRITE,
101 GENERIC_RIGHTS_GROUP_EXECUTE,
102 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
103 static const struct generic_mapping ali_generic_mapping = {
104 GENERIC_RIGHTS_ALIAS_READ,
105 GENERIC_RIGHTS_ALIAS_WRITE,
106 GENERIC_RIGHTS_ALIAS_EXECUTE,
107 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
109 /*******************************************************************
110 *******************************************************************/
112 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
113 const struct generic_mapping *map,
114 DOM_SID *sid, uint32 sid_access )
116 DOM_SID domadmin_sid;
117 SEC_ACE ace[5]; /* at most 5 entries */
118 size_t i = 0;
120 SEC_ACL *psa = NULL;
122 /* basic access for Everyone */
124 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
125 map->generic_execute | map->generic_read, 0);
127 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
129 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
130 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
131 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
132 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
134 /* Add Full Access for Domain Admins if we are a DC */
136 if ( IS_DC ) {
137 sid_copy( &domadmin_sid, get_global_sam_sid() );
138 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
139 init_sec_ace(&ace[i++], &domadmin_sid,
140 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
143 /* if we have a sid, give it some special access */
145 if ( sid ) {
146 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
149 /* create the security descriptor */
151 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
152 return NT_STATUS_NO_MEMORY;
154 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
155 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
156 psa, sd_size)) == NULL)
157 return NT_STATUS_NO_MEMORY;
159 return NT_STATUS_OK;
162 /*******************************************************************
163 Checks if access to an object should be granted, and returns that
164 level of access for further checks.
165 ********************************************************************/
167 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
168 SE_PRIV *rights, uint32 rights_mask,
169 uint32 des_access, uint32 *acc_granted,
170 const char *debug )
172 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
173 uint32 saved_mask = 0;
175 /* check privileges; certain SAM access bits should be overridden
176 by privileges (mostly having to do with creating/modifying/deleting
177 users and groups) */
179 if ( rights && user_has_any_privilege( token, rights ) ) {
181 saved_mask = (des_access & rights_mask);
182 des_access &= ~saved_mask;
184 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
185 rights_mask));
189 /* check the security descriptor first */
191 status = se_access_check(psd, token, des_access, acc_granted);
192 if (NT_STATUS_IS_OK(status)) {
193 goto done;
196 /* give root a free pass */
198 if ( geteuid() == sec_initial_uid() ) {
200 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
201 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
203 *acc_granted = des_access;
205 status = NT_STATUS_OK;
206 goto done;
210 done:
211 /* add in any bits saved during the privilege check (only
212 matters is status is ok) */
214 *acc_granted |= rights_mask;
216 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
217 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
218 des_access, *acc_granted));
220 return status;
223 /*******************************************************************
224 Checks if access to a function can be granted
225 ********************************************************************/
227 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
229 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
230 debug, acc_granted, acc_required));
232 /* check the security descriptor first */
234 if ( (acc_granted&acc_required) == acc_required )
235 return NT_STATUS_OK;
237 /* give root a free pass */
239 if (geteuid() == sec_initial_uid()) {
241 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
242 debug, acc_granted, acc_required));
243 DEBUGADD(4,("but overwritten by euid == 0\n"));
245 return NT_STATUS_OK;
248 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
249 debug, acc_granted, acc_required));
251 return NT_STATUS_ACCESS_DENIED;
254 /*******************************************************************
255 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
256 ********************************************************************/
258 static void map_max_allowed_access(const NT_USER_TOKEN *token,
259 uint32_t *pacc_requested)
261 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
262 return;
264 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
266 /* At least try for generic read. */
267 *pacc_requested = GENERIC_READ_ACCESS;
269 /* root gets anything. */
270 if (geteuid() == sec_initial_uid()) {
271 *pacc_requested |= GENERIC_ALL_ACCESS;
272 return;
275 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
277 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
278 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
279 *pacc_requested |= GENERIC_ALL_ACCESS;
280 return;
283 /* Full access for DOMAIN\Domain Admins. */
284 if ( IS_DC ) {
285 DOM_SID domadmin_sid;
286 sid_copy( &domadmin_sid, get_global_sam_sid() );
287 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
288 if (is_sid_in_token(token, &domadmin_sid)) {
289 *pacc_requested |= GENERIC_ALL_ACCESS;
290 return;
293 /* TODO ! Check privileges. */
296 /*******************************************************************
297 Fetch or create a dispinfo struct.
298 ********************************************************************/
300 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
303 * We do a static cache for DISP_INFO's here. Explanation can be found
304 * in Jeremy's checkin message to r11793:
306 * Fix the SAMR cache so it works across completely insane
307 * client behaviour (ie.:
308 * open pipe/open SAMR handle/enumerate 0 - 1024
309 * close SAMR handle, close pipe.
310 * open pipe/open SAMR handle/enumerate 1024 - 2048...
311 * close SAMR handle, close pipe.
312 * And on ad-nausium. Amazing.... probably object-oriented
313 * client side programming in action yet again.
314 * This change should *massively* improve performance when
315 * enumerating users from an LDAP database.
316 * Jeremy.
318 * "Our" and the builtin domain are the only ones where we ever
319 * enumerate stuff, so just cache 2 entries.
322 static struct disp_info *builtin_dispinfo;
323 static struct disp_info *domain_dispinfo;
325 /* There are two cases to consider here:
326 1) The SID is a domain SID and we look for an equality match, or
327 2) This is an account SID and so we return the DISP_INFO* for our
328 domain */
330 if (psid == NULL) {
331 return NULL;
334 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
336 * Necessary only once, but it does not really hurt.
338 if (builtin_dispinfo == NULL) {
339 builtin_dispinfo = talloc_zero(
340 talloc_autofree_context(), struct disp_info);
341 if (builtin_dispinfo == NULL) {
342 return NULL;
345 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
346 builtin_dispinfo->builtin_domain = true;
348 return builtin_dispinfo;
351 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
353 * Necessary only once, but it does not really hurt.
355 if (domain_dispinfo == NULL) {
356 domain_dispinfo = talloc_zero(
357 talloc_autofree_context(), struct disp_info);
358 if (domain_dispinfo == NULL) {
359 return NULL;
362 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
363 domain_dispinfo->builtin_domain = false;
365 return domain_dispinfo;
368 return NULL;
371 /*******************************************************************
372 Create a samr_info struct.
373 ********************************************************************/
375 static int samr_info_destructor(struct samr_info *info);
377 static struct samr_info *get_samr_info_by_sid(TALLOC_CTX *mem_ctx,
378 DOM_SID *psid)
380 struct samr_info *info;
381 fstring sid_str;
383 if (psid) {
384 sid_to_fstring(sid_str, psid);
385 } else {
386 fstrcpy(sid_str,"(NULL)");
389 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL) {
390 return NULL;
392 talloc_set_destructor(info, samr_info_destructor);
394 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
395 if (psid) {
396 sid_copy( &info->sid, psid);
397 info->builtin_domain = sid_check_is_builtin(psid);
398 } else {
399 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
400 info->builtin_domain = False;
403 info->disp_info = get_samr_dispinfo_by_sid(psid);
405 return info;
408 /*******************************************************************
409 Function to free the per SID data.
410 ********************************************************************/
412 static void free_samr_cache(DISP_INFO *disp_info)
414 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
415 sid_string_dbg(&disp_info->sid)));
417 /* We need to become root here because the paged search might have to
418 * tell the LDAP server we're not interested in the rest anymore. */
420 become_root();
422 TALLOC_FREE(disp_info->users);
423 TALLOC_FREE(disp_info->machines);
424 TALLOC_FREE(disp_info->groups);
425 TALLOC_FREE(disp_info->aliases);
426 TALLOC_FREE(disp_info->enum_users);
428 unbecome_root();
431 static int samr_info_destructor(struct samr_info *info)
433 /* Only free the dispinfo cache if no one bothered to set up
434 a timeout. */
436 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
437 free_samr_cache(info->disp_info);
439 return 0;
442 /*******************************************************************
443 Idle event handler. Throw away the disp info cache.
444 ********************************************************************/
446 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
447 struct timed_event *te,
448 struct timeval now,
449 void *private_data)
451 DISP_INFO *disp_info = (DISP_INFO *)private_data;
453 TALLOC_FREE(disp_info->cache_timeout_event);
455 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
456 "out\n"));
457 free_samr_cache(disp_info);
460 /*******************************************************************
461 Setup cache removal idle event handler.
462 ********************************************************************/
464 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
466 /* Remove any pending timeout and update. */
468 TALLOC_FREE(disp_info->cache_timeout_event);
470 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
471 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
472 (unsigned int)secs_fromnow ));
474 disp_info->cache_timeout_event = event_add_timed(
475 smbd_event_context(), NULL,
476 timeval_current_ofs(secs_fromnow, 0),
477 disp_info_cache_idle_timeout_handler, (void *)disp_info);
480 /*******************************************************************
481 Force flush any cache. We do this on any samr_set_xxx call.
482 We must also remove the timeout handler.
483 ********************************************************************/
485 static void force_flush_samr_cache(DISP_INFO *disp_info)
487 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
488 return;
491 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
492 TALLOC_FREE(disp_info->cache_timeout_event);
493 free_samr_cache(disp_info);
496 /*******************************************************************
497 Ensure password info is never given out. Paranioa... JRA.
498 ********************************************************************/
500 static void samr_clear_sam_passwd(struct samu *sam_pass)
503 if (!sam_pass)
504 return;
506 /* These now zero out the old password */
508 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
509 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
512 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
514 struct samr_displayentry *entry;
516 if (info->builtin_domain) {
517 /* No users in builtin. */
518 return 0;
521 if (info->users == NULL) {
522 info->users = pdb_search_users(info, acct_flags);
523 if (info->users == NULL) {
524 return 0;
527 /* Fetch the last possible entry, thus trigger an enumeration */
528 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
530 /* Ensure we cache this enumeration. */
531 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
533 return info->users->num_entries;
536 static uint32 count_sam_groups(struct disp_info *info)
538 struct samr_displayentry *entry;
540 if (info->builtin_domain) {
541 /* No groups in builtin. */
542 return 0;
545 if (info->groups == NULL) {
546 info->groups = pdb_search_groups(info);
547 if (info->groups == NULL) {
548 return 0;
551 /* Fetch the last possible entry, thus trigger an enumeration */
552 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
554 /* Ensure we cache this enumeration. */
555 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
557 return info->groups->num_entries;
560 static uint32 count_sam_aliases(struct disp_info *info)
562 struct samr_displayentry *entry;
564 if (info->aliases == NULL) {
565 info->aliases = pdb_search_aliases(info, &info->sid);
566 if (info->aliases == NULL) {
567 return 0;
570 /* Fetch the last possible entry, thus trigger an enumeration */
571 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
573 /* Ensure we cache this enumeration. */
574 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
576 return info->aliases->num_entries;
579 /*******************************************************************
580 _samr_Close
581 ********************************************************************/
583 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
585 if (!close_policy_hnd(p, r->in.handle)) {
586 return NT_STATUS_INVALID_HANDLE;
589 ZERO_STRUCTP(r->out.handle);
591 return NT_STATUS_OK;
594 /*******************************************************************
595 _samr_OpenDomain
596 ********************************************************************/
598 NTSTATUS _samr_OpenDomain(pipes_struct *p,
599 struct samr_OpenDomain *r)
601 struct samr_info *info;
602 SEC_DESC *psd = NULL;
603 uint32 acc_granted;
604 uint32 des_access = r->in.access_mask;
605 NTSTATUS status;
606 size_t sd_size;
607 SE_PRIV se_rights;
609 /* find the connection policy handle. */
611 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
612 return NT_STATUS_INVALID_HANDLE;
614 /*check if access can be granted as requested by client. */
615 map_max_allowed_access(p->server_info->ptok, &des_access);
617 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
618 se_map_generic( &des_access, &dom_generic_mapping );
620 se_priv_copy( &se_rights, &se_machine_account );
621 se_priv_add( &se_rights, &se_add_users );
623 status = access_check_samr_object( psd, p->server_info->ptok,
624 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
625 &acc_granted, "_samr_OpenDomain" );
627 if ( !NT_STATUS_IS_OK(status) )
628 return status;
630 if (!sid_check_is_domain(r->in.sid) &&
631 !sid_check_is_builtin(r->in.sid)) {
632 return NT_STATUS_NO_SUCH_DOMAIN;
635 /* associate the domain SID with the (unique) handle. */
636 if ((info = get_samr_info_by_sid(p->mem_ctx, r->in.sid))==NULL)
637 return NT_STATUS_NO_MEMORY;
638 info->acc_granted = acc_granted;
640 /* get a (unique) handle. open a policy on it. */
641 if (!create_policy_hnd(p, r->out.domain_handle, info))
642 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
644 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
646 return NT_STATUS_OK;
649 /*******************************************************************
650 _samr_GetUserPwInfo
651 ********************************************************************/
653 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
654 struct samr_GetUserPwInfo *r)
656 struct samr_info *info = NULL;
657 enum lsa_SidType sid_type;
658 uint32_t min_password_length = 0;
659 uint32_t password_properties = 0;
660 bool ret = false;
661 NTSTATUS status;
663 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
665 /* find the policy handle. open a policy on it. */
666 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
667 return NT_STATUS_INVALID_HANDLE;
670 status = access_check_samr_function(info->acc_granted,
671 SAMR_USER_ACCESS_GET_ATTRIBUTES,
672 "_samr_GetUserPwInfo" );
673 if (!NT_STATUS_IS_OK(status)) {
674 return status;
677 if (!sid_check_is_in_our_domain(&info->sid)) {
678 return NT_STATUS_OBJECT_TYPE_MISMATCH;
681 become_root();
682 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
683 unbecome_root();
684 if (ret == false) {
685 return NT_STATUS_NO_SUCH_USER;
688 switch (sid_type) {
689 case SID_NAME_USER:
690 become_root();
691 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
692 &min_password_length);
693 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
694 &password_properties);
695 unbecome_root();
697 if (lp_check_password_script() && *lp_check_password_script()) {
698 password_properties |= DOMAIN_PASSWORD_COMPLEX;
701 break;
702 default:
703 break;
706 r->out.info->min_password_length = min_password_length;
707 r->out.info->password_properties = password_properties;
709 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
711 return NT_STATUS_OK;
714 /*******************************************************************
715 ********************************************************************/
717 static bool get_lsa_policy_samr_sid( pipes_struct *p, struct policy_handle *pol,
718 DOM_SID *sid, uint32 *acc_granted,
719 DISP_INFO **ppdisp_info)
721 struct samr_info *info = NULL;
723 /* find the policy handle. open a policy on it. */
724 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
725 return False;
727 if (!info)
728 return False;
730 *sid = info->sid;
731 *acc_granted = info->acc_granted;
732 if (ppdisp_info) {
733 *ppdisp_info = info->disp_info;
736 return True;
739 /*******************************************************************
740 _samr_SetSecurity
741 ********************************************************************/
743 NTSTATUS _samr_SetSecurity(pipes_struct *p,
744 struct samr_SetSecurity *r)
746 DOM_SID pol_sid;
747 uint32 acc_granted, i;
748 SEC_ACL *dacl;
749 bool ret;
750 struct samu *sampass=NULL;
751 NTSTATUS status;
753 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
754 return NT_STATUS_INVALID_HANDLE;
756 if (!(sampass = samu_new( p->mem_ctx))) {
757 DEBUG(0,("No memory!\n"));
758 return NT_STATUS_NO_MEMORY;
761 /* get the user record */
762 become_root();
763 ret = pdb_getsampwsid(sampass, &pol_sid);
764 unbecome_root();
766 if (!ret) {
767 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
768 TALLOC_FREE(sampass);
769 return NT_STATUS_INVALID_HANDLE;
772 dacl = r->in.sdbuf->sd->dacl;
773 for (i=0; i < dacl->num_aces; i++) {
774 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
775 ret = pdb_set_pass_can_change(sampass,
776 (dacl->aces[i].access_mask &
777 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
778 True: False);
779 break;
783 if (!ret) {
784 TALLOC_FREE(sampass);
785 return NT_STATUS_ACCESS_DENIED;
788 status = access_check_samr_function(acc_granted,
789 SAMR_USER_ACCESS_SET_ATTRIBUTES,
790 "_samr_SetSecurity");
791 if (NT_STATUS_IS_OK(status)) {
792 become_root();
793 status = pdb_update_sam_account(sampass);
794 unbecome_root();
797 TALLOC_FREE(sampass);
799 return status;
802 /*******************************************************************
803 build correct perms based on policies and password times for _samr_query_sec_obj
804 *******************************************************************/
805 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
807 struct samu *sampass=NULL;
808 bool ret;
810 if ( !(sampass = samu_new( mem_ctx )) ) {
811 DEBUG(0,("No memory!\n"));
812 return False;
815 become_root();
816 ret = pdb_getsampwsid(sampass, user_sid);
817 unbecome_root();
819 if (ret == False) {
820 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
821 TALLOC_FREE(sampass);
822 return False;
825 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
827 if (pdb_get_pass_can_change(sampass)) {
828 TALLOC_FREE(sampass);
829 return True;
831 TALLOC_FREE(sampass);
832 return False;
836 /*******************************************************************
837 _samr_QuerySecurity
838 ********************************************************************/
840 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
841 struct samr_QuerySecurity *r)
843 NTSTATUS status;
844 DOM_SID pol_sid;
845 SEC_DESC * psd = NULL;
846 uint32 acc_granted;
847 size_t sd_size;
849 /* Get the SID. */
850 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
851 return NT_STATUS_INVALID_HANDLE;
853 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
854 sid_string_dbg(&pol_sid)));
856 status = access_check_samr_function(acc_granted,
857 STD_RIGHT_READ_CONTROL_ACCESS,
858 "_samr_QuerySecurity");
859 if (!NT_STATUS_IS_OK(status)) {
860 return status;
863 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
865 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
866 if (pol_sid.sid_rev_num == 0) {
867 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
868 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
869 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
870 /* check if it is our domain SID */
871 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
872 "with SID: %s\n", sid_string_dbg(&pol_sid)));
873 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
874 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
875 /* check if it is the Builtin Domain */
876 /* TODO: Builtin probably needs a different SD with restricted write access*/
877 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
878 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
879 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
880 } else if (sid_check_is_in_our_domain(&pol_sid) ||
881 sid_check_is_in_builtin(&pol_sid)) {
882 /* TODO: different SDs have to be generated for aliases groups and users.
883 Currently all three get a default user SD */
884 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
885 "with SID: %s\n", sid_string_dbg(&pol_sid)));
886 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
887 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
888 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
889 } else {
890 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
891 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
893 } else {
894 return NT_STATUS_OBJECT_TYPE_MISMATCH;
897 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
898 return NT_STATUS_NO_MEMORY;
900 return status;
903 /*******************************************************************
904 makes a SAM_ENTRY / UNISTR2* structure from a user list.
905 ********************************************************************/
907 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
908 struct samr_SamEntry **sam_pp,
909 uint32_t num_entries,
910 uint32_t start_idx,
911 struct samr_displayentry *entries)
913 uint32_t i;
914 struct samr_SamEntry *sam;
916 *sam_pp = NULL;
918 if (num_entries == 0) {
919 return NT_STATUS_OK;
922 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
923 if (sam == NULL) {
924 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
925 return NT_STATUS_NO_MEMORY;
928 for (i = 0; i < num_entries; i++) {
929 #if 0
931 * usrmgr expects a non-NULL terminated string with
932 * trust relationships
934 if (entries[i].acct_flags & ACB_DOMTRUST) {
935 init_unistr2(&uni_temp_name, entries[i].account_name,
936 UNI_FLAGS_NONE);
937 } else {
938 init_unistr2(&uni_temp_name, entries[i].account_name,
939 UNI_STR_TERMINATE);
941 #endif
942 init_lsa_String(&sam[i].name, entries[i].account_name);
943 sam[i].idx = entries[i].rid;
946 *sam_pp = sam;
948 return NT_STATUS_OK;
951 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
953 /*******************************************************************
954 _samr_EnumDomainUsers
955 ********************************************************************/
957 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
958 struct samr_EnumDomainUsers *r)
960 NTSTATUS status;
961 struct samr_info *info = NULL;
962 int num_account;
963 uint32 enum_context = *r->in.resume_handle;
964 enum remote_arch_types ra_type = get_remote_arch();
965 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
966 uint32 max_entries = max_sam_entries;
967 struct samr_displayentry *entries = NULL;
968 struct samr_SamArray *samr_array = NULL;
969 struct samr_SamEntry *samr_entries = NULL;
971 /* find the policy handle. open a policy on it. */
972 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
973 return NT_STATUS_INVALID_HANDLE;
975 status = access_check_samr_function(info->acc_granted,
976 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
977 "_samr_EnumDomainUsers");
978 if (!NT_STATUS_IS_OK(status)) {
979 return status;
982 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
984 if (info->builtin_domain) {
985 /* No users in builtin. */
986 *r->out.resume_handle = *r->in.resume_handle;
987 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
988 return status;
991 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
992 if (!samr_array) {
993 return NT_STATUS_NO_MEMORY;
995 *r->out.sam = samr_array;
997 become_root();
999 /* AS ROOT !!!! */
1001 if ((info->disp_info->enum_users != NULL) &&
1002 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1003 TALLOC_FREE(info->disp_info->enum_users);
1006 if (info->disp_info->enum_users == NULL) {
1007 info->disp_info->enum_users = pdb_search_users(
1008 info->disp_info, r->in.acct_flags);
1009 info->disp_info->enum_acb_mask = r->in.acct_flags;
1012 if (info->disp_info->enum_users == NULL) {
1013 /* END AS ROOT !!!! */
1014 unbecome_root();
1015 return NT_STATUS_ACCESS_DENIED;
1018 num_account = pdb_search_entries(info->disp_info->enum_users,
1019 enum_context, max_entries,
1020 &entries);
1022 /* END AS ROOT !!!! */
1024 unbecome_root();
1026 if (num_account == 0) {
1027 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1028 "total entries\n"));
1029 *r->out.resume_handle = *r->in.resume_handle;
1030 return NT_STATUS_OK;
1033 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1034 num_account, enum_context,
1035 entries);
1036 if (!NT_STATUS_IS_OK(status)) {
1037 return status;
1040 if (max_entries <= num_account) {
1041 status = STATUS_MORE_ENTRIES;
1042 } else {
1043 status = NT_STATUS_OK;
1046 /* Ensure we cache this enumeration. */
1047 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1049 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1051 samr_array->count = num_account;
1052 samr_array->entries = samr_entries;
1054 *r->out.resume_handle = *r->in.resume_handle + num_account;
1055 *r->out.num_entries = num_account;
1057 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1059 return status;
1062 /*******************************************************************
1063 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1064 ********************************************************************/
1066 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1067 struct samr_SamEntry **sam_pp,
1068 uint32_t num_sam_entries,
1069 struct samr_displayentry *entries)
1071 struct samr_SamEntry *sam;
1072 uint32_t i;
1074 *sam_pp = NULL;
1076 if (num_sam_entries == 0) {
1077 return;
1080 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1081 if (sam == NULL) {
1082 return;
1085 for (i = 0; i < num_sam_entries; i++) {
1087 * JRA. I think this should include the null. TNG does not.
1089 init_lsa_String(&sam[i].name, entries[i].account_name);
1090 sam[i].idx = entries[i].rid;
1093 *sam_pp = sam;
1096 /*******************************************************************
1097 _samr_EnumDomainGroups
1098 ********************************************************************/
1100 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1101 struct samr_EnumDomainGroups *r)
1103 NTSTATUS status;
1104 struct samr_info *info = NULL;
1105 struct samr_displayentry *groups;
1106 uint32 num_groups;
1107 struct samr_SamArray *samr_array = NULL;
1108 struct samr_SamEntry *samr_entries = NULL;
1110 /* find the policy handle. open a policy on it. */
1111 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1112 return NT_STATUS_INVALID_HANDLE;
1114 status = access_check_samr_function(info->acc_granted,
1115 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1116 "_samr_EnumDomainGroups");
1117 if (!NT_STATUS_IS_OK(status)) {
1118 return status;
1121 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1123 if (info->builtin_domain) {
1124 /* No groups in builtin. */
1125 *r->out.resume_handle = *r->in.resume_handle;
1126 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1127 return status;
1130 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1131 if (!samr_array) {
1132 return NT_STATUS_NO_MEMORY;
1135 /* the domain group array is being allocated in the function below */
1137 become_root();
1139 if (info->disp_info->groups == NULL) {
1140 info->disp_info->groups = pdb_search_groups(info->disp_info);
1142 if (info->disp_info->groups == NULL) {
1143 unbecome_root();
1144 return NT_STATUS_ACCESS_DENIED;
1148 num_groups = pdb_search_entries(info->disp_info->groups,
1149 *r->in.resume_handle,
1150 MAX_SAM_ENTRIES, &groups);
1151 unbecome_root();
1153 /* Ensure we cache this enumeration. */
1154 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1156 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1157 num_groups, groups);
1159 samr_array->count = num_groups;
1160 samr_array->entries = samr_entries;
1162 *r->out.sam = samr_array;
1163 *r->out.num_entries = num_groups;
1164 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1166 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1168 return status;
1171 /*******************************************************************
1172 _samr_EnumDomainAliases
1173 ********************************************************************/
1175 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1176 struct samr_EnumDomainAliases *r)
1178 NTSTATUS status;
1179 struct samr_info *info;
1180 struct samr_displayentry *aliases;
1181 uint32 num_aliases = 0;
1182 struct samr_SamArray *samr_array = NULL;
1183 struct samr_SamEntry *samr_entries = NULL;
1185 /* find the policy handle. open a policy on it. */
1186 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1187 return NT_STATUS_INVALID_HANDLE;
1189 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1190 sid_string_dbg(&info->sid)));
1192 status = access_check_samr_function(info->acc_granted,
1193 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1194 "_samr_EnumDomainAliases");
1195 if (!NT_STATUS_IS_OK(status)) {
1196 return status;
1199 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1200 if (!samr_array) {
1201 return NT_STATUS_NO_MEMORY;
1204 become_root();
1206 if (info->disp_info->aliases == NULL) {
1207 info->disp_info->aliases = pdb_search_aliases(
1208 info->disp_info, &info->sid);
1209 if (info->disp_info->aliases == NULL) {
1210 unbecome_root();
1211 return NT_STATUS_ACCESS_DENIED;
1215 num_aliases = pdb_search_entries(info->disp_info->aliases,
1216 *r->in.resume_handle,
1217 MAX_SAM_ENTRIES, &aliases);
1218 unbecome_root();
1220 /* Ensure we cache this enumeration. */
1221 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1223 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1224 num_aliases, aliases);
1226 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1228 samr_array->count = num_aliases;
1229 samr_array->entries = samr_entries;
1231 *r->out.sam = samr_array;
1232 *r->out.num_entries = num_aliases;
1233 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1235 return status;
1238 /*******************************************************************
1239 inits a samr_DispInfoGeneral structure.
1240 ********************************************************************/
1242 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1243 struct samr_DispInfoGeneral *r,
1244 uint32_t num_entries,
1245 uint32_t start_idx,
1246 struct samr_displayentry *entries)
1248 uint32 i;
1250 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1252 if (num_entries == 0) {
1253 return NT_STATUS_OK;
1256 r->count = num_entries;
1258 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1259 if (!r->entries) {
1260 return NT_STATUS_NO_MEMORY;
1263 for (i = 0; i < num_entries ; i++) {
1265 init_lsa_String(&r->entries[i].account_name,
1266 entries[i].account_name);
1268 init_lsa_String(&r->entries[i].description,
1269 entries[i].description);
1271 init_lsa_String(&r->entries[i].full_name,
1272 entries[i].fullname);
1274 r->entries[i].rid = entries[i].rid;
1275 r->entries[i].acct_flags = entries[i].acct_flags;
1276 r->entries[i].idx = start_idx+i+1;
1279 return NT_STATUS_OK;
1282 /*******************************************************************
1283 inits a samr_DispInfoFull structure.
1284 ********************************************************************/
1286 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1287 struct samr_DispInfoFull *r,
1288 uint32_t num_entries,
1289 uint32_t start_idx,
1290 struct samr_displayentry *entries)
1292 uint32_t i;
1294 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1296 if (num_entries == 0) {
1297 return NT_STATUS_OK;
1300 r->count = num_entries;
1302 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1303 if (!r->entries) {
1304 return NT_STATUS_NO_MEMORY;
1307 for (i = 0; i < num_entries ; i++) {
1309 init_lsa_String(&r->entries[i].account_name,
1310 entries[i].account_name);
1312 init_lsa_String(&r->entries[i].description,
1313 entries[i].description);
1315 r->entries[i].rid = entries[i].rid;
1316 r->entries[i].acct_flags = entries[i].acct_flags;
1317 r->entries[i].idx = start_idx+i+1;
1320 return NT_STATUS_OK;
1323 /*******************************************************************
1324 inits a samr_DispInfoFullGroups structure.
1325 ********************************************************************/
1327 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1328 struct samr_DispInfoFullGroups *r,
1329 uint32_t num_entries,
1330 uint32_t start_idx,
1331 struct samr_displayentry *entries)
1333 uint32_t i;
1335 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1337 if (num_entries == 0) {
1338 return NT_STATUS_OK;
1341 r->count = num_entries;
1343 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1344 if (!r->entries) {
1345 return NT_STATUS_NO_MEMORY;
1348 for (i = 0; i < num_entries ; i++) {
1350 init_lsa_String(&r->entries[i].account_name,
1351 entries[i].account_name);
1353 init_lsa_String(&r->entries[i].description,
1354 entries[i].description);
1356 r->entries[i].rid = entries[i].rid;
1357 r->entries[i].acct_flags = entries[i].acct_flags;
1358 r->entries[i].idx = start_idx+i+1;
1361 return NT_STATUS_OK;
1364 /*******************************************************************
1365 inits a samr_DispInfoAscii structure.
1366 ********************************************************************/
1368 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1369 struct samr_DispInfoAscii *r,
1370 uint32_t num_entries,
1371 uint32_t start_idx,
1372 struct samr_displayentry *entries)
1374 uint32_t i;
1376 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1378 if (num_entries == 0) {
1379 return NT_STATUS_OK;
1382 r->count = num_entries;
1384 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1385 if (!r->entries) {
1386 return NT_STATUS_NO_MEMORY;
1389 for (i = 0; i < num_entries ; i++) {
1391 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1392 entries[i].account_name);
1394 r->entries[i].idx = start_idx+i+1;
1397 return NT_STATUS_OK;
1400 /*******************************************************************
1401 inits a samr_DispInfoAscii structure.
1402 ********************************************************************/
1404 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1405 struct samr_DispInfoAscii *r,
1406 uint32_t num_entries,
1407 uint32_t start_idx,
1408 struct samr_displayentry *entries)
1410 uint32_t i;
1412 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1414 if (num_entries == 0) {
1415 return NT_STATUS_OK;
1418 r->count = num_entries;
1420 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1421 if (!r->entries) {
1422 return NT_STATUS_NO_MEMORY;
1425 for (i = 0; i < num_entries ; i++) {
1427 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1428 entries[i].account_name);
1430 r->entries[i].idx = start_idx+i+1;
1433 return NT_STATUS_OK;
1436 /*******************************************************************
1437 _samr_QueryDisplayInfo
1438 ********************************************************************/
1440 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1441 struct samr_QueryDisplayInfo *r)
1443 NTSTATUS status;
1444 struct samr_info *info = NULL;
1445 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1447 uint32 max_entries = r->in.max_entries;
1448 uint32 enum_context = r->in.start_idx;
1449 uint32 max_size = r->in.buf_size;
1451 union samr_DispInfo *disp_info = r->out.info;
1453 uint32 temp_size=0, total_data_size=0;
1454 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1455 uint32 num_account = 0;
1456 enum remote_arch_types ra_type = get_remote_arch();
1457 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1458 struct samr_displayentry *entries = NULL;
1460 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1462 /* find the policy handle. open a policy on it. */
1463 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1464 return NT_STATUS_INVALID_HANDLE;
1466 if (info->builtin_domain) {
1467 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1468 return NT_STATUS_OK;
1471 status = access_check_samr_function(info->acc_granted,
1472 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1473 "_samr_QueryDisplayInfo");
1474 if (!NT_STATUS_IS_OK(status)) {
1475 return status;
1479 * calculate how many entries we will return.
1480 * based on
1481 * - the number of entries the client asked
1482 * - our limit on that
1483 * - the starting point (enumeration context)
1484 * - the buffer size the client will accept
1488 * We are a lot more like W2K. Instead of reading the SAM
1489 * each time to find the records we need to send back,
1490 * we read it once and link that copy to the sam handle.
1491 * For large user list (over the MAX_SAM_ENTRIES)
1492 * it's a definitive win.
1493 * second point to notice: between enumerations
1494 * our sam is now the same as it's a snapshoot.
1495 * third point: got rid of the static SAM_USER_21 struct
1496 * no more intermediate.
1497 * con: it uses much more memory, as a full copy is stored
1498 * in memory.
1500 * If you want to change it, think twice and think
1501 * of the second point , that's really important.
1503 * JFM, 12/20/2001
1506 if ((r->in.level < 1) || (r->in.level > 5)) {
1507 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1508 (unsigned int)r->in.level ));
1509 return NT_STATUS_INVALID_INFO_CLASS;
1512 /* first limit the number of entries we will return */
1513 if(max_entries > max_sam_entries) {
1514 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1515 "entries, limiting to %d\n", max_entries,
1516 max_sam_entries));
1517 max_entries = max_sam_entries;
1520 /* calculate the size and limit on the number of entries we will
1521 * return */
1523 temp_size=max_entries*struct_size;
1525 if (temp_size>max_size) {
1526 max_entries=MIN((max_size/struct_size),max_entries);;
1527 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1528 "only %d entries\n", max_entries));
1531 become_root();
1533 /* THe following done as ROOT. Don't return without unbecome_root(). */
1535 switch (r->in.level) {
1536 case 0x1:
1537 case 0x4:
1538 if (info->disp_info->users == NULL) {
1539 info->disp_info->users = pdb_search_users(
1540 info->disp_info, 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 = pdb_search_users(
1559 info->disp_info, 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 info->disp_info);
1580 if (info->disp_info->groups == NULL) {
1581 unbecome_root();
1582 return NT_STATUS_ACCESS_DENIED;
1584 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1585 (unsigned int)enum_context ));
1586 } else {
1587 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1588 (unsigned int)enum_context ));
1591 num_account = pdb_search_entries(info->disp_info->groups,
1592 enum_context, max_entries,
1593 &entries);
1594 break;
1595 default:
1596 unbecome_root();
1597 smb_panic("info class changed");
1598 break;
1600 unbecome_root();
1603 /* Now create reply structure */
1604 switch (r->in.level) {
1605 case 0x1:
1606 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1607 num_account, enum_context,
1608 entries);
1609 break;
1610 case 0x2:
1611 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1612 num_account, enum_context,
1613 entries);
1614 break;
1615 case 0x3:
1616 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1617 num_account, enum_context,
1618 entries);
1619 break;
1620 case 0x4:
1621 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1622 num_account, enum_context,
1623 entries);
1624 break;
1625 case 0x5:
1626 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1627 num_account, enum_context,
1628 entries);
1629 break;
1630 default:
1631 smb_panic("info class changed");
1632 break;
1635 if (!NT_STATUS_IS_OK(disp_ret))
1636 return disp_ret;
1638 /* calculate the total size */
1639 total_data_size=num_account*struct_size;
1641 if (max_entries <= num_account) {
1642 status = STATUS_MORE_ENTRIES;
1643 } else {
1644 status = NT_STATUS_OK;
1647 /* Ensure we cache this enumeration. */
1648 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1650 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1652 *r->out.total_size = total_data_size;
1653 *r->out.returned_size = temp_size;
1655 return status;
1658 /****************************************************************
1659 _samr_QueryDisplayInfo2
1660 ****************************************************************/
1662 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1663 struct samr_QueryDisplayInfo2 *r)
1665 struct samr_QueryDisplayInfo q;
1667 q.in.domain_handle = r->in.domain_handle;
1668 q.in.level = r->in.level;
1669 q.in.start_idx = r->in.start_idx;
1670 q.in.max_entries = r->in.max_entries;
1671 q.in.buf_size = r->in.buf_size;
1673 q.out.total_size = r->out.total_size;
1674 q.out.returned_size = r->out.returned_size;
1675 q.out.info = r->out.info;
1677 return _samr_QueryDisplayInfo(p, &q);
1680 /****************************************************************
1681 _samr_QueryDisplayInfo3
1682 ****************************************************************/
1684 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1685 struct samr_QueryDisplayInfo3 *r)
1687 struct samr_QueryDisplayInfo q;
1689 q.in.domain_handle = r->in.domain_handle;
1690 q.in.level = r->in.level;
1691 q.in.start_idx = r->in.start_idx;
1692 q.in.max_entries = r->in.max_entries;
1693 q.in.buf_size = r->in.buf_size;
1695 q.out.total_size = r->out.total_size;
1696 q.out.returned_size = r->out.returned_size;
1697 q.out.info = r->out.info;
1699 return _samr_QueryDisplayInfo(p, &q);
1702 /*******************************************************************
1703 _samr_QueryAliasInfo
1704 ********************************************************************/
1706 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1707 struct samr_QueryAliasInfo *r)
1709 DOM_SID sid;
1710 struct acct_info info;
1711 uint32 acc_granted;
1712 NTSTATUS status;
1713 union samr_AliasInfo *alias_info = NULL;
1714 const char *alias_name = NULL;
1715 const char *alias_description = NULL;
1717 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1719 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1720 if (!alias_info) {
1721 return NT_STATUS_NO_MEMORY;
1724 /* find the policy handle. open a policy on it. */
1725 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1726 return NT_STATUS_INVALID_HANDLE;
1728 status = access_check_samr_function(acc_granted,
1729 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1730 "_samr_QueryAliasInfo");
1731 if (!NT_STATUS_IS_OK(status)) {
1732 return status;
1735 become_root();
1736 status = pdb_get_aliasinfo(&sid, &info);
1737 unbecome_root();
1739 if ( !NT_STATUS_IS_OK(status))
1740 return status;
1742 /* FIXME: info contains fstrings */
1743 alias_name = talloc_strdup(r, info.acct_name);
1744 alias_description = talloc_strdup(r, info.acct_desc);
1746 switch (r->in.level) {
1747 case ALIASINFOALL:
1748 alias_info->all.name.string = alias_name;
1749 alias_info->all.num_members = 1; /* ??? */
1750 alias_info->all.description.string = alias_description;
1751 break;
1752 case ALIASINFONAME:
1753 alias_info->name.string = alias_name;
1754 break;
1755 case ALIASINFODESCRIPTION:
1756 alias_info->description.string = alias_description;
1757 break;
1758 default:
1759 return NT_STATUS_INVALID_INFO_CLASS;
1762 *r->out.info = alias_info;
1764 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1766 return NT_STATUS_OK;
1769 /*******************************************************************
1770 _samr_LookupNames
1771 ********************************************************************/
1773 NTSTATUS _samr_LookupNames(pipes_struct *p,
1774 struct samr_LookupNames *r)
1776 NTSTATUS status;
1777 uint32 *rid;
1778 enum lsa_SidType *type;
1779 int i;
1780 int num_rids = r->in.num_names;
1781 DOM_SID pol_sid;
1782 uint32 acc_granted;
1783 struct samr_Ids rids, types;
1784 uint32_t num_mapped = 0;
1786 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1788 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1789 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1792 status = access_check_samr_function(acc_granted,
1793 0, /* Don't know the acc_bits yet */
1794 "_samr_LookupNames");
1795 if (!NT_STATUS_IS_OK(status)) {
1796 return status;
1799 if (num_rids > MAX_SAM_ENTRIES) {
1800 num_rids = MAX_SAM_ENTRIES;
1801 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1804 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1805 NT_STATUS_HAVE_NO_MEMORY(rid);
1807 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1808 NT_STATUS_HAVE_NO_MEMORY(type);
1810 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1811 sid_string_dbg(&pol_sid)));
1813 for (i = 0; i < num_rids; i++) {
1815 status = NT_STATUS_NONE_MAPPED;
1816 type[i] = SID_NAME_UNKNOWN;
1818 rid[i] = 0xffffffff;
1820 if (sid_check_is_builtin(&pol_sid)) {
1821 if (lookup_builtin_name(r->in.names[i].string,
1822 &rid[i]))
1824 type[i] = SID_NAME_ALIAS;
1826 } else {
1827 lookup_global_sam_name(r->in.names[i].string, 0,
1828 &rid[i], &type[i]);
1831 if (type[i] != SID_NAME_UNKNOWN) {
1832 num_mapped++;
1836 if (num_mapped == num_rids) {
1837 status = NT_STATUS_OK;
1838 } else if (num_mapped == 0) {
1839 status = NT_STATUS_NONE_MAPPED;
1840 } else {
1841 status = STATUS_SOME_UNMAPPED;
1844 rids.count = num_rids;
1845 rids.ids = rid;
1847 types.count = num_rids;
1848 types.ids = type;
1850 *r->out.rids = rids;
1851 *r->out.types = types;
1853 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1855 return status;
1858 /****************************************************************
1859 _samr_ChangePasswordUser
1860 ****************************************************************/
1862 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1863 struct samr_ChangePasswordUser *r)
1865 NTSTATUS status;
1866 bool ret = false;
1867 struct samu *pwd;
1868 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1869 struct samr_Password lm_pwd, nt_pwd;
1870 uint32_t acc_granted;
1871 struct dom_sid sid;
1873 DISP_INFO *disp_info = NULL;
1875 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) {
1876 return NT_STATUS_INVALID_HANDLE;
1879 status = access_check_samr_function(acc_granted,
1880 SAMR_USER_ACCESS_SET_PASSWORD,
1881 "_samr_ChangePasswordUser");
1882 if (!NT_STATUS_IS_OK(status)) {
1883 return status;
1886 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1887 sid_string_dbg(&sid)));
1889 if (!(pwd = samu_new(NULL))) {
1890 return NT_STATUS_NO_MEMORY;
1893 become_root();
1894 ret = pdb_getsampwsid(pwd, &sid);
1895 unbecome_root();
1897 if (!ret) {
1898 TALLOC_FREE(pwd);
1899 return NT_STATUS_WRONG_PASSWORD;
1903 const uint8_t *lm_pass, *nt_pass;
1905 lm_pass = pdb_get_lanman_passwd(pwd);
1906 nt_pass = pdb_get_nt_passwd(pwd);
1908 if (!lm_pass || !nt_pass) {
1909 status = NT_STATUS_WRONG_PASSWORD;
1910 goto out;
1913 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1914 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1917 /* basic sanity checking on parameters. Do this before any database ops */
1918 if (!r->in.lm_present || !r->in.nt_present ||
1919 !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1920 !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1921 /* we should really handle a change with lm not
1922 present */
1923 status = NT_STATUS_INVALID_PARAMETER_MIX;
1924 goto out;
1927 /* decrypt and check the new lm hash */
1928 D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1929 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1930 if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1931 status = NT_STATUS_WRONG_PASSWORD;
1932 goto out;
1935 /* decrypt and check the new nt hash */
1936 D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1937 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1938 if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1939 status = NT_STATUS_WRONG_PASSWORD;
1940 goto out;
1943 /* The NT Cross is not required by Win2k3 R2, but if present
1944 check the nt cross hash */
1945 if (r->in.cross1_present && r->in.nt_cross) {
1946 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1947 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1948 status = NT_STATUS_WRONG_PASSWORD;
1949 goto out;
1953 /* The LM Cross is not required by Win2k3 R2, but if present
1954 check the lm cross hash */
1955 if (r->in.cross2_present && r->in.lm_cross) {
1956 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1957 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1958 status = NT_STATUS_WRONG_PASSWORD;
1959 goto out;
1963 if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1964 !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1965 status = NT_STATUS_ACCESS_DENIED;
1966 goto out;
1969 status = pdb_update_sam_account(pwd);
1970 out:
1971 TALLOC_FREE(pwd);
1973 return status;
1976 /*******************************************************************
1977 _samr_ChangePasswordUser2
1978 ********************************************************************/
1980 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1981 struct samr_ChangePasswordUser2 *r)
1983 NTSTATUS status;
1984 fstring user_name;
1985 fstring wks;
1987 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1989 fstrcpy(user_name, r->in.account->string);
1990 fstrcpy(wks, r->in.server->string);
1992 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1995 * Pass the user through the NT -> unix user mapping
1996 * function.
1999 (void)map_username(user_name);
2002 * UNIX username case mangling not required, pass_oem_change
2003 * is case insensitive.
2006 status = pass_oem_change(user_name,
2007 r->in.lm_password->data,
2008 r->in.lm_verifier->hash,
2009 r->in.nt_password->data,
2010 r->in.nt_verifier->hash,
2011 NULL);
2013 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
2015 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2016 return NT_STATUS_WRONG_PASSWORD;
2019 return status;
2022 /****************************************************************
2023 _samr_OemChangePasswordUser2
2024 ****************************************************************/
2026 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
2027 struct samr_OemChangePasswordUser2 *r)
2029 NTSTATUS status;
2030 fstring user_name;
2031 const char *wks = NULL;
2033 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2035 fstrcpy(user_name, r->in.account->string);
2036 if (r->in.server && r->in.server->string) {
2037 wks = r->in.server->string;
2040 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
2043 * Pass the user through the NT -> unix user mapping
2044 * function.
2047 (void)map_username(user_name);
2050 * UNIX username case mangling not required, pass_oem_change
2051 * is case insensitive.
2054 if (!r->in.hash || !r->in.password) {
2055 return NT_STATUS_INVALID_PARAMETER;
2058 status = pass_oem_change(user_name,
2059 r->in.password->data,
2060 r->in.hash->hash,
2063 NULL);
2065 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2066 return NT_STATUS_WRONG_PASSWORD;
2069 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2071 return status;
2074 /*******************************************************************
2075 _samr_ChangePasswordUser3
2076 ********************************************************************/
2078 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
2079 struct samr_ChangePasswordUser3 *r)
2081 NTSTATUS status;
2082 fstring user_name;
2083 const char *wks = NULL;
2084 uint32 reject_reason;
2085 struct samr_DomInfo1 *dominfo = NULL;
2086 struct samr_ChangeReject *reject = NULL;
2087 uint32_t tmp;
2089 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2091 fstrcpy(user_name, r->in.account->string);
2092 if (r->in.server && r->in.server->string) {
2093 wks = r->in.server->string;
2096 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2099 * Pass the user through the NT -> unix user mapping
2100 * function.
2103 (void)map_username(user_name);
2106 * UNIX username case mangling not required, pass_oem_change
2107 * is case insensitive.
2110 status = pass_oem_change(user_name,
2111 r->in.lm_password->data,
2112 r->in.lm_verifier->hash,
2113 r->in.nt_password->data,
2114 r->in.nt_verifier->hash,
2115 &reject_reason);
2116 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2117 return NT_STATUS_WRONG_PASSWORD;
2120 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2121 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2123 time_t u_expire, u_min_age;
2124 uint32 account_policy_temp;
2126 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2127 if (!dominfo) {
2128 return NT_STATUS_NO_MEMORY;
2131 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2132 if (!reject) {
2133 return NT_STATUS_NO_MEMORY;
2136 become_root();
2138 /* AS ROOT !!! */
2140 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
2141 dominfo->min_password_length = tmp;
2143 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
2144 dominfo->password_history_length = tmp;
2146 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2147 &dominfo->password_properties);
2149 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2150 u_expire = account_policy_temp;
2152 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2153 u_min_age = account_policy_temp;
2155 /* !AS ROOT */
2157 unbecome_root();
2159 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2160 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2162 if (lp_check_password_script() && *lp_check_password_script()) {
2163 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2166 reject->reason = reject_reason;
2168 *r->out.dominfo = dominfo;
2169 *r->out.reject = reject;
2172 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2174 return status;
2177 /*******************************************************************
2178 makes a SAMR_R_LOOKUP_RIDS structure.
2179 ********************************************************************/
2181 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2182 const char **names,
2183 struct lsa_String **lsa_name_array_p)
2185 struct lsa_String *lsa_name_array = NULL;
2186 uint32_t i;
2188 *lsa_name_array_p = NULL;
2190 if (num_names != 0) {
2191 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2192 if (!lsa_name_array) {
2193 return false;
2197 for (i = 0; i < num_names; i++) {
2198 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2199 init_lsa_String(&lsa_name_array[i], names[i]);
2202 *lsa_name_array_p = lsa_name_array;
2204 return true;
2207 /*******************************************************************
2208 _samr_LookupRids
2209 ********************************************************************/
2211 NTSTATUS _samr_LookupRids(pipes_struct *p,
2212 struct samr_LookupRids *r)
2214 NTSTATUS status;
2215 const char **names;
2216 enum lsa_SidType *attrs = NULL;
2217 uint32 *wire_attrs = NULL;
2218 DOM_SID pol_sid;
2219 int num_rids = (int)r->in.num_rids;
2220 uint32 acc_granted;
2221 int i;
2222 struct lsa_Strings names_array;
2223 struct samr_Ids types_array;
2224 struct lsa_String *lsa_names = NULL;
2226 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2228 /* find the policy handle. open a policy on it. */
2229 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2230 return NT_STATUS_INVALID_HANDLE;
2232 status = access_check_samr_function(acc_granted,
2233 0, /* Don't know the acc_bits yet */
2234 "_samr_LookupRids");
2235 if (!NT_STATUS_IS_OK(status)) {
2236 return status;
2239 if (num_rids > 1000) {
2240 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2241 "to samba4 idl this is not possible\n", num_rids));
2242 return NT_STATUS_UNSUCCESSFUL;
2245 if (num_rids) {
2246 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2247 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2248 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2250 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2251 return NT_STATUS_NO_MEMORY;
2252 } else {
2253 names = NULL;
2254 attrs = NULL;
2255 wire_attrs = NULL;
2258 become_root(); /* lookup_sid can require root privs */
2259 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2260 names, attrs);
2261 unbecome_root();
2263 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2264 status = NT_STATUS_OK;
2267 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2268 &lsa_names)) {
2269 return NT_STATUS_NO_MEMORY;
2272 /* Convert from enum lsa_SidType to uint32 for wire format. */
2273 for (i = 0; i < num_rids; i++) {
2274 wire_attrs[i] = (uint32)attrs[i];
2277 names_array.count = num_rids;
2278 names_array.names = lsa_names;
2280 types_array.count = num_rids;
2281 types_array.ids = wire_attrs;
2283 *r->out.names = names_array;
2284 *r->out.types = types_array;
2286 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2288 return status;
2291 /*******************************************************************
2292 _samr_OpenUser
2293 ********************************************************************/
2295 NTSTATUS _samr_OpenUser(pipes_struct *p,
2296 struct samr_OpenUser *r)
2298 struct samu *sampass=NULL;
2299 DOM_SID sid;
2300 struct samr_info *info = NULL;
2301 SEC_DESC *psd = NULL;
2302 uint32 acc_granted;
2303 uint32 des_access = r->in.access_mask;
2304 size_t sd_size;
2305 bool ret;
2306 NTSTATUS nt_status;
2307 SE_PRIV se_rights;
2309 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2311 if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
2312 return NT_STATUS_INVALID_HANDLE;
2314 nt_status = access_check_samr_function(acc_granted,
2315 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2316 "_samr_OpenUser" );
2318 if ( !NT_STATUS_IS_OK(nt_status) )
2319 return nt_status;
2321 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2322 return NT_STATUS_NO_MEMORY;
2325 /* append the user's RID to it */
2327 if (!sid_append_rid(&sid, r->in.rid))
2328 return NT_STATUS_NO_SUCH_USER;
2330 /* check if access can be granted as requested by client. */
2332 map_max_allowed_access(p->server_info->ptok, &des_access);
2334 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2335 se_map_generic(&des_access, &usr_generic_mapping);
2337 se_priv_copy( &se_rights, &se_machine_account );
2338 se_priv_add( &se_rights, &se_add_users );
2340 nt_status = access_check_samr_object(psd, p->server_info->ptok,
2341 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2342 &acc_granted, "_samr_OpenUser");
2344 if ( !NT_STATUS_IS_OK(nt_status) )
2345 return nt_status;
2347 become_root();
2348 ret=pdb_getsampwsid(sampass, &sid);
2349 unbecome_root();
2351 /* check that the SID exists in our domain. */
2352 if (ret == False) {
2353 return NT_STATUS_NO_SUCH_USER;
2356 TALLOC_FREE(sampass);
2358 /* associate the user's SID and access bits with the new handle. */
2359 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
2360 return NT_STATUS_NO_MEMORY;
2361 info->acc_granted = acc_granted;
2363 /* get a (unique) handle. open a policy on it. */
2364 if (!create_policy_hnd(p, r->out.user_handle, info))
2365 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2367 return NT_STATUS_OK;
2370 /*************************************************************************
2371 *************************************************************************/
2373 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2374 DATA_BLOB *blob,
2375 struct lsa_BinaryString **_r)
2377 struct lsa_BinaryString *r;
2379 if (!blob || !_r) {
2380 return NT_STATUS_INVALID_PARAMETER;
2383 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2384 if (!r) {
2385 return NT_STATUS_NO_MEMORY;
2388 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2389 if (!r->array) {
2390 return NT_STATUS_NO_MEMORY;
2392 memcpy(r->array, blob->data, blob->length);
2393 r->size = blob->length;
2394 r->length = blob->length;
2396 if (!r->array) {
2397 return NT_STATUS_NO_MEMORY;
2400 *_r = r;
2402 return NT_STATUS_OK;
2405 /*************************************************************************
2406 get_user_info_1.
2407 *************************************************************************/
2409 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2410 struct samr_UserInfo1 *r,
2411 struct samu *pw,
2412 DOM_SID *domain_sid)
2414 const DOM_SID *sid_group;
2415 uint32_t primary_gid;
2417 become_root();
2418 sid_group = pdb_get_group_sid(pw);
2419 unbecome_root();
2421 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2422 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2423 "which conflicts with the domain sid %s. Failing operation.\n",
2424 pdb_get_username(pw), sid_string_dbg(sid_group),
2425 sid_string_dbg(domain_sid)));
2426 return NT_STATUS_UNSUCCESSFUL;
2429 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2430 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2431 r->primary_gid = primary_gid;
2432 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2433 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2435 return NT_STATUS_OK;
2438 /*************************************************************************
2439 get_user_info_2.
2440 *************************************************************************/
2442 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2443 struct samr_UserInfo2 *r,
2444 struct samu *pw)
2446 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2447 r->unknown.string = NULL;
2448 r->country_code = 0;
2449 r->code_page = 0;
2451 return NT_STATUS_OK;
2454 /*************************************************************************
2455 get_user_info_3.
2456 *************************************************************************/
2458 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2459 struct samr_UserInfo3 *r,
2460 struct samu *pw,
2461 DOM_SID *domain_sid)
2463 const DOM_SID *sid_user, *sid_group;
2464 uint32_t rid, primary_gid;
2466 sid_user = pdb_get_user_sid(pw);
2468 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2469 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2470 "the domain sid %s. Failing operation.\n",
2471 pdb_get_username(pw), sid_string_dbg(sid_user),
2472 sid_string_dbg(domain_sid)));
2473 return NT_STATUS_UNSUCCESSFUL;
2476 become_root();
2477 sid_group = pdb_get_group_sid(pw);
2478 unbecome_root();
2480 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2481 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2482 "which conflicts with the domain sid %s. Failing operation.\n",
2483 pdb_get_username(pw), sid_string_dbg(sid_group),
2484 sid_string_dbg(domain_sid)));
2485 return NT_STATUS_UNSUCCESSFUL;
2488 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2489 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2490 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2491 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2492 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2494 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2495 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2496 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2497 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2498 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2499 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2500 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2502 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2503 r->rid = rid;
2504 r->primary_gid = primary_gid;
2505 r->acct_flags = pdb_get_acct_ctrl(pw);
2506 r->bad_password_count = pdb_get_bad_password_count(pw);
2507 r->logon_count = pdb_get_logon_count(pw);
2509 return NT_STATUS_OK;
2512 /*************************************************************************
2513 get_user_info_4.
2514 *************************************************************************/
2516 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2517 struct samr_UserInfo4 *r,
2518 struct samu *pw)
2520 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2522 return NT_STATUS_OK;
2525 /*************************************************************************
2526 get_user_info_5.
2527 *************************************************************************/
2529 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2530 struct samr_UserInfo5 *r,
2531 struct samu *pw,
2532 DOM_SID *domain_sid)
2534 const DOM_SID *sid_user, *sid_group;
2535 uint32_t rid, primary_gid;
2537 sid_user = pdb_get_user_sid(pw);
2539 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2540 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2541 "the domain sid %s. Failing operation.\n",
2542 pdb_get_username(pw), sid_string_dbg(sid_user),
2543 sid_string_dbg(domain_sid)));
2544 return NT_STATUS_UNSUCCESSFUL;
2547 become_root();
2548 sid_group = pdb_get_group_sid(pw);
2549 unbecome_root();
2551 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2552 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2553 "which conflicts with the domain sid %s. Failing operation.\n",
2554 pdb_get_username(pw), sid_string_dbg(sid_group),
2555 sid_string_dbg(domain_sid)));
2556 return NT_STATUS_UNSUCCESSFUL;
2559 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2560 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2561 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2562 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2564 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2565 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2566 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2567 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2568 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2569 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2570 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2571 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2573 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2574 r->rid = rid;
2575 r->primary_gid = primary_gid;
2576 r->acct_flags = pdb_get_acct_ctrl(pw);
2577 r->bad_password_count = pdb_get_bad_password_count(pw);
2578 r->logon_count = pdb_get_logon_count(pw);
2580 return NT_STATUS_OK;
2583 /*************************************************************************
2584 get_user_info_6.
2585 *************************************************************************/
2587 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2588 struct samr_UserInfo6 *r,
2589 struct samu *pw)
2591 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2592 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2594 return NT_STATUS_OK;
2597 /*************************************************************************
2598 get_user_info_7. Safe. Only gives out account_name.
2599 *************************************************************************/
2601 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2602 struct samr_UserInfo7 *r,
2603 struct samu *smbpass)
2605 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2606 if (!r->account_name.string) {
2607 return NT_STATUS_NO_MEMORY;
2610 return NT_STATUS_OK;
2613 /*************************************************************************
2614 get_user_info_8.
2615 *************************************************************************/
2617 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2618 struct samr_UserInfo8 *r,
2619 struct samu *pw)
2621 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2623 return NT_STATUS_OK;
2626 /*************************************************************************
2627 get_user_info_9. Only gives out primary group SID.
2628 *************************************************************************/
2630 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2631 struct samr_UserInfo9 *r,
2632 struct samu *smbpass)
2634 r->primary_gid = pdb_get_group_rid(smbpass);
2636 return NT_STATUS_OK;
2639 /*************************************************************************
2640 get_user_info_10.
2641 *************************************************************************/
2643 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2644 struct samr_UserInfo10 *r,
2645 struct samu *pw)
2647 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2648 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2650 return NT_STATUS_OK;
2653 /*************************************************************************
2654 get_user_info_11.
2655 *************************************************************************/
2657 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2658 struct samr_UserInfo11 *r,
2659 struct samu *pw)
2661 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2663 return NT_STATUS_OK;
2666 /*************************************************************************
2667 get_user_info_12.
2668 *************************************************************************/
2670 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2671 struct samr_UserInfo12 *r,
2672 struct samu *pw)
2674 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2676 return NT_STATUS_OK;
2679 /*************************************************************************
2680 get_user_info_13.
2681 *************************************************************************/
2683 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2684 struct samr_UserInfo13 *r,
2685 struct samu *pw)
2687 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2689 return NT_STATUS_OK;
2692 /*************************************************************************
2693 get_user_info_14.
2694 *************************************************************************/
2696 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2697 struct samr_UserInfo14 *r,
2698 struct samu *pw)
2700 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2702 return NT_STATUS_OK;
2705 /*************************************************************************
2706 get_user_info_16. Safe. Only gives out acb bits.
2707 *************************************************************************/
2709 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2710 struct samr_UserInfo16 *r,
2711 struct samu *smbpass)
2713 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2715 return NT_STATUS_OK;
2718 /*************************************************************************
2719 get_user_info_17.
2720 *************************************************************************/
2722 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2723 struct samr_UserInfo17 *r,
2724 struct samu *pw)
2726 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2728 return NT_STATUS_OK;
2731 /*************************************************************************
2732 get_user_info_18. OK - this is the killer as it gives out password info.
2733 Ensure that this is only allowed on an encrypted connection with a root
2734 user. JRA.
2735 *************************************************************************/
2737 static NTSTATUS get_user_info_18(pipes_struct *p,
2738 TALLOC_CTX *mem_ctx,
2739 struct samr_UserInfo18 *r,
2740 DOM_SID *user_sid)
2742 struct samu *smbpass=NULL;
2743 bool ret;
2745 ZERO_STRUCTP(r);
2747 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2748 return NT_STATUS_ACCESS_DENIED;
2751 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2752 return NT_STATUS_ACCESS_DENIED;
2756 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2759 if ( !(smbpass = samu_new( mem_ctx )) ) {
2760 return NT_STATUS_NO_MEMORY;
2763 ret = pdb_getsampwsid(smbpass, user_sid);
2765 if (ret == False) {
2766 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2767 TALLOC_FREE(smbpass);
2768 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2771 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2773 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2774 TALLOC_FREE(smbpass);
2775 return NT_STATUS_ACCOUNT_DISABLED;
2778 r->lm_pwd_active = true;
2779 r->nt_pwd_active = true;
2780 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2781 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2782 r->password_expired = 0; /* FIXME */
2784 TALLOC_FREE(smbpass);
2786 return NT_STATUS_OK;
2789 /*************************************************************************
2790 get_user_info_20
2791 *************************************************************************/
2793 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2794 struct samr_UserInfo20 *r,
2795 struct samu *sampass)
2797 const char *munged_dial = NULL;
2798 DATA_BLOB blob;
2799 NTSTATUS status;
2800 struct lsa_BinaryString *parameters = NULL;
2802 ZERO_STRUCTP(r);
2804 munged_dial = pdb_get_munged_dial(sampass);
2806 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2807 munged_dial, (int)strlen(munged_dial)));
2809 if (munged_dial) {
2810 blob = base64_decode_data_blob(munged_dial);
2811 } else {
2812 blob = data_blob_string_const_null("");
2815 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2816 data_blob_free(&blob);
2817 if (!NT_STATUS_IS_OK(status)) {
2818 return status;
2821 r->parameters = *parameters;
2823 return NT_STATUS_OK;
2827 /*************************************************************************
2828 get_user_info_21
2829 *************************************************************************/
2831 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2832 struct samr_UserInfo21 *r,
2833 struct samu *pw,
2834 DOM_SID *domain_sid)
2836 NTSTATUS status;
2837 const DOM_SID *sid_user, *sid_group;
2838 uint32_t rid, primary_gid;
2839 NTTIME force_password_change;
2840 time_t must_change_time;
2841 struct lsa_BinaryString *parameters = NULL;
2842 const char *munged_dial = NULL;
2843 DATA_BLOB blob;
2845 ZERO_STRUCTP(r);
2847 sid_user = pdb_get_user_sid(pw);
2849 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2850 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2851 "the domain sid %s. Failing operation.\n",
2852 pdb_get_username(pw), sid_string_dbg(sid_user),
2853 sid_string_dbg(domain_sid)));
2854 return NT_STATUS_UNSUCCESSFUL;
2857 become_root();
2858 sid_group = pdb_get_group_sid(pw);
2859 unbecome_root();
2861 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2862 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2863 "which conflicts with the domain sid %s. Failing operation.\n",
2864 pdb_get_username(pw), sid_string_dbg(sid_group),
2865 sid_string_dbg(domain_sid)));
2866 return NT_STATUS_UNSUCCESSFUL;
2869 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2870 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2871 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2872 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2873 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2875 must_change_time = pdb_get_pass_must_change_time(pw);
2876 if (must_change_time == get_time_t_max()) {
2877 unix_to_nt_time_abs(&force_password_change, must_change_time);
2878 } else {
2879 unix_to_nt_time(&force_password_change, must_change_time);
2882 munged_dial = pdb_get_munged_dial(pw);
2883 if (munged_dial) {
2884 blob = base64_decode_data_blob(munged_dial);
2885 } else {
2886 blob = data_blob_string_const_null("");
2889 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2890 data_blob_free(&blob);
2891 if (!NT_STATUS_IS_OK(status)) {
2892 return status;
2895 r->force_password_change = force_password_change;
2897 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2898 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2899 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2900 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2901 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2902 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2903 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2904 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2905 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2907 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2908 r->parameters = *parameters;
2909 r->rid = rid;
2910 r->primary_gid = primary_gid;
2911 r->acct_flags = pdb_get_acct_ctrl(pw);
2912 r->bad_password_count = pdb_get_bad_password_count(pw);
2913 r->logon_count = pdb_get_logon_count(pw);
2914 r->fields_present = pdb_build_fields_present(pw);
2915 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2916 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2917 r->country_code = 0;
2918 r->code_page = 0;
2919 r->lm_password_set = 0;
2920 r->nt_password_set = 0;
2922 #if 0
2925 Look at a user on a real NT4 PDC with usrmgr, press
2926 'ok'. Then you will see that fields_present is set to
2927 0x08f827fa. Look at the user immediately after that again,
2928 and you will see that 0x00fffff is returned. This solves
2929 the problem that you get access denied after having looked
2930 at the user.
2931 -- Volker
2934 #endif
2937 return NT_STATUS_OK;
2940 /*******************************************************************
2941 _samr_QueryUserInfo
2942 ********************************************************************/
2944 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2945 struct samr_QueryUserInfo *r)
2947 NTSTATUS status;
2948 union samr_UserInfo *user_info = NULL;
2949 struct samr_info *info = NULL;
2950 DOM_SID domain_sid;
2951 uint32 rid;
2952 bool ret = false;
2953 struct samu *pwd = NULL;
2955 /* search for the handle */
2956 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2957 return NT_STATUS_INVALID_HANDLE;
2959 status = access_check_samr_function(info->acc_granted,
2960 SAMR_USER_ACCESS_GET_ATTRIBUTES,
2961 "_samr_QueryUserInfo");
2962 if (!NT_STATUS_IS_OK(status)) {
2963 return status;
2966 domain_sid = info->sid;
2968 sid_split_rid(&domain_sid, &rid);
2970 if (!sid_check_is_in_our_domain(&info->sid))
2971 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2973 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2974 sid_string_dbg(&info->sid)));
2976 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2977 if (!user_info) {
2978 return NT_STATUS_NO_MEMORY;
2981 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2983 if (!(pwd = samu_new(p->mem_ctx))) {
2984 return NT_STATUS_NO_MEMORY;
2987 become_root();
2988 ret = pdb_getsampwsid(pwd, &info->sid);
2989 unbecome_root();
2991 if (ret == false) {
2992 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2993 TALLOC_FREE(pwd);
2994 return NT_STATUS_NO_SUCH_USER;
2997 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2999 samr_clear_sam_passwd(pwd);
3001 switch (r->in.level) {
3002 case 1:
3003 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3004 break;
3005 case 2:
3006 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3007 break;
3008 case 3:
3009 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3010 break;
3011 case 4:
3012 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3013 break;
3014 case 5:
3015 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3016 break;
3017 case 6:
3018 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3019 break;
3020 case 7:
3021 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3022 break;
3023 case 8:
3024 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3025 break;
3026 case 9:
3027 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3028 break;
3029 case 10:
3030 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3031 break;
3032 case 11:
3033 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3034 break;
3035 case 12:
3036 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3037 break;
3038 case 13:
3039 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3040 break;
3041 case 14:
3042 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3043 break;
3044 case 16:
3045 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3046 break;
3047 case 17:
3048 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3049 break;
3050 case 18:
3051 /* level 18 is special */
3052 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
3053 break;
3054 case 20:
3055 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3056 break;
3057 case 21:
3058 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
3059 break;
3060 default:
3061 status = NT_STATUS_INVALID_INFO_CLASS;
3062 break;
3065 TALLOC_FREE(pwd);
3067 *r->out.info = user_info;
3069 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3071 return status;
3074 /****************************************************************
3075 ****************************************************************/
3077 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3078 struct samr_QueryUserInfo2 *r)
3080 struct samr_QueryUserInfo u;
3082 u.in.user_handle = r->in.user_handle;
3083 u.in.level = r->in.level;
3084 u.out.info = r->out.info;
3086 return _samr_QueryUserInfo(p, &u);
3089 /*******************************************************************
3090 _samr_GetGroupsForUser
3091 ********************************************************************/
3093 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3094 struct samr_GetGroupsForUser *r)
3096 struct samu *sam_pass=NULL;
3097 DOM_SID sid;
3098 DOM_SID *sids;
3099 struct samr_RidWithAttribute dom_gid;
3100 struct samr_RidWithAttribute *gids = NULL;
3101 uint32 primary_group_rid;
3102 size_t num_groups = 0;
3103 gid_t *unix_gids;
3104 size_t i, num_gids;
3105 uint32 acc_granted;
3106 bool ret;
3107 NTSTATUS result;
3108 bool success = False;
3110 struct samr_RidWithAttributeArray *rids = NULL;
3113 * from the SID in the request:
3114 * we should send back the list of DOMAIN GROUPS
3115 * the user is a member of
3117 * and only the DOMAIN GROUPS
3118 * no ALIASES !!! neither aliases of the domain
3119 * nor aliases of the builtin SID
3121 * JFM, 12/2/2001
3124 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3126 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3127 if (!rids) {
3128 return NT_STATUS_NO_MEMORY;
3131 /* find the policy handle. open a policy on it. */
3132 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
3133 return NT_STATUS_INVALID_HANDLE;
3135 result = access_check_samr_function(acc_granted,
3136 SAMR_USER_ACCESS_GET_GROUPS,
3137 "_samr_GetGroupsForUser");
3138 if (!NT_STATUS_IS_OK(result)) {
3139 return result;
3142 if (!sid_check_is_in_our_domain(&sid))
3143 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3145 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3146 return NT_STATUS_NO_MEMORY;
3149 become_root();
3150 ret = pdb_getsampwsid(sam_pass, &sid);
3151 unbecome_root();
3153 if (!ret) {
3154 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3155 sid_string_dbg(&sid)));
3156 return NT_STATUS_NO_SUCH_USER;
3159 sids = NULL;
3161 /* make both calls inside the root block */
3162 become_root();
3163 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3164 &sids, &unix_gids, &num_groups);
3165 if ( NT_STATUS_IS_OK(result) ) {
3166 success = sid_peek_check_rid(get_global_sam_sid(),
3167 pdb_get_group_sid(sam_pass),
3168 &primary_group_rid);
3170 unbecome_root();
3172 if (!NT_STATUS_IS_OK(result)) {
3173 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3174 sid_string_dbg(&sid)));
3175 return result;
3178 if ( !success ) {
3179 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3180 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3181 pdb_get_username(sam_pass)));
3182 TALLOC_FREE(sam_pass);
3183 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3186 gids = NULL;
3187 num_gids = 0;
3189 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3190 SE_GROUP_ENABLED);
3191 dom_gid.rid = primary_group_rid;
3192 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3194 for (i=0; i<num_groups; i++) {
3196 if (!sid_peek_check_rid(get_global_sam_sid(),
3197 &(sids[i]), &dom_gid.rid)) {
3198 DEBUG(10, ("Found sid %s not in our domain\n",
3199 sid_string_dbg(&sids[i])));
3200 continue;
3203 if (dom_gid.rid == primary_group_rid) {
3204 /* We added the primary group directly from the
3205 * sam_account. The other SIDs are unique from
3206 * enum_group_memberships */
3207 continue;
3210 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3213 rids->count = num_gids;
3214 rids->rids = gids;
3216 *r->out.rids = rids;
3218 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3220 return result;
3223 /*******************************************************************
3224 _samr_QueryDomainInfo
3225 ********************************************************************/
3227 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3228 struct samr_QueryDomainInfo *r)
3230 NTSTATUS status = NT_STATUS_OK;
3231 struct samr_info *info = NULL;
3232 union samr_DomainInfo *dom_info;
3233 time_t u_expire, u_min_age;
3235 time_t u_lock_duration, u_reset_time;
3236 uint32_t u_logout;
3238 uint32 account_policy_temp;
3240 time_t seq_num;
3241 uint32 server_role;
3243 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3245 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3246 if (!dom_info) {
3247 return NT_STATUS_NO_MEMORY;
3250 /* find the policy handle. open a policy on it. */
3251 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
3252 return NT_STATUS_INVALID_HANDLE;
3255 status = access_check_samr_function(info->acc_granted,
3256 SAMR_ACCESS_LOOKUP_DOMAIN,
3257 "_samr_QueryDomainInfo" );
3259 if ( !NT_STATUS_IS_OK(status) )
3260 return status;
3262 switch (r->in.level) {
3263 case 0x01:
3265 become_root();
3267 /* AS ROOT !!! */
3269 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
3270 &account_policy_temp);
3271 dom_info->info1.min_password_length = account_policy_temp;
3273 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
3274 dom_info->info1.password_history_length = account_policy_temp;
3276 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
3277 &dom_info->info1.password_properties);
3279 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
3280 u_expire = account_policy_temp;
3282 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
3283 u_min_age = account_policy_temp;
3285 /* !AS ROOT */
3287 unbecome_root();
3289 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
3290 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
3292 if (lp_check_password_script() && *lp_check_password_script()) {
3293 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
3296 break;
3297 case 0x02:
3299 become_root();
3301 /* AS ROOT !!! */
3303 dom_info->general.num_users = count_sam_users(info->disp_info, ACB_NORMAL);
3304 dom_info->general.num_groups = count_sam_groups(info->disp_info);
3305 dom_info->general.num_aliases = count_sam_aliases(info->disp_info);
3307 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3309 unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
3311 if (!pdb_get_seq_num(&seq_num))
3312 seq_num = time(NULL);
3314 /* !AS ROOT */
3316 unbecome_root();
3318 server_role = ROLE_DOMAIN_PDC;
3319 if (lp_server_role() == ROLE_DOMAIN_BDC)
3320 server_role = ROLE_DOMAIN_BDC;
3322 dom_info->general.oem_information.string = lp_serverstring();
3323 dom_info->general.domain_name.string = lp_workgroup();
3324 dom_info->general.primary.string = global_myname();
3325 dom_info->general.sequence_num = seq_num;
3326 dom_info->general.domain_server_state = DOMAIN_SERVER_ENABLED;
3327 dom_info->general.role = server_role;
3328 dom_info->general.unknown3 = 1;
3330 break;
3331 case 0x03:
3333 become_root();
3335 /* AS ROOT !!! */
3338 uint32 ul;
3339 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3340 u_logout = (time_t)ul;
3343 /* !AS ROOT */
3345 unbecome_root();
3347 unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
3349 break;
3350 case 0x04:
3351 dom_info->oem.oem_information.string = lp_serverstring();
3352 break;
3353 case 0x05:
3354 dom_info->info5.domain_name.string = get_global_sam_name();
3355 break;
3356 case 0x06:
3357 /* NT returns its own name when a PDC. win2k and later
3358 * only the name of the PDC if itself is a BDC (samba4
3359 * idl) */
3360 dom_info->info6.primary.string = global_myname();
3361 break;
3362 case 0x07:
3363 server_role = ROLE_DOMAIN_PDC;
3364 if (lp_server_role() == ROLE_DOMAIN_BDC)
3365 server_role = ROLE_DOMAIN_BDC;
3367 dom_info->info7.role = server_role;
3368 break;
3369 case 0x08:
3371 become_root();
3373 /* AS ROOT !!! */
3375 if (!pdb_get_seq_num(&seq_num)) {
3376 seq_num = time(NULL);
3379 /* !AS ROOT */
3381 unbecome_root();
3383 dom_info->info8.sequence_num = seq_num;
3384 dom_info->info8.domain_create_time = 0;
3386 break;
3387 case 0x09:
3389 dom_info->info9.domain_server_state = DOMAIN_SERVER_ENABLED;
3391 break;
3392 case 0x0b:
3394 /* AS ROOT !!! */
3396 become_root();
3398 dom_info->general2.general.num_users = count_sam_users(
3399 info->disp_info, ACB_NORMAL);
3400 dom_info->general2.general.num_groups = count_sam_groups(
3401 info->disp_info);
3402 dom_info->general2.general.num_aliases = count_sam_aliases(
3403 info->disp_info);
3405 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3407 unix_to_nt_time_abs(&dom_info->general2.general.force_logoff_time, u_logout);
3409 if (!pdb_get_seq_num(&seq_num))
3410 seq_num = time(NULL);
3412 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3413 u_lock_duration = account_policy_temp;
3414 if (u_lock_duration != -1) {
3415 u_lock_duration *= 60;
3418 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3419 u_reset_time = account_policy_temp * 60;
3421 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3422 &account_policy_temp);
3423 dom_info->general2.lockout_threshold = account_policy_temp;
3425 /* !AS ROOT */
3427 unbecome_root();
3429 server_role = ROLE_DOMAIN_PDC;
3430 if (lp_server_role() == ROLE_DOMAIN_BDC)
3431 server_role = ROLE_DOMAIN_BDC;
3433 dom_info->general2.general.oem_information.string = lp_serverstring();
3434 dom_info->general2.general.domain_name.string = lp_workgroup();
3435 dom_info->general2.general.primary.string = global_myname();
3436 dom_info->general2.general.sequence_num = seq_num;
3437 dom_info->general2.general.domain_server_state = DOMAIN_SERVER_ENABLED;
3438 dom_info->general2.general.role = server_role;
3439 dom_info->general2.general.unknown3 = 1;
3441 unix_to_nt_time_abs(&dom_info->general2.lockout_duration,
3442 u_lock_duration);
3443 unix_to_nt_time_abs(&dom_info->general2.lockout_window,
3444 u_reset_time);
3446 break;
3447 case 0x0c:
3449 become_root();
3451 /* AS ROOT !!! */
3453 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3454 u_lock_duration = account_policy_temp;
3455 if (u_lock_duration != -1) {
3456 u_lock_duration *= 60;
3459 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3460 u_reset_time = account_policy_temp * 60;
3462 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3463 &account_policy_temp);
3464 dom_info->info12.lockout_threshold = account_policy_temp;
3466 /* !AS ROOT */
3468 unbecome_root();
3470 unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
3471 u_lock_duration);
3472 unix_to_nt_time_abs(&dom_info->info12.lockout_window,
3473 u_reset_time);
3475 break;
3476 case 0x0d:
3478 become_root();
3480 /* AS ROOT !!! */
3482 if (!pdb_get_seq_num(&seq_num)) {
3483 seq_num = time(NULL);
3486 /* !AS ROOT */
3488 unbecome_root();
3490 dom_info->info13.sequence_num = seq_num;
3491 dom_info->info13.domain_create_time = 0;
3492 dom_info->info13.modified_count_at_last_promotion = 0;
3494 break;
3495 default:
3496 return NT_STATUS_INVALID_INFO_CLASS;
3499 *r->out.info = dom_info;
3501 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3503 return status;
3506 /* W2k3 seems to use the same check for all 3 objects that can be created via
3507 * SAMR, if you try to create for example "Dialup" as an alias it says
3508 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3509 * database. */
3511 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3513 enum lsa_SidType type;
3514 bool result;
3516 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3518 become_root();
3519 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3520 * whether the name already exists */
3521 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3522 NULL, NULL, NULL, &type);
3523 unbecome_root();
3525 if (!result) {
3526 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3527 return NT_STATUS_OK;
3530 DEBUG(5, ("trying to create %s, exists as %s\n",
3531 new_name, sid_type_lookup(type)));
3533 if (type == SID_NAME_DOM_GRP) {
3534 return NT_STATUS_GROUP_EXISTS;
3536 if (type == SID_NAME_ALIAS) {
3537 return NT_STATUS_ALIAS_EXISTS;
3540 /* Yes, the default is NT_STATUS_USER_EXISTS */
3541 return NT_STATUS_USER_EXISTS;
3544 /*******************************************************************
3545 _samr_CreateUser2
3546 ********************************************************************/
3548 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3549 struct samr_CreateUser2 *r)
3551 const char *account = NULL;
3552 DOM_SID sid;
3553 uint32_t acb_info = r->in.acct_flags;
3554 struct samr_info *info = NULL;
3555 NTSTATUS nt_status;
3556 uint32 acc_granted;
3557 SEC_DESC *psd;
3558 size_t sd_size;
3559 /* check this, when giving away 'add computer to domain' privs */
3560 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3561 bool can_add_account = False;
3562 SE_PRIV se_rights;
3563 DISP_INFO *disp_info = NULL;
3565 /* Get the domain SID stored in the domain policy */
3566 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted,
3567 &disp_info))
3568 return NT_STATUS_INVALID_HANDLE;
3570 if (disp_info->builtin_domain) {
3571 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3572 return NT_STATUS_ACCESS_DENIED;
3575 nt_status = access_check_samr_function(acc_granted,
3576 SAMR_DOMAIN_ACCESS_CREATE_USER,
3577 "_samr_CreateUser2");
3578 if (!NT_STATUS_IS_OK(nt_status)) {
3579 return nt_status;
3582 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3583 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3584 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3585 this parameter is not an account type */
3586 return NT_STATUS_INVALID_PARAMETER;
3589 account = r->in.account_name->string;
3590 if (account == NULL) {
3591 return NT_STATUS_NO_MEMORY;
3594 nt_status = can_create(p->mem_ctx, account);
3595 if (!NT_STATUS_IS_OK(nt_status)) {
3596 return nt_status;
3599 /* determine which user right we need to check based on the acb_info */
3601 if ( acb_info & ACB_WSTRUST )
3603 se_priv_copy( &se_rights, &se_machine_account );
3604 can_add_account = user_has_privileges(
3605 p->server_info->ptok, &se_rights );
3607 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3608 account for domain trusts and changes the ACB flags later */
3609 else if ( acb_info & ACB_NORMAL &&
3610 (account[strlen(account)-1] != '$') )
3612 se_priv_copy( &se_rights, &se_add_users );
3613 can_add_account = user_has_privileges(
3614 p->server_info->ptok, &se_rights );
3616 else /* implicit assumption of a BDC or domain trust account here
3617 * (we already check the flags earlier) */
3619 if ( lp_enable_privileges() ) {
3620 /* only Domain Admins can add a BDC or domain trust */
3621 se_priv_copy( &se_rights, &se_priv_none );
3622 can_add_account = nt_token_check_domain_rid(
3623 p->server_info->ptok,
3624 DOMAIN_GROUP_RID_ADMINS );
3628 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3629 uidtoname(p->server_info->utok.uid),
3630 can_add_account ? "True":"False" ));
3632 /********** BEGIN Admin BLOCK **********/
3634 if ( can_add_account )
3635 become_root();
3637 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3638 r->out.rid);
3640 if ( can_add_account )
3641 unbecome_root();
3643 /********** END Admin BLOCK **********/
3645 /* now check for failure */
3647 if ( !NT_STATUS_IS_OK(nt_status) )
3648 return nt_status;
3650 /* Get the user's SID */
3652 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3654 map_max_allowed_access(p->server_info->ptok, &des_access);
3656 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3657 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3658 se_map_generic(&des_access, &usr_generic_mapping);
3660 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3661 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3662 &acc_granted, "_samr_CreateUser2");
3664 if ( !NT_STATUS_IS_OK(nt_status) ) {
3665 return nt_status;
3668 /* associate the user's SID with the new handle. */
3669 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL) {
3670 return NT_STATUS_NO_MEMORY;
3673 ZERO_STRUCTP(info);
3674 info->sid = sid;
3675 info->acc_granted = acc_granted;
3677 /* get a (unique) handle. open a policy on it. */
3678 if (!create_policy_hnd(p, r->out.user_handle, info)) {
3679 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3682 /* After a "set" ensure we have no cached display info. */
3683 force_flush_samr_cache(info->disp_info);
3685 *r->out.access_granted = acc_granted;
3687 return NT_STATUS_OK;
3690 /****************************************************************
3691 ****************************************************************/
3693 NTSTATUS _samr_CreateUser(pipes_struct *p,
3694 struct samr_CreateUser *r)
3696 struct samr_CreateUser2 c;
3697 uint32_t access_granted;
3699 c.in.domain_handle = r->in.domain_handle;
3700 c.in.account_name = r->in.account_name;
3701 c.in.acct_flags = ACB_NORMAL;
3702 c.in.access_mask = r->in.access_mask;
3703 c.out.user_handle = r->out.user_handle;
3704 c.out.access_granted = &access_granted;
3705 c.out.rid = r->out.rid;
3707 return _samr_CreateUser2(p, &c);
3710 /*******************************************************************
3711 _samr_Connect
3712 ********************************************************************/
3714 NTSTATUS _samr_Connect(pipes_struct *p,
3715 struct samr_Connect *r)
3717 struct samr_info *info = NULL;
3718 uint32 des_access = r->in.access_mask;
3720 /* Access check */
3722 if (!pipe_access_check(p)) {
3723 DEBUG(3, ("access denied to _samr_Connect\n"));
3724 return NT_STATUS_ACCESS_DENIED;
3727 /* set up the SAMR connect_anon response */
3729 /* associate the user's SID with the new handle. */
3730 if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
3731 return NT_STATUS_NO_MEMORY;
3733 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3734 was observed from a win98 client trying to enumerate users (when configured
3735 user level access control on shares) --jerry */
3737 map_max_allowed_access(p->server_info->ptok, &des_access);
3739 se_map_generic( &des_access, &sam_generic_mapping );
3740 info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_LOOKUP_DOMAIN);
3742 /* get a (unique) handle. open a policy on it. */
3743 if (!create_policy_hnd(p, r->out.connect_handle, info))
3744 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3746 return NT_STATUS_OK;
3749 /*******************************************************************
3750 _samr_Connect2
3751 ********************************************************************/
3753 NTSTATUS _samr_Connect2(pipes_struct *p,
3754 struct samr_Connect2 *r)
3756 struct samr_info *info = NULL;
3757 SEC_DESC *psd = NULL;
3758 uint32 acc_granted;
3759 uint32 des_access = r->in.access_mask;
3760 NTSTATUS nt_status;
3761 size_t sd_size;
3762 const char *fn = "_samr_Connect2";
3764 switch (p->hdr_req.opnum) {
3765 case NDR_SAMR_CONNECT2:
3766 fn = "_samr_Connect2";
3767 break;
3768 case NDR_SAMR_CONNECT3:
3769 fn = "_samr_Connect3";
3770 break;
3771 case NDR_SAMR_CONNECT4:
3772 fn = "_samr_Connect4";
3773 break;
3774 case NDR_SAMR_CONNECT5:
3775 fn = "_samr_Connect5";
3776 break;
3779 DEBUG(5,("%s: %d\n", fn, __LINE__));
3781 /* Access check */
3783 if (!pipe_access_check(p)) {
3784 DEBUG(3, ("access denied to %s\n", fn));
3785 return NT_STATUS_ACCESS_DENIED;
3788 map_max_allowed_access(p->server_info->ptok, &des_access);
3790 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3791 se_map_generic(&des_access, &sam_generic_mapping);
3793 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3794 NULL, 0, des_access, &acc_granted, fn);
3796 if ( !NT_STATUS_IS_OK(nt_status) )
3797 return nt_status;
3799 /* associate the user's SID and access granted with the new handle. */
3800 if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
3801 return NT_STATUS_NO_MEMORY;
3803 info->acc_granted = acc_granted;
3804 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3806 /* get a (unique) handle. open a policy on it. */
3807 if (!create_policy_hnd(p, r->out.connect_handle, info))
3808 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3810 DEBUG(5,("%s: %d\n", fn, __LINE__));
3812 return nt_status;
3815 /****************************************************************
3816 _samr_Connect3
3817 ****************************************************************/
3819 NTSTATUS _samr_Connect3(pipes_struct *p,
3820 struct samr_Connect3 *r)
3822 struct samr_Connect2 c;
3824 c.in.system_name = r->in.system_name;
3825 c.in.access_mask = r->in.access_mask;
3826 c.out.connect_handle = r->out.connect_handle;
3828 return _samr_Connect2(p, &c);
3831 /*******************************************************************
3832 _samr_Connect4
3833 ********************************************************************/
3835 NTSTATUS _samr_Connect4(pipes_struct *p,
3836 struct samr_Connect4 *r)
3838 struct samr_Connect2 c;
3840 c.in.system_name = r->in.system_name;
3841 c.in.access_mask = r->in.access_mask;
3842 c.out.connect_handle = r->out.connect_handle;
3844 return _samr_Connect2(p, &c);
3847 /*******************************************************************
3848 _samr_Connect5
3849 ********************************************************************/
3851 NTSTATUS _samr_Connect5(pipes_struct *p,
3852 struct samr_Connect5 *r)
3854 NTSTATUS status;
3855 struct samr_Connect2 c;
3856 struct samr_ConnectInfo1 info1;
3858 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3859 info1.unknown2 = 0;
3861 c.in.system_name = r->in.system_name;
3862 c.in.access_mask = r->in.access_mask;
3863 c.out.connect_handle = r->out.connect_handle;
3865 *r->out.level_out = 1;
3867 status = _samr_Connect2(p, &c);
3868 if (!NT_STATUS_IS_OK(status)) {
3869 return status;
3872 r->out.info_out->info1 = info1;
3874 return NT_STATUS_OK;
3877 /**********************************************************************
3878 _samr_LookupDomain
3879 **********************************************************************/
3881 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3882 struct samr_LookupDomain *r)
3884 NTSTATUS status = NT_STATUS_OK;
3885 struct samr_info *info;
3886 const char *domain_name;
3887 DOM_SID *sid = NULL;
3889 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3890 return NT_STATUS_INVALID_HANDLE;
3892 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3893 Reverted that change so we will work with RAS servers again */
3895 status = access_check_samr_function(info->acc_granted,
3896 SAMR_ACCESS_LOOKUP_DOMAIN,
3897 "_samr_LookupDomain");
3898 if (!NT_STATUS_IS_OK(status)) {
3899 return status;
3902 domain_name = r->in.domain_name->string;
3903 if (!domain_name) {
3904 return NT_STATUS_INVALID_PARAMETER;
3907 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3908 if (!sid) {
3909 return NT_STATUS_NO_MEMORY;
3912 if (strequal(domain_name, builtin_domain_name())) {
3913 sid_copy(sid, &global_sid_Builtin);
3914 } else {
3915 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3916 status = NT_STATUS_NO_SUCH_DOMAIN;
3920 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3921 sid_string_dbg(sid)));
3923 *r->out.sid = sid;
3925 return status;
3928 /**********************************************************************
3929 _samr_EnumDomains
3930 **********************************************************************/
3932 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3933 struct samr_EnumDomains *r)
3935 NTSTATUS status;
3936 struct samr_info *info;
3937 uint32_t num_entries = 2;
3938 struct samr_SamEntry *entry_array = NULL;
3939 struct samr_SamArray *sam;
3941 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3942 return NT_STATUS_INVALID_HANDLE;
3944 status = access_check_samr_function(info->acc_granted,
3945 SAMR_ACCESS_ENUM_DOMAINS,
3946 "_samr_EnumDomains");
3947 if (!NT_STATUS_IS_OK(status)) {
3948 return status;
3951 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3952 if (!sam) {
3953 return NT_STATUS_NO_MEMORY;
3956 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3957 struct samr_SamEntry,
3958 num_entries);
3959 if (!entry_array) {
3960 return NT_STATUS_NO_MEMORY;
3963 entry_array[0].idx = 0;
3964 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3966 entry_array[1].idx = 1;
3967 init_lsa_String(&entry_array[1].name, "Builtin");
3969 sam->count = num_entries;
3970 sam->entries = entry_array;
3972 *r->out.sam = sam;
3973 *r->out.num_entries = num_entries;
3975 return status;
3978 /*******************************************************************
3979 _samr_OpenAlias
3980 ********************************************************************/
3982 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3983 struct samr_OpenAlias *r)
3985 DOM_SID sid;
3986 uint32 alias_rid = r->in.rid;
3987 struct samr_info *info = NULL;
3988 SEC_DESC *psd = NULL;
3989 uint32 acc_granted;
3990 uint32 des_access = r->in.access_mask;
3991 size_t sd_size;
3992 NTSTATUS status;
3993 SE_PRIV se_rights;
3995 /* find the domain policy and get the SID / access bits stored in the domain policy */
3997 if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
3998 return NT_STATUS_INVALID_HANDLE;
4000 status = access_check_samr_function(acc_granted,
4001 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4002 "_samr_OpenAlias");
4004 if ( !NT_STATUS_IS_OK(status) )
4005 return status;
4007 /* append the alias' RID to it */
4009 if (!sid_append_rid(&sid, alias_rid))
4010 return NT_STATUS_NO_SUCH_ALIAS;
4012 /*check if access can be granted as requested by client. */
4014 map_max_allowed_access(p->server_info->ptok, &des_access);
4016 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4017 se_map_generic(&des_access,&ali_generic_mapping);
4019 se_priv_copy( &se_rights, &se_add_users );
4022 status = access_check_samr_object(psd, p->server_info->ptok,
4023 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
4024 &acc_granted, "_samr_OpenAlias");
4026 if ( !NT_STATUS_IS_OK(status) )
4027 return status;
4030 /* Check we actually have the requested alias */
4031 enum lsa_SidType type;
4032 bool result;
4033 gid_t gid;
4035 become_root();
4036 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4037 unbecome_root();
4039 if (!result || (type != SID_NAME_ALIAS)) {
4040 return NT_STATUS_NO_SUCH_ALIAS;
4043 /* make sure there is a mapping */
4045 if ( !sid_to_gid( &sid, &gid ) ) {
4046 return NT_STATUS_NO_SUCH_ALIAS;
4051 /* associate the alias SID with the new handle. */
4052 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
4053 return NT_STATUS_NO_MEMORY;
4055 info->acc_granted = acc_granted;
4057 /* get a (unique) handle. open a policy on it. */
4058 if (!create_policy_hnd(p, r->out.alias_handle, info))
4059 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4061 return NT_STATUS_OK;
4064 /*******************************************************************
4065 set_user_info_2
4066 ********************************************************************/
4068 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4069 struct samr_UserInfo2 *id2,
4070 struct samu *pwd)
4072 if (id2 == NULL) {
4073 DEBUG(5,("set_user_info_2: NULL id2\n"));
4074 return NT_STATUS_ACCESS_DENIED;
4077 copy_id2_to_sam_passwd(pwd, id2);
4079 return pdb_update_sam_account(pwd);
4082 /*******************************************************************
4083 set_user_info_4
4084 ********************************************************************/
4086 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4087 struct samr_UserInfo4 *id4,
4088 struct samu *pwd)
4090 if (id4 == NULL) {
4091 DEBUG(5,("set_user_info_2: NULL id4\n"));
4092 return NT_STATUS_ACCESS_DENIED;
4095 copy_id4_to_sam_passwd(pwd, id4);
4097 return pdb_update_sam_account(pwd);
4100 /*******************************************************************
4101 set_user_info_6
4102 ********************************************************************/
4104 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4105 struct samr_UserInfo6 *id6,
4106 struct samu *pwd)
4108 if (id6 == NULL) {
4109 DEBUG(5,("set_user_info_6: NULL id6\n"));
4110 return NT_STATUS_ACCESS_DENIED;
4113 copy_id6_to_sam_passwd(pwd, id6);
4115 return pdb_update_sam_account(pwd);
4118 /*******************************************************************
4119 set_user_info_7
4120 ********************************************************************/
4122 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4123 struct samr_UserInfo7 *id7,
4124 struct samu *pwd)
4126 NTSTATUS rc;
4128 if (id7 == NULL) {
4129 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4130 return NT_STATUS_ACCESS_DENIED;
4133 if (!id7->account_name.string) {
4134 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4135 return NT_STATUS_ACCESS_DENIED;
4138 /* check to see if the new username already exists. Note: we can't
4139 reliably lock all backends, so there is potentially the
4140 possibility that a user can be created in between this check and
4141 the rename. The rename should fail, but may not get the
4142 exact same failure status code. I think this is small enough
4143 of a window for this type of operation and the results are
4144 simply that the rename fails with a slightly different status
4145 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4147 rc = can_create(mem_ctx, id7->account_name.string);
4149 /* when there is nothing to change, we're done here */
4150 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4151 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4152 return NT_STATUS_OK;
4154 if (!NT_STATUS_IS_OK(rc)) {
4155 return rc;
4158 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4160 return rc;
4163 /*******************************************************************
4164 set_user_info_8
4165 ********************************************************************/
4167 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4168 struct samr_UserInfo8 *id8,
4169 struct samu *pwd)
4171 if (id8 == NULL) {
4172 DEBUG(5,("set_user_info_8: NULL id8\n"));
4173 return NT_STATUS_ACCESS_DENIED;
4176 copy_id8_to_sam_passwd(pwd, id8);
4178 return pdb_update_sam_account(pwd);
4181 /*******************************************************************
4182 set_user_info_10
4183 ********************************************************************/
4185 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4186 struct samr_UserInfo10 *id10,
4187 struct samu *pwd)
4189 if (id10 == NULL) {
4190 DEBUG(5,("set_user_info_8: NULL id10\n"));
4191 return NT_STATUS_ACCESS_DENIED;
4194 copy_id10_to_sam_passwd(pwd, id10);
4196 return pdb_update_sam_account(pwd);
4199 /*******************************************************************
4200 set_user_info_11
4201 ********************************************************************/
4203 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4204 struct samr_UserInfo11 *id11,
4205 struct samu *pwd)
4207 if (id11 == NULL) {
4208 DEBUG(5,("set_user_info_11: NULL id11\n"));
4209 return NT_STATUS_ACCESS_DENIED;
4212 copy_id11_to_sam_passwd(pwd, id11);
4214 return pdb_update_sam_account(pwd);
4217 /*******************************************************************
4218 set_user_info_12
4219 ********************************************************************/
4221 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4222 struct samr_UserInfo12 *id12,
4223 struct samu *pwd)
4225 if (id12 == NULL) {
4226 DEBUG(5,("set_user_info_12: NULL id12\n"));
4227 return NT_STATUS_ACCESS_DENIED;
4230 copy_id12_to_sam_passwd(pwd, id12);
4232 return pdb_update_sam_account(pwd);
4235 /*******************************************************************
4236 set_user_info_13
4237 ********************************************************************/
4239 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4240 struct samr_UserInfo13 *id13,
4241 struct samu *pwd)
4243 if (id13 == NULL) {
4244 DEBUG(5,("set_user_info_13: NULL id13\n"));
4245 return NT_STATUS_ACCESS_DENIED;
4248 copy_id13_to_sam_passwd(pwd, id13);
4250 return pdb_update_sam_account(pwd);
4253 /*******************************************************************
4254 set_user_info_14
4255 ********************************************************************/
4257 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4258 struct samr_UserInfo14 *id14,
4259 struct samu *pwd)
4261 if (id14 == NULL) {
4262 DEBUG(5,("set_user_info_14: NULL id14\n"));
4263 return NT_STATUS_ACCESS_DENIED;
4266 copy_id14_to_sam_passwd(pwd, id14);
4268 return pdb_update_sam_account(pwd);
4271 /*******************************************************************
4272 set_user_info_16
4273 ********************************************************************/
4275 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4276 struct samr_UserInfo16 *id16,
4277 struct samu *pwd)
4279 if (id16 == NULL) {
4280 DEBUG(5,("set_user_info_16: NULL id16\n"));
4281 return NT_STATUS_ACCESS_DENIED;
4284 copy_id16_to_sam_passwd(pwd, id16);
4286 return pdb_update_sam_account(pwd);
4289 /*******************************************************************
4290 set_user_info_17
4291 ********************************************************************/
4293 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4294 struct samr_UserInfo17 *id17,
4295 struct samu *pwd)
4297 if (id17 == NULL) {
4298 DEBUG(5,("set_user_info_17: NULL id17\n"));
4299 return NT_STATUS_ACCESS_DENIED;
4302 copy_id17_to_sam_passwd(pwd, id17);
4304 return pdb_update_sam_account(pwd);
4307 /*******************************************************************
4308 set_user_info_18
4309 ********************************************************************/
4311 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4312 TALLOC_CTX *mem_ctx,
4313 DATA_BLOB *session_key,
4314 struct samu *pwd)
4316 if (id18 == NULL) {
4317 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4318 return NT_STATUS_INVALID_PARAMETER;
4321 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4322 if (!session_key->length) {
4323 return NT_STATUS_NO_USER_SESSION_KEY;
4327 if (id18->nt_pwd_active) {
4329 DATA_BLOB in, out;
4331 in = data_blob_const(id18->nt_pwd.hash, 16);
4332 out = data_blob_talloc_zero(mem_ctx, 16);
4334 sess_crypt_blob(&out, &in, session_key, false);
4336 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4337 return NT_STATUS_ACCESS_DENIED;
4340 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4343 if (id18->lm_pwd_active) {
4345 DATA_BLOB in, out;
4347 in = data_blob_const(id18->lm_pwd.hash, 16);
4348 out = data_blob_talloc_zero(mem_ctx, 16);
4350 sess_crypt_blob(&out, &in, session_key, false);
4352 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4353 return NT_STATUS_ACCESS_DENIED;
4356 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4359 copy_id18_to_sam_passwd(pwd, id18);
4361 return pdb_update_sam_account(pwd);
4364 /*******************************************************************
4365 set_user_info_20
4366 ********************************************************************/
4368 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4369 struct samr_UserInfo20 *id20,
4370 struct samu *pwd)
4372 if (id20 == NULL) {
4373 DEBUG(5,("set_user_info_20: NULL id20\n"));
4374 return NT_STATUS_ACCESS_DENIED;
4377 copy_id20_to_sam_passwd(pwd, id20);
4379 return pdb_update_sam_account(pwd);
4382 /*******************************************************************
4383 set_user_info_21
4384 ********************************************************************/
4386 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4387 TALLOC_CTX *mem_ctx,
4388 DATA_BLOB *session_key,
4389 struct samu *pwd)
4391 NTSTATUS status;
4393 if (id21 == NULL) {
4394 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4395 return NT_STATUS_INVALID_PARAMETER;
4398 if (id21->fields_present == 0) {
4399 return NT_STATUS_INVALID_PARAMETER;
4402 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4403 return NT_STATUS_ACCESS_DENIED;
4406 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4407 if (id21->nt_password_set) {
4408 DATA_BLOB in, out;
4410 if ((id21->nt_owf_password.length != 16) ||
4411 (id21->nt_owf_password.size != 16)) {
4412 return NT_STATUS_INVALID_PARAMETER;
4415 if (!session_key->length) {
4416 return NT_STATUS_NO_USER_SESSION_KEY;
4419 in = data_blob_const(id21->nt_owf_password.array, 16);
4420 out = data_blob_talloc_zero(mem_ctx, 16);
4422 sess_crypt_blob(&out, &in, session_key, false);
4424 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4425 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4429 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4430 if (id21->lm_password_set) {
4431 DATA_BLOB in, out;
4433 if ((id21->lm_owf_password.length != 16) ||
4434 (id21->lm_owf_password.size != 16)) {
4435 return NT_STATUS_INVALID_PARAMETER;
4438 if (!session_key->length) {
4439 return NT_STATUS_NO_USER_SESSION_KEY;
4442 in = data_blob_const(id21->lm_owf_password.array, 16);
4443 out = data_blob_talloc_zero(mem_ctx, 16);
4445 sess_crypt_blob(&out, &in, session_key, false);
4447 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4448 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4452 /* we need to separately check for an account rename first */
4454 if (id21->account_name.string &&
4455 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4458 /* check to see if the new username already exists. Note: we can't
4459 reliably lock all backends, so there is potentially the
4460 possibility that a user can be created in between this check and
4461 the rename. The rename should fail, but may not get the
4462 exact same failure status code. I think this is small enough
4463 of a window for this type of operation and the results are
4464 simply that the rename fails with a slightly different status
4465 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4467 status = can_create(mem_ctx, id21->account_name.string);
4468 if (!NT_STATUS_IS_OK(status)) {
4469 return status;
4472 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4474 if (!NT_STATUS_IS_OK(status)) {
4475 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4476 nt_errstr(status)));
4477 return status;
4480 /* set the new username so that later
4481 functions can work on the new account */
4482 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4485 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4488 * The funny part about the previous two calls is
4489 * that pwd still has the password hashes from the
4490 * passdb entry. These have not been updated from
4491 * id21. I don't know if they need to be set. --jerry
4494 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4495 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4496 if ( !NT_STATUS_IS_OK(status) ) {
4497 return status;
4501 /* Don't worry about writing out the user account since the
4502 primary group SID is generated solely from the user's Unix
4503 primary group. */
4505 /* write the change out */
4506 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4507 return status;
4510 return NT_STATUS_OK;
4513 /*******************************************************************
4514 set_user_info_23
4515 ********************************************************************/
4517 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4518 struct samr_UserInfo23 *id23,
4519 struct samu *pwd)
4521 char *plaintext_buf = NULL;
4522 uint32 len = 0;
4523 uint32_t acct_ctrl;
4524 NTSTATUS status;
4526 if (id23 == NULL) {
4527 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4528 return NT_STATUS_INVALID_PARAMETER;
4531 if (id23->info.fields_present == 0) {
4532 return NT_STATUS_INVALID_PARAMETER;
4535 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4536 return NT_STATUS_ACCESS_DENIED;
4539 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4540 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4542 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4543 pdb_get_username(pwd)));
4545 if (!decode_pw_buffer(mem_ctx,
4546 id23->password.data,
4547 &plaintext_buf,
4548 &len,
4549 STR_UNICODE)) {
4550 return NT_STATUS_WRONG_PASSWORD;
4553 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4554 return NT_STATUS_ACCESS_DENIED;
4558 copy_id23_to_sam_passwd(pwd, id23);
4560 acct_ctrl = pdb_get_acct_ctrl(pwd);
4562 /* if it's a trust account, don't update /etc/passwd */
4563 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4564 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4565 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4566 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4567 } else if (plaintext_buf) {
4568 /* update the UNIX password */
4569 if (lp_unix_password_sync() ) {
4570 struct passwd *passwd;
4571 if (pdb_get_username(pwd) == NULL) {
4572 DEBUG(1, ("chgpasswd: User without name???\n"));
4573 return NT_STATUS_ACCESS_DENIED;
4576 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4577 if (passwd == NULL) {
4578 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4581 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4582 return NT_STATUS_ACCESS_DENIED;
4584 TALLOC_FREE(passwd);
4588 if (plaintext_buf) {
4589 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4592 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4593 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4594 pwd)))) {
4595 return status;
4598 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4599 return status;
4602 return NT_STATUS_OK;
4605 /*******************************************************************
4606 set_user_info_pw
4607 ********************************************************************/
4609 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4611 uint32 len = 0;
4612 char *plaintext_buf = NULL;
4613 uint32 acct_ctrl;
4615 DEBUG(5, ("Attempting administrator password change for user %s\n",
4616 pdb_get_username(pwd)));
4618 acct_ctrl = pdb_get_acct_ctrl(pwd);
4620 if (!decode_pw_buffer(talloc_tos(),
4621 pass,
4622 &plaintext_buf,
4623 &len,
4624 STR_UNICODE)) {
4625 return False;
4628 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4629 return False;
4632 /* if it's a trust account, don't update /etc/passwd */
4633 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4634 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4635 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4636 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4637 } else {
4638 /* update the UNIX password */
4639 if (lp_unix_password_sync()) {
4640 struct passwd *passwd;
4642 if (pdb_get_username(pwd) == NULL) {
4643 DEBUG(1, ("chgpasswd: User without name???\n"));
4644 return False;
4647 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4648 if (passwd == NULL) {
4649 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4652 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4653 return False;
4655 TALLOC_FREE(passwd);
4659 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4661 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4663 return True;
4666 /*******************************************************************
4667 set_user_info_24
4668 ********************************************************************/
4670 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4671 struct samr_UserInfo24 *id24,
4672 struct samu *pwd)
4674 NTSTATUS status;
4676 if (id24 == NULL) {
4677 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4678 return NT_STATUS_INVALID_PARAMETER;
4681 if (!set_user_info_pw(id24->password.data, pwd)) {
4682 return NT_STATUS_WRONG_PASSWORD;
4685 copy_id24_to_sam_passwd(pwd, id24);
4687 status = pdb_update_sam_account(pwd);
4688 if (!NT_STATUS_IS_OK(status)) {
4689 return status;
4692 return NT_STATUS_OK;
4695 /*******************************************************************
4696 set_user_info_25
4697 ********************************************************************/
4699 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4700 struct samr_UserInfo25 *id25,
4701 struct samu *pwd)
4703 NTSTATUS status;
4705 if (id25 == NULL) {
4706 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4707 return NT_STATUS_INVALID_PARAMETER;
4710 if (id25->info.fields_present == 0) {
4711 return NT_STATUS_INVALID_PARAMETER;
4714 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4715 return NT_STATUS_ACCESS_DENIED;
4718 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4719 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4721 if (!set_user_info_pw(id25->password.data, pwd)) {
4722 return NT_STATUS_WRONG_PASSWORD;
4726 copy_id25_to_sam_passwd(pwd, id25);
4728 /* write the change out */
4729 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4730 return status;
4734 * We need to "pdb_update_sam_account" before the unix primary group
4735 * is set, because the idealx scripts would also change the
4736 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4737 * the delete explicit / add explicit, which would then fail to find
4738 * the previous primaryGroupSid value.
4741 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4742 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4743 if ( !NT_STATUS_IS_OK(status) ) {
4744 return status;
4748 return NT_STATUS_OK;
4751 /*******************************************************************
4752 set_user_info_26
4753 ********************************************************************/
4755 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4756 struct samr_UserInfo26 *id26,
4757 struct samu *pwd)
4759 NTSTATUS status;
4761 if (id26 == NULL) {
4762 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4763 return NT_STATUS_INVALID_PARAMETER;
4766 if (!set_user_info_pw(id26->password.data, pwd)) {
4767 return NT_STATUS_WRONG_PASSWORD;
4770 copy_id26_to_sam_passwd(pwd, id26);
4772 status = pdb_update_sam_account(pwd);
4773 if (!NT_STATUS_IS_OK(status)) {
4774 return status;
4777 return NT_STATUS_OK;
4781 /*******************************************************************
4782 samr_SetUserInfo
4783 ********************************************************************/
4785 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4786 struct samr_SetUserInfo *r)
4788 NTSTATUS status;
4789 struct samu *pwd = NULL;
4790 DOM_SID sid;
4791 union samr_UserInfo *info = r->in.info;
4792 uint16_t switch_value = r->in.level;
4793 uint32_t acc_granted;
4794 uint32_t acc_required;
4795 bool ret;
4796 bool has_enough_rights = False;
4797 uint32_t acb_info;
4798 DISP_INFO *disp_info = NULL;
4800 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4802 /* find the policy handle. open a policy on it. */
4803 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) {
4804 return NT_STATUS_INVALID_HANDLE;
4807 /* This is tricky. A WinXP domain join sets
4808 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4809 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4810 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4811 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4812 we'll use the set from the WinXP join as the basis. */
4814 switch (switch_value) {
4815 case 7:
4816 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
4817 break;
4818 case 18:
4819 case 24:
4820 case 25:
4821 case 26:
4822 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4823 break;
4824 default:
4825 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4826 SAMR_USER_ACCESS_SET_ATTRIBUTES |
4827 SAMR_USER_ACCESS_GET_ATTRIBUTES;
4828 break;
4831 status = access_check_samr_function(acc_granted,
4832 acc_required,
4833 "_samr_SetUserInfo");
4834 if (!NT_STATUS_IS_OK(status)) {
4835 return status;
4838 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4839 sid_string_dbg(&sid), switch_value));
4841 if (info == NULL) {
4842 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4843 return NT_STATUS_INVALID_INFO_CLASS;
4846 if (!(pwd = samu_new(NULL))) {
4847 return NT_STATUS_NO_MEMORY;
4850 become_root();
4851 ret = pdb_getsampwsid(pwd, &sid);
4852 unbecome_root();
4854 if (!ret) {
4855 TALLOC_FREE(pwd);
4856 return NT_STATUS_NO_SUCH_USER;
4859 /* deal with machine password changes differently from userinfo changes */
4860 /* check to see if we have the sufficient rights */
4862 acb_info = pdb_get_acct_ctrl(pwd);
4863 if (acb_info & ACB_WSTRUST)
4864 has_enough_rights = user_has_privileges(p->server_info->ptok,
4865 &se_machine_account);
4866 else if (acb_info & ACB_NORMAL)
4867 has_enough_rights = user_has_privileges(p->server_info->ptok,
4868 &se_add_users);
4869 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4870 if (lp_enable_privileges()) {
4871 has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
4872 DOMAIN_GROUP_RID_ADMINS);
4876 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4877 uidtoname(p->server_info->utok.uid),
4878 has_enough_rights ? "" : " not"));
4880 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4882 if (has_enough_rights) {
4883 become_root();
4886 /* ok! user info levels (lots: see MSDEV help), off we go... */
4888 switch (switch_value) {
4890 case 2:
4891 status = set_user_info_2(p->mem_ctx,
4892 &info->info2, pwd);
4893 break;
4895 case 4:
4896 status = set_user_info_4(p->mem_ctx,
4897 &info->info4, pwd);
4898 break;
4900 case 6:
4901 status = set_user_info_6(p->mem_ctx,
4902 &info->info6, pwd);
4903 break;
4905 case 7:
4906 status = set_user_info_7(p->mem_ctx,
4907 &info->info7, pwd);
4908 break;
4910 case 8:
4911 status = set_user_info_8(p->mem_ctx,
4912 &info->info8, pwd);
4913 break;
4915 case 10:
4916 status = set_user_info_10(p->mem_ctx,
4917 &info->info10, pwd);
4918 break;
4920 case 11:
4921 status = set_user_info_11(p->mem_ctx,
4922 &info->info11, pwd);
4923 break;
4925 case 12:
4926 status = set_user_info_12(p->mem_ctx,
4927 &info->info12, pwd);
4928 break;
4930 case 13:
4931 status = set_user_info_13(p->mem_ctx,
4932 &info->info13, pwd);
4933 break;
4935 case 14:
4936 status = set_user_info_14(p->mem_ctx,
4937 &info->info14, pwd);
4938 break;
4940 case 16:
4941 status = set_user_info_16(p->mem_ctx,
4942 &info->info16, pwd);
4943 break;
4945 case 17:
4946 status = set_user_info_17(p->mem_ctx,
4947 &info->info17, pwd);
4948 break;
4950 case 18:
4951 /* Used by AS/U JRA. */
4952 status = set_user_info_18(&info->info18,
4953 p->mem_ctx,
4954 &p->server_info->user_session_key,
4955 pwd);
4956 break;
4958 case 20:
4959 status = set_user_info_20(p->mem_ctx,
4960 &info->info20, pwd);
4961 break;
4963 case 21:
4964 status = set_user_info_21(&info->info21,
4965 p->mem_ctx,
4966 &p->server_info->user_session_key,
4967 pwd);
4968 break;
4970 case 23:
4971 if (!p->server_info->user_session_key.length) {
4972 status = NT_STATUS_NO_USER_SESSION_KEY;
4974 SamOEMhashBlob(info->info23.password.data, 516,
4975 &p->server_info->user_session_key);
4977 dump_data(100, info->info23.password.data, 516);
4979 status = set_user_info_23(p->mem_ctx,
4980 &info->info23, pwd);
4981 break;
4983 case 24:
4984 if (!p->server_info->user_session_key.length) {
4985 status = NT_STATUS_NO_USER_SESSION_KEY;
4987 SamOEMhashBlob(info->info24.password.data,
4988 516,
4989 &p->server_info->user_session_key);
4991 dump_data(100, info->info24.password.data, 516);
4993 status = set_user_info_24(p->mem_ctx,
4994 &info->info24, pwd);
4995 break;
4997 case 25:
4998 if (!p->server_info->user_session_key.length) {
4999 status = NT_STATUS_NO_USER_SESSION_KEY;
5001 encode_or_decode_arc4_passwd_buffer(
5002 info->info25.password.data,
5003 &p->server_info->user_session_key);
5005 dump_data(100, info->info25.password.data, 532);
5007 status = set_user_info_25(p->mem_ctx,
5008 &info->info25, pwd);
5009 break;
5011 case 26:
5012 if (!p->server_info->user_session_key.length) {
5013 status = NT_STATUS_NO_USER_SESSION_KEY;
5015 encode_or_decode_arc4_passwd_buffer(
5016 info->info26.password.data,
5017 &p->server_info->user_session_key);
5019 dump_data(100, info->info26.password.data, 516);
5021 status = set_user_info_26(p->mem_ctx,
5022 &info->info26, pwd);
5023 break;
5025 default:
5026 status = NT_STATUS_INVALID_INFO_CLASS;
5029 TALLOC_FREE(pwd);
5031 if (has_enough_rights) {
5032 unbecome_root();
5035 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
5037 if (NT_STATUS_IS_OK(status)) {
5038 force_flush_samr_cache(disp_info);
5041 return status;
5044 /*******************************************************************
5045 _samr_SetUserInfo2
5046 ********************************************************************/
5048 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
5049 struct samr_SetUserInfo2 *r)
5051 struct samr_SetUserInfo q;
5053 q.in.user_handle = r->in.user_handle;
5054 q.in.level = r->in.level;
5055 q.in.info = r->in.info;
5057 return _samr_SetUserInfo(p, &q);
5060 /*********************************************************************
5061 _samr_GetAliasMembership
5062 *********************************************************************/
5064 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
5065 struct samr_GetAliasMembership *r)
5067 size_t num_alias_rids;
5068 uint32 *alias_rids;
5069 struct samr_info *info = NULL;
5070 size_t i;
5072 NTSTATUS ntstatus1;
5073 NTSTATUS ntstatus2;
5075 DOM_SID *members;
5077 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5079 /* find the policy handle. open a policy on it. */
5080 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5081 return NT_STATUS_INVALID_HANDLE;
5083 ntstatus1 = access_check_samr_function(info->acc_granted,
5084 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
5085 "_samr_GetAliasMembership");
5086 ntstatus2 = access_check_samr_function(info->acc_granted,
5087 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
5088 "_samr_GetAliasMembership");
5090 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
5091 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
5092 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
5093 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
5097 if (!sid_check_is_domain(&info->sid) &&
5098 !sid_check_is_builtin(&info->sid))
5099 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5101 if (r->in.sids->num_sids) {
5102 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
5104 if (members == NULL)
5105 return NT_STATUS_NO_MEMORY;
5106 } else {
5107 members = NULL;
5110 for (i=0; i<r->in.sids->num_sids; i++)
5111 sid_copy(&members[i], r->in.sids->sids[i].sid);
5113 alias_rids = NULL;
5114 num_alias_rids = 0;
5116 become_root();
5117 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
5118 r->in.sids->num_sids,
5119 &alias_rids, &num_alias_rids);
5120 unbecome_root();
5122 if (!NT_STATUS_IS_OK(ntstatus1)) {
5123 return ntstatus1;
5126 r->out.rids->count = num_alias_rids;
5127 r->out.rids->ids = alias_rids;
5129 return NT_STATUS_OK;
5132 /*********************************************************************
5133 _samr_GetMembersInAlias
5134 *********************************************************************/
5136 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5137 struct samr_GetMembersInAlias *r)
5139 NTSTATUS status;
5140 size_t i;
5141 size_t num_sids = 0;
5142 struct lsa_SidPtr *sids = NULL;
5143 DOM_SID *pdb_sids = NULL;
5145 DOM_SID alias_sid;
5147 uint32 acc_granted;
5149 /* find the policy handle. open a policy on it. */
5150 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
5151 return NT_STATUS_INVALID_HANDLE;
5153 status = access_check_samr_function(acc_granted,
5154 SAMR_ALIAS_ACCESS_GET_MEMBERS,
5155 "_samr_GetMembersInAlias");
5156 if (!NT_STATUS_IS_OK(status)) {
5157 return status;
5160 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5162 become_root();
5163 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
5164 unbecome_root();
5166 if (!NT_STATUS_IS_OK(status)) {
5167 return status;
5170 if (num_sids) {
5171 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5172 if (sids == NULL) {
5173 TALLOC_FREE(pdb_sids);
5174 return NT_STATUS_NO_MEMORY;
5178 for (i = 0; i < num_sids; i++) {
5179 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5180 if (!sids[i].sid) {
5181 TALLOC_FREE(pdb_sids);
5182 return NT_STATUS_NO_MEMORY;
5186 r->out.sids->num_sids = num_sids;
5187 r->out.sids->sids = sids;
5189 TALLOC_FREE(pdb_sids);
5191 return NT_STATUS_OK;
5194 /*********************************************************************
5195 _samr_QueryGroupMember
5196 *********************************************************************/
5198 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5199 struct samr_QueryGroupMember *r)
5201 DOM_SID group_sid;
5202 size_t i, num_members;
5204 uint32 *rid=NULL;
5205 uint32 *attr=NULL;
5207 uint32 acc_granted;
5209 NTSTATUS status;
5210 struct samr_RidTypeArray *rids = NULL;
5212 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5213 if (!rids) {
5214 return NT_STATUS_NO_MEMORY;
5217 /* find the policy handle. open a policy on it. */
5218 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5219 return NT_STATUS_INVALID_HANDLE;
5221 status = access_check_samr_function(acc_granted,
5222 SAMR_GROUP_ACCESS_GET_MEMBERS,
5223 "_samr_QueryGroupMember");
5224 if (!NT_STATUS_IS_OK(status)) {
5225 return status;
5228 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
5230 if (!sid_check_is_in_our_domain(&group_sid)) {
5231 DEBUG(3, ("sid %s is not in our domain\n",
5232 sid_string_dbg(&group_sid)));
5233 return NT_STATUS_NO_SUCH_GROUP;
5236 DEBUG(10, ("lookup on Domain SID\n"));
5238 become_root();
5239 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
5240 &rid, &num_members);
5241 unbecome_root();
5243 if (!NT_STATUS_IS_OK(status))
5244 return status;
5246 if (num_members) {
5247 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5248 if (attr == NULL) {
5249 return NT_STATUS_NO_MEMORY;
5251 } else {
5252 attr = NULL;
5255 for (i=0; i<num_members; i++)
5256 attr[i] = SID_NAME_USER;
5258 rids->count = num_members;
5259 rids->types = attr;
5260 rids->rids = rid;
5262 *r->out.rids = rids;
5264 return NT_STATUS_OK;
5267 /*********************************************************************
5268 _samr_AddAliasMember
5269 *********************************************************************/
5271 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5272 struct samr_AddAliasMember *r)
5274 DOM_SID alias_sid;
5275 uint32 acc_granted;
5276 SE_PRIV se_rights;
5277 bool can_add_accounts;
5278 NTSTATUS status;
5279 DISP_INFO *disp_info = NULL;
5281 /* Find the policy handle. Open a policy on it. */
5282 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5283 return NT_STATUS_INVALID_HANDLE;
5285 status = access_check_samr_function(acc_granted,
5286 SAMR_ALIAS_ACCESS_ADD_MEMBER,
5287 "_samr_AddAliasMember");
5288 if (!NT_STATUS_IS_OK(status)) {
5289 return status;
5292 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5294 se_priv_copy( &se_rights, &se_add_users );
5295 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5297 /******** BEGIN SeAddUsers BLOCK *********/
5299 if ( can_add_accounts )
5300 become_root();
5302 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
5304 if ( can_add_accounts )
5305 unbecome_root();
5307 /******** END SeAddUsers BLOCK *********/
5309 if (NT_STATUS_IS_OK(status)) {
5310 force_flush_samr_cache(disp_info);
5313 return status;
5316 /*********************************************************************
5317 _samr_DeleteAliasMember
5318 *********************************************************************/
5320 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5321 struct samr_DeleteAliasMember *r)
5323 DOM_SID alias_sid;
5324 uint32 acc_granted;
5325 SE_PRIV se_rights;
5326 bool can_add_accounts;
5327 NTSTATUS status;
5328 DISP_INFO *disp_info = NULL;
5330 /* Find the policy handle. Open a policy on it. */
5331 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5332 return NT_STATUS_INVALID_HANDLE;
5334 status = access_check_samr_function(acc_granted,
5335 SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
5336 "_samr_DeleteAliasMember");
5337 if (!NT_STATUS_IS_OK(status)) {
5338 return status;
5341 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5342 sid_string_dbg(&alias_sid)));
5344 se_priv_copy( &se_rights, &se_add_users );
5345 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5347 /******** BEGIN SeAddUsers BLOCK *********/
5349 if ( can_add_accounts )
5350 become_root();
5352 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
5354 if ( can_add_accounts )
5355 unbecome_root();
5357 /******** END SeAddUsers BLOCK *********/
5359 if (NT_STATUS_IS_OK(status)) {
5360 force_flush_samr_cache(disp_info);
5363 return status;
5366 /*********************************************************************
5367 _samr_AddGroupMember
5368 *********************************************************************/
5370 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5371 struct samr_AddGroupMember *r)
5373 NTSTATUS status;
5374 DOM_SID group_sid;
5375 uint32 group_rid;
5376 uint32 acc_granted;
5377 SE_PRIV se_rights;
5378 bool can_add_accounts;
5379 DISP_INFO *disp_info = NULL;
5381 /* Find the policy handle. Open a policy on it. */
5382 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5383 return NT_STATUS_INVALID_HANDLE;
5385 status = access_check_samr_function(acc_granted,
5386 SAMR_GROUP_ACCESS_ADD_MEMBER,
5387 "_samr_AddGroupMember");
5388 if (!NT_STATUS_IS_OK(status)) {
5389 return status;
5392 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
5394 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
5395 &group_rid)) {
5396 return NT_STATUS_INVALID_HANDLE;
5399 se_priv_copy( &se_rights, &se_add_users );
5400 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5402 /******** BEGIN SeAddUsers BLOCK *********/
5404 if ( can_add_accounts )
5405 become_root();
5407 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5409 if ( can_add_accounts )
5410 unbecome_root();
5412 /******** END SeAddUsers BLOCK *********/
5414 force_flush_samr_cache(disp_info);
5416 return status;
5419 /*********************************************************************
5420 _samr_DeleteGroupMember
5421 *********************************************************************/
5423 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5424 struct samr_DeleteGroupMember *r)
5427 NTSTATUS status;
5428 DOM_SID group_sid;
5429 uint32 group_rid;
5430 uint32 acc_granted;
5431 SE_PRIV se_rights;
5432 bool can_add_accounts;
5433 DISP_INFO *disp_info = NULL;
5436 * delete the group member named r->in.rid
5437 * who is a member of the sid associated with the handle
5438 * the rid is a user's rid as the group is a domain group.
5441 /* Find the policy handle. Open a policy on it. */
5442 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5443 return NT_STATUS_INVALID_HANDLE;
5445 status = access_check_samr_function(acc_granted,
5446 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
5447 "_samr_DeleteGroupMember");
5448 if (!NT_STATUS_IS_OK(status)) {
5449 return status;
5452 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
5453 &group_rid)) {
5454 return NT_STATUS_INVALID_HANDLE;
5457 se_priv_copy( &se_rights, &se_add_users );
5458 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5460 /******** BEGIN SeAddUsers BLOCK *********/
5462 if ( can_add_accounts )
5463 become_root();
5465 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5467 if ( can_add_accounts )
5468 unbecome_root();
5470 /******** END SeAddUsers BLOCK *********/
5472 force_flush_samr_cache(disp_info);
5474 return status;
5477 /*********************************************************************
5478 _samr_DeleteUser
5479 *********************************************************************/
5481 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5482 struct samr_DeleteUser *r)
5484 NTSTATUS status;
5485 DOM_SID user_sid;
5486 struct samu *sam_pass=NULL;
5487 uint32 acc_granted;
5488 bool can_add_accounts;
5489 uint32 acb_info;
5490 DISP_INFO *disp_info = NULL;
5491 bool ret;
5493 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5495 /* Find the policy handle. Open a policy on it. */
5496 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
5497 return NT_STATUS_INVALID_HANDLE;
5499 status = access_check_samr_function(acc_granted,
5500 STD_RIGHT_DELETE_ACCESS,
5501 "_samr_DeleteUser");
5502 if (!NT_STATUS_IS_OK(status)) {
5503 return status;
5506 if (!sid_check_is_in_our_domain(&user_sid))
5507 return NT_STATUS_CANNOT_DELETE;
5509 /* check if the user exists before trying to delete */
5510 if ( !(sam_pass = samu_new( NULL )) ) {
5511 return NT_STATUS_NO_MEMORY;
5514 become_root();
5515 ret = pdb_getsampwsid(sam_pass, &user_sid);
5516 unbecome_root();
5518 if( !ret ) {
5519 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5520 sid_string_dbg(&user_sid)));
5521 TALLOC_FREE(sam_pass);
5522 return NT_STATUS_NO_SUCH_USER;
5525 acb_info = pdb_get_acct_ctrl(sam_pass);
5527 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
5528 if ( acb_info & ACB_WSTRUST ) {
5529 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
5530 } else {
5531 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5534 /******** BEGIN SeAddUsers BLOCK *********/
5536 if ( can_add_accounts )
5537 become_root();
5539 status = pdb_delete_user(p->mem_ctx, sam_pass);
5541 if ( can_add_accounts )
5542 unbecome_root();
5544 /******** END SeAddUsers BLOCK *********/
5546 if ( !NT_STATUS_IS_OK(status) ) {
5547 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5548 "user %s: %s.\n", pdb_get_username(sam_pass),
5549 nt_errstr(status)));
5550 TALLOC_FREE(sam_pass);
5551 return status;
5555 TALLOC_FREE(sam_pass);
5557 if (!close_policy_hnd(p, r->in.user_handle))
5558 return NT_STATUS_OBJECT_NAME_INVALID;
5560 ZERO_STRUCTP(r->out.user_handle);
5562 force_flush_samr_cache(disp_info);
5564 return NT_STATUS_OK;
5567 /*********************************************************************
5568 _samr_DeleteDomainGroup
5569 *********************************************************************/
5571 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5572 struct samr_DeleteDomainGroup *r)
5574 NTSTATUS status;
5575 DOM_SID group_sid;
5576 uint32 group_rid;
5577 uint32 acc_granted;
5578 SE_PRIV se_rights;
5579 bool can_add_accounts;
5580 DISP_INFO *disp_info = NULL;
5582 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5584 /* Find the policy handle. Open a policy on it. */
5585 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5586 return NT_STATUS_INVALID_HANDLE;
5588 status = access_check_samr_function(acc_granted,
5589 STD_RIGHT_DELETE_ACCESS,
5590 "_samr_DeleteDomainGroup");
5591 if (!NT_STATUS_IS_OK(status)) {
5592 return status;
5595 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
5597 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
5598 &group_rid)) {
5599 return NT_STATUS_NO_SUCH_GROUP;
5602 se_priv_copy( &se_rights, &se_add_users );
5603 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5605 /******** BEGIN SeAddUsers BLOCK *********/
5607 if ( can_add_accounts )
5608 become_root();
5610 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5612 if ( can_add_accounts )
5613 unbecome_root();
5615 /******** END SeAddUsers BLOCK *********/
5617 if ( !NT_STATUS_IS_OK(status) ) {
5618 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5619 "entry for group %s: %s\n",
5620 sid_string_dbg(&group_sid),
5621 nt_errstr(status)));
5622 return status;
5625 if (!close_policy_hnd(p, r->in.group_handle))
5626 return NT_STATUS_OBJECT_NAME_INVALID;
5628 force_flush_samr_cache(disp_info);
5630 return NT_STATUS_OK;
5633 /*********************************************************************
5634 _samr_DeleteDomAlias
5635 *********************************************************************/
5637 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5638 struct samr_DeleteDomAlias *r)
5640 DOM_SID alias_sid;
5641 uint32 acc_granted;
5642 SE_PRIV se_rights;
5643 bool can_add_accounts;
5644 NTSTATUS status;
5645 DISP_INFO *disp_info = NULL;
5647 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5649 /* Find the policy handle. Open a policy on it. */
5650 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5651 return NT_STATUS_INVALID_HANDLE;
5653 /* copy the handle to the outgoing reply */
5655 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
5657 status = access_check_samr_function(acc_granted,
5658 STD_RIGHT_DELETE_ACCESS,
5659 "_samr_DeleteDomAlias");
5660 if (!NT_STATUS_IS_OK(status)) {
5661 return status;
5664 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5666 /* Don't let Windows delete builtin groups */
5668 if ( sid_check_is_in_builtin( &alias_sid ) ) {
5669 return NT_STATUS_SPECIAL_ACCOUNT;
5672 if (!sid_check_is_in_our_domain(&alias_sid))
5673 return NT_STATUS_NO_SUCH_ALIAS;
5675 DEBUG(10, ("lookup on Local SID\n"));
5677 se_priv_copy( &se_rights, &se_add_users );
5678 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5680 /******** BEGIN SeAddUsers BLOCK *********/
5682 if ( can_add_accounts )
5683 become_root();
5685 /* Have passdb delete the alias */
5686 status = pdb_delete_alias(&alias_sid);
5688 if ( can_add_accounts )
5689 unbecome_root();
5691 /******** END SeAddUsers BLOCK *********/
5693 if ( !NT_STATUS_IS_OK(status))
5694 return status;
5696 if (!close_policy_hnd(p, r->in.alias_handle))
5697 return NT_STATUS_OBJECT_NAME_INVALID;
5699 force_flush_samr_cache(disp_info);
5701 return NT_STATUS_OK;
5704 /*********************************************************************
5705 _samr_CreateDomainGroup
5706 *********************************************************************/
5708 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5709 struct samr_CreateDomainGroup *r)
5712 NTSTATUS status;
5713 DOM_SID dom_sid;
5714 DOM_SID info_sid;
5715 const char *name;
5716 struct samr_info *info;
5717 uint32 acc_granted;
5718 SE_PRIV se_rights;
5719 bool can_add_accounts;
5720 DISP_INFO *disp_info = NULL;
5722 /* Find the policy handle. Open a policy on it. */
5723 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5724 return NT_STATUS_INVALID_HANDLE;
5726 status = access_check_samr_function(acc_granted,
5727 SAMR_DOMAIN_ACCESS_CREATE_GROUP,
5728 "_samr_CreateDomainGroup");
5729 if (!NT_STATUS_IS_OK(status)) {
5730 return status;
5733 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5734 return NT_STATUS_ACCESS_DENIED;
5736 name = r->in.name->string;
5737 if (name == NULL) {
5738 return NT_STATUS_NO_MEMORY;
5741 status = can_create(p->mem_ctx, name);
5742 if (!NT_STATUS_IS_OK(status)) {
5743 return status;
5746 se_priv_copy( &se_rights, &se_add_users );
5747 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5749 /******** BEGIN SeAddUsers BLOCK *********/
5751 if ( can_add_accounts )
5752 become_root();
5754 /* check that we successfully create the UNIX group */
5756 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5758 if ( can_add_accounts )
5759 unbecome_root();
5761 /******** END SeAddUsers BLOCK *********/
5763 /* check if we should bail out here */
5765 if ( !NT_STATUS_IS_OK(status) )
5766 return status;
5768 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5770 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5771 return NT_STATUS_NO_MEMORY;
5773 /* they created it; let the user do what he wants with it */
5775 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5777 /* get a (unique) handle. open a policy on it. */
5778 if (!create_policy_hnd(p, r->out.group_handle, info))
5779 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5781 force_flush_samr_cache(disp_info);
5783 return NT_STATUS_OK;
5786 /*********************************************************************
5787 _samr_CreateDomAlias
5788 *********************************************************************/
5790 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5791 struct samr_CreateDomAlias *r)
5793 DOM_SID dom_sid;
5794 DOM_SID info_sid;
5795 const char *name = NULL;
5796 struct samr_info *info;
5797 uint32 acc_granted;
5798 gid_t gid;
5799 NTSTATUS result;
5800 SE_PRIV se_rights;
5801 bool can_add_accounts;
5802 DISP_INFO *disp_info = NULL;
5804 /* Find the policy handle. Open a policy on it. */
5805 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5806 return NT_STATUS_INVALID_HANDLE;
5808 result = access_check_samr_function(acc_granted,
5809 SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
5810 "_samr_CreateDomAlias");
5811 if (!NT_STATUS_IS_OK(result)) {
5812 return result;
5815 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5816 return NT_STATUS_ACCESS_DENIED;
5818 name = r->in.alias_name->string;
5820 se_priv_copy( &se_rights, &se_add_users );
5821 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5823 result = can_create(p->mem_ctx, name);
5824 if (!NT_STATUS_IS_OK(result)) {
5825 return result;
5828 /******** BEGIN SeAddUsers BLOCK *********/
5830 if ( can_add_accounts )
5831 become_root();
5833 /* Have passdb create the alias */
5834 result = pdb_create_alias(name, r->out.rid);
5836 if ( can_add_accounts )
5837 unbecome_root();
5839 /******** END SeAddUsers BLOCK *********/
5841 if (!NT_STATUS_IS_OK(result)) {
5842 DEBUG(10, ("pdb_create_alias failed: %s\n",
5843 nt_errstr(result)));
5844 return result;
5847 sid_copy(&info_sid, get_global_sam_sid());
5848 sid_append_rid(&info_sid, *r->out.rid);
5850 if (!sid_to_gid(&info_sid, &gid)) {
5851 DEBUG(10, ("Could not find alias just created\n"));
5852 return NT_STATUS_ACCESS_DENIED;
5855 /* check if the group has been successfully created */
5856 if ( getgrgid(gid) == NULL ) {
5857 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5858 gid));
5859 return NT_STATUS_ACCESS_DENIED;
5862 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5863 return NT_STATUS_NO_MEMORY;
5865 /* they created it; let the user do what he wants with it */
5867 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5869 /* get a (unique) handle. open a policy on it. */
5870 if (!create_policy_hnd(p, r->out.alias_handle, info))
5871 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5873 force_flush_samr_cache(disp_info);
5875 return NT_STATUS_OK;
5878 /*********************************************************************
5879 _samr_QueryGroupInfo
5880 *********************************************************************/
5882 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5883 struct samr_QueryGroupInfo *r)
5885 NTSTATUS status;
5886 DOM_SID group_sid;
5887 GROUP_MAP map;
5888 union samr_GroupInfo *info = NULL;
5889 uint32 acc_granted;
5890 bool ret;
5891 uint32_t attributes = SE_GROUP_MANDATORY |
5892 SE_GROUP_ENABLED_BY_DEFAULT |
5893 SE_GROUP_ENABLED;
5894 const char *group_name = NULL;
5895 const char *group_description = NULL;
5897 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5898 return NT_STATUS_INVALID_HANDLE;
5900 status = access_check_samr_function(acc_granted,
5901 SAMR_GROUP_ACCESS_LOOKUP_INFO,
5902 "_samr_QueryGroupInfo");
5903 if (!NT_STATUS_IS_OK(status)) {
5904 return status;
5907 become_root();
5908 ret = get_domain_group_from_sid(group_sid, &map);
5909 unbecome_root();
5910 if (!ret)
5911 return NT_STATUS_INVALID_HANDLE;
5913 /* FIXME: map contains fstrings */
5914 group_name = talloc_strdup(r, map.nt_name);
5915 group_description = talloc_strdup(r, map.comment);
5917 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5918 if (!info) {
5919 return NT_STATUS_NO_MEMORY;
5922 switch (r->in.level) {
5923 case 1: {
5924 uint32 *members;
5925 size_t num_members;
5927 become_root();
5928 status = pdb_enum_group_members(
5929 p->mem_ctx, &group_sid, &members, &num_members);
5930 unbecome_root();
5932 if (!NT_STATUS_IS_OK(status)) {
5933 return status;
5936 info->all.name.string = group_name;
5937 info->all.attributes = attributes;
5938 info->all.num_members = num_members;
5939 info->all.description.string = group_description;
5940 break;
5942 case 2:
5943 info->name.string = group_name;
5944 break;
5945 case 3:
5946 info->attributes.attributes = attributes;
5947 break;
5948 case 4:
5949 info->description.string = group_description;
5950 break;
5951 case 5: {
5953 uint32 *members;
5954 size_t num_members;
5958 become_root();
5959 status = pdb_enum_group_members(
5960 p->mem_ctx, &group_sid, &members, &num_members);
5961 unbecome_root();
5963 if (!NT_STATUS_IS_OK(status)) {
5964 return status;
5967 info->all2.name.string = group_name;
5968 info->all2.attributes = attributes;
5969 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5970 info->all2.description.string = group_description;
5972 break;
5974 default:
5975 return NT_STATUS_INVALID_INFO_CLASS;
5978 *r->out.info = info;
5980 return NT_STATUS_OK;
5983 /*********************************************************************
5984 _samr_SetGroupInfo
5985 *********************************************************************/
5987 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5988 struct samr_SetGroupInfo *r)
5990 DOM_SID group_sid;
5991 GROUP_MAP map;
5992 uint32 acc_granted;
5993 NTSTATUS status;
5994 bool ret;
5995 bool can_mod_accounts;
5996 DISP_INFO *disp_info = NULL;
5998 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5999 return NT_STATUS_INVALID_HANDLE;
6001 status = access_check_samr_function(acc_granted,
6002 SAMR_GROUP_ACCESS_SET_INFO,
6003 "_samr_SetGroupInfo");
6004 if (!NT_STATUS_IS_OK(status)) {
6005 return status;
6008 become_root();
6009 ret = get_domain_group_from_sid(group_sid, &map);
6010 unbecome_root();
6011 if (!ret)
6012 return NT_STATUS_NO_SUCH_GROUP;
6014 switch (r->in.level) {
6015 case 1:
6016 fstrcpy(map.comment, r->in.info->all.description.string);
6017 break;
6018 case 2:
6019 /* group rename is not supported yet */
6020 return NT_STATUS_NOT_SUPPORTED;
6021 case 4:
6022 fstrcpy(map.comment, r->in.info->description.string);
6023 break;
6024 default:
6025 return NT_STATUS_INVALID_INFO_CLASS;
6028 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
6030 /******** BEGIN SeAddUsers BLOCK *********/
6032 if ( can_mod_accounts )
6033 become_root();
6035 status = pdb_update_group_mapping_entry(&map);
6037 if ( can_mod_accounts )
6038 unbecome_root();
6040 /******** End SeAddUsers BLOCK *********/
6042 if (NT_STATUS_IS_OK(status)) {
6043 force_flush_samr_cache(disp_info);
6046 return status;
6049 /*********************************************************************
6050 _samr_SetAliasInfo
6051 *********************************************************************/
6053 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
6054 struct samr_SetAliasInfo *r)
6056 DOM_SID group_sid;
6057 struct acct_info info;
6058 uint32 acc_granted;
6059 bool can_mod_accounts;
6060 NTSTATUS status;
6061 DISP_INFO *disp_info = NULL;
6063 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
6064 return NT_STATUS_INVALID_HANDLE;
6066 status = access_check_samr_function(acc_granted,
6067 SAMR_ALIAS_ACCESS_SET_INFO,
6068 "_samr_SetAliasInfo");
6069 if (!NT_STATUS_IS_OK(status)) {
6070 return status;
6073 /* get the current group information */
6075 become_root();
6076 status = pdb_get_aliasinfo( &group_sid, &info );
6077 unbecome_root();
6079 if ( !NT_STATUS_IS_OK(status))
6080 return status;
6082 switch (r->in.level) {
6083 case ALIASINFONAME:
6085 fstring group_name;
6087 /* We currently do not support renaming groups in the
6088 the BUILTIN domain. Refer to util_builtin.c to understand
6089 why. The eventually needs to be fixed to be like Windows
6090 where you can rename builtin groups, just not delete them */
6092 if ( sid_check_is_in_builtin( &group_sid ) ) {
6093 return NT_STATUS_SPECIAL_ACCOUNT;
6096 /* There has to be a valid name (and it has to be different) */
6098 if ( !r->in.info->name.string )
6099 return NT_STATUS_INVALID_PARAMETER;
6101 /* If the name is the same just reply "ok". Yes this
6102 doesn't allow you to change the case of a group name. */
6104 if ( strequal( r->in.info->name.string, info.acct_name ) )
6105 return NT_STATUS_OK;
6107 fstrcpy( info.acct_name, r->in.info->name.string);
6109 /* make sure the name doesn't already exist as a user
6110 or local group */
6112 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6113 status = can_create( p->mem_ctx, group_name );
6114 if ( !NT_STATUS_IS_OK( status ) )
6115 return status;
6116 break;
6118 case ALIASINFODESCRIPTION:
6119 if (r->in.info->description.string) {
6120 fstrcpy(info.acct_desc,
6121 r->in.info->description.string);
6122 } else {
6123 fstrcpy( info.acct_desc, "" );
6125 break;
6126 default:
6127 return NT_STATUS_INVALID_INFO_CLASS;
6130 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
6132 /******** BEGIN SeAddUsers BLOCK *********/
6134 if ( can_mod_accounts )
6135 become_root();
6137 status = pdb_set_aliasinfo( &group_sid, &info );
6139 if ( can_mod_accounts )
6140 unbecome_root();
6142 /******** End SeAddUsers BLOCK *********/
6144 if (NT_STATUS_IS_OK(status))
6145 force_flush_samr_cache(disp_info);
6147 return status;
6150 /****************************************************************
6151 _samr_GetDomPwInfo
6152 ****************************************************************/
6154 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
6155 struct samr_GetDomPwInfo *r)
6157 uint32_t min_password_length = 0;
6158 uint32_t password_properties = 0;
6160 /* Perform access check. Since this rpc does not require a
6161 policy handle it will not be caught by the access checks on
6162 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6164 if (!pipe_access_check(p)) {
6165 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6166 return NT_STATUS_ACCESS_DENIED;
6169 become_root();
6170 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
6171 &min_password_length);
6172 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
6173 &password_properties);
6174 unbecome_root();
6176 if (lp_check_password_script() && *lp_check_password_script()) {
6177 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6180 r->out.info->min_password_length = min_password_length;
6181 r->out.info->password_properties = password_properties;
6183 return NT_STATUS_OK;
6186 /*********************************************************************
6187 _samr_OpenGroup
6188 *********************************************************************/
6190 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6191 struct samr_OpenGroup *r)
6194 DOM_SID sid;
6195 DOM_SID info_sid;
6196 GROUP_MAP map;
6197 struct samr_info *info;
6198 SEC_DESC *psd = NULL;
6199 uint32 acc_granted;
6200 uint32 des_access = r->in.access_mask;
6201 size_t sd_size;
6202 NTSTATUS status;
6203 fstring sid_string;
6204 bool ret;
6205 SE_PRIV se_rights;
6207 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
6208 return NT_STATUS_INVALID_HANDLE;
6210 status = access_check_samr_function(acc_granted,
6211 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
6212 "_samr_OpenGroup");
6214 if ( !NT_STATUS_IS_OK(status) )
6215 return status;
6217 /*check if access can be granted as requested by client. */
6218 map_max_allowed_access(p->server_info->ptok, &des_access);
6220 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6221 se_map_generic(&des_access,&grp_generic_mapping);
6223 se_priv_copy( &se_rights, &se_add_users );
6225 status = access_check_samr_object(psd, p->server_info->ptok,
6226 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
6227 &acc_granted, "_samr_OpenGroup");
6229 if ( !NT_STATUS_IS_OK(status) )
6230 return status;
6232 /* this should not be hard-coded like this */
6234 if (!sid_equal(&sid, get_global_sam_sid()))
6235 return NT_STATUS_ACCESS_DENIED;
6237 sid_copy(&info_sid, get_global_sam_sid());
6238 sid_append_rid(&info_sid, r->in.rid);
6239 sid_to_fstring(sid_string, &info_sid);
6241 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
6242 return NT_STATUS_NO_MEMORY;
6244 info->acc_granted = acc_granted;
6246 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
6248 /* check if that group really exists */
6249 become_root();
6250 ret = get_domain_group_from_sid(info->sid, &map);
6251 unbecome_root();
6252 if (!ret)
6253 return NT_STATUS_NO_SUCH_GROUP;
6255 /* get a (unique) handle. open a policy on it. */
6256 if (!create_policy_hnd(p, r->out.group_handle, info))
6257 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6259 return NT_STATUS_OK;
6262 /*********************************************************************
6263 _samr_RemoveMemberFromForeignDomain
6264 *********************************************************************/
6266 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6267 struct samr_RemoveMemberFromForeignDomain *r)
6269 DOM_SID delete_sid, domain_sid;
6270 uint32 acc_granted;
6271 NTSTATUS result;
6272 DISP_INFO *disp_info = NULL;
6274 sid_copy( &delete_sid, r->in.sid );
6276 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6277 sid_string_dbg(&delete_sid)));
6279 /* Find the policy handle. Open a policy on it. */
6281 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
6282 &acc_granted, &disp_info))
6283 return NT_STATUS_INVALID_HANDLE;
6285 result = access_check_samr_function(acc_granted,
6286 STD_RIGHT_DELETE_ACCESS,
6287 "_samr_RemoveMemberFromForeignDomain");
6289 if (!NT_STATUS_IS_OK(result))
6290 return result;
6292 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6293 sid_string_dbg(&domain_sid)));
6295 /* we can only delete a user from a group since we don't have
6296 nested groups anyways. So in the latter case, just say OK */
6298 /* TODO: The above comment nowadays is bogus. Since we have nested
6299 * groups now, and aliases members are never reported out of the unix
6300 * group membership, the "just say OK" makes this call a no-op. For
6301 * us. This needs fixing however. */
6303 /* I've only ever seen this in the wild when deleting a user from
6304 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6305 * is the user about to be deleted. I very much suspect this is the
6306 * only application of this call. To verify this, let people report
6307 * other cases. */
6309 if (!sid_check_is_builtin(&domain_sid)) {
6310 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6311 "global_sam_sid() = %s\n",
6312 sid_string_dbg(&domain_sid),
6313 sid_string_dbg(get_global_sam_sid())));
6314 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6315 return NT_STATUS_OK;
6318 force_flush_samr_cache(disp_info);
6320 result = NT_STATUS_OK;
6322 return result;
6325 /*******************************************************************
6326 _samr_QueryDomainInfo2
6327 ********************************************************************/
6329 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6330 struct samr_QueryDomainInfo2 *r)
6332 struct samr_QueryDomainInfo q;
6334 q.in.domain_handle = r->in.domain_handle;
6335 q.in.level = r->in.level;
6337 q.out.info = r->out.info;
6339 return _samr_QueryDomainInfo(p, &q);
6342 /*******************************************************************
6343 _samr_SetDomainInfo
6344 ********************************************************************/
6346 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6347 struct samr_SetDomainInfo *r)
6349 struct samr_info *info = NULL;
6350 time_t u_expire, u_min_age;
6351 time_t u_logout;
6352 time_t u_lock_duration, u_reset_time;
6353 NTSTATUS result;
6355 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6357 /* find the policy handle. open a policy on it. */
6358 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
6359 return NT_STATUS_INVALID_HANDLE;
6361 /* We do have different access bits for info
6362 * levels here, but we're really just looking for
6363 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
6364 * this maps to different specific bits. So
6365 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
6366 * set we are ok. */
6368 result = access_check_samr_function(info->acc_granted,
6369 SAMR_DOMAIN_ACCESS_SET_INFO_1,
6370 "_samr_SetDomainInfo");
6372 if (!NT_STATUS_IS_OK(result))
6373 return result;
6375 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6377 switch (r->in.level) {
6378 case 0x01:
6379 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
6380 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
6381 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
6382 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
6383 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
6384 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
6385 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
6386 break;
6387 case 0x03:
6388 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
6389 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
6390 break;
6391 case 0x04:
6392 break;
6393 case 0x06:
6394 break;
6395 case 0x07:
6396 break;
6397 case 0x09:
6398 break;
6399 case 0x0c:
6400 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
6401 if (u_lock_duration != -1)
6402 u_lock_duration /= 60;
6404 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
6406 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6407 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
6408 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
6409 break;
6410 default:
6411 return NT_STATUS_INVALID_INFO_CLASS;
6414 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6416 return NT_STATUS_OK;
6419 /****************************************************************
6420 _samr_GetDisplayEnumerationIndex
6421 ****************************************************************/
6423 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6424 struct samr_GetDisplayEnumerationIndex *r)
6426 struct samr_info *info = NULL;
6427 uint32_t max_entries = (uint32_t) -1;
6428 uint32_t enum_context = 0;
6429 int i;
6430 uint32_t num_account = 0;
6431 struct samr_displayentry *entries = NULL;
6432 NTSTATUS status;
6434 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6436 /* find the policy handle. open a policy on it. */
6437 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
6438 return NT_STATUS_INVALID_HANDLE;
6441 status = access_check_samr_function(info->acc_granted,
6442 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
6443 "_samr_GetDisplayEnumerationIndex");
6444 if (!NT_STATUS_IS_OK(status)) {
6445 return status;
6448 if ((r->in.level < 1) || (r->in.level > 3)) {
6449 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6450 "Unknown info level (%u)\n",
6451 r->in.level));
6452 return NT_STATUS_INVALID_INFO_CLASS;
6455 become_root();
6457 /* The following done as ROOT. Don't return without unbecome_root(). */
6459 switch (r->in.level) {
6460 case 1:
6461 if (info->disp_info->users == NULL) {
6462 info->disp_info->users = pdb_search_users(
6463 info->disp_info, ACB_NORMAL);
6464 if (info->disp_info->users == NULL) {
6465 unbecome_root();
6466 return NT_STATUS_ACCESS_DENIED;
6468 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6469 "starting user enumeration at index %u\n",
6470 (unsigned int)enum_context));
6471 } else {
6472 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6473 "using cached user enumeration at index %u\n",
6474 (unsigned int)enum_context));
6476 num_account = pdb_search_entries(info->disp_info->users,
6477 enum_context, max_entries,
6478 &entries);
6479 break;
6480 case 2:
6481 if (info->disp_info->machines == NULL) {
6482 info->disp_info->machines = pdb_search_users(
6483 info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6484 if (info->disp_info->machines == NULL) {
6485 unbecome_root();
6486 return NT_STATUS_ACCESS_DENIED;
6488 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6489 "starting machine enumeration at index %u\n",
6490 (unsigned int)enum_context));
6491 } else {
6492 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6493 "using cached machine enumeration at index %u\n",
6494 (unsigned int)enum_context));
6496 num_account = pdb_search_entries(info->disp_info->machines,
6497 enum_context, max_entries,
6498 &entries);
6499 break;
6500 case 3:
6501 if (info->disp_info->groups == NULL) {
6502 info->disp_info->groups = pdb_search_groups(
6503 info->disp_info);
6504 if (info->disp_info->groups == NULL) {
6505 unbecome_root();
6506 return NT_STATUS_ACCESS_DENIED;
6508 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6509 "starting group enumeration at index %u\n",
6510 (unsigned int)enum_context));
6511 } else {
6512 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6513 "using cached group enumeration at index %u\n",
6514 (unsigned int)enum_context));
6516 num_account = pdb_search_entries(info->disp_info->groups,
6517 enum_context, max_entries,
6518 &entries);
6519 break;
6520 default:
6521 unbecome_root();
6522 smb_panic("info class changed");
6523 break;
6526 unbecome_root();
6528 /* Ensure we cache this enumeration. */
6529 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
6531 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6532 r->in.name->string));
6534 for (i=0; i<num_account; i++) {
6535 if (strequal(entries[i].account_name, r->in.name->string)) {
6536 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6537 "found %s at idx %d\n",
6538 r->in.name->string, i));
6539 *r->out.idx = i;
6540 return NT_STATUS_OK;
6544 /* assuming account_name lives at the very end */
6545 *r->out.idx = num_account;
6547 return NT_STATUS_NO_MORE_ENTRIES;
6550 /****************************************************************
6551 _samr_GetDisplayEnumerationIndex2
6552 ****************************************************************/
6554 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6555 struct samr_GetDisplayEnumerationIndex2 *r)
6557 struct samr_GetDisplayEnumerationIndex q;
6559 q.in.domain_handle = r->in.domain_handle;
6560 q.in.level = r->in.level;
6561 q.in.name = r->in.name;
6563 q.out.idx = r->out.idx;
6565 return _samr_GetDisplayEnumerationIndex(p, &q);
6568 /****************************************************************
6569 ****************************************************************/
6571 NTSTATUS _samr_Shutdown(pipes_struct *p,
6572 struct samr_Shutdown *r)
6574 p->rng_fault_state = true;
6575 return NT_STATUS_NOT_IMPLEMENTED;
6578 /****************************************************************
6579 ****************************************************************/
6581 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6582 struct samr_SetMemberAttributesOfGroup *r)
6584 p->rng_fault_state = true;
6585 return NT_STATUS_NOT_IMPLEMENTED;
6588 /****************************************************************
6589 ****************************************************************/
6591 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6592 struct samr_TestPrivateFunctionsDomain *r)
6594 return NT_STATUS_NOT_IMPLEMENTED;
6597 /****************************************************************
6598 ****************************************************************/
6600 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6601 struct samr_TestPrivateFunctionsUser *r)
6603 return NT_STATUS_NOT_IMPLEMENTED;
6606 /****************************************************************
6607 ****************************************************************/
6609 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6610 struct samr_AddMultipleMembersToAlias *r)
6612 p->rng_fault_state = true;
6613 return NT_STATUS_NOT_IMPLEMENTED;
6616 /****************************************************************
6617 ****************************************************************/
6619 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6620 struct samr_RemoveMultipleMembersFromAlias *r)
6622 p->rng_fault_state = true;
6623 return NT_STATUS_NOT_IMPLEMENTED;
6626 /****************************************************************
6627 ****************************************************************/
6629 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6630 struct samr_SetBootKeyInformation *r)
6632 p->rng_fault_state = true;
6633 return NT_STATUS_NOT_IMPLEMENTED;
6636 /****************************************************************
6637 ****************************************************************/
6639 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6640 struct samr_GetBootKeyInformation *r)
6642 p->rng_fault_state = true;
6643 return NT_STATUS_NOT_IMPLEMENTED;
6646 /****************************************************************
6647 ****************************************************************/
6649 NTSTATUS _samr_RidToSid(pipes_struct *p,
6650 struct samr_RidToSid *r)
6652 p->rng_fault_state = true;
6653 return NT_STATUS_NOT_IMPLEMENTED;
6656 /****************************************************************
6657 ****************************************************************/
6659 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6660 struct samr_SetDsrmPassword *r)
6662 p->rng_fault_state = true;
6663 return NT_STATUS_NOT_IMPLEMENTED;
6666 /****************************************************************
6667 ****************************************************************/
6669 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6670 struct samr_ValidatePassword *r)
6672 p->rng_fault_state = true;
6673 return NT_STATUS_NOT_IMPLEMENTED;