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.
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 struct samr_connect_info {
55 typedef struct disp_info {
56 DOM_SID sid; /* identify which domain this is. */
57 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
58 struct pdb_search *users; /* querydispinfo 1 and 4 */
59 struct pdb_search *machines; /* querydispinfo 2 */
60 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
61 struct pdb_search *aliases; /* enumaliases */
64 struct pdb_search *enum_users; /* enumusers with a mask */
66 struct timed_event *cache_timeout_event; /* cache idle timeout
70 /* We keep a static list of these by SID as modern clients close down
71 all resources between each request in a complete enumeration. */
74 /* for use by the \PIPE\samr policy */
76 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
77 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
82 static const struct generic_mapping sam_generic_mapping = {
83 GENERIC_RIGHTS_SAM_READ,
84 GENERIC_RIGHTS_SAM_WRITE,
85 GENERIC_RIGHTS_SAM_EXECUTE,
86 GENERIC_RIGHTS_SAM_ALL_ACCESS};
87 static const struct generic_mapping dom_generic_mapping = {
88 GENERIC_RIGHTS_DOMAIN_READ,
89 GENERIC_RIGHTS_DOMAIN_WRITE,
90 GENERIC_RIGHTS_DOMAIN_EXECUTE,
91 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
92 static const struct generic_mapping usr_generic_mapping = {
93 GENERIC_RIGHTS_USER_READ,
94 GENERIC_RIGHTS_USER_WRITE,
95 GENERIC_RIGHTS_USER_EXECUTE,
96 GENERIC_RIGHTS_USER_ALL_ACCESS};
97 static const struct generic_mapping usr_nopwchange_generic_mapping = {
98 GENERIC_RIGHTS_USER_READ,
99 GENERIC_RIGHTS_USER_WRITE,
100 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
101 GENERIC_RIGHTS_USER_ALL_ACCESS};
102 static const struct generic_mapping grp_generic_mapping = {
103 GENERIC_RIGHTS_GROUP_READ,
104 GENERIC_RIGHTS_GROUP_WRITE,
105 GENERIC_RIGHTS_GROUP_EXECUTE,
106 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
107 static const struct generic_mapping ali_generic_mapping = {
108 GENERIC_RIGHTS_ALIAS_READ,
109 GENERIC_RIGHTS_ALIAS_WRITE,
110 GENERIC_RIGHTS_ALIAS_EXECUTE,
111 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
113 /*******************************************************************
114 *******************************************************************/
116 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
117 const struct generic_mapping *map,
118 DOM_SID *sid, uint32 sid_access )
120 DOM_SID domadmin_sid;
121 SEC_ACE ace[5]; /* at most 5 entries */
126 /* basic access for Everyone */
128 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
129 map->generic_execute | map->generic_read, 0);
131 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
133 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
134 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
135 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
136 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
138 /* Add Full Access for Domain Admins if we are a DC */
141 sid_copy( &domadmin_sid, get_global_sam_sid() );
142 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
143 init_sec_ace(&ace[i++], &domadmin_sid,
144 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
147 /* if we have a sid, give it some special access */
150 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
153 /* create the security descriptor */
155 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
156 return NT_STATUS_NO_MEMORY;
158 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
159 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
160 psa, sd_size)) == NULL)
161 return NT_STATUS_NO_MEMORY;
166 /*******************************************************************
167 Checks if access to an object should be granted, and returns that
168 level of access for further checks.
169 ********************************************************************/
171 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
172 SE_PRIV *rights, uint32 rights_mask,
173 uint32 des_access, uint32 *acc_granted,
176 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
177 uint32 saved_mask = 0;
179 /* check privileges; certain SAM access bits should be overridden
180 by privileges (mostly having to do with creating/modifying/deleting
183 if ( rights && user_has_any_privilege( token, rights ) ) {
185 saved_mask = (des_access & rights_mask);
186 des_access &= ~saved_mask;
188 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
193 /* check the security descriptor first */
195 status = se_access_check(psd, token, des_access, acc_granted);
196 if (NT_STATUS_IS_OK(status)) {
200 /* give root a free pass */
202 if ( geteuid() == sec_initial_uid() ) {
204 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
205 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
207 *acc_granted = des_access;
209 status = NT_STATUS_OK;
215 /* add in any bits saved during the privilege check (only
216 matters is status is ok) */
218 *acc_granted |= rights_mask;
220 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
221 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
222 des_access, *acc_granted));
227 /*******************************************************************
228 Checks if access to a function can be granted
229 ********************************************************************/
231 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
233 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
234 debug, acc_granted, acc_required));
236 /* check the security descriptor first */
238 if ( (acc_granted&acc_required) == acc_required )
241 /* give root a free pass */
243 if (geteuid() == sec_initial_uid()) {
245 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
246 debug, acc_granted, acc_required));
247 DEBUGADD(4,("but overwritten by euid == 0\n"));
252 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
253 debug, acc_granted, acc_required));
255 return NT_STATUS_ACCESS_DENIED;
258 /*******************************************************************
259 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
260 ********************************************************************/
262 static void map_max_allowed_access(const NT_USER_TOKEN *token,
263 uint32_t *pacc_requested)
265 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
268 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
270 /* At least try for generic read. */
271 *pacc_requested = GENERIC_READ_ACCESS;
273 /* root gets anything. */
274 if (geteuid() == sec_initial_uid()) {
275 *pacc_requested |= GENERIC_ALL_ACCESS;
279 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
281 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
282 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
283 *pacc_requested |= GENERIC_ALL_ACCESS;
287 /* Full access for DOMAIN\Domain Admins. */
289 DOM_SID domadmin_sid;
290 sid_copy( &domadmin_sid, get_global_sam_sid() );
291 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
292 if (is_sid_in_token(token, &domadmin_sid)) {
293 *pacc_requested |= GENERIC_ALL_ACCESS;
297 /* TODO ! Check privileges. */
300 /*******************************************************************
301 Fetch or create a dispinfo struct.
302 ********************************************************************/
304 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
307 * We do a static cache for DISP_INFO's here. Explanation can be found
308 * in Jeremy's checkin message to r11793:
310 * Fix the SAMR cache so it works across completely insane
311 * client behaviour (ie.:
312 * open pipe/open SAMR handle/enumerate 0 - 1024
313 * close SAMR handle, close pipe.
314 * open pipe/open SAMR handle/enumerate 1024 - 2048...
315 * close SAMR handle, close pipe.
316 * And on ad-nausium. Amazing.... probably object-oriented
317 * client side programming in action yet again.
318 * This change should *massively* improve performance when
319 * enumerating users from an LDAP database.
322 * "Our" and the builtin domain are the only ones where we ever
323 * enumerate stuff, so just cache 2 entries.
326 static struct disp_info *builtin_dispinfo;
327 static struct disp_info *domain_dispinfo;
329 /* There are two cases to consider here:
330 1) The SID is a domain SID and we look for an equality match, or
331 2) This is an account SID and so we return the DISP_INFO* for our
338 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
340 * Necessary only once, but it does not really hurt.
342 if (builtin_dispinfo == NULL) {
343 builtin_dispinfo = talloc_zero(
344 talloc_autofree_context(), struct disp_info);
345 if (builtin_dispinfo == NULL) {
349 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
350 builtin_dispinfo->builtin_domain = true;
352 return builtin_dispinfo;
355 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
357 * Necessary only once, but it does not really hurt.
359 if (domain_dispinfo == NULL) {
360 domain_dispinfo = talloc_zero(
361 talloc_autofree_context(), struct disp_info);
362 if (domain_dispinfo == NULL) {
366 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
367 domain_dispinfo->builtin_domain = false;
369 return domain_dispinfo;
375 /*******************************************************************
376 Create a samr_info struct.
377 ********************************************************************/
379 static int samr_info_destructor(struct samr_info *info);
381 static struct samr_info *get_samr_info_by_sid(TALLOC_CTX *mem_ctx,
384 struct samr_info *info;
386 info = talloc_zero(mem_ctx, struct samr_info);
390 talloc_set_destructor(info, samr_info_destructor);
392 DEBUG(10, ("get_samr_info_by_sid: created new info for sid %s\n",
393 sid_string_dbg(psid)));
396 sid_copy( &info->sid, psid);
397 info->builtin_domain = sid_check_is_builtin(psid);
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);
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. */
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);
431 static int samr_info_destructor(struct samr_info *info)
433 /* Only free the dispinfo cache if no one bothered to set up
436 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
437 free_samr_cache(info->disp_info);
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,
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 "
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)) {
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)
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. */
521 if (info->users == NULL) {
522 info->users = pdb_search_users(info, acct_flags);
523 if (info->users == NULL) {
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. */
545 if (info->groups == NULL) {
546 info->groups = pdb_search_groups(info);
547 if (info->groups == NULL) {
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) {
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 /*******************************************************************
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);
594 /*******************************************************************
596 ********************************************************************/
598 NTSTATUS _samr_OpenDomain(pipes_struct *p,
599 struct samr_OpenDomain *r)
601 struct samr_connect_info *cinfo;
602 struct samr_info *info;
603 SEC_DESC *psd = NULL;
605 uint32 des_access = r->in.access_mask;
610 /* find the connection policy handle. */
612 cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
613 struct samr_connect_info, &status);
614 if (!NT_STATUS_IS_OK(status)) {
618 /*check if access can be granted as requested by client. */
619 map_max_allowed_access(p->server_info->ptok, &des_access);
621 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
622 se_map_generic( &des_access, &dom_generic_mapping );
624 se_priv_copy( &se_rights, &se_machine_account );
625 se_priv_add( &se_rights, &se_add_users );
627 status = access_check_samr_object( psd, p->server_info->ptok,
628 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
629 &acc_granted, "_samr_OpenDomain" );
631 if ( !NT_STATUS_IS_OK(status) )
634 if (!sid_check_is_domain(r->in.sid) &&
635 !sid_check_is_builtin(r->in.sid)) {
636 return NT_STATUS_NO_SUCH_DOMAIN;
639 /* associate the domain SID with the (unique) handle. */
640 if ((info = get_samr_info_by_sid(p->mem_ctx, r->in.sid))==NULL)
641 return NT_STATUS_NO_MEMORY;
642 info->acc_granted = acc_granted;
644 /* get a (unique) handle. open a policy on it. */
645 if (!create_policy_hnd(p, r->out.domain_handle, info))
646 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
648 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
653 /*******************************************************************
655 ********************************************************************/
657 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
658 struct samr_GetUserPwInfo *r)
660 struct samr_info *info = NULL;
661 enum lsa_SidType sid_type;
662 uint32_t min_password_length = 0;
663 uint32_t password_properties = 0;
667 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
669 /* find the policy handle. open a policy on it. */
670 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
671 return NT_STATUS_INVALID_HANDLE;
674 status = access_check_samr_function(info->acc_granted,
675 SAMR_USER_ACCESS_GET_ATTRIBUTES,
676 "_samr_GetUserPwInfo" );
677 if (!NT_STATUS_IS_OK(status)) {
681 if (!sid_check_is_in_our_domain(&info->sid)) {
682 return NT_STATUS_OBJECT_TYPE_MISMATCH;
686 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
689 return NT_STATUS_NO_SUCH_USER;
695 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
696 &min_password_length);
697 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
698 &password_properties);
701 if (lp_check_password_script() && *lp_check_password_script()) {
702 password_properties |= DOMAIN_PASSWORD_COMPLEX;
710 r->out.info->min_password_length = min_password_length;
711 r->out.info->password_properties = password_properties;
713 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
718 /*******************************************************************
719 ********************************************************************/
721 static bool get_lsa_policy_samr_sid( pipes_struct *p, struct policy_handle *pol,
722 DOM_SID *sid, uint32 *acc_granted,
723 DISP_INFO **ppdisp_info)
725 struct samr_info *info = NULL;
727 /* find the policy handle. open a policy on it. */
728 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
735 *acc_granted = info->acc_granted;
737 *ppdisp_info = info->disp_info;
743 /*******************************************************************
745 ********************************************************************/
747 NTSTATUS _samr_SetSecurity(pipes_struct *p,
748 struct samr_SetSecurity *r)
751 uint32 acc_granted, i;
754 struct samu *sampass=NULL;
757 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
758 return NT_STATUS_INVALID_HANDLE;
760 if (!(sampass = samu_new( p->mem_ctx))) {
761 DEBUG(0,("No memory!\n"));
762 return NT_STATUS_NO_MEMORY;
765 /* get the user record */
767 ret = pdb_getsampwsid(sampass, &pol_sid);
771 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
772 TALLOC_FREE(sampass);
773 return NT_STATUS_INVALID_HANDLE;
776 dacl = r->in.sdbuf->sd->dacl;
777 for (i=0; i < dacl->num_aces; i++) {
778 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
779 ret = pdb_set_pass_can_change(sampass,
780 (dacl->aces[i].access_mask &
781 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
788 TALLOC_FREE(sampass);
789 return NT_STATUS_ACCESS_DENIED;
792 status = access_check_samr_function(acc_granted,
793 SAMR_USER_ACCESS_SET_ATTRIBUTES,
794 "_samr_SetSecurity");
795 if (NT_STATUS_IS_OK(status)) {
797 status = pdb_update_sam_account(sampass);
801 TALLOC_FREE(sampass);
806 /*******************************************************************
807 build correct perms based on policies and password times for _samr_query_sec_obj
808 *******************************************************************/
809 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
811 struct samu *sampass=NULL;
814 if ( !(sampass = samu_new( mem_ctx )) ) {
815 DEBUG(0,("No memory!\n"));
820 ret = pdb_getsampwsid(sampass, user_sid);
824 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
825 TALLOC_FREE(sampass);
829 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
831 if (pdb_get_pass_can_change(sampass)) {
832 TALLOC_FREE(sampass);
835 TALLOC_FREE(sampass);
840 /*******************************************************************
842 ********************************************************************/
844 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
845 struct samr_QuerySecurity *r)
849 SEC_DESC * psd = NULL;
854 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
855 return NT_STATUS_INVALID_HANDLE;
857 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
858 sid_string_dbg(&pol_sid)));
860 status = access_check_samr_function(acc_granted,
861 STD_RIGHT_READ_CONTROL_ACCESS,
862 "_samr_QuerySecurity");
863 if (!NT_STATUS_IS_OK(status)) {
867 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
869 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
870 if (pol_sid.sid_rev_num == 0) {
871 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
872 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
873 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
874 /* check if it is our domain SID */
875 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
876 "with SID: %s\n", sid_string_dbg(&pol_sid)));
877 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
878 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
879 /* check if it is the Builtin Domain */
880 /* TODO: Builtin probably needs a different SD with restricted write access*/
881 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
882 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
883 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
884 } else if (sid_check_is_in_our_domain(&pol_sid) ||
885 sid_check_is_in_builtin(&pol_sid)) {
886 /* TODO: different SDs have to be generated for aliases groups and users.
887 Currently all three get a default user SD */
888 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
889 "with SID: %s\n", sid_string_dbg(&pol_sid)));
890 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
891 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
892 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
894 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
895 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
898 return NT_STATUS_OBJECT_TYPE_MISMATCH;
901 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
902 return NT_STATUS_NO_MEMORY;
907 /*******************************************************************
908 makes a SAM_ENTRY / UNISTR2* structure from a user list.
909 ********************************************************************/
911 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
912 struct samr_SamEntry **sam_pp,
913 uint32_t num_entries,
915 struct samr_displayentry *entries)
918 struct samr_SamEntry *sam;
922 if (num_entries == 0) {
926 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
928 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
929 return NT_STATUS_NO_MEMORY;
932 for (i = 0; i < num_entries; i++) {
935 * usrmgr expects a non-NULL terminated string with
936 * trust relationships
938 if (entries[i].acct_flags & ACB_DOMTRUST) {
939 init_unistr2(&uni_temp_name, entries[i].account_name,
942 init_unistr2(&uni_temp_name, entries[i].account_name,
946 init_lsa_String(&sam[i].name, entries[i].account_name);
947 sam[i].idx = entries[i].rid;
955 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
957 /*******************************************************************
958 _samr_EnumDomainUsers
959 ********************************************************************/
961 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
962 struct samr_EnumDomainUsers *r)
965 struct samr_info *info = NULL;
967 uint32 enum_context = *r->in.resume_handle;
968 enum remote_arch_types ra_type = get_remote_arch();
969 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
970 uint32 max_entries = max_sam_entries;
971 struct samr_displayentry *entries = NULL;
972 struct samr_SamArray *samr_array = NULL;
973 struct samr_SamEntry *samr_entries = NULL;
975 /* find the policy handle. open a policy on it. */
976 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
977 return NT_STATUS_INVALID_HANDLE;
979 status = access_check_samr_function(info->acc_granted,
980 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
981 "_samr_EnumDomainUsers");
982 if (!NT_STATUS_IS_OK(status)) {
986 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
988 if (info->builtin_domain) {
989 /* No users in builtin. */
990 *r->out.resume_handle = *r->in.resume_handle;
991 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
995 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
997 return NT_STATUS_NO_MEMORY;
999 *r->out.sam = samr_array;
1005 if ((info->disp_info->enum_users != NULL) &&
1006 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
1007 TALLOC_FREE(info->disp_info->enum_users);
1010 if (info->disp_info->enum_users == NULL) {
1011 info->disp_info->enum_users = pdb_search_users(
1012 info->disp_info, r->in.acct_flags);
1013 info->disp_info->enum_acb_mask = r->in.acct_flags;
1016 if (info->disp_info->enum_users == NULL) {
1017 /* END AS ROOT !!!! */
1019 return NT_STATUS_ACCESS_DENIED;
1022 num_account = pdb_search_entries(info->disp_info->enum_users,
1023 enum_context, max_entries,
1026 /* END AS ROOT !!!! */
1030 if (num_account == 0) {
1031 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1032 "total entries\n"));
1033 *r->out.resume_handle = *r->in.resume_handle;
1034 return NT_STATUS_OK;
1037 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1038 num_account, enum_context,
1040 if (!NT_STATUS_IS_OK(status)) {
1044 if (max_entries <= num_account) {
1045 status = STATUS_MORE_ENTRIES;
1047 status = NT_STATUS_OK;
1050 /* Ensure we cache this enumeration. */
1051 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1053 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1055 samr_array->count = num_account;
1056 samr_array->entries = samr_entries;
1058 *r->out.resume_handle = *r->in.resume_handle + num_account;
1059 *r->out.num_entries = num_account;
1061 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1066 /*******************************************************************
1067 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1068 ********************************************************************/
1070 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1071 struct samr_SamEntry **sam_pp,
1072 uint32_t num_sam_entries,
1073 struct samr_displayentry *entries)
1075 struct samr_SamEntry *sam;
1080 if (num_sam_entries == 0) {
1084 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1089 for (i = 0; i < num_sam_entries; i++) {
1091 * JRA. I think this should include the null. TNG does not.
1093 init_lsa_String(&sam[i].name, entries[i].account_name);
1094 sam[i].idx = entries[i].rid;
1100 /*******************************************************************
1101 _samr_EnumDomainGroups
1102 ********************************************************************/
1104 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1105 struct samr_EnumDomainGroups *r)
1108 struct samr_info *info = NULL;
1109 struct samr_displayentry *groups;
1111 struct samr_SamArray *samr_array = NULL;
1112 struct samr_SamEntry *samr_entries = NULL;
1114 /* find the policy handle. open a policy on it. */
1115 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1116 return NT_STATUS_INVALID_HANDLE;
1118 status = access_check_samr_function(info->acc_granted,
1119 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1120 "_samr_EnumDomainGroups");
1121 if (!NT_STATUS_IS_OK(status)) {
1125 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1127 if (info->builtin_domain) {
1128 /* No groups in builtin. */
1129 *r->out.resume_handle = *r->in.resume_handle;
1130 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1134 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1136 return NT_STATUS_NO_MEMORY;
1139 /* the domain group array is being allocated in the function below */
1143 if (info->disp_info->groups == NULL) {
1144 info->disp_info->groups = pdb_search_groups(info->disp_info);
1146 if (info->disp_info->groups == NULL) {
1148 return NT_STATUS_ACCESS_DENIED;
1152 num_groups = pdb_search_entries(info->disp_info->groups,
1153 *r->in.resume_handle,
1154 MAX_SAM_ENTRIES, &groups);
1157 /* Ensure we cache this enumeration. */
1158 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1160 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1161 num_groups, groups);
1163 samr_array->count = num_groups;
1164 samr_array->entries = samr_entries;
1166 *r->out.sam = samr_array;
1167 *r->out.num_entries = num_groups;
1168 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1170 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1175 /*******************************************************************
1176 _samr_EnumDomainAliases
1177 ********************************************************************/
1179 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1180 struct samr_EnumDomainAliases *r)
1183 struct samr_info *info;
1184 struct samr_displayentry *aliases;
1185 uint32 num_aliases = 0;
1186 struct samr_SamArray *samr_array = NULL;
1187 struct samr_SamEntry *samr_entries = NULL;
1189 /* find the policy handle. open a policy on it. */
1190 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1191 return NT_STATUS_INVALID_HANDLE;
1193 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1194 sid_string_dbg(&info->sid)));
1196 status = access_check_samr_function(info->acc_granted,
1197 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1198 "_samr_EnumDomainAliases");
1199 if (!NT_STATUS_IS_OK(status)) {
1203 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1205 return NT_STATUS_NO_MEMORY;
1210 if (info->disp_info->aliases == NULL) {
1211 info->disp_info->aliases = pdb_search_aliases(
1212 info->disp_info, &info->sid);
1213 if (info->disp_info->aliases == NULL) {
1215 return NT_STATUS_ACCESS_DENIED;
1219 num_aliases = pdb_search_entries(info->disp_info->aliases,
1220 *r->in.resume_handle,
1221 MAX_SAM_ENTRIES, &aliases);
1224 /* Ensure we cache this enumeration. */
1225 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1227 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1228 num_aliases, aliases);
1230 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1232 samr_array->count = num_aliases;
1233 samr_array->entries = samr_entries;
1235 *r->out.sam = samr_array;
1236 *r->out.num_entries = num_aliases;
1237 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1242 /*******************************************************************
1243 inits a samr_DispInfoGeneral structure.
1244 ********************************************************************/
1246 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1247 struct samr_DispInfoGeneral *r,
1248 uint32_t num_entries,
1250 struct samr_displayentry *entries)
1254 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1256 if (num_entries == 0) {
1257 return NT_STATUS_OK;
1260 r->count = num_entries;
1262 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1264 return NT_STATUS_NO_MEMORY;
1267 for (i = 0; i < num_entries ; i++) {
1269 init_lsa_String(&r->entries[i].account_name,
1270 entries[i].account_name);
1272 init_lsa_String(&r->entries[i].description,
1273 entries[i].description);
1275 init_lsa_String(&r->entries[i].full_name,
1276 entries[i].fullname);
1278 r->entries[i].rid = entries[i].rid;
1279 r->entries[i].acct_flags = entries[i].acct_flags;
1280 r->entries[i].idx = start_idx+i+1;
1283 return NT_STATUS_OK;
1286 /*******************************************************************
1287 inits a samr_DispInfoFull structure.
1288 ********************************************************************/
1290 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1291 struct samr_DispInfoFull *r,
1292 uint32_t num_entries,
1294 struct samr_displayentry *entries)
1298 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1300 if (num_entries == 0) {
1301 return NT_STATUS_OK;
1304 r->count = num_entries;
1306 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1308 return NT_STATUS_NO_MEMORY;
1311 for (i = 0; i < num_entries ; i++) {
1313 init_lsa_String(&r->entries[i].account_name,
1314 entries[i].account_name);
1316 init_lsa_String(&r->entries[i].description,
1317 entries[i].description);
1319 r->entries[i].rid = entries[i].rid;
1320 r->entries[i].acct_flags = entries[i].acct_flags;
1321 r->entries[i].idx = start_idx+i+1;
1324 return NT_STATUS_OK;
1327 /*******************************************************************
1328 inits a samr_DispInfoFullGroups structure.
1329 ********************************************************************/
1331 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1332 struct samr_DispInfoFullGroups *r,
1333 uint32_t num_entries,
1335 struct samr_displayentry *entries)
1339 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1341 if (num_entries == 0) {
1342 return NT_STATUS_OK;
1345 r->count = num_entries;
1347 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1349 return NT_STATUS_NO_MEMORY;
1352 for (i = 0; i < num_entries ; i++) {
1354 init_lsa_String(&r->entries[i].account_name,
1355 entries[i].account_name);
1357 init_lsa_String(&r->entries[i].description,
1358 entries[i].description);
1360 r->entries[i].rid = entries[i].rid;
1361 r->entries[i].acct_flags = entries[i].acct_flags;
1362 r->entries[i].idx = start_idx+i+1;
1365 return NT_STATUS_OK;
1368 /*******************************************************************
1369 inits a samr_DispInfoAscii structure.
1370 ********************************************************************/
1372 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1373 struct samr_DispInfoAscii *r,
1374 uint32_t num_entries,
1376 struct samr_displayentry *entries)
1380 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1382 if (num_entries == 0) {
1383 return NT_STATUS_OK;
1386 r->count = num_entries;
1388 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1390 return NT_STATUS_NO_MEMORY;
1393 for (i = 0; i < num_entries ; i++) {
1395 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1396 entries[i].account_name);
1398 r->entries[i].idx = start_idx+i+1;
1401 return NT_STATUS_OK;
1404 /*******************************************************************
1405 inits a samr_DispInfoAscii structure.
1406 ********************************************************************/
1408 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1409 struct samr_DispInfoAscii *r,
1410 uint32_t num_entries,
1412 struct samr_displayentry *entries)
1416 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1418 if (num_entries == 0) {
1419 return NT_STATUS_OK;
1422 r->count = num_entries;
1424 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1426 return NT_STATUS_NO_MEMORY;
1429 for (i = 0; i < num_entries ; i++) {
1431 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1432 entries[i].account_name);
1434 r->entries[i].idx = start_idx+i+1;
1437 return NT_STATUS_OK;
1440 /*******************************************************************
1441 _samr_QueryDisplayInfo
1442 ********************************************************************/
1444 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1445 struct samr_QueryDisplayInfo *r)
1448 struct samr_info *info = NULL;
1449 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1451 uint32 max_entries = r->in.max_entries;
1452 uint32 enum_context = r->in.start_idx;
1453 uint32 max_size = r->in.buf_size;
1455 union samr_DispInfo *disp_info = r->out.info;
1457 uint32 temp_size=0, total_data_size=0;
1458 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1459 uint32 num_account = 0;
1460 enum remote_arch_types ra_type = get_remote_arch();
1461 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1462 struct samr_displayentry *entries = NULL;
1464 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1466 /* find the policy handle. open a policy on it. */
1467 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1468 return NT_STATUS_INVALID_HANDLE;
1470 if (info->builtin_domain) {
1471 DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
1472 return NT_STATUS_OK;
1475 status = access_check_samr_function(info->acc_granted,
1476 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1477 "_samr_QueryDisplayInfo");
1478 if (!NT_STATUS_IS_OK(status)) {
1483 * calculate how many entries we will return.
1485 * - the number of entries the client asked
1486 * - our limit on that
1487 * - the starting point (enumeration context)
1488 * - the buffer size the client will accept
1492 * We are a lot more like W2K. Instead of reading the SAM
1493 * each time to find the records we need to send back,
1494 * we read it once and link that copy to the sam handle.
1495 * For large user list (over the MAX_SAM_ENTRIES)
1496 * it's a definitive win.
1497 * second point to notice: between enumerations
1498 * our sam is now the same as it's a snapshoot.
1499 * third point: got rid of the static SAM_USER_21 struct
1500 * no more intermediate.
1501 * con: it uses much more memory, as a full copy is stored
1504 * If you want to change it, think twice and think
1505 * of the second point , that's really important.
1510 if ((r->in.level < 1) || (r->in.level > 5)) {
1511 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1512 (unsigned int)r->in.level ));
1513 return NT_STATUS_INVALID_INFO_CLASS;
1516 /* first limit the number of entries we will return */
1517 if(max_entries > max_sam_entries) {
1518 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1519 "entries, limiting to %d\n", max_entries,
1521 max_entries = max_sam_entries;
1524 /* calculate the size and limit on the number of entries we will
1527 temp_size=max_entries*struct_size;
1529 if (temp_size>max_size) {
1530 max_entries=MIN((max_size/struct_size),max_entries);;
1531 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1532 "only %d entries\n", max_entries));
1537 /* THe following done as ROOT. Don't return without unbecome_root(). */
1539 switch (r->in.level) {
1542 if (info->disp_info->users == NULL) {
1543 info->disp_info->users = pdb_search_users(
1544 info->disp_info, ACB_NORMAL);
1545 if (info->disp_info->users == NULL) {
1547 return NT_STATUS_ACCESS_DENIED;
1549 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1550 (unsigned int)enum_context ));
1552 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1553 (unsigned int)enum_context ));
1556 num_account = pdb_search_entries(info->disp_info->users,
1557 enum_context, max_entries,
1561 if (info->disp_info->machines == NULL) {
1562 info->disp_info->machines = pdb_search_users(
1563 info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1564 if (info->disp_info->machines == NULL) {
1566 return NT_STATUS_ACCESS_DENIED;
1568 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1569 (unsigned int)enum_context ));
1571 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1572 (unsigned int)enum_context ));
1575 num_account = pdb_search_entries(info->disp_info->machines,
1576 enum_context, max_entries,
1581 if (info->disp_info->groups == NULL) {
1582 info->disp_info->groups = pdb_search_groups(
1584 if (info->disp_info->groups == NULL) {
1586 return NT_STATUS_ACCESS_DENIED;
1588 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1589 (unsigned int)enum_context ));
1591 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1592 (unsigned int)enum_context ));
1595 num_account = pdb_search_entries(info->disp_info->groups,
1596 enum_context, max_entries,
1601 smb_panic("info class changed");
1607 /* Now create reply structure */
1608 switch (r->in.level) {
1610 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1611 num_account, enum_context,
1615 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1616 num_account, enum_context,
1620 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1621 num_account, enum_context,
1625 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1626 num_account, enum_context,
1630 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1631 num_account, enum_context,
1635 smb_panic("info class changed");
1639 if (!NT_STATUS_IS_OK(disp_ret))
1642 /* calculate the total size */
1643 total_data_size=num_account*struct_size;
1645 if (max_entries <= num_account) {
1646 status = STATUS_MORE_ENTRIES;
1648 status = NT_STATUS_OK;
1651 /* Ensure we cache this enumeration. */
1652 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1654 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1656 *r->out.total_size = total_data_size;
1657 *r->out.returned_size = temp_size;
1662 /****************************************************************
1663 _samr_QueryDisplayInfo2
1664 ****************************************************************/
1666 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1667 struct samr_QueryDisplayInfo2 *r)
1669 struct samr_QueryDisplayInfo q;
1671 q.in.domain_handle = r->in.domain_handle;
1672 q.in.level = r->in.level;
1673 q.in.start_idx = r->in.start_idx;
1674 q.in.max_entries = r->in.max_entries;
1675 q.in.buf_size = r->in.buf_size;
1677 q.out.total_size = r->out.total_size;
1678 q.out.returned_size = r->out.returned_size;
1679 q.out.info = r->out.info;
1681 return _samr_QueryDisplayInfo(p, &q);
1684 /****************************************************************
1685 _samr_QueryDisplayInfo3
1686 ****************************************************************/
1688 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1689 struct samr_QueryDisplayInfo3 *r)
1691 struct samr_QueryDisplayInfo q;
1693 q.in.domain_handle = r->in.domain_handle;
1694 q.in.level = r->in.level;
1695 q.in.start_idx = r->in.start_idx;
1696 q.in.max_entries = r->in.max_entries;
1697 q.in.buf_size = r->in.buf_size;
1699 q.out.total_size = r->out.total_size;
1700 q.out.returned_size = r->out.returned_size;
1701 q.out.info = r->out.info;
1703 return _samr_QueryDisplayInfo(p, &q);
1706 /*******************************************************************
1707 _samr_QueryAliasInfo
1708 ********************************************************************/
1710 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1711 struct samr_QueryAliasInfo *r)
1714 struct acct_info info;
1717 union samr_AliasInfo *alias_info = NULL;
1718 const char *alias_name = NULL;
1719 const char *alias_description = NULL;
1721 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1723 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1725 return NT_STATUS_NO_MEMORY;
1728 /* find the policy handle. open a policy on it. */
1729 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1730 return NT_STATUS_INVALID_HANDLE;
1732 status = access_check_samr_function(acc_granted,
1733 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1734 "_samr_QueryAliasInfo");
1735 if (!NT_STATUS_IS_OK(status)) {
1740 status = pdb_get_aliasinfo(&sid, &info);
1743 if ( !NT_STATUS_IS_OK(status))
1746 /* FIXME: info contains fstrings */
1747 alias_name = talloc_strdup(r, info.acct_name);
1748 alias_description = talloc_strdup(r, info.acct_desc);
1750 switch (r->in.level) {
1752 alias_info->all.name.string = alias_name;
1753 alias_info->all.num_members = 1; /* ??? */
1754 alias_info->all.description.string = alias_description;
1756 case ALIASINFODESCRIPTION:
1757 alias_info->description.string = alias_description;
1760 return NT_STATUS_INVALID_INFO_CLASS;
1763 *r->out.info = alias_info;
1765 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1767 return NT_STATUS_OK;
1770 /*******************************************************************
1772 ********************************************************************/
1774 NTSTATUS _samr_LookupNames(pipes_struct *p,
1775 struct samr_LookupNames *r)
1779 enum lsa_SidType *type;
1781 int num_rids = r->in.num_names;
1784 struct samr_Ids rids, types;
1785 uint32_t num_mapped = 0;
1787 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1789 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1790 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1793 status = access_check_samr_function(acc_granted,
1794 0, /* Don't know the acc_bits yet */
1795 "_samr_LookupNames");
1796 if (!NT_STATUS_IS_OK(status)) {
1800 if (num_rids > MAX_SAM_ENTRIES) {
1801 num_rids = MAX_SAM_ENTRIES;
1802 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1805 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1806 NT_STATUS_HAVE_NO_MEMORY(rid);
1808 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1809 NT_STATUS_HAVE_NO_MEMORY(type);
1811 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1812 sid_string_dbg(&pol_sid)));
1814 for (i = 0; i < num_rids; i++) {
1816 status = NT_STATUS_NONE_MAPPED;
1817 type[i] = SID_NAME_UNKNOWN;
1819 rid[i] = 0xffffffff;
1821 if (sid_check_is_builtin(&pol_sid)) {
1822 if (lookup_builtin_name(r->in.names[i].string,
1825 type[i] = SID_NAME_ALIAS;
1828 lookup_global_sam_name(r->in.names[i].string, 0,
1832 if (type[i] != SID_NAME_UNKNOWN) {
1837 if (num_mapped == num_rids) {
1838 status = NT_STATUS_OK;
1839 } else if (num_mapped == 0) {
1840 status = NT_STATUS_NONE_MAPPED;
1842 status = STATUS_SOME_UNMAPPED;
1845 rids.count = num_rids;
1848 types.count = num_rids;
1851 *r->out.rids = rids;
1852 *r->out.types = types;
1854 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1859 /*******************************************************************
1860 _samr_ChangePasswordUser2
1861 ********************************************************************/
1863 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1864 struct samr_ChangePasswordUser2 *r)
1870 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1872 fstrcpy(user_name, r->in.account->string);
1873 fstrcpy(wks, r->in.server->string);
1875 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1878 * Pass the user through the NT -> unix user mapping
1882 (void)map_username(user_name);
1885 * UNIX username case mangling not required, pass_oem_change
1886 * is case insensitive.
1889 status = pass_oem_change(user_name,
1890 r->in.lm_password->data,
1891 r->in.lm_verifier->hash,
1892 r->in.nt_password->data,
1893 r->in.nt_verifier->hash,
1896 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1901 /*******************************************************************
1902 _samr_ChangePasswordUser3
1903 ********************************************************************/
1905 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1906 struct samr_ChangePasswordUser3 *r)
1910 const char *wks = NULL;
1911 uint32 reject_reason;
1912 struct samr_DomInfo1 *dominfo = NULL;
1913 struct samr_ChangeReject *reject = NULL;
1916 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1918 fstrcpy(user_name, r->in.account->string);
1919 if (r->in.server && r->in.server->string) {
1920 wks = r->in.server->string;
1923 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1926 * Pass the user through the NT -> unix user mapping
1930 (void)map_username(user_name);
1933 * UNIX username case mangling not required, pass_oem_change
1934 * is case insensitive.
1937 status = pass_oem_change(user_name,
1938 r->in.lm_password->data,
1939 r->in.lm_verifier->hash,
1940 r->in.nt_password->data,
1941 r->in.nt_verifier->hash,
1944 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1945 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1947 time_t u_expire, u_min_age;
1948 uint32 account_policy_temp;
1950 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1952 return NT_STATUS_NO_MEMORY;
1955 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1957 return NT_STATUS_NO_MEMORY;
1964 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
1965 dominfo->min_password_length = tmp;
1967 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
1968 dominfo->password_history_length = tmp;
1970 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
1971 &dominfo->password_properties);
1973 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1974 u_expire = account_policy_temp;
1976 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1977 u_min_age = account_policy_temp;
1983 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
1984 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
1986 if (lp_check_password_script() && *lp_check_password_script()) {
1987 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
1990 reject->reason = reject_reason;
1992 *r->out.dominfo = dominfo;
1993 *r->out.reject = reject;
1996 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2001 /*******************************************************************
2002 makes a SAMR_R_LOOKUP_RIDS structure.
2003 ********************************************************************/
2005 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2007 struct lsa_String **lsa_name_array_p)
2009 struct lsa_String *lsa_name_array = NULL;
2012 *lsa_name_array_p = NULL;
2014 if (num_names != 0) {
2015 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2016 if (!lsa_name_array) {
2021 for (i = 0; i < num_names; i++) {
2022 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2023 init_lsa_String(&lsa_name_array[i], names[i]);
2026 *lsa_name_array_p = lsa_name_array;
2031 /*******************************************************************
2033 ********************************************************************/
2035 NTSTATUS _samr_LookupRids(pipes_struct *p,
2036 struct samr_LookupRids *r)
2040 enum lsa_SidType *attrs = NULL;
2041 uint32 *wire_attrs = NULL;
2043 int num_rids = (int)r->in.num_rids;
2046 struct lsa_Strings names_array;
2047 struct samr_Ids types_array;
2048 struct lsa_String *lsa_names = NULL;
2050 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2052 /* find the policy handle. open a policy on it. */
2053 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2054 return NT_STATUS_INVALID_HANDLE;
2056 status = access_check_samr_function(acc_granted,
2057 0, /* Don't know the acc_bits yet */
2058 "_samr_LookupRids");
2059 if (!NT_STATUS_IS_OK(status)) {
2063 if (num_rids > 1000) {
2064 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2065 "to samba4 idl this is not possible\n", num_rids));
2066 return NT_STATUS_UNSUCCESSFUL;
2070 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2071 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2072 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2074 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2075 return NT_STATUS_NO_MEMORY;
2082 become_root(); /* lookup_sid can require root privs */
2083 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2087 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2088 status = NT_STATUS_OK;
2091 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2093 return NT_STATUS_NO_MEMORY;
2096 /* Convert from enum lsa_SidType to uint32 for wire format. */
2097 for (i = 0; i < num_rids; i++) {
2098 wire_attrs[i] = (uint32)attrs[i];
2101 names_array.count = num_rids;
2102 names_array.names = lsa_names;
2104 types_array.count = num_rids;
2105 types_array.ids = wire_attrs;
2107 *r->out.names = names_array;
2108 *r->out.types = types_array;
2110 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2115 /*******************************************************************
2117 ********************************************************************/
2119 NTSTATUS _samr_OpenUser(pipes_struct *p,
2120 struct samr_OpenUser *r)
2122 struct samu *sampass=NULL;
2124 struct samr_info *info = NULL;
2125 SEC_DESC *psd = NULL;
2127 uint32 des_access = r->in.access_mask;
2133 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2135 if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
2136 return NT_STATUS_INVALID_HANDLE;
2138 nt_status = access_check_samr_function(acc_granted,
2139 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2142 if ( !NT_STATUS_IS_OK(nt_status) )
2145 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2146 return NT_STATUS_NO_MEMORY;
2149 /* append the user's RID to it */
2151 if (!sid_append_rid(&sid, r->in.rid))
2152 return NT_STATUS_NO_SUCH_USER;
2154 /* check if access can be granted as requested by client. */
2156 map_max_allowed_access(p->server_info->ptok, &des_access);
2158 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2159 se_map_generic(&des_access, &usr_generic_mapping);
2161 se_priv_copy( &se_rights, &se_machine_account );
2162 se_priv_add( &se_rights, &se_add_users );
2164 nt_status = access_check_samr_object(psd, p->server_info->ptok,
2165 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2166 &acc_granted, "_samr_OpenUser");
2168 if ( !NT_STATUS_IS_OK(nt_status) )
2172 ret=pdb_getsampwsid(sampass, &sid);
2175 /* check that the SID exists in our domain. */
2177 return NT_STATUS_NO_SUCH_USER;
2180 TALLOC_FREE(sampass);
2182 /* associate the user's SID and access bits with the new handle. */
2183 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
2184 return NT_STATUS_NO_MEMORY;
2185 info->acc_granted = acc_granted;
2187 /* get a (unique) handle. open a policy on it. */
2188 if (!create_policy_hnd(p, r->out.user_handle, info))
2189 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2191 return NT_STATUS_OK;
2194 /*************************************************************************
2195 *************************************************************************/
2197 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2199 struct lsa_BinaryString **_r)
2201 struct lsa_BinaryString *r;
2204 return NT_STATUS_INVALID_PARAMETER;
2207 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2209 return NT_STATUS_NO_MEMORY;
2212 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2214 return NT_STATUS_NO_MEMORY;
2216 memcpy(r->array, blob->data, blob->length);
2217 r->size = blob->length;
2218 r->length = blob->length;
2221 return NT_STATUS_NO_MEMORY;
2226 return NT_STATUS_OK;
2229 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2230 struct samr_UserInfo5 *r,
2232 DOM_SID *domain_sid)
2234 const DOM_SID *sid_user, *sid_group;
2235 uint32_t rid, primary_gid;
2237 sid_user = pdb_get_user_sid(pw);
2239 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2240 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2241 "the domain sid %s. Failing operation.\n",
2242 pdb_get_username(pw), sid_string_dbg(sid_user),
2243 sid_string_dbg(domain_sid)));
2244 return NT_STATUS_UNSUCCESSFUL;
2248 sid_group = pdb_get_group_sid(pw);
2251 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2252 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2253 "which conflicts with the domain sid %s. Failing operation.\n",
2254 pdb_get_username(pw), sid_string_dbg(sid_group),
2255 sid_string_dbg(domain_sid)));
2256 return NT_STATUS_UNSUCCESSFUL;
2259 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2260 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2261 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2262 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2264 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2265 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2266 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2267 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2268 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2269 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2270 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2271 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2273 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2275 r->primary_gid = primary_gid;
2276 r->acct_flags = pdb_get_acct_ctrl(pw);
2277 r->bad_password_count = pdb_get_bad_password_count(pw);
2278 r->logon_count = pdb_get_logon_count(pw);
2280 return NT_STATUS_OK;
2283 /*************************************************************************
2284 get_user_info_7. Safe. Only gives out account_name.
2285 *************************************************************************/
2287 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2288 struct samr_UserInfo7 *r,
2289 struct samu *smbpass)
2291 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2292 if (!r->account_name.string) {
2293 return NT_STATUS_NO_MEMORY;
2296 return NT_STATUS_OK;
2299 /*************************************************************************
2300 get_user_info_9. Only gives out primary group SID.
2301 *************************************************************************/
2303 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2304 struct samr_UserInfo9 *r,
2305 struct samu *smbpass)
2307 r->primary_gid = pdb_get_group_rid(smbpass);
2309 return NT_STATUS_OK;
2312 /*************************************************************************
2313 get_user_info_16. Safe. Only gives out acb bits.
2314 *************************************************************************/
2316 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2317 struct samr_UserInfo16 *r,
2318 struct samu *smbpass)
2320 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2322 return NT_STATUS_OK;
2325 /*************************************************************************
2326 get_user_info_18. OK - this is the killer as it gives out password info.
2327 Ensure that this is only allowed on an encrypted connection with a root
2329 *************************************************************************/
2331 static NTSTATUS get_user_info_18(pipes_struct *p,
2332 TALLOC_CTX *mem_ctx,
2333 struct samr_UserInfo18 *r,
2336 struct samu *smbpass=NULL;
2341 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2342 return NT_STATUS_ACCESS_DENIED;
2345 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2346 return NT_STATUS_ACCESS_DENIED;
2350 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2353 if ( !(smbpass = samu_new( mem_ctx )) ) {
2354 return NT_STATUS_NO_MEMORY;
2357 ret = pdb_getsampwsid(smbpass, user_sid);
2360 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2361 TALLOC_FREE(smbpass);
2362 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2365 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2367 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2368 TALLOC_FREE(smbpass);
2369 return NT_STATUS_ACCOUNT_DISABLED;
2372 r->lm_pwd_active = true;
2373 r->nt_pwd_active = true;
2374 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2375 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2376 r->password_expired = 0; /* FIXME */
2378 TALLOC_FREE(smbpass);
2380 return NT_STATUS_OK;
2383 /*************************************************************************
2385 *************************************************************************/
2387 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2388 struct samr_UserInfo20 *r,
2389 struct samu *sampass)
2391 const char *munged_dial = NULL;
2394 struct lsa_BinaryString *parameters = NULL;
2398 munged_dial = pdb_get_munged_dial(sampass);
2400 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2401 munged_dial, (int)strlen(munged_dial)));
2404 blob = base64_decode_data_blob(munged_dial);
2406 blob = data_blob_string_const_null("");
2409 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2410 data_blob_free(&blob);
2411 if (!NT_STATUS_IS_OK(status)) {
2415 r->parameters = *parameters;
2417 return NT_STATUS_OK;
2421 /*************************************************************************
2423 *************************************************************************/
2425 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2426 struct samr_UserInfo21 *r,
2428 DOM_SID *domain_sid)
2431 const DOM_SID *sid_user, *sid_group;
2432 uint32_t rid, primary_gid;
2433 NTTIME force_password_change;
2434 time_t must_change_time;
2435 struct lsa_BinaryString *parameters = NULL;
2436 const char *munged_dial = NULL;
2441 sid_user = pdb_get_user_sid(pw);
2443 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2444 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2445 "the domain sid %s. Failing operation.\n",
2446 pdb_get_username(pw), sid_string_dbg(sid_user),
2447 sid_string_dbg(domain_sid)));
2448 return NT_STATUS_UNSUCCESSFUL;
2452 sid_group = pdb_get_group_sid(pw);
2455 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2456 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2457 "which conflicts with the domain sid %s. Failing operation.\n",
2458 pdb_get_username(pw), sid_string_dbg(sid_group),
2459 sid_string_dbg(domain_sid)));
2460 return NT_STATUS_UNSUCCESSFUL;
2463 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2464 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2465 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2466 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2467 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2469 must_change_time = pdb_get_pass_must_change_time(pw);
2470 if (must_change_time == get_time_t_max()) {
2471 unix_to_nt_time_abs(&force_password_change, must_change_time);
2473 unix_to_nt_time(&force_password_change, must_change_time);
2476 munged_dial = pdb_get_munged_dial(pw);
2478 blob = base64_decode_data_blob(munged_dial);
2480 blob = data_blob_string_const_null("");
2483 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2484 data_blob_free(&blob);
2485 if (!NT_STATUS_IS_OK(status)) {
2489 r->force_password_change = force_password_change;
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->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2498 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2499 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2501 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2502 r->parameters = *parameters;
2504 r->primary_gid = primary_gid;
2505 r->acct_flags = pdb_get_acct_ctrl(pw);
2506 r->bad_password_count = pdb_get_bad_password_count(pw);
2507 r->logon_count = pdb_get_logon_count(pw);
2508 r->fields_present = pdb_build_fields_present(pw);
2509 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2510 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2511 r->country_code = 0;
2513 r->lm_password_set = 0;
2514 r->nt_password_set = 0;
2519 Look at a user on a real NT4 PDC with usrmgr, press
2520 'ok'. Then you will see that fields_present is set to
2521 0x08f827fa. Look at the user immediately after that again,
2522 and you will see that 0x00fffff is returned. This solves
2523 the problem that you get access denied after having looked
2531 return NT_STATUS_OK;
2534 /*******************************************************************
2536 ********************************************************************/
2538 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2539 struct samr_QueryUserInfo *r)
2542 union samr_UserInfo *user_info = NULL;
2543 struct samr_info *info = NULL;
2547 struct samu *pwd = NULL;
2549 /* search for the handle */
2550 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2551 return NT_STATUS_INVALID_HANDLE;
2553 status = access_check_samr_function(info->acc_granted,
2554 SAMR_USER_ACCESS_GET_ATTRIBUTES,
2555 "_samr_QueryUserInfo");
2556 if (!NT_STATUS_IS_OK(status)) {
2560 domain_sid = info->sid;
2562 sid_split_rid(&domain_sid, &rid);
2564 if (!sid_check_is_in_our_domain(&info->sid))
2565 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2567 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2568 sid_string_dbg(&info->sid)));
2570 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2572 return NT_STATUS_NO_MEMORY;
2575 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2577 if (!(pwd = samu_new(p->mem_ctx))) {
2578 return NT_STATUS_NO_MEMORY;
2582 ret = pdb_getsampwsid(pwd, &info->sid);
2586 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2588 return NT_STATUS_NO_SUCH_USER;
2591 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2593 samr_clear_sam_passwd(pwd);
2595 switch (r->in.level) {
2597 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2600 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2603 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2606 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2609 /* level 18 is special */
2610 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2613 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
2616 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
2619 status = NT_STATUS_INVALID_INFO_CLASS;
2625 *r->out.info = user_info;
2627 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2632 /****************************************************************
2633 ****************************************************************/
2635 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2636 struct samr_QueryUserInfo2 *r)
2638 struct samr_QueryUserInfo u;
2640 u.in.user_handle = r->in.user_handle;
2641 u.in.level = r->in.level;
2642 u.out.info = r->out.info;
2644 return _samr_QueryUserInfo(p, &u);
2647 /*******************************************************************
2648 _samr_GetGroupsForUser
2649 ********************************************************************/
2651 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2652 struct samr_GetGroupsForUser *r)
2654 struct samu *sam_pass=NULL;
2657 struct samr_RidWithAttribute dom_gid;
2658 struct samr_RidWithAttribute *gids = NULL;
2659 uint32 primary_group_rid;
2660 size_t num_groups = 0;
2666 bool success = False;
2668 struct samr_RidWithAttributeArray *rids = NULL;
2671 * from the SID in the request:
2672 * we should send back the list of DOMAIN GROUPS
2673 * the user is a member of
2675 * and only the DOMAIN GROUPS
2676 * no ALIASES !!! neither aliases of the domain
2677 * nor aliases of the builtin SID
2682 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2684 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2686 return NT_STATUS_NO_MEMORY;
2689 /* find the policy handle. open a policy on it. */
2690 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2691 return NT_STATUS_INVALID_HANDLE;
2693 result = access_check_samr_function(acc_granted,
2694 SAMR_USER_ACCESS_GET_GROUPS,
2695 "_samr_GetGroupsForUser");
2696 if (!NT_STATUS_IS_OK(result)) {
2700 if (!sid_check_is_in_our_domain(&sid))
2701 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2703 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2704 return NT_STATUS_NO_MEMORY;
2708 ret = pdb_getsampwsid(sam_pass, &sid);
2712 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2713 sid_string_dbg(&sid)));
2714 return NT_STATUS_NO_SUCH_USER;
2719 /* make both calls inside the root block */
2721 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2722 &sids, &unix_gids, &num_groups);
2723 if ( NT_STATUS_IS_OK(result) ) {
2724 success = sid_peek_check_rid(get_global_sam_sid(),
2725 pdb_get_group_sid(sam_pass),
2726 &primary_group_rid);
2730 if (!NT_STATUS_IS_OK(result)) {
2731 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2732 sid_string_dbg(&sid)));
2737 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2738 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2739 pdb_get_username(sam_pass)));
2740 TALLOC_FREE(sam_pass);
2741 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2747 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2749 dom_gid.rid = primary_group_rid;
2750 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2752 for (i=0; i<num_groups; i++) {
2754 if (!sid_peek_check_rid(get_global_sam_sid(),
2755 &(sids[i]), &dom_gid.rid)) {
2756 DEBUG(10, ("Found sid %s not in our domain\n",
2757 sid_string_dbg(&sids[i])));
2761 if (dom_gid.rid == primary_group_rid) {
2762 /* We added the primary group directly from the
2763 * sam_account. The other SIDs are unique from
2764 * enum_group_memberships */
2768 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2771 rids->count = num_gids;
2774 *r->out.rids = rids;
2776 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2781 /*******************************************************************
2782 _samr_QueryDomainInfo
2783 ********************************************************************/
2785 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2786 struct samr_QueryDomainInfo *r)
2788 NTSTATUS status = NT_STATUS_OK;
2789 struct samr_info *info = NULL;
2790 union samr_DomainInfo *dom_info;
2791 time_t u_expire, u_min_age;
2793 time_t u_lock_duration, u_reset_time;
2796 uint32 account_policy_temp;
2801 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2803 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2805 return NT_STATUS_NO_MEMORY;
2808 /* find the policy handle. open a policy on it. */
2809 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
2810 return NT_STATUS_INVALID_HANDLE;
2813 status = access_check_samr_function(info->acc_granted,
2814 SAMR_ACCESS_LOOKUP_DOMAIN,
2815 "_samr_QueryDomainInfo" );
2817 if ( !NT_STATUS_IS_OK(status) )
2820 switch (r->in.level) {
2827 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
2828 &account_policy_temp);
2829 dom_info->info1.min_password_length = account_policy_temp;
2831 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2832 dom_info->info1.password_history_length = account_policy_temp;
2834 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2835 &dom_info->info1.password_properties);
2837 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2838 u_expire = account_policy_temp;
2840 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2841 u_min_age = account_policy_temp;
2847 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
2848 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
2850 if (lp_check_password_script() && *lp_check_password_script()) {
2851 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
2861 dom_info->general.num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2862 dom_info->general.num_groups = count_sam_groups(info->disp_info);
2863 dom_info->general.num_aliases = count_sam_aliases(info->disp_info);
2865 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
2867 unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
2869 if (!pdb_get_seq_num(&seq_num))
2870 seq_num = time(NULL);
2876 server_role = ROLE_DOMAIN_PDC;
2877 if (lp_server_role() == ROLE_DOMAIN_BDC)
2878 server_role = ROLE_DOMAIN_BDC;
2880 dom_info->general.oem_information.string = lp_serverstring();
2881 dom_info->general.domain_name.string = lp_workgroup();
2882 dom_info->general.primary.string = global_myname();
2883 dom_info->general.sequence_num = seq_num;
2884 dom_info->general.domain_server_state = DOMAIN_SERVER_ENABLED;
2885 dom_info->general.role = server_role;
2886 dom_info->general.unknown3 = 1;
2897 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2898 u_logout = (time_t)ul;
2905 unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
2909 dom_info->oem.oem_information.string = lp_serverstring();
2912 dom_info->info5.domain_name.string = get_global_sam_name();
2915 /* NT returns its own name when a PDC. win2k and later
2916 * only the name of the PDC if itself is a BDC (samba4
2918 dom_info->info6.primary.string = global_myname();
2921 server_role = ROLE_DOMAIN_PDC;
2922 if (lp_server_role() == ROLE_DOMAIN_BDC)
2923 server_role = ROLE_DOMAIN_BDC;
2925 dom_info->info7.role = server_role;
2933 if (!pdb_get_seq_num(&seq_num)) {
2934 seq_num = time(NULL);
2941 dom_info->info8.sequence_num = seq_num;
2942 dom_info->info8.domain_create_time = 0;
2951 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2952 u_lock_duration = account_policy_temp;
2953 if (u_lock_duration != -1) {
2954 u_lock_duration *= 60;
2957 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2958 u_reset_time = account_policy_temp * 60;
2960 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
2961 &account_policy_temp);
2962 dom_info->info12.lockout_threshold = account_policy_temp;
2968 unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
2970 unix_to_nt_time_abs(&dom_info->info12.lockout_window,
2975 return NT_STATUS_INVALID_INFO_CLASS;
2978 *r->out.info = dom_info;
2980 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2985 /* W2k3 seems to use the same check for all 3 objects that can be created via
2986 * SAMR, if you try to create for example "Dialup" as an alias it says
2987 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
2990 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
2992 enum lsa_SidType type;
2995 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
2998 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
2999 * whether the name already exists */
3000 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3001 NULL, NULL, NULL, &type);
3005 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3006 return NT_STATUS_OK;
3009 DEBUG(5, ("trying to create %s, exists as %s\n",
3010 new_name, sid_type_lookup(type)));
3012 if (type == SID_NAME_DOM_GRP) {
3013 return NT_STATUS_GROUP_EXISTS;
3015 if (type == SID_NAME_ALIAS) {
3016 return NT_STATUS_ALIAS_EXISTS;
3019 /* Yes, the default is NT_STATUS_USER_EXISTS */
3020 return NT_STATUS_USER_EXISTS;
3023 /*******************************************************************
3025 ********************************************************************/
3027 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3028 struct samr_CreateUser2 *r)
3030 const char *account = NULL;
3032 uint32_t acb_info = r->in.acct_flags;
3033 struct samr_info *info = NULL;
3038 /* check this, when giving away 'add computer to domain' privs */
3039 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3040 bool can_add_account = False;
3042 DISP_INFO *disp_info = NULL;
3044 /* Get the domain SID stored in the domain policy */
3045 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted,
3047 return NT_STATUS_INVALID_HANDLE;
3049 if (disp_info->builtin_domain) {
3050 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3051 return NT_STATUS_ACCESS_DENIED;
3054 nt_status = access_check_samr_function(acc_granted,
3055 SAMR_DOMAIN_ACCESS_CREATE_USER,
3056 "_samr_CreateUser2");
3057 if (!NT_STATUS_IS_OK(nt_status)) {
3061 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3062 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3063 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3064 this parameter is not an account type */
3065 return NT_STATUS_INVALID_PARAMETER;
3068 account = r->in.account_name->string;
3069 if (account == NULL) {
3070 return NT_STATUS_NO_MEMORY;
3073 nt_status = can_create(p->mem_ctx, account);
3074 if (!NT_STATUS_IS_OK(nt_status)) {
3078 /* determine which user right we need to check based on the acb_info */
3080 if ( acb_info & ACB_WSTRUST )
3082 se_priv_copy( &se_rights, &se_machine_account );
3083 can_add_account = user_has_privileges(
3084 p->server_info->ptok, &se_rights );
3086 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3087 account for domain trusts and changes the ACB flags later */
3088 else if ( acb_info & ACB_NORMAL &&
3089 (account[strlen(account)-1] != '$') )
3091 se_priv_copy( &se_rights, &se_add_users );
3092 can_add_account = user_has_privileges(
3093 p->server_info->ptok, &se_rights );
3095 else /* implicit assumption of a BDC or domain trust account here
3096 * (we already check the flags earlier) */
3098 if ( lp_enable_privileges() ) {
3099 /* only Domain Admins can add a BDC or domain trust */
3100 se_priv_copy( &se_rights, &se_priv_none );
3101 can_add_account = nt_token_check_domain_rid(
3102 p->server_info->ptok,
3103 DOMAIN_GROUP_RID_ADMINS );
3107 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3108 uidtoname(p->server_info->utok.uid),
3109 can_add_account ? "True":"False" ));
3111 /********** BEGIN Admin BLOCK **********/
3113 if ( can_add_account )
3116 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3119 if ( can_add_account )
3122 /********** END Admin BLOCK **********/
3124 /* now check for failure */
3126 if ( !NT_STATUS_IS_OK(nt_status) )
3129 /* Get the user's SID */
3131 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3133 map_max_allowed_access(p->server_info->ptok, &des_access);
3135 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3136 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3137 se_map_generic(&des_access, &usr_generic_mapping);
3139 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3140 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3141 &acc_granted, "_samr_CreateUser2");
3143 if ( !NT_STATUS_IS_OK(nt_status) ) {
3147 /* associate the user's SID with the new handle. */
3148 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL) {
3149 return NT_STATUS_NO_MEMORY;
3154 info->acc_granted = acc_granted;
3156 /* get a (unique) handle. open a policy on it. */
3157 if (!create_policy_hnd(p, r->out.user_handle, info)) {
3158 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3161 /* After a "set" ensure we have no cached display info. */
3162 force_flush_samr_cache(info->disp_info);
3164 *r->out.access_granted = acc_granted;
3166 return NT_STATUS_OK;
3169 /****************************************************************
3170 ****************************************************************/
3172 NTSTATUS _samr_CreateUser(pipes_struct *p,
3173 struct samr_CreateUser *r)
3175 struct samr_CreateUser2 c;
3176 uint32_t access_granted;
3178 c.in.domain_handle = r->in.domain_handle;
3179 c.in.account_name = r->in.account_name;
3180 c.in.acct_flags = ACB_NORMAL;
3181 c.in.access_mask = r->in.access_mask;
3182 c.out.user_handle = r->out.user_handle;
3183 c.out.access_granted = &access_granted;
3184 c.out.rid = r->out.rid;
3186 return _samr_CreateUser2(p, &c);
3189 /*******************************************************************
3191 ********************************************************************/
3193 NTSTATUS _samr_Connect(pipes_struct *p,
3194 struct samr_Connect *r)
3196 struct samr_connect_info *info;
3197 uint32_t acc_granted;
3198 struct policy_handle hnd;
3199 uint32 des_access = r->in.access_mask;
3204 if (!pipe_access_check(p)) {
3205 DEBUG(3, ("access denied to _samr_Connect\n"));
3206 return NT_STATUS_ACCESS_DENIED;
3209 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3210 was observed from a win98 client trying to enumerate users (when configured
3211 user level access control on shares) --jerry */
3213 map_max_allowed_access(p->server_info->ptok, &des_access);
3215 se_map_generic( &des_access, &sam_generic_mapping );
3217 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3218 |SAMR_ACCESS_LOOKUP_DOMAIN);
3220 /* set up the SAMR connect_anon response */
3222 info = policy_handle_create(p, &hnd, acc_granted,
3223 struct samr_connect_info,
3225 if (!NT_STATUS_IS_OK(status)) {
3229 *r->out.connect_handle = hnd;
3230 return NT_STATUS_OK;
3233 /*******************************************************************
3235 ********************************************************************/
3237 NTSTATUS _samr_Connect2(pipes_struct *p,
3238 struct samr_Connect2 *r)
3240 struct samr_connect_info *info = NULL;
3241 struct policy_handle hnd;
3242 SEC_DESC *psd = NULL;
3244 uint32 des_access = r->in.access_mask;
3247 const char *fn = "_samr_Connect2";
3249 switch (p->hdr_req.opnum) {
3250 case NDR_SAMR_CONNECT2:
3251 fn = "_samr_Connect2";
3253 case NDR_SAMR_CONNECT3:
3254 fn = "_samr_Connect3";
3256 case NDR_SAMR_CONNECT4:
3257 fn = "_samr_Connect4";
3259 case NDR_SAMR_CONNECT5:
3260 fn = "_samr_Connect5";
3264 DEBUG(5,("%s: %d\n", fn, __LINE__));
3268 if (!pipe_access_check(p)) {
3269 DEBUG(3, ("access denied to %s\n", fn));
3270 return NT_STATUS_ACCESS_DENIED;
3273 map_max_allowed_access(p->server_info->ptok, &des_access);
3275 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3276 se_map_generic(&des_access, &sam_generic_mapping);
3278 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3279 NULL, 0, des_access, &acc_granted, fn);
3281 if ( !NT_STATUS_IS_OK(nt_status) )
3284 info = policy_handle_create(p, &hnd, acc_granted,
3285 struct samr_connect_info, &nt_status);
3286 if (!NT_STATUS_IS_OK(nt_status)) {
3290 DEBUG(5,("%s: %d\n", fn, __LINE__));
3292 *r->out.connect_handle = hnd;
3293 return NT_STATUS_OK;
3296 /****************************************************************
3298 ****************************************************************/
3300 NTSTATUS _samr_Connect3(pipes_struct *p,
3301 struct samr_Connect3 *r)
3303 struct samr_Connect2 c;
3305 c.in.system_name = r->in.system_name;
3306 c.in.access_mask = r->in.access_mask;
3307 c.out.connect_handle = r->out.connect_handle;
3309 return _samr_Connect2(p, &c);
3312 /*******************************************************************
3314 ********************************************************************/
3316 NTSTATUS _samr_Connect4(pipes_struct *p,
3317 struct samr_Connect4 *r)
3319 struct samr_Connect2 c;
3321 c.in.system_name = r->in.system_name;
3322 c.in.access_mask = r->in.access_mask;
3323 c.out.connect_handle = r->out.connect_handle;
3325 return _samr_Connect2(p, &c);
3328 /*******************************************************************
3330 ********************************************************************/
3332 NTSTATUS _samr_Connect5(pipes_struct *p,
3333 struct samr_Connect5 *r)
3336 struct samr_Connect2 c;
3337 struct samr_ConnectInfo1 info1;
3339 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3342 c.in.system_name = r->in.system_name;
3343 c.in.access_mask = r->in.access_mask;
3344 c.out.connect_handle = r->out.connect_handle;
3346 status = _samr_Connect2(p, &c);
3347 if (!NT_STATUS_IS_OK(status)) {
3351 *r->out.level_out = 1;
3352 r->out.info_out->info1 = info1;
3354 return NT_STATUS_OK;
3357 /**********************************************************************
3359 **********************************************************************/
3361 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3362 struct samr_LookupDomain *r)
3365 struct samr_connect_info *info;
3366 const char *domain_name;
3367 DOM_SID *sid = NULL;
3369 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3370 Reverted that change so we will work with RAS servers again */
3372 info = policy_handle_find(p, r->in.connect_handle,
3373 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3374 struct samr_connect_info,
3376 if (!NT_STATUS_IS_OK(status)) {
3380 domain_name = r->in.domain_name->string;
3382 return NT_STATUS_INVALID_PARAMETER;
3385 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3387 return NT_STATUS_NO_MEMORY;
3390 if (strequal(domain_name, builtin_domain_name())) {
3391 sid_copy(sid, &global_sid_Builtin);
3393 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3394 status = NT_STATUS_NO_SUCH_DOMAIN;
3398 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3399 sid_string_dbg(sid)));
3406 /**********************************************************************
3408 **********************************************************************/
3410 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3411 struct samr_EnumDomains *r)
3414 struct samr_connect_info *info;
3415 uint32_t num_entries = 2;
3416 struct samr_SamEntry *entry_array = NULL;
3417 struct samr_SamArray *sam;
3419 info = policy_handle_find(p, r->in.connect_handle,
3420 SAMR_ACCESS_ENUM_DOMAINS, NULL,
3421 struct samr_connect_info, &status);
3422 if (!NT_STATUS_IS_OK(status)) {
3426 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3428 return NT_STATUS_NO_MEMORY;
3431 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3432 struct samr_SamEntry,
3435 return NT_STATUS_NO_MEMORY;
3438 entry_array[0].idx = 0;
3439 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3441 entry_array[1].idx = 1;
3442 init_lsa_String(&entry_array[1].name, "Builtin");
3444 sam->count = num_entries;
3445 sam->entries = entry_array;
3448 *r->out.num_entries = num_entries;
3453 /*******************************************************************
3455 ********************************************************************/
3457 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3458 struct samr_OpenAlias *r)
3461 uint32 alias_rid = r->in.rid;
3462 struct samr_info *info = NULL;
3463 SEC_DESC *psd = NULL;
3465 uint32 des_access = r->in.access_mask;
3470 /* find the domain policy and get the SID / access bits stored in the domain policy */
3472 if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
3473 return NT_STATUS_INVALID_HANDLE;
3475 status = access_check_samr_function(acc_granted,
3476 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3479 if ( !NT_STATUS_IS_OK(status) )
3482 /* append the alias' RID to it */
3484 if (!sid_append_rid(&sid, alias_rid))
3485 return NT_STATUS_NO_SUCH_ALIAS;
3487 /*check if access can be granted as requested by client. */
3489 map_max_allowed_access(p->server_info->ptok, &des_access);
3491 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3492 se_map_generic(&des_access,&ali_generic_mapping);
3494 se_priv_copy( &se_rights, &se_add_users );
3497 status = access_check_samr_object(psd, p->server_info->ptok,
3498 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3499 &acc_granted, "_samr_OpenAlias");
3501 if ( !NT_STATUS_IS_OK(status) )
3505 /* Check we actually have the requested alias */
3506 enum lsa_SidType type;
3511 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3514 if (!result || (type != SID_NAME_ALIAS)) {
3515 return NT_STATUS_NO_SUCH_ALIAS;
3518 /* make sure there is a mapping */
3520 if ( !sid_to_gid( &sid, &gid ) ) {
3521 return NT_STATUS_NO_SUCH_ALIAS;
3526 /* associate the alias SID with the new handle. */
3527 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
3528 return NT_STATUS_NO_MEMORY;
3530 info->acc_granted = acc_granted;
3532 /* get a (unique) handle. open a policy on it. */
3533 if (!create_policy_hnd(p, r->out.alias_handle, info))
3534 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3536 return NT_STATUS_OK;
3539 /*******************************************************************
3541 ********************************************************************/
3543 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3544 struct samr_UserInfo7 *id7,
3550 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3551 return NT_STATUS_ACCESS_DENIED;
3554 if (!id7->account_name.string) {
3555 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3556 return NT_STATUS_ACCESS_DENIED;
3559 /* check to see if the new username already exists. Note: we can't
3560 reliably lock all backends, so there is potentially the
3561 possibility that a user can be created in between this check and
3562 the rename. The rename should fail, but may not get the
3563 exact same failure status code. I think this is small enough
3564 of a window for this type of operation and the results are
3565 simply that the rename fails with a slightly different status
3566 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3568 rc = can_create(mem_ctx, id7->account_name.string);
3569 if (!NT_STATUS_IS_OK(rc)) {
3573 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3578 /*******************************************************************
3580 ********************************************************************/
3582 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3586 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3590 /* FIX ME: check if the value is really changed --metze */
3591 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3595 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3602 /*******************************************************************
3604 ********************************************************************/
3606 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
3607 TALLOC_CTX *mem_ctx,
3608 DATA_BLOB *session_key,
3612 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3613 return NT_STATUS_INVALID_PARAMETER;
3616 if (id18->nt_pwd_active || id18->lm_pwd_active) {
3617 if (!session_key->length) {
3618 return NT_STATUS_NO_USER_SESSION_KEY;
3622 if (id18->nt_pwd_active) {
3626 in = data_blob_const(id18->nt_pwd.hash, 16);
3627 out = data_blob_talloc_zero(mem_ctx, 16);
3629 sess_crypt_blob(&out, &in, session_key, false);
3631 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
3632 return NT_STATUS_ACCESS_DENIED;
3635 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3638 if (id18->lm_pwd_active) {
3642 in = data_blob_const(id18->lm_pwd.hash, 16);
3643 out = data_blob_talloc_zero(mem_ctx, 16);
3645 sess_crypt_blob(&out, &in, session_key, false);
3647 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
3648 return NT_STATUS_ACCESS_DENIED;
3651 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3654 copy_id18_to_sam_passwd(pwd, id18);
3656 return pdb_update_sam_account(pwd);
3659 /*******************************************************************
3661 ********************************************************************/
3663 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3667 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3671 copy_id20_to_sam_passwd(pwd, id20);
3673 /* write the change out */
3674 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3681 /*******************************************************************
3683 ********************************************************************/
3685 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
3686 TALLOC_CTX *mem_ctx,
3687 DATA_BLOB *session_key,
3693 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3694 return NT_STATUS_INVALID_PARAMETER;
3697 if (id21->fields_present == 0) {
3698 return NT_STATUS_INVALID_PARAMETER;
3701 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3702 return NT_STATUS_ACCESS_DENIED;
3705 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
3706 if (id21->nt_password_set) {
3709 if ((id21->nt_owf_password.length != 16) ||
3710 (id21->nt_owf_password.size != 16)) {
3711 return NT_STATUS_INVALID_PARAMETER;
3714 if (!session_key->length) {
3715 return NT_STATUS_NO_USER_SESSION_KEY;
3718 in = data_blob_const(id21->nt_owf_password.array, 16);
3719 out = data_blob_talloc_zero(mem_ctx, 16);
3721 sess_crypt_blob(&out, &in, session_key, false);
3723 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
3724 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3728 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
3729 if (id21->lm_password_set) {
3732 if ((id21->lm_owf_password.length != 16) ||
3733 (id21->lm_owf_password.size != 16)) {
3734 return NT_STATUS_INVALID_PARAMETER;
3737 if (!session_key->length) {
3738 return NT_STATUS_NO_USER_SESSION_KEY;
3741 in = data_blob_const(id21->lm_owf_password.array, 16);
3742 out = data_blob_talloc_zero(mem_ctx, 16);
3744 sess_crypt_blob(&out, &in, session_key, false);
3746 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
3747 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3751 /* we need to separately check for an account rename first */
3753 if (id21->account_name.string &&
3754 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3757 /* check to see if the new username already exists. Note: we can't
3758 reliably lock all backends, so there is potentially the
3759 possibility that a user can be created in between this check and
3760 the rename. The rename should fail, but may not get the
3761 exact same failure status code. I think this is small enough
3762 of a window for this type of operation and the results are
3763 simply that the rename fails with a slightly different status
3764 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3766 status = can_create(mem_ctx, id21->account_name.string);
3767 if (!NT_STATUS_IS_OK(status)) {
3771 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3773 if (!NT_STATUS_IS_OK(status)) {
3774 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3775 nt_errstr(status)));
3779 /* set the new username so that later
3780 functions can work on the new account */
3781 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3784 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3787 * The funny part about the previous two calls is
3788 * that pwd still has the password hashes from the
3789 * passdb entry. These have not been updated from
3790 * id21. I don't know if they need to be set. --jerry
3793 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3794 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3795 if ( !NT_STATUS_IS_OK(status) ) {
3800 /* Don't worry about writing out the user account since the
3801 primary group SID is generated solely from the user's Unix
3804 /* write the change out */
3805 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3809 return NT_STATUS_OK;
3812 /*******************************************************************
3814 ********************************************************************/
3816 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3817 struct samr_UserInfo23 *id23,
3820 char *plaintext_buf = NULL;
3826 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3827 return NT_STATUS_INVALID_PARAMETER;
3830 if (id23->info.fields_present == 0) {
3831 return NT_STATUS_INVALID_PARAMETER;
3834 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3835 return NT_STATUS_ACCESS_DENIED;
3838 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3839 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
3841 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3842 pdb_get_username(pwd)));
3844 if (!decode_pw_buffer(mem_ctx,
3845 id23->password.data,
3849 return NT_STATUS_WRONG_PASSWORD;
3852 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3853 return NT_STATUS_ACCESS_DENIED;
3857 copy_id23_to_sam_passwd(pwd, id23);
3859 acct_ctrl = pdb_get_acct_ctrl(pwd);
3861 /* if it's a trust account, don't update /etc/passwd */
3862 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3863 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3864 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3865 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3866 } else if (plaintext_buf) {
3867 /* update the UNIX password */
3868 if (lp_unix_password_sync() ) {
3869 struct passwd *passwd;
3870 if (pdb_get_username(pwd) == NULL) {
3871 DEBUG(1, ("chgpasswd: User without name???\n"));
3872 return NT_STATUS_ACCESS_DENIED;
3875 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3876 if (passwd == NULL) {
3877 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3880 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3881 return NT_STATUS_ACCESS_DENIED;
3883 TALLOC_FREE(passwd);
3887 if (plaintext_buf) {
3888 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3891 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3892 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3897 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3901 return NT_STATUS_OK;
3904 /*******************************************************************
3906 ********************************************************************/
3908 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
3911 char *plaintext_buf = NULL;
3914 DEBUG(5, ("Attempting administrator password change for user %s\n",
3915 pdb_get_username(pwd)));
3917 acct_ctrl = pdb_get_acct_ctrl(pwd);
3919 if (!decode_pw_buffer(talloc_tos(),
3927 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3931 /* if it's a trust account, don't update /etc/passwd */
3932 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3933 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3934 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3935 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3937 /* update the UNIX password */
3938 if (lp_unix_password_sync()) {
3939 struct passwd *passwd;
3941 if (pdb_get_username(pwd) == NULL) {
3942 DEBUG(1, ("chgpasswd: User without name???\n"));
3946 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3947 if (passwd == NULL) {
3948 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3951 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3954 TALLOC_FREE(passwd);
3958 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3960 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3965 /*******************************************************************
3967 ********************************************************************/
3969 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
3970 struct samr_UserInfo24 *id24,
3976 DEBUG(5, ("set_user_info_24: NULL id24\n"));
3977 return NT_STATUS_INVALID_PARAMETER;
3980 if (!set_user_info_pw(id24->password.data, pwd)) {
3981 return NT_STATUS_WRONG_PASSWORD;
3984 copy_id24_to_sam_passwd(pwd, id24);
3986 status = pdb_update_sam_account(pwd);
3987 if (!NT_STATUS_IS_OK(status)) {
3991 return NT_STATUS_OK;
3994 /*******************************************************************
3996 ********************************************************************/
3998 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
3999 struct samr_UserInfo25 *id25,
4005 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4006 return NT_STATUS_INVALID_PARAMETER;
4009 if (id25->info.fields_present == 0) {
4010 return NT_STATUS_INVALID_PARAMETER;
4013 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4014 return NT_STATUS_ACCESS_DENIED;
4017 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4018 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4020 if (!set_user_info_pw(id25->password.data, pwd)) {
4021 return NT_STATUS_WRONG_PASSWORD;
4025 copy_id25_to_sam_passwd(pwd, id25);
4027 /* write the change out */
4028 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4033 * We need to "pdb_update_sam_account" before the unix primary group
4034 * is set, because the idealx scripts would also change the
4035 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4036 * the delete explicit / add explicit, which would then fail to find
4037 * the previous primaryGroupSid value.
4040 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4041 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4042 if ( !NT_STATUS_IS_OK(status) ) {
4047 return NT_STATUS_OK;
4050 /*******************************************************************
4052 ********************************************************************/
4054 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4055 struct samr_UserInfo26 *id26,
4061 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4062 return NT_STATUS_INVALID_PARAMETER;
4065 if (!set_user_info_pw(id26->password.data, pwd)) {
4066 return NT_STATUS_WRONG_PASSWORD;
4069 copy_id26_to_sam_passwd(pwd, id26);
4071 status = pdb_update_sam_account(pwd);
4072 if (!NT_STATUS_IS_OK(status)) {
4076 return NT_STATUS_OK;
4080 /*******************************************************************
4082 ********************************************************************/
4084 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4085 struct samr_SetUserInfo *r)
4088 struct samu *pwd = NULL;
4090 union samr_UserInfo *info = r->in.info;
4091 uint16_t switch_value = r->in.level;
4092 uint32_t acc_granted;
4093 uint32_t acc_required;
4095 bool has_enough_rights = False;
4097 DISP_INFO *disp_info = NULL;
4099 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4101 /* find the policy handle. open a policy on it. */
4102 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) {
4103 return NT_STATUS_INVALID_HANDLE;
4106 /* This is tricky. A WinXP domain join sets
4107 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4108 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4109 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4110 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4111 we'll use the set from the WinXP join as the basis. */
4113 switch (switch_value) {
4118 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4121 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4122 SAMR_USER_ACCESS_SET_ATTRIBUTES |
4123 SAMR_USER_ACCESS_GET_ATTRIBUTES;
4127 status = access_check_samr_function(acc_granted,
4129 "_samr_SetUserInfo");
4130 if (!NT_STATUS_IS_OK(status)) {
4134 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4135 sid_string_dbg(&sid), switch_value));
4138 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4139 return NT_STATUS_INVALID_INFO_CLASS;
4142 if (!(pwd = samu_new(NULL))) {
4143 return NT_STATUS_NO_MEMORY;
4147 ret = pdb_getsampwsid(pwd, &sid);
4152 return NT_STATUS_NO_SUCH_USER;
4155 /* deal with machine password changes differently from userinfo changes */
4156 /* check to see if we have the sufficient rights */
4158 acb_info = pdb_get_acct_ctrl(pwd);
4159 if (acb_info & ACB_WSTRUST)
4160 has_enough_rights = user_has_privileges(p->server_info->ptok,
4161 &se_machine_account);
4162 else if (acb_info & ACB_NORMAL)
4163 has_enough_rights = user_has_privileges(p->server_info->ptok,
4165 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4166 if (lp_enable_privileges()) {
4167 has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
4168 DOMAIN_GROUP_RID_ADMINS);
4172 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4173 uidtoname(p->server_info->utok.uid),
4174 has_enough_rights ? "" : " not"));
4176 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4178 if (has_enough_rights) {
4182 /* ok! user info levels (lots: see MSDEV help), off we go... */
4184 switch (switch_value) {
4187 status = set_user_info_7(p->mem_ctx,
4192 if (!set_user_info_16(&info->info16, pwd)) {
4193 status = NT_STATUS_ACCESS_DENIED;
4198 /* Used by AS/U JRA. */
4199 status = set_user_info_18(&info->info18,
4201 &p->server_info->user_session_key,
4206 if (!set_user_info_20(&info->info20, pwd)) {
4207 status = NT_STATUS_ACCESS_DENIED;
4212 status = set_user_info_21(&info->info21,
4214 &p->server_info->user_session_key,
4219 if (!p->server_info->user_session_key.length) {
4220 status = NT_STATUS_NO_USER_SESSION_KEY;
4222 SamOEMhashBlob(info->info23.password.data, 516,
4223 &p->server_info->user_session_key);
4225 dump_data(100, info->info23.password.data, 516);
4227 status = set_user_info_23(p->mem_ctx,
4228 &info->info23, pwd);
4232 if (!p->server_info->user_session_key.length) {
4233 status = NT_STATUS_NO_USER_SESSION_KEY;
4235 SamOEMhashBlob(info->info24.password.data,
4237 &p->server_info->user_session_key);
4239 dump_data(100, info->info24.password.data, 516);
4241 status = set_user_info_24(p->mem_ctx,
4242 &info->info24, pwd);
4246 if (!p->server_info->user_session_key.length) {
4247 status = NT_STATUS_NO_USER_SESSION_KEY;
4249 encode_or_decode_arc4_passwd_buffer(
4250 info->info25.password.data,
4251 &p->server_info->user_session_key);
4253 dump_data(100, info->info25.password.data, 532);
4255 status = set_user_info_25(p->mem_ctx,
4256 &info->info25, pwd);
4260 if (!p->server_info->user_session_key.length) {
4261 status = NT_STATUS_NO_USER_SESSION_KEY;
4263 encode_or_decode_arc4_passwd_buffer(
4264 info->info26.password.data,
4265 &p->server_info->user_session_key);
4267 dump_data(100, info->info26.password.data, 516);
4269 status = set_user_info_26(p->mem_ctx,
4270 &info->info26, pwd);
4274 status = NT_STATUS_INVALID_INFO_CLASS;
4279 if (has_enough_rights) {
4283 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4285 if (NT_STATUS_IS_OK(status)) {
4286 force_flush_samr_cache(disp_info);
4292 /*******************************************************************
4294 ********************************************************************/
4296 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4297 struct samr_SetUserInfo2 *r)
4299 struct samr_SetUserInfo q;
4301 q.in.user_handle = r->in.user_handle;
4302 q.in.level = r->in.level;
4303 q.in.info = r->in.info;
4305 return _samr_SetUserInfo(p, &q);
4308 /*********************************************************************
4309 _samr_GetAliasMembership
4310 *********************************************************************/
4312 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4313 struct samr_GetAliasMembership *r)
4315 size_t num_alias_rids;
4317 struct samr_info *info = NULL;
4325 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4327 /* find the policy handle. open a policy on it. */
4328 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4329 return NT_STATUS_INVALID_HANDLE;
4331 ntstatus1 = access_check_samr_function(info->acc_granted,
4332 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
4333 "_samr_GetAliasMembership");
4334 ntstatus2 = access_check_samr_function(info->acc_granted,
4335 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4336 "_samr_GetAliasMembership");
4338 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4339 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4340 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4341 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4345 if (!sid_check_is_domain(&info->sid) &&
4346 !sid_check_is_builtin(&info->sid))
4347 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4349 if (r->in.sids->num_sids) {
4350 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4352 if (members == NULL)
4353 return NT_STATUS_NO_MEMORY;
4358 for (i=0; i<r->in.sids->num_sids; i++)
4359 sid_copy(&members[i], r->in.sids->sids[i].sid);
4365 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4366 r->in.sids->num_sids,
4367 &alias_rids, &num_alias_rids);
4370 if (!NT_STATUS_IS_OK(ntstatus1)) {
4374 r->out.rids->count = num_alias_rids;
4375 r->out.rids->ids = alias_rids;
4377 return NT_STATUS_OK;
4380 /*********************************************************************
4381 _samr_GetMembersInAlias
4382 *********************************************************************/
4384 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4385 struct samr_GetMembersInAlias *r)
4389 size_t num_sids = 0;
4390 struct lsa_SidPtr *sids = NULL;
4391 DOM_SID *pdb_sids = NULL;
4397 /* find the policy handle. open a policy on it. */
4398 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4399 return NT_STATUS_INVALID_HANDLE;
4401 status = access_check_samr_function(acc_granted,
4402 SAMR_ALIAS_ACCESS_GET_MEMBERS,
4403 "_samr_GetMembersInAlias");
4404 if (!NT_STATUS_IS_OK(status)) {
4408 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4411 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4414 if (!NT_STATUS_IS_OK(status)) {
4419 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4421 TALLOC_FREE(pdb_sids);
4422 return NT_STATUS_NO_MEMORY;
4426 for (i = 0; i < num_sids; i++) {
4427 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4429 TALLOC_FREE(pdb_sids);
4430 return NT_STATUS_NO_MEMORY;
4434 r->out.sids->num_sids = num_sids;
4435 r->out.sids->sids = sids;
4437 TALLOC_FREE(pdb_sids);
4439 return NT_STATUS_OK;
4442 /*********************************************************************
4443 _samr_QueryGroupMember
4444 *********************************************************************/
4446 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4447 struct samr_QueryGroupMember *r)
4450 size_t i, num_members;
4458 struct samr_RidTypeArray *rids = NULL;
4460 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4462 return NT_STATUS_NO_MEMORY;
4465 /* find the policy handle. open a policy on it. */
4466 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4467 return NT_STATUS_INVALID_HANDLE;
4469 status = access_check_samr_function(acc_granted,
4470 SAMR_GROUP_ACCESS_GET_MEMBERS,
4471 "_samr_QueryGroupMember");
4472 if (!NT_STATUS_IS_OK(status)) {
4476 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4478 if (!sid_check_is_in_our_domain(&group_sid)) {
4479 DEBUG(3, ("sid %s is not in our domain\n",
4480 sid_string_dbg(&group_sid)));
4481 return NT_STATUS_NO_SUCH_GROUP;
4484 DEBUG(10, ("lookup on Domain SID\n"));
4487 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4488 &rid, &num_members);
4491 if (!NT_STATUS_IS_OK(status))
4495 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4497 return NT_STATUS_NO_MEMORY;
4503 for (i=0; i<num_members; i++)
4504 attr[i] = SID_NAME_USER;
4506 rids->count = num_members;
4510 *r->out.rids = rids;
4512 return NT_STATUS_OK;
4515 /*********************************************************************
4516 _samr_AddAliasMember
4517 *********************************************************************/
4519 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4520 struct samr_AddAliasMember *r)
4525 bool can_add_accounts;
4527 DISP_INFO *disp_info = NULL;
4529 /* Find the policy handle. Open a policy on it. */
4530 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4531 return NT_STATUS_INVALID_HANDLE;
4533 status = access_check_samr_function(acc_granted,
4534 SAMR_ALIAS_ACCESS_ADD_MEMBER,
4535 "_samr_AddAliasMember");
4536 if (!NT_STATUS_IS_OK(status)) {
4540 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4542 se_priv_copy( &se_rights, &se_add_users );
4543 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4545 /******** BEGIN SeAddUsers BLOCK *********/
4547 if ( can_add_accounts )
4550 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4552 if ( can_add_accounts )
4555 /******** END SeAddUsers BLOCK *********/
4557 if (NT_STATUS_IS_OK(status)) {
4558 force_flush_samr_cache(disp_info);
4564 /*********************************************************************
4565 _samr_DeleteAliasMember
4566 *********************************************************************/
4568 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4569 struct samr_DeleteAliasMember *r)
4574 bool can_add_accounts;
4576 DISP_INFO *disp_info = NULL;
4578 /* Find the policy handle. Open a policy on it. */
4579 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4580 return NT_STATUS_INVALID_HANDLE;
4582 status = access_check_samr_function(acc_granted,
4583 SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
4584 "_samr_DeleteAliasMember");
4585 if (!NT_STATUS_IS_OK(status)) {
4589 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4590 sid_string_dbg(&alias_sid)));
4592 se_priv_copy( &se_rights, &se_add_users );
4593 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4595 /******** BEGIN SeAddUsers BLOCK *********/
4597 if ( can_add_accounts )
4600 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4602 if ( can_add_accounts )
4605 /******** END SeAddUsers BLOCK *********/
4607 if (NT_STATUS_IS_OK(status)) {
4608 force_flush_samr_cache(disp_info);
4614 /*********************************************************************
4615 _samr_AddGroupMember
4616 *********************************************************************/
4618 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4619 struct samr_AddGroupMember *r)
4626 bool can_add_accounts;
4627 DISP_INFO *disp_info = NULL;
4629 /* Find the policy handle. Open a policy on it. */
4630 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4631 return NT_STATUS_INVALID_HANDLE;
4633 status = access_check_samr_function(acc_granted,
4634 SAMR_GROUP_ACCESS_ADD_MEMBER,
4635 "_samr_AddGroupMember");
4636 if (!NT_STATUS_IS_OK(status)) {
4640 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4642 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4644 return NT_STATUS_INVALID_HANDLE;
4647 se_priv_copy( &se_rights, &se_add_users );
4648 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4650 /******** BEGIN SeAddUsers BLOCK *********/
4652 if ( can_add_accounts )
4655 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4657 if ( can_add_accounts )
4660 /******** END SeAddUsers BLOCK *********/
4662 force_flush_samr_cache(disp_info);
4667 /*********************************************************************
4668 _samr_DeleteGroupMember
4669 *********************************************************************/
4671 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4672 struct samr_DeleteGroupMember *r)
4680 bool can_add_accounts;
4681 DISP_INFO *disp_info = NULL;
4684 * delete the group member named r->in.rid
4685 * who is a member of the sid associated with the handle
4686 * the rid is a user's rid as the group is a domain group.
4689 /* Find the policy handle. Open a policy on it. */
4690 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4691 return NT_STATUS_INVALID_HANDLE;
4693 status = access_check_samr_function(acc_granted,
4694 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
4695 "_samr_DeleteGroupMember");
4696 if (!NT_STATUS_IS_OK(status)) {
4700 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4702 return NT_STATUS_INVALID_HANDLE;
4705 se_priv_copy( &se_rights, &se_add_users );
4706 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4708 /******** BEGIN SeAddUsers BLOCK *********/
4710 if ( can_add_accounts )
4713 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4715 if ( can_add_accounts )
4718 /******** END SeAddUsers BLOCK *********/
4720 force_flush_samr_cache(disp_info);
4725 /*********************************************************************
4727 *********************************************************************/
4729 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4730 struct samr_DeleteUser *r)
4734 struct samu *sam_pass=NULL;
4736 bool can_add_accounts;
4738 DISP_INFO *disp_info = NULL;
4741 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4743 /* Find the policy handle. Open a policy on it. */
4744 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4745 return NT_STATUS_INVALID_HANDLE;
4747 status = access_check_samr_function(acc_granted,
4748 STD_RIGHT_DELETE_ACCESS,
4749 "_samr_DeleteUser");
4750 if (!NT_STATUS_IS_OK(status)) {
4754 if (!sid_check_is_in_our_domain(&user_sid))
4755 return NT_STATUS_CANNOT_DELETE;
4757 /* check if the user exists before trying to delete */
4758 if ( !(sam_pass = samu_new( NULL )) ) {
4759 return NT_STATUS_NO_MEMORY;
4763 ret = pdb_getsampwsid(sam_pass, &user_sid);
4767 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4768 sid_string_dbg(&user_sid)));
4769 TALLOC_FREE(sam_pass);
4770 return NT_STATUS_NO_SUCH_USER;
4773 acb_info = pdb_get_acct_ctrl(sam_pass);
4775 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4776 if ( acb_info & ACB_WSTRUST ) {
4777 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
4779 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
4782 /******** BEGIN SeAddUsers BLOCK *********/
4784 if ( can_add_accounts )
4787 status = pdb_delete_user(p->mem_ctx, sam_pass);
4789 if ( can_add_accounts )
4792 /******** END SeAddUsers BLOCK *********/
4794 if ( !NT_STATUS_IS_OK(status) ) {
4795 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4796 "user %s: %s.\n", pdb_get_username(sam_pass),
4797 nt_errstr(status)));
4798 TALLOC_FREE(sam_pass);
4803 TALLOC_FREE(sam_pass);
4805 if (!close_policy_hnd(p, r->in.user_handle))
4806 return NT_STATUS_OBJECT_NAME_INVALID;
4808 ZERO_STRUCTP(r->out.user_handle);
4810 force_flush_samr_cache(disp_info);
4812 return NT_STATUS_OK;
4815 /*********************************************************************
4816 _samr_DeleteDomainGroup
4817 *********************************************************************/
4819 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4820 struct samr_DeleteDomainGroup *r)
4827 bool can_add_accounts;
4828 DISP_INFO *disp_info = NULL;
4830 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4832 /* Find the policy handle. Open a policy on it. */
4833 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4834 return NT_STATUS_INVALID_HANDLE;
4836 status = access_check_samr_function(acc_granted,
4837 STD_RIGHT_DELETE_ACCESS,
4838 "_samr_DeleteDomainGroup");
4839 if (!NT_STATUS_IS_OK(status)) {
4843 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4845 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4847 return NT_STATUS_NO_SUCH_GROUP;
4850 se_priv_copy( &se_rights, &se_add_users );
4851 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4853 /******** BEGIN SeAddUsers BLOCK *********/
4855 if ( can_add_accounts )
4858 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4860 if ( can_add_accounts )
4863 /******** END SeAddUsers BLOCK *********/
4865 if ( !NT_STATUS_IS_OK(status) ) {
4866 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4867 "entry for group %s: %s\n",
4868 sid_string_dbg(&group_sid),
4869 nt_errstr(status)));
4873 if (!close_policy_hnd(p, r->in.group_handle))
4874 return NT_STATUS_OBJECT_NAME_INVALID;
4876 force_flush_samr_cache(disp_info);
4878 return NT_STATUS_OK;
4881 /*********************************************************************
4882 _samr_DeleteDomAlias
4883 *********************************************************************/
4885 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4886 struct samr_DeleteDomAlias *r)
4891 bool can_add_accounts;
4893 DISP_INFO *disp_info = NULL;
4895 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4897 /* Find the policy handle. Open a policy on it. */
4898 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4899 return NT_STATUS_INVALID_HANDLE;
4901 /* copy the handle to the outgoing reply */
4903 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4905 status = access_check_samr_function(acc_granted,
4906 STD_RIGHT_DELETE_ACCESS,
4907 "_samr_DeleteDomAlias");
4908 if (!NT_STATUS_IS_OK(status)) {
4912 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4914 /* Don't let Windows delete builtin groups */
4916 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4917 return NT_STATUS_SPECIAL_ACCOUNT;
4920 if (!sid_check_is_in_our_domain(&alias_sid))
4921 return NT_STATUS_NO_SUCH_ALIAS;
4923 DEBUG(10, ("lookup on Local SID\n"));
4925 se_priv_copy( &se_rights, &se_add_users );
4926 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4928 /******** BEGIN SeAddUsers BLOCK *********/
4930 if ( can_add_accounts )
4933 /* Have passdb delete the alias */
4934 status = pdb_delete_alias(&alias_sid);
4936 if ( can_add_accounts )
4939 /******** END SeAddUsers BLOCK *********/
4941 if ( !NT_STATUS_IS_OK(status))
4944 if (!close_policy_hnd(p, r->in.alias_handle))
4945 return NT_STATUS_OBJECT_NAME_INVALID;
4947 force_flush_samr_cache(disp_info);
4949 return NT_STATUS_OK;
4952 /*********************************************************************
4953 _samr_CreateDomainGroup
4954 *********************************************************************/
4956 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4957 struct samr_CreateDomainGroup *r)
4964 struct samr_info *info;
4967 bool can_add_accounts;
4968 DISP_INFO *disp_info = NULL;
4970 /* Find the policy handle. Open a policy on it. */
4971 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4972 return NT_STATUS_INVALID_HANDLE;
4974 status = access_check_samr_function(acc_granted,
4975 SAMR_DOMAIN_ACCESS_CREATE_GROUP,
4976 "_samr_CreateDomainGroup");
4977 if (!NT_STATUS_IS_OK(status)) {
4981 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4982 return NT_STATUS_ACCESS_DENIED;
4984 name = r->in.name->string;
4986 return NT_STATUS_NO_MEMORY;
4989 status = can_create(p->mem_ctx, name);
4990 if (!NT_STATUS_IS_OK(status)) {
4994 se_priv_copy( &se_rights, &se_add_users );
4995 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4997 /******** BEGIN SeAddUsers BLOCK *********/
4999 if ( can_add_accounts )
5002 /* check that we successfully create the UNIX group */
5004 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5006 if ( can_add_accounts )
5009 /******** END SeAddUsers BLOCK *********/
5011 /* check if we should bail out here */
5013 if ( !NT_STATUS_IS_OK(status) )
5016 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5018 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5019 return NT_STATUS_NO_MEMORY;
5021 /* they created it; let the user do what he wants with it */
5023 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5025 /* get a (unique) handle. open a policy on it. */
5026 if (!create_policy_hnd(p, r->out.group_handle, info))
5027 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5029 force_flush_samr_cache(disp_info);
5031 return NT_STATUS_OK;
5034 /*********************************************************************
5035 _samr_CreateDomAlias
5036 *********************************************************************/
5038 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5039 struct samr_CreateDomAlias *r)
5043 const char *name = NULL;
5044 struct samr_info *info;
5049 bool can_add_accounts;
5050 DISP_INFO *disp_info = NULL;
5052 /* Find the policy handle. Open a policy on it. */
5053 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5054 return NT_STATUS_INVALID_HANDLE;
5056 result = access_check_samr_function(acc_granted,
5057 SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
5058 "_samr_CreateDomAlias");
5059 if (!NT_STATUS_IS_OK(result)) {
5063 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5064 return NT_STATUS_ACCESS_DENIED;
5066 name = r->in.alias_name->string;
5068 se_priv_copy( &se_rights, &se_add_users );
5069 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5071 result = can_create(p->mem_ctx, name);
5072 if (!NT_STATUS_IS_OK(result)) {
5076 /******** BEGIN SeAddUsers BLOCK *********/
5078 if ( can_add_accounts )
5081 /* Have passdb create the alias */
5082 result = pdb_create_alias(name, r->out.rid);
5084 if ( can_add_accounts )
5087 /******** END SeAddUsers BLOCK *********/
5089 if (!NT_STATUS_IS_OK(result)) {
5090 DEBUG(10, ("pdb_create_alias failed: %s\n",
5091 nt_errstr(result)));
5095 sid_copy(&info_sid, get_global_sam_sid());
5096 sid_append_rid(&info_sid, *r->out.rid);
5098 if (!sid_to_gid(&info_sid, &gid)) {
5099 DEBUG(10, ("Could not find alias just created\n"));
5100 return NT_STATUS_ACCESS_DENIED;
5103 /* check if the group has been successfully created */
5104 if ( getgrgid(gid) == NULL ) {
5105 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5107 return NT_STATUS_ACCESS_DENIED;
5110 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5111 return NT_STATUS_NO_MEMORY;
5113 /* they created it; let the user do what he wants with it */
5115 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5117 /* get a (unique) handle. open a policy on it. */
5118 if (!create_policy_hnd(p, r->out.alias_handle, info))
5119 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5121 force_flush_samr_cache(disp_info);
5123 return NT_STATUS_OK;
5126 /*********************************************************************
5127 _samr_QueryGroupInfo
5128 *********************************************************************/
5130 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5131 struct samr_QueryGroupInfo *r)
5136 union samr_GroupInfo *info = NULL;
5139 uint32_t attributes = SE_GROUP_MANDATORY |
5140 SE_GROUP_ENABLED_BY_DEFAULT |
5142 const char *group_name = NULL;
5143 const char *group_description = NULL;
5145 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5146 return NT_STATUS_INVALID_HANDLE;
5148 status = access_check_samr_function(acc_granted,
5149 SAMR_GROUP_ACCESS_LOOKUP_INFO,
5150 "_samr_QueryGroupInfo");
5151 if (!NT_STATUS_IS_OK(status)) {
5156 ret = get_domain_group_from_sid(group_sid, &map);
5159 return NT_STATUS_INVALID_HANDLE;
5161 /* FIXME: map contains fstrings */
5162 group_name = talloc_strdup(r, map.nt_name);
5163 group_description = talloc_strdup(r, map.comment);
5165 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5167 return NT_STATUS_NO_MEMORY;
5170 switch (r->in.level) {
5176 status = pdb_enum_group_members(
5177 p->mem_ctx, &group_sid, &members, &num_members);
5180 if (!NT_STATUS_IS_OK(status)) {
5184 info->all.name.string = group_name;
5185 info->all.attributes = attributes;
5186 info->all.num_members = num_members;
5187 info->all.description.string = group_description;
5191 info->name.string = group_name;
5194 info->attributes.attributes = attributes;
5197 info->description.string = group_description;
5207 status = pdb_enum_group_members(
5208 p->mem_ctx, &group_sid, &members, &num_members);
5211 if (!NT_STATUS_IS_OK(status)) {
5215 info->all2.name.string = group_name;
5216 info->all2.attributes = attributes;
5217 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5218 info->all2.description.string = group_description;
5223 return NT_STATUS_INVALID_INFO_CLASS;
5226 *r->out.info = info;
5228 return NT_STATUS_OK;
5231 /*********************************************************************
5233 *********************************************************************/
5235 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5236 struct samr_SetGroupInfo *r)
5243 bool can_mod_accounts;
5244 DISP_INFO *disp_info = NULL;
5246 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5247 return NT_STATUS_INVALID_HANDLE;
5249 status = access_check_samr_function(acc_granted,
5250 SAMR_GROUP_ACCESS_SET_INFO,
5251 "_samr_SetGroupInfo");
5252 if (!NT_STATUS_IS_OK(status)) {
5257 ret = get_domain_group_from_sid(group_sid, &map);
5260 return NT_STATUS_NO_SUCH_GROUP;
5262 switch (r->in.level) {
5264 fstrcpy(map.comment, r->in.info->all.description.string);
5267 /* group rename is not supported yet */
5268 return NT_STATUS_NOT_SUPPORTED;
5270 fstrcpy(map.comment, r->in.info->description.string);
5273 return NT_STATUS_INVALID_INFO_CLASS;
5276 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5278 /******** BEGIN SeAddUsers BLOCK *********/
5280 if ( can_mod_accounts )
5283 status = pdb_update_group_mapping_entry(&map);
5285 if ( can_mod_accounts )
5288 /******** End SeAddUsers BLOCK *********/
5290 if (NT_STATUS_IS_OK(status)) {
5291 force_flush_samr_cache(disp_info);
5297 /*********************************************************************
5299 *********************************************************************/
5301 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5302 struct samr_SetAliasInfo *r)
5305 struct acct_info info;
5307 bool can_mod_accounts;
5309 DISP_INFO *disp_info = NULL;
5311 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5312 return NT_STATUS_INVALID_HANDLE;
5314 status = access_check_samr_function(acc_granted,
5315 SAMR_ALIAS_ACCESS_SET_INFO,
5316 "_samr_SetAliasInfo");
5317 if (!NT_STATUS_IS_OK(status)) {
5321 /* get the current group information */
5324 status = pdb_get_aliasinfo( &group_sid, &info );
5327 if ( !NT_STATUS_IS_OK(status))
5330 switch (r->in.level) {
5335 /* We currently do not support renaming groups in the
5336 the BUILTIN domain. Refer to util_builtin.c to understand
5337 why. The eventually needs to be fixed to be like Windows
5338 where you can rename builtin groups, just not delete them */
5340 if ( sid_check_is_in_builtin( &group_sid ) ) {
5341 return NT_STATUS_SPECIAL_ACCOUNT;
5344 /* There has to be a valid name (and it has to be different) */
5346 if ( !r->in.info->name.string )
5347 return NT_STATUS_INVALID_PARAMETER;
5349 /* If the name is the same just reply "ok". Yes this
5350 doesn't allow you to change the case of a group name. */
5352 if ( strequal( r->in.info->name.string, info.acct_name ) )
5353 return NT_STATUS_OK;
5355 fstrcpy( info.acct_name, r->in.info->name.string);
5357 /* make sure the name doesn't already exist as a user
5360 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5361 status = can_create( p->mem_ctx, group_name );
5362 if ( !NT_STATUS_IS_OK( status ) )
5366 case ALIASINFODESCRIPTION:
5367 if (r->in.info->description.string) {
5368 fstrcpy(info.acct_desc,
5369 r->in.info->description.string);
5371 fstrcpy( info.acct_desc, "" );
5375 return NT_STATUS_INVALID_INFO_CLASS;
5378 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5380 /******** BEGIN SeAddUsers BLOCK *********/
5382 if ( can_mod_accounts )
5385 status = pdb_set_aliasinfo( &group_sid, &info );
5387 if ( can_mod_accounts )
5390 /******** End SeAddUsers BLOCK *********/
5392 if (NT_STATUS_IS_OK(status))
5393 force_flush_samr_cache(disp_info);
5398 /****************************************************************
5400 ****************************************************************/
5402 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5403 struct samr_GetDomPwInfo *r)
5405 uint32_t min_password_length = 0;
5406 uint32_t password_properties = 0;
5408 /* Perform access check. Since this rpc does not require a
5409 policy handle it will not be caught by the access checks on
5410 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5412 if (!pipe_access_check(p)) {
5413 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5414 return NT_STATUS_ACCESS_DENIED;
5418 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5419 &min_password_length);
5420 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5421 &password_properties);
5424 if (lp_check_password_script() && *lp_check_password_script()) {
5425 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5428 r->out.info->min_password_length = min_password_length;
5429 r->out.info->password_properties = password_properties;
5431 return NT_STATUS_OK;
5434 /*********************************************************************
5436 *********************************************************************/
5438 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5439 struct samr_OpenGroup *r)
5445 struct samr_info *info;
5446 SEC_DESC *psd = NULL;
5448 uint32 des_access = r->in.access_mask;
5455 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5456 return NT_STATUS_INVALID_HANDLE;
5458 status = access_check_samr_function(acc_granted,
5459 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
5462 if ( !NT_STATUS_IS_OK(status) )
5465 /*check if access can be granted as requested by client. */
5466 map_max_allowed_access(p->server_info->ptok, &des_access);
5468 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5469 se_map_generic(&des_access,&grp_generic_mapping);
5471 se_priv_copy( &se_rights, &se_add_users );
5473 status = access_check_samr_object(psd, p->server_info->ptok,
5474 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5475 &acc_granted, "_samr_OpenGroup");
5477 if ( !NT_STATUS_IS_OK(status) )
5480 /* this should not be hard-coded like this */
5482 if (!sid_equal(&sid, get_global_sam_sid()))
5483 return NT_STATUS_ACCESS_DENIED;
5485 sid_copy(&info_sid, get_global_sam_sid());
5486 sid_append_rid(&info_sid, r->in.rid);
5487 sid_to_fstring(sid_string, &info_sid);
5489 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5490 return NT_STATUS_NO_MEMORY;
5492 info->acc_granted = acc_granted;
5494 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5496 /* check if that group really exists */
5498 ret = get_domain_group_from_sid(info->sid, &map);
5501 return NT_STATUS_NO_SUCH_GROUP;
5503 /* get a (unique) handle. open a policy on it. */
5504 if (!create_policy_hnd(p, r->out.group_handle, info))
5505 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5507 return NT_STATUS_OK;
5510 /*********************************************************************
5511 _samr_RemoveMemberFromForeignDomain
5512 *********************************************************************/
5514 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5515 struct samr_RemoveMemberFromForeignDomain *r)
5517 DOM_SID delete_sid, domain_sid;
5520 DISP_INFO *disp_info = NULL;
5522 sid_copy( &delete_sid, r->in.sid );
5524 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5525 sid_string_dbg(&delete_sid)));
5527 /* Find the policy handle. Open a policy on it. */
5529 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5530 &acc_granted, &disp_info))
5531 return NT_STATUS_INVALID_HANDLE;
5533 result = access_check_samr_function(acc_granted,
5534 STD_RIGHT_DELETE_ACCESS,
5535 "_samr_RemoveMemberFromForeignDomain");
5537 if (!NT_STATUS_IS_OK(result))
5540 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5541 sid_string_dbg(&domain_sid)));
5543 /* we can only delete a user from a group since we don't have
5544 nested groups anyways. So in the latter case, just say OK */
5546 /* TODO: The above comment nowadays is bogus. Since we have nested
5547 * groups now, and aliases members are never reported out of the unix
5548 * group membership, the "just say OK" makes this call a no-op. For
5549 * us. This needs fixing however. */
5551 /* I've only ever seen this in the wild when deleting a user from
5552 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5553 * is the user about to be deleted. I very much suspect this is the
5554 * only application of this call. To verify this, let people report
5557 if (!sid_check_is_builtin(&domain_sid)) {
5558 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5559 "global_sam_sid() = %s\n",
5560 sid_string_dbg(&domain_sid),
5561 sid_string_dbg(get_global_sam_sid())));
5562 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5563 return NT_STATUS_OK;
5566 force_flush_samr_cache(disp_info);
5568 result = NT_STATUS_OK;
5573 /*******************************************************************
5574 _samr_QueryDomainInfo2
5575 ********************************************************************/
5577 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5578 struct samr_QueryDomainInfo2 *r)
5580 struct samr_QueryDomainInfo q;
5582 q.in.domain_handle = r->in.domain_handle;
5583 q.in.level = r->in.level;
5585 q.out.info = r->out.info;
5587 return _samr_QueryDomainInfo(p, &q);
5590 /*******************************************************************
5592 ********************************************************************/
5594 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5595 struct samr_SetDomainInfo *r)
5597 struct samr_info *info = NULL;
5598 time_t u_expire, u_min_age;
5600 time_t u_lock_duration, u_reset_time;
5603 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5605 /* find the policy handle. open a policy on it. */
5606 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5607 return NT_STATUS_INVALID_HANDLE;
5609 /* We do have different access bits for info
5610 * levels here, but we're really just looking for
5611 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5612 * this maps to different specific bits. So
5613 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
5616 result = access_check_samr_function(info->acc_granted,
5617 SAMR_DOMAIN_ACCESS_SET_INFO_1,
5618 "_samr_SetDomainInfo");
5620 if (!NT_STATUS_IS_OK(result))
5623 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5625 switch (r->in.level) {
5627 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5628 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5629 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5630 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5631 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5632 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5633 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5638 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5639 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5648 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5649 if (u_lock_duration != -1)
5650 u_lock_duration /= 60;
5652 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5654 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5655 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5656 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5659 return NT_STATUS_INVALID_INFO_CLASS;
5662 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5664 return NT_STATUS_OK;
5667 /****************************************************************
5668 _samr_GetDisplayEnumerationIndex
5669 ****************************************************************/
5671 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5672 struct samr_GetDisplayEnumerationIndex *r)
5674 struct samr_info *info = NULL;
5675 uint32_t max_entries = (uint32_t) -1;
5676 uint32_t enum_context = 0;
5678 uint32_t num_account = 0;
5679 struct samr_displayentry *entries = NULL;
5682 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5684 /* find the policy handle. open a policy on it. */
5685 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5686 return NT_STATUS_INVALID_HANDLE;
5689 status = access_check_samr_function(info->acc_granted,
5690 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
5691 "_samr_GetDisplayEnumerationIndex");
5692 if (!NT_STATUS_IS_OK(status)) {
5696 if ((r->in.level < 1) || (r->in.level > 3)) {
5697 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5698 "Unknown info level (%u)\n",
5700 return NT_STATUS_INVALID_INFO_CLASS;
5705 /* The following done as ROOT. Don't return without unbecome_root(). */
5707 switch (r->in.level) {
5709 if (info->disp_info->users == NULL) {
5710 info->disp_info->users = pdb_search_users(
5711 info->disp_info, ACB_NORMAL);
5712 if (info->disp_info->users == NULL) {
5714 return NT_STATUS_ACCESS_DENIED;
5716 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5717 "starting user enumeration at index %u\n",
5718 (unsigned int)enum_context));
5720 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5721 "using cached user enumeration at index %u\n",
5722 (unsigned int)enum_context));
5724 num_account = pdb_search_entries(info->disp_info->users,
5725 enum_context, max_entries,
5729 if (info->disp_info->machines == NULL) {
5730 info->disp_info->machines = pdb_search_users(
5731 info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
5732 if (info->disp_info->machines == NULL) {
5734 return NT_STATUS_ACCESS_DENIED;
5736 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5737 "starting machine enumeration at index %u\n",
5738 (unsigned int)enum_context));
5740 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5741 "using cached machine enumeration at index %u\n",
5742 (unsigned int)enum_context));
5744 num_account = pdb_search_entries(info->disp_info->machines,
5745 enum_context, max_entries,
5749 if (info->disp_info->groups == NULL) {
5750 info->disp_info->groups = pdb_search_groups(
5752 if (info->disp_info->groups == NULL) {
5754 return NT_STATUS_ACCESS_DENIED;
5756 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5757 "starting group enumeration at index %u\n",
5758 (unsigned int)enum_context));
5760 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5761 "using cached group enumeration at index %u\n",
5762 (unsigned int)enum_context));
5764 num_account = pdb_search_entries(info->disp_info->groups,
5765 enum_context, max_entries,
5770 smb_panic("info class changed");
5776 /* Ensure we cache this enumeration. */
5777 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5779 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5780 r->in.name->string));
5782 for (i=0; i<num_account; i++) {
5783 if (strequal(entries[i].account_name, r->in.name->string)) {
5784 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5785 "found %s at idx %d\n",
5786 r->in.name->string, i));
5788 return NT_STATUS_OK;
5792 /* assuming account_name lives at the very end */
5793 *r->out.idx = num_account;
5795 return NT_STATUS_NO_MORE_ENTRIES;
5798 /****************************************************************
5799 _samr_GetDisplayEnumerationIndex2
5800 ****************************************************************/
5802 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5803 struct samr_GetDisplayEnumerationIndex2 *r)
5805 struct samr_GetDisplayEnumerationIndex q;
5807 q.in.domain_handle = r->in.domain_handle;
5808 q.in.level = r->in.level;
5809 q.in.name = r->in.name;
5811 q.out.idx = r->out.idx;
5813 return _samr_GetDisplayEnumerationIndex(p, &q);
5816 /****************************************************************
5817 ****************************************************************/
5819 NTSTATUS _samr_Shutdown(pipes_struct *p,
5820 struct samr_Shutdown *r)
5822 p->rng_fault_state = true;
5823 return NT_STATUS_NOT_IMPLEMENTED;
5826 /****************************************************************
5827 ****************************************************************/
5829 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5830 struct samr_SetMemberAttributesOfGroup *r)
5832 p->rng_fault_state = true;
5833 return NT_STATUS_NOT_IMPLEMENTED;
5836 /****************************************************************
5837 ****************************************************************/
5839 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5840 struct samr_ChangePasswordUser *r)
5842 p->rng_fault_state = true;
5843 return NT_STATUS_NOT_IMPLEMENTED;
5846 /****************************************************************
5847 ****************************************************************/
5849 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5850 struct samr_TestPrivateFunctionsDomain *r)
5852 p->rng_fault_state = true;
5853 return NT_STATUS_NOT_IMPLEMENTED;
5856 /****************************************************************
5857 ****************************************************************/
5859 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5860 struct samr_TestPrivateFunctionsUser *r)
5862 p->rng_fault_state = true;
5863 return NT_STATUS_NOT_IMPLEMENTED;
5866 /****************************************************************
5867 ****************************************************************/
5869 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5870 struct samr_AddMultipleMembersToAlias *r)
5872 p->rng_fault_state = true;
5873 return NT_STATUS_NOT_IMPLEMENTED;
5876 /****************************************************************
5877 ****************************************************************/
5879 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5880 struct samr_RemoveMultipleMembersFromAlias *r)
5882 p->rng_fault_state = true;
5883 return NT_STATUS_NOT_IMPLEMENTED;
5886 /****************************************************************
5887 ****************************************************************/
5889 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5890 struct samr_OemChangePasswordUser2 *r)
5892 p->rng_fault_state = true;
5893 return NT_STATUS_NOT_IMPLEMENTED;
5896 /****************************************************************
5897 ****************************************************************/
5899 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5900 struct samr_SetBootKeyInformation *r)
5902 p->rng_fault_state = true;
5903 return NT_STATUS_NOT_IMPLEMENTED;
5906 /****************************************************************
5907 ****************************************************************/
5909 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5910 struct samr_GetBootKeyInformation *r)
5912 p->rng_fault_state = true;
5913 return NT_STATUS_NOT_IMPLEMENTED;
5916 /****************************************************************
5917 ****************************************************************/
5919 NTSTATUS _samr_RidToSid(pipes_struct *p,
5920 struct samr_RidToSid *r)
5922 p->rng_fault_state = true;
5923 return NT_STATUS_NOT_IMPLEMENTED;
5926 /****************************************************************
5927 ****************************************************************/
5929 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5930 struct samr_SetDsrmPassword *r)
5932 p->rng_fault_state = true;
5933 return NT_STATUS_NOT_IMPLEMENTED;
5936 /****************************************************************
5937 ****************************************************************/
5939 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5940 struct samr_ValidatePassword *r)
5942 p->rng_fault_state = true;
5943 return NT_STATUS_NOT_IMPLEMENTED;