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.
35 #include "../libcli/auth/libcli_auth.h"
38 #define DBGC_CLASS DBGC_RPC_SRV
40 #define SAMR_USR_RIGHTS_WRITE_PW \
41 ( READ_CONTROL_ACCESS | \
42 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
43 SAMR_USER_ACCESS_SET_LOC_COM)
44 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
45 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
47 #define DISP_INFO_CACHE_TIMEOUT 10
49 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
50 #define MAX_SAM_ENTRIES_W95 50
52 struct samr_connect_info {
56 struct samr_domain_info {
58 struct disp_info *disp_info;
61 struct samr_user_info {
65 struct samr_group_info {
69 struct samr_alias_info {
73 typedef struct disp_info {
74 DOM_SID sid; /* identify which domain this is. */
75 struct pdb_search *users; /* querydispinfo 1 and 4 */
76 struct pdb_search *machines; /* querydispinfo 2 */
77 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
78 struct pdb_search *aliases; /* enumaliases */
81 struct pdb_search *enum_users; /* enumusers with a mask */
83 struct timed_event *cache_timeout_event; /* cache idle timeout
87 static const struct generic_mapping sam_generic_mapping = {
88 GENERIC_RIGHTS_SAM_READ,
89 GENERIC_RIGHTS_SAM_WRITE,
90 GENERIC_RIGHTS_SAM_EXECUTE,
91 GENERIC_RIGHTS_SAM_ALL_ACCESS};
92 static const struct generic_mapping dom_generic_mapping = {
93 GENERIC_RIGHTS_DOMAIN_READ,
94 GENERIC_RIGHTS_DOMAIN_WRITE,
95 GENERIC_RIGHTS_DOMAIN_EXECUTE,
96 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
97 static const struct generic_mapping usr_generic_mapping = {
98 GENERIC_RIGHTS_USER_READ,
99 GENERIC_RIGHTS_USER_WRITE,
100 GENERIC_RIGHTS_USER_EXECUTE,
101 GENERIC_RIGHTS_USER_ALL_ACCESS};
102 static const struct generic_mapping usr_nopwchange_generic_mapping = {
103 GENERIC_RIGHTS_USER_READ,
104 GENERIC_RIGHTS_USER_WRITE,
105 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
106 GENERIC_RIGHTS_USER_ALL_ACCESS};
107 static const struct generic_mapping grp_generic_mapping = {
108 GENERIC_RIGHTS_GROUP_READ,
109 GENERIC_RIGHTS_GROUP_WRITE,
110 GENERIC_RIGHTS_GROUP_EXECUTE,
111 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
112 static const struct generic_mapping ali_generic_mapping = {
113 GENERIC_RIGHTS_ALIAS_READ,
114 GENERIC_RIGHTS_ALIAS_WRITE,
115 GENERIC_RIGHTS_ALIAS_EXECUTE,
116 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
118 /*******************************************************************
119 *******************************************************************/
121 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
122 const struct generic_mapping *map,
123 DOM_SID *sid, uint32 sid_access )
125 DOM_SID domadmin_sid;
126 SEC_ACE ace[5]; /* at most 5 entries */
131 /* basic access for Everyone */
133 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
134 map->generic_execute | map->generic_read, 0);
136 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
138 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
139 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
140 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
141 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
143 /* Add Full Access for Domain Admins if we are a DC */
146 sid_copy( &domadmin_sid, get_global_sam_sid() );
147 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
148 init_sec_ace(&ace[i++], &domadmin_sid,
149 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
152 /* if we have a sid, give it some special access */
155 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
158 /* create the security descriptor */
160 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
161 return NT_STATUS_NO_MEMORY;
163 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
164 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
165 psa, sd_size)) == NULL)
166 return NT_STATUS_NO_MEMORY;
171 /*******************************************************************
172 Checks if access to an object should be granted, and returns that
173 level of access for further checks.
174 ********************************************************************/
176 NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token,
177 SE_PRIV *rights, uint32 rights_mask,
178 uint32 des_access, uint32 *acc_granted,
181 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
182 uint32 saved_mask = 0;
184 /* check privileges; certain SAM access bits should be overridden
185 by privileges (mostly having to do with creating/modifying/deleting
188 if (rights && !se_priv_equal(rights, &se_priv_none) &&
189 user_has_any_privilege(token, rights)) {
191 saved_mask = (des_access & rights_mask);
192 des_access &= ~saved_mask;
194 DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
199 /* check the security descriptor first */
201 status = se_access_check(psd, token, des_access, acc_granted);
202 if (NT_STATUS_IS_OK(status)) {
206 /* give root a free pass */
208 if ( geteuid() == sec_initial_uid() ) {
210 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
211 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
213 *acc_granted = des_access;
215 status = NT_STATUS_OK;
221 /* add in any bits saved during the privilege check (only
222 matters is status is ok) */
224 *acc_granted |= rights_mask;
226 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
227 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
228 des_access, *acc_granted));
234 /*******************************************************************
235 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
236 ********************************************************************/
238 void map_max_allowed_access(const NT_USER_TOKEN *token,
239 uint32_t *pacc_requested)
241 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
244 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
246 /* At least try for generic read|execute - Everyone gets that. */
247 *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
249 /* root gets anything. */
250 if (geteuid() == sec_initial_uid()) {
251 *pacc_requested |= GENERIC_ALL_ACCESS;
255 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
257 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
258 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
259 *pacc_requested |= GENERIC_ALL_ACCESS;
263 /* Full access for DOMAIN\Domain Admins. */
265 DOM_SID domadmin_sid;
266 sid_copy( &domadmin_sid, get_global_sam_sid() );
267 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
268 if (is_sid_in_token(token, &domadmin_sid)) {
269 *pacc_requested |= GENERIC_ALL_ACCESS;
273 /* TODO ! Check privileges. */
276 /*******************************************************************
277 Fetch or create a dispinfo struct.
278 ********************************************************************/
280 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
283 * We do a static cache for DISP_INFO's here. Explanation can be found
284 * in Jeremy's checkin message to r11793:
286 * Fix the SAMR cache so it works across completely insane
287 * client behaviour (ie.:
288 * open pipe/open SAMR handle/enumerate 0 - 1024
289 * close SAMR handle, close pipe.
290 * open pipe/open SAMR handle/enumerate 1024 - 2048...
291 * close SAMR handle, close pipe.
292 * And on ad-nausium. Amazing.... probably object-oriented
293 * client side programming in action yet again.
294 * This change should *massively* improve performance when
295 * enumerating users from an LDAP database.
298 * "Our" and the builtin domain are the only ones where we ever
299 * enumerate stuff, so just cache 2 entries.
302 static struct disp_info *builtin_dispinfo;
303 static struct disp_info *domain_dispinfo;
305 /* There are two cases to consider here:
306 1) The SID is a domain SID and we look for an equality match, or
307 2) This is an account SID and so we return the DISP_INFO* for our
314 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
316 * Necessary only once, but it does not really hurt.
318 if (builtin_dispinfo == NULL) {
319 builtin_dispinfo = talloc_zero(
320 talloc_autofree_context(), struct disp_info);
321 if (builtin_dispinfo == NULL) {
325 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
327 return builtin_dispinfo;
330 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
332 * Necessary only once, but it does not really hurt.
334 if (domain_dispinfo == NULL) {
335 domain_dispinfo = talloc_zero(
336 talloc_autofree_context(), struct disp_info);
337 if (domain_dispinfo == NULL) {
341 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
343 return domain_dispinfo;
349 /*******************************************************************
350 Function to free the per SID data.
351 ********************************************************************/
353 static void free_samr_cache(DISP_INFO *disp_info)
355 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
356 sid_string_dbg(&disp_info->sid)));
358 /* We need to become root here because the paged search might have to
359 * tell the LDAP server we're not interested in the rest anymore. */
363 TALLOC_FREE(disp_info->users);
364 TALLOC_FREE(disp_info->machines);
365 TALLOC_FREE(disp_info->groups);
366 TALLOC_FREE(disp_info->aliases);
367 TALLOC_FREE(disp_info->enum_users);
372 /*******************************************************************
373 Idle event handler. Throw away the disp info cache.
374 ********************************************************************/
376 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
377 struct timed_event *te,
381 DISP_INFO *disp_info = (DISP_INFO *)private_data;
383 TALLOC_FREE(disp_info->cache_timeout_event);
385 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
387 free_samr_cache(disp_info);
390 /*******************************************************************
391 Setup cache removal idle event handler.
392 ********************************************************************/
394 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
396 /* Remove any pending timeout and update. */
398 TALLOC_FREE(disp_info->cache_timeout_event);
400 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
401 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
402 (unsigned int)secs_fromnow ));
404 disp_info->cache_timeout_event = event_add_timed(
405 smbd_event_context(), NULL,
406 timeval_current_ofs(secs_fromnow, 0),
407 disp_info_cache_idle_timeout_handler, (void *)disp_info);
410 /*******************************************************************
411 Force flush any cache. We do this on any samr_set_xxx call.
412 We must also remove the timeout handler.
413 ********************************************************************/
415 static void force_flush_samr_cache(const struct dom_sid *sid)
417 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
419 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
423 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
424 TALLOC_FREE(disp_info->cache_timeout_event);
425 free_samr_cache(disp_info);
428 /*******************************************************************
429 Ensure password info is never given out. Paranioa... JRA.
430 ********************************************************************/
432 static void samr_clear_sam_passwd(struct samu *sam_pass)
438 /* These now zero out the old password */
440 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
441 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
444 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
446 struct samr_displayentry *entry;
448 if (sid_check_is_builtin(&info->sid)) {
449 /* No users in builtin. */
453 if (info->users == NULL) {
454 info->users = pdb_search_users(info, acct_flags);
455 if (info->users == NULL) {
459 /* Fetch the last possible entry, thus trigger an enumeration */
460 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
462 /* Ensure we cache this enumeration. */
463 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
465 return info->users->num_entries;
468 static uint32 count_sam_groups(struct disp_info *info)
470 struct samr_displayentry *entry;
472 if (sid_check_is_builtin(&info->sid)) {
473 /* No groups in builtin. */
477 if (info->groups == NULL) {
478 info->groups = pdb_search_groups(info);
479 if (info->groups == NULL) {
483 /* Fetch the last possible entry, thus trigger an enumeration */
484 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
486 /* Ensure we cache this enumeration. */
487 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
489 return info->groups->num_entries;
492 static uint32 count_sam_aliases(struct disp_info *info)
494 struct samr_displayentry *entry;
496 if (info->aliases == NULL) {
497 info->aliases = pdb_search_aliases(info, &info->sid);
498 if (info->aliases == NULL) {
502 /* Fetch the last possible entry, thus trigger an enumeration */
503 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
505 /* Ensure we cache this enumeration. */
506 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
508 return info->aliases->num_entries;
511 /*******************************************************************
513 ********************************************************************/
515 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
517 if (!close_policy_hnd(p, r->in.handle)) {
518 return NT_STATUS_INVALID_HANDLE;
521 ZERO_STRUCTP(r->out.handle);
526 /*******************************************************************
528 ********************************************************************/
530 NTSTATUS _samr_OpenDomain(pipes_struct *p,
531 struct samr_OpenDomain *r)
533 struct samr_connect_info *cinfo;
534 struct samr_domain_info *dinfo;
535 SEC_DESC *psd = NULL;
537 uint32 des_access = r->in.access_mask;
540 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
543 /* find the connection policy handle. */
545 cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
546 struct samr_connect_info, &status);
547 if (!NT_STATUS_IS_OK(status)) {
551 /*check if access can be granted as requested by client. */
552 map_max_allowed_access(p->server_info->ptok, &des_access);
554 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
555 se_map_generic( &des_access, &dom_generic_mapping );
558 * Users with SeMachineAccount or SeAddUser get additional
559 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
561 se_priv_copy( &se_rights, &se_machine_account );
562 se_priv_add( &se_rights, &se_add_users );
565 * Users with SeAddUser get the ability to manipulate groups
568 if (user_has_any_privilege(p->server_info->ptok, &se_add_users)) {
569 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
570 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
571 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
572 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
573 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
576 status = access_check_object( psd, p->server_info->ptok,
577 &se_rights, extra_access, des_access,
578 &acc_granted, "_samr_OpenDomain" );
580 if ( !NT_STATUS_IS_OK(status) )
583 if (!sid_check_is_domain(r->in.sid) &&
584 !sid_check_is_builtin(r->in.sid)) {
585 return NT_STATUS_NO_SUCH_DOMAIN;
588 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
589 struct samr_domain_info, &status);
590 if (!NT_STATUS_IS_OK(status)) {
593 dinfo->sid = *r->in.sid;
594 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
596 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
601 /*******************************************************************
603 ********************************************************************/
605 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
606 struct samr_GetUserPwInfo *r)
608 struct samr_user_info *uinfo;
609 enum lsa_SidType sid_type;
610 uint32_t min_password_length = 0;
611 uint32_t password_properties = 0;
615 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
617 uinfo = policy_handle_find(p, r->in.user_handle,
618 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
619 struct samr_user_info, &status);
620 if (!NT_STATUS_IS_OK(status)) {
624 if (!sid_check_is_in_our_domain(&uinfo->sid)) {
625 return NT_STATUS_OBJECT_TYPE_MISMATCH;
629 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
632 return NT_STATUS_NO_SUCH_USER;
638 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
639 &min_password_length);
640 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
641 &password_properties);
644 if (lp_check_password_script() && *lp_check_password_script()) {
645 password_properties |= DOMAIN_PASSWORD_COMPLEX;
653 r->out.info->min_password_length = min_password_length;
654 r->out.info->password_properties = password_properties;
656 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
661 /*******************************************************************
663 ********************************************************************/
665 NTSTATUS _samr_SetSecurity(pipes_struct *p,
666 struct samr_SetSecurity *r)
668 struct samr_user_info *uinfo;
672 struct samu *sampass=NULL;
675 uinfo = policy_handle_find(p, r->in.handle,
676 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
677 struct samr_user_info, &status);
678 if (!NT_STATUS_IS_OK(status)) {
682 if (!(sampass = samu_new( p->mem_ctx))) {
683 DEBUG(0,("No memory!\n"));
684 return NT_STATUS_NO_MEMORY;
687 /* get the user record */
689 ret = pdb_getsampwsid(sampass, &uinfo->sid);
693 DEBUG(4, ("User %s not found\n",
694 sid_string_dbg(&uinfo->sid)));
695 TALLOC_FREE(sampass);
696 return NT_STATUS_INVALID_HANDLE;
699 dacl = r->in.sdbuf->sd->dacl;
700 for (i=0; i < dacl->num_aces; i++) {
701 if (sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
702 ret = pdb_set_pass_can_change(sampass,
703 (dacl->aces[i].access_mask &
704 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
711 TALLOC_FREE(sampass);
712 return NT_STATUS_ACCESS_DENIED;
716 status = pdb_update_sam_account(sampass);
719 TALLOC_FREE(sampass);
724 /*******************************************************************
725 build correct perms based on policies and password times for _samr_query_sec_obj
726 *******************************************************************/
727 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
729 struct samu *sampass=NULL;
732 if ( !(sampass = samu_new( mem_ctx )) ) {
733 DEBUG(0,("No memory!\n"));
738 ret = pdb_getsampwsid(sampass, user_sid);
742 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
743 TALLOC_FREE(sampass);
747 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
749 if (pdb_get_pass_can_change(sampass)) {
750 TALLOC_FREE(sampass);
753 TALLOC_FREE(sampass);
758 /*******************************************************************
760 ********************************************************************/
762 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
763 struct samr_QuerySecurity *r)
765 struct samr_connect_info *cinfo;
766 struct samr_domain_info *dinfo;
767 struct samr_user_info *uinfo;
768 struct samr_group_info *ginfo;
769 struct samr_alias_info *ainfo;
771 SEC_DESC * psd = NULL;
774 cinfo = policy_handle_find(p, r->in.handle,
775 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
776 struct samr_connect_info, &status);
777 if (NT_STATUS_IS_OK(status)) {
778 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
779 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
780 &sam_generic_mapping, NULL, 0);
784 dinfo = policy_handle_find(p, r->in.handle,
785 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
786 struct samr_domain_info, &status);
787 if (NT_STATUS_IS_OK(status)) {
788 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
789 "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
791 * TODO: Builtin probably needs a different SD with restricted
794 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
795 &dom_generic_mapping, NULL, 0);
799 uinfo = policy_handle_find(p, r->in.handle,
800 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
801 struct samr_user_info, &status);
802 if (NT_STATUS_IS_OK(status)) {
803 DEBUG(10,("_samr_QuerySecurity: querying security on user "
804 "Object with SID: %s\n",
805 sid_string_dbg(&uinfo->sid)));
806 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
807 status = make_samr_object_sd(
808 p->mem_ctx, &psd, &sd_size,
809 &usr_generic_mapping,
810 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
812 status = make_samr_object_sd(
813 p->mem_ctx, &psd, &sd_size,
814 &usr_nopwchange_generic_mapping,
815 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
820 ginfo = policy_handle_find(p, r->in.handle,
821 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
822 struct samr_group_info, &status);
823 if (NT_STATUS_IS_OK(status)) {
825 * TODO: different SDs have to be generated for aliases groups
826 * and users. Currently all three get a default user SD
828 DEBUG(10,("_samr_QuerySecurity: querying security on group "
829 "Object with SID: %s\n",
830 sid_string_dbg(&ginfo->sid)));
831 status = make_samr_object_sd(
832 p->mem_ctx, &psd, &sd_size,
833 &usr_nopwchange_generic_mapping,
834 &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
838 ainfo = policy_handle_find(p, r->in.handle,
839 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
840 struct samr_alias_info, &status);
841 if (NT_STATUS_IS_OK(status)) {
843 * TODO: different SDs have to be generated for aliases groups
844 * and users. Currently all three get a default user SD
846 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
847 "Object with SID: %s\n",
848 sid_string_dbg(&ainfo->sid)));
849 status = make_samr_object_sd(
850 p->mem_ctx, &psd, &sd_size,
851 &usr_nopwchange_generic_mapping,
852 &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
856 return NT_STATUS_OBJECT_TYPE_MISMATCH;
858 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
859 return NT_STATUS_NO_MEMORY;
864 /*******************************************************************
865 makes a SAM_ENTRY / UNISTR2* structure from a user list.
866 ********************************************************************/
868 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
869 struct samr_SamEntry **sam_pp,
870 uint32_t num_entries,
872 struct samr_displayentry *entries)
875 struct samr_SamEntry *sam;
879 if (num_entries == 0) {
883 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
885 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
886 return NT_STATUS_NO_MEMORY;
889 for (i = 0; i < num_entries; i++) {
892 * usrmgr expects a non-NULL terminated string with
893 * trust relationships
895 if (entries[i].acct_flags & ACB_DOMTRUST) {
896 init_unistr2(&uni_temp_name, entries[i].account_name,
899 init_unistr2(&uni_temp_name, entries[i].account_name,
903 init_lsa_String(&sam[i].name, entries[i].account_name);
904 sam[i].idx = entries[i].rid;
912 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
914 /*******************************************************************
915 _samr_EnumDomainUsers
916 ********************************************************************/
918 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
919 struct samr_EnumDomainUsers *r)
922 struct samr_domain_info *dinfo;
924 uint32 enum_context = *r->in.resume_handle;
925 enum remote_arch_types ra_type = get_remote_arch();
926 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
927 uint32 max_entries = max_sam_entries;
928 struct samr_displayentry *entries = NULL;
929 struct samr_SamArray *samr_array = NULL;
930 struct samr_SamEntry *samr_entries = NULL;
932 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
934 dinfo = policy_handle_find(p, r->in.domain_handle,
935 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
936 struct samr_domain_info, &status);
937 if (!NT_STATUS_IS_OK(status)) {
941 if (sid_check_is_builtin(&dinfo->sid)) {
942 /* No users in builtin. */
943 *r->out.resume_handle = *r->in.resume_handle;
944 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
948 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
950 return NT_STATUS_NO_MEMORY;
952 *r->out.sam = samr_array;
958 if ((dinfo->disp_info->enum_users != NULL) &&
959 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
960 TALLOC_FREE(dinfo->disp_info->enum_users);
963 if (dinfo->disp_info->enum_users == NULL) {
964 dinfo->disp_info->enum_users = pdb_search_users(
965 dinfo->disp_info, r->in.acct_flags);
966 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
969 if (dinfo->disp_info->enum_users == NULL) {
970 /* END AS ROOT !!!! */
972 return NT_STATUS_ACCESS_DENIED;
975 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
976 enum_context, max_entries,
979 /* END AS ROOT !!!! */
983 if (num_account == 0) {
984 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
986 *r->out.resume_handle = *r->in.resume_handle;
990 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
991 num_account, enum_context,
993 if (!NT_STATUS_IS_OK(status)) {
997 if (max_entries <= num_account) {
998 status = STATUS_MORE_ENTRIES;
1000 status = NT_STATUS_OK;
1003 /* Ensure we cache this enumeration. */
1004 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1006 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1008 samr_array->count = num_account;
1009 samr_array->entries = samr_entries;
1011 *r->out.resume_handle = *r->in.resume_handle + num_account;
1012 *r->out.num_entries = num_account;
1014 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1019 /*******************************************************************
1020 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1021 ********************************************************************/
1023 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1024 struct samr_SamEntry **sam_pp,
1025 uint32_t num_sam_entries,
1026 struct samr_displayentry *entries)
1028 struct samr_SamEntry *sam;
1033 if (num_sam_entries == 0) {
1037 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1042 for (i = 0; i < num_sam_entries; i++) {
1044 * JRA. I think this should include the null. TNG does not.
1046 init_lsa_String(&sam[i].name, entries[i].account_name);
1047 sam[i].idx = entries[i].rid;
1053 /*******************************************************************
1054 _samr_EnumDomainGroups
1055 ********************************************************************/
1057 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1058 struct samr_EnumDomainGroups *r)
1061 struct samr_domain_info *dinfo;
1062 struct samr_displayentry *groups;
1064 struct samr_SamArray *samr_array = NULL;
1065 struct samr_SamEntry *samr_entries = NULL;
1067 dinfo = policy_handle_find(p, r->in.domain_handle,
1068 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1069 struct samr_domain_info, &status);
1070 if (!NT_STATUS_IS_OK(status)) {
1074 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1076 if (sid_check_is_builtin(&dinfo->sid)) {
1077 /* No groups in builtin. */
1078 *r->out.resume_handle = *r->in.resume_handle;
1079 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1083 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1085 return NT_STATUS_NO_MEMORY;
1088 /* the domain group array is being allocated in the function below */
1092 if (dinfo->disp_info->groups == NULL) {
1093 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1095 if (dinfo->disp_info->groups == NULL) {
1097 return NT_STATUS_ACCESS_DENIED;
1101 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1102 *r->in.resume_handle,
1103 MAX_SAM_ENTRIES, &groups);
1106 /* Ensure we cache this enumeration. */
1107 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1109 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1110 num_groups, groups);
1112 if (MAX_SAM_ENTRIES <= num_groups) {
1113 status = STATUS_MORE_ENTRIES;
1115 status = NT_STATUS_OK;
1118 samr_array->count = num_groups;
1119 samr_array->entries = samr_entries;
1121 *r->out.sam = samr_array;
1122 *r->out.num_entries = num_groups;
1123 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1125 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1130 /*******************************************************************
1131 _samr_EnumDomainAliases
1132 ********************************************************************/
1134 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1135 struct samr_EnumDomainAliases *r)
1138 struct samr_domain_info *dinfo;
1139 struct samr_displayentry *aliases;
1140 uint32 num_aliases = 0;
1141 struct samr_SamArray *samr_array = NULL;
1142 struct samr_SamEntry *samr_entries = NULL;
1144 dinfo = policy_handle_find(p, r->in.domain_handle,
1145 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1146 struct samr_domain_info, &status);
1147 if (!NT_STATUS_IS_OK(status)) {
1151 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1152 sid_string_dbg(&dinfo->sid)));
1154 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1156 return NT_STATUS_NO_MEMORY;
1161 if (dinfo->disp_info->aliases == NULL) {
1162 dinfo->disp_info->aliases = pdb_search_aliases(
1163 dinfo->disp_info, &dinfo->sid);
1164 if (dinfo->disp_info->aliases == NULL) {
1166 return NT_STATUS_ACCESS_DENIED;
1170 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1171 *r->in.resume_handle,
1172 MAX_SAM_ENTRIES, &aliases);
1175 /* Ensure we cache this enumeration. */
1176 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1178 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1179 num_aliases, aliases);
1181 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1183 if (MAX_SAM_ENTRIES <= num_aliases) {
1184 status = STATUS_MORE_ENTRIES;
1186 status = NT_STATUS_OK;
1189 samr_array->count = num_aliases;
1190 samr_array->entries = samr_entries;
1192 *r->out.sam = samr_array;
1193 *r->out.num_entries = num_aliases;
1194 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1199 /*******************************************************************
1200 inits a samr_DispInfoGeneral structure.
1201 ********************************************************************/
1203 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1204 struct samr_DispInfoGeneral *r,
1205 uint32_t num_entries,
1207 struct samr_displayentry *entries)
1211 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1213 if (num_entries == 0) {
1214 return NT_STATUS_OK;
1217 r->count = num_entries;
1219 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1221 return NT_STATUS_NO_MEMORY;
1224 for (i = 0; i < num_entries ; i++) {
1226 init_lsa_String(&r->entries[i].account_name,
1227 entries[i].account_name);
1229 init_lsa_String(&r->entries[i].description,
1230 entries[i].description);
1232 init_lsa_String(&r->entries[i].full_name,
1233 entries[i].fullname);
1235 r->entries[i].rid = entries[i].rid;
1236 r->entries[i].acct_flags = entries[i].acct_flags;
1237 r->entries[i].idx = start_idx+i+1;
1240 return NT_STATUS_OK;
1243 /*******************************************************************
1244 inits a samr_DispInfoFull structure.
1245 ********************************************************************/
1247 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1248 struct samr_DispInfoFull *r,
1249 uint32_t num_entries,
1251 struct samr_displayentry *entries)
1255 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1257 if (num_entries == 0) {
1258 return NT_STATUS_OK;
1261 r->count = num_entries;
1263 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1265 return NT_STATUS_NO_MEMORY;
1268 for (i = 0; i < num_entries ; i++) {
1270 init_lsa_String(&r->entries[i].account_name,
1271 entries[i].account_name);
1273 init_lsa_String(&r->entries[i].description,
1274 entries[i].description);
1276 r->entries[i].rid = entries[i].rid;
1277 r->entries[i].acct_flags = entries[i].acct_flags;
1278 r->entries[i].idx = start_idx+i+1;
1281 return NT_STATUS_OK;
1284 /*******************************************************************
1285 inits a samr_DispInfoFullGroups structure.
1286 ********************************************************************/
1288 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1289 struct samr_DispInfoFullGroups *r,
1290 uint32_t num_entries,
1292 struct samr_displayentry *entries)
1296 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1298 if (num_entries == 0) {
1299 return NT_STATUS_OK;
1302 r->count = num_entries;
1304 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1306 return NT_STATUS_NO_MEMORY;
1309 for (i = 0; i < num_entries ; i++) {
1311 init_lsa_String(&r->entries[i].account_name,
1312 entries[i].account_name);
1314 init_lsa_String(&r->entries[i].description,
1315 entries[i].description);
1317 r->entries[i].rid = entries[i].rid;
1318 r->entries[i].acct_flags = entries[i].acct_flags;
1319 r->entries[i].idx = start_idx+i+1;
1322 return NT_STATUS_OK;
1325 /*******************************************************************
1326 inits a samr_DispInfoAscii structure.
1327 ********************************************************************/
1329 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1330 struct samr_DispInfoAscii *r,
1331 uint32_t num_entries,
1333 struct samr_displayentry *entries)
1337 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1339 if (num_entries == 0) {
1340 return NT_STATUS_OK;
1343 r->count = num_entries;
1345 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1347 return NT_STATUS_NO_MEMORY;
1350 for (i = 0; i < num_entries ; i++) {
1352 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1353 entries[i].account_name);
1355 r->entries[i].idx = start_idx+i+1;
1358 return NT_STATUS_OK;
1361 /*******************************************************************
1362 inits a samr_DispInfoAscii structure.
1363 ********************************************************************/
1365 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1366 struct samr_DispInfoAscii *r,
1367 uint32_t num_entries,
1369 struct samr_displayentry *entries)
1373 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1375 if (num_entries == 0) {
1376 return NT_STATUS_OK;
1379 r->count = num_entries;
1381 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1383 return NT_STATUS_NO_MEMORY;
1386 for (i = 0; i < num_entries ; i++) {
1388 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1389 entries[i].account_name);
1391 r->entries[i].idx = start_idx+i+1;
1394 return NT_STATUS_OK;
1397 /*******************************************************************
1398 _samr_QueryDisplayInfo
1399 ********************************************************************/
1401 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1402 struct samr_QueryDisplayInfo *r)
1405 struct samr_domain_info *dinfo;
1406 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1408 uint32 max_entries = r->in.max_entries;
1409 uint32 enum_context = r->in.start_idx;
1410 uint32 max_size = r->in.buf_size;
1412 union samr_DispInfo *disp_info = r->out.info;
1414 uint32 temp_size=0, total_data_size=0;
1415 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1416 uint32 num_account = 0;
1417 enum remote_arch_types ra_type = get_remote_arch();
1418 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1419 struct samr_displayentry *entries = NULL;
1421 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1423 dinfo = policy_handle_find(p, r->in.domain_handle,
1424 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1425 struct samr_domain_info, &status);
1426 if (!NT_STATUS_IS_OK(status)) {
1430 if (sid_check_is_builtin(&dinfo->sid)) {
1431 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1432 return NT_STATUS_OK;
1436 * calculate how many entries we will return.
1438 * - the number of entries the client asked
1439 * - our limit on that
1440 * - the starting point (enumeration context)
1441 * - the buffer size the client will accept
1445 * We are a lot more like W2K. Instead of reading the SAM
1446 * each time to find the records we need to send back,
1447 * we read it once and link that copy to the sam handle.
1448 * For large user list (over the MAX_SAM_ENTRIES)
1449 * it's a definitive win.
1450 * second point to notice: between enumerations
1451 * our sam is now the same as it's a snapshoot.
1452 * third point: got rid of the static SAM_USER_21 struct
1453 * no more intermediate.
1454 * con: it uses much more memory, as a full copy is stored
1457 * If you want to change it, think twice and think
1458 * of the second point , that's really important.
1463 if ((r->in.level < 1) || (r->in.level > 5)) {
1464 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1465 (unsigned int)r->in.level ));
1466 return NT_STATUS_INVALID_INFO_CLASS;
1469 /* first limit the number of entries we will return */
1470 if(max_entries > max_sam_entries) {
1471 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1472 "entries, limiting to %d\n", max_entries,
1474 max_entries = max_sam_entries;
1477 /* calculate the size and limit on the number of entries we will
1480 temp_size=max_entries*struct_size;
1482 if (temp_size>max_size) {
1483 max_entries=MIN((max_size/struct_size),max_entries);;
1484 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1485 "only %d entries\n", max_entries));
1490 /* THe following done as ROOT. Don't return without unbecome_root(). */
1492 switch (r->in.level) {
1495 if (dinfo->disp_info->users == NULL) {
1496 dinfo->disp_info->users = pdb_search_users(
1497 dinfo->disp_info, ACB_NORMAL);
1498 if (dinfo->disp_info->users == NULL) {
1500 return NT_STATUS_ACCESS_DENIED;
1502 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1503 (unsigned int)enum_context ));
1505 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1506 (unsigned int)enum_context ));
1509 num_account = pdb_search_entries(dinfo->disp_info->users,
1510 enum_context, max_entries,
1514 if (dinfo->disp_info->machines == NULL) {
1515 dinfo->disp_info->machines = pdb_search_users(
1516 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1517 if (dinfo->disp_info->machines == NULL) {
1519 return NT_STATUS_ACCESS_DENIED;
1521 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1522 (unsigned int)enum_context ));
1524 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1525 (unsigned int)enum_context ));
1528 num_account = pdb_search_entries(dinfo->disp_info->machines,
1529 enum_context, max_entries,
1534 if (dinfo->disp_info->groups == NULL) {
1535 dinfo->disp_info->groups = pdb_search_groups(
1537 if (dinfo->disp_info->groups == NULL) {
1539 return NT_STATUS_ACCESS_DENIED;
1541 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1542 (unsigned int)enum_context ));
1544 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1545 (unsigned int)enum_context ));
1548 num_account = pdb_search_entries(dinfo->disp_info->groups,
1549 enum_context, max_entries,
1554 smb_panic("info class changed");
1560 /* Now create reply structure */
1561 switch (r->in.level) {
1563 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1564 num_account, enum_context,
1568 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1569 num_account, enum_context,
1573 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1574 num_account, enum_context,
1578 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1579 num_account, enum_context,
1583 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1584 num_account, enum_context,
1588 smb_panic("info class changed");
1592 if (!NT_STATUS_IS_OK(disp_ret))
1595 /* calculate the total size */
1596 total_data_size=num_account*struct_size;
1598 if (max_entries <= num_account) {
1599 status = STATUS_MORE_ENTRIES;
1601 status = NT_STATUS_OK;
1604 /* Ensure we cache this enumeration. */
1605 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1607 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1609 *r->out.total_size = total_data_size;
1610 *r->out.returned_size = temp_size;
1615 /****************************************************************
1616 _samr_QueryDisplayInfo2
1617 ****************************************************************/
1619 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1620 struct samr_QueryDisplayInfo2 *r)
1622 struct samr_QueryDisplayInfo q;
1624 q.in.domain_handle = r->in.domain_handle;
1625 q.in.level = r->in.level;
1626 q.in.start_idx = r->in.start_idx;
1627 q.in.max_entries = r->in.max_entries;
1628 q.in.buf_size = r->in.buf_size;
1630 q.out.total_size = r->out.total_size;
1631 q.out.returned_size = r->out.returned_size;
1632 q.out.info = r->out.info;
1634 return _samr_QueryDisplayInfo(p, &q);
1637 /****************************************************************
1638 _samr_QueryDisplayInfo3
1639 ****************************************************************/
1641 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1642 struct samr_QueryDisplayInfo3 *r)
1644 struct samr_QueryDisplayInfo q;
1646 q.in.domain_handle = r->in.domain_handle;
1647 q.in.level = r->in.level;
1648 q.in.start_idx = r->in.start_idx;
1649 q.in.max_entries = r->in.max_entries;
1650 q.in.buf_size = r->in.buf_size;
1652 q.out.total_size = r->out.total_size;
1653 q.out.returned_size = r->out.returned_size;
1654 q.out.info = r->out.info;
1656 return _samr_QueryDisplayInfo(p, &q);
1659 /*******************************************************************
1660 _samr_QueryAliasInfo
1661 ********************************************************************/
1663 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1664 struct samr_QueryAliasInfo *r)
1666 struct samr_alias_info *ainfo;
1667 struct acct_info info;
1669 union samr_AliasInfo *alias_info = NULL;
1670 const char *alias_name = NULL;
1671 const char *alias_description = NULL;
1673 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1675 ainfo = policy_handle_find(p, r->in.alias_handle,
1676 SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1677 struct samr_alias_info, &status);
1678 if (!NT_STATUS_IS_OK(status)) {
1682 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1684 return NT_STATUS_NO_MEMORY;
1688 status = pdb_get_aliasinfo(&ainfo->sid, &info);
1691 if ( !NT_STATUS_IS_OK(status))
1694 /* FIXME: info contains fstrings */
1695 alias_name = talloc_strdup(r, info.acct_name);
1696 alias_description = talloc_strdup(r, info.acct_desc);
1698 switch (r->in.level) {
1700 alias_info->all.name.string = alias_name;
1701 alias_info->all.num_members = 1; /* ??? */
1702 alias_info->all.description.string = alias_description;
1705 alias_info->name.string = alias_name;
1707 case ALIASINFODESCRIPTION:
1708 alias_info->description.string = alias_description;
1711 return NT_STATUS_INVALID_INFO_CLASS;
1714 *r->out.info = alias_info;
1716 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1718 return NT_STATUS_OK;
1721 /*******************************************************************
1723 ********************************************************************/
1725 NTSTATUS _samr_LookupNames(pipes_struct *p,
1726 struct samr_LookupNames *r)
1728 struct samr_domain_info *dinfo;
1731 enum lsa_SidType *type;
1733 int num_rids = r->in.num_names;
1734 struct samr_Ids rids, types;
1735 uint32_t num_mapped = 0;
1737 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1739 dinfo = policy_handle_find(p, r->in.domain_handle,
1740 0 /* Don't know the acc_bits yet */, NULL,
1741 struct samr_domain_info, &status);
1742 if (!NT_STATUS_IS_OK(status)) {
1746 if (num_rids > MAX_SAM_ENTRIES) {
1747 num_rids = MAX_SAM_ENTRIES;
1748 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1751 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1752 NT_STATUS_HAVE_NO_MEMORY(rid);
1754 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1755 NT_STATUS_HAVE_NO_MEMORY(type);
1757 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1758 sid_string_dbg(&dinfo->sid)));
1760 for (i = 0; i < num_rids; i++) {
1762 status = NT_STATUS_NONE_MAPPED;
1763 type[i] = SID_NAME_UNKNOWN;
1765 rid[i] = 0xffffffff;
1767 if (sid_check_is_builtin(&dinfo->sid)) {
1768 if (lookup_builtin_name(r->in.names[i].string,
1771 type[i] = SID_NAME_ALIAS;
1774 lookup_global_sam_name(r->in.names[i].string, 0,
1778 if (type[i] != SID_NAME_UNKNOWN) {
1783 if (num_mapped == num_rids) {
1784 status = NT_STATUS_OK;
1785 } else if (num_mapped == 0) {
1786 status = NT_STATUS_NONE_MAPPED;
1788 status = STATUS_SOME_UNMAPPED;
1791 rids.count = num_rids;
1794 types.count = num_rids;
1797 *r->out.rids = rids;
1798 *r->out.types = types;
1800 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1805 /****************************************************************
1806 _samr_ChangePasswordUser
1807 ****************************************************************/
1809 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1810 struct samr_ChangePasswordUser *r)
1814 struct samr_user_info *uinfo;
1816 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1817 struct samr_Password lm_pwd, nt_pwd;
1819 uinfo = policy_handle_find(p, r->in.user_handle,
1820 SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1821 struct samr_user_info, &status);
1822 if (!NT_STATUS_IS_OK(status)) {
1826 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1827 sid_string_dbg(&uinfo->sid)));
1829 if (!(pwd = samu_new(NULL))) {
1830 return NT_STATUS_NO_MEMORY;
1834 ret = pdb_getsampwsid(pwd, &uinfo->sid);
1839 return NT_STATUS_WRONG_PASSWORD;
1843 const uint8_t *lm_pass, *nt_pass;
1845 lm_pass = pdb_get_lanman_passwd(pwd);
1846 nt_pass = pdb_get_nt_passwd(pwd);
1848 if (!lm_pass || !nt_pass) {
1849 status = NT_STATUS_WRONG_PASSWORD;
1853 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1854 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1857 /* basic sanity checking on parameters. Do this before any database ops */
1858 if (!r->in.lm_present || !r->in.nt_present ||
1859 !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1860 !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1861 /* we should really handle a change with lm not
1863 status = NT_STATUS_INVALID_PARAMETER_MIX;
1867 /* decrypt and check the new lm hash */
1868 D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1869 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1870 if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1871 status = NT_STATUS_WRONG_PASSWORD;
1875 /* decrypt and check the new nt hash */
1876 D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1877 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1878 if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1879 status = NT_STATUS_WRONG_PASSWORD;
1883 /* The NT Cross is not required by Win2k3 R2, but if present
1884 check the nt cross hash */
1885 if (r->in.cross1_present && r->in.nt_cross) {
1886 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1887 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1888 status = NT_STATUS_WRONG_PASSWORD;
1893 /* The LM Cross is not required by Win2k3 R2, but if present
1894 check the lm cross hash */
1895 if (r->in.cross2_present && r->in.lm_cross) {
1896 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1897 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1898 status = NT_STATUS_WRONG_PASSWORD;
1903 if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1904 !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1905 status = NT_STATUS_ACCESS_DENIED;
1909 status = pdb_update_sam_account(pwd);
1916 /*******************************************************************
1917 _samr_ChangePasswordUser2
1918 ********************************************************************/
1920 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1921 struct samr_ChangePasswordUser2 *r)
1927 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1929 fstrcpy(user_name, r->in.account->string);
1930 fstrcpy(wks, r->in.server->string);
1932 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1935 * Pass the user through the NT -> unix user mapping
1939 (void)map_username(user_name);
1942 * UNIX username case mangling not required, pass_oem_change
1943 * is case insensitive.
1946 status = pass_oem_change(user_name,
1947 r->in.lm_password->data,
1948 r->in.lm_verifier->hash,
1949 r->in.nt_password->data,
1950 r->in.nt_verifier->hash,
1953 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1955 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1956 return NT_STATUS_WRONG_PASSWORD;
1962 /****************************************************************
1963 _samr_OemChangePasswordUser2
1964 ****************************************************************/
1966 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
1967 struct samr_OemChangePasswordUser2 *r)
1971 const char *wks = NULL;
1973 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1975 fstrcpy(user_name, r->in.account->string);
1976 if (r->in.server && r->in.server->string) {
1977 wks = r->in.server->string;
1980 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1983 * Pass the user through the NT -> unix user mapping
1987 (void)map_username(user_name);
1990 * UNIX username case mangling not required, pass_oem_change
1991 * is case insensitive.
1994 if (!r->in.hash || !r->in.password) {
1995 return NT_STATUS_INVALID_PARAMETER;
1998 status = pass_oem_change(user_name,
1999 r->in.password->data,
2005 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2006 return NT_STATUS_WRONG_PASSWORD;
2009 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2014 /*******************************************************************
2015 _samr_ChangePasswordUser3
2016 ********************************************************************/
2018 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
2019 struct samr_ChangePasswordUser3 *r)
2023 const char *wks = NULL;
2024 uint32 reject_reason;
2025 struct samr_DomInfo1 *dominfo = NULL;
2026 struct samr_ChangeReject *reject = NULL;
2029 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2031 fstrcpy(user_name, r->in.account->string);
2032 if (r->in.server && r->in.server->string) {
2033 wks = r->in.server->string;
2036 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2039 * Pass the user through the NT -> unix user mapping
2043 (void)map_username(user_name);
2046 * UNIX username case mangling not required, pass_oem_change
2047 * is case insensitive.
2050 status = pass_oem_change(user_name,
2051 r->in.lm_password->data,
2052 r->in.lm_verifier->hash,
2053 r->in.nt_password->data,
2054 r->in.nt_verifier->hash,
2056 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2057 return NT_STATUS_WRONG_PASSWORD;
2060 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2061 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2063 time_t u_expire, u_min_age;
2064 uint32 account_policy_temp;
2066 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2068 return NT_STATUS_NO_MEMORY;
2071 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2073 return NT_STATUS_NO_MEMORY;
2080 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
2081 dominfo->min_password_length = tmp;
2083 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
2084 dominfo->password_history_length = tmp;
2086 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2087 &dominfo->password_properties);
2089 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2090 u_expire = account_policy_temp;
2092 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2093 u_min_age = account_policy_temp;
2099 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2100 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2102 if (lp_check_password_script() && *lp_check_password_script()) {
2103 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2106 reject->reason = reject_reason;
2108 *r->out.dominfo = dominfo;
2109 *r->out.reject = reject;
2112 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2117 /*******************************************************************
2118 makes a SAMR_R_LOOKUP_RIDS structure.
2119 ********************************************************************/
2121 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2123 struct lsa_String **lsa_name_array_p)
2125 struct lsa_String *lsa_name_array = NULL;
2128 *lsa_name_array_p = NULL;
2130 if (num_names != 0) {
2131 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2132 if (!lsa_name_array) {
2137 for (i = 0; i < num_names; i++) {
2138 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2139 init_lsa_String(&lsa_name_array[i], names[i]);
2142 *lsa_name_array_p = lsa_name_array;
2147 /*******************************************************************
2149 ********************************************************************/
2151 NTSTATUS _samr_LookupRids(pipes_struct *p,
2152 struct samr_LookupRids *r)
2154 struct samr_domain_info *dinfo;
2157 enum lsa_SidType *attrs = NULL;
2158 uint32 *wire_attrs = NULL;
2159 int num_rids = (int)r->in.num_rids;
2161 struct lsa_Strings names_array;
2162 struct samr_Ids types_array;
2163 struct lsa_String *lsa_names = NULL;
2165 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2167 dinfo = policy_handle_find(p, r->in.domain_handle,
2168 0 /* Don't know the acc_bits yet */, NULL,
2169 struct samr_domain_info, &status);
2170 if (!NT_STATUS_IS_OK(status)) {
2174 if (num_rids > 1000) {
2175 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2176 "to samba4 idl this is not possible\n", num_rids));
2177 return NT_STATUS_UNSUCCESSFUL;
2181 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2182 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2183 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2185 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2186 return NT_STATUS_NO_MEMORY;
2193 become_root(); /* lookup_sid can require root privs */
2194 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2198 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2199 status = NT_STATUS_OK;
2202 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2204 return NT_STATUS_NO_MEMORY;
2207 /* Convert from enum lsa_SidType to uint32 for wire format. */
2208 for (i = 0; i < num_rids; i++) {
2209 wire_attrs[i] = (uint32)attrs[i];
2212 names_array.count = num_rids;
2213 names_array.names = lsa_names;
2215 types_array.count = num_rids;
2216 types_array.ids = wire_attrs;
2218 *r->out.names = names_array;
2219 *r->out.types = types_array;
2221 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2226 /*******************************************************************
2228 ********************************************************************/
2230 NTSTATUS _samr_OpenUser(pipes_struct *p,
2231 struct samr_OpenUser *r)
2233 struct samu *sampass=NULL;
2235 struct samr_domain_info *dinfo;
2236 struct samr_user_info *uinfo;
2237 SEC_DESC *psd = NULL;
2239 uint32 des_access = r->in.access_mask;
2240 uint32_t extra_access = 0;
2247 dinfo = policy_handle_find(p, r->in.domain_handle,
2248 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2249 struct samr_domain_info, &status);
2250 if (!NT_STATUS_IS_OK(status)) {
2254 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2255 return NT_STATUS_NO_MEMORY;
2258 /* append the user's RID to it */
2260 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2261 return NT_STATUS_NO_SUCH_USER;
2263 /* check if access can be granted as requested by client. */
2265 map_max_allowed_access(p->server_info->ptok, &des_access);
2267 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2268 se_map_generic(&des_access, &usr_generic_mapping);
2271 * Get the sampass first as we need to check privilages
2272 * based on what kind of user object this is.
2273 * But don't reveal info too early if it didn't exist.
2277 ret=pdb_getsampwsid(sampass, &sid);
2280 se_priv_copy(&se_rights, &se_priv_none);
2283 * We do the override access checks on *open*, not at
2287 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2289 if ((acb_info & ACB_WSTRUST) &&
2290 user_has_any_privilege(p->server_info->ptok,
2291 &se_machine_account)) {
2293 * SeMachineAccount is needed to add
2294 * GENERIC_RIGHTS_USER_WRITE to a machine
2297 se_priv_add(&se_rights, &se_machine_account);
2298 DEBUG(10,("_samr_OpenUser: adding machine account "
2299 "rights to handle for user %s\n",
2300 pdb_get_username(sampass) ));
2302 if ((acb_info & ACB_NORMAL) &&
2303 user_has_any_privilege(p->server_info->ptok,
2306 * SeAddUsers is needed to add
2307 * GENERIC_RIGHTS_USER_WRITE to a normal
2310 se_priv_add(&se_rights, &se_add_users);
2311 DEBUG(10,("_samr_OpenUser: adding add user "
2312 "rights to handle for user %s\n",
2313 pdb_get_username(sampass) ));
2316 * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
2317 * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not
2318 * what Windows does but is a hack for people who haven't
2319 * set up privilages on groups in Samba.
2321 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2322 if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2323 DOMAIN_GROUP_RID_ADMINS)) {
2324 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2325 extra_access = GENERIC_RIGHTS_USER_WRITE;
2326 DEBUG(4,("_samr_OpenUser: Allowing "
2327 "GENERIC_RIGHTS_USER_WRITE for "
2333 TALLOC_FREE(sampass);
2335 nt_status = access_check_object(psd, p->server_info->ptok,
2336 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2337 &acc_granted, "_samr_OpenUser");
2339 if ( !NT_STATUS_IS_OK(nt_status) )
2342 /* check that the SID exists in our domain. */
2344 return NT_STATUS_NO_SUCH_USER;
2347 /* If we did the rid admins hack above, allow access. */
2348 acc_granted |= extra_access;
2350 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2351 struct samr_user_info, &nt_status);
2352 if (!NT_STATUS_IS_OK(nt_status)) {
2357 return NT_STATUS_OK;
2360 /*************************************************************************
2361 *************************************************************************/
2363 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2365 struct lsa_BinaryString **_r)
2367 struct lsa_BinaryString *r;
2370 return NT_STATUS_INVALID_PARAMETER;
2373 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2375 return NT_STATUS_NO_MEMORY;
2378 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2380 return NT_STATUS_NO_MEMORY;
2382 memcpy(r->array, blob->data, blob->length);
2383 r->size = blob->length;
2384 r->length = blob->length;
2387 return NT_STATUS_NO_MEMORY;
2392 return NT_STATUS_OK;
2395 /*************************************************************************
2397 *************************************************************************/
2399 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2400 struct samr_UserInfo1 *r,
2402 DOM_SID *domain_sid)
2404 const DOM_SID *sid_group;
2405 uint32_t primary_gid;
2408 sid_group = pdb_get_group_sid(pw);
2411 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2412 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2413 "which conflicts with the domain sid %s. Failing operation.\n",
2414 pdb_get_username(pw), sid_string_dbg(sid_group),
2415 sid_string_dbg(domain_sid)));
2416 return NT_STATUS_UNSUCCESSFUL;
2419 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2420 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2421 r->primary_gid = primary_gid;
2422 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2423 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2425 return NT_STATUS_OK;
2428 /*************************************************************************
2430 *************************************************************************/
2432 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2433 struct samr_UserInfo2 *r,
2436 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2437 r->unknown.string = NULL;
2438 r->country_code = 0;
2441 return NT_STATUS_OK;
2444 /*************************************************************************
2446 *************************************************************************/
2448 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2449 struct samr_UserInfo3 *r,
2451 DOM_SID *domain_sid)
2453 const DOM_SID *sid_user, *sid_group;
2454 uint32_t rid, primary_gid;
2456 sid_user = pdb_get_user_sid(pw);
2458 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2459 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2460 "the domain sid %s. Failing operation.\n",
2461 pdb_get_username(pw), sid_string_dbg(sid_user),
2462 sid_string_dbg(domain_sid)));
2463 return NT_STATUS_UNSUCCESSFUL;
2467 sid_group = pdb_get_group_sid(pw);
2470 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2471 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2472 "which conflicts with the domain sid %s. Failing operation.\n",
2473 pdb_get_username(pw), sid_string_dbg(sid_group),
2474 sid_string_dbg(domain_sid)));
2475 return NT_STATUS_UNSUCCESSFUL;
2478 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2479 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2480 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2481 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2482 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2484 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2485 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2486 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2487 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2488 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2489 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2490 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2492 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2494 r->primary_gid = primary_gid;
2495 r->acct_flags = pdb_get_acct_ctrl(pw);
2496 r->bad_password_count = pdb_get_bad_password_count(pw);
2497 r->logon_count = pdb_get_logon_count(pw);
2499 return NT_STATUS_OK;
2502 /*************************************************************************
2504 *************************************************************************/
2506 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2507 struct samr_UserInfo4 *r,
2510 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2512 return NT_STATUS_OK;
2515 /*************************************************************************
2517 *************************************************************************/
2519 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2520 struct samr_UserInfo5 *r,
2522 DOM_SID *domain_sid)
2524 const DOM_SID *sid_user, *sid_group;
2525 uint32_t rid, primary_gid;
2527 sid_user = pdb_get_user_sid(pw);
2529 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2530 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2531 "the domain sid %s. Failing operation.\n",
2532 pdb_get_username(pw), sid_string_dbg(sid_user),
2533 sid_string_dbg(domain_sid)));
2534 return NT_STATUS_UNSUCCESSFUL;
2538 sid_group = pdb_get_group_sid(pw);
2541 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2542 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2543 "which conflicts with the domain sid %s. Failing operation.\n",
2544 pdb_get_username(pw), sid_string_dbg(sid_group),
2545 sid_string_dbg(domain_sid)));
2546 return NT_STATUS_UNSUCCESSFUL;
2549 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2550 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2551 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2552 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2554 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2555 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2556 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2557 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2558 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2559 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2560 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2561 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2563 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2565 r->primary_gid = primary_gid;
2566 r->acct_flags = pdb_get_acct_ctrl(pw);
2567 r->bad_password_count = pdb_get_bad_password_count(pw);
2568 r->logon_count = pdb_get_logon_count(pw);
2570 return NT_STATUS_OK;
2573 /*************************************************************************
2575 *************************************************************************/
2577 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2578 struct samr_UserInfo6 *r,
2581 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2582 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2584 return NT_STATUS_OK;
2587 /*************************************************************************
2588 get_user_info_7. Safe. Only gives out account_name.
2589 *************************************************************************/
2591 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2592 struct samr_UserInfo7 *r,
2593 struct samu *smbpass)
2595 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2596 if (!r->account_name.string) {
2597 return NT_STATUS_NO_MEMORY;
2600 return NT_STATUS_OK;
2603 /*************************************************************************
2605 *************************************************************************/
2607 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2608 struct samr_UserInfo8 *r,
2611 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2613 return NT_STATUS_OK;
2616 /*************************************************************************
2617 get_user_info_9. Only gives out primary group SID.
2618 *************************************************************************/
2620 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2621 struct samr_UserInfo9 *r,
2622 struct samu *smbpass)
2624 r->primary_gid = pdb_get_group_rid(smbpass);
2626 return NT_STATUS_OK;
2629 /*************************************************************************
2631 *************************************************************************/
2633 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2634 struct samr_UserInfo10 *r,
2637 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2638 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2640 return NT_STATUS_OK;
2643 /*************************************************************************
2645 *************************************************************************/
2647 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2648 struct samr_UserInfo11 *r,
2651 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2653 return NT_STATUS_OK;
2656 /*************************************************************************
2658 *************************************************************************/
2660 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2661 struct samr_UserInfo12 *r,
2664 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2666 return NT_STATUS_OK;
2669 /*************************************************************************
2671 *************************************************************************/
2673 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2674 struct samr_UserInfo13 *r,
2677 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2679 return NT_STATUS_OK;
2682 /*************************************************************************
2684 *************************************************************************/
2686 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2687 struct samr_UserInfo14 *r,
2690 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2692 return NT_STATUS_OK;
2695 /*************************************************************************
2696 get_user_info_16. Safe. Only gives out acb bits.
2697 *************************************************************************/
2699 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2700 struct samr_UserInfo16 *r,
2701 struct samu *smbpass)
2703 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2705 return NT_STATUS_OK;
2708 /*************************************************************************
2710 *************************************************************************/
2712 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2713 struct samr_UserInfo17 *r,
2716 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2718 return NT_STATUS_OK;
2721 /*************************************************************************
2722 get_user_info_18. OK - this is the killer as it gives out password info.
2723 Ensure that this is only allowed on an encrypted connection with a root
2725 *************************************************************************/
2727 static NTSTATUS get_user_info_18(pipes_struct *p,
2728 TALLOC_CTX *mem_ctx,
2729 struct samr_UserInfo18 *r,
2732 struct samu *smbpass=NULL;
2737 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2738 return NT_STATUS_ACCESS_DENIED;
2741 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2742 return NT_STATUS_ACCESS_DENIED;
2746 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2749 if ( !(smbpass = samu_new( mem_ctx )) ) {
2750 return NT_STATUS_NO_MEMORY;
2753 ret = pdb_getsampwsid(smbpass, user_sid);
2756 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2757 TALLOC_FREE(smbpass);
2758 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2761 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2763 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2764 TALLOC_FREE(smbpass);
2765 return NT_STATUS_ACCOUNT_DISABLED;
2768 r->lm_pwd_active = true;
2769 r->nt_pwd_active = true;
2770 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2771 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2772 r->password_expired = 0; /* FIXME */
2774 TALLOC_FREE(smbpass);
2776 return NT_STATUS_OK;
2779 /*************************************************************************
2781 *************************************************************************/
2783 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2784 struct samr_UserInfo20 *r,
2785 struct samu *sampass)
2787 const char *munged_dial = NULL;
2790 struct lsa_BinaryString *parameters = NULL;
2794 munged_dial = pdb_get_munged_dial(sampass);
2796 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2797 munged_dial, (int)strlen(munged_dial)));
2800 blob = base64_decode_data_blob(munged_dial);
2802 blob = data_blob_string_const_null("");
2805 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2806 data_blob_free(&blob);
2807 if (!NT_STATUS_IS_OK(status)) {
2811 r->parameters = *parameters;
2813 return NT_STATUS_OK;
2817 /*************************************************************************
2819 *************************************************************************/
2821 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2822 struct samr_UserInfo21 *r,
2824 DOM_SID *domain_sid,
2825 uint32_t acc_granted)
2828 const DOM_SID *sid_user, *sid_group;
2829 uint32_t rid, primary_gid;
2830 NTTIME force_password_change;
2831 time_t must_change_time;
2832 struct lsa_BinaryString *parameters = NULL;
2833 const char *munged_dial = NULL;
2838 sid_user = pdb_get_user_sid(pw);
2840 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2841 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2842 "the domain sid %s. Failing operation.\n",
2843 pdb_get_username(pw), sid_string_dbg(sid_user),
2844 sid_string_dbg(domain_sid)));
2845 return NT_STATUS_UNSUCCESSFUL;
2849 sid_group = pdb_get_group_sid(pw);
2852 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2853 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2854 "which conflicts with the domain sid %s. Failing operation.\n",
2855 pdb_get_username(pw), sid_string_dbg(sid_group),
2856 sid_string_dbg(domain_sid)));
2857 return NT_STATUS_UNSUCCESSFUL;
2860 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2861 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2862 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2863 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2864 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2866 must_change_time = pdb_get_pass_must_change_time(pw);
2867 if (must_change_time == get_time_t_max()) {
2868 unix_to_nt_time_abs(&force_password_change, must_change_time);
2870 unix_to_nt_time(&force_password_change, must_change_time);
2873 munged_dial = pdb_get_munged_dial(pw);
2875 blob = base64_decode_data_blob(munged_dial);
2877 blob = data_blob_string_const_null("");
2880 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2881 data_blob_free(&blob);
2882 if (!NT_STATUS_IS_OK(status)) {
2886 r->force_password_change = force_password_change;
2888 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2889 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2890 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2891 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2892 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2893 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2894 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2895 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2896 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2898 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2899 r->parameters = *parameters;
2901 r->primary_gid = primary_gid;
2902 r->acct_flags = pdb_get_acct_ctrl(pw);
2903 r->bad_password_count = pdb_get_bad_password_count(pw);
2904 r->logon_count = pdb_get_logon_count(pw);
2905 r->fields_present = pdb_build_fields_present(pw);
2906 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2907 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2908 r->country_code = 0;
2910 r->lm_password_set = 0;
2911 r->nt_password_set = 0;
2916 Look at a user on a real NT4 PDC with usrmgr, press
2917 'ok'. Then you will see that fields_present is set to
2918 0x08f827fa. Look at the user immediately after that again,
2919 and you will see that 0x00fffff is returned. This solves
2920 the problem that you get access denied after having looked
2928 return NT_STATUS_OK;
2931 /*******************************************************************
2933 ********************************************************************/
2935 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2936 struct samr_QueryUserInfo *r)
2939 union samr_UserInfo *user_info = NULL;
2940 struct samr_user_info *uinfo;
2944 struct samu *pwd = NULL;
2945 uint32_t acc_required, acc_granted;
2947 switch (r->in.level) {
2948 case 1: /* UserGeneralInformation */
2949 /* USER_READ_GENERAL */
2950 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2952 case 2: /* UserPreferencesInformation */
2953 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2954 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2955 SAMR_USER_ACCESS_GET_NAME_ETC;
2957 case 3: /* UserLogonInformation */
2958 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2959 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2960 SAMR_USER_ACCESS_GET_LOCALE |
2961 SAMR_USER_ACCESS_GET_LOGONINFO |
2962 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2964 case 4: /* UserLogonHoursInformation */
2965 /* USER_READ_LOGON */
2966 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2968 case 5: /* UserAccountInformation */
2969 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2970 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2971 SAMR_USER_ACCESS_GET_LOCALE |
2972 SAMR_USER_ACCESS_GET_LOGONINFO |
2973 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2975 case 6: /* UserNameInformation */
2976 case 7: /* UserAccountNameInformation */
2977 case 8: /* UserFullNameInformation */
2978 case 9: /* UserPrimaryGroupInformation */
2979 case 13: /* UserAdminCommentInformation */
2980 /* USER_READ_GENERAL */
2981 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2983 case 10: /* UserHomeInformation */
2984 case 11: /* UserScriptInformation */
2985 case 12: /* UserProfileInformation */
2986 case 14: /* UserWorkStationsInformation */
2987 /* USER_READ_LOGON */
2988 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2990 case 16: /* UserControlInformation */
2991 case 17: /* UserExpiresInformation */
2992 case 20: /* UserParametersInformation */
2993 /* USER_READ_ACCOUNT */
2994 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2996 case 21: /* UserAllInformation */
2998 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3000 case 18: /* UserInternal1Information */
3002 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3004 case 23: /* UserInternal4Information */
3005 case 24: /* UserInternal4InformationNew */
3006 case 25: /* UserInternal4InformationNew */
3007 case 26: /* UserInternal5InformationNew */
3009 return NT_STATUS_INVALID_INFO_CLASS;
3013 uinfo = policy_handle_find(p, r->in.user_handle,
3014 acc_required, &acc_granted,
3015 struct samr_user_info, &status);
3016 if (!NT_STATUS_IS_OK(status)) {
3020 domain_sid = uinfo->sid;
3022 sid_split_rid(&domain_sid, &rid);
3024 if (!sid_check_is_in_our_domain(&uinfo->sid))
3025 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3027 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3028 sid_string_dbg(&uinfo->sid)));
3030 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3032 return NT_STATUS_NO_MEMORY;
3035 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3037 if (!(pwd = samu_new(p->mem_ctx))) {
3038 return NT_STATUS_NO_MEMORY;
3042 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3046 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3048 return NT_STATUS_NO_SUCH_USER;
3051 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3053 samr_clear_sam_passwd(pwd);
3055 switch (r->in.level) {
3057 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3060 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3063 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3066 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3069 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3072 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3075 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3078 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3081 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3084 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3087 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3090 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3093 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3096 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3099 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3102 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3105 /* level 18 is special */
3106 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3110 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3113 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3116 status = NT_STATUS_INVALID_INFO_CLASS;
3120 if (!NT_STATUS_IS_OK(status)) {
3124 *r->out.info = user_info;
3129 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3134 /****************************************************************
3135 ****************************************************************/
3137 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3138 struct samr_QueryUserInfo2 *r)
3140 struct samr_QueryUserInfo u;
3142 u.in.user_handle = r->in.user_handle;
3143 u.in.level = r->in.level;
3144 u.out.info = r->out.info;
3146 return _samr_QueryUserInfo(p, &u);
3149 /*******************************************************************
3150 _samr_GetGroupsForUser
3151 ********************************************************************/
3153 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3154 struct samr_GetGroupsForUser *r)
3156 struct samr_user_info *uinfo;
3157 struct samu *sam_pass=NULL;
3159 struct samr_RidWithAttribute dom_gid;
3160 struct samr_RidWithAttribute *gids = NULL;
3161 uint32 primary_group_rid;
3162 size_t num_groups = 0;
3167 bool success = False;
3169 struct samr_RidWithAttributeArray *rids = NULL;
3172 * from the SID in the request:
3173 * we should send back the list of DOMAIN GROUPS
3174 * the user is a member of
3176 * and only the DOMAIN GROUPS
3177 * no ALIASES !!! neither aliases of the domain
3178 * nor aliases of the builtin SID
3183 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3185 uinfo = policy_handle_find(p, r->in.user_handle,
3186 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3187 struct samr_user_info, &result);
3188 if (!NT_STATUS_IS_OK(result)) {
3192 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3194 return NT_STATUS_NO_MEMORY;
3197 if (!sid_check_is_in_our_domain(&uinfo->sid))
3198 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3200 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3201 return NT_STATUS_NO_MEMORY;
3205 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3209 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3210 sid_string_dbg(&uinfo->sid)));
3211 return NT_STATUS_NO_SUCH_USER;
3216 /* make both calls inside the root block */
3218 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3219 &sids, &unix_gids, &num_groups);
3220 if ( NT_STATUS_IS_OK(result) ) {
3221 success = sid_peek_check_rid(get_global_sam_sid(),
3222 pdb_get_group_sid(sam_pass),
3223 &primary_group_rid);
3227 if (!NT_STATUS_IS_OK(result)) {
3228 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3229 sid_string_dbg(&uinfo->sid)));
3234 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3235 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3236 pdb_get_username(sam_pass)));
3237 TALLOC_FREE(sam_pass);
3238 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3244 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3246 dom_gid.rid = primary_group_rid;
3247 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3249 for (i=0; i<num_groups; i++) {
3251 if (!sid_peek_check_rid(get_global_sam_sid(),
3252 &(sids[i]), &dom_gid.rid)) {
3253 DEBUG(10, ("Found sid %s not in our domain\n",
3254 sid_string_dbg(&sids[i])));
3258 if (dom_gid.rid == primary_group_rid) {
3259 /* We added the primary group directly from the
3260 * sam_account. The other SIDs are unique from
3261 * enum_group_memberships */
3265 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3268 rids->count = num_gids;
3271 *r->out.rids = rids;
3273 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3278 /*******************************************************************
3279 _samr_QueryDomainInfo
3280 ********************************************************************/
3282 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3283 struct samr_QueryDomainInfo *r)
3285 NTSTATUS status = NT_STATUS_OK;
3286 struct samr_domain_info *dinfo;
3287 union samr_DomainInfo *dom_info;
3288 time_t u_expire, u_min_age;
3290 time_t u_lock_duration, u_reset_time;
3293 uint32 account_policy_temp;
3297 uint32_t acc_required;
3299 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3301 switch (r->in.level) {
3302 case 1: /* DomainPasswordInformation */
3303 case 12: /* DomainLockoutInformation */
3304 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3305 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3307 case 11: /* DomainGeneralInformation2 */
3308 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3309 * DOMAIN_READ_OTHER_PARAMETERS */
3310 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3311 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3313 case 2: /* DomainGeneralInformation */
3314 case 3: /* DomainLogoffInformation */
3315 case 4: /* DomainOemInformation */
3316 case 5: /* DomainReplicationInformation */
3317 case 6: /* DomainReplicationInformation */
3318 case 7: /* DomainServerRoleInformation */
3319 case 8: /* DomainModifiedInformation */
3320 case 9: /* DomainStateInformation */
3321 case 10: /* DomainUasInformation */
3322 case 13: /* DomainModifiedInformation2 */
3323 /* DOMAIN_READ_OTHER_PARAMETERS */
3324 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3327 return NT_STATUS_INVALID_INFO_CLASS;
3330 dinfo = policy_handle_find(p, r->in.domain_handle,
3332 struct samr_domain_info, &status);
3333 if (!NT_STATUS_IS_OK(status)) {
3337 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3339 return NT_STATUS_NO_MEMORY;
3342 switch (r->in.level) {
3349 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
3350 &account_policy_temp);
3351 dom_info->info1.min_password_length = account_policy_temp;
3353 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
3354 dom_info->info1.password_history_length = account_policy_temp;
3356 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
3357 &dom_info->info1.password_properties);
3359 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
3360 u_expire = account_policy_temp;
3362 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
3363 u_min_age = account_policy_temp;
3369 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
3370 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
3372 if (lp_check_password_script() && *lp_check_password_script()) {
3373 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
3383 dom_info->general.num_users = count_sam_users(
3384 dinfo->disp_info, ACB_NORMAL);
3385 dom_info->general.num_groups = count_sam_groups(
3387 dom_info->general.num_aliases = count_sam_aliases(
3390 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3392 unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
3394 if (!pdb_get_seq_num(&seq_num))
3395 seq_num = time(NULL);
3401 server_role = ROLE_DOMAIN_PDC;
3402 if (lp_server_role() == ROLE_DOMAIN_BDC)
3403 server_role = ROLE_DOMAIN_BDC;
3405 dom_info->general.oem_information.string = lp_serverstring();
3406 dom_info->general.domain_name.string = lp_workgroup();
3407 dom_info->general.primary.string = global_myname();
3408 dom_info->general.sequence_num = seq_num;
3409 dom_info->general.domain_server_state = DOMAIN_SERVER_ENABLED;
3410 dom_info->general.role = server_role;
3411 dom_info->general.unknown3 = 1;
3422 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3423 u_logout = (time_t)ul;
3430 unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
3434 dom_info->oem.oem_information.string = lp_serverstring();
3437 dom_info->info5.domain_name.string = get_global_sam_name();
3440 /* NT returns its own name when a PDC. win2k and later
3441 * only the name of the PDC if itself is a BDC (samba4
3443 dom_info->info6.primary.string = global_myname();
3446 server_role = ROLE_DOMAIN_PDC;
3447 if (lp_server_role() == ROLE_DOMAIN_BDC)
3448 server_role = ROLE_DOMAIN_BDC;
3450 dom_info->info7.role = server_role;
3458 if (!pdb_get_seq_num(&seq_num)) {
3459 seq_num = time(NULL);
3466 dom_info->info8.sequence_num = seq_num;
3467 dom_info->info8.domain_create_time = 0;
3472 dom_info->info9.domain_server_state = DOMAIN_SERVER_ENABLED;
3481 dom_info->general2.general.num_users = count_sam_users(
3482 dinfo->disp_info, ACB_NORMAL);
3483 dom_info->general2.general.num_groups = count_sam_groups(
3485 dom_info->general2.general.num_aliases = count_sam_aliases(
3488 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3490 unix_to_nt_time_abs(&dom_info->general2.general.force_logoff_time, u_logout);
3492 if (!pdb_get_seq_num(&seq_num))
3493 seq_num = time(NULL);
3495 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3496 u_lock_duration = account_policy_temp;
3497 if (u_lock_duration != -1) {
3498 u_lock_duration *= 60;
3501 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3502 u_reset_time = account_policy_temp * 60;
3504 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3505 &account_policy_temp);
3506 dom_info->general2.lockout_threshold = account_policy_temp;
3512 server_role = ROLE_DOMAIN_PDC;
3513 if (lp_server_role() == ROLE_DOMAIN_BDC)
3514 server_role = ROLE_DOMAIN_BDC;
3516 dom_info->general2.general.oem_information.string = lp_serverstring();
3517 dom_info->general2.general.domain_name.string = lp_workgroup();
3518 dom_info->general2.general.primary.string = global_myname();
3519 dom_info->general2.general.sequence_num = seq_num;
3520 dom_info->general2.general.domain_server_state = DOMAIN_SERVER_ENABLED;
3521 dom_info->general2.general.role = server_role;
3522 dom_info->general2.general.unknown3 = 1;
3524 unix_to_nt_time_abs(&dom_info->general2.lockout_duration,
3526 unix_to_nt_time_abs(&dom_info->general2.lockout_window,
3536 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3537 u_lock_duration = account_policy_temp;
3538 if (u_lock_duration != -1) {
3539 u_lock_duration *= 60;
3542 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3543 u_reset_time = account_policy_temp * 60;
3545 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3546 &account_policy_temp);
3547 dom_info->info12.lockout_threshold = account_policy_temp;
3553 unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
3555 unix_to_nt_time_abs(&dom_info->info12.lockout_window,
3565 if (!pdb_get_seq_num(&seq_num)) {
3566 seq_num = time(NULL);
3573 dom_info->info13.sequence_num = seq_num;
3574 dom_info->info13.domain_create_time = 0;
3575 dom_info->info13.modified_count_at_last_promotion = 0;
3579 return NT_STATUS_INVALID_INFO_CLASS;
3582 *r->out.info = dom_info;
3584 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3589 /* W2k3 seems to use the same check for all 3 objects that can be created via
3590 * SAMR, if you try to create for example "Dialup" as an alias it says
3591 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3594 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3596 enum lsa_SidType type;
3599 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3602 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3603 * whether the name already exists */
3604 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3605 NULL, NULL, NULL, &type);
3609 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3610 return NT_STATUS_OK;
3613 DEBUG(5, ("trying to create %s, exists as %s\n",
3614 new_name, sid_type_lookup(type)));
3616 if (type == SID_NAME_DOM_GRP) {
3617 return NT_STATUS_GROUP_EXISTS;
3619 if (type == SID_NAME_ALIAS) {
3620 return NT_STATUS_ALIAS_EXISTS;
3623 /* Yes, the default is NT_STATUS_USER_EXISTS */
3624 return NT_STATUS_USER_EXISTS;
3627 /*******************************************************************
3629 ********************************************************************/
3631 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3632 struct samr_CreateUser2 *r)
3634 const char *account = NULL;
3636 uint32_t acb_info = r->in.acct_flags;
3637 struct samr_domain_info *dinfo;
3638 struct samr_user_info *uinfo;
3643 /* check this, when giving away 'add computer to domain' privs */
3644 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3645 bool can_add_account = False;
3648 dinfo = policy_handle_find(p, r->in.domain_handle,
3649 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3650 struct samr_domain_info, &nt_status);
3651 if (!NT_STATUS_IS_OK(nt_status)) {
3655 if (sid_check_is_builtin(&dinfo->sid)) {
3656 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3657 return NT_STATUS_ACCESS_DENIED;
3660 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3661 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3662 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3663 this parameter is not an account type */
3664 return NT_STATUS_INVALID_PARAMETER;
3667 account = r->in.account_name->string;
3668 if (account == NULL) {
3669 return NT_STATUS_NO_MEMORY;
3672 nt_status = can_create(p->mem_ctx, account);
3673 if (!NT_STATUS_IS_OK(nt_status)) {
3677 /* determine which user right we need to check based on the acb_info */
3679 if (geteuid() == sec_initial_uid()) {
3680 se_priv_copy(&se_rights, &se_priv_none);
3681 can_add_account = true;
3682 } else if (acb_info & ACB_WSTRUST) {
3683 se_priv_copy(&se_rights, &se_machine_account);
3684 can_add_account = user_has_privileges(
3685 p->server_info->ptok, &se_rights );
3686 } else if (acb_info & ACB_NORMAL &&
3687 (account[strlen(account)-1] != '$')) {
3688 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3689 account for domain trusts and changes the ACB flags later */
3690 se_priv_copy(&se_rights, &se_add_users);
3691 can_add_account = user_has_privileges(
3692 p->server_info->ptok, &se_rights );
3693 } else if (lp_enable_privileges()) {
3694 /* implicit assumption of a BDC or domain trust account here
3695 * (we already check the flags earlier) */
3696 /* only Domain Admins can add a BDC or domain trust */
3697 se_priv_copy(&se_rights, &se_priv_none);
3698 can_add_account = nt_token_check_domain_rid(
3699 p->server_info->ptok,
3700 DOMAIN_GROUP_RID_ADMINS );
3703 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3704 uidtoname(p->server_info->utok.uid),
3705 can_add_account ? "True":"False" ));
3707 if (!can_add_account) {
3708 return NT_STATUS_ACCESS_DENIED;
3711 /********** BEGIN Admin BLOCK **********/
3714 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3718 /********** END Admin BLOCK **********/
3720 /* now check for failure */
3722 if ( !NT_STATUS_IS_OK(nt_status) )
3725 /* Get the user's SID */
3727 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3729 map_max_allowed_access(p->server_info->ptok, &des_access);
3731 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3732 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3733 se_map_generic(&des_access, &usr_generic_mapping);
3736 * JRA - TESTME. We just created this user so we
3737 * had rights to create them. Do we need to check
3738 * any further access on this object ? Can't we
3739 * just assume we have all the rights we need ?
3742 nt_status = access_check_object(psd, p->server_info->ptok,
3743 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3744 &acc_granted, "_samr_CreateUser2");
3746 if ( !NT_STATUS_IS_OK(nt_status) ) {
3750 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3751 struct samr_user_info, &nt_status);
3752 if (!NT_STATUS_IS_OK(nt_status)) {
3757 /* After a "set" ensure we have no cached display info. */
3758 force_flush_samr_cache(&sid);
3760 *r->out.access_granted = acc_granted;
3762 return NT_STATUS_OK;
3765 /****************************************************************
3766 ****************************************************************/
3768 NTSTATUS _samr_CreateUser(pipes_struct *p,
3769 struct samr_CreateUser *r)
3771 struct samr_CreateUser2 c;
3772 uint32_t access_granted;
3774 c.in.domain_handle = r->in.domain_handle;
3775 c.in.account_name = r->in.account_name;
3776 c.in.acct_flags = ACB_NORMAL;
3777 c.in.access_mask = r->in.access_mask;
3778 c.out.user_handle = r->out.user_handle;
3779 c.out.access_granted = &access_granted;
3780 c.out.rid = r->out.rid;
3782 return _samr_CreateUser2(p, &c);
3785 /*******************************************************************
3787 ********************************************************************/
3789 NTSTATUS _samr_Connect(pipes_struct *p,
3790 struct samr_Connect *r)
3792 struct samr_connect_info *info;
3793 uint32_t acc_granted;
3794 struct policy_handle hnd;
3795 uint32 des_access = r->in.access_mask;
3800 if (!pipe_access_check(p)) {
3801 DEBUG(3, ("access denied to _samr_Connect\n"));
3802 return NT_STATUS_ACCESS_DENIED;
3805 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3806 was observed from a win98 client trying to enumerate users (when configured
3807 user level access control on shares) --jerry */
3809 map_max_allowed_access(p->server_info->ptok, &des_access);
3811 se_map_generic( &des_access, &sam_generic_mapping );
3813 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3814 |SAMR_ACCESS_LOOKUP_DOMAIN);
3816 /* set up the SAMR connect_anon response */
3818 info = policy_handle_create(p, &hnd, acc_granted,
3819 struct samr_connect_info,
3821 if (!NT_STATUS_IS_OK(status)) {
3825 *r->out.connect_handle = hnd;
3826 return NT_STATUS_OK;
3829 /*******************************************************************
3831 ********************************************************************/
3833 NTSTATUS _samr_Connect2(pipes_struct *p,
3834 struct samr_Connect2 *r)
3836 struct samr_connect_info *info = NULL;
3837 struct policy_handle hnd;
3838 SEC_DESC *psd = NULL;
3840 uint32 des_access = r->in.access_mask;
3843 const char *fn = "_samr_Connect2";
3845 switch (p->hdr_req.opnum) {
3846 case NDR_SAMR_CONNECT2:
3847 fn = "_samr_Connect2";
3849 case NDR_SAMR_CONNECT3:
3850 fn = "_samr_Connect3";
3852 case NDR_SAMR_CONNECT4:
3853 fn = "_samr_Connect4";
3855 case NDR_SAMR_CONNECT5:
3856 fn = "_samr_Connect5";
3860 DEBUG(5,("%s: %d\n", fn, __LINE__));
3864 if (!pipe_access_check(p)) {
3865 DEBUG(3, ("access denied to %s\n", fn));
3866 return NT_STATUS_ACCESS_DENIED;
3869 map_max_allowed_access(p->server_info->ptok, &des_access);
3871 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3872 se_map_generic(&des_access, &sam_generic_mapping);
3874 nt_status = access_check_object(psd, p->server_info->ptok,
3875 NULL, 0, des_access, &acc_granted, fn);
3877 if ( !NT_STATUS_IS_OK(nt_status) )
3880 info = policy_handle_create(p, &hnd, acc_granted,
3881 struct samr_connect_info, &nt_status);
3882 if (!NT_STATUS_IS_OK(nt_status)) {
3886 DEBUG(5,("%s: %d\n", fn, __LINE__));
3888 *r->out.connect_handle = hnd;
3889 return NT_STATUS_OK;
3892 /****************************************************************
3894 ****************************************************************/
3896 NTSTATUS _samr_Connect3(pipes_struct *p,
3897 struct samr_Connect3 *r)
3899 struct samr_Connect2 c;
3901 c.in.system_name = r->in.system_name;
3902 c.in.access_mask = r->in.access_mask;
3903 c.out.connect_handle = r->out.connect_handle;
3905 return _samr_Connect2(p, &c);
3908 /*******************************************************************
3910 ********************************************************************/
3912 NTSTATUS _samr_Connect4(pipes_struct *p,
3913 struct samr_Connect4 *r)
3915 struct samr_Connect2 c;
3917 c.in.system_name = r->in.system_name;
3918 c.in.access_mask = r->in.access_mask;
3919 c.out.connect_handle = r->out.connect_handle;
3921 return _samr_Connect2(p, &c);
3924 /*******************************************************************
3926 ********************************************************************/
3928 NTSTATUS _samr_Connect5(pipes_struct *p,
3929 struct samr_Connect5 *r)
3932 struct samr_Connect2 c;
3933 struct samr_ConnectInfo1 info1;
3935 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3938 c.in.system_name = r->in.system_name;
3939 c.in.access_mask = r->in.access_mask;
3940 c.out.connect_handle = r->out.connect_handle;
3942 *r->out.level_out = 1;
3944 status = _samr_Connect2(p, &c);
3945 if (!NT_STATUS_IS_OK(status)) {
3949 r->out.info_out->info1 = info1;
3951 return NT_STATUS_OK;
3954 /**********************************************************************
3956 **********************************************************************/
3958 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3959 struct samr_LookupDomain *r)
3962 struct samr_connect_info *info;
3963 const char *domain_name;
3964 DOM_SID *sid = NULL;
3966 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3967 Reverted that change so we will work with RAS servers again */
3969 info = policy_handle_find(p, r->in.connect_handle,
3970 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3971 struct samr_connect_info,
3973 if (!NT_STATUS_IS_OK(status)) {
3977 domain_name = r->in.domain_name->string;
3979 return NT_STATUS_INVALID_PARAMETER;
3982 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3984 return NT_STATUS_NO_MEMORY;
3987 if (strequal(domain_name, builtin_domain_name())) {
3988 sid_copy(sid, &global_sid_Builtin);
3990 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3991 status = NT_STATUS_NO_SUCH_DOMAIN;
3995 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3996 sid_string_dbg(sid)));
4003 /**********************************************************************
4005 **********************************************************************/
4007 NTSTATUS _samr_EnumDomains(pipes_struct *p,
4008 struct samr_EnumDomains *r)
4011 struct samr_connect_info *info;
4012 uint32_t num_entries = 2;
4013 struct samr_SamEntry *entry_array = NULL;
4014 struct samr_SamArray *sam;
4016 info = policy_handle_find(p, r->in.connect_handle,
4017 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4018 struct samr_connect_info, &status);
4019 if (!NT_STATUS_IS_OK(status)) {
4023 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4025 return NT_STATUS_NO_MEMORY;
4028 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4029 struct samr_SamEntry,
4032 return NT_STATUS_NO_MEMORY;
4035 entry_array[0].idx = 0;
4036 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4038 entry_array[1].idx = 1;
4039 init_lsa_String(&entry_array[1].name, "Builtin");
4041 sam->count = num_entries;
4042 sam->entries = entry_array;
4045 *r->out.num_entries = num_entries;
4050 /*******************************************************************
4052 ********************************************************************/
4054 NTSTATUS _samr_OpenAlias(pipes_struct *p,
4055 struct samr_OpenAlias *r)
4058 uint32 alias_rid = r->in.rid;
4059 struct samr_alias_info *ainfo;
4060 struct samr_domain_info *dinfo;
4061 SEC_DESC *psd = NULL;
4063 uint32 des_access = r->in.access_mask;
4068 dinfo = policy_handle_find(p, r->in.domain_handle,
4069 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4070 struct samr_domain_info, &status);
4071 if (!NT_STATUS_IS_OK(status)) {
4075 /* append the alias' RID to it */
4077 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4078 return NT_STATUS_NO_SUCH_ALIAS;
4080 /*check if access can be granted as requested by client. */
4082 map_max_allowed_access(p->server_info->ptok, &des_access);
4084 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4085 se_map_generic(&des_access,&ali_generic_mapping);
4087 se_priv_copy( &se_rights, &se_add_users );
4089 status = access_check_object(psd, p->server_info->ptok,
4090 &se_rights, GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4091 des_access, &acc_granted, "_samr_OpenAlias");
4093 if ( !NT_STATUS_IS_OK(status) )
4097 /* Check we actually have the requested alias */
4098 enum lsa_SidType type;
4103 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4106 if (!result || (type != SID_NAME_ALIAS)) {
4107 return NT_STATUS_NO_SUCH_ALIAS;
4110 /* make sure there is a mapping */
4112 if ( !sid_to_gid( &sid, &gid ) ) {
4113 return NT_STATUS_NO_SUCH_ALIAS;
4118 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4119 struct samr_alias_info, &status);
4120 if (!NT_STATUS_IS_OK(status)) {
4125 return NT_STATUS_OK;
4128 /*******************************************************************
4130 ********************************************************************/
4132 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4133 struct samr_UserInfo2 *id2,
4137 DEBUG(5,("set_user_info_2: NULL id2\n"));
4138 return NT_STATUS_ACCESS_DENIED;
4141 copy_id2_to_sam_passwd(pwd, id2);
4143 return pdb_update_sam_account(pwd);
4146 /*******************************************************************
4148 ********************************************************************/
4150 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4151 struct samr_UserInfo4 *id4,
4155 DEBUG(5,("set_user_info_2: NULL id4\n"));
4156 return NT_STATUS_ACCESS_DENIED;
4159 copy_id4_to_sam_passwd(pwd, id4);
4161 return pdb_update_sam_account(pwd);
4164 /*******************************************************************
4166 ********************************************************************/
4168 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4169 struct samr_UserInfo6 *id6,
4173 DEBUG(5,("set_user_info_6: NULL id6\n"));
4174 return NT_STATUS_ACCESS_DENIED;
4177 copy_id6_to_sam_passwd(pwd, id6);
4179 return pdb_update_sam_account(pwd);
4182 /*******************************************************************
4184 ********************************************************************/
4186 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4187 struct samr_UserInfo7 *id7,
4193 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4194 return NT_STATUS_ACCESS_DENIED;
4197 if (!id7->account_name.string) {
4198 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4199 return NT_STATUS_ACCESS_DENIED;
4202 /* check to see if the new username already exists. Note: we can't
4203 reliably lock all backends, so there is potentially the
4204 possibility that a user can be created in between this check and
4205 the rename. The rename should fail, but may not get the
4206 exact same failure status code. I think this is small enough
4207 of a window for this type of operation and the results are
4208 simply that the rename fails with a slightly different status
4209 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4211 rc = can_create(mem_ctx, id7->account_name.string);
4213 /* when there is nothing to change, we're done here */
4214 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4215 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4216 return NT_STATUS_OK;
4218 if (!NT_STATUS_IS_OK(rc)) {
4222 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4227 /*******************************************************************
4229 ********************************************************************/
4231 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4232 struct samr_UserInfo8 *id8,
4236 DEBUG(5,("set_user_info_8: NULL id8\n"));
4237 return NT_STATUS_ACCESS_DENIED;
4240 copy_id8_to_sam_passwd(pwd, id8);
4242 return pdb_update_sam_account(pwd);
4245 /*******************************************************************
4247 ********************************************************************/
4249 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4250 struct samr_UserInfo10 *id10,
4254 DEBUG(5,("set_user_info_8: NULL id10\n"));
4255 return NT_STATUS_ACCESS_DENIED;
4258 copy_id10_to_sam_passwd(pwd, id10);
4260 return pdb_update_sam_account(pwd);
4263 /*******************************************************************
4265 ********************************************************************/
4267 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4268 struct samr_UserInfo11 *id11,
4272 DEBUG(5,("set_user_info_11: NULL id11\n"));
4273 return NT_STATUS_ACCESS_DENIED;
4276 copy_id11_to_sam_passwd(pwd, id11);
4278 return pdb_update_sam_account(pwd);
4281 /*******************************************************************
4283 ********************************************************************/
4285 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4286 struct samr_UserInfo12 *id12,
4290 DEBUG(5,("set_user_info_12: NULL id12\n"));
4291 return NT_STATUS_ACCESS_DENIED;
4294 copy_id12_to_sam_passwd(pwd, id12);
4296 return pdb_update_sam_account(pwd);
4299 /*******************************************************************
4301 ********************************************************************/
4303 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4304 struct samr_UserInfo13 *id13,
4308 DEBUG(5,("set_user_info_13: NULL id13\n"));
4309 return NT_STATUS_ACCESS_DENIED;
4312 copy_id13_to_sam_passwd(pwd, id13);
4314 return pdb_update_sam_account(pwd);
4317 /*******************************************************************
4319 ********************************************************************/
4321 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4322 struct samr_UserInfo14 *id14,
4326 DEBUG(5,("set_user_info_14: NULL id14\n"));
4327 return NT_STATUS_ACCESS_DENIED;
4330 copy_id14_to_sam_passwd(pwd, id14);
4332 return pdb_update_sam_account(pwd);
4335 /*******************************************************************
4337 ********************************************************************/
4339 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4340 struct samr_UserInfo16 *id16,
4344 DEBUG(5,("set_user_info_16: NULL id16\n"));
4345 return NT_STATUS_ACCESS_DENIED;
4348 copy_id16_to_sam_passwd(pwd, id16);
4350 return pdb_update_sam_account(pwd);
4353 /*******************************************************************
4355 ********************************************************************/
4357 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4358 struct samr_UserInfo17 *id17,
4362 DEBUG(5,("set_user_info_17: NULL id17\n"));
4363 return NT_STATUS_ACCESS_DENIED;
4366 copy_id17_to_sam_passwd(pwd, id17);
4368 return pdb_update_sam_account(pwd);
4371 /*******************************************************************
4373 ********************************************************************/
4375 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4376 TALLOC_CTX *mem_ctx,
4377 DATA_BLOB *session_key,
4381 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4382 return NT_STATUS_INVALID_PARAMETER;
4385 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4386 if (!session_key->length) {
4387 return NT_STATUS_NO_USER_SESSION_KEY;
4391 if (id18->nt_pwd_active) {
4395 in = data_blob_const(id18->nt_pwd.hash, 16);
4396 out = data_blob_talloc_zero(mem_ctx, 16);
4398 sess_crypt_blob(&out, &in, session_key, false);
4400 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4401 return NT_STATUS_ACCESS_DENIED;
4404 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4407 if (id18->lm_pwd_active) {
4411 in = data_blob_const(id18->lm_pwd.hash, 16);
4412 out = data_blob_talloc_zero(mem_ctx, 16);
4414 sess_crypt_blob(&out, &in, session_key, false);
4416 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4417 return NT_STATUS_ACCESS_DENIED;
4420 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4423 copy_id18_to_sam_passwd(pwd, id18);
4425 return pdb_update_sam_account(pwd);
4428 /*******************************************************************
4430 ********************************************************************/
4432 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4433 struct samr_UserInfo20 *id20,
4437 DEBUG(5,("set_user_info_20: NULL id20\n"));
4438 return NT_STATUS_ACCESS_DENIED;
4441 copy_id20_to_sam_passwd(pwd, id20);
4443 return pdb_update_sam_account(pwd);
4446 /*******************************************************************
4448 ********************************************************************/
4450 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4451 TALLOC_CTX *mem_ctx,
4452 DATA_BLOB *session_key,
4458 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4459 return NT_STATUS_INVALID_PARAMETER;
4462 if (id21->fields_present == 0) {
4463 return NT_STATUS_INVALID_PARAMETER;
4466 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4467 return NT_STATUS_ACCESS_DENIED;
4470 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4471 if (id21->nt_password_set) {
4474 if ((id21->nt_owf_password.length != 16) ||
4475 (id21->nt_owf_password.size != 16)) {
4476 return NT_STATUS_INVALID_PARAMETER;
4479 if (!session_key->length) {
4480 return NT_STATUS_NO_USER_SESSION_KEY;
4483 in = data_blob_const(id21->nt_owf_password.array, 16);
4484 out = data_blob_talloc_zero(mem_ctx, 16);
4486 sess_crypt_blob(&out, &in, session_key, false);
4488 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4489 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4493 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4494 if (id21->lm_password_set) {
4497 if ((id21->lm_owf_password.length != 16) ||
4498 (id21->lm_owf_password.size != 16)) {
4499 return NT_STATUS_INVALID_PARAMETER;
4502 if (!session_key->length) {
4503 return NT_STATUS_NO_USER_SESSION_KEY;
4506 in = data_blob_const(id21->lm_owf_password.array, 16);
4507 out = data_blob_talloc_zero(mem_ctx, 16);
4509 sess_crypt_blob(&out, &in, session_key, false);
4511 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4512 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4516 /* we need to separately check for an account rename first */
4518 if (id21->account_name.string &&
4519 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4522 /* check to see if the new username already exists. Note: we can't
4523 reliably lock all backends, so there is potentially the
4524 possibility that a user can be created in between this check and
4525 the rename. The rename should fail, but may not get the
4526 exact same failure status code. I think this is small enough
4527 of a window for this type of operation and the results are
4528 simply that the rename fails with a slightly different status
4529 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4531 status = can_create(mem_ctx, id21->account_name.string);
4532 if (!NT_STATUS_IS_OK(status)) {
4536 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4538 if (!NT_STATUS_IS_OK(status)) {
4539 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4540 nt_errstr(status)));
4544 /* set the new username so that later
4545 functions can work on the new account */
4546 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4549 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4552 * The funny part about the previous two calls is
4553 * that pwd still has the password hashes from the
4554 * passdb entry. These have not been updated from
4555 * id21. I don't know if they need to be set. --jerry
4558 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4559 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4560 if ( !NT_STATUS_IS_OK(status) ) {
4565 /* Don't worry about writing out the user account since the
4566 primary group SID is generated solely from the user's Unix
4569 /* write the change out */
4570 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4574 return NT_STATUS_OK;
4577 /*******************************************************************
4579 ********************************************************************/
4581 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4582 struct samr_UserInfo23 *id23,
4585 char *plaintext_buf = NULL;
4591 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4592 return NT_STATUS_INVALID_PARAMETER;
4595 if (id23->info.fields_present == 0) {
4596 return NT_STATUS_INVALID_PARAMETER;
4599 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4600 return NT_STATUS_ACCESS_DENIED;
4603 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4604 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4606 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4607 pdb_get_username(pwd)));
4609 if (!decode_pw_buffer(mem_ctx,
4610 id23->password.data,
4614 return NT_STATUS_WRONG_PASSWORD;
4617 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4618 return NT_STATUS_ACCESS_DENIED;
4622 copy_id23_to_sam_passwd(pwd, id23);
4624 acct_ctrl = pdb_get_acct_ctrl(pwd);
4626 /* if it's a trust account, don't update /etc/passwd */
4627 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4628 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4629 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4630 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4631 } else if (plaintext_buf) {
4632 /* update the UNIX password */
4633 if (lp_unix_password_sync() ) {
4634 struct passwd *passwd;
4635 if (pdb_get_username(pwd) == NULL) {
4636 DEBUG(1, ("chgpasswd: User without name???\n"));
4637 return NT_STATUS_ACCESS_DENIED;
4640 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4641 if (passwd == NULL) {
4642 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4645 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4646 return NT_STATUS_ACCESS_DENIED;
4648 TALLOC_FREE(passwd);
4652 if (plaintext_buf) {
4653 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4656 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4657 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4662 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4666 return NT_STATUS_OK;
4669 /*******************************************************************
4671 ********************************************************************/
4673 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4676 char *plaintext_buf = NULL;
4679 DEBUG(5, ("Attempting administrator password change for user %s\n",
4680 pdb_get_username(pwd)));
4682 acct_ctrl = pdb_get_acct_ctrl(pwd);
4684 if (!decode_pw_buffer(talloc_tos(),
4692 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4696 /* if it's a trust account, don't update /etc/passwd */
4697 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4698 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4699 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4700 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4702 /* update the UNIX password */
4703 if (lp_unix_password_sync()) {
4704 struct passwd *passwd;
4706 if (pdb_get_username(pwd) == NULL) {
4707 DEBUG(1, ("chgpasswd: User without name???\n"));
4711 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4712 if (passwd == NULL) {
4713 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4716 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4719 TALLOC_FREE(passwd);
4723 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4725 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4730 /*******************************************************************
4732 ********************************************************************/
4734 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4735 struct samr_UserInfo24 *id24,
4741 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4742 return NT_STATUS_INVALID_PARAMETER;
4745 if (!set_user_info_pw(id24->password.data, pwd)) {
4746 return NT_STATUS_WRONG_PASSWORD;
4749 copy_id24_to_sam_passwd(pwd, id24);
4751 status = pdb_update_sam_account(pwd);
4752 if (!NT_STATUS_IS_OK(status)) {
4756 return NT_STATUS_OK;
4759 /*******************************************************************
4761 ********************************************************************/
4763 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4764 struct samr_UserInfo25 *id25,
4770 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4771 return NT_STATUS_INVALID_PARAMETER;
4774 if (id25->info.fields_present == 0) {
4775 return NT_STATUS_INVALID_PARAMETER;
4778 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4779 return NT_STATUS_ACCESS_DENIED;
4782 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4783 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4785 if (!set_user_info_pw(id25->password.data, pwd)) {
4786 return NT_STATUS_WRONG_PASSWORD;
4790 copy_id25_to_sam_passwd(pwd, id25);
4792 /* write the change out */
4793 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4798 * We need to "pdb_update_sam_account" before the unix primary group
4799 * is set, because the idealx scripts would also change the
4800 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4801 * the delete explicit / add explicit, which would then fail to find
4802 * the previous primaryGroupSid value.
4805 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4806 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4807 if ( !NT_STATUS_IS_OK(status) ) {
4812 return NT_STATUS_OK;
4815 /*******************************************************************
4817 ********************************************************************/
4819 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4820 struct samr_UserInfo26 *id26,
4826 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4827 return NT_STATUS_INVALID_PARAMETER;
4830 if (!set_user_info_pw(id26->password.data, pwd)) {
4831 return NT_STATUS_WRONG_PASSWORD;
4834 copy_id26_to_sam_passwd(pwd, id26);
4836 status = pdb_update_sam_account(pwd);
4837 if (!NT_STATUS_IS_OK(status)) {
4841 return NT_STATUS_OK;
4844 /*************************************************************
4845 **************************************************************/
4847 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4849 uint32_t acc_required = 0;
4851 /* USER_ALL_USERNAME */
4852 if (fields & SAMR_FIELD_ACCOUNT_NAME)
4853 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4854 /* USER_ALL_FULLNAME */
4855 if (fields & SAMR_FIELD_FULL_NAME)
4856 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4857 /* USER_ALL_PRIMARYGROUPID */
4858 if (fields & SAMR_FIELD_PRIMARY_GID)
4859 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4860 /* USER_ALL_HOMEDIRECTORY */
4861 if (fields & SAMR_FIELD_HOME_DIRECTORY)
4862 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4863 /* USER_ALL_HOMEDIRECTORYDRIVE */
4864 if (fields & SAMR_FIELD_HOME_DRIVE)
4865 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4866 /* USER_ALL_SCRIPTPATH */
4867 if (fields & SAMR_FIELD_LOGON_SCRIPT)
4868 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4869 /* USER_ALL_PROFILEPATH */
4870 if (fields & SAMR_FIELD_PROFILE_PATH)
4871 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4872 /* USER_ALL_ADMINCOMMENT */
4873 if (fields & SAMR_FIELD_COMMENT)
4874 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4875 /* USER_ALL_WORKSTATIONS */
4876 if (fields & SAMR_FIELD_WORKSTATIONS)
4877 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4878 /* USER_ALL_LOGONHOURS */
4879 if (fields & SAMR_FIELD_LOGON_HOURS)
4880 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4881 /* USER_ALL_ACCOUNTEXPIRES */
4882 if (fields & SAMR_FIELD_ACCT_EXPIRY)
4883 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4884 /* USER_ALL_USERACCOUNTCONTROL */
4885 if (fields & SAMR_FIELD_ACCT_FLAGS)
4886 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4887 /* USER_ALL_PARAMETERS */
4888 if (fields & SAMR_FIELD_PARAMETERS)
4889 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4890 /* USER_ALL_USERCOMMENT */
4891 if (fields & SAMR_FIELD_COMMENT)
4892 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4893 /* USER_ALL_COUNTRYCODE */
4894 if (fields & SAMR_FIELD_COUNTRY_CODE)
4895 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4896 /* USER_ALL_CODEPAGE */
4897 if (fields & SAMR_FIELD_CODE_PAGE)
4898 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4899 /* USER_ALL_NTPASSWORDPRESENT */
4900 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
4901 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4902 /* USER_ALL_LMPASSWORDPRESENT */
4903 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
4904 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4905 /* USER_ALL_PASSWORDEXPIRED */
4906 if (fields & SAMR_FIELD_EXPIRED_FLAG)
4907 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4909 return acc_required;
4912 /*******************************************************************
4914 ********************************************************************/
4916 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4917 struct samr_SetUserInfo *r)
4919 struct samr_user_info *uinfo;
4921 struct samu *pwd = NULL;
4922 union samr_UserInfo *info = r->in.info;
4923 uint32_t acc_required = 0;
4924 uint32_t fields = 0;
4927 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4929 /* This is tricky. A WinXP domain join sets
4930 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4931 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4932 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4933 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4934 we'll use the set from the WinXP join as the basis. */
4936 switch (r->in.level) {
4937 case 2: /* UserPreferencesInformation */
4938 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
4939 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
4941 case 4: /* UserLogonHoursInformation */
4942 case 6: /* UserNameInformation */
4943 case 7: /* UserAccountNameInformation */
4944 case 8: /* UserFullNameInformation */
4945 case 9: /* UserPrimaryGroupInformation */
4946 case 10: /* UserHomeInformation */
4947 case 11: /* UserScriptInformation */
4948 case 12: /* UserProfileInformation */
4949 case 13: /* UserAdminCommentInformation */
4950 case 14: /* UserWorkStationsInformation */
4951 case 16: /* UserControlInformation */
4952 case 17: /* UserExpiresInformation */
4953 case 20: /* UserParametersInformation */
4954 /* USER_WRITE_ACCOUNT */
4955 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
4957 case 18: /* UserInternal1Information */
4958 /* FIXME: gd, this is a guess */
4959 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4961 case 21: /* UserAllInformation */
4962 fields = info->info21.fields_present;
4963 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4965 case 23: /* UserInternal4Information */
4966 fields = info->info23.info.fields_present;
4967 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4969 case 25: /* UserInternal4InformationNew */
4970 fields = info->info25.info.fields_present;
4971 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4973 case 24: /* UserInternal5Information */
4974 case 26: /* UserInternal5InformationNew */
4975 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4978 return NT_STATUS_INVALID_INFO_CLASS;
4981 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
4982 struct samr_user_info, &status);
4983 if (!NT_STATUS_IS_OK(status)) {
4987 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4988 sid_string_dbg(&uinfo->sid), r->in.level));
4991 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4992 return NT_STATUS_INVALID_INFO_CLASS;
4995 if (!(pwd = samu_new(NULL))) {
4996 return NT_STATUS_NO_MEMORY;
5000 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5005 return NT_STATUS_NO_SUCH_USER;
5008 /* ================ BEGIN Privilege BLOCK ================ */
5012 /* ok! user info levels (lots: see MSDEV help), off we go... */
5014 switch (r->in.level) {
5017 status = set_user_info_2(p->mem_ctx,
5022 status = set_user_info_4(p->mem_ctx,
5027 status = set_user_info_6(p->mem_ctx,
5032 status = set_user_info_7(p->mem_ctx,
5037 status = set_user_info_8(p->mem_ctx,
5042 status = set_user_info_10(p->mem_ctx,
5043 &info->info10, pwd);
5047 status = set_user_info_11(p->mem_ctx,
5048 &info->info11, pwd);
5052 status = set_user_info_12(p->mem_ctx,
5053 &info->info12, pwd);
5057 status = set_user_info_13(p->mem_ctx,
5058 &info->info13, pwd);
5062 status = set_user_info_14(p->mem_ctx,
5063 &info->info14, pwd);
5067 status = set_user_info_16(p->mem_ctx,
5068 &info->info16, pwd);
5072 status = set_user_info_17(p->mem_ctx,
5073 &info->info17, pwd);
5077 /* Used by AS/U JRA. */
5078 status = set_user_info_18(&info->info18,
5080 &p->server_info->user_session_key,
5085 status = set_user_info_20(p->mem_ctx,
5086 &info->info20, pwd);
5090 status = set_user_info_21(&info->info21,
5092 &p->server_info->user_session_key,
5097 if (!p->server_info->user_session_key.length) {
5098 status = NT_STATUS_NO_USER_SESSION_KEY;
5100 arcfour_crypt_blob(info->info23.password.data, 516,
5101 &p->server_info->user_session_key);
5103 dump_data(100, info->info23.password.data, 516);
5105 status = set_user_info_23(p->mem_ctx,
5106 &info->info23, pwd);
5110 if (!p->server_info->user_session_key.length) {
5111 status = NT_STATUS_NO_USER_SESSION_KEY;
5113 arcfour_crypt_blob(info->info24.password.data,
5115 &p->server_info->user_session_key);
5117 dump_data(100, info->info24.password.data, 516);
5119 status = set_user_info_24(p->mem_ctx,
5120 &info->info24, pwd);
5124 if (!p->server_info->user_session_key.length) {
5125 status = NT_STATUS_NO_USER_SESSION_KEY;
5127 encode_or_decode_arc4_passwd_buffer(
5128 info->info25.password.data,
5129 &p->server_info->user_session_key);
5131 dump_data(100, info->info25.password.data, 532);
5133 status = set_user_info_25(p->mem_ctx,
5134 &info->info25, pwd);
5138 if (!p->server_info->user_session_key.length) {
5139 status = NT_STATUS_NO_USER_SESSION_KEY;
5141 encode_or_decode_arc4_passwd_buffer(
5142 info->info26.password.data,
5143 &p->server_info->user_session_key);
5145 dump_data(100, info->info26.password.data, 516);
5147 status = set_user_info_26(p->mem_ctx,
5148 &info->info26, pwd);
5152 status = NT_STATUS_INVALID_INFO_CLASS;
5159 /* ================ END Privilege BLOCK ================ */
5161 if (NT_STATUS_IS_OK(status)) {
5162 force_flush_samr_cache(&uinfo->sid);
5168 /*******************************************************************
5170 ********************************************************************/
5172 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
5173 struct samr_SetUserInfo2 *r)
5175 struct samr_SetUserInfo q;
5177 q.in.user_handle = r->in.user_handle;
5178 q.in.level = r->in.level;
5179 q.in.info = r->in.info;
5181 return _samr_SetUserInfo(p, &q);
5184 /*********************************************************************
5185 _samr_GetAliasMembership
5186 *********************************************************************/
5188 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
5189 struct samr_GetAliasMembership *r)
5191 size_t num_alias_rids;
5193 struct samr_domain_info *dinfo;
5200 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5202 dinfo = policy_handle_find(p, r->in.domain_handle,
5203 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5204 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5205 struct samr_domain_info, &status);
5206 if (!NT_STATUS_IS_OK(status)) {
5210 if (!sid_check_is_domain(&dinfo->sid) &&
5211 !sid_check_is_builtin(&dinfo->sid))
5212 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5214 if (r->in.sids->num_sids) {
5215 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
5217 if (members == NULL)
5218 return NT_STATUS_NO_MEMORY;
5223 for (i=0; i<r->in.sids->num_sids; i++)
5224 sid_copy(&members[i], r->in.sids->sids[i].sid);
5230 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5231 r->in.sids->num_sids,
5232 &alias_rids, &num_alias_rids);
5235 if (!NT_STATUS_IS_OK(status)) {
5239 r->out.rids->count = num_alias_rids;
5240 r->out.rids->ids = alias_rids;
5242 return NT_STATUS_OK;
5245 /*********************************************************************
5246 _samr_GetMembersInAlias
5247 *********************************************************************/
5249 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5250 struct samr_GetMembersInAlias *r)
5252 struct samr_alias_info *ainfo;
5255 size_t num_sids = 0;
5256 struct lsa_SidPtr *sids = NULL;
5257 DOM_SID *pdb_sids = NULL;
5259 ainfo = policy_handle_find(p, r->in.alias_handle,
5260 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5261 struct samr_alias_info, &status);
5262 if (!NT_STATUS_IS_OK(status)) {
5266 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5269 status = pdb_enum_aliasmem(&ainfo->sid, &pdb_sids, &num_sids);
5272 if (!NT_STATUS_IS_OK(status)) {
5277 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5279 TALLOC_FREE(pdb_sids);
5280 return NT_STATUS_NO_MEMORY;
5284 for (i = 0; i < num_sids; i++) {
5285 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5287 TALLOC_FREE(pdb_sids);
5288 return NT_STATUS_NO_MEMORY;
5292 r->out.sids->num_sids = num_sids;
5293 r->out.sids->sids = sids;
5295 TALLOC_FREE(pdb_sids);
5297 return NT_STATUS_OK;
5300 /*********************************************************************
5301 _samr_QueryGroupMember
5302 *********************************************************************/
5304 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5305 struct samr_QueryGroupMember *r)
5307 struct samr_group_info *ginfo;
5308 size_t i, num_members;
5314 struct samr_RidTypeArray *rids = NULL;
5316 ginfo = policy_handle_find(p, r->in.group_handle,
5317 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5318 struct samr_group_info, &status);
5319 if (!NT_STATUS_IS_OK(status)) {
5323 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5325 return NT_STATUS_NO_MEMORY;
5328 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5330 if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5331 DEBUG(3, ("sid %s is not in our domain\n",
5332 sid_string_dbg(&ginfo->sid)));
5333 return NT_STATUS_NO_SUCH_GROUP;
5336 DEBUG(10, ("lookup on Domain SID\n"));
5339 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5340 &rid, &num_members);
5343 if (!NT_STATUS_IS_OK(status))
5347 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5349 return NT_STATUS_NO_MEMORY;
5355 for (i=0; i<num_members; i++)
5356 attr[i] = SID_NAME_USER;
5358 rids->count = num_members;
5362 *r->out.rids = rids;
5364 return NT_STATUS_OK;
5367 /*********************************************************************
5368 _samr_AddAliasMember
5369 *********************************************************************/
5371 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5372 struct samr_AddAliasMember *r)
5374 struct samr_alias_info *ainfo;
5377 ainfo = policy_handle_find(p, r->in.alias_handle,
5378 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5379 struct samr_alias_info, &status);
5380 if (!NT_STATUS_IS_OK(status)) {
5384 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5386 /******** BEGIN SeAddUsers BLOCK *********/
5389 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5392 /******** END SeAddUsers BLOCK *********/
5394 if (NT_STATUS_IS_OK(status)) {
5395 force_flush_samr_cache(&ainfo->sid);
5401 /*********************************************************************
5402 _samr_DeleteAliasMember
5403 *********************************************************************/
5405 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5406 struct samr_DeleteAliasMember *r)
5408 struct samr_alias_info *ainfo;
5411 ainfo = policy_handle_find(p, r->in.alias_handle,
5412 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5413 struct samr_alias_info, &status);
5414 if (!NT_STATUS_IS_OK(status)) {
5418 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5419 sid_string_dbg(&ainfo->sid)));
5421 /******** BEGIN SeAddUsers BLOCK *********/
5424 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5427 /******** END SeAddUsers BLOCK *********/
5429 if (NT_STATUS_IS_OK(status)) {
5430 force_flush_samr_cache(&ainfo->sid);
5436 /*********************************************************************
5437 _samr_AddGroupMember
5438 *********************************************************************/
5440 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5441 struct samr_AddGroupMember *r)
5443 struct samr_group_info *ginfo;
5447 ginfo = policy_handle_find(p, r->in.group_handle,
5448 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5449 struct samr_group_info, &status);
5450 if (!NT_STATUS_IS_OK(status)) {
5454 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5456 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5458 return NT_STATUS_INVALID_HANDLE;
5461 /******** BEGIN SeAddUsers BLOCK *********/
5464 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5467 /******** END SeAddUsers BLOCK *********/
5469 force_flush_samr_cache(&ginfo->sid);
5474 /*********************************************************************
5475 _samr_DeleteGroupMember
5476 *********************************************************************/
5478 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5479 struct samr_DeleteGroupMember *r)
5482 struct samr_group_info *ginfo;
5487 * delete the group member named r->in.rid
5488 * who is a member of the sid associated with the handle
5489 * the rid is a user's rid as the group is a domain group.
5492 ginfo = policy_handle_find(p, r->in.group_handle,
5493 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5494 struct samr_group_info, &status);
5495 if (!NT_STATUS_IS_OK(status)) {
5499 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5501 return NT_STATUS_INVALID_HANDLE;
5504 /******** BEGIN SeAddUsers BLOCK *********/
5507 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5510 /******** END SeAddUsers BLOCK *********/
5512 force_flush_samr_cache(&ginfo->sid);
5517 /*********************************************************************
5519 *********************************************************************/
5521 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5522 struct samr_DeleteUser *r)
5524 struct samr_user_info *uinfo;
5526 struct samu *sam_pass=NULL;
5529 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5531 uinfo = policy_handle_find(p, r->in.user_handle,
5532 STD_RIGHT_DELETE_ACCESS, NULL,
5533 struct samr_user_info, &status);
5534 if (!NT_STATUS_IS_OK(status)) {
5538 if (!sid_check_is_in_our_domain(&uinfo->sid))
5539 return NT_STATUS_CANNOT_DELETE;
5541 /* check if the user exists before trying to delete */
5542 if ( !(sam_pass = samu_new( NULL )) ) {
5543 return NT_STATUS_NO_MEMORY;
5547 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5551 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5552 sid_string_dbg(&uinfo->sid)));
5553 TALLOC_FREE(sam_pass);
5554 return NT_STATUS_NO_SUCH_USER;
5557 /******** BEGIN SeAddUsers BLOCK *********/
5560 status = pdb_delete_user(p->mem_ctx, sam_pass);
5563 /******** END SeAddUsers BLOCK *********/
5565 if ( !NT_STATUS_IS_OK(status) ) {
5566 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5567 "user %s: %s.\n", pdb_get_username(sam_pass),
5568 nt_errstr(status)));
5569 TALLOC_FREE(sam_pass);
5574 TALLOC_FREE(sam_pass);
5576 if (!close_policy_hnd(p, r->in.user_handle))
5577 return NT_STATUS_OBJECT_NAME_INVALID;
5579 ZERO_STRUCTP(r->out.user_handle);
5581 force_flush_samr_cache(&uinfo->sid);
5583 return NT_STATUS_OK;
5586 /*********************************************************************
5587 _samr_DeleteDomainGroup
5588 *********************************************************************/
5590 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5591 struct samr_DeleteDomainGroup *r)
5593 struct samr_group_info *ginfo;
5597 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5599 ginfo = policy_handle_find(p, r->in.group_handle,
5600 STD_RIGHT_DELETE_ACCESS, NULL,
5601 struct samr_group_info, &status);
5602 if (!NT_STATUS_IS_OK(status)) {
5606 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5608 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5610 return NT_STATUS_NO_SUCH_GROUP;
5613 /******** BEGIN SeAddUsers BLOCK *********/
5616 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5619 /******** END SeAddUsers BLOCK *********/
5621 if ( !NT_STATUS_IS_OK(status) ) {
5622 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5623 "entry for group %s: %s\n",
5624 sid_string_dbg(&ginfo->sid),
5625 nt_errstr(status)));
5629 if (!close_policy_hnd(p, r->in.group_handle))
5630 return NT_STATUS_OBJECT_NAME_INVALID;
5632 force_flush_samr_cache(&ginfo->sid);
5634 return NT_STATUS_OK;
5637 /*********************************************************************
5638 _samr_DeleteDomAlias
5639 *********************************************************************/
5641 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5642 struct samr_DeleteDomAlias *r)
5644 struct samr_alias_info *ainfo;
5647 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5649 ainfo = policy_handle_find(p, r->in.alias_handle,
5650 STD_RIGHT_DELETE_ACCESS, NULL,
5651 struct samr_alias_info, &status);
5652 if (!NT_STATUS_IS_OK(status)) {
5656 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5658 /* Don't let Windows delete builtin groups */
5660 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5661 return NT_STATUS_SPECIAL_ACCOUNT;
5664 if (!sid_check_is_in_our_domain(&ainfo->sid))
5665 return NT_STATUS_NO_SUCH_ALIAS;
5667 DEBUG(10, ("lookup on Local SID\n"));
5669 /******** BEGIN SeAddUsers BLOCK *********/
5672 /* Have passdb delete the alias */
5673 status = pdb_delete_alias(&ainfo->sid);
5676 /******** END SeAddUsers BLOCK *********/
5678 if ( !NT_STATUS_IS_OK(status))
5681 if (!close_policy_hnd(p, r->in.alias_handle))
5682 return NT_STATUS_OBJECT_NAME_INVALID;
5684 force_flush_samr_cache(&ainfo->sid);
5686 return NT_STATUS_OK;
5689 /*********************************************************************
5690 _samr_CreateDomainGroup
5691 *********************************************************************/
5693 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5694 struct samr_CreateDomainGroup *r)
5699 struct samr_domain_info *dinfo;
5700 struct samr_group_info *ginfo;
5702 dinfo = policy_handle_find(p, r->in.domain_handle,
5703 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5704 struct samr_domain_info, &status);
5705 if (!NT_STATUS_IS_OK(status)) {
5709 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5710 return NT_STATUS_ACCESS_DENIED;
5712 name = r->in.name->string;
5714 return NT_STATUS_NO_MEMORY;
5717 status = can_create(p->mem_ctx, name);
5718 if (!NT_STATUS_IS_OK(status)) {
5722 /******** BEGIN SeAddUsers BLOCK *********/
5725 /* check that we successfully create the UNIX group */
5726 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5729 /******** END SeAddUsers BLOCK *********/
5731 /* check if we should bail out here */
5733 if ( !NT_STATUS_IS_OK(status) )
5736 ginfo = policy_handle_create(p, r->out.group_handle,
5737 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5738 struct samr_group_info, &status);
5739 if (!NT_STATUS_IS_OK(status)) {
5742 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5744 force_flush_samr_cache(&dinfo->sid);
5746 return NT_STATUS_OK;
5749 /*********************************************************************
5750 _samr_CreateDomAlias
5751 *********************************************************************/
5753 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5754 struct samr_CreateDomAlias *r)
5757 const char *name = NULL;
5758 struct samr_domain_info *dinfo;
5759 struct samr_alias_info *ainfo;
5763 dinfo = policy_handle_find(p, r->in.domain_handle,
5764 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5765 struct samr_domain_info, &result);
5766 if (!NT_STATUS_IS_OK(result)) {
5770 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5771 return NT_STATUS_ACCESS_DENIED;
5773 name = r->in.alias_name->string;
5775 result = can_create(p->mem_ctx, name);
5776 if (!NT_STATUS_IS_OK(result)) {
5780 /******** BEGIN SeAddUsers BLOCK *********/
5783 /* Have passdb create the alias */
5784 result = pdb_create_alias(name, r->out.rid);
5787 /******** END SeAddUsers BLOCK *********/
5789 if (!NT_STATUS_IS_OK(result)) {
5790 DEBUG(10, ("pdb_create_alias failed: %s\n",
5791 nt_errstr(result)));
5795 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5797 if (!sid_to_gid(&info_sid, &gid)) {
5798 DEBUG(10, ("Could not find alias just created\n"));
5799 return NT_STATUS_ACCESS_DENIED;
5802 /* check if the group has been successfully created */
5803 if ( getgrgid(gid) == NULL ) {
5804 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5805 (unsigned int)gid));
5806 return NT_STATUS_ACCESS_DENIED;
5809 ainfo = policy_handle_create(p, r->out.alias_handle,
5810 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5811 struct samr_alias_info, &result);
5812 if (!NT_STATUS_IS_OK(result)) {
5815 ainfo->sid = info_sid;
5817 force_flush_samr_cache(&info_sid);
5819 return NT_STATUS_OK;
5822 /*********************************************************************
5823 _samr_QueryGroupInfo
5824 *********************************************************************/
5826 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5827 struct samr_QueryGroupInfo *r)
5829 struct samr_group_info *ginfo;
5832 union samr_GroupInfo *info = NULL;
5834 uint32_t attributes = SE_GROUP_MANDATORY |
5835 SE_GROUP_ENABLED_BY_DEFAULT |
5837 const char *group_name = NULL;
5838 const char *group_description = NULL;
5840 ginfo = policy_handle_find(p, r->in.group_handle,
5841 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5842 struct samr_group_info, &status);
5843 if (!NT_STATUS_IS_OK(status)) {
5848 ret = get_domain_group_from_sid(ginfo->sid, &map);
5851 return NT_STATUS_INVALID_HANDLE;
5853 /* FIXME: map contains fstrings */
5854 group_name = talloc_strdup(r, map.nt_name);
5855 group_description = talloc_strdup(r, map.comment);
5857 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5859 return NT_STATUS_NO_MEMORY;
5862 switch (r->in.level) {
5868 status = pdb_enum_group_members(
5869 p->mem_ctx, &ginfo->sid, &members,
5873 if (!NT_STATUS_IS_OK(status)) {
5877 info->all.name.string = group_name;
5878 info->all.attributes = attributes;
5879 info->all.num_members = num_members;
5880 info->all.description.string = group_description;
5884 info->name.string = group_name;
5887 info->attributes.attributes = attributes;
5890 info->description.string = group_description;
5900 status = pdb_enum_group_members(
5901 p->mem_ctx, &ginfo->sid, &members,
5905 if (!NT_STATUS_IS_OK(status)) {
5909 info->all2.name.string = group_name;
5910 info->all2.attributes = attributes;
5911 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5912 info->all2.description.string = group_description;
5917 return NT_STATUS_INVALID_INFO_CLASS;
5920 *r->out.info = info;
5922 return NT_STATUS_OK;
5925 /*********************************************************************
5927 *********************************************************************/
5929 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5930 struct samr_SetGroupInfo *r)
5932 struct samr_group_info *ginfo;
5937 ginfo = policy_handle_find(p, r->in.group_handle,
5938 SAMR_GROUP_ACCESS_SET_INFO, NULL,
5939 struct samr_group_info, &status);
5940 if (!NT_STATUS_IS_OK(status)) {
5945 ret = get_domain_group_from_sid(ginfo->sid, &map);
5948 return NT_STATUS_NO_SUCH_GROUP;
5950 switch (r->in.level) {
5952 fstrcpy(map.comment, r->in.info->all.description.string);
5955 /* group rename is not supported yet */
5956 return NT_STATUS_NOT_SUPPORTED;
5958 fstrcpy(map.comment, r->in.info->description.string);
5961 return NT_STATUS_INVALID_INFO_CLASS;
5964 /******** BEGIN SeAddUsers BLOCK *********/
5967 status = pdb_update_group_mapping_entry(&map);
5970 /******** End SeAddUsers BLOCK *********/
5972 if (NT_STATUS_IS_OK(status)) {
5973 force_flush_samr_cache(&ginfo->sid);
5979 /*********************************************************************
5981 *********************************************************************/
5983 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5984 struct samr_SetAliasInfo *r)
5986 struct samr_alias_info *ainfo;
5987 struct acct_info info;
5990 ainfo = policy_handle_find(p, r->in.alias_handle,
5991 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
5992 struct samr_alias_info, &status);
5993 if (!NT_STATUS_IS_OK(status)) {
5997 /* get the current group information */
6000 status = pdb_get_aliasinfo( &ainfo->sid, &info );
6003 if ( !NT_STATUS_IS_OK(status))
6006 switch (r->in.level) {
6011 /* We currently do not support renaming groups in the
6012 the BUILTIN domain. Refer to util_builtin.c to understand
6013 why. The eventually needs to be fixed to be like Windows
6014 where you can rename builtin groups, just not delete them */
6016 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6017 return NT_STATUS_SPECIAL_ACCOUNT;
6020 /* There has to be a valid name (and it has to be different) */
6022 if ( !r->in.info->name.string )
6023 return NT_STATUS_INVALID_PARAMETER;
6025 /* If the name is the same just reply "ok". Yes this
6026 doesn't allow you to change the case of a group name. */
6028 if ( strequal( r->in.info->name.string, info.acct_name ) )
6029 return NT_STATUS_OK;
6031 fstrcpy( info.acct_name, r->in.info->name.string);
6033 /* make sure the name doesn't already exist as a user
6036 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6037 status = can_create( p->mem_ctx, group_name );
6038 if ( !NT_STATUS_IS_OK( status ) )
6042 case ALIASINFODESCRIPTION:
6043 if (r->in.info->description.string) {
6044 fstrcpy(info.acct_desc,
6045 r->in.info->description.string);
6047 fstrcpy( info.acct_desc, "" );
6051 return NT_STATUS_INVALID_INFO_CLASS;
6054 /******** BEGIN SeAddUsers BLOCK *********/
6057 status = pdb_set_aliasinfo( &ainfo->sid, &info );
6060 /******** End SeAddUsers BLOCK *********/
6062 if (NT_STATUS_IS_OK(status))
6063 force_flush_samr_cache(&ainfo->sid);
6068 /****************************************************************
6070 ****************************************************************/
6072 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
6073 struct samr_GetDomPwInfo *r)
6075 uint32_t min_password_length = 0;
6076 uint32_t password_properties = 0;
6078 /* Perform access check. Since this rpc does not require a
6079 policy handle it will not be caught by the access checks on
6080 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6082 if (!pipe_access_check(p)) {
6083 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6084 return NT_STATUS_ACCESS_DENIED;
6088 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
6089 &min_password_length);
6090 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
6091 &password_properties);
6094 if (lp_check_password_script() && *lp_check_password_script()) {
6095 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6098 r->out.info->min_password_length = min_password_length;
6099 r->out.info->password_properties = password_properties;
6101 return NT_STATUS_OK;
6104 /*********************************************************************
6106 *********************************************************************/
6108 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6109 struct samr_OpenGroup *r)
6114 struct samr_domain_info *dinfo;
6115 struct samr_group_info *ginfo;
6116 SEC_DESC *psd = NULL;
6118 uint32 des_access = r->in.access_mask;
6124 dinfo = policy_handle_find(p, r->in.domain_handle,
6125 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6126 struct samr_domain_info, &status);
6127 if (!NT_STATUS_IS_OK(status)) {
6131 /*check if access can be granted as requested by client. */
6132 map_max_allowed_access(p->server_info->ptok, &des_access);
6134 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6135 se_map_generic(&des_access,&grp_generic_mapping);
6137 se_priv_copy( &se_rights, &se_add_users );
6139 status = access_check_object(psd, p->server_info->ptok,
6140 &se_rights, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6141 des_access, &acc_granted, "_samr_OpenGroup");
6143 if ( !NT_STATUS_IS_OK(status) )
6146 /* this should not be hard-coded like this */
6148 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
6149 return NT_STATUS_ACCESS_DENIED;
6151 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6153 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6154 sid_string_dbg(&info_sid)));
6156 /* check if that group really exists */
6158 ret = get_domain_group_from_sid(info_sid, &map);
6161 return NT_STATUS_NO_SUCH_GROUP;
6163 ginfo = policy_handle_create(p, r->out.group_handle,
6165 struct samr_group_info, &status);
6166 if (!NT_STATUS_IS_OK(status)) {
6169 ginfo->sid = info_sid;
6171 return NT_STATUS_OK;
6174 /*********************************************************************
6175 _samr_RemoveMemberFromForeignDomain
6176 *********************************************************************/
6178 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6179 struct samr_RemoveMemberFromForeignDomain *r)
6181 struct samr_domain_info *dinfo;
6184 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6185 sid_string_dbg(r->in.sid)));
6187 /* Find the policy handle. Open a policy on it. */
6189 dinfo = policy_handle_find(p, r->in.domain_handle,
6190 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6191 struct samr_domain_info, &result);
6192 if (!NT_STATUS_IS_OK(result)) {
6196 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6197 sid_string_dbg(&dinfo->sid)));
6199 /* we can only delete a user from a group since we don't have
6200 nested groups anyways. So in the latter case, just say OK */
6202 /* TODO: The above comment nowadays is bogus. Since we have nested
6203 * groups now, and aliases members are never reported out of the unix
6204 * group membership, the "just say OK" makes this call a no-op. For
6205 * us. This needs fixing however. */
6207 /* I've only ever seen this in the wild when deleting a user from
6208 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6209 * is the user about to be deleted. I very much suspect this is the
6210 * only application of this call. To verify this, let people report
6213 if (!sid_check_is_builtin(&dinfo->sid)) {
6214 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6215 "global_sam_sid() = %s\n",
6216 sid_string_dbg(&dinfo->sid),
6217 sid_string_dbg(get_global_sam_sid())));
6218 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6219 return NT_STATUS_OK;
6222 force_flush_samr_cache(&dinfo->sid);
6224 result = NT_STATUS_OK;
6229 /*******************************************************************
6230 _samr_QueryDomainInfo2
6231 ********************************************************************/
6233 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6234 struct samr_QueryDomainInfo2 *r)
6236 struct samr_QueryDomainInfo q;
6238 q.in.domain_handle = r->in.domain_handle;
6239 q.in.level = r->in.level;
6241 q.out.info = r->out.info;
6243 return _samr_QueryDomainInfo(p, &q);
6246 /*******************************************************************
6248 ********************************************************************/
6250 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6251 struct samr_SetDomainInfo *r)
6253 struct samr_domain_info *dinfo;
6254 time_t u_expire, u_min_age;
6256 time_t u_lock_duration, u_reset_time;
6258 uint32_t acc_required = 0;
6260 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6262 switch (r->in.level) {
6263 case 1: /* DomainPasswordInformation */
6264 case 12: /* DomainLockoutInformation */
6265 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6266 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6268 case 3: /* DomainLogoffInformation */
6269 case 4: /* DomainOemInformation */
6270 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6271 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6273 case 6: /* DomainReplicationInformation */
6274 case 9: /* DomainStateInformation */
6275 case 7: /* DomainServerRoleInformation */
6276 /* DOMAIN_ADMINISTER_SERVER */
6277 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6280 return NT_STATUS_INVALID_INFO_CLASS;
6283 dinfo = policy_handle_find(p, r->in.domain_handle,
6285 struct samr_domain_info, &result);
6286 if (!NT_STATUS_IS_OK(result)) {
6290 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6292 switch (r->in.level) {
6294 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
6295 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
6296 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
6297 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
6298 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
6299 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
6300 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
6303 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
6304 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
6315 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
6316 if (u_lock_duration != -1)
6317 u_lock_duration /= 60;
6319 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
6321 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6322 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
6323 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
6326 return NT_STATUS_INVALID_INFO_CLASS;
6329 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6331 return NT_STATUS_OK;
6334 /****************************************************************
6335 _samr_GetDisplayEnumerationIndex
6336 ****************************************************************/
6338 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6339 struct samr_GetDisplayEnumerationIndex *r)
6341 struct samr_domain_info *dinfo;
6342 uint32_t max_entries = (uint32_t) -1;
6343 uint32_t enum_context = 0;
6345 uint32_t num_account = 0;
6346 struct samr_displayentry *entries = NULL;
6349 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6351 dinfo = policy_handle_find(p, r->in.domain_handle,
6352 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6353 struct samr_domain_info, &status);
6354 if (!NT_STATUS_IS_OK(status)) {
6358 if ((r->in.level < 1) || (r->in.level > 3)) {
6359 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6360 "Unknown info level (%u)\n",
6362 return NT_STATUS_INVALID_INFO_CLASS;
6367 /* The following done as ROOT. Don't return without unbecome_root(). */
6369 switch (r->in.level) {
6371 if (dinfo->disp_info->users == NULL) {
6372 dinfo->disp_info->users = pdb_search_users(
6373 dinfo->disp_info, ACB_NORMAL);
6374 if (dinfo->disp_info->users == NULL) {
6376 return NT_STATUS_ACCESS_DENIED;
6378 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6379 "starting user enumeration at index %u\n",
6380 (unsigned int)enum_context));
6382 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6383 "using cached user enumeration at index %u\n",
6384 (unsigned int)enum_context));
6386 num_account = pdb_search_entries(dinfo->disp_info->users,
6387 enum_context, max_entries,
6391 if (dinfo->disp_info->machines == NULL) {
6392 dinfo->disp_info->machines = pdb_search_users(
6393 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6394 if (dinfo->disp_info->machines == NULL) {
6396 return NT_STATUS_ACCESS_DENIED;
6398 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6399 "starting machine enumeration at index %u\n",
6400 (unsigned int)enum_context));
6402 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6403 "using cached machine enumeration at index %u\n",
6404 (unsigned int)enum_context));
6406 num_account = pdb_search_entries(dinfo->disp_info->machines,
6407 enum_context, max_entries,
6411 if (dinfo->disp_info->groups == NULL) {
6412 dinfo->disp_info->groups = pdb_search_groups(
6414 if (dinfo->disp_info->groups == NULL) {
6416 return NT_STATUS_ACCESS_DENIED;
6418 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6419 "starting group enumeration at index %u\n",
6420 (unsigned int)enum_context));
6422 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6423 "using cached group enumeration at index %u\n",
6424 (unsigned int)enum_context));
6426 num_account = pdb_search_entries(dinfo->disp_info->groups,
6427 enum_context, max_entries,
6432 smb_panic("info class changed");
6438 /* Ensure we cache this enumeration. */
6439 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6441 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6442 r->in.name->string));
6444 for (i=0; i<num_account; i++) {
6445 if (strequal(entries[i].account_name, r->in.name->string)) {
6446 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6447 "found %s at idx %d\n",
6448 r->in.name->string, i));
6450 return NT_STATUS_OK;
6454 /* assuming account_name lives at the very end */
6455 *r->out.idx = num_account;
6457 return NT_STATUS_NO_MORE_ENTRIES;
6460 /****************************************************************
6461 _samr_GetDisplayEnumerationIndex2
6462 ****************************************************************/
6464 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6465 struct samr_GetDisplayEnumerationIndex2 *r)
6467 struct samr_GetDisplayEnumerationIndex q;
6469 q.in.domain_handle = r->in.domain_handle;
6470 q.in.level = r->in.level;
6471 q.in.name = r->in.name;
6473 q.out.idx = r->out.idx;
6475 return _samr_GetDisplayEnumerationIndex(p, &q);
6478 /****************************************************************
6480 ****************************************************************/
6482 NTSTATUS _samr_RidToSid(pipes_struct *p,
6483 struct samr_RidToSid *r)
6485 struct samr_domain_info *dinfo;
6489 dinfo = policy_handle_find(p, r->in.domain_handle,
6491 struct samr_domain_info, &status);
6492 if (!NT_STATUS_IS_OK(status)) {
6496 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6497 return NT_STATUS_NO_MEMORY;
6500 *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
6502 return NT_STATUS_NO_MEMORY;
6505 return NT_STATUS_OK;
6508 /****************************************************************
6509 ****************************************************************/
6511 NTSTATUS _samr_Shutdown(pipes_struct *p,
6512 struct samr_Shutdown *r)
6514 p->rng_fault_state = true;
6515 return NT_STATUS_NOT_IMPLEMENTED;
6518 /****************************************************************
6519 ****************************************************************/
6521 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6522 struct samr_SetMemberAttributesOfGroup *r)
6524 p->rng_fault_state = true;
6525 return NT_STATUS_NOT_IMPLEMENTED;
6528 /****************************************************************
6529 ****************************************************************/
6531 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6532 struct samr_TestPrivateFunctionsDomain *r)
6534 return NT_STATUS_NOT_IMPLEMENTED;
6537 /****************************************************************
6538 ****************************************************************/
6540 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6541 struct samr_TestPrivateFunctionsUser *r)
6543 return NT_STATUS_NOT_IMPLEMENTED;
6546 /****************************************************************
6547 ****************************************************************/
6549 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6550 struct samr_AddMultipleMembersToAlias *r)
6552 p->rng_fault_state = true;
6553 return NT_STATUS_NOT_IMPLEMENTED;
6556 /****************************************************************
6557 ****************************************************************/
6559 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6560 struct samr_RemoveMultipleMembersFromAlias *r)
6562 p->rng_fault_state = true;
6563 return NT_STATUS_NOT_IMPLEMENTED;
6566 /****************************************************************
6567 ****************************************************************/
6569 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6570 struct samr_SetBootKeyInformation *r)
6572 p->rng_fault_state = true;
6573 return NT_STATUS_NOT_IMPLEMENTED;
6576 /****************************************************************
6577 ****************************************************************/
6579 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6580 struct samr_GetBootKeyInformation *r)
6582 p->rng_fault_state = true;
6583 return NT_STATUS_NOT_IMPLEMENTED;
6586 /****************************************************************
6587 ****************************************************************/
6589 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6590 struct samr_SetDsrmPassword *r)
6592 p->rng_fault_state = true;
6593 return NT_STATUS_NOT_IMPLEMENTED;
6596 /****************************************************************
6597 ****************************************************************/
6599 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6600 struct samr_ValidatePassword *r)
6602 p->rng_fault_state = true;
6603 return NT_STATUS_NOT_IMPLEMENTED;