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 "system/passwd.h"
36 #include "../libcli/auth/libcli_auth.h"
38 #include "../librpc/gen_ndr/srv_samr.h"
39 #include "rpc_server/samr/srv_samr_util.h"
40 #include "../lib/crypto/arcfour.h"
42 #include "rpc_client/init_lsa.h"
43 #include "../libcli/security/security.h"
46 #include "rpc_server/srv_access_check.h"
47 #include "../lib/tsocket/tsocket.h"
48 #include "lib/util/base64.h"
51 #define DBGC_CLASS DBGC_RPC_SRV
53 #define SAMR_USR_RIGHTS_WRITE_PW \
54 ( READ_CONTROL_ACCESS | \
55 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
56 SAMR_USER_ACCESS_SET_LOC_COM)
57 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
58 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
60 #define DISP_INFO_CACHE_TIMEOUT 10
62 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
63 #define MAX_SAM_ENTRIES_W95 50
65 struct samr_connect_info {
69 struct samr_domain_info {
71 struct disp_info *disp_info;
74 struct samr_user_info {
78 struct samr_group_info {
82 struct samr_alias_info {
86 typedef struct disp_info {
87 struct dom_sid sid; /* identify which domain this is. */
88 struct pdb_search *users; /* querydispinfo 1 and 4 */
89 struct pdb_search *machines; /* querydispinfo 2 */
90 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
91 struct pdb_search *aliases; /* enumaliases */
93 uint32_t enum_acb_mask;
94 struct pdb_search *enum_users; /* enumusers with a mask */
96 struct tevent_timer *cache_timeout_event; /* cache idle timeout
100 static const struct generic_mapping sam_generic_mapping = {
101 GENERIC_RIGHTS_SAM_READ,
102 GENERIC_RIGHTS_SAM_WRITE,
103 GENERIC_RIGHTS_SAM_EXECUTE,
104 GENERIC_RIGHTS_SAM_ALL_ACCESS};
105 static const struct generic_mapping dom_generic_mapping = {
106 GENERIC_RIGHTS_DOMAIN_READ,
107 GENERIC_RIGHTS_DOMAIN_WRITE,
108 GENERIC_RIGHTS_DOMAIN_EXECUTE,
109 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
110 static const struct generic_mapping usr_generic_mapping = {
111 GENERIC_RIGHTS_USER_READ,
112 GENERIC_RIGHTS_USER_WRITE,
113 GENERIC_RIGHTS_USER_EXECUTE,
114 GENERIC_RIGHTS_USER_ALL_ACCESS};
115 static const struct generic_mapping usr_nopwchange_generic_mapping = {
116 GENERIC_RIGHTS_USER_READ,
117 GENERIC_RIGHTS_USER_WRITE,
118 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
119 GENERIC_RIGHTS_USER_ALL_ACCESS};
120 static const struct generic_mapping grp_generic_mapping = {
121 GENERIC_RIGHTS_GROUP_READ,
122 GENERIC_RIGHTS_GROUP_WRITE,
123 GENERIC_RIGHTS_GROUP_EXECUTE,
124 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
125 static const struct generic_mapping ali_generic_mapping = {
126 GENERIC_RIGHTS_ALIAS_READ,
127 GENERIC_RIGHTS_ALIAS_WRITE,
128 GENERIC_RIGHTS_ALIAS_EXECUTE,
129 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
131 /*******************************************************************
132 *******************************************************************/
134 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
135 const struct generic_mapping *map,
136 struct dom_sid *sid, uint32_t sid_access )
138 struct dom_sid domadmin_sid;
139 struct security_ace ace[5]; /* at most 5 entries */
142 struct security_acl *psa = NULL;
144 /* basic access for Everyone */
146 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
147 map->generic_execute | map->generic_read, 0);
149 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
151 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
152 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
153 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
154 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
156 /* Add Full Access for Domain Admins if we are a DC */
159 sid_compose(&domadmin_sid, get_global_sam_sid(),
161 init_sec_ace(&ace[i++], &domadmin_sid,
162 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
165 /* if we have a sid, give it some special access */
168 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
171 /* create the security descriptor */
173 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
174 return NT_STATUS_NO_MEMORY;
176 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
177 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
178 psa, sd_size)) == NULL)
179 return NT_STATUS_NO_MEMORY;
184 /*******************************************************************
185 Fetch or create a dispinfo struct.
186 ********************************************************************/
188 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
191 * We do a static cache for DISP_INFO's here. Explanation can be found
192 * in Jeremy's checkin message to r11793:
194 * Fix the SAMR cache so it works across completely insane
195 * client behaviour (ie.:
196 * open pipe/open SAMR handle/enumerate 0 - 1024
197 * close SAMR handle, close pipe.
198 * open pipe/open SAMR handle/enumerate 1024 - 2048...
199 * close SAMR handle, close pipe.
200 * And on ad-nausium. Amazing.... probably object-oriented
201 * client side programming in action yet again.
202 * This change should *massively* improve performance when
203 * enumerating users from an LDAP database.
206 * "Our" and the builtin domain are the only ones where we ever
207 * enumerate stuff, so just cache 2 entries.
210 static struct disp_info *builtin_dispinfo;
211 static struct disp_info *domain_dispinfo;
213 /* There are two cases to consider here:
214 1) The SID is a domain SID and we look for an equality match, or
215 2) This is an account SID and so we return the DISP_INFO* for our
222 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
224 * Necessary only once, but it does not really hurt.
226 if (builtin_dispinfo == NULL) {
227 builtin_dispinfo = talloc_zero(NULL, struct disp_info);
228 if (builtin_dispinfo == NULL) {
232 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
234 return builtin_dispinfo;
237 if (sid_check_is_our_sam(psid) || sid_check_is_in_our_sam(psid)) {
239 * Necessary only once, but it does not really hurt.
241 if (domain_dispinfo == NULL) {
242 domain_dispinfo = talloc_zero(NULL, struct disp_info);
243 if (domain_dispinfo == NULL) {
247 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
249 return domain_dispinfo;
255 /*******************************************************************
256 Function to free the per SID data.
257 ********************************************************************/
259 static void free_samr_cache(DISP_INFO *disp_info)
261 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
262 sid_string_dbg(&disp_info->sid)));
264 /* We need to become root here because the paged search might have to
265 * tell the LDAP server we're not interested in the rest anymore. */
269 TALLOC_FREE(disp_info->users);
270 TALLOC_FREE(disp_info->machines);
271 TALLOC_FREE(disp_info->groups);
272 TALLOC_FREE(disp_info->aliases);
273 TALLOC_FREE(disp_info->enum_users);
278 /*******************************************************************
279 Idle event handler. Throw away the disp info cache.
280 ********************************************************************/
282 static void disp_info_cache_idle_timeout_handler(struct tevent_context *ev_ctx,
283 struct tevent_timer *te,
287 DISP_INFO *disp_info = (DISP_INFO *)private_data;
289 TALLOC_FREE(disp_info->cache_timeout_event);
291 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
293 free_samr_cache(disp_info);
296 /*******************************************************************
297 Setup cache removal idle event handler.
298 ********************************************************************/
300 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
302 /* Remove any pending timeout and update. */
304 TALLOC_FREE(disp_info->cache_timeout_event);
306 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
307 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
308 (unsigned int)secs_fromnow ));
310 disp_info->cache_timeout_event = tevent_add_timer(
311 global_event_context(), NULL,
312 timeval_current_ofs(secs_fromnow, 0),
313 disp_info_cache_idle_timeout_handler, (void *)disp_info);
316 /*******************************************************************
317 Force flush any cache. We do this on any samr_set_xxx call.
318 We must also remove the timeout handler.
319 ********************************************************************/
321 static void force_flush_samr_cache(const struct dom_sid *sid)
323 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
325 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
329 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
330 TALLOC_FREE(disp_info->cache_timeout_event);
331 free_samr_cache(disp_info);
334 /*******************************************************************
335 Ensure password info is never given out. Paranioa... JRA.
336 ********************************************************************/
338 static void samr_clear_sam_passwd(struct samu *sam_pass)
344 /* These now zero out the old password */
346 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
347 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
350 static uint32_t count_sam_users(struct disp_info *info, uint32_t acct_flags)
352 struct samr_displayentry *entry;
354 if (sid_check_is_builtin(&info->sid)) {
355 /* No users in builtin. */
359 if (info->users == NULL) {
360 info->users = pdb_search_users(info, acct_flags);
361 if (info->users == NULL) {
365 /* Fetch the last possible entry, thus trigger an enumeration */
366 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
368 /* Ensure we cache this enumeration. */
369 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
371 return info->users->num_entries;
374 static uint32_t count_sam_groups(struct disp_info *info)
376 struct samr_displayentry *entry;
378 if (sid_check_is_builtin(&info->sid)) {
379 /* No groups in builtin. */
383 if (info->groups == NULL) {
384 info->groups = pdb_search_groups(info);
385 if (info->groups == NULL) {
389 /* Fetch the last possible entry, thus trigger an enumeration */
390 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
392 /* Ensure we cache this enumeration. */
393 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
395 return info->groups->num_entries;
398 static uint32_t count_sam_aliases(struct disp_info *info)
400 struct samr_displayentry *entry;
402 if (info->aliases == NULL) {
403 info->aliases = pdb_search_aliases(info, &info->sid);
404 if (info->aliases == NULL) {
408 /* Fetch the last possible entry, thus trigger an enumeration */
409 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
411 /* Ensure we cache this enumeration. */
412 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
414 return info->aliases->num_entries;
417 /*******************************************************************
419 ********************************************************************/
421 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
423 if (!close_policy_hnd(p, r->in.handle)) {
424 return NT_STATUS_INVALID_HANDLE;
427 ZERO_STRUCTP(r->out.handle);
432 /*******************************************************************
434 ********************************************************************/
436 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
437 struct samr_OpenDomain *r)
439 struct samr_domain_info *dinfo;
440 struct security_descriptor *psd = NULL;
441 uint32_t acc_granted;
442 uint32_t des_access = r->in.access_mask;
445 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
447 /* find the connection policy handle. */
449 (void)policy_handle_find(p, r->in.connect_handle, 0, NULL,
450 struct samr_connect_info, &status);
451 if (!NT_STATUS_IS_OK(status)) {
455 /*check if access can be granted as requested by client. */
456 map_max_allowed_access(p->session_info->security_token,
457 p->session_info->unix_token,
460 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
461 se_map_generic( &des_access, &dom_generic_mapping );
464 * Users with SeAddUser get the ability to manipulate groups
467 if (security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS)) {
468 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
469 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
470 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
471 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
472 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
476 * Users with SeMachineAccount or SeAddUser get additional
477 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
480 status = access_check_object( psd, p->session_info->security_token,
481 SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
482 extra_access, des_access,
483 &acc_granted, "_samr_OpenDomain" );
485 if ( !NT_STATUS_IS_OK(status) )
488 if (!sid_check_is_our_sam(r->in.sid) &&
489 !sid_check_is_builtin(r->in.sid)) {
490 return NT_STATUS_NO_SUCH_DOMAIN;
493 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
494 struct samr_domain_info, &status);
495 if (!NT_STATUS_IS_OK(status)) {
498 dinfo->sid = *r->in.sid;
499 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
501 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
506 /*******************************************************************
508 ********************************************************************/
510 NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
511 struct samr_GetUserPwInfo *r)
513 struct samr_user_info *uinfo;
514 enum lsa_SidType sid_type;
515 uint32_t min_password_length = 0;
516 uint32_t password_properties = 0;
520 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
522 uinfo = policy_handle_find(p, r->in.user_handle,
523 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
524 struct samr_user_info, &status);
525 if (!NT_STATUS_IS_OK(status)) {
529 if (!sid_check_is_in_our_sam(&uinfo->sid)) {
530 return NT_STATUS_OBJECT_TYPE_MISMATCH;
534 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
537 return NT_STATUS_NO_SUCH_USER;
543 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
544 &min_password_length);
545 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
546 &password_properties);
549 if (lp_check_password_script(talloc_tos())
550 && *lp_check_password_script(talloc_tos())) {
551 password_properties |= DOMAIN_PASSWORD_COMPLEX;
559 r->out.info->min_password_length = min_password_length;
560 r->out.info->password_properties = password_properties;
562 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
567 /*******************************************************************
569 ********************************************************************/
571 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
572 struct samr_SetSecurity *r)
574 struct samr_user_info *uinfo;
576 struct security_acl *dacl;
578 struct samu *sampass=NULL;
581 uinfo = policy_handle_find(p, r->in.handle,
582 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
583 struct samr_user_info, &status);
584 if (!NT_STATUS_IS_OK(status)) {
588 if (!(sampass = samu_new( p->mem_ctx))) {
589 DEBUG(0,("No memory!\n"));
590 return NT_STATUS_NO_MEMORY;
593 /* get the user record */
595 ret = pdb_getsampwsid(sampass, &uinfo->sid);
599 DEBUG(4, ("User %s not found\n",
600 sid_string_dbg(&uinfo->sid)));
601 TALLOC_FREE(sampass);
602 return NT_STATUS_INVALID_HANDLE;
605 dacl = r->in.sdbuf->sd->dacl;
606 for (i=0; i < dacl->num_aces; i++) {
607 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
608 ret = pdb_set_pass_can_change(sampass,
609 (dacl->aces[i].access_mask &
610 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
617 TALLOC_FREE(sampass);
618 return NT_STATUS_ACCESS_DENIED;
622 status = pdb_update_sam_account(sampass);
625 TALLOC_FREE(sampass);
630 /*******************************************************************
631 build correct perms based on policies and password times for _samr_query_sec_obj
632 *******************************************************************/
633 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
635 struct samu *sampass=NULL;
638 if ( !(sampass = samu_new( mem_ctx )) ) {
639 DEBUG(0,("No memory!\n"));
644 ret = pdb_getsampwsid(sampass, user_sid);
648 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
649 TALLOC_FREE(sampass);
653 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
655 if (pdb_get_pass_can_change(sampass)) {
656 TALLOC_FREE(sampass);
659 TALLOC_FREE(sampass);
664 /*******************************************************************
666 ********************************************************************/
668 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
669 struct samr_QuerySecurity *r)
671 struct samr_domain_info *dinfo;
672 struct samr_user_info *uinfo;
673 struct samr_group_info *ginfo;
674 struct samr_alias_info *ainfo;
676 struct security_descriptor * psd = NULL;
679 (void)policy_handle_find(p, r->in.handle,
680 SEC_STD_READ_CONTROL, NULL,
681 struct samr_connect_info, &status);
682 if (NT_STATUS_IS_OK(status)) {
683 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
684 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
685 &sam_generic_mapping, NULL, 0);
689 dinfo = policy_handle_find(p, r->in.handle,
690 SEC_STD_READ_CONTROL, NULL,
691 struct samr_domain_info, &status);
692 if (NT_STATUS_IS_OK(status)) {
693 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
694 "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
696 * TODO: Builtin probably needs a different SD with restricted
699 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
700 &dom_generic_mapping, NULL, 0);
704 uinfo = policy_handle_find(p, r->in.handle,
705 SEC_STD_READ_CONTROL, NULL,
706 struct samr_user_info, &status);
707 if (NT_STATUS_IS_OK(status)) {
708 DEBUG(10,("_samr_QuerySecurity: querying security on user "
709 "Object with SID: %s\n",
710 sid_string_dbg(&uinfo->sid)));
711 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
712 status = make_samr_object_sd(
713 p->mem_ctx, &psd, &sd_size,
714 &usr_generic_mapping,
715 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
717 status = make_samr_object_sd(
718 p->mem_ctx, &psd, &sd_size,
719 &usr_nopwchange_generic_mapping,
720 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
725 ginfo = policy_handle_find(p, r->in.handle,
726 SEC_STD_READ_CONTROL, NULL,
727 struct samr_group_info, &status);
728 if (NT_STATUS_IS_OK(status)) {
730 * TODO: different SDs have to be generated for aliases groups
731 * and users. Currently all three get a default user SD
733 DEBUG(10,("_samr_QuerySecurity: querying security on group "
734 "Object with SID: %s\n",
735 sid_string_dbg(&ginfo->sid)));
736 status = make_samr_object_sd(
737 p->mem_ctx, &psd, &sd_size,
738 &usr_nopwchange_generic_mapping,
739 &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
743 ainfo = policy_handle_find(p, r->in.handle,
744 SEC_STD_READ_CONTROL, NULL,
745 struct samr_alias_info, &status);
746 if (NT_STATUS_IS_OK(status)) {
748 * TODO: different SDs have to be generated for aliases groups
749 * and users. Currently all three get a default user SD
751 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
752 "Object with SID: %s\n",
753 sid_string_dbg(&ainfo->sid)));
754 status = make_samr_object_sd(
755 p->mem_ctx, &psd, &sd_size,
756 &usr_nopwchange_generic_mapping,
757 &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
761 return NT_STATUS_OBJECT_TYPE_MISMATCH;
763 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
764 return NT_STATUS_NO_MEMORY;
769 /*******************************************************************
770 makes a SAM_ENTRY / UNISTR2* structure from a user list.
771 ********************************************************************/
773 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
774 struct samr_SamEntry **sam_pp,
775 uint32_t num_entries,
777 struct samr_displayentry *entries)
780 struct samr_SamEntry *sam;
784 if (num_entries == 0) {
788 sam = talloc_zero_array(ctx, struct samr_SamEntry, num_entries);
790 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
791 return NT_STATUS_NO_MEMORY;
794 for (i = 0; i < num_entries; i++) {
797 * usrmgr expects a non-NULL terminated string with
798 * trust relationships
800 if (entries[i].acct_flags & ACB_DOMTRUST) {
801 init_unistr2(&uni_temp_name, entries[i].account_name,
804 init_unistr2(&uni_temp_name, entries[i].account_name,
808 init_lsa_String(&sam[i].name, entries[i].account_name);
809 sam[i].idx = entries[i].rid;
817 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
819 /*******************************************************************
820 _samr_EnumDomainUsers
821 ********************************************************************/
823 NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
824 struct samr_EnumDomainUsers *r)
827 struct samr_domain_info *dinfo;
829 uint32_t enum_context = *r->in.resume_handle;
830 enum remote_arch_types ra_type = get_remote_arch();
831 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
832 uint32_t max_entries = max_sam_entries;
833 struct samr_displayentry *entries = NULL;
834 struct samr_SamArray *samr_array = NULL;
835 struct samr_SamEntry *samr_entries = NULL;
837 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
839 dinfo = policy_handle_find(p, r->in.domain_handle,
840 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
841 struct samr_domain_info, &status);
842 if (!NT_STATUS_IS_OK(status)) {
846 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
848 return NT_STATUS_NO_MEMORY;
850 *r->out.sam = samr_array;
852 if (sid_check_is_builtin(&dinfo->sid)) {
853 /* No users in builtin. */
854 *r->out.resume_handle = *r->in.resume_handle;
855 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
863 if ((dinfo->disp_info->enum_users != NULL) &&
864 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
865 TALLOC_FREE(dinfo->disp_info->enum_users);
868 if (dinfo->disp_info->enum_users == NULL) {
869 dinfo->disp_info->enum_users = pdb_search_users(
870 dinfo->disp_info, r->in.acct_flags);
871 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
874 if (dinfo->disp_info->enum_users == NULL) {
875 /* END AS ROOT !!!! */
877 return NT_STATUS_ACCESS_DENIED;
880 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
881 enum_context, max_entries,
884 /* END AS ROOT !!!! */
888 if (num_account == 0) {
889 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
891 *r->out.resume_handle = *r->in.resume_handle;
895 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
896 num_account, enum_context,
898 if (!NT_STATUS_IS_OK(status)) {
902 if (max_entries <= num_account) {
903 status = STATUS_MORE_ENTRIES;
905 status = NT_STATUS_OK;
908 /* Ensure we cache this enumeration. */
909 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
911 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
913 samr_array->count = num_account;
914 samr_array->entries = samr_entries;
916 *r->out.resume_handle = *r->in.resume_handle + num_account;
917 *r->out.num_entries = num_account;
919 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
924 /*******************************************************************
925 makes a SAM_ENTRY / UNISTR2* structure from a group list.
926 ********************************************************************/
928 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
929 struct samr_SamEntry **sam_pp,
930 uint32_t num_sam_entries,
931 struct samr_displayentry *entries)
933 struct samr_SamEntry *sam;
938 if (num_sam_entries == 0) {
942 sam = talloc_zero_array(ctx, struct samr_SamEntry, num_sam_entries);
947 for (i = 0; i < num_sam_entries; i++) {
949 * JRA. I think this should include the null. TNG does not.
951 init_lsa_String(&sam[i].name, entries[i].account_name);
952 sam[i].idx = entries[i].rid;
958 /*******************************************************************
959 _samr_EnumDomainGroups
960 ********************************************************************/
962 NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
963 struct samr_EnumDomainGroups *r)
966 struct samr_domain_info *dinfo;
967 struct samr_displayentry *groups;
969 struct samr_SamArray *samr_array = NULL;
970 struct samr_SamEntry *samr_entries = NULL;
972 dinfo = policy_handle_find(p, r->in.domain_handle,
973 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
974 struct samr_domain_info, &status);
975 if (!NT_STATUS_IS_OK(status)) {
979 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
981 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
983 return NT_STATUS_NO_MEMORY;
985 *r->out.sam = samr_array;
987 if (sid_check_is_builtin(&dinfo->sid)) {
988 /* No groups in builtin. */
989 *r->out.resume_handle = *r->in.resume_handle;
990 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
994 /* the domain group array is being allocated in the function below */
998 if (dinfo->disp_info->groups == NULL) {
999 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1001 if (dinfo->disp_info->groups == NULL) {
1003 return NT_STATUS_ACCESS_DENIED;
1007 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1008 *r->in.resume_handle,
1009 MAX_SAM_ENTRIES, &groups);
1012 /* Ensure we cache this enumeration. */
1013 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1015 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1016 num_groups, groups);
1018 if (MAX_SAM_ENTRIES <= num_groups) {
1019 status = STATUS_MORE_ENTRIES;
1021 status = NT_STATUS_OK;
1024 samr_array->count = num_groups;
1025 samr_array->entries = samr_entries;
1027 *r->out.num_entries = num_groups;
1028 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1030 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1035 /*******************************************************************
1036 _samr_EnumDomainAliases
1037 ********************************************************************/
1039 NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1040 struct samr_EnumDomainAliases *r)
1043 struct samr_domain_info *dinfo;
1044 struct samr_displayentry *aliases;
1045 uint32_t num_aliases = 0;
1046 struct samr_SamArray *samr_array = NULL;
1047 struct samr_SamEntry *samr_entries = NULL;
1049 dinfo = policy_handle_find(p, r->in.domain_handle,
1050 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1051 struct samr_domain_info, &status);
1052 if (!NT_STATUS_IS_OK(status)) {
1056 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1057 sid_string_dbg(&dinfo->sid)));
1059 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
1061 return NT_STATUS_NO_MEMORY;
1066 if (dinfo->disp_info->aliases == NULL) {
1067 dinfo->disp_info->aliases = pdb_search_aliases(
1068 dinfo->disp_info, &dinfo->sid);
1069 if (dinfo->disp_info->aliases == NULL) {
1071 return NT_STATUS_ACCESS_DENIED;
1075 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1076 *r->in.resume_handle,
1077 MAX_SAM_ENTRIES, &aliases);
1080 /* Ensure we cache this enumeration. */
1081 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1083 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1084 num_aliases, aliases);
1086 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1088 if (MAX_SAM_ENTRIES <= num_aliases) {
1089 status = STATUS_MORE_ENTRIES;
1091 status = NT_STATUS_OK;
1094 samr_array->count = num_aliases;
1095 samr_array->entries = samr_entries;
1097 *r->out.sam = samr_array;
1098 *r->out.num_entries = num_aliases;
1099 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1104 /*******************************************************************
1105 inits a samr_DispInfoGeneral structure.
1106 ********************************************************************/
1108 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1109 struct samr_DispInfoGeneral *r,
1110 uint32_t num_entries,
1112 struct samr_displayentry *entries)
1116 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1118 if (num_entries == 0) {
1119 return NT_STATUS_OK;
1122 r->count = num_entries;
1124 r->entries = talloc_zero_array(ctx, struct samr_DispEntryGeneral, num_entries);
1126 return NT_STATUS_NO_MEMORY;
1129 for (i = 0; i < num_entries ; i++) {
1131 init_lsa_String(&r->entries[i].account_name,
1132 entries[i].account_name);
1134 init_lsa_String(&r->entries[i].description,
1135 entries[i].description);
1137 init_lsa_String(&r->entries[i].full_name,
1138 entries[i].fullname);
1140 r->entries[i].rid = entries[i].rid;
1141 r->entries[i].acct_flags = entries[i].acct_flags;
1142 r->entries[i].idx = start_idx+i+1;
1145 return NT_STATUS_OK;
1148 /*******************************************************************
1149 inits a samr_DispInfoFull structure.
1150 ********************************************************************/
1152 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1153 struct samr_DispInfoFull *r,
1154 uint32_t num_entries,
1156 struct samr_displayentry *entries)
1160 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1162 if (num_entries == 0) {
1163 return NT_STATUS_OK;
1166 r->count = num_entries;
1168 r->entries = talloc_zero_array(ctx, struct samr_DispEntryFull, num_entries);
1170 return NT_STATUS_NO_MEMORY;
1173 for (i = 0; i < num_entries ; i++) {
1175 init_lsa_String(&r->entries[i].account_name,
1176 entries[i].account_name);
1178 init_lsa_String(&r->entries[i].description,
1179 entries[i].description);
1181 r->entries[i].rid = entries[i].rid;
1182 r->entries[i].acct_flags = entries[i].acct_flags;
1183 r->entries[i].idx = start_idx+i+1;
1186 return NT_STATUS_OK;
1189 /*******************************************************************
1190 inits a samr_DispInfoFullGroups structure.
1191 ********************************************************************/
1193 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1194 struct samr_DispInfoFullGroups *r,
1195 uint32_t num_entries,
1197 struct samr_displayentry *entries)
1201 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1203 if (num_entries == 0) {
1204 return NT_STATUS_OK;
1207 r->count = num_entries;
1209 r->entries = talloc_zero_array(ctx, struct samr_DispEntryFullGroup, num_entries);
1211 return NT_STATUS_NO_MEMORY;
1214 for (i = 0; i < num_entries ; i++) {
1216 init_lsa_String(&r->entries[i].account_name,
1217 entries[i].account_name);
1219 init_lsa_String(&r->entries[i].description,
1220 entries[i].description);
1222 r->entries[i].rid = entries[i].rid;
1223 r->entries[i].acct_flags = entries[i].acct_flags;
1224 r->entries[i].idx = start_idx+i+1;
1227 return NT_STATUS_OK;
1230 /*******************************************************************
1231 inits a samr_DispInfoAscii structure.
1232 ********************************************************************/
1234 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1235 struct samr_DispInfoAscii *r,
1236 uint32_t num_entries,
1238 struct samr_displayentry *entries)
1242 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1244 if (num_entries == 0) {
1245 return NT_STATUS_OK;
1248 r->count = num_entries;
1250 r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1252 return NT_STATUS_NO_MEMORY;
1255 for (i = 0; i < num_entries ; i++) {
1257 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1258 entries[i].account_name);
1260 r->entries[i].idx = start_idx+i+1;
1263 return NT_STATUS_OK;
1266 /*******************************************************************
1267 inits a samr_DispInfoAscii structure.
1268 ********************************************************************/
1270 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1271 struct samr_DispInfoAscii *r,
1272 uint32_t num_entries,
1274 struct samr_displayentry *entries)
1278 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1280 if (num_entries == 0) {
1281 return NT_STATUS_OK;
1284 r->count = num_entries;
1286 r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1288 return NT_STATUS_NO_MEMORY;
1291 for (i = 0; i < num_entries ; i++) {
1293 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1294 entries[i].account_name);
1296 r->entries[i].idx = start_idx+i+1;
1299 return NT_STATUS_OK;
1302 /*******************************************************************
1303 _samr_QueryDisplayInfo
1304 ********************************************************************/
1306 NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1307 struct samr_QueryDisplayInfo *r)
1310 struct samr_domain_info *dinfo;
1311 uint32_t struct_size=0x20; /* W2K always reply that, client doesn't care */
1313 uint32_t max_entries = r->in.max_entries;
1315 union samr_DispInfo *disp_info = r->out.info;
1317 uint32_t temp_size=0;
1318 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1319 uint32_t num_account = 0;
1320 enum remote_arch_types ra_type = get_remote_arch();
1321 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1322 struct samr_displayentry *entries = NULL;
1324 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1326 dinfo = policy_handle_find(p, r->in.domain_handle,
1327 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1328 struct samr_domain_info, &status);
1329 if (!NT_STATUS_IS_OK(status)) {
1333 if (sid_check_is_builtin(&dinfo->sid)) {
1334 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1335 return NT_STATUS_OK;
1339 * calculate how many entries we will return.
1341 * - the number of entries the client asked
1342 * - our limit on that
1343 * - the starting point (enumeration context)
1344 * - the buffer size the client will accept
1348 * We are a lot more like W2K. Instead of reading the SAM
1349 * each time to find the records we need to send back,
1350 * we read it once and link that copy to the sam handle.
1351 * For large user list (over the MAX_SAM_ENTRIES)
1352 * it's a definitive win.
1353 * second point to notice: between enumerations
1354 * our sam is now the same as it's a snapshoot.
1355 * third point: got rid of the static SAM_USER_21 struct
1356 * no more intermediate.
1357 * con: it uses much more memory, as a full copy is stored
1360 * If you want to change it, think twice and think
1361 * of the second point , that's really important.
1366 if ((r->in.level < 1) || (r->in.level > 5)) {
1367 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1368 (unsigned int)r->in.level ));
1369 return NT_STATUS_INVALID_INFO_CLASS;
1372 /* first limit the number of entries we will return */
1373 if (r->in.max_entries > max_sam_entries) {
1374 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1375 "entries, limiting to %d\n", r->in.max_entries,
1377 max_entries = max_sam_entries;
1380 /* calculate the size and limit on the number of entries we will
1383 temp_size=max_entries*struct_size;
1385 if (temp_size > r->in.buf_size) {
1386 max_entries = MIN((r->in.buf_size / struct_size),max_entries);
1387 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1388 "only %d entries\n", max_entries));
1393 /* THe following done as ROOT. Don't return without unbecome_root(). */
1395 switch (r->in.level) {
1398 if (dinfo->disp_info->users == NULL) {
1399 dinfo->disp_info->users = pdb_search_users(
1400 dinfo->disp_info, ACB_NORMAL);
1401 if (dinfo->disp_info->users == NULL) {
1403 return NT_STATUS_ACCESS_DENIED;
1405 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1406 (unsigned int)r->in.start_idx));
1408 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1409 (unsigned int)r->in.start_idx));
1412 num_account = pdb_search_entries(dinfo->disp_info->users,
1413 r->in.start_idx, max_entries,
1417 if (dinfo->disp_info->machines == NULL) {
1418 dinfo->disp_info->machines = pdb_search_users(
1419 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1420 if (dinfo->disp_info->machines == NULL) {
1422 return NT_STATUS_ACCESS_DENIED;
1424 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1425 (unsigned int)r->in.start_idx));
1427 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1428 (unsigned int)r->in.start_idx));
1431 num_account = pdb_search_entries(dinfo->disp_info->machines,
1432 r->in.start_idx, max_entries,
1437 if (dinfo->disp_info->groups == NULL) {
1438 dinfo->disp_info->groups = pdb_search_groups(
1440 if (dinfo->disp_info->groups == NULL) {
1442 return NT_STATUS_ACCESS_DENIED;
1444 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1445 (unsigned int)r->in.start_idx));
1447 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1448 (unsigned int)r->in.start_idx));
1451 num_account = pdb_search_entries(dinfo->disp_info->groups,
1452 r->in.start_idx, max_entries,
1457 smb_panic("info class changed");
1463 /* Now create reply structure */
1464 switch (r->in.level) {
1466 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1467 num_account, r->in.start_idx,
1471 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1472 num_account, r->in.start_idx,
1476 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1477 num_account, r->in.start_idx,
1481 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1482 num_account, r->in.start_idx,
1486 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1487 num_account, r->in.start_idx,
1491 smb_panic("info class changed");
1495 if (!NT_STATUS_IS_OK(disp_ret))
1498 if (max_entries <= num_account) {
1499 status = STATUS_MORE_ENTRIES;
1501 status = NT_STATUS_OK;
1504 /* Ensure we cache this enumeration. */
1505 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1507 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1509 *r->out.total_size = num_account * struct_size;
1510 *r->out.returned_size = num_account ? temp_size : 0;
1515 /****************************************************************
1516 _samr_QueryDisplayInfo2
1517 ****************************************************************/
1519 NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1520 struct samr_QueryDisplayInfo2 *r)
1522 struct samr_QueryDisplayInfo q;
1524 q.in.domain_handle = r->in.domain_handle;
1525 q.in.level = r->in.level;
1526 q.in.start_idx = r->in.start_idx;
1527 q.in.max_entries = r->in.max_entries;
1528 q.in.buf_size = r->in.buf_size;
1530 q.out.total_size = r->out.total_size;
1531 q.out.returned_size = r->out.returned_size;
1532 q.out.info = r->out.info;
1534 return _samr_QueryDisplayInfo(p, &q);
1537 /****************************************************************
1538 _samr_QueryDisplayInfo3
1539 ****************************************************************/
1541 NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1542 struct samr_QueryDisplayInfo3 *r)
1544 struct samr_QueryDisplayInfo q;
1546 q.in.domain_handle = r->in.domain_handle;
1547 q.in.level = r->in.level;
1548 q.in.start_idx = r->in.start_idx;
1549 q.in.max_entries = r->in.max_entries;
1550 q.in.buf_size = r->in.buf_size;
1552 q.out.total_size = r->out.total_size;
1553 q.out.returned_size = r->out.returned_size;
1554 q.out.info = r->out.info;
1556 return _samr_QueryDisplayInfo(p, &q);
1559 /*******************************************************************
1560 _samr_QueryAliasInfo
1561 ********************************************************************/
1563 NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1564 struct samr_QueryAliasInfo *r)
1566 struct samr_alias_info *ainfo;
1567 struct acct_info *info;
1569 union samr_AliasInfo *alias_info = NULL;
1570 const char *alias_name = NULL;
1571 const char *alias_description = NULL;
1573 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1575 ainfo = policy_handle_find(p, r->in.alias_handle,
1576 SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1577 struct samr_alias_info, &status);
1578 if (!NT_STATUS_IS_OK(status)) {
1582 alias_info = talloc_zero(p->mem_ctx, union samr_AliasInfo);
1584 return NT_STATUS_NO_MEMORY;
1587 info = talloc_zero(p->mem_ctx, struct acct_info);
1589 return NT_STATUS_NO_MEMORY;
1593 status = pdb_get_aliasinfo(&ainfo->sid, info);
1596 if (!NT_STATUS_IS_OK(status)) {
1601 alias_name = talloc_steal(r, info->acct_name);
1602 alias_description = talloc_steal(r, info->acct_desc);
1605 switch (r->in.level) {
1607 alias_info->all.name.string = alias_name;
1608 alias_info->all.num_members = 1; /* ??? */
1609 alias_info->all.description.string = alias_description;
1612 alias_info->name.string = alias_name;
1614 case ALIASINFODESCRIPTION:
1615 alias_info->description.string = alias_description;
1618 return NT_STATUS_INVALID_INFO_CLASS;
1621 *r->out.info = alias_info;
1623 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1625 return NT_STATUS_OK;
1628 /*******************************************************************
1630 ********************************************************************/
1632 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1633 struct samr_LookupNames *r)
1635 struct samr_domain_info *dinfo;
1638 enum lsa_SidType *type;
1640 int num_rids = r->in.num_names;
1641 struct samr_Ids rids, types;
1642 uint32_t num_mapped = 0;
1644 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1646 dinfo = policy_handle_find(p, r->in.domain_handle,
1647 0 /* Don't know the acc_bits yet */, NULL,
1648 struct samr_domain_info, &status);
1649 if (!NT_STATUS_IS_OK(status)) {
1653 if (num_rids > MAX_SAM_ENTRIES) {
1654 num_rids = MAX_SAM_ENTRIES;
1655 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1658 rid = talloc_array(p->mem_ctx, uint32_t, num_rids);
1659 NT_STATUS_HAVE_NO_MEMORY(rid);
1661 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1662 NT_STATUS_HAVE_NO_MEMORY(type);
1664 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1665 sid_string_dbg(&dinfo->sid)));
1667 for (i = 0; i < num_rids; i++) {
1669 status = NT_STATUS_NONE_MAPPED;
1670 type[i] = SID_NAME_UNKNOWN;
1672 rid[i] = 0xffffffff;
1674 if (sid_check_is_builtin(&dinfo->sid)) {
1675 if (lookup_builtin_name(r->in.names[i].string,
1678 type[i] = SID_NAME_ALIAS;
1681 lookup_global_sam_name(r->in.names[i].string, 0,
1685 if (type[i] != SID_NAME_UNKNOWN) {
1690 if (num_mapped == num_rids) {
1691 status = NT_STATUS_OK;
1692 } else if (num_mapped == 0) {
1693 status = NT_STATUS_NONE_MAPPED;
1695 status = STATUS_SOME_UNMAPPED;
1698 rids.count = num_rids;
1701 types.count = num_rids;
1702 types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1703 NT_STATUS_HAVE_NO_MEMORY(type);
1704 for (i = 0; i < num_rids; i++) {
1705 types.ids[i] = (type[i] & 0xffffffff);
1708 *r->out.rids = rids;
1709 *r->out.types = types;
1711 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1716 /****************************************************************
1717 _samr_ChangePasswordUser.
1719 So old it is just not worth implementing
1720 because it does not supply a plaintext and so we can't do password
1721 complexity checking and cannot update other services that use a
1722 plaintext password via passwd chat/pam password change/ldap password
1724 ****************************************************************/
1726 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1727 struct samr_ChangePasswordUser *r)
1729 return NT_STATUS_NOT_IMPLEMENTED;
1732 /*******************************************************************
1733 _samr_ChangePasswordUser2
1734 ********************************************************************/
1736 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1737 struct samr_ChangePasswordUser2 *r)
1740 char *user_name = NULL;
1742 const char *wks = NULL;
1744 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1746 if (!r->in.account->string) {
1747 return NT_STATUS_INVALID_PARAMETER;
1749 if (r->in.server && r->in.server->string) {
1750 wks = r->in.server->string;
1753 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1756 * Pass the user through the NT -> unix user mapping
1760 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1762 return NT_STATUS_NO_MEMORY;
1765 rhost = tsocket_address_inet_addr_string(p->remote_address,
1767 if (rhost == NULL) {
1768 return NT_STATUS_NO_MEMORY;
1772 * UNIX username case mangling not required, pass_oem_change
1773 * is case insensitive.
1776 status = pass_oem_change(user_name,
1778 r->in.lm_password->data,
1779 r->in.lm_verifier->hash,
1780 r->in.nt_password->data,
1781 r->in.nt_verifier->hash,
1784 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1786 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1787 return NT_STATUS_WRONG_PASSWORD;
1793 /****************************************************************
1794 _samr_OemChangePasswordUser2
1795 ****************************************************************/
1797 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1798 struct samr_OemChangePasswordUser2 *r)
1801 char *user_name = NULL;
1802 const char *wks = NULL;
1805 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1807 if (!r->in.account->string) {
1808 return NT_STATUS_INVALID_PARAMETER;
1810 if (r->in.server && r->in.server->string) {
1811 wks = r->in.server->string;
1814 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1817 * Pass the user through the NT -> unix user mapping
1821 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1823 return NT_STATUS_NO_MEMORY;
1827 * UNIX username case mangling not required, pass_oem_change
1828 * is case insensitive.
1831 if (!r->in.hash || !r->in.password) {
1832 return NT_STATUS_INVALID_PARAMETER;
1835 rhost = tsocket_address_inet_addr_string(p->remote_address,
1837 if (rhost == NULL) {
1838 return NT_STATUS_NO_MEMORY;
1841 status = pass_oem_change(user_name,
1843 r->in.password->data,
1849 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1850 return NT_STATUS_WRONG_PASSWORD;
1853 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1858 /*******************************************************************
1859 _samr_ChangePasswordUser3
1860 ********************************************************************/
1862 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
1863 struct samr_ChangePasswordUser3 *r)
1866 char *user_name = NULL;
1867 const char *wks = NULL;
1868 enum samPwdChangeReason reject_reason;
1869 struct samr_DomInfo1 *dominfo = NULL;
1870 struct userPwdChangeFailureInformation *reject = NULL;
1874 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1876 if (!r->in.account->string) {
1877 return NT_STATUS_INVALID_PARAMETER;
1879 if (r->in.server && r->in.server->string) {
1880 wks = r->in.server->string;
1883 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1886 * Pass the user through the NT -> unix user mapping
1890 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1892 return NT_STATUS_NO_MEMORY;
1895 rhost = tsocket_address_inet_addr_string(p->remote_address,
1897 if (rhost == NULL) {
1898 return NT_STATUS_NO_MEMORY;
1902 * UNIX username case mangling not required, pass_oem_change
1903 * is case insensitive.
1906 status = pass_oem_change(user_name,
1908 r->in.lm_password->data,
1909 r->in.lm_verifier->hash,
1910 r->in.nt_password->data,
1911 r->in.nt_verifier->hash,
1913 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1914 return NT_STATUS_WRONG_PASSWORD;
1917 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1918 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1920 time_t u_expire, u_min_age;
1921 uint32_t account_policy_temp;
1923 dominfo = talloc_zero(p->mem_ctx, struct samr_DomInfo1);
1925 return NT_STATUS_NO_MEMORY;
1928 reject = talloc_zero(p->mem_ctx,
1929 struct userPwdChangeFailureInformation);
1931 return NT_STATUS_NO_MEMORY;
1938 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
1939 dominfo->min_password_length = tmp;
1941 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
1942 dominfo->password_history_length = tmp;
1944 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
1945 &dominfo->password_properties);
1947 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
1948 u_expire = account_policy_temp;
1950 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
1951 u_min_age = account_policy_temp;
1957 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
1958 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
1960 if (lp_check_password_script(talloc_tos())
1961 && *lp_check_password_script(talloc_tos())) {
1962 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
1965 reject->extendedFailureReason = reject_reason;
1967 *r->out.dominfo = dominfo;
1968 *r->out.reject = reject;
1971 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1976 /*******************************************************************
1977 makes a SAMR_R_LOOKUP_RIDS structure.
1978 ********************************************************************/
1980 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32_t num_names,
1982 struct lsa_String **lsa_name_array_p)
1984 struct lsa_String *lsa_name_array = NULL;
1987 *lsa_name_array_p = NULL;
1989 if (num_names != 0) {
1990 lsa_name_array = talloc_zero_array(ctx, struct lsa_String, num_names);
1991 if (!lsa_name_array) {
1996 for (i = 0; i < num_names; i++) {
1997 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
1998 init_lsa_String(&lsa_name_array[i], names[i]);
2001 *lsa_name_array_p = lsa_name_array;
2006 /*******************************************************************
2008 ********************************************************************/
2010 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2011 struct samr_LookupRids *r)
2013 struct samr_domain_info *dinfo;
2016 enum lsa_SidType *attrs = NULL;
2017 uint32_t *wire_attrs = NULL;
2018 int num_rids = (int)r->in.num_rids;
2020 struct lsa_Strings names_array;
2021 struct samr_Ids types_array;
2022 struct lsa_String *lsa_names = NULL;
2024 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2026 dinfo = policy_handle_find(p, r->in.domain_handle,
2027 0 /* Don't know the acc_bits yet */, NULL,
2028 struct samr_domain_info, &status);
2029 if (!NT_STATUS_IS_OK(status)) {
2033 if (num_rids > 1000) {
2034 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2035 "to samba4 idl this is not possible\n", num_rids));
2036 return NT_STATUS_UNSUCCESSFUL;
2040 names = talloc_zero_array(p->mem_ctx, const char *, num_rids);
2041 attrs = talloc_zero_array(p->mem_ctx, enum lsa_SidType, num_rids);
2042 wire_attrs = talloc_zero_array(p->mem_ctx, uint32_t, num_rids);
2044 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2045 return NT_STATUS_NO_MEMORY;
2052 become_root(); /* lookup_sid can require root privs */
2053 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2057 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2058 status = NT_STATUS_OK;
2061 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2063 return NT_STATUS_NO_MEMORY;
2066 /* Convert from enum lsa_SidType to uint32_t for wire format. */
2067 for (i = 0; i < num_rids; i++) {
2068 wire_attrs[i] = (uint32_t)attrs[i];
2071 names_array.count = num_rids;
2072 names_array.names = lsa_names;
2074 types_array.count = num_rids;
2075 types_array.ids = wire_attrs;
2077 *r->out.names = names_array;
2078 *r->out.types = types_array;
2080 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2085 /*******************************************************************
2087 ********************************************************************/
2089 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2090 struct samr_OpenUser *r)
2092 struct samu *sampass=NULL;
2094 struct samr_domain_info *dinfo;
2095 struct samr_user_info *uinfo;
2096 struct security_descriptor *psd = NULL;
2097 uint32_t acc_granted;
2098 uint32_t des_access = r->in.access_mask;
2099 uint32_t extra_access = 0;
2104 /* These two privileges, if != SEC_PRIV_INVALID, indicate
2105 * privileges that the user must have to complete this
2106 * operation in defience of the fixed ACL */
2107 enum sec_privilege needed_priv_1, needed_priv_2;
2110 dinfo = policy_handle_find(p, r->in.domain_handle,
2111 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2112 struct samr_domain_info, &status);
2113 if (!NT_STATUS_IS_OK(status)) {
2117 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2118 return NT_STATUS_NO_MEMORY;
2121 /* append the user's RID to it */
2123 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2124 return NT_STATUS_NO_SUCH_USER;
2126 /* check if access can be granted as requested by client. */
2127 map_max_allowed_access(p->session_info->security_token,
2128 p->session_info->unix_token,
2131 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2132 se_map_generic(&des_access, &usr_generic_mapping);
2135 * Get the sampass first as we need to check privileges
2136 * based on what kind of user object this is.
2137 * But don't reveal info too early if it didn't exist.
2141 ret=pdb_getsampwsid(sampass, &sid);
2144 needed_priv_1 = SEC_PRIV_INVALID;
2145 needed_priv_2 = SEC_PRIV_INVALID;
2147 * We do the override access checks on *open*, not at
2151 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2153 if (acb_info & ACB_WSTRUST) {
2155 * SeMachineAccount is needed to add
2156 * GENERIC_RIGHTS_USER_WRITE to a machine
2159 needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2161 if (acb_info & ACB_NORMAL) {
2163 * SeAddUsers is needed to add
2164 * GENERIC_RIGHTS_USER_WRITE to a normal
2167 needed_priv_1 = SEC_PRIV_ADD_USERS;
2170 * Cheat - we have not set a specific privilege for
2171 * server (BDC) or domain trust account, so allow
2172 * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2173 * DOMAIN_RID_ADMINS.
2175 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2176 if (lp_enable_privileges() && nt_token_check_domain_rid(p->session_info->security_token,
2177 DOMAIN_RID_ADMINS)) {
2178 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2179 extra_access = GENERIC_RIGHTS_USER_WRITE;
2180 DEBUG(4,("_samr_OpenUser: Allowing "
2181 "GENERIC_RIGHTS_USER_WRITE for "
2187 TALLOC_FREE(sampass);
2189 nt_status = access_check_object(psd, p->session_info->security_token,
2190 needed_priv_1, needed_priv_2,
2191 GENERIC_RIGHTS_USER_WRITE, des_access,
2192 &acc_granted, "_samr_OpenUser");
2194 if ( !NT_STATUS_IS_OK(nt_status) )
2197 /* check that the SID exists in our domain. */
2199 return NT_STATUS_NO_SUCH_USER;
2202 /* If we did the rid admins hack above, allow access. */
2203 acc_granted |= extra_access;
2205 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2206 struct samr_user_info, &nt_status);
2207 if (!NT_STATUS_IS_OK(nt_status)) {
2212 return NT_STATUS_OK;
2215 /*************************************************************************
2216 *************************************************************************/
2218 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2220 struct lsa_BinaryString **_r)
2222 struct lsa_BinaryString *r;
2225 return NT_STATUS_INVALID_PARAMETER;
2228 r = talloc_zero(mem_ctx, struct lsa_BinaryString);
2230 return NT_STATUS_NO_MEMORY;
2233 r->array = talloc_zero_array(mem_ctx, uint16_t, blob->length/2);
2235 return NT_STATUS_NO_MEMORY;
2237 memcpy(r->array, blob->data, blob->length);
2238 r->size = blob->length;
2239 r->length = blob->length;
2242 return NT_STATUS_NO_MEMORY;
2247 return NT_STATUS_OK;
2250 /*************************************************************************
2251 *************************************************************************/
2253 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2256 struct samr_LogonHours hours;
2257 const int units_per_week = 168;
2260 hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2265 hours.units_per_week = units_per_week;
2266 memset(hours.bits, 0xFF, units_per_week);
2268 if (pdb_get_hours(pw)) {
2269 memcpy(hours.bits, pdb_get_hours(pw),
2270 MIN(pdb_get_hours_len(pw), units_per_week));
2276 /*************************************************************************
2278 *************************************************************************/
2280 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2281 struct samr_UserInfo1 *r,
2283 struct dom_sid *domain_sid)
2285 const struct dom_sid *sid_group;
2286 uint32_t primary_gid;
2289 sid_group = pdb_get_group_sid(pw);
2292 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2293 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2294 "which conflicts with the domain sid %s. Failing operation.\n",
2295 pdb_get_username(pw), sid_string_dbg(sid_group),
2296 sid_string_dbg(domain_sid)));
2297 return NT_STATUS_UNSUCCESSFUL;
2300 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2301 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2302 r->primary_gid = primary_gid;
2303 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2304 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2306 return NT_STATUS_OK;
2309 /*************************************************************************
2311 *************************************************************************/
2313 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2314 struct samr_UserInfo2 *r,
2317 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2318 r->reserved.string = NULL;
2319 r->country_code = pdb_get_country_code(pw);
2320 r->code_page = pdb_get_code_page(pw);
2322 return NT_STATUS_OK;
2325 /*************************************************************************
2327 *************************************************************************/
2329 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2330 struct samr_UserInfo3 *r,
2332 struct dom_sid *domain_sid)
2334 const struct dom_sid *sid_user, *sid_group;
2335 uint32_t rid, primary_gid;
2337 sid_user = pdb_get_user_sid(pw);
2339 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2340 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2341 "the domain sid %s. Failing operation.\n",
2342 pdb_get_username(pw), sid_string_dbg(sid_user),
2343 sid_string_dbg(domain_sid)));
2344 return NT_STATUS_UNSUCCESSFUL;
2348 sid_group = pdb_get_group_sid(pw);
2351 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2352 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2353 "which conflicts with the domain sid %s. Failing operation.\n",
2354 pdb_get_username(pw), sid_string_dbg(sid_group),
2355 sid_string_dbg(domain_sid)));
2356 return NT_STATUS_UNSUCCESSFUL;
2359 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2360 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2361 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2362 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2363 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2365 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2366 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2367 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2368 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2369 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2370 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2371 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2373 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2375 r->primary_gid = primary_gid;
2376 r->acct_flags = pdb_get_acct_ctrl(pw);
2377 r->bad_password_count = pdb_get_bad_password_count(pw);
2378 r->logon_count = pdb_get_logon_count(pw);
2380 return NT_STATUS_OK;
2383 /*************************************************************************
2385 *************************************************************************/
2387 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2388 struct samr_UserInfo4 *r,
2391 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2393 return NT_STATUS_OK;
2396 /*************************************************************************
2398 *************************************************************************/
2400 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2401 struct samr_UserInfo5 *r,
2403 struct dom_sid *domain_sid)
2405 const struct dom_sid *sid_user, *sid_group;
2406 uint32_t rid, primary_gid;
2408 sid_user = pdb_get_user_sid(pw);
2410 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2411 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2412 "the domain sid %s. Failing operation.\n",
2413 pdb_get_username(pw), sid_string_dbg(sid_user),
2414 sid_string_dbg(domain_sid)));
2415 return NT_STATUS_UNSUCCESSFUL;
2419 sid_group = pdb_get_group_sid(pw);
2422 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2423 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2424 "which conflicts with the domain sid %s. Failing operation.\n",
2425 pdb_get_username(pw), sid_string_dbg(sid_group),
2426 sid_string_dbg(domain_sid)));
2427 return NT_STATUS_UNSUCCESSFUL;
2430 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2431 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2432 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2433 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2435 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2436 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2437 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2438 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2439 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2440 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2441 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2442 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2444 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2446 r->primary_gid = primary_gid;
2447 r->acct_flags = pdb_get_acct_ctrl(pw);
2448 r->bad_password_count = pdb_get_bad_password_count(pw);
2449 r->logon_count = pdb_get_logon_count(pw);
2451 return NT_STATUS_OK;
2454 /*************************************************************************
2456 *************************************************************************/
2458 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2459 struct samr_UserInfo6 *r,
2462 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2463 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2465 return NT_STATUS_OK;
2468 /*************************************************************************
2469 get_user_info_7. Safe. Only gives out account_name.
2470 *************************************************************************/
2472 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2473 struct samr_UserInfo7 *r,
2474 struct samu *smbpass)
2476 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2477 if (!r->account_name.string) {
2478 return NT_STATUS_NO_MEMORY;
2481 return NT_STATUS_OK;
2484 /*************************************************************************
2486 *************************************************************************/
2488 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2489 struct samr_UserInfo8 *r,
2492 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2494 return NT_STATUS_OK;
2497 /*************************************************************************
2498 get_user_info_9. Only gives out primary group SID.
2499 *************************************************************************/
2501 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2502 struct samr_UserInfo9 *r,
2503 struct samu *smbpass)
2505 r->primary_gid = pdb_get_group_rid(smbpass);
2507 return NT_STATUS_OK;
2510 /*************************************************************************
2512 *************************************************************************/
2514 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2515 struct samr_UserInfo10 *r,
2518 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2519 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2521 return NT_STATUS_OK;
2524 /*************************************************************************
2526 *************************************************************************/
2528 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2529 struct samr_UserInfo11 *r,
2532 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2534 return NT_STATUS_OK;
2537 /*************************************************************************
2539 *************************************************************************/
2541 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2542 struct samr_UserInfo12 *r,
2545 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2547 return NT_STATUS_OK;
2550 /*************************************************************************
2552 *************************************************************************/
2554 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2555 struct samr_UserInfo13 *r,
2558 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2560 return NT_STATUS_OK;
2563 /*************************************************************************
2565 *************************************************************************/
2567 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2568 struct samr_UserInfo14 *r,
2571 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2573 return NT_STATUS_OK;
2576 /*************************************************************************
2577 get_user_info_16. Safe. Only gives out acb bits.
2578 *************************************************************************/
2580 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2581 struct samr_UserInfo16 *r,
2582 struct samu *smbpass)
2584 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2586 return NT_STATUS_OK;
2589 /*************************************************************************
2591 *************************************************************************/
2593 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2594 struct samr_UserInfo17 *r,
2597 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2599 return NT_STATUS_OK;
2602 /*************************************************************************
2603 get_user_info_18. OK - this is the killer as it gives out password info.
2604 Ensure that this is only allowed on an encrypted connection with a root
2606 *************************************************************************/
2608 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2609 TALLOC_CTX *mem_ctx,
2610 struct samr_UserInfo18 *r,
2611 struct dom_sid *user_sid)
2613 struct samu *smbpass=NULL;
2615 const uint8_t *nt_pass = NULL;
2616 const uint8_t *lm_pass = NULL;
2620 if (p->transport != NCALRPC) {
2621 return NT_STATUS_INVALID_INFO_CLASS;
2624 if (!security_token_is_system(p->session_info->security_token)) {
2625 return NT_STATUS_ACCESS_DENIED;
2629 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2632 if ( !(smbpass = samu_new( mem_ctx )) ) {
2633 return NT_STATUS_NO_MEMORY;
2636 ret = pdb_getsampwsid(smbpass, user_sid);
2639 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2640 TALLOC_FREE(smbpass);
2641 return root_mode() ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2644 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2646 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2647 TALLOC_FREE(smbpass);
2648 return NT_STATUS_ACCOUNT_DISABLED;
2651 lm_pass = pdb_get_lanman_passwd(smbpass);
2652 if (lm_pass != NULL) {
2653 memcpy(r->lm_pwd.hash, lm_pass, 16);
2654 r->lm_pwd_active = true;
2657 nt_pass = pdb_get_nt_passwd(smbpass);
2658 if (nt_pass != NULL) {
2659 memcpy(r->nt_pwd.hash, nt_pass, 16);
2660 r->nt_pwd_active = true;
2662 r->password_expired = 0; /* FIXME */
2664 TALLOC_FREE(smbpass);
2666 return NT_STATUS_OK;
2669 /*************************************************************************
2671 *************************************************************************/
2673 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2674 struct samr_UserInfo20 *r,
2675 struct samu *sampass)
2677 const char *munged_dial = NULL;
2680 struct lsa_BinaryString *parameters = NULL;
2684 munged_dial = pdb_get_munged_dial(sampass);
2686 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2687 munged_dial, (int)strlen(munged_dial)));
2690 blob = base64_decode_data_blob(munged_dial);
2692 blob = data_blob_string_const_null("");
2695 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2696 data_blob_free(&blob);
2697 if (!NT_STATUS_IS_OK(status)) {
2701 r->parameters = *parameters;
2703 return NT_STATUS_OK;
2707 /*************************************************************************
2709 *************************************************************************/
2711 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2712 struct samr_UserInfo21 *r,
2714 struct dom_sid *domain_sid,
2715 uint32_t acc_granted)
2718 const struct dom_sid *sid_user, *sid_group;
2719 uint32_t rid, primary_gid;
2720 NTTIME force_password_change;
2721 time_t must_change_time;
2722 struct lsa_BinaryString *parameters = NULL;
2723 const char *munged_dial = NULL;
2728 sid_user = pdb_get_user_sid(pw);
2730 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2731 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2732 "the domain sid %s. Failing operation.\n",
2733 pdb_get_username(pw), sid_string_dbg(sid_user),
2734 sid_string_dbg(domain_sid)));
2735 return NT_STATUS_UNSUCCESSFUL;
2739 sid_group = pdb_get_group_sid(pw);
2742 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2743 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2744 "which conflicts with the domain sid %s. Failing operation.\n",
2745 pdb_get_username(pw), sid_string_dbg(sid_group),
2746 sid_string_dbg(domain_sid)));
2747 return NT_STATUS_UNSUCCESSFUL;
2750 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2751 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2752 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2753 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2754 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2756 must_change_time = pdb_get_pass_must_change_time(pw);
2757 if (pdb_is_password_change_time_max(must_change_time)) {
2758 unix_to_nt_time_abs(&force_password_change, must_change_time);
2760 unix_to_nt_time(&force_password_change, must_change_time);
2763 munged_dial = pdb_get_munged_dial(pw);
2765 blob = base64_decode_data_blob(munged_dial);
2767 blob = data_blob_string_const_null("");
2770 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2771 data_blob_free(&blob);
2772 if (!NT_STATUS_IS_OK(status)) {
2776 r->force_password_change = force_password_change;
2778 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2779 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2780 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2781 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2782 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2783 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2784 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2785 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2786 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2788 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2789 r->parameters = *parameters;
2791 r->primary_gid = primary_gid;
2792 r->acct_flags = pdb_get_acct_ctrl(pw);
2793 r->bad_password_count = pdb_get_bad_password_count(pw);
2794 r->logon_count = pdb_get_logon_count(pw);
2795 r->fields_present = pdb_build_fields_present(pw);
2796 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2797 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2798 r->country_code = pdb_get_country_code(pw);
2799 r->code_page = pdb_get_code_page(pw);
2800 r->lm_password_set = 0;
2801 r->nt_password_set = 0;
2806 Look at a user on a real NT4 PDC with usrmgr, press
2807 'ok'. Then you will see that fields_present is set to
2808 0x08f827fa. Look at the user immediately after that again,
2809 and you will see that 0x00fffff is returned. This solves
2810 the problem that you get access denied after having looked
2818 return NT_STATUS_OK;
2821 /*******************************************************************
2823 ********************************************************************/
2825 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
2826 struct samr_QueryUserInfo *r)
2829 union samr_UserInfo *user_info = NULL;
2830 struct samr_user_info *uinfo;
2831 struct dom_sid domain_sid;
2834 struct samu *pwd = NULL;
2835 uint32_t acc_required, acc_granted;
2837 switch (r->in.level) {
2838 case 1: /* UserGeneralInformation */
2839 /* USER_READ_GENERAL */
2840 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2842 case 2: /* UserPreferencesInformation */
2843 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2844 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2845 SAMR_USER_ACCESS_GET_NAME_ETC;
2847 case 3: /* UserLogonInformation */
2848 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2849 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2850 SAMR_USER_ACCESS_GET_LOCALE |
2851 SAMR_USER_ACCESS_GET_LOGONINFO |
2852 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2854 case 4: /* UserLogonHoursInformation */
2855 /* USER_READ_LOGON */
2856 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2858 case 5: /* UserAccountInformation */
2859 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2860 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2861 SAMR_USER_ACCESS_GET_LOCALE |
2862 SAMR_USER_ACCESS_GET_LOGONINFO |
2863 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2865 case 6: /* UserNameInformation */
2866 case 7: /* UserAccountNameInformation */
2867 case 8: /* UserFullNameInformation */
2868 case 9: /* UserPrimaryGroupInformation */
2869 case 13: /* UserAdminCommentInformation */
2870 /* USER_READ_GENERAL */
2871 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2873 case 10: /* UserHomeInformation */
2874 case 11: /* UserScriptInformation */
2875 case 12: /* UserProfileInformation */
2876 case 14: /* UserWorkStationsInformation */
2877 /* USER_READ_LOGON */
2878 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2880 case 16: /* UserControlInformation */
2881 case 17: /* UserExpiresInformation */
2882 case 20: /* UserParametersInformation */
2883 /* USER_READ_ACCOUNT */
2884 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2886 case 21: /* UserAllInformation */
2888 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2890 case 18: /* UserInternal1Information */
2892 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2894 case 23: /* UserInternal4Information */
2895 case 24: /* UserInternal4InformationNew */
2896 case 25: /* UserInternal4InformationNew */
2897 case 26: /* UserInternal5InformationNew */
2899 return NT_STATUS_INVALID_INFO_CLASS;
2903 uinfo = policy_handle_find(p, r->in.user_handle,
2904 acc_required, &acc_granted,
2905 struct samr_user_info, &status);
2906 if (!NT_STATUS_IS_OK(status)) {
2910 domain_sid = uinfo->sid;
2912 sid_split_rid(&domain_sid, &rid);
2914 if (!sid_check_is_in_our_sam(&uinfo->sid))
2915 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2917 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2918 sid_string_dbg(&uinfo->sid)));
2920 user_info = talloc_zero(p->mem_ctx, union samr_UserInfo);
2922 return NT_STATUS_NO_MEMORY;
2925 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2927 if (!(pwd = samu_new(p->mem_ctx))) {
2928 return NT_STATUS_NO_MEMORY;
2932 ret = pdb_getsampwsid(pwd, &uinfo->sid);
2936 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
2938 return NT_STATUS_NO_SUCH_USER;
2941 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2943 samr_clear_sam_passwd(pwd);
2945 switch (r->in.level) {
2947 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
2950 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
2953 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
2956 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
2959 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2962 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
2965 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2968 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
2971 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2974 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
2977 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
2980 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
2983 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
2986 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
2989 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2992 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
2995 /* level 18 is special */
2996 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3000 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3003 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3006 status = NT_STATUS_INVALID_INFO_CLASS;
3010 if (!NT_STATUS_IS_OK(status)) {
3014 *r->out.info = user_info;
3019 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3024 /****************************************************************
3025 ****************************************************************/
3027 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3028 struct samr_QueryUserInfo2 *r)
3030 struct samr_QueryUserInfo u;
3032 u.in.user_handle = r->in.user_handle;
3033 u.in.level = r->in.level;
3034 u.out.info = r->out.info;
3036 return _samr_QueryUserInfo(p, &u);
3039 /*******************************************************************
3040 _samr_GetGroupsForUser
3041 ********************************************************************/
3043 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3044 struct samr_GetGroupsForUser *r)
3046 struct samr_user_info *uinfo;
3047 struct samu *sam_pass=NULL;
3048 struct dom_sid *sids;
3049 struct samr_RidWithAttribute dom_gid;
3050 struct samr_RidWithAttribute *gids = NULL;
3051 uint32_t primary_group_rid;
3052 uint32_t num_groups = 0;
3054 uint32_t i, num_gids;
3057 bool success = False;
3059 struct samr_RidWithAttributeArray *rids = NULL;
3062 * from the SID in the request:
3063 * we should send back the list of DOMAIN GROUPS
3064 * the user is a member of
3066 * and only the DOMAIN GROUPS
3067 * no ALIASES !!! neither aliases of the domain
3068 * nor aliases of the builtin SID
3073 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3075 uinfo = policy_handle_find(p, r->in.user_handle,
3076 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3077 struct samr_user_info, &result);
3078 if (!NT_STATUS_IS_OK(result)) {
3082 rids = talloc_zero(p->mem_ctx, struct samr_RidWithAttributeArray);
3084 return NT_STATUS_NO_MEMORY;
3087 if (!sid_check_is_in_our_sam(&uinfo->sid))
3088 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3090 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3091 return NT_STATUS_NO_MEMORY;
3095 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3099 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3100 sid_string_dbg(&uinfo->sid)));
3101 return NT_STATUS_NO_SUCH_USER;
3106 /* make both calls inside the root block */
3108 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3109 &sids, &unix_gids, &num_groups);
3110 if ( NT_STATUS_IS_OK(result) ) {
3111 success = sid_peek_check_rid(get_global_sam_sid(),
3112 pdb_get_group_sid(sam_pass),
3113 &primary_group_rid);
3117 if (!NT_STATUS_IS_OK(result)) {
3118 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3119 sid_string_dbg(&uinfo->sid)));
3124 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3125 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3126 pdb_get_username(sam_pass)));
3127 TALLOC_FREE(sam_pass);
3128 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3134 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3136 dom_gid.rid = primary_group_rid;
3137 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3139 for (i=0; i<num_groups; i++) {
3141 if (!sid_peek_check_rid(get_global_sam_sid(),
3142 &(sids[i]), &dom_gid.rid)) {
3143 DEBUG(10, ("Found sid %s not in our domain\n",
3144 sid_string_dbg(&sids[i])));
3148 if (dom_gid.rid == primary_group_rid) {
3149 /* We added the primary group directly from the
3150 * sam_account. The other SIDs are unique from
3151 * enum_group_memberships */
3155 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3158 rids->count = num_gids;
3161 *r->out.rids = rids;
3163 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3168 /*******************************************************************
3169 ********************************************************************/
3171 static uint32_t samr_get_server_role(void)
3173 uint32_t role = ROLE_DOMAIN_PDC;
3175 if (lp_server_role() == ROLE_DOMAIN_BDC) {
3176 role = ROLE_DOMAIN_BDC;
3182 /*******************************************************************
3183 ********************************************************************/
3185 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3186 struct samr_DomInfo1 *r)
3188 uint32_t account_policy_temp;
3189 time_t u_expire, u_min_age;
3195 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3196 r->min_password_length = account_policy_temp;
3198 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3199 r->password_history_length = account_policy_temp;
3201 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3202 &r->password_properties);
3204 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3205 u_expire = account_policy_temp;
3207 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3208 u_min_age = account_policy_temp;
3214 unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3215 unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3217 if (lp_check_password_script(talloc_tos()) && *lp_check_password_script(talloc_tos())) {
3218 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3221 return NT_STATUS_OK;
3224 /*******************************************************************
3225 ********************************************************************/
3227 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3228 struct samr_DomGeneralInformation *r,
3229 struct samr_domain_info *dinfo)
3238 r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3239 r->num_groups = count_sam_groups(dinfo->disp_info);
3240 r->num_aliases = count_sam_aliases(dinfo->disp_info);
3242 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3244 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3246 if (!pdb_get_seq_num(&seq_num)) {
3247 seq_num = time(NULL);
3254 r->oem_information.string = lp_server_string(r);
3255 r->domain_name.string = lp_workgroup();
3256 r->primary.string = lp_netbios_name();
3257 r->sequence_num = seq_num;
3258 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3259 r->role = (enum samr_Role) samr_get_server_role();
3262 return NT_STATUS_OK;
3265 /*******************************************************************
3266 ********************************************************************/
3268 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3269 struct samr_DomInfo3 *r)
3279 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3280 u_logout = (time_t)ul;
3287 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3289 return NT_STATUS_OK;
3292 /*******************************************************************
3293 ********************************************************************/
3295 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3296 struct samr_DomOEMInformation *r)
3298 r->oem_information.string = lp_server_string(r);
3300 return NT_STATUS_OK;
3303 /*******************************************************************
3304 ********************************************************************/
3306 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3307 struct samr_DomInfo5 *r)
3309 r->domain_name.string = get_global_sam_name();
3311 return NT_STATUS_OK;
3314 /*******************************************************************
3315 ********************************************************************/
3317 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3318 struct samr_DomInfo6 *r)
3320 /* NT returns its own name when a PDC. win2k and later
3321 * only the name of the PDC if itself is a BDC (samba4
3323 r->primary.string = lp_netbios_name();
3325 return NT_STATUS_OK;
3328 /*******************************************************************
3329 ********************************************************************/
3331 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3332 struct samr_DomInfo7 *r)
3334 r->role = (enum samr_Role) samr_get_server_role();
3336 return NT_STATUS_OK;
3339 /*******************************************************************
3340 ********************************************************************/
3342 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3343 struct samr_DomInfo8 *r)
3351 if (!pdb_get_seq_num(&seq_num)) {
3352 seq_num = time(NULL);
3359 r->sequence_num = seq_num;
3360 r->domain_create_time = 0;
3362 return NT_STATUS_OK;
3365 /*******************************************************************
3366 ********************************************************************/
3368 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3369 struct samr_DomInfo9 *r)
3371 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3373 return NT_STATUS_OK;
3376 /*******************************************************************
3377 ********************************************************************/
3379 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3380 struct samr_DomGeneralInformation2 *r,
3381 struct samr_domain_info *dinfo)
3384 uint32_t account_policy_temp;
3385 time_t u_lock_duration, u_reset_time;
3387 status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3388 if (!NT_STATUS_IS_OK(status)) {
3396 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3397 u_lock_duration = account_policy_temp;
3398 if (u_lock_duration != -1) {
3399 u_lock_duration *= 60;
3402 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3403 u_reset_time = account_policy_temp * 60;
3405 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3406 r->lockout_threshold = account_policy_temp;
3412 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3413 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3415 return NT_STATUS_OK;
3418 /*******************************************************************
3419 ********************************************************************/
3421 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3422 struct samr_DomInfo12 *r)
3424 uint32_t account_policy_temp;
3425 time_t u_lock_duration, u_reset_time;
3431 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3432 u_lock_duration = account_policy_temp;
3433 if (u_lock_duration != -1) {
3434 u_lock_duration *= 60;
3437 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3438 u_reset_time = account_policy_temp * 60;
3440 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3441 r->lockout_threshold = account_policy_temp;
3447 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3448 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3450 return NT_STATUS_OK;
3453 /*******************************************************************
3454 ********************************************************************/
3456 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3457 struct samr_DomInfo13 *r)
3465 if (!pdb_get_seq_num(&seq_num)) {
3466 seq_num = time(NULL);
3473 r->sequence_num = seq_num;
3474 r->domain_create_time = 0;
3475 r->modified_count_at_last_promotion = 0;
3477 return NT_STATUS_OK;
3480 /*******************************************************************
3481 _samr_QueryDomainInfo
3482 ********************************************************************/
3484 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3485 struct samr_QueryDomainInfo *r)
3487 NTSTATUS status = NT_STATUS_OK;
3488 struct samr_domain_info *dinfo;
3489 union samr_DomainInfo *dom_info;
3491 uint32_t acc_required;
3493 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3495 switch (r->in.level) {
3496 case 1: /* DomainPasswordInformation */
3497 case 12: /* DomainLockoutInformation */
3498 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3499 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3501 case 11: /* DomainGeneralInformation2 */
3502 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3503 * DOMAIN_READ_OTHER_PARAMETERS */
3504 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3505 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3507 case 2: /* DomainGeneralInformation */
3508 case 3: /* DomainLogoffInformation */
3509 case 4: /* DomainOemInformation */
3510 case 5: /* DomainReplicationInformation */
3511 case 6: /* DomainReplicationInformation */
3512 case 7: /* DomainServerRoleInformation */
3513 case 8: /* DomainModifiedInformation */
3514 case 9: /* DomainStateInformation */
3515 case 10: /* DomainUasInformation */
3516 case 13: /* DomainModifiedInformation2 */
3517 /* DOMAIN_READ_OTHER_PARAMETERS */
3518 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3521 return NT_STATUS_INVALID_INFO_CLASS;
3524 dinfo = policy_handle_find(p, r->in.domain_handle,
3526 struct samr_domain_info, &status);
3527 if (!NT_STATUS_IS_OK(status)) {
3531 dom_info = talloc_zero(p->mem_ctx, union samr_DomainInfo);
3533 return NT_STATUS_NO_MEMORY;
3536 switch (r->in.level) {
3538 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3541 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3544 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3547 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3550 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3553 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3556 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3559 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3562 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3565 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3568 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3571 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3574 return NT_STATUS_INVALID_INFO_CLASS;
3577 if (!NT_STATUS_IS_OK(status)) {
3581 *r->out.info = dom_info;
3583 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3588 /* W2k3 seems to use the same check for all 3 objects that can be created via
3589 * SAMR, if you try to create for example "Dialup" as an alias it says
3590 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3593 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3595 enum lsa_SidType type;
3598 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3601 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3602 * whether the name already exists */
3603 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3604 NULL, NULL, NULL, &type);
3608 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3609 return NT_STATUS_OK;
3612 DEBUG(5, ("trying to create %s, exists as %s\n",
3613 new_name, sid_type_lookup(type)));
3615 if (type == SID_NAME_DOM_GRP) {
3616 return NT_STATUS_GROUP_EXISTS;
3618 if (type == SID_NAME_ALIAS) {
3619 return NT_STATUS_ALIAS_EXISTS;
3622 /* Yes, the default is NT_STATUS_USER_EXISTS */
3623 return NT_STATUS_USER_EXISTS;
3626 /*******************************************************************
3628 ********************************************************************/
3630 NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3631 struct samr_CreateUser2 *r)
3633 const char *account = NULL;
3635 uint32_t acb_info = r->in.acct_flags;
3636 struct samr_domain_info *dinfo;
3637 struct samr_user_info *uinfo;
3639 uint32_t acc_granted;
3640 struct security_descriptor *psd;
3642 /* check this, when giving away 'add computer to domain' privs */
3643 uint32_t des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3644 bool can_add_account = False;
3646 /* Which privilege is needed to override the ACL? */
3647 enum sec_privilege needed_priv = SEC_PRIV_INVALID;
3649 dinfo = policy_handle_find(p, r->in.domain_handle,
3650 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3651 struct samr_domain_info, &nt_status);
3652 if (!NT_STATUS_IS_OK(nt_status)) {
3656 if (sid_check_is_builtin(&dinfo->sid)) {
3657 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3658 return NT_STATUS_ACCESS_DENIED;
3661 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3662 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3663 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3664 this parameter is not an account type */
3665 return NT_STATUS_INVALID_PARAMETER;
3668 account = r->in.account_name->string;
3669 if (account == NULL) {
3670 return NT_STATUS_NO_MEMORY;
3673 nt_status = can_create(p->mem_ctx, account);
3674 if (!NT_STATUS_IS_OK(nt_status)) {
3678 /* determine which user right we need to check based on the acb_info */
3681 can_add_account = true;
3682 } else if (acb_info & ACB_WSTRUST) {
3683 needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
3684 can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_MACHINE_ACCOUNT);
3685 } else if (acb_info & ACB_NORMAL &&
3686 (account[strlen(account)-1] != '$')) {
3687 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3688 account for domain trusts and changes the ACB flags later */
3689 needed_priv = SEC_PRIV_ADD_USERS;
3690 can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS);
3691 } else if (lp_enable_privileges()) {
3692 /* implicit assumption of a BDC or domain trust account here
3693 * (we already check the flags earlier) */
3694 /* only Domain Admins can add a BDC or domain trust */
3695 can_add_account = nt_token_check_domain_rid(
3696 p->session_info->security_token,
3697 DOMAIN_RID_ADMINS );
3700 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3701 uidtoname(p->session_info->unix_token->uid),
3702 can_add_account ? "True":"False" ));
3704 if (!can_add_account) {
3705 return NT_STATUS_ACCESS_DENIED;
3708 /********** BEGIN Admin BLOCK **********/
3711 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3715 /********** END Admin BLOCK **********/
3717 /* now check for failure */
3719 if ( !NT_STATUS_IS_OK(nt_status) )
3722 /* Get the user's SID */
3724 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3726 map_max_allowed_access(p->session_info->security_token,
3727 p->session_info->unix_token,
3730 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3731 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3732 se_map_generic(&des_access, &usr_generic_mapping);
3735 * JRA - TESTME. We just created this user so we
3736 * had rights to create them. Do we need to check
3737 * any further access on this object ? Can't we
3738 * just assume we have all the rights we need ?
3741 nt_status = access_check_object(psd, p->session_info->security_token,
3742 needed_priv, SEC_PRIV_INVALID,
3743 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(struct 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(struct pipes_struct *p,
3790 struct samr_Connect *r)
3792 uint32_t acc_granted;
3793 struct policy_handle hnd;
3794 uint32_t des_access = r->in.access_mask;
3799 if (!pipe_access_check(p)) {
3800 DEBUG(3, ("access denied to _samr_Connect\n"));
3801 return NT_STATUS_ACCESS_DENIED;
3804 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3805 was observed from a win98 client trying to enumerate users (when configured
3806 user level access control on shares) --jerry */
3808 map_max_allowed_access(p->session_info->security_token,
3809 p->session_info->unix_token,
3812 se_map_generic( &des_access, &sam_generic_mapping );
3814 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3815 |SAMR_ACCESS_LOOKUP_DOMAIN);
3817 /* set up the SAMR connect_anon response */
3819 (void)policy_handle_create(p, &hnd, acc_granted,
3820 struct samr_connect_info,
3822 if (!NT_STATUS_IS_OK(status)) {
3826 *r->out.connect_handle = hnd;
3827 return NT_STATUS_OK;
3830 /*******************************************************************
3832 ********************************************************************/
3834 NTSTATUS _samr_Connect2(struct pipes_struct *p,
3835 struct samr_Connect2 *r)
3837 struct policy_handle hnd;
3838 struct security_descriptor *psd = NULL;
3839 uint32_t acc_granted;
3840 uint32_t des_access = r->in.access_mask;
3843 const char *fn = "_samr_Connect2";
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->session_info->security_token,
3870 p->session_info->unix_token,
3873 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3874 se_map_generic(&des_access, &sam_generic_mapping);
3876 nt_status = access_check_object(psd, p->session_info->security_token,
3877 SEC_PRIV_INVALID, SEC_PRIV_INVALID,
3878 0, des_access, &acc_granted, fn);
3880 if ( !NT_STATUS_IS_OK(nt_status) )
3883 (void)policy_handle_create(p, &hnd, acc_granted,
3884 struct samr_connect_info, &nt_status);
3885 if (!NT_STATUS_IS_OK(nt_status)) {
3889 DEBUG(5,("%s: %d\n", fn, __LINE__));
3891 *r->out.connect_handle = hnd;
3892 return NT_STATUS_OK;
3895 /****************************************************************
3897 ****************************************************************/
3899 NTSTATUS _samr_Connect3(struct pipes_struct *p,
3900 struct samr_Connect3 *r)
3902 struct samr_Connect2 c;
3904 c.in.system_name = r->in.system_name;
3905 c.in.access_mask = r->in.access_mask;
3906 c.out.connect_handle = r->out.connect_handle;
3908 return _samr_Connect2(p, &c);
3911 /*******************************************************************
3913 ********************************************************************/
3915 NTSTATUS _samr_Connect4(struct pipes_struct *p,
3916 struct samr_Connect4 *r)
3918 struct samr_Connect2 c;
3920 c.in.system_name = r->in.system_name;
3921 c.in.access_mask = r->in.access_mask;
3922 c.out.connect_handle = r->out.connect_handle;
3924 return _samr_Connect2(p, &c);
3927 /*******************************************************************
3929 ********************************************************************/
3931 NTSTATUS _samr_Connect5(struct pipes_struct *p,
3932 struct samr_Connect5 *r)
3935 struct samr_Connect2 c;
3936 struct samr_ConnectInfo1 info1;
3938 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3941 c.in.system_name = r->in.system_name;
3942 c.in.access_mask = r->in.access_mask;
3943 c.out.connect_handle = r->out.connect_handle;
3945 *r->out.level_out = 1;
3947 status = _samr_Connect2(p, &c);
3948 if (!NT_STATUS_IS_OK(status)) {
3952 r->out.info_out->info1 = info1;
3954 return NT_STATUS_OK;
3957 /**********************************************************************
3959 **********************************************************************/
3961 NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
3962 struct samr_LookupDomain *r)
3965 const char *domain_name;
3966 struct dom_sid *sid = NULL;
3968 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3969 Reverted that change so we will work with RAS servers again */
3971 (void)policy_handle_find(p, r->in.connect_handle,
3972 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3973 struct samr_connect_info,
3975 if (!NT_STATUS_IS_OK(status)) {
3979 domain_name = r->in.domain_name->string;
3981 return NT_STATUS_INVALID_PARAMETER;
3984 sid = talloc_zero(p->mem_ctx, struct dom_sid2);
3986 return NT_STATUS_NO_MEMORY;
3989 if (strequal(domain_name, builtin_domain_name())) {
3990 sid_copy(sid, &global_sid_Builtin);
3992 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3993 status = NT_STATUS_NO_SUCH_DOMAIN;
3997 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3998 sid_string_dbg(sid)));
4005 /**********************************************************************
4007 **********************************************************************/
4009 NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4010 struct samr_EnumDomains *r)
4013 uint32_t num_entries = 2;
4014 struct samr_SamEntry *entry_array = NULL;
4015 struct samr_SamArray *sam;
4017 (void)policy_handle_find(p, r->in.connect_handle,
4018 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4019 struct samr_connect_info, &status);
4020 if (!NT_STATUS_IS_OK(status)) {
4024 sam = talloc_zero(p->mem_ctx, struct samr_SamArray);
4026 return NT_STATUS_NO_MEMORY;
4029 entry_array = talloc_zero_array(p->mem_ctx,
4030 struct samr_SamEntry,
4033 return NT_STATUS_NO_MEMORY;
4036 entry_array[0].idx = 0;
4037 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4039 entry_array[1].idx = 1;
4040 init_lsa_String(&entry_array[1].name, "Builtin");
4042 sam->count = num_entries;
4043 sam->entries = entry_array;
4046 *r->out.num_entries = num_entries;
4051 /*******************************************************************
4053 ********************************************************************/
4055 NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4056 struct samr_OpenAlias *r)
4059 uint32_t alias_rid = r->in.rid;
4060 struct samr_alias_info *ainfo;
4061 struct samr_domain_info *dinfo;
4062 struct security_descriptor *psd = NULL;
4063 uint32_t acc_granted;
4064 uint32_t 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->session_info->security_token,
4083 p->session_info->unix_token,
4086 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4087 se_map_generic(&des_access,&ali_generic_mapping);
4089 status = access_check_object(psd, p->session_info->security_token,
4090 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
4091 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4092 des_access, &acc_granted, "_samr_OpenAlias");
4094 if ( !NT_STATUS_IS_OK(status) )
4098 /* Check we actually have the requested alias */
4099 enum lsa_SidType type;
4104 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4107 if (!result || (type != SID_NAME_ALIAS)) {
4108 return NT_STATUS_NO_SUCH_ALIAS;
4111 /* make sure there is a mapping */
4113 if ( !sid_to_gid( &sid, &gid ) ) {
4114 return NT_STATUS_NO_SUCH_ALIAS;
4119 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4120 struct samr_alias_info, &status);
4121 if (!NT_STATUS_IS_OK(status)) {
4126 return NT_STATUS_OK;
4129 /*******************************************************************
4131 ********************************************************************/
4133 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4134 struct samr_UserInfo2 *id2,
4138 DEBUG(5,("set_user_info_2: NULL id2\n"));
4139 return NT_STATUS_ACCESS_DENIED;
4142 copy_id2_to_sam_passwd(pwd, id2);
4144 return pdb_update_sam_account(pwd);
4147 /*******************************************************************
4149 ********************************************************************/
4151 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4152 struct samr_UserInfo4 *id4,
4156 DEBUG(5,("set_user_info_2: NULL id4\n"));
4157 return NT_STATUS_ACCESS_DENIED;
4160 copy_id4_to_sam_passwd(pwd, id4);
4162 return pdb_update_sam_account(pwd);
4165 /*******************************************************************
4167 ********************************************************************/
4169 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4170 struct samr_UserInfo6 *id6,
4174 DEBUG(5,("set_user_info_6: NULL id6\n"));
4175 return NT_STATUS_ACCESS_DENIED;
4178 copy_id6_to_sam_passwd(pwd, id6);
4180 return pdb_update_sam_account(pwd);
4183 /*******************************************************************
4185 ********************************************************************/
4187 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4188 struct samr_UserInfo7 *id7,
4194 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4195 return NT_STATUS_ACCESS_DENIED;
4198 if (!id7->account_name.string) {
4199 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4200 return NT_STATUS_ACCESS_DENIED;
4203 /* check to see if the new username already exists. Note: we can't
4204 reliably lock all backends, so there is potentially the
4205 possibility that a user can be created in between this check and
4206 the rename. The rename should fail, but may not get the
4207 exact same failure status code. I think this is small enough
4208 of a window for this type of operation and the results are
4209 simply that the rename fails with a slightly different status
4210 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4212 rc = can_create(mem_ctx, id7->account_name.string);
4214 /* when there is nothing to change, we're done here */
4215 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4216 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4217 return NT_STATUS_OK;
4219 if (!NT_STATUS_IS_OK(rc)) {
4223 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4228 /*******************************************************************
4230 ********************************************************************/
4232 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4233 struct samr_UserInfo8 *id8,
4237 DEBUG(5,("set_user_info_8: NULL id8\n"));
4238 return NT_STATUS_ACCESS_DENIED;
4241 copy_id8_to_sam_passwd(pwd, id8);
4243 return pdb_update_sam_account(pwd);
4246 /*******************************************************************
4248 ********************************************************************/
4250 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4251 struct samr_UserInfo10 *id10,
4255 DEBUG(5,("set_user_info_8: NULL id10\n"));
4256 return NT_STATUS_ACCESS_DENIED;
4259 copy_id10_to_sam_passwd(pwd, id10);
4261 return pdb_update_sam_account(pwd);
4264 /*******************************************************************
4266 ********************************************************************/
4268 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4269 struct samr_UserInfo11 *id11,
4273 DEBUG(5,("set_user_info_11: NULL id11\n"));
4274 return NT_STATUS_ACCESS_DENIED;
4277 copy_id11_to_sam_passwd(pwd, id11);
4279 return pdb_update_sam_account(pwd);
4282 /*******************************************************************
4284 ********************************************************************/
4286 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4287 struct samr_UserInfo12 *id12,
4291 DEBUG(5,("set_user_info_12: NULL id12\n"));
4292 return NT_STATUS_ACCESS_DENIED;
4295 copy_id12_to_sam_passwd(pwd, id12);
4297 return pdb_update_sam_account(pwd);
4300 /*******************************************************************
4302 ********************************************************************/
4304 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4305 struct samr_UserInfo13 *id13,
4309 DEBUG(5,("set_user_info_13: NULL id13\n"));
4310 return NT_STATUS_ACCESS_DENIED;
4313 copy_id13_to_sam_passwd(pwd, id13);
4315 return pdb_update_sam_account(pwd);
4318 /*******************************************************************
4320 ********************************************************************/
4322 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4323 struct samr_UserInfo14 *id14,
4327 DEBUG(5,("set_user_info_14: NULL id14\n"));
4328 return NT_STATUS_ACCESS_DENIED;
4331 copy_id14_to_sam_passwd(pwd, id14);
4333 return pdb_update_sam_account(pwd);
4336 /*******************************************************************
4338 ********************************************************************/
4340 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4341 struct samr_UserInfo16 *id16,
4345 DEBUG(5,("set_user_info_16: NULL id16\n"));
4346 return NT_STATUS_ACCESS_DENIED;
4349 copy_id16_to_sam_passwd(pwd, id16);
4351 return pdb_update_sam_account(pwd);
4354 /*******************************************************************
4356 ********************************************************************/
4358 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4359 struct samr_UserInfo17 *id17,
4363 DEBUG(5,("set_user_info_17: NULL id17\n"));
4364 return NT_STATUS_ACCESS_DENIED;
4367 copy_id17_to_sam_passwd(pwd, id17);
4369 return pdb_update_sam_account(pwd);
4372 /*******************************************************************
4374 ********************************************************************/
4376 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4377 TALLOC_CTX *mem_ctx,
4378 DATA_BLOB *session_key,
4382 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4383 return NT_STATUS_INVALID_PARAMETER;
4386 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4387 if (!session_key->length) {
4388 return NT_STATUS_NO_USER_SESSION_KEY;
4392 if (id18->nt_pwd_active) {
4396 in = data_blob_const(id18->nt_pwd.hash, 16);
4397 out = data_blob_talloc_zero(mem_ctx, 16);
4399 sess_crypt_blob(&out, &in, session_key, false);
4401 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4402 return NT_STATUS_ACCESS_DENIED;
4405 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4408 if (id18->lm_pwd_active) {
4412 in = data_blob_const(id18->lm_pwd.hash, 16);
4413 out = data_blob_talloc_zero(mem_ctx, 16);
4415 sess_crypt_blob(&out, &in, session_key, false);
4417 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4418 return NT_STATUS_ACCESS_DENIED;
4421 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4424 copy_id18_to_sam_passwd(pwd, id18);
4426 return pdb_update_sam_account(pwd);
4429 /*******************************************************************
4431 ********************************************************************/
4433 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4434 struct samr_UserInfo20 *id20,
4438 DEBUG(5,("set_user_info_20: NULL id20\n"));
4439 return NT_STATUS_ACCESS_DENIED;
4442 copy_id20_to_sam_passwd(pwd, id20);
4444 return pdb_update_sam_account(pwd);
4447 /*******************************************************************
4449 ********************************************************************/
4451 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4452 TALLOC_CTX *mem_ctx,
4453 DATA_BLOB *session_key,
4459 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4460 return NT_STATUS_INVALID_PARAMETER;
4463 if (id21->fields_present == 0) {
4464 return NT_STATUS_INVALID_PARAMETER;
4467 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4468 return NT_STATUS_ACCESS_DENIED;
4471 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4472 if (id21->nt_password_set) {
4475 if ((id21->nt_owf_password.length != 16) ||
4476 (id21->nt_owf_password.size != 16)) {
4477 return NT_STATUS_INVALID_PARAMETER;
4480 if (!session_key->length) {
4481 return NT_STATUS_NO_USER_SESSION_KEY;
4484 in = data_blob_const(id21->nt_owf_password.array, 16);
4485 out = data_blob_talloc_zero(mem_ctx, 16);
4487 sess_crypt_blob(&out, &in, session_key, false);
4489 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4490 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4494 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4495 if (id21->lm_password_set) {
4498 if ((id21->lm_owf_password.length != 16) ||
4499 (id21->lm_owf_password.size != 16)) {
4500 return NT_STATUS_INVALID_PARAMETER;
4503 if (!session_key->length) {
4504 return NT_STATUS_NO_USER_SESSION_KEY;
4507 in = data_blob_const(id21->lm_owf_password.array, 16);
4508 out = data_blob_talloc_zero(mem_ctx, 16);
4510 sess_crypt_blob(&out, &in, session_key, false);
4512 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4513 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4517 /* we need to separately check for an account rename first */
4519 if (id21->account_name.string &&
4520 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4523 /* check to see if the new username already exists. Note: we can't
4524 reliably lock all backends, so there is potentially the
4525 possibility that a user can be created in between this check and
4526 the rename. The rename should fail, but may not get the
4527 exact same failure status code. I think this is small enough
4528 of a window for this type of operation and the results are
4529 simply that the rename fails with a slightly different status
4530 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4532 status = can_create(mem_ctx, id21->account_name.string);
4533 if (!NT_STATUS_IS_OK(status)) {
4537 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4539 if (!NT_STATUS_IS_OK(status)) {
4540 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4541 nt_errstr(status)));
4545 /* set the new username so that later
4546 functions can work on the new account */
4547 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4550 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4553 * The funny part about the previous two calls is
4554 * that pwd still has the password hashes from the
4555 * passdb entry. These have not been updated from
4556 * id21. I don't know if they need to be set. --jerry
4559 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4560 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4561 if ( !NT_STATUS_IS_OK(status) ) {
4566 /* Don't worry about writing out the user account since the
4567 primary group SID is generated solely from the user's Unix
4570 /* write the change out */
4571 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4575 return NT_STATUS_OK;
4578 /*******************************************************************
4580 ********************************************************************/
4582 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4583 struct samr_UserInfo23 *id23,
4587 char *plaintext_buf = NULL;
4593 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4594 return NT_STATUS_INVALID_PARAMETER;
4597 if (id23->info.fields_present == 0) {
4598 return NT_STATUS_INVALID_PARAMETER;
4601 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4602 return NT_STATUS_ACCESS_DENIED;
4605 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4606 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4608 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4609 pdb_get_username(pwd)));
4611 if (!decode_pw_buffer(mem_ctx,
4612 id23->password.data,
4616 return NT_STATUS_WRONG_PASSWORD;
4619 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4620 return NT_STATUS_ACCESS_DENIED;
4624 copy_id23_to_sam_passwd(pwd, id23);
4626 acct_ctrl = pdb_get_acct_ctrl(pwd);
4628 /* if it's a trust account, don't update /etc/passwd */
4629 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4630 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4631 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4632 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4633 } else if (plaintext_buf) {
4634 /* update the UNIX password */
4635 if (lp_unix_password_sync() ) {
4636 struct passwd *passwd;
4637 if (pdb_get_username(pwd) == NULL) {
4638 DEBUG(1, ("chgpasswd: User without name???\n"));
4639 return NT_STATUS_ACCESS_DENIED;
4642 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4643 if (passwd == NULL) {
4644 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4647 if(!chgpasswd(pdb_get_username(pwd), rhost,
4648 passwd, "", plaintext_buf, True)) {
4649 return NT_STATUS_ACCESS_DENIED;
4651 TALLOC_FREE(passwd);
4655 if (plaintext_buf) {
4656 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4659 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4660 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4665 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4669 return NT_STATUS_OK;
4672 /*******************************************************************
4674 ********************************************************************/
4676 static bool set_user_info_pw(uint8_t *pass, const char *rhost, struct samu *pwd)
4679 char *plaintext_buf = NULL;
4682 DEBUG(5, ("Attempting administrator password change for user %s\n",
4683 pdb_get_username(pwd)));
4685 acct_ctrl = pdb_get_acct_ctrl(pwd);
4687 if (!decode_pw_buffer(talloc_tos(),
4695 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4699 /* if it's a trust account, don't update /etc/passwd */
4700 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4701 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4702 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4703 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4705 /* update the UNIX password */
4706 if (lp_unix_password_sync()) {
4707 struct passwd *passwd;
4709 if (pdb_get_username(pwd) == NULL) {
4710 DEBUG(1, ("chgpasswd: User without name???\n"));
4714 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4715 if (passwd == NULL) {
4716 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4719 if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
4720 "", plaintext_buf, True)) {
4723 TALLOC_FREE(passwd);
4727 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4729 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4734 /*******************************************************************
4736 ********************************************************************/
4738 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4740 struct samr_UserInfo24 *id24,
4746 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4747 return NT_STATUS_INVALID_PARAMETER;
4750 if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
4751 return NT_STATUS_WRONG_PASSWORD;
4754 copy_id24_to_sam_passwd(pwd, id24);
4756 status = pdb_update_sam_account(pwd);
4757 if (!NT_STATUS_IS_OK(status)) {
4761 return NT_STATUS_OK;
4764 /*******************************************************************
4766 ********************************************************************/
4768 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4770 struct samr_UserInfo25 *id25,
4776 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4777 return NT_STATUS_INVALID_PARAMETER;
4780 if (id25->info.fields_present == 0) {
4781 return NT_STATUS_INVALID_PARAMETER;
4784 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4785 return NT_STATUS_ACCESS_DENIED;
4788 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4789 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4791 if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
4792 return NT_STATUS_WRONG_PASSWORD;
4796 copy_id25_to_sam_passwd(pwd, id25);
4798 /* write the change out */
4799 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4804 * We need to "pdb_update_sam_account" before the unix primary group
4805 * is set, because the idealx scripts would also change the
4806 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4807 * the delete explicit / add explicit, which would then fail to find
4808 * the previous primaryGroupSid value.
4811 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4812 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4813 if ( !NT_STATUS_IS_OK(status) ) {
4818 return NT_STATUS_OK;
4821 /*******************************************************************
4823 ********************************************************************/
4825 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4827 struct samr_UserInfo26 *id26,
4833 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4834 return NT_STATUS_INVALID_PARAMETER;
4837 if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
4838 return NT_STATUS_WRONG_PASSWORD;
4841 copy_id26_to_sam_passwd(pwd, id26);
4843 status = pdb_update_sam_account(pwd);
4844 if (!NT_STATUS_IS_OK(status)) {
4848 return NT_STATUS_OK;
4851 /*************************************************************
4852 **************************************************************/
4854 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4856 uint32_t acc_required = 0;
4858 /* USER_ALL_USERNAME */
4859 if (fields & SAMR_FIELD_ACCOUNT_NAME)
4860 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4861 /* USER_ALL_FULLNAME */
4862 if (fields & SAMR_FIELD_FULL_NAME)
4863 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4864 /* USER_ALL_PRIMARYGROUPID */
4865 if (fields & SAMR_FIELD_PRIMARY_GID)
4866 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4867 /* USER_ALL_HOMEDIRECTORY */
4868 if (fields & SAMR_FIELD_HOME_DIRECTORY)
4869 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4870 /* USER_ALL_HOMEDIRECTORYDRIVE */
4871 if (fields & SAMR_FIELD_HOME_DRIVE)
4872 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4873 /* USER_ALL_SCRIPTPATH */
4874 if (fields & SAMR_FIELD_LOGON_SCRIPT)
4875 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4876 /* USER_ALL_PROFILEPATH */
4877 if (fields & SAMR_FIELD_PROFILE_PATH)
4878 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4879 /* USER_ALL_ADMINCOMMENT */
4880 if (fields & SAMR_FIELD_COMMENT)
4881 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4882 /* USER_ALL_WORKSTATIONS */
4883 if (fields & SAMR_FIELD_WORKSTATIONS)
4884 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4885 /* USER_ALL_LOGONHOURS */
4886 if (fields & SAMR_FIELD_LOGON_HOURS)
4887 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4888 /* USER_ALL_ACCOUNTEXPIRES */
4889 if (fields & SAMR_FIELD_ACCT_EXPIRY)
4890 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4891 /* USER_ALL_USERACCOUNTCONTROL */
4892 if (fields & SAMR_FIELD_ACCT_FLAGS)
4893 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4894 /* USER_ALL_PARAMETERS */
4895 if (fields & SAMR_FIELD_PARAMETERS)
4896 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4897 /* USER_ALL_USERCOMMENT */
4898 if (fields & SAMR_FIELD_COMMENT)
4899 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4900 /* USER_ALL_COUNTRYCODE */
4901 if (fields & SAMR_FIELD_COUNTRY_CODE)
4902 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4903 /* USER_ALL_CODEPAGE */
4904 if (fields & SAMR_FIELD_CODE_PAGE)
4905 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4906 /* USER_ALL_NTPASSWORDPRESENT */
4907 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
4908 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4909 /* USER_ALL_LMPASSWORDPRESENT */
4910 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
4911 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4912 /* USER_ALL_PASSWORDEXPIRED */
4913 if (fields & SAMR_FIELD_EXPIRED_FLAG)
4914 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4916 return acc_required;
4919 /*******************************************************************
4921 ********************************************************************/
4923 NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
4924 struct samr_SetUserInfo *r)
4926 struct samr_user_info *uinfo;
4928 struct samu *pwd = NULL;
4929 union samr_UserInfo *info = r->in.info;
4930 uint32_t acc_required = 0;
4931 uint32_t fields = 0;
4934 DATA_BLOB session_key;
4936 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4938 /* This is tricky. A WinXP domain join sets
4939 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4940 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4941 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4942 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4943 we'll use the set from the WinXP join as the basis. */
4945 switch (r->in.level) {
4946 case 2: /* UserPreferencesInformation */
4947 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
4948 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
4950 case 4: /* UserLogonHoursInformation */
4951 case 6: /* UserNameInformation */
4952 case 7: /* UserAccountNameInformation */
4953 case 8: /* UserFullNameInformation */
4954 case 9: /* UserPrimaryGroupInformation */
4955 case 10: /* UserHomeInformation */
4956 case 11: /* UserScriptInformation */
4957 case 12: /* UserProfileInformation */
4958 case 13: /* UserAdminCommentInformation */
4959 case 14: /* UserWorkStationsInformation */
4960 case 16: /* UserControlInformation */
4961 case 17: /* UserExpiresInformation */
4962 case 20: /* UserParametersInformation */
4963 /* USER_WRITE_ACCOUNT */
4964 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
4966 case 18: /* UserInternal1Information */
4967 /* FIXME: gd, this is a guess */
4968 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4970 case 21: /* UserAllInformation */
4971 fields = info->info21.fields_present;
4972 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4974 case 23: /* UserInternal4Information */
4975 fields = info->info23.info.fields_present;
4976 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4978 case 25: /* UserInternal4InformationNew */
4979 fields = info->info25.info.fields_present;
4980 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4982 case 24: /* UserInternal5Information */
4983 case 26: /* UserInternal5InformationNew */
4984 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4987 return NT_STATUS_INVALID_INFO_CLASS;
4990 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
4991 struct samr_user_info, &status);
4992 if (!NT_STATUS_IS_OK(status)) {
4996 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4997 sid_string_dbg(&uinfo->sid), r->in.level));
5000 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5001 return NT_STATUS_INVALID_INFO_CLASS;
5004 if (!(pwd = samu_new(NULL))) {
5005 return NT_STATUS_NO_MEMORY;
5009 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5014 return NT_STATUS_NO_SUCH_USER;
5017 rhost = tsocket_address_inet_addr_string(p->remote_address,
5019 if (rhost == NULL) {
5020 return NT_STATUS_NO_MEMORY;
5023 /* ================ BEGIN Privilege BLOCK ================ */
5027 /* ok! user info levels (lots: see MSDEV help), off we go... */
5029 switch (r->in.level) {
5032 status = set_user_info_2(p->mem_ctx,
5037 status = set_user_info_4(p->mem_ctx,
5042 status = set_user_info_6(p->mem_ctx,
5047 status = set_user_info_7(p->mem_ctx,
5052 status = set_user_info_8(p->mem_ctx,
5057 status = set_user_info_10(p->mem_ctx,
5058 &info->info10, pwd);
5062 status = set_user_info_11(p->mem_ctx,
5063 &info->info11, pwd);
5067 status = set_user_info_12(p->mem_ctx,
5068 &info->info12, pwd);
5072 status = set_user_info_13(p->mem_ctx,
5073 &info->info13, pwd);
5077 status = set_user_info_14(p->mem_ctx,
5078 &info->info14, pwd);
5082 status = set_user_info_16(p->mem_ctx,
5083 &info->info16, pwd);
5087 status = set_user_info_17(p->mem_ctx,
5088 &info->info17, pwd);
5092 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5093 if(!NT_STATUS_IS_OK(status)) {
5096 /* Used by AS/U JRA. */
5097 status = set_user_info_18(&info->info18,
5104 status = set_user_info_20(p->mem_ctx,
5105 &info->info20, pwd);
5109 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5110 if(!NT_STATUS_IS_OK(status)) {
5113 status = set_user_info_21(&info->info21,
5120 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5121 if(!NT_STATUS_IS_OK(status)) {
5124 arcfour_crypt_blob(info->info23.password.data, 516,
5127 dump_data(100, info->info23.password.data, 516);
5129 status = set_user_info_23(p->mem_ctx,
5136 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5137 if(!NT_STATUS_IS_OK(status)) {
5140 arcfour_crypt_blob(info->info24.password.data,
5144 dump_data(100, info->info24.password.data, 516);
5146 status = set_user_info_24(p->mem_ctx,
5148 &info->info24, pwd);
5152 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5153 if(!NT_STATUS_IS_OK(status)) {
5156 encode_or_decode_arc4_passwd_buffer(
5157 info->info25.password.data,
5160 dump_data(100, info->info25.password.data, 532);
5162 status = set_user_info_25(p->mem_ctx,
5164 &info->info25, pwd);
5168 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5169 if(!NT_STATUS_IS_OK(status)) {
5172 encode_or_decode_arc4_passwd_buffer(
5173 info->info26.password.data,
5176 dump_data(100, info->info26.password.data, 516);
5178 status = set_user_info_26(p->mem_ctx,
5180 &info->info26, pwd);
5184 status = NT_STATUS_INVALID_INFO_CLASS;
5191 /* ================ END Privilege BLOCK ================ */
5193 if (NT_STATUS_IS_OK(status)) {
5194 force_flush_samr_cache(&uinfo->sid);
5200 /*******************************************************************
5202 ********************************************************************/
5204 NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
5205 struct samr_SetUserInfo2 *r)
5207 struct samr_SetUserInfo q;
5209 q.in.user_handle = r->in.user_handle;
5210 q.in.level = r->in.level;
5211 q.in.info = r->in.info;
5213 return _samr_SetUserInfo(p, &q);
5216 /*********************************************************************
5217 _samr_GetAliasMembership
5218 *********************************************************************/
5220 NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
5221 struct samr_GetAliasMembership *r)
5223 size_t num_alias_rids;
5224 uint32_t *alias_rids;
5225 struct samr_domain_info *dinfo;
5230 struct dom_sid *members;
5232 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5234 dinfo = policy_handle_find(p, r->in.domain_handle,
5235 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5236 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5237 struct samr_domain_info, &status);
5238 if (!NT_STATUS_IS_OK(status)) {
5242 if (!sid_check_is_our_sam(&dinfo->sid) &&
5243 !sid_check_is_builtin(&dinfo->sid))
5244 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5246 if (r->in.sids->num_sids) {
5247 members = talloc_array(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
5249 if (members == NULL)
5250 return NT_STATUS_NO_MEMORY;
5255 for (i=0; i<r->in.sids->num_sids; i++)
5256 sid_copy(&members[i], r->in.sids->sids[i].sid);
5262 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5263 r->in.sids->num_sids,
5264 &alias_rids, &num_alias_rids);
5267 if (!NT_STATUS_IS_OK(status)) {
5271 r->out.rids->count = num_alias_rids;
5272 r->out.rids->ids = alias_rids;
5274 if (r->out.rids->ids == NULL) {
5275 /* Windows domain clients don't accept a NULL ptr here */
5276 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5278 if (r->out.rids->ids == NULL) {
5279 return NT_STATUS_NO_MEMORY;
5282 return NT_STATUS_OK;
5285 /*********************************************************************
5286 _samr_GetMembersInAlias
5287 *********************************************************************/
5289 NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
5290 struct samr_GetMembersInAlias *r)
5292 struct samr_alias_info *ainfo;
5295 size_t num_sids = 0;
5296 struct lsa_SidPtr *sids = NULL;
5297 struct dom_sid *pdb_sids = NULL;
5299 ainfo = policy_handle_find(p, r->in.alias_handle,
5300 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5301 struct samr_alias_info, &status);
5302 if (!NT_STATUS_IS_OK(status)) {
5306 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5309 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5313 if (!NT_STATUS_IS_OK(status)) {
5318 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr, num_sids);
5320 TALLOC_FREE(pdb_sids);
5321 return NT_STATUS_NO_MEMORY;
5325 for (i = 0; i < num_sids; i++) {
5326 sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
5328 TALLOC_FREE(pdb_sids);
5329 return NT_STATUS_NO_MEMORY;
5333 r->out.sids->num_sids = num_sids;
5334 r->out.sids->sids = sids;
5336 TALLOC_FREE(pdb_sids);
5338 return NT_STATUS_OK;
5341 /*********************************************************************
5342 _samr_QueryGroupMember
5343 *********************************************************************/
5345 NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
5346 struct samr_QueryGroupMember *r)
5348 struct samr_group_info *ginfo;
5349 size_t i, num_members;
5352 uint32_t *attr=NULL;
5355 struct samr_RidAttrArray *rids = NULL;
5357 ginfo = policy_handle_find(p, r->in.group_handle,
5358 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5359 struct samr_group_info, &status);
5360 if (!NT_STATUS_IS_OK(status)) {
5364 rids = talloc_zero(p->mem_ctx, struct samr_RidAttrArray);
5366 return NT_STATUS_NO_MEMORY;
5369 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5371 if (!sid_check_is_in_our_sam(&ginfo->sid)) {
5372 DEBUG(3, ("sid %s is not in our domain\n",
5373 sid_string_dbg(&ginfo->sid)));
5374 return NT_STATUS_NO_SUCH_GROUP;
5377 DEBUG(10, ("lookup on Domain SID\n"));
5380 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5381 &rid, &num_members);
5384 if (!NT_STATUS_IS_OK(status))
5388 attr=talloc_zero_array(p->mem_ctx, uint32_t, num_members);
5390 return NT_STATUS_NO_MEMORY;
5396 for (i=0; i<num_members; i++) {
5397 attr[i] = SE_GROUP_MANDATORY |
5398 SE_GROUP_ENABLED_BY_DEFAULT |
5402 rids->count = num_members;
5403 rids->attributes = attr;
5406 *r->out.rids = rids;
5408 return NT_STATUS_OK;
5411 /*********************************************************************
5412 _samr_AddAliasMember
5413 *********************************************************************/
5415 NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
5416 struct samr_AddAliasMember *r)
5418 struct samr_alias_info *ainfo;
5421 ainfo = policy_handle_find(p, r->in.alias_handle,
5422 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5423 struct samr_alias_info, &status);
5424 if (!NT_STATUS_IS_OK(status)) {
5428 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5430 /******** BEGIN SeAddUsers BLOCK *********/
5433 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5436 /******** END SeAddUsers BLOCK *********/
5438 if (NT_STATUS_IS_OK(status)) {
5439 force_flush_samr_cache(&ainfo->sid);
5445 /*********************************************************************
5446 _samr_DeleteAliasMember
5447 *********************************************************************/
5449 NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
5450 struct samr_DeleteAliasMember *r)
5452 struct samr_alias_info *ainfo;
5455 ainfo = policy_handle_find(p, r->in.alias_handle,
5456 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5457 struct samr_alias_info, &status);
5458 if (!NT_STATUS_IS_OK(status)) {
5462 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5463 sid_string_dbg(&ainfo->sid)));
5465 /******** BEGIN SeAddUsers BLOCK *********/
5468 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5471 /******** END SeAddUsers BLOCK *********/
5473 if (NT_STATUS_IS_OK(status)) {
5474 force_flush_samr_cache(&ainfo->sid);
5480 /*********************************************************************
5481 _samr_AddGroupMember
5482 *********************************************************************/
5484 NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
5485 struct samr_AddGroupMember *r)
5487 struct samr_group_info *ginfo;
5491 ginfo = policy_handle_find(p, r->in.group_handle,
5492 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5493 struct samr_group_info, &status);
5494 if (!NT_STATUS_IS_OK(status)) {
5498 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5500 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5502 return NT_STATUS_INVALID_HANDLE;
5505 /******** BEGIN SeAddUsers BLOCK *********/
5508 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5511 /******** END SeAddUsers BLOCK *********/
5513 force_flush_samr_cache(&ginfo->sid);
5518 /*********************************************************************
5519 _samr_DeleteGroupMember
5520 *********************************************************************/
5522 NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
5523 struct samr_DeleteGroupMember *r)
5526 struct samr_group_info *ginfo;
5531 * delete the group member named r->in.rid
5532 * who is a member of the sid associated with the handle
5533 * the rid is a user's rid as the group is a domain group.
5536 ginfo = policy_handle_find(p, r->in.group_handle,
5537 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5538 struct samr_group_info, &status);
5539 if (!NT_STATUS_IS_OK(status)) {
5543 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5545 return NT_STATUS_INVALID_HANDLE;
5548 /******** BEGIN SeAddUsers BLOCK *********/
5551 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5554 /******** END SeAddUsers BLOCK *********/
5556 force_flush_samr_cache(&ginfo->sid);
5561 /*********************************************************************
5563 *********************************************************************/
5565 NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
5566 struct samr_DeleteUser *r)
5568 struct samr_user_info *uinfo;
5570 struct samu *sam_pass=NULL;
5573 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5575 uinfo = policy_handle_find(p, r->in.user_handle,
5576 SEC_STD_DELETE, NULL,
5577 struct samr_user_info, &status);
5578 if (!NT_STATUS_IS_OK(status)) {
5582 if (!sid_check_is_in_our_sam(&uinfo->sid))
5583 return NT_STATUS_CANNOT_DELETE;
5585 /* check if the user exists before trying to delete */
5586 if ( !(sam_pass = samu_new( NULL )) ) {
5587 return NT_STATUS_NO_MEMORY;
5591 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5595 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5596 sid_string_dbg(&uinfo->sid)));
5597 TALLOC_FREE(sam_pass);
5598 return NT_STATUS_NO_SUCH_USER;
5601 /******** BEGIN SeAddUsers BLOCK *********/
5604 status = pdb_delete_user(p->mem_ctx, sam_pass);
5607 /******** END SeAddUsers BLOCK *********/
5609 if ( !NT_STATUS_IS_OK(status) ) {
5610 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5611 "user %s: %s.\n", pdb_get_username(sam_pass),
5612 nt_errstr(status)));
5613 TALLOC_FREE(sam_pass);
5618 TALLOC_FREE(sam_pass);
5620 force_flush_samr_cache(&uinfo->sid);
5622 if (!close_policy_hnd(p, r->in.user_handle))
5623 return NT_STATUS_OBJECT_NAME_INVALID;
5625 ZERO_STRUCTP(r->out.user_handle);
5627 return NT_STATUS_OK;
5630 /*********************************************************************
5631 _samr_DeleteDomainGroup
5632 *********************************************************************/
5634 NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
5635 struct samr_DeleteDomainGroup *r)
5637 struct samr_group_info *ginfo;
5641 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5643 ginfo = policy_handle_find(p, r->in.group_handle,
5644 SEC_STD_DELETE, NULL,
5645 struct samr_group_info, &status);
5646 if (!NT_STATUS_IS_OK(status)) {
5650 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5652 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5654 return NT_STATUS_NO_SUCH_GROUP;
5657 /******** BEGIN SeAddUsers BLOCK *********/
5660 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5663 /******** END SeAddUsers BLOCK *********/
5665 if ( !NT_STATUS_IS_OK(status) ) {
5666 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5667 "entry for group %s: %s\n",
5668 sid_string_dbg(&ginfo->sid),
5669 nt_errstr(status)));
5673 force_flush_samr_cache(&ginfo->sid);
5675 if (!close_policy_hnd(p, r->in.group_handle))
5676 return NT_STATUS_OBJECT_NAME_INVALID;
5678 return NT_STATUS_OK;
5681 /*********************************************************************
5682 _samr_DeleteDomAlias
5683 *********************************************************************/
5685 NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
5686 struct samr_DeleteDomAlias *r)
5688 struct samr_alias_info *ainfo;
5691 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5693 ainfo = policy_handle_find(p, r->in.alias_handle,
5694 SEC_STD_DELETE, NULL,
5695 struct samr_alias_info, &status);
5696 if (!NT_STATUS_IS_OK(status)) {
5700 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5702 /* Don't let Windows delete builtin groups */
5704 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5705 return NT_STATUS_SPECIAL_ACCOUNT;
5708 if (!sid_check_is_in_our_sam(&ainfo->sid))
5709 return NT_STATUS_NO_SUCH_ALIAS;
5711 DEBUG(10, ("lookup on Local SID\n"));
5713 /******** BEGIN SeAddUsers BLOCK *********/
5716 /* Have passdb delete the alias */
5717 status = pdb_delete_alias(&ainfo->sid);
5720 /******** END SeAddUsers BLOCK *********/
5722 if ( !NT_STATUS_IS_OK(status))
5725 force_flush_samr_cache(&ainfo->sid);
5727 if (!close_policy_hnd(p, r->in.alias_handle))
5728 return NT_STATUS_OBJECT_NAME_INVALID;
5730 return NT_STATUS_OK;
5733 /*********************************************************************
5734 _samr_CreateDomainGroup
5735 *********************************************************************/
5737 NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
5738 struct samr_CreateDomainGroup *r)
5743 struct samr_domain_info *dinfo;
5744 struct samr_group_info *ginfo;
5746 dinfo = policy_handle_find(p, r->in.domain_handle,
5747 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5748 struct samr_domain_info, &status);
5749 if (!NT_STATUS_IS_OK(status)) {
5753 if (!sid_check_is_our_sam(&dinfo->sid)) {
5754 return NT_STATUS_ACCESS_DENIED;
5757 name = r->in.name->string;
5759 return NT_STATUS_NO_MEMORY;
5762 status = can_create(p->mem_ctx, name);
5763 if (!NT_STATUS_IS_OK(status)) {
5767 /******** BEGIN SeAddUsers BLOCK *********/
5770 /* check that we successfully create the UNIX group */
5771 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5774 /******** END SeAddUsers BLOCK *********/
5776 /* check if we should bail out here */
5778 if ( !NT_STATUS_IS_OK(status) )
5781 ginfo = policy_handle_create(p, r->out.group_handle,
5782 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5783 struct samr_group_info, &status);
5784 if (!NT_STATUS_IS_OK(status)) {
5787 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5789 force_flush_samr_cache(&dinfo->sid);
5791 return NT_STATUS_OK;
5794 /*********************************************************************
5795 _samr_CreateDomAlias
5796 *********************************************************************/
5798 NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
5799 struct samr_CreateDomAlias *r)
5801 struct dom_sid info_sid;
5802 const char *name = NULL;
5803 struct samr_domain_info *dinfo;
5804 struct samr_alias_info *ainfo;
5808 dinfo = policy_handle_find(p, r->in.domain_handle,
5809 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5810 struct samr_domain_info, &result);
5811 if (!NT_STATUS_IS_OK(result)) {
5815 if (!sid_check_is_our_sam(&dinfo->sid)) {
5816 return NT_STATUS_ACCESS_DENIED;
5819 name = r->in.alias_name->string;
5821 result = can_create(p->mem_ctx, name);
5822 if (!NT_STATUS_IS_OK(result)) {
5826 /******** BEGIN SeAddUsers BLOCK *********/
5829 /* Have passdb create the alias */
5830 result = pdb_create_alias(name, r->out.rid);
5833 /******** END SeAddUsers BLOCK *********/
5835 if (!NT_STATUS_IS_OK(result)) {
5836 DEBUG(10, ("pdb_create_alias failed: %s\n",
5837 nt_errstr(result)));
5841 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5843 if (!sid_to_gid(&info_sid, &gid)) {
5844 DEBUG(10, ("Could not find alias just created\n"));
5845 return NT_STATUS_ACCESS_DENIED;
5848 /* check if the group has been successfully created */
5849 if ( getgrgid(gid) == NULL ) {
5850 DEBUG(1, ("getgrgid(%u) of just created alias failed\n",
5851 (unsigned int)gid));
5852 return NT_STATUS_ACCESS_DENIED;
5855 ainfo = policy_handle_create(p, r->out.alias_handle,
5856 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5857 struct samr_alias_info, &result);
5858 if (!NT_STATUS_IS_OK(result)) {
5861 ainfo->sid = info_sid;
5863 force_flush_samr_cache(&info_sid);
5865 return NT_STATUS_OK;
5868 /*********************************************************************
5869 _samr_QueryGroupInfo
5870 *********************************************************************/
5872 NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
5873 struct samr_QueryGroupInfo *r)
5875 struct samr_group_info *ginfo;
5878 union samr_GroupInfo *info = NULL;
5880 uint32_t attributes = SE_GROUP_MANDATORY |
5881 SE_GROUP_ENABLED_BY_DEFAULT |
5883 const char *group_name = NULL;
5884 const char *group_description = NULL;
5886 ginfo = policy_handle_find(p, r->in.group_handle,
5887 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5888 struct samr_group_info, &status);
5889 if (!NT_STATUS_IS_OK(status)) {
5893 map = talloc_zero(p->mem_ctx, GROUP_MAP);
5895 return NT_STATUS_NO_MEMORY;
5899 ret = get_domain_group_from_sid(ginfo->sid, map);
5902 return NT_STATUS_INVALID_HANDLE;
5904 group_name = talloc_move(r, &map->nt_name);
5905 group_description = talloc_move(r, &map->comment);
5909 info = talloc_zero(p->mem_ctx, union samr_GroupInfo);
5911 return NT_STATUS_NO_MEMORY;
5914 switch (r->in.level) {
5920 status = pdb_enum_group_members(
5921 p->mem_ctx, &ginfo->sid, &members,
5925 if (!NT_STATUS_IS_OK(status)) {
5929 info->all.name.string = group_name;
5930 info->all.attributes = attributes;
5931 info->all.num_members = num_members;
5932 info->all.description.string = group_description;
5936 info->name.string = group_name;
5939 info->attributes.attributes = attributes;
5942 info->description.string = group_description;
5952 status = pdb_enum_group_members(
5953 p->mem_ctx, &ginfo->sid, &members,
5957 if (!NT_STATUS_IS_OK(status)) {
5961 info->all2.name.string = group_name;
5962 info->all2.attributes = attributes;
5963 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5964 info->all2.description.string = group_description;
5969 return NT_STATUS_INVALID_INFO_CLASS;
5972 *r->out.info = info;
5974 return NT_STATUS_OK;
5977 /*********************************************************************
5979 *********************************************************************/
5981 NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
5982 struct samr_SetGroupInfo *r)
5984 struct samr_group_info *ginfo;
5989 ginfo = policy_handle_find(p, r->in.group_handle,
5990 SAMR_GROUP_ACCESS_SET_INFO, NULL,
5991 struct samr_group_info, &status);
5992 if (!NT_STATUS_IS_OK(status)) {
5996 map = talloc_zero(p->mem_ctx, GROUP_MAP);
5998 return NT_STATUS_NO_MEMORY;
6002 ret = get_domain_group_from_sid(ginfo->sid, map);
6005 return NT_STATUS_NO_SUCH_GROUP;
6007 switch (r->in.level) {
6009 map->nt_name = talloc_strdup(map,
6010 r->in.info->name.string);
6011 if (!map->nt_name) {
6012 return NT_STATUS_NO_MEMORY;
6018 map->comment = talloc_strdup(map,
6019 r->in.info->description.string);
6020 if (!map->comment) {
6021 return NT_STATUS_NO_MEMORY;
6025 return NT_STATUS_INVALID_INFO_CLASS;
6028 /******** BEGIN SeAddUsers BLOCK *********/
6031 status = pdb_update_group_mapping_entry(map);
6034 /******** End SeAddUsers BLOCK *********/
6038 if (NT_STATUS_IS_OK(status)) {
6039 force_flush_samr_cache(&ginfo->sid);
6045 /*********************************************************************
6047 *********************************************************************/
6049 NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
6050 struct samr_SetAliasInfo *r)
6052 struct samr_alias_info *ainfo;
6053 struct acct_info *info;
6056 ainfo = policy_handle_find(p, r->in.alias_handle,
6057 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6058 struct samr_alias_info, &status);
6059 if (!NT_STATUS_IS_OK(status)) {
6063 info = talloc_zero(p->mem_ctx, struct acct_info);
6065 return NT_STATUS_NO_MEMORY;
6068 /* get the current group information */
6071 status = pdb_get_aliasinfo(&ainfo->sid, info);
6074 if ( !NT_STATUS_IS_OK(status))
6077 switch (r->in.level) {
6082 /* We currently do not support renaming groups in the
6083 the BUILTIN domain. Refer to util_builtin.c to understand
6084 why. The eventually needs to be fixed to be like Windows
6085 where you can rename builtin groups, just not delete them */
6087 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6088 return NT_STATUS_SPECIAL_ACCOUNT;
6091 /* There has to be a valid name (and it has to be different) */
6093 if ( !r->in.info->name.string )
6094 return NT_STATUS_INVALID_PARAMETER;
6096 /* If the name is the same just reply "ok". Yes this
6097 doesn't allow you to change the case of a group name. */
6099 if (strequal(r->in.info->name.string, info->acct_name)) {
6100 return NT_STATUS_OK;
6103 talloc_free(info->acct_name);
6104 info->acct_name = talloc_strdup(info, r->in.info->name.string);
6105 if (!info->acct_name) {
6106 return NT_STATUS_NO_MEMORY;
6109 /* make sure the name doesn't already exist as a user
6112 group_name = talloc_asprintf(p->mem_ctx,
6116 if (group_name == NULL) {
6117 return NT_STATUS_NO_MEMORY;
6120 status = can_create( p->mem_ctx, group_name );
6121 talloc_free(group_name);
6122 if ( !NT_STATUS_IS_OK( status ) )
6126 case ALIASINFODESCRIPTION:
6127 TALLOC_FREE(info->acct_desc);
6128 if (r->in.info->description.string) {
6129 info->acct_desc = talloc_strdup(info,
6130 r->in.info->description.string);
6132 info->acct_desc = talloc_strdup(info, "");
6134 if (!info->acct_desc) {
6135 return NT_STATUS_NO_MEMORY;
6139 return NT_STATUS_INVALID_INFO_CLASS;
6142 /******** BEGIN SeAddUsers BLOCK *********/
6145 status = pdb_set_aliasinfo(&ainfo->sid, info);
6148 /******** End SeAddUsers BLOCK *********/
6150 if (NT_STATUS_IS_OK(status))
6151 force_flush_samr_cache(&ainfo->sid);
6156 /****************************************************************
6158 ****************************************************************/
6160 NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
6161 struct samr_GetDomPwInfo *r)
6163 uint32_t min_password_length = 0;
6164 uint32_t password_properties = 0;
6166 /* Perform access check. Since this rpc does not require a
6167 policy handle it will not be caught by the access checks on
6168 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6170 if (!pipe_access_check(p)) {
6171 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6172 return NT_STATUS_ACCESS_DENIED;
6176 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6177 &min_password_length);
6178 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6179 &password_properties);
6182 if (lp_check_password_script(talloc_tos()) && *lp_check_password_script(talloc_tos())) {
6183 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6186 r->out.info->min_password_length = min_password_length;
6187 r->out.info->password_properties = password_properties;
6189 return NT_STATUS_OK;
6192 /*********************************************************************
6194 *********************************************************************/
6196 NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
6197 struct samr_OpenGroup *r)
6200 struct dom_sid info_sid;
6202 struct samr_domain_info *dinfo;
6203 struct samr_group_info *ginfo;
6204 struct security_descriptor *psd = NULL;
6205 uint32_t acc_granted;
6206 uint32_t des_access = r->in.access_mask;
6211 dinfo = policy_handle_find(p, r->in.domain_handle,
6212 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6213 struct samr_domain_info, &status);
6214 if (!NT_STATUS_IS_OK(status)) {
6218 /*check if access can be granted as requested by client. */
6219 map_max_allowed_access(p->session_info->security_token,
6220 p->session_info->unix_token,
6223 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6224 se_map_generic(&des_access,&grp_generic_mapping);
6226 status = access_check_object(psd, p->session_info->security_token,
6227 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6228 des_access, &acc_granted, "_samr_OpenGroup");
6230 if ( !NT_STATUS_IS_OK(status) )
6233 /* this should not be hard-coded like this */
6235 if (!sid_check_is_our_sam(&dinfo->sid)) {
6236 return NT_STATUS_ACCESS_DENIED;
6239 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6241 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6242 sid_string_dbg(&info_sid)));
6244 map = talloc_zero(p->mem_ctx, GROUP_MAP);
6246 return NT_STATUS_NO_MEMORY;
6249 /* check if that group really exists */
6251 ret = get_domain_group_from_sid(info_sid, map);
6254 return NT_STATUS_NO_SUCH_GROUP;
6258 ginfo = policy_handle_create(p, r->out.group_handle,
6260 struct samr_group_info, &status);
6261 if (!NT_STATUS_IS_OK(status)) {
6264 ginfo->sid = info_sid;
6266 return NT_STATUS_OK;
6269 /*********************************************************************
6270 _samr_RemoveMemberFromForeignDomain
6271 *********************************************************************/
6273 NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
6274 struct samr_RemoveMemberFromForeignDomain *r)
6276 struct samr_domain_info *dinfo;
6279 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6280 sid_string_dbg(r->in.sid)));
6282 /* Find the policy handle. Open a policy on it. */
6284 dinfo = policy_handle_find(p, r->in.domain_handle,
6285 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6286 struct samr_domain_info, &result);
6287 if (!NT_STATUS_IS_OK(result)) {
6291 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6292 sid_string_dbg(&dinfo->sid)));
6294 /* we can only delete a user from a group since we don't have
6295 nested groups anyways. So in the latter case, just say OK */
6297 /* TODO: The above comment nowadays is bogus. Since we have nested
6298 * groups now, and aliases members are never reported out of the unix
6299 * group membership, the "just say OK" makes this call a no-op. For
6300 * us. This needs fixing however. */
6302 /* I've only ever seen this in the wild when deleting a user from
6303 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6304 * is the user about to be deleted. I very much suspect this is the
6305 * only application of this call. To verify this, let people report
6308 if (!sid_check_is_builtin(&dinfo->sid)) {
6309 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6310 "global_sam_sid() = %s\n",
6311 sid_string_dbg(&dinfo->sid),
6312 sid_string_dbg(get_global_sam_sid())));
6313 DEBUGADD(1,("please report to samba-technical@lists.samba.org!\n"));
6314 return NT_STATUS_OK;
6317 force_flush_samr_cache(&dinfo->sid);
6319 result = NT_STATUS_OK;
6324 /*******************************************************************
6325 _samr_QueryDomainInfo2
6326 ********************************************************************/
6328 NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
6329 struct samr_QueryDomainInfo2 *r)
6331 struct samr_QueryDomainInfo q;
6333 q.in.domain_handle = r->in.domain_handle;
6334 q.in.level = r->in.level;
6336 q.out.info = r->out.info;
6338 return _samr_QueryDomainInfo(p, &q);
6341 /*******************************************************************
6342 ********************************************************************/
6344 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6345 struct samr_DomInfo1 *r)
6347 time_t u_expire, u_min_age;
6349 u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6350 u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6352 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6353 (uint32_t)r->min_password_length);
6354 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6355 (uint32_t)r->password_history_length);
6356 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6357 (uint32_t)r->password_properties);
6358 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6359 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6361 return NT_STATUS_OK;
6364 /*******************************************************************
6365 ********************************************************************/
6367 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6368 struct samr_DomInfo3 *r)
6372 u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6374 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6376 return NT_STATUS_OK;
6379 /*******************************************************************
6380 ********************************************************************/
6382 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6383 struct samr_DomInfo12 *r)
6385 time_t u_lock_duration, u_reset_time;
6388 * It is not possible to set lockout_duration < lockout_window.
6389 * (The test is the other way around since the negative numbers
6392 * This constraint is documented here for the samr rpc service:
6393 * MS-SAMR 3.1.1.6 Attribute Constraints for Originating Updates
6394 * http://msdn.microsoft.com/en-us/library/cc245667%28PROT.10%29.aspx
6396 * And here for the ldap backend:
6397 * MS-ADTS 3.1.1.5.3.2 Constraints
6398 * http://msdn.microsoft.com/en-us/library/cc223462(PROT.10).aspx
6400 if (r->lockout_duration > r->lockout_window) {
6401 return NT_STATUS_INVALID_PARAMETER;
6404 u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6405 if (u_lock_duration != -1) {
6406 u_lock_duration /= 60;
6409 u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6411 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6412 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6413 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6414 (uint32_t)r->lockout_threshold);
6416 return NT_STATUS_OK;
6419 /*******************************************************************
6421 ********************************************************************/
6423 NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
6424 struct samr_SetDomainInfo *r)
6427 uint32_t acc_required = 0;
6429 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6431 switch (r->in.level) {
6432 case 1: /* DomainPasswordInformation */
6433 case 12: /* DomainLockoutInformation */
6434 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6435 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6437 case 3: /* DomainLogoffInformation */
6438 case 4: /* DomainOemInformation */
6439 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6440 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6442 case 6: /* DomainReplicationInformation */
6443 case 9: /* DomainStateInformation */
6444 case 7: /* DomainServerRoleInformation */
6445 /* DOMAIN_ADMINISTER_SERVER */
6446 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6449 return NT_STATUS_INVALID_INFO_CLASS;
6452 (void)policy_handle_find(p, r->in.domain_handle,
6454 struct samr_domain_info, &status);
6455 if (!NT_STATUS_IS_OK(status)) {
6459 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6461 switch (r->in.level) {
6463 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6466 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6477 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6480 return NT_STATUS_INVALID_INFO_CLASS;
6483 if (!NT_STATUS_IS_OK(status)) {
6487 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6489 return NT_STATUS_OK;
6492 /****************************************************************
6493 _samr_GetDisplayEnumerationIndex
6494 ****************************************************************/
6496 NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
6497 struct samr_GetDisplayEnumerationIndex *r)
6499 struct samr_domain_info *dinfo;
6500 uint32_t max_entries = (uint32_t) -1;
6501 uint32_t enum_context = 0;
6503 uint32_t num_account = 0;
6504 struct samr_displayentry *entries = NULL;
6507 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6509 dinfo = policy_handle_find(p, r->in.domain_handle,
6510 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6511 struct samr_domain_info, &status);
6512 if (!NT_STATUS_IS_OK(status)) {
6516 if ((r->in.level < 1) || (r->in.level > 3)) {
6517 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6518 "Unknown info level (%u)\n",
6520 return NT_STATUS_INVALID_INFO_CLASS;
6525 /* The following done as ROOT. Don't return without unbecome_root(). */
6527 switch (r->in.level) {
6529 if (dinfo->disp_info->users == NULL) {
6530 dinfo->disp_info->users = pdb_search_users(
6531 dinfo->disp_info, ACB_NORMAL);
6532 if (dinfo->disp_info->users == NULL) {
6534 return NT_STATUS_ACCESS_DENIED;
6536 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6537 "starting user enumeration at index %u\n",
6538 (unsigned int)enum_context));
6540 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6541 "using cached user enumeration at index %u\n",
6542 (unsigned int)enum_context));
6544 num_account = pdb_search_entries(dinfo->disp_info->users,
6545 enum_context, max_entries,
6549 if (dinfo->disp_info->machines == NULL) {
6550 dinfo->disp_info->machines = pdb_search_users(
6551 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6552 if (dinfo->disp_info->machines == NULL) {
6554 return NT_STATUS_ACCESS_DENIED;
6556 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6557 "starting machine enumeration at index %u\n",
6558 (unsigned int)enum_context));
6560 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6561 "using cached machine enumeration at index %u\n",
6562 (unsigned int)enum_context));
6564 num_account = pdb_search_entries(dinfo->disp_info->machines,
6565 enum_context, max_entries,
6569 if (dinfo->disp_info->groups == NULL) {
6570 dinfo->disp_info->groups = pdb_search_groups(
6572 if (dinfo->disp_info->groups == NULL) {
6574 return NT_STATUS_ACCESS_DENIED;
6576 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6577 "starting group enumeration at index %u\n",
6578 (unsigned int)enum_context));
6580 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6581 "using cached group enumeration at index %u\n",
6582 (unsigned int)enum_context));
6584 num_account = pdb_search_entries(dinfo->disp_info->groups,
6585 enum_context, max_entries,
6590 smb_panic("info class changed");
6596 /* Ensure we cache this enumeration. */
6597 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6599 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6600 r->in.name->string));
6602 for (i=0; i<num_account; i++) {
6603 if (strequal(entries[i].account_name, r->in.name->string)) {
6604 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6605 "found %s at idx %d\n",
6606 r->in.name->string, i));
6608 return NT_STATUS_OK;
6612 /* assuming account_name lives at the very end */
6613 *r->out.idx = num_account;
6615 return NT_STATUS_NO_MORE_ENTRIES;
6618 /****************************************************************
6619 _samr_GetDisplayEnumerationIndex2
6620 ****************************************************************/
6622 NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
6623 struct samr_GetDisplayEnumerationIndex2 *r)
6625 struct samr_GetDisplayEnumerationIndex q;
6627 q.in.domain_handle = r->in.domain_handle;
6628 q.in.level = r->in.level;
6629 q.in.name = r->in.name;
6631 q.out.idx = r->out.idx;
6633 return _samr_GetDisplayEnumerationIndex(p, &q);
6636 /****************************************************************
6638 ****************************************************************/
6640 NTSTATUS _samr_RidToSid(struct pipes_struct *p,
6641 struct samr_RidToSid *r)
6643 struct samr_domain_info *dinfo;
6647 dinfo = policy_handle_find(p, r->in.domain_handle,
6649 struct samr_domain_info, &status);
6650 if (!NT_STATUS_IS_OK(status)) {
6654 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6655 return NT_STATUS_NO_MEMORY;
6658 *r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
6660 return NT_STATUS_NO_MEMORY;
6663 return NT_STATUS_OK;
6666 /****************************************************************
6667 ****************************************************************/
6669 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
6670 const struct samr_PwInfo *dom_pw_info,
6671 const struct samr_ValidatePasswordReq2 *req,
6672 struct samr_ValidatePasswordRepCtr *rep)
6676 if (req->password.string == NULL) {
6677 return SAMR_VALIDATION_STATUS_SUCCESS;
6679 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6680 ZERO_STRUCT(rep->info);
6681 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6683 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6684 status = check_password_complexity(req->account.string,
6685 req->password.string,
6687 if (!NT_STATUS_IS_OK(status)) {
6688 ZERO_STRUCT(rep->info);
6689 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6693 return SAMR_VALIDATION_STATUS_SUCCESS;
6696 /****************************************************************
6697 ****************************************************************/
6699 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
6700 const struct samr_PwInfo *dom_pw_info,
6701 const struct samr_ValidatePasswordReq3 *req,
6702 struct samr_ValidatePasswordRepCtr *rep)
6706 if (req->password.string == NULL) {
6707 return SAMR_VALIDATION_STATUS_SUCCESS;
6709 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6710 ZERO_STRUCT(rep->info);
6711 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6713 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6714 status = check_password_complexity(req->account.string,
6715 req->password.string,
6717 if (!NT_STATUS_IS_OK(status)) {
6718 ZERO_STRUCT(rep->info);
6719 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6723 return SAMR_VALIDATION_STATUS_SUCCESS;
6726 /****************************************************************
6727 _samr_ValidatePassword
6728 ****************************************************************/
6730 NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
6731 struct samr_ValidatePassword *r)
6733 union samr_ValidatePasswordRep *rep;
6735 struct samr_GetDomPwInfo pw;
6736 struct samr_PwInfo dom_pw_info;
6738 if (p->transport != NCACN_IP_TCP && p->transport != NCALRPC) {
6739 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
6740 return NT_STATUS_ACCESS_DENIED;
6743 if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
6744 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
6745 return NT_STATUS_ACCESS_DENIED;
6748 if (r->in.level < 1 || r->in.level > 3) {
6749 return NT_STATUS_INVALID_INFO_CLASS;
6752 pw.in.domain_name = NULL;
6753 pw.out.info = &dom_pw_info;
6755 status = _samr_GetDomPwInfo(p, &pw);
6756 if (!NT_STATUS_IS_OK(status)) {
6760 rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
6762 return NT_STATUS_NO_MEMORY;
6765 switch (r->in.level) {
6767 status = NT_STATUS_NOT_SUPPORTED;
6770 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
6776 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
6782 status = NT_STATUS_INVALID_INFO_CLASS;
6786 if (!NT_STATUS_IS_OK(status)) {
6793 return NT_STATUS_OK;
6796 /****************************************************************
6797 ****************************************************************/
6799 NTSTATUS _samr_Shutdown(struct pipes_struct *p,
6800 struct samr_Shutdown *r)
6802 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6803 return NT_STATUS_NOT_IMPLEMENTED;
6806 /****************************************************************
6807 ****************************************************************/
6809 NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
6810 struct samr_SetMemberAttributesOfGroup *r)
6812 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6813 return NT_STATUS_NOT_IMPLEMENTED;
6816 /****************************************************************
6817 ****************************************************************/
6819 NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
6820 struct samr_TestPrivateFunctionsDomain *r)
6822 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6823 return NT_STATUS_NOT_IMPLEMENTED;
6826 /****************************************************************
6827 ****************************************************************/
6829 NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
6830 struct samr_TestPrivateFunctionsUser *r)
6832 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6833 return NT_STATUS_NOT_IMPLEMENTED;
6836 /****************************************************************
6837 ****************************************************************/
6839 NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
6840 struct samr_AddMultipleMembersToAlias *r)
6842 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6843 return NT_STATUS_NOT_IMPLEMENTED;
6846 /****************************************************************
6847 ****************************************************************/
6849 NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
6850 struct samr_RemoveMultipleMembersFromAlias *r)
6852 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6853 return NT_STATUS_NOT_IMPLEMENTED;
6856 /****************************************************************
6857 ****************************************************************/
6859 NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
6860 struct samr_SetBootKeyInformation *r)
6862 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6863 return NT_STATUS_NOT_IMPLEMENTED;
6866 /****************************************************************
6867 ****************************************************************/
6869 NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
6870 struct samr_GetBootKeyInformation *r)
6872 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6873 return NT_STATUS_NOT_IMPLEMENTED;
6876 /****************************************************************
6877 ****************************************************************/
6879 NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
6880 struct samr_SetDsrmPassword *r)
6882 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6883 return NT_STATUS_NOT_IMPLEMENTED;