s3-samr: Fix potential memory leak in _samr_ChangePasswordUser().
[Samba.git] / source3 / rpc_server / srv_samr_nt.c
bloba86ebe50f122745c4ba6141575fba12242c005b1
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 ALIASINFODESCRIPTION:
1753 alias_info->description.string = alias_description;
1754 break;
1755 default:
1756 return NT_STATUS_INVALID_INFO_CLASS;
1759 *r->out.info = alias_info;
1761 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1763 return NT_STATUS_OK;
1766 /*******************************************************************
1767 _samr_LookupNames
1768 ********************************************************************/
1770 NTSTATUS _samr_LookupNames(pipes_struct *p,
1771 struct samr_LookupNames *r)
1773 NTSTATUS status;
1774 uint32 *rid;
1775 enum lsa_SidType *type;
1776 int i;
1777 int num_rids = r->in.num_names;
1778 DOM_SID pol_sid;
1779 uint32 acc_granted;
1780 struct samr_Ids rids, types;
1781 uint32_t num_mapped = 0;
1783 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1785 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1786 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1789 status = access_check_samr_function(acc_granted,
1790 0, /* Don't know the acc_bits yet */
1791 "_samr_LookupNames");
1792 if (!NT_STATUS_IS_OK(status)) {
1793 return status;
1796 if (num_rids > MAX_SAM_ENTRIES) {
1797 num_rids = MAX_SAM_ENTRIES;
1798 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1801 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1802 NT_STATUS_HAVE_NO_MEMORY(rid);
1804 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1805 NT_STATUS_HAVE_NO_MEMORY(type);
1807 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1808 sid_string_dbg(&pol_sid)));
1810 for (i = 0; i < num_rids; i++) {
1812 status = NT_STATUS_NONE_MAPPED;
1813 type[i] = SID_NAME_UNKNOWN;
1815 rid[i] = 0xffffffff;
1817 if (sid_check_is_builtin(&pol_sid)) {
1818 if (lookup_builtin_name(r->in.names[i].string,
1819 &rid[i]))
1821 type[i] = SID_NAME_ALIAS;
1823 } else {
1824 lookup_global_sam_name(r->in.names[i].string, 0,
1825 &rid[i], &type[i]);
1828 if (type[i] != SID_NAME_UNKNOWN) {
1829 num_mapped++;
1833 if (num_mapped == num_rids) {
1834 status = NT_STATUS_OK;
1835 } else if (num_mapped == 0) {
1836 status = NT_STATUS_NONE_MAPPED;
1837 } else {
1838 status = STATUS_SOME_UNMAPPED;
1841 rids.count = num_rids;
1842 rids.ids = rid;
1844 types.count = num_rids;
1845 types.ids = type;
1847 *r->out.rids = rids;
1848 *r->out.types = types;
1850 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1852 return status;
1855 /****************************************************************
1856 _samr_ChangePasswordUser
1857 ****************************************************************/
1859 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1860 struct samr_ChangePasswordUser *r)
1862 NTSTATUS status;
1863 bool ret = false;
1864 struct samu *pwd;
1865 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1866 struct samr_Password lm_pwd, nt_pwd;
1867 uint32_t acc_granted;
1868 struct dom_sid sid;
1870 DISP_INFO *disp_info = NULL;
1872 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) {
1873 return NT_STATUS_INVALID_HANDLE;
1876 status = access_check_samr_function(acc_granted,
1877 SAMR_USER_ACCESS_SET_PASSWORD,
1878 "_samr_ChangePasswordUser");
1879 if (!NT_STATUS_IS_OK(status)) {
1880 return status;
1883 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1884 sid_string_dbg(&sid)));
1886 if (!(pwd = samu_new(NULL))) {
1887 return NT_STATUS_NO_MEMORY;
1890 become_root();
1891 ret = pdb_getsampwsid(pwd, &sid);
1892 unbecome_root();
1894 if (!ret) {
1895 TALLOC_FREE(pwd);
1896 return NT_STATUS_WRONG_PASSWORD;
1900 const uint8_t *lm_pass, *nt_pass;
1902 lm_pass = pdb_get_lanman_passwd(pwd);
1903 nt_pass = pdb_get_nt_passwd(pwd);
1905 if (!lm_pass || !nt_pass) {
1906 status = NT_STATUS_WRONG_PASSWORD;
1907 goto out;
1910 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1911 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1914 /* basic sanity checking on parameters. Do this before any database ops */
1915 if (!r->in.lm_present || !r->in.nt_present ||
1916 !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1917 !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1918 /* we should really handle a change with lm not
1919 present */
1920 status = NT_STATUS_INVALID_PARAMETER_MIX;
1921 goto out;
1924 /* decrypt and check the new lm hash */
1925 D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1926 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1927 if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1928 status = NT_STATUS_WRONG_PASSWORD;
1929 goto out;
1932 /* decrypt and check the new nt hash */
1933 D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1934 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1935 if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1936 status = NT_STATUS_WRONG_PASSWORD;
1937 goto out;
1940 /* The NT Cross is not required by Win2k3 R2, but if present
1941 check the nt cross hash */
1942 if (r->in.cross1_present && r->in.nt_cross) {
1943 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1944 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1945 status = NT_STATUS_WRONG_PASSWORD;
1946 goto out;
1950 /* The LM Cross is not required by Win2k3 R2, but if present
1951 check the lm cross hash */
1952 if (r->in.cross2_present && r->in.lm_cross) {
1953 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1954 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1955 status = NT_STATUS_WRONG_PASSWORD;
1956 goto out;
1960 if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1961 !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1962 status = NT_STATUS_ACCESS_DENIED;
1963 goto out;
1966 status = pdb_update_sam_account(pwd);
1967 out:
1968 TALLOC_FREE(pwd);
1970 return status;
1973 /*******************************************************************
1974 _samr_ChangePasswordUser2
1975 ********************************************************************/
1977 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1978 struct samr_ChangePasswordUser2 *r)
1980 NTSTATUS status;
1981 fstring user_name;
1982 fstring wks;
1984 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1986 fstrcpy(user_name, r->in.account->string);
1987 fstrcpy(wks, r->in.server->string);
1989 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1992 * Pass the user through the NT -> unix user mapping
1993 * function.
1996 (void)map_username(user_name);
1999 * UNIX username case mangling not required, pass_oem_change
2000 * is case insensitive.
2003 status = pass_oem_change(user_name,
2004 r->in.lm_password->data,
2005 r->in.lm_verifier->hash,
2006 r->in.nt_password->data,
2007 r->in.nt_verifier->hash,
2008 NULL);
2010 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
2012 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2013 return NT_STATUS_WRONG_PASSWORD;
2016 return status;
2019 /****************************************************************
2020 _samr_OemChangePasswordUser2
2021 ****************************************************************/
2023 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
2024 struct samr_OemChangePasswordUser2 *r)
2026 NTSTATUS status;
2027 fstring user_name;
2028 const char *wks = NULL;
2030 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2032 fstrcpy(user_name, r->in.account->string);
2033 if (r->in.server && r->in.server->string) {
2034 wks = r->in.server->string;
2037 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
2040 * Pass the user through the NT -> unix user mapping
2041 * function.
2044 (void)map_username(user_name);
2047 * UNIX username case mangling not required, pass_oem_change
2048 * is case insensitive.
2051 if (!r->in.hash || !r->in.password) {
2052 return NT_STATUS_INVALID_PARAMETER;
2055 status = pass_oem_change(user_name,
2056 r->in.password->data,
2057 r->in.hash->hash,
2060 NULL);
2062 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2063 return NT_STATUS_WRONG_PASSWORD;
2066 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2068 return status;
2071 /*******************************************************************
2072 _samr_ChangePasswordUser3
2073 ********************************************************************/
2075 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
2076 struct samr_ChangePasswordUser3 *r)
2078 NTSTATUS status;
2079 fstring user_name;
2080 const char *wks = NULL;
2081 uint32 reject_reason;
2082 struct samr_DomInfo1 *dominfo = NULL;
2083 struct samr_ChangeReject *reject = NULL;
2084 uint32_t tmp;
2086 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2088 fstrcpy(user_name, r->in.account->string);
2089 if (r->in.server && r->in.server->string) {
2090 wks = r->in.server->string;
2093 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2096 * Pass the user through the NT -> unix user mapping
2097 * function.
2100 (void)map_username(user_name);
2103 * UNIX username case mangling not required, pass_oem_change
2104 * is case insensitive.
2107 status = pass_oem_change(user_name,
2108 r->in.lm_password->data,
2109 r->in.lm_verifier->hash,
2110 r->in.nt_password->data,
2111 r->in.nt_verifier->hash,
2112 &reject_reason);
2113 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2114 return NT_STATUS_WRONG_PASSWORD;
2117 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2118 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2120 time_t u_expire, u_min_age;
2121 uint32 account_policy_temp;
2123 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2124 if (!dominfo) {
2125 return NT_STATUS_NO_MEMORY;
2128 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2129 if (!reject) {
2130 return NT_STATUS_NO_MEMORY;
2133 become_root();
2135 /* AS ROOT !!! */
2137 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
2138 dominfo->min_password_length = tmp;
2140 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
2141 dominfo->password_history_length = tmp;
2143 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2144 &dominfo->password_properties);
2146 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2147 u_expire = account_policy_temp;
2149 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2150 u_min_age = account_policy_temp;
2152 /* !AS ROOT */
2154 unbecome_root();
2156 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2157 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2159 if (lp_check_password_script() && *lp_check_password_script()) {
2160 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2163 reject->reason = reject_reason;
2165 *r->out.dominfo = dominfo;
2166 *r->out.reject = reject;
2169 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2171 return status;
2174 /*******************************************************************
2175 makes a SAMR_R_LOOKUP_RIDS structure.
2176 ********************************************************************/
2178 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2179 const char **names,
2180 struct lsa_String **lsa_name_array_p)
2182 struct lsa_String *lsa_name_array = NULL;
2183 uint32_t i;
2185 *lsa_name_array_p = NULL;
2187 if (num_names != 0) {
2188 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2189 if (!lsa_name_array) {
2190 return false;
2194 for (i = 0; i < num_names; i++) {
2195 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2196 init_lsa_String(&lsa_name_array[i], names[i]);
2199 *lsa_name_array_p = lsa_name_array;
2201 return true;
2204 /*******************************************************************
2205 _samr_LookupRids
2206 ********************************************************************/
2208 NTSTATUS _samr_LookupRids(pipes_struct *p,
2209 struct samr_LookupRids *r)
2211 NTSTATUS status;
2212 const char **names;
2213 enum lsa_SidType *attrs = NULL;
2214 uint32 *wire_attrs = NULL;
2215 DOM_SID pol_sid;
2216 int num_rids = (int)r->in.num_rids;
2217 uint32 acc_granted;
2218 int i;
2219 struct lsa_Strings names_array;
2220 struct samr_Ids types_array;
2221 struct lsa_String *lsa_names = NULL;
2223 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2225 /* find the policy handle. open a policy on it. */
2226 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2227 return NT_STATUS_INVALID_HANDLE;
2229 status = access_check_samr_function(acc_granted,
2230 0, /* Don't know the acc_bits yet */
2231 "_samr_LookupRids");
2232 if (!NT_STATUS_IS_OK(status)) {
2233 return status;
2236 if (num_rids > 1000) {
2237 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2238 "to samba4 idl this is not possible\n", num_rids));
2239 return NT_STATUS_UNSUCCESSFUL;
2242 if (num_rids) {
2243 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2244 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2245 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2247 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2248 return NT_STATUS_NO_MEMORY;
2249 } else {
2250 names = NULL;
2251 attrs = NULL;
2252 wire_attrs = NULL;
2255 become_root(); /* lookup_sid can require root privs */
2256 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2257 names, attrs);
2258 unbecome_root();
2260 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2261 status = NT_STATUS_OK;
2264 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2265 &lsa_names)) {
2266 return NT_STATUS_NO_MEMORY;
2269 /* Convert from enum lsa_SidType to uint32 for wire format. */
2270 for (i = 0; i < num_rids; i++) {
2271 wire_attrs[i] = (uint32)attrs[i];
2274 names_array.count = num_rids;
2275 names_array.names = lsa_names;
2277 types_array.count = num_rids;
2278 types_array.ids = wire_attrs;
2280 *r->out.names = names_array;
2281 *r->out.types = types_array;
2283 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2285 return status;
2288 /*******************************************************************
2289 _samr_OpenUser
2290 ********************************************************************/
2292 NTSTATUS _samr_OpenUser(pipes_struct *p,
2293 struct samr_OpenUser *r)
2295 struct samu *sampass=NULL;
2296 DOM_SID sid;
2297 struct samr_info *info = NULL;
2298 SEC_DESC *psd = NULL;
2299 uint32 acc_granted;
2300 uint32 des_access = r->in.access_mask;
2301 size_t sd_size;
2302 bool ret;
2303 NTSTATUS nt_status;
2304 SE_PRIV se_rights;
2306 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2308 if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
2309 return NT_STATUS_INVALID_HANDLE;
2311 nt_status = access_check_samr_function(acc_granted,
2312 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2313 "_samr_OpenUser" );
2315 if ( !NT_STATUS_IS_OK(nt_status) )
2316 return nt_status;
2318 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2319 return NT_STATUS_NO_MEMORY;
2322 /* append the user's RID to it */
2324 if (!sid_append_rid(&sid, r->in.rid))
2325 return NT_STATUS_NO_SUCH_USER;
2327 /* check if access can be granted as requested by client. */
2329 map_max_allowed_access(p->server_info->ptok, &des_access);
2331 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2332 se_map_generic(&des_access, &usr_generic_mapping);
2334 se_priv_copy( &se_rights, &se_machine_account );
2335 se_priv_add( &se_rights, &se_add_users );
2337 nt_status = access_check_samr_object(psd, p->server_info->ptok,
2338 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2339 &acc_granted, "_samr_OpenUser");
2341 if ( !NT_STATUS_IS_OK(nt_status) )
2342 return nt_status;
2344 become_root();
2345 ret=pdb_getsampwsid(sampass, &sid);
2346 unbecome_root();
2348 /* check that the SID exists in our domain. */
2349 if (ret == False) {
2350 return NT_STATUS_NO_SUCH_USER;
2353 TALLOC_FREE(sampass);
2355 /* associate the user's SID and access bits with the new handle. */
2356 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
2357 return NT_STATUS_NO_MEMORY;
2358 info->acc_granted = acc_granted;
2360 /* get a (unique) handle. open a policy on it. */
2361 if (!create_policy_hnd(p, r->out.user_handle, info))
2362 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2364 return NT_STATUS_OK;
2367 /*************************************************************************
2368 *************************************************************************/
2370 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2371 DATA_BLOB *blob,
2372 struct lsa_BinaryString **_r)
2374 struct lsa_BinaryString *r;
2376 if (!blob || !_r) {
2377 return NT_STATUS_INVALID_PARAMETER;
2380 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2381 if (!r) {
2382 return NT_STATUS_NO_MEMORY;
2385 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2386 if (!r->array) {
2387 return NT_STATUS_NO_MEMORY;
2389 memcpy(r->array, blob->data, blob->length);
2390 r->size = blob->length;
2391 r->length = blob->length;
2393 if (!r->array) {
2394 return NT_STATUS_NO_MEMORY;
2397 *_r = r;
2399 return NT_STATUS_OK;
2402 /*************************************************************************
2403 get_user_info_1.
2404 *************************************************************************/
2406 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2407 struct samr_UserInfo1 *r,
2408 struct samu *pw,
2409 DOM_SID *domain_sid)
2411 const DOM_SID *sid_group;
2412 uint32_t primary_gid;
2414 become_root();
2415 sid_group = pdb_get_group_sid(pw);
2416 unbecome_root();
2418 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2419 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2420 "which conflicts with the domain sid %s. Failing operation.\n",
2421 pdb_get_username(pw), sid_string_dbg(sid_group),
2422 sid_string_dbg(domain_sid)));
2423 return NT_STATUS_UNSUCCESSFUL;
2426 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2427 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2428 r->primary_gid = primary_gid;
2429 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2430 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2432 return NT_STATUS_OK;
2435 /*************************************************************************
2436 get_user_info_2.
2437 *************************************************************************/
2439 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2440 struct samr_UserInfo2 *r,
2441 struct samu *pw)
2443 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2444 r->unknown.string = NULL;
2445 r->country_code = 0;
2446 r->code_page = 0;
2448 return NT_STATUS_OK;
2451 /*************************************************************************
2452 get_user_info_3.
2453 *************************************************************************/
2455 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2456 struct samr_UserInfo3 *r,
2457 struct samu *pw,
2458 DOM_SID *domain_sid)
2460 const DOM_SID *sid_user, *sid_group;
2461 uint32_t rid, primary_gid;
2463 sid_user = pdb_get_user_sid(pw);
2465 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2466 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2467 "the domain sid %s. Failing operation.\n",
2468 pdb_get_username(pw), sid_string_dbg(sid_user),
2469 sid_string_dbg(domain_sid)));
2470 return NT_STATUS_UNSUCCESSFUL;
2473 become_root();
2474 sid_group = pdb_get_group_sid(pw);
2475 unbecome_root();
2477 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2478 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2479 "which conflicts with the domain sid %s. Failing operation.\n",
2480 pdb_get_username(pw), sid_string_dbg(sid_group),
2481 sid_string_dbg(domain_sid)));
2482 return NT_STATUS_UNSUCCESSFUL;
2485 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2486 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2487 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2488 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2489 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2491 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2492 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2493 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2494 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2495 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2496 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2497 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2499 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2500 r->rid = rid;
2501 r->primary_gid = primary_gid;
2502 r->acct_flags = pdb_get_acct_ctrl(pw);
2503 r->bad_password_count = pdb_get_bad_password_count(pw);
2504 r->logon_count = pdb_get_logon_count(pw);
2506 return NT_STATUS_OK;
2509 /*************************************************************************
2510 get_user_info_4.
2511 *************************************************************************/
2513 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2514 struct samr_UserInfo4 *r,
2515 struct samu *pw)
2517 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2519 return NT_STATUS_OK;
2522 /*************************************************************************
2523 get_user_info_5.
2524 *************************************************************************/
2526 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2527 struct samr_UserInfo5 *r,
2528 struct samu *pw,
2529 DOM_SID *domain_sid)
2531 const DOM_SID *sid_user, *sid_group;
2532 uint32_t rid, primary_gid;
2534 sid_user = pdb_get_user_sid(pw);
2536 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2537 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2538 "the domain sid %s. Failing operation.\n",
2539 pdb_get_username(pw), sid_string_dbg(sid_user),
2540 sid_string_dbg(domain_sid)));
2541 return NT_STATUS_UNSUCCESSFUL;
2544 become_root();
2545 sid_group = pdb_get_group_sid(pw);
2546 unbecome_root();
2548 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2549 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2550 "which conflicts with the domain sid %s. Failing operation.\n",
2551 pdb_get_username(pw), sid_string_dbg(sid_group),
2552 sid_string_dbg(domain_sid)));
2553 return NT_STATUS_UNSUCCESSFUL;
2556 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2557 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2558 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2559 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2561 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2562 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2563 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2564 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2565 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2566 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2567 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2568 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2570 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2571 r->rid = rid;
2572 r->primary_gid = primary_gid;
2573 r->acct_flags = pdb_get_acct_ctrl(pw);
2574 r->bad_password_count = pdb_get_bad_password_count(pw);
2575 r->logon_count = pdb_get_logon_count(pw);
2577 return NT_STATUS_OK;
2580 /*************************************************************************
2581 get_user_info_6.
2582 *************************************************************************/
2584 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2585 struct samr_UserInfo6 *r,
2586 struct samu *pw)
2588 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2589 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2591 return NT_STATUS_OK;
2594 /*************************************************************************
2595 get_user_info_7. Safe. Only gives out account_name.
2596 *************************************************************************/
2598 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2599 struct samr_UserInfo7 *r,
2600 struct samu *smbpass)
2602 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2603 if (!r->account_name.string) {
2604 return NT_STATUS_NO_MEMORY;
2607 return NT_STATUS_OK;
2610 /*************************************************************************
2611 get_user_info_8.
2612 *************************************************************************/
2614 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2615 struct samr_UserInfo8 *r,
2616 struct samu *pw)
2618 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2620 return NT_STATUS_OK;
2623 /*************************************************************************
2624 get_user_info_9. Only gives out primary group SID.
2625 *************************************************************************/
2627 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2628 struct samr_UserInfo9 *r,
2629 struct samu *smbpass)
2631 r->primary_gid = pdb_get_group_rid(smbpass);
2633 return NT_STATUS_OK;
2636 /*************************************************************************
2637 get_user_info_10.
2638 *************************************************************************/
2640 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2641 struct samr_UserInfo10 *r,
2642 struct samu *pw)
2644 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2645 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2647 return NT_STATUS_OK;
2650 /*************************************************************************
2651 get_user_info_11.
2652 *************************************************************************/
2654 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2655 struct samr_UserInfo11 *r,
2656 struct samu *pw)
2658 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2660 return NT_STATUS_OK;
2663 /*************************************************************************
2664 get_user_info_12.
2665 *************************************************************************/
2667 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2668 struct samr_UserInfo12 *r,
2669 struct samu *pw)
2671 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2673 return NT_STATUS_OK;
2676 /*************************************************************************
2677 get_user_info_13.
2678 *************************************************************************/
2680 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2681 struct samr_UserInfo13 *r,
2682 struct samu *pw)
2684 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2686 return NT_STATUS_OK;
2689 /*************************************************************************
2690 get_user_info_14.
2691 *************************************************************************/
2693 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2694 struct samr_UserInfo14 *r,
2695 struct samu *pw)
2697 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2699 return NT_STATUS_OK;
2702 /*************************************************************************
2703 get_user_info_16. Safe. Only gives out acb bits.
2704 *************************************************************************/
2706 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2707 struct samr_UserInfo16 *r,
2708 struct samu *smbpass)
2710 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2712 return NT_STATUS_OK;
2715 /*************************************************************************
2716 get_user_info_17.
2717 *************************************************************************/
2719 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2720 struct samr_UserInfo17 *r,
2721 struct samu *pw)
2723 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2725 return NT_STATUS_OK;
2728 /*************************************************************************
2729 get_user_info_18. OK - this is the killer as it gives out password info.
2730 Ensure that this is only allowed on an encrypted connection with a root
2731 user. JRA.
2732 *************************************************************************/
2734 static NTSTATUS get_user_info_18(pipes_struct *p,
2735 TALLOC_CTX *mem_ctx,
2736 struct samr_UserInfo18 *r,
2737 DOM_SID *user_sid)
2739 struct samu *smbpass=NULL;
2740 bool ret;
2742 ZERO_STRUCTP(r);
2744 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2745 return NT_STATUS_ACCESS_DENIED;
2748 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2749 return NT_STATUS_ACCESS_DENIED;
2753 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2756 if ( !(smbpass = samu_new( mem_ctx )) ) {
2757 return NT_STATUS_NO_MEMORY;
2760 ret = pdb_getsampwsid(smbpass, user_sid);
2762 if (ret == False) {
2763 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2764 TALLOC_FREE(smbpass);
2765 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2768 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2770 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2771 TALLOC_FREE(smbpass);
2772 return NT_STATUS_ACCOUNT_DISABLED;
2775 r->lm_pwd_active = true;
2776 r->nt_pwd_active = true;
2777 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2778 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2779 r->password_expired = 0; /* FIXME */
2781 TALLOC_FREE(smbpass);
2783 return NT_STATUS_OK;
2786 /*************************************************************************
2787 get_user_info_20
2788 *************************************************************************/
2790 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2791 struct samr_UserInfo20 *r,
2792 struct samu *sampass)
2794 const char *munged_dial = NULL;
2795 DATA_BLOB blob;
2796 NTSTATUS status;
2797 struct lsa_BinaryString *parameters = NULL;
2799 ZERO_STRUCTP(r);
2801 munged_dial = pdb_get_munged_dial(sampass);
2803 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2804 munged_dial, (int)strlen(munged_dial)));
2806 if (munged_dial) {
2807 blob = base64_decode_data_blob(munged_dial);
2808 } else {
2809 blob = data_blob_string_const_null("");
2812 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2813 data_blob_free(&blob);
2814 if (!NT_STATUS_IS_OK(status)) {
2815 return status;
2818 r->parameters = *parameters;
2820 return NT_STATUS_OK;
2824 /*************************************************************************
2825 get_user_info_21
2826 *************************************************************************/
2828 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2829 struct samr_UserInfo21 *r,
2830 struct samu *pw,
2831 DOM_SID *domain_sid)
2833 NTSTATUS status;
2834 const DOM_SID *sid_user, *sid_group;
2835 uint32_t rid, primary_gid;
2836 NTTIME force_password_change;
2837 time_t must_change_time;
2838 struct lsa_BinaryString *parameters = NULL;
2839 const char *munged_dial = NULL;
2840 DATA_BLOB blob;
2842 ZERO_STRUCTP(r);
2844 sid_user = pdb_get_user_sid(pw);
2846 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2847 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2848 "the domain sid %s. Failing operation.\n",
2849 pdb_get_username(pw), sid_string_dbg(sid_user),
2850 sid_string_dbg(domain_sid)));
2851 return NT_STATUS_UNSUCCESSFUL;
2854 become_root();
2855 sid_group = pdb_get_group_sid(pw);
2856 unbecome_root();
2858 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2859 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2860 "which conflicts with the domain sid %s. Failing operation.\n",
2861 pdb_get_username(pw), sid_string_dbg(sid_group),
2862 sid_string_dbg(domain_sid)));
2863 return NT_STATUS_UNSUCCESSFUL;
2866 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2867 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2868 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2869 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2870 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2872 must_change_time = pdb_get_pass_must_change_time(pw);
2873 if (must_change_time == get_time_t_max()) {
2874 unix_to_nt_time_abs(&force_password_change, must_change_time);
2875 } else {
2876 unix_to_nt_time(&force_password_change, must_change_time);
2879 munged_dial = pdb_get_munged_dial(pw);
2880 if (munged_dial) {
2881 blob = base64_decode_data_blob(munged_dial);
2882 } else {
2883 blob = data_blob_string_const_null("");
2886 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2887 data_blob_free(&blob);
2888 if (!NT_STATUS_IS_OK(status)) {
2889 return status;
2892 r->force_password_change = force_password_change;
2894 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2895 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2896 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2897 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2898 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2899 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2900 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2901 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2902 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2904 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2905 r->parameters = *parameters;
2906 r->rid = rid;
2907 r->primary_gid = primary_gid;
2908 r->acct_flags = pdb_get_acct_ctrl(pw);
2909 r->bad_password_count = pdb_get_bad_password_count(pw);
2910 r->logon_count = pdb_get_logon_count(pw);
2911 r->fields_present = pdb_build_fields_present(pw);
2912 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2913 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2914 r->country_code = 0;
2915 r->code_page = 0;
2916 r->lm_password_set = 0;
2917 r->nt_password_set = 0;
2919 #if 0
2922 Look at a user on a real NT4 PDC with usrmgr, press
2923 'ok'. Then you will see that fields_present is set to
2924 0x08f827fa. Look at the user immediately after that again,
2925 and you will see that 0x00fffff is returned. This solves
2926 the problem that you get access denied after having looked
2927 at the user.
2928 -- Volker
2931 #endif
2934 return NT_STATUS_OK;
2937 /*******************************************************************
2938 _samr_QueryUserInfo
2939 ********************************************************************/
2941 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2942 struct samr_QueryUserInfo *r)
2944 NTSTATUS status;
2945 union samr_UserInfo *user_info = NULL;
2946 struct samr_info *info = NULL;
2947 DOM_SID domain_sid;
2948 uint32 rid;
2949 bool ret = false;
2950 struct samu *pwd = NULL;
2952 /* search for the handle */
2953 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2954 return NT_STATUS_INVALID_HANDLE;
2956 status = access_check_samr_function(info->acc_granted,
2957 SAMR_USER_ACCESS_GET_ATTRIBUTES,
2958 "_samr_QueryUserInfo");
2959 if (!NT_STATUS_IS_OK(status)) {
2960 return status;
2963 domain_sid = info->sid;
2965 sid_split_rid(&domain_sid, &rid);
2967 if (!sid_check_is_in_our_domain(&info->sid))
2968 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2970 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2971 sid_string_dbg(&info->sid)));
2973 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2974 if (!user_info) {
2975 return NT_STATUS_NO_MEMORY;
2978 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2980 if (!(pwd = samu_new(p->mem_ctx))) {
2981 return NT_STATUS_NO_MEMORY;
2984 become_root();
2985 ret = pdb_getsampwsid(pwd, &info->sid);
2986 unbecome_root();
2988 if (ret == false) {
2989 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2990 TALLOC_FREE(pwd);
2991 return NT_STATUS_NO_SUCH_USER;
2994 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2996 samr_clear_sam_passwd(pwd);
2998 switch (r->in.level) {
2999 case 1:
3000 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3001 break;
3002 case 2:
3003 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3004 break;
3005 case 3:
3006 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3007 break;
3008 case 4:
3009 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3010 break;
3011 case 5:
3012 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3013 break;
3014 case 6:
3015 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3016 break;
3017 case 7:
3018 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3019 break;
3020 case 8:
3021 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3022 break;
3023 case 9:
3024 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3025 break;
3026 case 10:
3027 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3028 break;
3029 case 11:
3030 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3031 break;
3032 case 12:
3033 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3034 break;
3035 case 13:
3036 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3037 break;
3038 case 14:
3039 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3040 break;
3041 case 16:
3042 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3043 break;
3044 case 17:
3045 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3046 break;
3047 case 18:
3048 /* level 18 is special */
3049 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
3050 break;
3051 case 20:
3052 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3053 break;
3054 case 21:
3055 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
3056 break;
3057 default:
3058 status = NT_STATUS_INVALID_INFO_CLASS;
3059 break;
3062 TALLOC_FREE(pwd);
3064 *r->out.info = user_info;
3066 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3068 return status;
3071 /****************************************************************
3072 ****************************************************************/
3074 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3075 struct samr_QueryUserInfo2 *r)
3077 struct samr_QueryUserInfo u;
3079 u.in.user_handle = r->in.user_handle;
3080 u.in.level = r->in.level;
3081 u.out.info = r->out.info;
3083 return _samr_QueryUserInfo(p, &u);
3086 /*******************************************************************
3087 _samr_GetGroupsForUser
3088 ********************************************************************/
3090 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3091 struct samr_GetGroupsForUser *r)
3093 struct samu *sam_pass=NULL;
3094 DOM_SID sid;
3095 DOM_SID *sids;
3096 struct samr_RidWithAttribute dom_gid;
3097 struct samr_RidWithAttribute *gids = NULL;
3098 uint32 primary_group_rid;
3099 size_t num_groups = 0;
3100 gid_t *unix_gids;
3101 size_t i, num_gids;
3102 uint32 acc_granted;
3103 bool ret;
3104 NTSTATUS result;
3105 bool success = False;
3107 struct samr_RidWithAttributeArray *rids = NULL;
3110 * from the SID in the request:
3111 * we should send back the list of DOMAIN GROUPS
3112 * the user is a member of
3114 * and only the DOMAIN GROUPS
3115 * no ALIASES !!! neither aliases of the domain
3116 * nor aliases of the builtin SID
3118 * JFM, 12/2/2001
3121 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3123 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3124 if (!rids) {
3125 return NT_STATUS_NO_MEMORY;
3128 /* find the policy handle. open a policy on it. */
3129 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
3130 return NT_STATUS_INVALID_HANDLE;
3132 result = access_check_samr_function(acc_granted,
3133 SAMR_USER_ACCESS_GET_GROUPS,
3134 "_samr_GetGroupsForUser");
3135 if (!NT_STATUS_IS_OK(result)) {
3136 return result;
3139 if (!sid_check_is_in_our_domain(&sid))
3140 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3142 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3143 return NT_STATUS_NO_MEMORY;
3146 become_root();
3147 ret = pdb_getsampwsid(sam_pass, &sid);
3148 unbecome_root();
3150 if (!ret) {
3151 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3152 sid_string_dbg(&sid)));
3153 return NT_STATUS_NO_SUCH_USER;
3156 sids = NULL;
3158 /* make both calls inside the root block */
3159 become_root();
3160 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3161 &sids, &unix_gids, &num_groups);
3162 if ( NT_STATUS_IS_OK(result) ) {
3163 success = sid_peek_check_rid(get_global_sam_sid(),
3164 pdb_get_group_sid(sam_pass),
3165 &primary_group_rid);
3167 unbecome_root();
3169 if (!NT_STATUS_IS_OK(result)) {
3170 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3171 sid_string_dbg(&sid)));
3172 return result;
3175 if ( !success ) {
3176 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3177 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3178 pdb_get_username(sam_pass)));
3179 TALLOC_FREE(sam_pass);
3180 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3183 gids = NULL;
3184 num_gids = 0;
3186 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3187 SE_GROUP_ENABLED);
3188 dom_gid.rid = primary_group_rid;
3189 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3191 for (i=0; i<num_groups; i++) {
3193 if (!sid_peek_check_rid(get_global_sam_sid(),
3194 &(sids[i]), &dom_gid.rid)) {
3195 DEBUG(10, ("Found sid %s not in our domain\n",
3196 sid_string_dbg(&sids[i])));
3197 continue;
3200 if (dom_gid.rid == primary_group_rid) {
3201 /* We added the primary group directly from the
3202 * sam_account. The other SIDs are unique from
3203 * enum_group_memberships */
3204 continue;
3207 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3210 rids->count = num_gids;
3211 rids->rids = gids;
3213 *r->out.rids = rids;
3215 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3217 return result;
3220 /*******************************************************************
3221 _samr_QueryDomainInfo
3222 ********************************************************************/
3224 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3225 struct samr_QueryDomainInfo *r)
3227 NTSTATUS status = NT_STATUS_OK;
3228 struct samr_info *info = NULL;
3229 union samr_DomainInfo *dom_info;
3230 time_t u_expire, u_min_age;
3232 time_t u_lock_duration, u_reset_time;
3233 uint32_t u_logout;
3235 uint32 account_policy_temp;
3237 time_t seq_num;
3238 uint32 server_role;
3240 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3242 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3243 if (!dom_info) {
3244 return NT_STATUS_NO_MEMORY;
3247 /* find the policy handle. open a policy on it. */
3248 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
3249 return NT_STATUS_INVALID_HANDLE;
3252 status = access_check_samr_function(info->acc_granted,
3253 SAMR_ACCESS_LOOKUP_DOMAIN,
3254 "_samr_QueryDomainInfo" );
3256 if ( !NT_STATUS_IS_OK(status) )
3257 return status;
3259 switch (r->in.level) {
3260 case 0x01:
3262 become_root();
3264 /* AS ROOT !!! */
3266 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
3267 &account_policy_temp);
3268 dom_info->info1.min_password_length = account_policy_temp;
3270 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
3271 dom_info->info1.password_history_length = account_policy_temp;
3273 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
3274 &dom_info->info1.password_properties);
3276 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
3277 u_expire = account_policy_temp;
3279 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
3280 u_min_age = account_policy_temp;
3282 /* !AS ROOT */
3284 unbecome_root();
3286 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
3287 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
3289 if (lp_check_password_script() && *lp_check_password_script()) {
3290 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
3293 break;
3294 case 0x02:
3296 become_root();
3298 /* AS ROOT !!! */
3300 dom_info->general.num_users = count_sam_users(info->disp_info, ACB_NORMAL);
3301 dom_info->general.num_groups = count_sam_groups(info->disp_info);
3302 dom_info->general.num_aliases = count_sam_aliases(info->disp_info);
3304 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3306 unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
3308 if (!pdb_get_seq_num(&seq_num))
3309 seq_num = time(NULL);
3311 /* !AS ROOT */
3313 unbecome_root();
3315 server_role = ROLE_DOMAIN_PDC;
3316 if (lp_server_role() == ROLE_DOMAIN_BDC)
3317 server_role = ROLE_DOMAIN_BDC;
3319 dom_info->general.oem_information.string = lp_serverstring();
3320 dom_info->general.domain_name.string = lp_workgroup();
3321 dom_info->general.primary.string = global_myname();
3322 dom_info->general.sequence_num = seq_num;
3323 dom_info->general.domain_server_state = DOMAIN_SERVER_ENABLED;
3324 dom_info->general.role = server_role;
3325 dom_info->general.unknown3 = 1;
3327 break;
3328 case 0x03:
3330 become_root();
3332 /* AS ROOT !!! */
3335 uint32 ul;
3336 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3337 u_logout = (time_t)ul;
3340 /* !AS ROOT */
3342 unbecome_root();
3344 unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
3346 break;
3347 case 0x04:
3348 dom_info->oem.oem_information.string = lp_serverstring();
3349 break;
3350 case 0x05:
3351 dom_info->info5.domain_name.string = get_global_sam_name();
3352 break;
3353 case 0x06:
3354 /* NT returns its own name when a PDC. win2k and later
3355 * only the name of the PDC if itself is a BDC (samba4
3356 * idl) */
3357 dom_info->info6.primary.string = global_myname();
3358 break;
3359 case 0x07:
3360 server_role = ROLE_DOMAIN_PDC;
3361 if (lp_server_role() == ROLE_DOMAIN_BDC)
3362 server_role = ROLE_DOMAIN_BDC;
3364 dom_info->info7.role = server_role;
3365 break;
3366 case 0x08:
3368 become_root();
3370 /* AS ROOT !!! */
3372 if (!pdb_get_seq_num(&seq_num)) {
3373 seq_num = time(NULL);
3376 /* !AS ROOT */
3378 unbecome_root();
3380 dom_info->info8.sequence_num = seq_num;
3381 dom_info->info8.domain_create_time = 0;
3383 break;
3384 case 0x0c:
3386 become_root();
3388 /* AS ROOT !!! */
3390 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3391 u_lock_duration = account_policy_temp;
3392 if (u_lock_duration != -1) {
3393 u_lock_duration *= 60;
3396 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3397 u_reset_time = account_policy_temp * 60;
3399 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3400 &account_policy_temp);
3401 dom_info->info12.lockout_threshold = account_policy_temp;
3403 /* !AS ROOT */
3405 unbecome_root();
3407 unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
3408 u_lock_duration);
3409 unix_to_nt_time_abs(&dom_info->info12.lockout_window,
3410 u_reset_time);
3412 break;
3413 default:
3414 return NT_STATUS_INVALID_INFO_CLASS;
3417 *r->out.info = dom_info;
3419 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3421 return status;
3424 /* W2k3 seems to use the same check for all 3 objects that can be created via
3425 * SAMR, if you try to create for example "Dialup" as an alias it says
3426 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3427 * database. */
3429 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3431 enum lsa_SidType type;
3432 bool result;
3434 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3436 become_root();
3437 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3438 * whether the name already exists */
3439 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3440 NULL, NULL, NULL, &type);
3441 unbecome_root();
3443 if (!result) {
3444 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3445 return NT_STATUS_OK;
3448 DEBUG(5, ("trying to create %s, exists as %s\n",
3449 new_name, sid_type_lookup(type)));
3451 if (type == SID_NAME_DOM_GRP) {
3452 return NT_STATUS_GROUP_EXISTS;
3454 if (type == SID_NAME_ALIAS) {
3455 return NT_STATUS_ALIAS_EXISTS;
3458 /* Yes, the default is NT_STATUS_USER_EXISTS */
3459 return NT_STATUS_USER_EXISTS;
3462 /*******************************************************************
3463 _samr_CreateUser2
3464 ********************************************************************/
3466 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3467 struct samr_CreateUser2 *r)
3469 const char *account = NULL;
3470 DOM_SID sid;
3471 uint32_t acb_info = r->in.acct_flags;
3472 struct samr_info *info = NULL;
3473 NTSTATUS nt_status;
3474 uint32 acc_granted;
3475 SEC_DESC *psd;
3476 size_t sd_size;
3477 /* check this, when giving away 'add computer to domain' privs */
3478 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3479 bool can_add_account = False;
3480 SE_PRIV se_rights;
3481 DISP_INFO *disp_info = NULL;
3483 /* Get the domain SID stored in the domain policy */
3484 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted,
3485 &disp_info))
3486 return NT_STATUS_INVALID_HANDLE;
3488 if (disp_info->builtin_domain) {
3489 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3490 return NT_STATUS_ACCESS_DENIED;
3493 nt_status = access_check_samr_function(acc_granted,
3494 SAMR_DOMAIN_ACCESS_CREATE_USER,
3495 "_samr_CreateUser2");
3496 if (!NT_STATUS_IS_OK(nt_status)) {
3497 return nt_status;
3500 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3501 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3502 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3503 this parameter is not an account type */
3504 return NT_STATUS_INVALID_PARAMETER;
3507 account = r->in.account_name->string;
3508 if (account == NULL) {
3509 return NT_STATUS_NO_MEMORY;
3512 nt_status = can_create(p->mem_ctx, account);
3513 if (!NT_STATUS_IS_OK(nt_status)) {
3514 return nt_status;
3517 /* determine which user right we need to check based on the acb_info */
3519 if ( acb_info & ACB_WSTRUST )
3521 se_priv_copy( &se_rights, &se_machine_account );
3522 can_add_account = user_has_privileges(
3523 p->server_info->ptok, &se_rights );
3525 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3526 account for domain trusts and changes the ACB flags later */
3527 else if ( acb_info & ACB_NORMAL &&
3528 (account[strlen(account)-1] != '$') )
3530 se_priv_copy( &se_rights, &se_add_users );
3531 can_add_account = user_has_privileges(
3532 p->server_info->ptok, &se_rights );
3534 else /* implicit assumption of a BDC or domain trust account here
3535 * (we already check the flags earlier) */
3537 if ( lp_enable_privileges() ) {
3538 /* only Domain Admins can add a BDC or domain trust */
3539 se_priv_copy( &se_rights, &se_priv_none );
3540 can_add_account = nt_token_check_domain_rid(
3541 p->server_info->ptok,
3542 DOMAIN_GROUP_RID_ADMINS );
3546 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3547 uidtoname(p->server_info->utok.uid),
3548 can_add_account ? "True":"False" ));
3550 /********** BEGIN Admin BLOCK **********/
3552 if ( can_add_account )
3553 become_root();
3555 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3556 r->out.rid);
3558 if ( can_add_account )
3559 unbecome_root();
3561 /********** END Admin BLOCK **********/
3563 /* now check for failure */
3565 if ( !NT_STATUS_IS_OK(nt_status) )
3566 return nt_status;
3568 /* Get the user's SID */
3570 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3572 map_max_allowed_access(p->server_info->ptok, &des_access);
3574 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3575 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3576 se_map_generic(&des_access, &usr_generic_mapping);
3578 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3579 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3580 &acc_granted, "_samr_CreateUser2");
3582 if ( !NT_STATUS_IS_OK(nt_status) ) {
3583 return nt_status;
3586 /* associate the user's SID with the new handle. */
3587 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL) {
3588 return NT_STATUS_NO_MEMORY;
3591 ZERO_STRUCTP(info);
3592 info->sid = sid;
3593 info->acc_granted = acc_granted;
3595 /* get a (unique) handle. open a policy on it. */
3596 if (!create_policy_hnd(p, r->out.user_handle, info)) {
3597 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3600 /* After a "set" ensure we have no cached display info. */
3601 force_flush_samr_cache(info->disp_info);
3603 *r->out.access_granted = acc_granted;
3605 return NT_STATUS_OK;
3608 /****************************************************************
3609 ****************************************************************/
3611 NTSTATUS _samr_CreateUser(pipes_struct *p,
3612 struct samr_CreateUser *r)
3614 struct samr_CreateUser2 c;
3615 uint32_t access_granted;
3617 c.in.domain_handle = r->in.domain_handle;
3618 c.in.account_name = r->in.account_name;
3619 c.in.acct_flags = ACB_NORMAL;
3620 c.in.access_mask = r->in.access_mask;
3621 c.out.user_handle = r->out.user_handle;
3622 c.out.access_granted = &access_granted;
3623 c.out.rid = r->out.rid;
3625 return _samr_CreateUser2(p, &c);
3628 /*******************************************************************
3629 _samr_Connect
3630 ********************************************************************/
3632 NTSTATUS _samr_Connect(pipes_struct *p,
3633 struct samr_Connect *r)
3635 struct samr_info *info = NULL;
3636 uint32 des_access = r->in.access_mask;
3638 /* Access check */
3640 if (!pipe_access_check(p)) {
3641 DEBUG(3, ("access denied to _samr_Connect\n"));
3642 return NT_STATUS_ACCESS_DENIED;
3645 /* set up the SAMR connect_anon response */
3647 /* associate the user's SID with the new handle. */
3648 if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
3649 return NT_STATUS_NO_MEMORY;
3651 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3652 was observed from a win98 client trying to enumerate users (when configured
3653 user level access control on shares) --jerry */
3655 map_max_allowed_access(p->server_info->ptok, &des_access);
3657 se_map_generic( &des_access, &sam_generic_mapping );
3658 info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_LOOKUP_DOMAIN);
3660 /* get a (unique) handle. open a policy on it. */
3661 if (!create_policy_hnd(p, r->out.connect_handle, info))
3662 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3664 return NT_STATUS_OK;
3667 /*******************************************************************
3668 _samr_Connect2
3669 ********************************************************************/
3671 NTSTATUS _samr_Connect2(pipes_struct *p,
3672 struct samr_Connect2 *r)
3674 struct samr_info *info = NULL;
3675 SEC_DESC *psd = NULL;
3676 uint32 acc_granted;
3677 uint32 des_access = r->in.access_mask;
3678 NTSTATUS nt_status;
3679 size_t sd_size;
3680 const char *fn = "_samr_Connect2";
3682 switch (p->hdr_req.opnum) {
3683 case NDR_SAMR_CONNECT2:
3684 fn = "_samr_Connect2";
3685 break;
3686 case NDR_SAMR_CONNECT3:
3687 fn = "_samr_Connect3";
3688 break;
3689 case NDR_SAMR_CONNECT4:
3690 fn = "_samr_Connect4";
3691 break;
3692 case NDR_SAMR_CONNECT5:
3693 fn = "_samr_Connect5";
3694 break;
3697 DEBUG(5,("%s: %d\n", fn, __LINE__));
3699 /* Access check */
3701 if (!pipe_access_check(p)) {
3702 DEBUG(3, ("access denied to %s\n", fn));
3703 return NT_STATUS_ACCESS_DENIED;
3706 map_max_allowed_access(p->server_info->ptok, &des_access);
3708 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3709 se_map_generic(&des_access, &sam_generic_mapping);
3711 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3712 NULL, 0, des_access, &acc_granted, fn);
3714 if ( !NT_STATUS_IS_OK(nt_status) )
3715 return nt_status;
3717 /* associate the user's SID and access granted with the new handle. */
3718 if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
3719 return NT_STATUS_NO_MEMORY;
3721 info->acc_granted = acc_granted;
3722 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3724 /* get a (unique) handle. open a policy on it. */
3725 if (!create_policy_hnd(p, r->out.connect_handle, info))
3726 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3728 DEBUG(5,("%s: %d\n", fn, __LINE__));
3730 return nt_status;
3733 /****************************************************************
3734 _samr_Connect3
3735 ****************************************************************/
3737 NTSTATUS _samr_Connect3(pipes_struct *p,
3738 struct samr_Connect3 *r)
3740 struct samr_Connect2 c;
3742 c.in.system_name = r->in.system_name;
3743 c.in.access_mask = r->in.access_mask;
3744 c.out.connect_handle = r->out.connect_handle;
3746 return _samr_Connect2(p, &c);
3749 /*******************************************************************
3750 _samr_Connect4
3751 ********************************************************************/
3753 NTSTATUS _samr_Connect4(pipes_struct *p,
3754 struct samr_Connect4 *r)
3756 struct samr_Connect2 c;
3758 c.in.system_name = r->in.system_name;
3759 c.in.access_mask = r->in.access_mask;
3760 c.out.connect_handle = r->out.connect_handle;
3762 return _samr_Connect2(p, &c);
3765 /*******************************************************************
3766 _samr_Connect5
3767 ********************************************************************/
3769 NTSTATUS _samr_Connect5(pipes_struct *p,
3770 struct samr_Connect5 *r)
3772 NTSTATUS status;
3773 struct samr_Connect2 c;
3774 struct samr_ConnectInfo1 info1;
3776 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3777 info1.unknown2 = 0;
3779 c.in.system_name = r->in.system_name;
3780 c.in.access_mask = r->in.access_mask;
3781 c.out.connect_handle = r->out.connect_handle;
3783 *r->out.level_out = 1;
3785 status = _samr_Connect2(p, &c);
3786 if (!NT_STATUS_IS_OK(status)) {
3787 return status;
3790 r->out.info_out->info1 = info1;
3792 return NT_STATUS_OK;
3795 /**********************************************************************
3796 _samr_LookupDomain
3797 **********************************************************************/
3799 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3800 struct samr_LookupDomain *r)
3802 NTSTATUS status = NT_STATUS_OK;
3803 struct samr_info *info;
3804 const char *domain_name;
3805 DOM_SID *sid = NULL;
3807 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3808 return NT_STATUS_INVALID_HANDLE;
3810 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3811 Reverted that change so we will work with RAS servers again */
3813 status = access_check_samr_function(info->acc_granted,
3814 SAMR_ACCESS_LOOKUP_DOMAIN,
3815 "_samr_LookupDomain");
3816 if (!NT_STATUS_IS_OK(status)) {
3817 return status;
3820 domain_name = r->in.domain_name->string;
3821 if (!domain_name) {
3822 return NT_STATUS_INVALID_PARAMETER;
3825 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3826 if (!sid) {
3827 return NT_STATUS_NO_MEMORY;
3830 if (strequal(domain_name, builtin_domain_name())) {
3831 sid_copy(sid, &global_sid_Builtin);
3832 } else {
3833 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3834 status = NT_STATUS_NO_SUCH_DOMAIN;
3838 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3839 sid_string_dbg(sid)));
3841 *r->out.sid = sid;
3843 return status;
3846 /**********************************************************************
3847 _samr_EnumDomains
3848 **********************************************************************/
3850 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3851 struct samr_EnumDomains *r)
3853 NTSTATUS status;
3854 struct samr_info *info;
3855 uint32_t num_entries = 2;
3856 struct samr_SamEntry *entry_array = NULL;
3857 struct samr_SamArray *sam;
3859 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3860 return NT_STATUS_INVALID_HANDLE;
3862 status = access_check_samr_function(info->acc_granted,
3863 SAMR_ACCESS_ENUM_DOMAINS,
3864 "_samr_EnumDomains");
3865 if (!NT_STATUS_IS_OK(status)) {
3866 return status;
3869 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3870 if (!sam) {
3871 return NT_STATUS_NO_MEMORY;
3874 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3875 struct samr_SamEntry,
3876 num_entries);
3877 if (!entry_array) {
3878 return NT_STATUS_NO_MEMORY;
3881 entry_array[0].idx = 0;
3882 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3884 entry_array[1].idx = 1;
3885 init_lsa_String(&entry_array[1].name, "Builtin");
3887 sam->count = num_entries;
3888 sam->entries = entry_array;
3890 *r->out.sam = sam;
3891 *r->out.num_entries = num_entries;
3893 return status;
3896 /*******************************************************************
3897 _samr_OpenAlias
3898 ********************************************************************/
3900 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3901 struct samr_OpenAlias *r)
3903 DOM_SID sid;
3904 uint32 alias_rid = r->in.rid;
3905 struct samr_info *info = NULL;
3906 SEC_DESC *psd = NULL;
3907 uint32 acc_granted;
3908 uint32 des_access = r->in.access_mask;
3909 size_t sd_size;
3910 NTSTATUS status;
3911 SE_PRIV se_rights;
3913 /* find the domain policy and get the SID / access bits stored in the domain policy */
3915 if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
3916 return NT_STATUS_INVALID_HANDLE;
3918 status = access_check_samr_function(acc_granted,
3919 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3920 "_samr_OpenAlias");
3922 if ( !NT_STATUS_IS_OK(status) )
3923 return status;
3925 /* append the alias' RID to it */
3927 if (!sid_append_rid(&sid, alias_rid))
3928 return NT_STATUS_NO_SUCH_ALIAS;
3930 /*check if access can be granted as requested by client. */
3932 map_max_allowed_access(p->server_info->ptok, &des_access);
3934 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3935 se_map_generic(&des_access,&ali_generic_mapping);
3937 se_priv_copy( &se_rights, &se_add_users );
3940 status = access_check_samr_object(psd, p->server_info->ptok,
3941 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3942 &acc_granted, "_samr_OpenAlias");
3944 if ( !NT_STATUS_IS_OK(status) )
3945 return status;
3948 /* Check we actually have the requested alias */
3949 enum lsa_SidType type;
3950 bool result;
3951 gid_t gid;
3953 become_root();
3954 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3955 unbecome_root();
3957 if (!result || (type != SID_NAME_ALIAS)) {
3958 return NT_STATUS_NO_SUCH_ALIAS;
3961 /* make sure there is a mapping */
3963 if ( !sid_to_gid( &sid, &gid ) ) {
3964 return NT_STATUS_NO_SUCH_ALIAS;
3969 /* associate the alias SID with the new handle. */
3970 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
3971 return NT_STATUS_NO_MEMORY;
3973 info->acc_granted = acc_granted;
3975 /* get a (unique) handle. open a policy on it. */
3976 if (!create_policy_hnd(p, r->out.alias_handle, info))
3977 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3979 return NT_STATUS_OK;
3982 /*******************************************************************
3983 set_user_info_2
3984 ********************************************************************/
3986 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
3987 struct samr_UserInfo2 *id2,
3988 struct samu *pwd)
3990 if (id2 == NULL) {
3991 DEBUG(5,("set_user_info_2: NULL id2\n"));
3992 return NT_STATUS_ACCESS_DENIED;
3995 copy_id2_to_sam_passwd(pwd, id2);
3997 return pdb_update_sam_account(pwd);
4000 /*******************************************************************
4001 set_user_info_4
4002 ********************************************************************/
4004 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4005 struct samr_UserInfo4 *id4,
4006 struct samu *pwd)
4008 if (id4 == NULL) {
4009 DEBUG(5,("set_user_info_2: NULL id4\n"));
4010 return NT_STATUS_ACCESS_DENIED;
4013 copy_id4_to_sam_passwd(pwd, id4);
4015 return pdb_update_sam_account(pwd);
4018 /*******************************************************************
4019 set_user_info_6
4020 ********************************************************************/
4022 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4023 struct samr_UserInfo6 *id6,
4024 struct samu *pwd)
4026 if (id6 == NULL) {
4027 DEBUG(5,("set_user_info_6: NULL id6\n"));
4028 return NT_STATUS_ACCESS_DENIED;
4031 copy_id6_to_sam_passwd(pwd, id6);
4033 return pdb_update_sam_account(pwd);
4036 /*******************************************************************
4037 set_user_info_7
4038 ********************************************************************/
4040 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4041 struct samr_UserInfo7 *id7,
4042 struct samu *pwd)
4044 NTSTATUS rc;
4046 if (id7 == NULL) {
4047 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4048 return NT_STATUS_ACCESS_DENIED;
4051 if (!id7->account_name.string) {
4052 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4053 return NT_STATUS_ACCESS_DENIED;
4056 /* check to see if the new username already exists. Note: we can't
4057 reliably lock all backends, so there is potentially the
4058 possibility that a user can be created in between this check and
4059 the rename. The rename should fail, but may not get the
4060 exact same failure status code. I think this is small enough
4061 of a window for this type of operation and the results are
4062 simply that the rename fails with a slightly different status
4063 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4065 rc = can_create(mem_ctx, id7->account_name.string);
4066 if (!NT_STATUS_IS_OK(rc)) {
4067 return rc;
4070 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4072 return rc;
4075 /*******************************************************************
4076 set_user_info_8
4077 ********************************************************************/
4079 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4080 struct samr_UserInfo8 *id8,
4081 struct samu *pwd)
4083 if (id8 == NULL) {
4084 DEBUG(5,("set_user_info_8: NULL id8\n"));
4085 return NT_STATUS_ACCESS_DENIED;
4088 copy_id8_to_sam_passwd(pwd, id8);
4090 return pdb_update_sam_account(pwd);
4093 /*******************************************************************
4094 set_user_info_10
4095 ********************************************************************/
4097 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4098 struct samr_UserInfo10 *id10,
4099 struct samu *pwd)
4101 if (id10 == NULL) {
4102 DEBUG(5,("set_user_info_8: NULL id10\n"));
4103 return NT_STATUS_ACCESS_DENIED;
4106 copy_id10_to_sam_passwd(pwd, id10);
4108 return pdb_update_sam_account(pwd);
4111 /*******************************************************************
4112 set_user_info_11
4113 ********************************************************************/
4115 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4116 struct samr_UserInfo11 *id11,
4117 struct samu *pwd)
4119 if (id11 == NULL) {
4120 DEBUG(5,("set_user_info_11: NULL id11\n"));
4121 return NT_STATUS_ACCESS_DENIED;
4124 copy_id11_to_sam_passwd(pwd, id11);
4126 return pdb_update_sam_account(pwd);
4129 /*******************************************************************
4130 set_user_info_12
4131 ********************************************************************/
4133 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4134 struct samr_UserInfo12 *id12,
4135 struct samu *pwd)
4137 if (id12 == NULL) {
4138 DEBUG(5,("set_user_info_12: NULL id12\n"));
4139 return NT_STATUS_ACCESS_DENIED;
4142 copy_id12_to_sam_passwd(pwd, id12);
4144 return pdb_update_sam_account(pwd);
4147 /*******************************************************************
4148 set_user_info_13
4149 ********************************************************************/
4151 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4152 struct samr_UserInfo13 *id13,
4153 struct samu *pwd)
4155 if (id13 == NULL) {
4156 DEBUG(5,("set_user_info_13: NULL id13\n"));
4157 return NT_STATUS_ACCESS_DENIED;
4160 copy_id13_to_sam_passwd(pwd, id13);
4162 return pdb_update_sam_account(pwd);
4165 /*******************************************************************
4166 set_user_info_14
4167 ********************************************************************/
4169 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4170 struct samr_UserInfo14 *id14,
4171 struct samu *pwd)
4173 if (id14 == NULL) {
4174 DEBUG(5,("set_user_info_14: NULL id14\n"));
4175 return NT_STATUS_ACCESS_DENIED;
4178 copy_id14_to_sam_passwd(pwd, id14);
4180 return pdb_update_sam_account(pwd);
4183 /*******************************************************************
4184 set_user_info_16
4185 ********************************************************************/
4187 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4188 struct samr_UserInfo16 *id16,
4189 struct samu *pwd)
4191 if (id16 == NULL) {
4192 DEBUG(5,("set_user_info_16: NULL id16\n"));
4193 return NT_STATUS_ACCESS_DENIED;
4196 copy_id16_to_sam_passwd(pwd, id16);
4198 return pdb_update_sam_account(pwd);
4201 /*******************************************************************
4202 set_user_info_17
4203 ********************************************************************/
4205 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4206 struct samr_UserInfo17 *id17,
4207 struct samu *pwd)
4209 if (id17 == NULL) {
4210 DEBUG(5,("set_user_info_17: NULL id17\n"));
4211 return NT_STATUS_ACCESS_DENIED;
4214 copy_id17_to_sam_passwd(pwd, id17);
4216 return pdb_update_sam_account(pwd);
4219 /*******************************************************************
4220 set_user_info_18
4221 ********************************************************************/
4223 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4224 TALLOC_CTX *mem_ctx,
4225 DATA_BLOB *session_key,
4226 struct samu *pwd)
4228 if (id18 == NULL) {
4229 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4230 return NT_STATUS_INVALID_PARAMETER;
4233 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4234 if (!session_key->length) {
4235 return NT_STATUS_NO_USER_SESSION_KEY;
4239 if (id18->nt_pwd_active) {
4241 DATA_BLOB in, out;
4243 in = data_blob_const(id18->nt_pwd.hash, 16);
4244 out = data_blob_talloc_zero(mem_ctx, 16);
4246 sess_crypt_blob(&out, &in, session_key, false);
4248 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4249 return NT_STATUS_ACCESS_DENIED;
4252 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4255 if (id18->lm_pwd_active) {
4257 DATA_BLOB in, out;
4259 in = data_blob_const(id18->lm_pwd.hash, 16);
4260 out = data_blob_talloc_zero(mem_ctx, 16);
4262 sess_crypt_blob(&out, &in, session_key, false);
4264 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4265 return NT_STATUS_ACCESS_DENIED;
4268 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4271 copy_id18_to_sam_passwd(pwd, id18);
4273 return pdb_update_sam_account(pwd);
4276 /*******************************************************************
4277 set_user_info_20
4278 ********************************************************************/
4280 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4281 struct samr_UserInfo20 *id20,
4282 struct samu *pwd)
4284 if (id20 == NULL) {
4285 DEBUG(5,("set_user_info_20: NULL id20\n"));
4286 return NT_STATUS_ACCESS_DENIED;
4289 copy_id20_to_sam_passwd(pwd, id20);
4291 return pdb_update_sam_account(pwd);
4294 /*******************************************************************
4295 set_user_info_21
4296 ********************************************************************/
4298 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4299 TALLOC_CTX *mem_ctx,
4300 DATA_BLOB *session_key,
4301 struct samu *pwd)
4303 NTSTATUS status;
4305 if (id21 == NULL) {
4306 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4307 return NT_STATUS_INVALID_PARAMETER;
4310 if (id21->fields_present == 0) {
4311 return NT_STATUS_INVALID_PARAMETER;
4314 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4315 return NT_STATUS_ACCESS_DENIED;
4318 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4319 if (id21->nt_password_set) {
4320 DATA_BLOB in, out;
4322 if ((id21->nt_owf_password.length != 16) ||
4323 (id21->nt_owf_password.size != 16)) {
4324 return NT_STATUS_INVALID_PARAMETER;
4327 if (!session_key->length) {
4328 return NT_STATUS_NO_USER_SESSION_KEY;
4331 in = data_blob_const(id21->nt_owf_password.array, 16);
4332 out = data_blob_talloc_zero(mem_ctx, 16);
4334 sess_crypt_blob(&out, &in, session_key, false);
4336 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4337 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4341 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4342 if (id21->lm_password_set) {
4343 DATA_BLOB in, out;
4345 if ((id21->lm_owf_password.length != 16) ||
4346 (id21->lm_owf_password.size != 16)) {
4347 return NT_STATUS_INVALID_PARAMETER;
4350 if (!session_key->length) {
4351 return NT_STATUS_NO_USER_SESSION_KEY;
4354 in = data_blob_const(id21->lm_owf_password.array, 16);
4355 out = data_blob_talloc_zero(mem_ctx, 16);
4357 sess_crypt_blob(&out, &in, session_key, false);
4359 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4360 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4364 /* we need to separately check for an account rename first */
4366 if (id21->account_name.string &&
4367 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4370 /* check to see if the new username already exists. Note: we can't
4371 reliably lock all backends, so there is potentially the
4372 possibility that a user can be created in between this check and
4373 the rename. The rename should fail, but may not get the
4374 exact same failure status code. I think this is small enough
4375 of a window for this type of operation and the results are
4376 simply that the rename fails with a slightly different status
4377 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4379 status = can_create(mem_ctx, id21->account_name.string);
4380 if (!NT_STATUS_IS_OK(status)) {
4381 return status;
4384 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4386 if (!NT_STATUS_IS_OK(status)) {
4387 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4388 nt_errstr(status)));
4389 return status;
4392 /* set the new username so that later
4393 functions can work on the new account */
4394 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4397 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4400 * The funny part about the previous two calls is
4401 * that pwd still has the password hashes from the
4402 * passdb entry. These have not been updated from
4403 * id21. I don't know if they need to be set. --jerry
4406 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4407 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4408 if ( !NT_STATUS_IS_OK(status) ) {
4409 return status;
4413 /* Don't worry about writing out the user account since the
4414 primary group SID is generated solely from the user's Unix
4415 primary group. */
4417 /* write the change out */
4418 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4419 return status;
4422 return NT_STATUS_OK;
4425 /*******************************************************************
4426 set_user_info_23
4427 ********************************************************************/
4429 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4430 struct samr_UserInfo23 *id23,
4431 struct samu *pwd)
4433 char *plaintext_buf = NULL;
4434 uint32 len = 0;
4435 uint32_t acct_ctrl;
4436 NTSTATUS status;
4438 if (id23 == NULL) {
4439 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4440 return NT_STATUS_INVALID_PARAMETER;
4443 if (id23->info.fields_present == 0) {
4444 return NT_STATUS_INVALID_PARAMETER;
4447 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4448 return NT_STATUS_ACCESS_DENIED;
4451 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4452 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4454 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4455 pdb_get_username(pwd)));
4457 if (!decode_pw_buffer(mem_ctx,
4458 id23->password.data,
4459 &plaintext_buf,
4460 &len,
4461 STR_UNICODE)) {
4462 return NT_STATUS_WRONG_PASSWORD;
4465 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4466 return NT_STATUS_ACCESS_DENIED;
4470 copy_id23_to_sam_passwd(pwd, id23);
4472 acct_ctrl = pdb_get_acct_ctrl(pwd);
4474 /* if it's a trust account, don't update /etc/passwd */
4475 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4476 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4477 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4478 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4479 } else if (plaintext_buf) {
4480 /* update the UNIX password */
4481 if (lp_unix_password_sync() ) {
4482 struct passwd *passwd;
4483 if (pdb_get_username(pwd) == NULL) {
4484 DEBUG(1, ("chgpasswd: User without name???\n"));
4485 return NT_STATUS_ACCESS_DENIED;
4488 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4489 if (passwd == NULL) {
4490 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4493 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4494 return NT_STATUS_ACCESS_DENIED;
4496 TALLOC_FREE(passwd);
4500 if (plaintext_buf) {
4501 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4504 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4505 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4506 pwd)))) {
4507 return status;
4510 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4511 return status;
4514 return NT_STATUS_OK;
4517 /*******************************************************************
4518 set_user_info_pw
4519 ********************************************************************/
4521 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4523 uint32 len = 0;
4524 char *plaintext_buf = NULL;
4525 uint32 acct_ctrl;
4527 DEBUG(5, ("Attempting administrator password change for user %s\n",
4528 pdb_get_username(pwd)));
4530 acct_ctrl = pdb_get_acct_ctrl(pwd);
4532 if (!decode_pw_buffer(talloc_tos(),
4533 pass,
4534 &plaintext_buf,
4535 &len,
4536 STR_UNICODE)) {
4537 return False;
4540 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4541 return False;
4544 /* if it's a trust account, don't update /etc/passwd */
4545 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4546 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4547 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4548 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4549 } else {
4550 /* update the UNIX password */
4551 if (lp_unix_password_sync()) {
4552 struct passwd *passwd;
4554 if (pdb_get_username(pwd) == NULL) {
4555 DEBUG(1, ("chgpasswd: User without name???\n"));
4556 return False;
4559 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4560 if (passwd == NULL) {
4561 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4564 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4565 return False;
4567 TALLOC_FREE(passwd);
4571 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4573 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4575 return True;
4578 /*******************************************************************
4579 set_user_info_24
4580 ********************************************************************/
4582 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4583 struct samr_UserInfo24 *id24,
4584 struct samu *pwd)
4586 NTSTATUS status;
4588 if (id24 == NULL) {
4589 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4590 return NT_STATUS_INVALID_PARAMETER;
4593 if (!set_user_info_pw(id24->password.data, pwd)) {
4594 return NT_STATUS_WRONG_PASSWORD;
4597 copy_id24_to_sam_passwd(pwd, id24);
4599 status = pdb_update_sam_account(pwd);
4600 if (!NT_STATUS_IS_OK(status)) {
4601 return status;
4604 return NT_STATUS_OK;
4607 /*******************************************************************
4608 set_user_info_25
4609 ********************************************************************/
4611 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4612 struct samr_UserInfo25 *id25,
4613 struct samu *pwd)
4615 NTSTATUS status;
4617 if (id25 == NULL) {
4618 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4619 return NT_STATUS_INVALID_PARAMETER;
4622 if (id25->info.fields_present == 0) {
4623 return NT_STATUS_INVALID_PARAMETER;
4626 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4627 return NT_STATUS_ACCESS_DENIED;
4630 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4631 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4633 if (!set_user_info_pw(id25->password.data, pwd)) {
4634 return NT_STATUS_WRONG_PASSWORD;
4638 copy_id25_to_sam_passwd(pwd, id25);
4640 /* write the change out */
4641 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4642 return status;
4646 * We need to "pdb_update_sam_account" before the unix primary group
4647 * is set, because the idealx scripts would also change the
4648 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4649 * the delete explicit / add explicit, which would then fail to find
4650 * the previous primaryGroupSid value.
4653 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4654 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4655 if ( !NT_STATUS_IS_OK(status) ) {
4656 return status;
4660 return NT_STATUS_OK;
4663 /*******************************************************************
4664 set_user_info_26
4665 ********************************************************************/
4667 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4668 struct samr_UserInfo26 *id26,
4669 struct samu *pwd)
4671 NTSTATUS status;
4673 if (id26 == NULL) {
4674 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4675 return NT_STATUS_INVALID_PARAMETER;
4678 if (!set_user_info_pw(id26->password.data, pwd)) {
4679 return NT_STATUS_WRONG_PASSWORD;
4682 copy_id26_to_sam_passwd(pwd, id26);
4684 status = pdb_update_sam_account(pwd);
4685 if (!NT_STATUS_IS_OK(status)) {
4686 return status;
4689 return NT_STATUS_OK;
4693 /*******************************************************************
4694 samr_SetUserInfo
4695 ********************************************************************/
4697 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4698 struct samr_SetUserInfo *r)
4700 NTSTATUS status;
4701 struct samu *pwd = NULL;
4702 DOM_SID sid;
4703 union samr_UserInfo *info = r->in.info;
4704 uint16_t switch_value = r->in.level;
4705 uint32_t acc_granted;
4706 uint32_t acc_required;
4707 bool ret;
4708 bool has_enough_rights = False;
4709 uint32_t acb_info;
4710 DISP_INFO *disp_info = NULL;
4712 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4714 /* find the policy handle. open a policy on it. */
4715 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) {
4716 return NT_STATUS_INVALID_HANDLE;
4719 /* This is tricky. A WinXP domain join sets
4720 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4721 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4722 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4723 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4724 we'll use the set from the WinXP join as the basis. */
4726 switch (switch_value) {
4727 case 18:
4728 case 24:
4729 case 25:
4730 case 26:
4731 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4732 break;
4733 default:
4734 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4735 SAMR_USER_ACCESS_SET_ATTRIBUTES |
4736 SAMR_USER_ACCESS_GET_ATTRIBUTES;
4737 break;
4740 status = access_check_samr_function(acc_granted,
4741 acc_required,
4742 "_samr_SetUserInfo");
4743 if (!NT_STATUS_IS_OK(status)) {
4744 return status;
4747 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4748 sid_string_dbg(&sid), switch_value));
4750 if (info == NULL) {
4751 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4752 return NT_STATUS_INVALID_INFO_CLASS;
4755 if (!(pwd = samu_new(NULL))) {
4756 return NT_STATUS_NO_MEMORY;
4759 become_root();
4760 ret = pdb_getsampwsid(pwd, &sid);
4761 unbecome_root();
4763 if (!ret) {
4764 TALLOC_FREE(pwd);
4765 return NT_STATUS_NO_SUCH_USER;
4768 /* deal with machine password changes differently from userinfo changes */
4769 /* check to see if we have the sufficient rights */
4771 acb_info = pdb_get_acct_ctrl(pwd);
4772 if (acb_info & ACB_WSTRUST)
4773 has_enough_rights = user_has_privileges(p->server_info->ptok,
4774 &se_machine_account);
4775 else if (acb_info & ACB_NORMAL)
4776 has_enough_rights = user_has_privileges(p->server_info->ptok,
4777 &se_add_users);
4778 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4779 if (lp_enable_privileges()) {
4780 has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
4781 DOMAIN_GROUP_RID_ADMINS);
4785 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4786 uidtoname(p->server_info->utok.uid),
4787 has_enough_rights ? "" : " not"));
4789 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4791 if (has_enough_rights) {
4792 become_root();
4795 /* ok! user info levels (lots: see MSDEV help), off we go... */
4797 switch (switch_value) {
4799 case 2:
4800 status = set_user_info_2(p->mem_ctx,
4801 &info->info2, pwd);
4802 break;
4804 case 4:
4805 status = set_user_info_4(p->mem_ctx,
4806 &info->info4, pwd);
4807 break;
4809 case 6:
4810 status = set_user_info_6(p->mem_ctx,
4811 &info->info6, pwd);
4812 break;
4814 case 7:
4815 status = set_user_info_7(p->mem_ctx,
4816 &info->info7, pwd);
4817 break;
4819 case 8:
4820 status = set_user_info_8(p->mem_ctx,
4821 &info->info8, pwd);
4822 break;
4824 case 10:
4825 status = set_user_info_10(p->mem_ctx,
4826 &info->info10, pwd);
4827 break;
4829 case 11:
4830 status = set_user_info_11(p->mem_ctx,
4831 &info->info11, pwd);
4832 break;
4834 case 12:
4835 status = set_user_info_12(p->mem_ctx,
4836 &info->info12, pwd);
4837 break;
4839 case 13:
4840 status = set_user_info_13(p->mem_ctx,
4841 &info->info13, pwd);
4842 break;
4844 case 14:
4845 status = set_user_info_14(p->mem_ctx,
4846 &info->info14, pwd);
4847 break;
4849 case 16:
4850 status = set_user_info_16(p->mem_ctx,
4851 &info->info16, pwd);
4852 break;
4854 case 17:
4855 status = set_user_info_17(p->mem_ctx,
4856 &info->info17, pwd);
4857 break;
4859 case 18:
4860 /* Used by AS/U JRA. */
4861 status = set_user_info_18(&info->info18,
4862 p->mem_ctx,
4863 &p->server_info->user_session_key,
4864 pwd);
4865 break;
4867 case 20:
4868 status = set_user_info_20(p->mem_ctx,
4869 &info->info20, pwd);
4870 break;
4872 case 21:
4873 status = set_user_info_21(&info->info21,
4874 p->mem_ctx,
4875 &p->server_info->user_session_key,
4876 pwd);
4877 break;
4879 case 23:
4880 if (!p->server_info->user_session_key.length) {
4881 status = NT_STATUS_NO_USER_SESSION_KEY;
4883 SamOEMhashBlob(info->info23.password.data, 516,
4884 &p->server_info->user_session_key);
4886 dump_data(100, info->info23.password.data, 516);
4888 status = set_user_info_23(p->mem_ctx,
4889 &info->info23, pwd);
4890 break;
4892 case 24:
4893 if (!p->server_info->user_session_key.length) {
4894 status = NT_STATUS_NO_USER_SESSION_KEY;
4896 SamOEMhashBlob(info->info24.password.data,
4897 516,
4898 &p->server_info->user_session_key);
4900 dump_data(100, info->info24.password.data, 516);
4902 status = set_user_info_24(p->mem_ctx,
4903 &info->info24, pwd);
4904 break;
4906 case 25:
4907 if (!p->server_info->user_session_key.length) {
4908 status = NT_STATUS_NO_USER_SESSION_KEY;
4910 encode_or_decode_arc4_passwd_buffer(
4911 info->info25.password.data,
4912 &p->server_info->user_session_key);
4914 dump_data(100, info->info25.password.data, 532);
4916 status = set_user_info_25(p->mem_ctx,
4917 &info->info25, pwd);
4918 break;
4920 case 26:
4921 if (!p->server_info->user_session_key.length) {
4922 status = NT_STATUS_NO_USER_SESSION_KEY;
4924 encode_or_decode_arc4_passwd_buffer(
4925 info->info26.password.data,
4926 &p->server_info->user_session_key);
4928 dump_data(100, info->info26.password.data, 516);
4930 status = set_user_info_26(p->mem_ctx,
4931 &info->info26, pwd);
4932 break;
4934 default:
4935 status = NT_STATUS_INVALID_INFO_CLASS;
4938 TALLOC_FREE(pwd);
4940 if (has_enough_rights) {
4941 unbecome_root();
4944 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4946 if (NT_STATUS_IS_OK(status)) {
4947 force_flush_samr_cache(disp_info);
4950 return status;
4953 /*******************************************************************
4954 _samr_SetUserInfo2
4955 ********************************************************************/
4957 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4958 struct samr_SetUserInfo2 *r)
4960 struct samr_SetUserInfo q;
4962 q.in.user_handle = r->in.user_handle;
4963 q.in.level = r->in.level;
4964 q.in.info = r->in.info;
4966 return _samr_SetUserInfo(p, &q);
4969 /*********************************************************************
4970 _samr_GetAliasMembership
4971 *********************************************************************/
4973 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4974 struct samr_GetAliasMembership *r)
4976 size_t num_alias_rids;
4977 uint32 *alias_rids;
4978 struct samr_info *info = NULL;
4979 size_t i;
4981 NTSTATUS ntstatus1;
4982 NTSTATUS ntstatus2;
4984 DOM_SID *members;
4986 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4988 /* find the policy handle. open a policy on it. */
4989 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4990 return NT_STATUS_INVALID_HANDLE;
4992 ntstatus1 = access_check_samr_function(info->acc_granted,
4993 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
4994 "_samr_GetAliasMembership");
4995 ntstatus2 = access_check_samr_function(info->acc_granted,
4996 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4997 "_samr_GetAliasMembership");
4999 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
5000 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
5001 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
5002 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
5006 if (!sid_check_is_domain(&info->sid) &&
5007 !sid_check_is_builtin(&info->sid))
5008 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5010 if (r->in.sids->num_sids) {
5011 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
5013 if (members == NULL)
5014 return NT_STATUS_NO_MEMORY;
5015 } else {
5016 members = NULL;
5019 for (i=0; i<r->in.sids->num_sids; i++)
5020 sid_copy(&members[i], r->in.sids->sids[i].sid);
5022 alias_rids = NULL;
5023 num_alias_rids = 0;
5025 become_root();
5026 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
5027 r->in.sids->num_sids,
5028 &alias_rids, &num_alias_rids);
5029 unbecome_root();
5031 if (!NT_STATUS_IS_OK(ntstatus1)) {
5032 return ntstatus1;
5035 r->out.rids->count = num_alias_rids;
5036 r->out.rids->ids = alias_rids;
5038 return NT_STATUS_OK;
5041 /*********************************************************************
5042 _samr_GetMembersInAlias
5043 *********************************************************************/
5045 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5046 struct samr_GetMembersInAlias *r)
5048 NTSTATUS status;
5049 size_t i;
5050 size_t num_sids = 0;
5051 struct lsa_SidPtr *sids = NULL;
5052 DOM_SID *pdb_sids = NULL;
5054 DOM_SID alias_sid;
5056 uint32 acc_granted;
5058 /* find the policy handle. open a policy on it. */
5059 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
5060 return NT_STATUS_INVALID_HANDLE;
5062 status = access_check_samr_function(acc_granted,
5063 SAMR_ALIAS_ACCESS_GET_MEMBERS,
5064 "_samr_GetMembersInAlias");
5065 if (!NT_STATUS_IS_OK(status)) {
5066 return status;
5069 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5071 become_root();
5072 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
5073 unbecome_root();
5075 if (!NT_STATUS_IS_OK(status)) {
5076 return status;
5079 if (num_sids) {
5080 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5081 if (sids == NULL) {
5082 TALLOC_FREE(pdb_sids);
5083 return NT_STATUS_NO_MEMORY;
5087 for (i = 0; i < num_sids; i++) {
5088 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5089 if (!sids[i].sid) {
5090 TALLOC_FREE(pdb_sids);
5091 return NT_STATUS_NO_MEMORY;
5095 r->out.sids->num_sids = num_sids;
5096 r->out.sids->sids = sids;
5098 TALLOC_FREE(pdb_sids);
5100 return NT_STATUS_OK;
5103 /*********************************************************************
5104 _samr_QueryGroupMember
5105 *********************************************************************/
5107 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5108 struct samr_QueryGroupMember *r)
5110 DOM_SID group_sid;
5111 size_t i, num_members;
5113 uint32 *rid=NULL;
5114 uint32 *attr=NULL;
5116 uint32 acc_granted;
5118 NTSTATUS status;
5119 struct samr_RidTypeArray *rids = NULL;
5121 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5122 if (!rids) {
5123 return NT_STATUS_NO_MEMORY;
5126 /* find the policy handle. open a policy on it. */
5127 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5128 return NT_STATUS_INVALID_HANDLE;
5130 status = access_check_samr_function(acc_granted,
5131 SAMR_GROUP_ACCESS_GET_MEMBERS,
5132 "_samr_QueryGroupMember");
5133 if (!NT_STATUS_IS_OK(status)) {
5134 return status;
5137 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
5139 if (!sid_check_is_in_our_domain(&group_sid)) {
5140 DEBUG(3, ("sid %s is not in our domain\n",
5141 sid_string_dbg(&group_sid)));
5142 return NT_STATUS_NO_SUCH_GROUP;
5145 DEBUG(10, ("lookup on Domain SID\n"));
5147 become_root();
5148 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
5149 &rid, &num_members);
5150 unbecome_root();
5152 if (!NT_STATUS_IS_OK(status))
5153 return status;
5155 if (num_members) {
5156 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5157 if (attr == NULL) {
5158 return NT_STATUS_NO_MEMORY;
5160 } else {
5161 attr = NULL;
5164 for (i=0; i<num_members; i++)
5165 attr[i] = SID_NAME_USER;
5167 rids->count = num_members;
5168 rids->types = attr;
5169 rids->rids = rid;
5171 *r->out.rids = rids;
5173 return NT_STATUS_OK;
5176 /*********************************************************************
5177 _samr_AddAliasMember
5178 *********************************************************************/
5180 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5181 struct samr_AddAliasMember *r)
5183 DOM_SID alias_sid;
5184 uint32 acc_granted;
5185 SE_PRIV se_rights;
5186 bool can_add_accounts;
5187 NTSTATUS status;
5188 DISP_INFO *disp_info = NULL;
5190 /* Find the policy handle. Open a policy on it. */
5191 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5192 return NT_STATUS_INVALID_HANDLE;
5194 status = access_check_samr_function(acc_granted,
5195 SAMR_ALIAS_ACCESS_ADD_MEMBER,
5196 "_samr_AddAliasMember");
5197 if (!NT_STATUS_IS_OK(status)) {
5198 return status;
5201 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5203 se_priv_copy( &se_rights, &se_add_users );
5204 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5206 /******** BEGIN SeAddUsers BLOCK *********/
5208 if ( can_add_accounts )
5209 become_root();
5211 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
5213 if ( can_add_accounts )
5214 unbecome_root();
5216 /******** END SeAddUsers BLOCK *********/
5218 if (NT_STATUS_IS_OK(status)) {
5219 force_flush_samr_cache(disp_info);
5222 return status;
5225 /*********************************************************************
5226 _samr_DeleteAliasMember
5227 *********************************************************************/
5229 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5230 struct samr_DeleteAliasMember *r)
5232 DOM_SID alias_sid;
5233 uint32 acc_granted;
5234 SE_PRIV se_rights;
5235 bool can_add_accounts;
5236 NTSTATUS status;
5237 DISP_INFO *disp_info = NULL;
5239 /* Find the policy handle. Open a policy on it. */
5240 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5241 return NT_STATUS_INVALID_HANDLE;
5243 status = access_check_samr_function(acc_granted,
5244 SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
5245 "_samr_DeleteAliasMember");
5246 if (!NT_STATUS_IS_OK(status)) {
5247 return status;
5250 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5251 sid_string_dbg(&alias_sid)));
5253 se_priv_copy( &se_rights, &se_add_users );
5254 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5256 /******** BEGIN SeAddUsers BLOCK *********/
5258 if ( can_add_accounts )
5259 become_root();
5261 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
5263 if ( can_add_accounts )
5264 unbecome_root();
5266 /******** END SeAddUsers BLOCK *********/
5268 if (NT_STATUS_IS_OK(status)) {
5269 force_flush_samr_cache(disp_info);
5272 return status;
5275 /*********************************************************************
5276 _samr_AddGroupMember
5277 *********************************************************************/
5279 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5280 struct samr_AddGroupMember *r)
5282 NTSTATUS status;
5283 DOM_SID group_sid;
5284 uint32 group_rid;
5285 uint32 acc_granted;
5286 SE_PRIV se_rights;
5287 bool can_add_accounts;
5288 DISP_INFO *disp_info = NULL;
5290 /* Find the policy handle. Open a policy on it. */
5291 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5292 return NT_STATUS_INVALID_HANDLE;
5294 status = access_check_samr_function(acc_granted,
5295 SAMR_GROUP_ACCESS_ADD_MEMBER,
5296 "_samr_AddGroupMember");
5297 if (!NT_STATUS_IS_OK(status)) {
5298 return status;
5301 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
5303 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
5304 &group_rid)) {
5305 return NT_STATUS_INVALID_HANDLE;
5308 se_priv_copy( &se_rights, &se_add_users );
5309 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5311 /******** BEGIN SeAddUsers BLOCK *********/
5313 if ( can_add_accounts )
5314 become_root();
5316 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5318 if ( can_add_accounts )
5319 unbecome_root();
5321 /******** END SeAddUsers BLOCK *********/
5323 force_flush_samr_cache(disp_info);
5325 return status;
5328 /*********************************************************************
5329 _samr_DeleteGroupMember
5330 *********************************************************************/
5332 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5333 struct samr_DeleteGroupMember *r)
5336 NTSTATUS status;
5337 DOM_SID group_sid;
5338 uint32 group_rid;
5339 uint32 acc_granted;
5340 SE_PRIV se_rights;
5341 bool can_add_accounts;
5342 DISP_INFO *disp_info = NULL;
5345 * delete the group member named r->in.rid
5346 * who is a member of the sid associated with the handle
5347 * the rid is a user's rid as the group is a domain group.
5350 /* Find the policy handle. Open a policy on it. */
5351 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5352 return NT_STATUS_INVALID_HANDLE;
5354 status = access_check_samr_function(acc_granted,
5355 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
5356 "_samr_DeleteGroupMember");
5357 if (!NT_STATUS_IS_OK(status)) {
5358 return status;
5361 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
5362 &group_rid)) {
5363 return NT_STATUS_INVALID_HANDLE;
5366 se_priv_copy( &se_rights, &se_add_users );
5367 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5369 /******** BEGIN SeAddUsers BLOCK *********/
5371 if ( can_add_accounts )
5372 become_root();
5374 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5376 if ( can_add_accounts )
5377 unbecome_root();
5379 /******** END SeAddUsers BLOCK *********/
5381 force_flush_samr_cache(disp_info);
5383 return status;
5386 /*********************************************************************
5387 _samr_DeleteUser
5388 *********************************************************************/
5390 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5391 struct samr_DeleteUser *r)
5393 NTSTATUS status;
5394 DOM_SID user_sid;
5395 struct samu *sam_pass=NULL;
5396 uint32 acc_granted;
5397 bool can_add_accounts;
5398 uint32 acb_info;
5399 DISP_INFO *disp_info = NULL;
5400 bool ret;
5402 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5404 /* Find the policy handle. Open a policy on it. */
5405 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
5406 return NT_STATUS_INVALID_HANDLE;
5408 status = access_check_samr_function(acc_granted,
5409 STD_RIGHT_DELETE_ACCESS,
5410 "_samr_DeleteUser");
5411 if (!NT_STATUS_IS_OK(status)) {
5412 return status;
5415 if (!sid_check_is_in_our_domain(&user_sid))
5416 return NT_STATUS_CANNOT_DELETE;
5418 /* check if the user exists before trying to delete */
5419 if ( !(sam_pass = samu_new( NULL )) ) {
5420 return NT_STATUS_NO_MEMORY;
5423 become_root();
5424 ret = pdb_getsampwsid(sam_pass, &user_sid);
5425 unbecome_root();
5427 if( !ret ) {
5428 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5429 sid_string_dbg(&user_sid)));
5430 TALLOC_FREE(sam_pass);
5431 return NT_STATUS_NO_SUCH_USER;
5434 acb_info = pdb_get_acct_ctrl(sam_pass);
5436 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
5437 if ( acb_info & ACB_WSTRUST ) {
5438 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
5439 } else {
5440 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5443 /******** BEGIN SeAddUsers BLOCK *********/
5445 if ( can_add_accounts )
5446 become_root();
5448 status = pdb_delete_user(p->mem_ctx, sam_pass);
5450 if ( can_add_accounts )
5451 unbecome_root();
5453 /******** END SeAddUsers BLOCK *********/
5455 if ( !NT_STATUS_IS_OK(status) ) {
5456 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5457 "user %s: %s.\n", pdb_get_username(sam_pass),
5458 nt_errstr(status)));
5459 TALLOC_FREE(sam_pass);
5460 return status;
5464 TALLOC_FREE(sam_pass);
5466 if (!close_policy_hnd(p, r->in.user_handle))
5467 return NT_STATUS_OBJECT_NAME_INVALID;
5469 ZERO_STRUCTP(r->out.user_handle);
5471 force_flush_samr_cache(disp_info);
5473 return NT_STATUS_OK;
5476 /*********************************************************************
5477 _samr_DeleteDomainGroup
5478 *********************************************************************/
5480 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5481 struct samr_DeleteDomainGroup *r)
5483 NTSTATUS status;
5484 DOM_SID group_sid;
5485 uint32 group_rid;
5486 uint32 acc_granted;
5487 SE_PRIV se_rights;
5488 bool can_add_accounts;
5489 DISP_INFO *disp_info = NULL;
5491 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5493 /* Find the policy handle. Open a policy on it. */
5494 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5495 return NT_STATUS_INVALID_HANDLE;
5497 status = access_check_samr_function(acc_granted,
5498 STD_RIGHT_DELETE_ACCESS,
5499 "_samr_DeleteDomainGroup");
5500 if (!NT_STATUS_IS_OK(status)) {
5501 return status;
5504 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
5506 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
5507 &group_rid)) {
5508 return NT_STATUS_NO_SUCH_GROUP;
5511 se_priv_copy( &se_rights, &se_add_users );
5512 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5514 /******** BEGIN SeAddUsers BLOCK *********/
5516 if ( can_add_accounts )
5517 become_root();
5519 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5521 if ( can_add_accounts )
5522 unbecome_root();
5524 /******** END SeAddUsers BLOCK *********/
5526 if ( !NT_STATUS_IS_OK(status) ) {
5527 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5528 "entry for group %s: %s\n",
5529 sid_string_dbg(&group_sid),
5530 nt_errstr(status)));
5531 return status;
5534 if (!close_policy_hnd(p, r->in.group_handle))
5535 return NT_STATUS_OBJECT_NAME_INVALID;
5537 force_flush_samr_cache(disp_info);
5539 return NT_STATUS_OK;
5542 /*********************************************************************
5543 _samr_DeleteDomAlias
5544 *********************************************************************/
5546 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5547 struct samr_DeleteDomAlias *r)
5549 DOM_SID alias_sid;
5550 uint32 acc_granted;
5551 SE_PRIV se_rights;
5552 bool can_add_accounts;
5553 NTSTATUS status;
5554 DISP_INFO *disp_info = NULL;
5556 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5558 /* Find the policy handle. Open a policy on it. */
5559 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
5560 return NT_STATUS_INVALID_HANDLE;
5562 /* copy the handle to the outgoing reply */
5564 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
5566 status = access_check_samr_function(acc_granted,
5567 STD_RIGHT_DELETE_ACCESS,
5568 "_samr_DeleteDomAlias");
5569 if (!NT_STATUS_IS_OK(status)) {
5570 return status;
5573 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
5575 /* Don't let Windows delete builtin groups */
5577 if ( sid_check_is_in_builtin( &alias_sid ) ) {
5578 return NT_STATUS_SPECIAL_ACCOUNT;
5581 if (!sid_check_is_in_our_domain(&alias_sid))
5582 return NT_STATUS_NO_SUCH_ALIAS;
5584 DEBUG(10, ("lookup on Local SID\n"));
5586 se_priv_copy( &se_rights, &se_add_users );
5587 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5589 /******** BEGIN SeAddUsers BLOCK *********/
5591 if ( can_add_accounts )
5592 become_root();
5594 /* Have passdb delete the alias */
5595 status = pdb_delete_alias(&alias_sid);
5597 if ( can_add_accounts )
5598 unbecome_root();
5600 /******** END SeAddUsers BLOCK *********/
5602 if ( !NT_STATUS_IS_OK(status))
5603 return status;
5605 if (!close_policy_hnd(p, r->in.alias_handle))
5606 return NT_STATUS_OBJECT_NAME_INVALID;
5608 force_flush_samr_cache(disp_info);
5610 return NT_STATUS_OK;
5613 /*********************************************************************
5614 _samr_CreateDomainGroup
5615 *********************************************************************/
5617 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5618 struct samr_CreateDomainGroup *r)
5621 NTSTATUS status;
5622 DOM_SID dom_sid;
5623 DOM_SID info_sid;
5624 const char *name;
5625 struct samr_info *info;
5626 uint32 acc_granted;
5627 SE_PRIV se_rights;
5628 bool can_add_accounts;
5629 DISP_INFO *disp_info = NULL;
5631 /* Find the policy handle. Open a policy on it. */
5632 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5633 return NT_STATUS_INVALID_HANDLE;
5635 status = access_check_samr_function(acc_granted,
5636 SAMR_DOMAIN_ACCESS_CREATE_GROUP,
5637 "_samr_CreateDomainGroup");
5638 if (!NT_STATUS_IS_OK(status)) {
5639 return status;
5642 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5643 return NT_STATUS_ACCESS_DENIED;
5645 name = r->in.name->string;
5646 if (name == NULL) {
5647 return NT_STATUS_NO_MEMORY;
5650 status = can_create(p->mem_ctx, name);
5651 if (!NT_STATUS_IS_OK(status)) {
5652 return status;
5655 se_priv_copy( &se_rights, &se_add_users );
5656 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5658 /******** BEGIN SeAddUsers BLOCK *********/
5660 if ( can_add_accounts )
5661 become_root();
5663 /* check that we successfully create the UNIX group */
5665 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5667 if ( can_add_accounts )
5668 unbecome_root();
5670 /******** END SeAddUsers BLOCK *********/
5672 /* check if we should bail out here */
5674 if ( !NT_STATUS_IS_OK(status) )
5675 return status;
5677 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5679 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5680 return NT_STATUS_NO_MEMORY;
5682 /* they created it; let the user do what he wants with it */
5684 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5686 /* get a (unique) handle. open a policy on it. */
5687 if (!create_policy_hnd(p, r->out.group_handle, info))
5688 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5690 force_flush_samr_cache(disp_info);
5692 return NT_STATUS_OK;
5695 /*********************************************************************
5696 _samr_CreateDomAlias
5697 *********************************************************************/
5699 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5700 struct samr_CreateDomAlias *r)
5702 DOM_SID dom_sid;
5703 DOM_SID info_sid;
5704 const char *name = NULL;
5705 struct samr_info *info;
5706 uint32 acc_granted;
5707 gid_t gid;
5708 NTSTATUS result;
5709 SE_PRIV se_rights;
5710 bool can_add_accounts;
5711 DISP_INFO *disp_info = NULL;
5713 /* Find the policy handle. Open a policy on it. */
5714 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5715 return NT_STATUS_INVALID_HANDLE;
5717 result = access_check_samr_function(acc_granted,
5718 SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
5719 "_samr_CreateDomAlias");
5720 if (!NT_STATUS_IS_OK(result)) {
5721 return result;
5724 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5725 return NT_STATUS_ACCESS_DENIED;
5727 name = r->in.alias_name->string;
5729 se_priv_copy( &se_rights, &se_add_users );
5730 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5732 result = can_create(p->mem_ctx, name);
5733 if (!NT_STATUS_IS_OK(result)) {
5734 return result;
5737 /******** BEGIN SeAddUsers BLOCK *********/
5739 if ( can_add_accounts )
5740 become_root();
5742 /* Have passdb create the alias */
5743 result = pdb_create_alias(name, r->out.rid);
5745 if ( can_add_accounts )
5746 unbecome_root();
5748 /******** END SeAddUsers BLOCK *********/
5750 if (!NT_STATUS_IS_OK(result)) {
5751 DEBUG(10, ("pdb_create_alias failed: %s\n",
5752 nt_errstr(result)));
5753 return result;
5756 sid_copy(&info_sid, get_global_sam_sid());
5757 sid_append_rid(&info_sid, *r->out.rid);
5759 if (!sid_to_gid(&info_sid, &gid)) {
5760 DEBUG(10, ("Could not find alias just created\n"));
5761 return NT_STATUS_ACCESS_DENIED;
5764 /* check if the group has been successfully created */
5765 if ( getgrgid(gid) == NULL ) {
5766 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5767 gid));
5768 return NT_STATUS_ACCESS_DENIED;
5771 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5772 return NT_STATUS_NO_MEMORY;
5774 /* they created it; let the user do what he wants with it */
5776 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5778 /* get a (unique) handle. open a policy on it. */
5779 if (!create_policy_hnd(p, r->out.alias_handle, info))
5780 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5782 force_flush_samr_cache(disp_info);
5784 return NT_STATUS_OK;
5787 /*********************************************************************
5788 _samr_QueryGroupInfo
5789 *********************************************************************/
5791 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5792 struct samr_QueryGroupInfo *r)
5794 NTSTATUS status;
5795 DOM_SID group_sid;
5796 GROUP_MAP map;
5797 union samr_GroupInfo *info = NULL;
5798 uint32 acc_granted;
5799 bool ret;
5800 uint32_t attributes = SE_GROUP_MANDATORY |
5801 SE_GROUP_ENABLED_BY_DEFAULT |
5802 SE_GROUP_ENABLED;
5803 const char *group_name = NULL;
5804 const char *group_description = NULL;
5806 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5807 return NT_STATUS_INVALID_HANDLE;
5809 status = access_check_samr_function(acc_granted,
5810 SAMR_GROUP_ACCESS_LOOKUP_INFO,
5811 "_samr_QueryGroupInfo");
5812 if (!NT_STATUS_IS_OK(status)) {
5813 return status;
5816 become_root();
5817 ret = get_domain_group_from_sid(group_sid, &map);
5818 unbecome_root();
5819 if (!ret)
5820 return NT_STATUS_INVALID_HANDLE;
5822 /* FIXME: map contains fstrings */
5823 group_name = talloc_strdup(r, map.nt_name);
5824 group_description = talloc_strdup(r, map.comment);
5826 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5827 if (!info) {
5828 return NT_STATUS_NO_MEMORY;
5831 switch (r->in.level) {
5832 case 1: {
5833 uint32 *members;
5834 size_t num_members;
5836 become_root();
5837 status = pdb_enum_group_members(
5838 p->mem_ctx, &group_sid, &members, &num_members);
5839 unbecome_root();
5841 if (!NT_STATUS_IS_OK(status)) {
5842 return status;
5845 info->all.name.string = group_name;
5846 info->all.attributes = attributes;
5847 info->all.num_members = num_members;
5848 info->all.description.string = group_description;
5849 break;
5851 case 2:
5852 info->name.string = group_name;
5853 break;
5854 case 3:
5855 info->attributes.attributes = attributes;
5856 break;
5857 case 4:
5858 info->description.string = group_description;
5859 break;
5860 case 5: {
5862 uint32 *members;
5863 size_t num_members;
5867 become_root();
5868 status = pdb_enum_group_members(
5869 p->mem_ctx, &group_sid, &members, &num_members);
5870 unbecome_root();
5872 if (!NT_STATUS_IS_OK(status)) {
5873 return status;
5876 info->all2.name.string = group_name;
5877 info->all2.attributes = attributes;
5878 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5879 info->all2.description.string = group_description;
5881 break;
5883 default:
5884 return NT_STATUS_INVALID_INFO_CLASS;
5887 *r->out.info = info;
5889 return NT_STATUS_OK;
5892 /*********************************************************************
5893 _samr_SetGroupInfo
5894 *********************************************************************/
5896 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5897 struct samr_SetGroupInfo *r)
5899 DOM_SID group_sid;
5900 GROUP_MAP map;
5901 uint32 acc_granted;
5902 NTSTATUS status;
5903 bool ret;
5904 bool can_mod_accounts;
5905 DISP_INFO *disp_info = NULL;
5907 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5908 return NT_STATUS_INVALID_HANDLE;
5910 status = access_check_samr_function(acc_granted,
5911 SAMR_GROUP_ACCESS_SET_INFO,
5912 "_samr_SetGroupInfo");
5913 if (!NT_STATUS_IS_OK(status)) {
5914 return status;
5917 become_root();
5918 ret = get_domain_group_from_sid(group_sid, &map);
5919 unbecome_root();
5920 if (!ret)
5921 return NT_STATUS_NO_SUCH_GROUP;
5923 switch (r->in.level) {
5924 case 1:
5925 fstrcpy(map.comment, r->in.info->all.description.string);
5926 break;
5927 case 2:
5928 /* group rename is not supported yet */
5929 return NT_STATUS_NOT_SUPPORTED;
5930 case 4:
5931 fstrcpy(map.comment, r->in.info->description.string);
5932 break;
5933 default:
5934 return NT_STATUS_INVALID_INFO_CLASS;
5937 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5939 /******** BEGIN SeAddUsers BLOCK *********/
5941 if ( can_mod_accounts )
5942 become_root();
5944 status = pdb_update_group_mapping_entry(&map);
5946 if ( can_mod_accounts )
5947 unbecome_root();
5949 /******** End SeAddUsers BLOCK *********/
5951 if (NT_STATUS_IS_OK(status)) {
5952 force_flush_samr_cache(disp_info);
5955 return status;
5958 /*********************************************************************
5959 _samr_SetAliasInfo
5960 *********************************************************************/
5962 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5963 struct samr_SetAliasInfo *r)
5965 DOM_SID group_sid;
5966 struct acct_info info;
5967 uint32 acc_granted;
5968 bool can_mod_accounts;
5969 NTSTATUS status;
5970 DISP_INFO *disp_info = NULL;
5972 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5973 return NT_STATUS_INVALID_HANDLE;
5975 status = access_check_samr_function(acc_granted,
5976 SAMR_ALIAS_ACCESS_SET_INFO,
5977 "_samr_SetAliasInfo");
5978 if (!NT_STATUS_IS_OK(status)) {
5979 return status;
5982 /* get the current group information */
5984 become_root();
5985 status = pdb_get_aliasinfo( &group_sid, &info );
5986 unbecome_root();
5988 if ( !NT_STATUS_IS_OK(status))
5989 return status;
5991 switch (r->in.level) {
5992 case ALIASINFONAME:
5994 fstring group_name;
5996 /* We currently do not support renaming groups in the
5997 the BUILTIN domain. Refer to util_builtin.c to understand
5998 why. The eventually needs to be fixed to be like Windows
5999 where you can rename builtin groups, just not delete them */
6001 if ( sid_check_is_in_builtin( &group_sid ) ) {
6002 return NT_STATUS_SPECIAL_ACCOUNT;
6005 /* There has to be a valid name (and it has to be different) */
6007 if ( !r->in.info->name.string )
6008 return NT_STATUS_INVALID_PARAMETER;
6010 /* If the name is the same just reply "ok". Yes this
6011 doesn't allow you to change the case of a group name. */
6013 if ( strequal( r->in.info->name.string, info.acct_name ) )
6014 return NT_STATUS_OK;
6016 fstrcpy( info.acct_name, r->in.info->name.string);
6018 /* make sure the name doesn't already exist as a user
6019 or local group */
6021 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6022 status = can_create( p->mem_ctx, group_name );
6023 if ( !NT_STATUS_IS_OK( status ) )
6024 return status;
6025 break;
6027 case ALIASINFODESCRIPTION:
6028 if (r->in.info->description.string) {
6029 fstrcpy(info.acct_desc,
6030 r->in.info->description.string);
6031 } else {
6032 fstrcpy( info.acct_desc, "" );
6034 break;
6035 default:
6036 return NT_STATUS_INVALID_INFO_CLASS;
6039 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
6041 /******** BEGIN SeAddUsers BLOCK *********/
6043 if ( can_mod_accounts )
6044 become_root();
6046 status = pdb_set_aliasinfo( &group_sid, &info );
6048 if ( can_mod_accounts )
6049 unbecome_root();
6051 /******** End SeAddUsers BLOCK *********/
6053 if (NT_STATUS_IS_OK(status))
6054 force_flush_samr_cache(disp_info);
6056 return status;
6059 /****************************************************************
6060 _samr_GetDomPwInfo
6061 ****************************************************************/
6063 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
6064 struct samr_GetDomPwInfo *r)
6066 uint32_t min_password_length = 0;
6067 uint32_t password_properties = 0;
6069 /* Perform access check. Since this rpc does not require a
6070 policy handle it will not be caught by the access checks on
6071 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6073 if (!pipe_access_check(p)) {
6074 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6075 return NT_STATUS_ACCESS_DENIED;
6078 become_root();
6079 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
6080 &min_password_length);
6081 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
6082 &password_properties);
6083 unbecome_root();
6085 if (lp_check_password_script() && *lp_check_password_script()) {
6086 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6089 r->out.info->min_password_length = min_password_length;
6090 r->out.info->password_properties = password_properties;
6092 return NT_STATUS_OK;
6095 /*********************************************************************
6096 _samr_OpenGroup
6097 *********************************************************************/
6099 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6100 struct samr_OpenGroup *r)
6103 DOM_SID sid;
6104 DOM_SID info_sid;
6105 GROUP_MAP map;
6106 struct samr_info *info;
6107 SEC_DESC *psd = NULL;
6108 uint32 acc_granted;
6109 uint32 des_access = r->in.access_mask;
6110 size_t sd_size;
6111 NTSTATUS status;
6112 fstring sid_string;
6113 bool ret;
6114 SE_PRIV se_rights;
6116 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
6117 return NT_STATUS_INVALID_HANDLE;
6119 status = access_check_samr_function(acc_granted,
6120 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
6121 "_samr_OpenGroup");
6123 if ( !NT_STATUS_IS_OK(status) )
6124 return status;
6126 /*check if access can be granted as requested by client. */
6127 map_max_allowed_access(p->server_info->ptok, &des_access);
6129 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6130 se_map_generic(&des_access,&grp_generic_mapping);
6132 se_priv_copy( &se_rights, &se_add_users );
6134 status = access_check_samr_object(psd, p->server_info->ptok,
6135 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
6136 &acc_granted, "_samr_OpenGroup");
6138 if ( !NT_STATUS_IS_OK(status) )
6139 return status;
6141 /* this should not be hard-coded like this */
6143 if (!sid_equal(&sid, get_global_sam_sid()))
6144 return NT_STATUS_ACCESS_DENIED;
6146 sid_copy(&info_sid, get_global_sam_sid());
6147 sid_append_rid(&info_sid, r->in.rid);
6148 sid_to_fstring(sid_string, &info_sid);
6150 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
6151 return NT_STATUS_NO_MEMORY;
6153 info->acc_granted = acc_granted;
6155 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
6157 /* check if that group really exists */
6158 become_root();
6159 ret = get_domain_group_from_sid(info->sid, &map);
6160 unbecome_root();
6161 if (!ret)
6162 return NT_STATUS_NO_SUCH_GROUP;
6164 /* get a (unique) handle. open a policy on it. */
6165 if (!create_policy_hnd(p, r->out.group_handle, info))
6166 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6168 return NT_STATUS_OK;
6171 /*********************************************************************
6172 _samr_RemoveMemberFromForeignDomain
6173 *********************************************************************/
6175 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6176 struct samr_RemoveMemberFromForeignDomain *r)
6178 DOM_SID delete_sid, domain_sid;
6179 uint32 acc_granted;
6180 NTSTATUS result;
6181 DISP_INFO *disp_info = NULL;
6183 sid_copy( &delete_sid, r->in.sid );
6185 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6186 sid_string_dbg(&delete_sid)));
6188 /* Find the policy handle. Open a policy on it. */
6190 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
6191 &acc_granted, &disp_info))
6192 return NT_STATUS_INVALID_HANDLE;
6194 result = access_check_samr_function(acc_granted,
6195 STD_RIGHT_DELETE_ACCESS,
6196 "_samr_RemoveMemberFromForeignDomain");
6198 if (!NT_STATUS_IS_OK(result))
6199 return result;
6201 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6202 sid_string_dbg(&domain_sid)));
6204 /* we can only delete a user from a group since we don't have
6205 nested groups anyways. So in the latter case, just say OK */
6207 /* TODO: The above comment nowadays is bogus. Since we have nested
6208 * groups now, and aliases members are never reported out of the unix
6209 * group membership, the "just say OK" makes this call a no-op. For
6210 * us. This needs fixing however. */
6212 /* I've only ever seen this in the wild when deleting a user from
6213 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6214 * is the user about to be deleted. I very much suspect this is the
6215 * only application of this call. To verify this, let people report
6216 * other cases. */
6218 if (!sid_check_is_builtin(&domain_sid)) {
6219 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6220 "global_sam_sid() = %s\n",
6221 sid_string_dbg(&domain_sid),
6222 sid_string_dbg(get_global_sam_sid())));
6223 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6224 return NT_STATUS_OK;
6227 force_flush_samr_cache(disp_info);
6229 result = NT_STATUS_OK;
6231 return result;
6234 /*******************************************************************
6235 _samr_QueryDomainInfo2
6236 ********************************************************************/
6238 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6239 struct samr_QueryDomainInfo2 *r)
6241 struct samr_QueryDomainInfo q;
6243 q.in.domain_handle = r->in.domain_handle;
6244 q.in.level = r->in.level;
6246 q.out.info = r->out.info;
6248 return _samr_QueryDomainInfo(p, &q);
6251 /*******************************************************************
6252 _samr_SetDomainInfo
6253 ********************************************************************/
6255 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6256 struct samr_SetDomainInfo *r)
6258 struct samr_info *info = NULL;
6259 time_t u_expire, u_min_age;
6260 time_t u_logout;
6261 time_t u_lock_duration, u_reset_time;
6262 NTSTATUS result;
6264 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6266 /* find the policy handle. open a policy on it. */
6267 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
6268 return NT_STATUS_INVALID_HANDLE;
6270 /* We do have different access bits for info
6271 * levels here, but we're really just looking for
6272 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
6273 * this maps to different specific bits. So
6274 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
6275 * set we are ok. */
6277 result = access_check_samr_function(info->acc_granted,
6278 SAMR_DOMAIN_ACCESS_SET_INFO_1,
6279 "_samr_SetDomainInfo");
6281 if (!NT_STATUS_IS_OK(result))
6282 return result;
6284 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6286 switch (r->in.level) {
6287 case 0x01:
6288 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
6289 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
6290 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
6291 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
6292 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
6293 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
6294 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
6295 break;
6296 case 0x02:
6297 break;
6298 case 0x03:
6299 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
6300 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
6301 break;
6302 case 0x05:
6303 break;
6304 case 0x06:
6305 break;
6306 case 0x07:
6307 break;
6308 case 0x0c:
6309 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
6310 if (u_lock_duration != -1)
6311 u_lock_duration /= 60;
6313 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
6315 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6316 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
6317 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
6318 break;
6319 default:
6320 return NT_STATUS_INVALID_INFO_CLASS;
6323 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6325 return NT_STATUS_OK;
6328 /****************************************************************
6329 _samr_GetDisplayEnumerationIndex
6330 ****************************************************************/
6332 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6333 struct samr_GetDisplayEnumerationIndex *r)
6335 struct samr_info *info = NULL;
6336 uint32_t max_entries = (uint32_t) -1;
6337 uint32_t enum_context = 0;
6338 int i;
6339 uint32_t num_account = 0;
6340 struct samr_displayentry *entries = NULL;
6341 NTSTATUS status;
6343 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6345 /* find the policy handle. open a policy on it. */
6346 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
6347 return NT_STATUS_INVALID_HANDLE;
6350 status = access_check_samr_function(info->acc_granted,
6351 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
6352 "_samr_GetDisplayEnumerationIndex");
6353 if (!NT_STATUS_IS_OK(status)) {
6354 return status;
6357 if ((r->in.level < 1) || (r->in.level > 3)) {
6358 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6359 "Unknown info level (%u)\n",
6360 r->in.level));
6361 return NT_STATUS_INVALID_INFO_CLASS;
6364 become_root();
6366 /* The following done as ROOT. Don't return without unbecome_root(). */
6368 switch (r->in.level) {
6369 case 1:
6370 if (info->disp_info->users == NULL) {
6371 info->disp_info->users = pdb_search_users(
6372 info->disp_info, ACB_NORMAL);
6373 if (info->disp_info->users == NULL) {
6374 unbecome_root();
6375 return NT_STATUS_ACCESS_DENIED;
6377 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6378 "starting user enumeration at index %u\n",
6379 (unsigned int)enum_context));
6380 } else {
6381 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6382 "using cached user enumeration at index %u\n",
6383 (unsigned int)enum_context));
6385 num_account = pdb_search_entries(info->disp_info->users,
6386 enum_context, max_entries,
6387 &entries);
6388 break;
6389 case 2:
6390 if (info->disp_info->machines == NULL) {
6391 info->disp_info->machines = pdb_search_users(
6392 info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6393 if (info->disp_info->machines == NULL) {
6394 unbecome_root();
6395 return NT_STATUS_ACCESS_DENIED;
6397 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6398 "starting machine enumeration at index %u\n",
6399 (unsigned int)enum_context));
6400 } else {
6401 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6402 "using cached machine enumeration at index %u\n",
6403 (unsigned int)enum_context));
6405 num_account = pdb_search_entries(info->disp_info->machines,
6406 enum_context, max_entries,
6407 &entries);
6408 break;
6409 case 3:
6410 if (info->disp_info->groups == NULL) {
6411 info->disp_info->groups = pdb_search_groups(
6412 info->disp_info);
6413 if (info->disp_info->groups == NULL) {
6414 unbecome_root();
6415 return NT_STATUS_ACCESS_DENIED;
6417 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6418 "starting group enumeration at index %u\n",
6419 (unsigned int)enum_context));
6420 } else {
6421 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6422 "using cached group enumeration at index %u\n",
6423 (unsigned int)enum_context));
6425 num_account = pdb_search_entries(info->disp_info->groups,
6426 enum_context, max_entries,
6427 &entries);
6428 break;
6429 default:
6430 unbecome_root();
6431 smb_panic("info class changed");
6432 break;
6435 unbecome_root();
6437 /* Ensure we cache this enumeration. */
6438 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
6440 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6441 r->in.name->string));
6443 for (i=0; i<num_account; i++) {
6444 if (strequal(entries[i].account_name, r->in.name->string)) {
6445 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6446 "found %s at idx %d\n",
6447 r->in.name->string, i));
6448 *r->out.idx = i;
6449 return NT_STATUS_OK;
6453 /* assuming account_name lives at the very end */
6454 *r->out.idx = num_account;
6456 return NT_STATUS_NO_MORE_ENTRIES;
6459 /****************************************************************
6460 _samr_GetDisplayEnumerationIndex2
6461 ****************************************************************/
6463 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6464 struct samr_GetDisplayEnumerationIndex2 *r)
6466 struct samr_GetDisplayEnumerationIndex q;
6468 q.in.domain_handle = r->in.domain_handle;
6469 q.in.level = r->in.level;
6470 q.in.name = r->in.name;
6472 q.out.idx = r->out.idx;
6474 return _samr_GetDisplayEnumerationIndex(p, &q);
6477 /****************************************************************
6478 ****************************************************************/
6480 NTSTATUS _samr_Shutdown(pipes_struct *p,
6481 struct samr_Shutdown *r)
6483 p->rng_fault_state = true;
6484 return NT_STATUS_NOT_IMPLEMENTED;
6487 /****************************************************************
6488 ****************************************************************/
6490 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6491 struct samr_SetMemberAttributesOfGroup *r)
6493 p->rng_fault_state = true;
6494 return NT_STATUS_NOT_IMPLEMENTED;
6497 /****************************************************************
6498 ****************************************************************/
6500 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6501 struct samr_TestPrivateFunctionsDomain *r)
6503 p->rng_fault_state = true;
6504 return NT_STATUS_NOT_IMPLEMENTED;
6507 /****************************************************************
6508 ****************************************************************/
6510 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6511 struct samr_TestPrivateFunctionsUser *r)
6513 return NT_STATUS_NOT_IMPLEMENTED;
6516 /****************************************************************
6517 ****************************************************************/
6519 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6520 struct samr_AddMultipleMembersToAlias *r)
6522 p->rng_fault_state = true;
6523 return NT_STATUS_NOT_IMPLEMENTED;
6526 /****************************************************************
6527 ****************************************************************/
6529 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6530 struct samr_RemoveMultipleMembersFromAlias *r)
6532 p->rng_fault_state = true;
6533 return NT_STATUS_NOT_IMPLEMENTED;
6536 /****************************************************************
6537 ****************************************************************/
6539 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6540 struct samr_SetBootKeyInformation *r)
6542 p->rng_fault_state = true;
6543 return NT_STATUS_NOT_IMPLEMENTED;
6546 /****************************************************************
6547 ****************************************************************/
6549 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6550 struct samr_GetBootKeyInformation *r)
6552 p->rng_fault_state = true;
6553 return NT_STATUS_NOT_IMPLEMENTED;
6556 /****************************************************************
6557 ****************************************************************/
6559 NTSTATUS _samr_RidToSid(pipes_struct *p,
6560 struct samr_RidToSid *r)
6562 p->rng_fault_state = true;
6563 return NT_STATUS_NOT_IMPLEMENTED;
6566 /****************************************************************
6567 ****************************************************************/
6569 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6570 struct samr_SetDsrmPassword *r)
6572 p->rng_fault_state = true;
6573 return NT_STATUS_NOT_IMPLEMENTED;
6576 /****************************************************************
6577 ****************************************************************/
6579 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6580 struct samr_ValidatePassword *r)
6582 p->rng_fault_state = true;
6583 return NT_STATUS_NOT_IMPLEMENTED;