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 "smbd/globals.h"
37 #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"
49 #define DBGC_CLASS DBGC_RPC_SRV
51 #define SAMR_USR_RIGHTS_WRITE_PW \
52 ( READ_CONTROL_ACCESS | \
53 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
54 SAMR_USER_ACCESS_SET_LOC_COM)
55 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
56 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
58 #define DISP_INFO_CACHE_TIMEOUT 10
60 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
61 #define MAX_SAM_ENTRIES_W95 50
63 struct samr_connect_info {
67 struct samr_domain_info {
69 struct disp_info *disp_info;
72 struct samr_user_info {
76 struct samr_group_info {
80 struct samr_alias_info {
84 typedef struct disp_info {
85 struct dom_sid sid; /* identify which domain this is. */
86 struct pdb_search *users; /* querydispinfo 1 and 4 */
87 struct pdb_search *machines; /* querydispinfo 2 */
88 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
89 struct pdb_search *aliases; /* enumaliases */
91 uint32_t enum_acb_mask;
92 struct pdb_search *enum_users; /* enumusers with a mask */
94 struct timed_event *cache_timeout_event; /* cache idle timeout
98 static const struct generic_mapping sam_generic_mapping = {
99 GENERIC_RIGHTS_SAM_READ,
100 GENERIC_RIGHTS_SAM_WRITE,
101 GENERIC_RIGHTS_SAM_EXECUTE,
102 GENERIC_RIGHTS_SAM_ALL_ACCESS};
103 static const struct generic_mapping dom_generic_mapping = {
104 GENERIC_RIGHTS_DOMAIN_READ,
105 GENERIC_RIGHTS_DOMAIN_WRITE,
106 GENERIC_RIGHTS_DOMAIN_EXECUTE,
107 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
108 static const struct generic_mapping usr_generic_mapping = {
109 GENERIC_RIGHTS_USER_READ,
110 GENERIC_RIGHTS_USER_WRITE,
111 GENERIC_RIGHTS_USER_EXECUTE,
112 GENERIC_RIGHTS_USER_ALL_ACCESS};
113 static const struct generic_mapping usr_nopwchange_generic_mapping = {
114 GENERIC_RIGHTS_USER_READ,
115 GENERIC_RIGHTS_USER_WRITE,
116 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
117 GENERIC_RIGHTS_USER_ALL_ACCESS};
118 static const struct generic_mapping grp_generic_mapping = {
119 GENERIC_RIGHTS_GROUP_READ,
120 GENERIC_RIGHTS_GROUP_WRITE,
121 GENERIC_RIGHTS_GROUP_EXECUTE,
122 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
123 static const struct generic_mapping ali_generic_mapping = {
124 GENERIC_RIGHTS_ALIAS_READ,
125 GENERIC_RIGHTS_ALIAS_WRITE,
126 GENERIC_RIGHTS_ALIAS_EXECUTE,
127 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
129 /*******************************************************************
130 *******************************************************************/
132 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
133 const struct generic_mapping *map,
134 struct dom_sid *sid, uint32 sid_access )
136 struct dom_sid domadmin_sid;
137 struct security_ace ace[5]; /* at most 5 entries */
140 struct security_acl *psa = NULL;
142 /* basic access for Everyone */
144 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
145 map->generic_execute | map->generic_read, 0);
147 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
149 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
150 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
151 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
152 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
154 /* Add Full Access for Domain Admins if we are a DC */
157 sid_compose(&domadmin_sid, get_global_sam_sid(),
159 init_sec_ace(&ace[i++], &domadmin_sid,
160 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
163 /* if we have a sid, give it some special access */
166 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
169 /* create the security descriptor */
171 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
172 return NT_STATUS_NO_MEMORY;
174 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
175 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
176 psa, sd_size)) == NULL)
177 return NT_STATUS_NO_MEMORY;
182 /*******************************************************************
183 Checks if access to an object should be granted, and returns that
184 level of access for further checks.
186 If the user has either of needed_priv_1 or needed_priv_2 then they
187 get the rights in rights_mask in addition to any calulated rights.
189 This handles the unusual case where we need to allow two different
190 privileges to obtain exactly the same rights, which occours only in
192 ********************************************************************/
194 NTSTATUS access_check_object( struct security_descriptor *psd, struct security_token *token,
195 enum sec_privilege needed_priv_1, enum sec_privilege needed_priv_2,
197 uint32 des_access, uint32 *acc_granted,
200 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
201 uint32 saved_mask = 0;
203 /* check privileges; certain SAM access bits should be overridden
204 by privileges (mostly having to do with creating/modifying/deleting
207 if ((needed_priv_1 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_1)) ||
208 (needed_priv_2 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_2))) {
209 saved_mask = (des_access & rights_mask);
210 des_access &= ~saved_mask;
212 DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
217 /* check the security descriptor first */
219 status = se_access_check(psd, token, des_access, acc_granted);
220 if (NT_STATUS_IS_OK(status)) {
224 /* give root a free pass */
226 if ( geteuid() == sec_initial_uid() ) {
228 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
229 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
231 *acc_granted = des_access;
233 status = NT_STATUS_OK;
239 /* add in any bits saved during the privilege check (only
240 matters is status is ok) */
242 *acc_granted |= rights_mask;
244 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
245 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
246 des_access, *acc_granted));
252 /*******************************************************************
253 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
254 ********************************************************************/
256 void map_max_allowed_access(const struct security_token *nt_token,
257 const struct security_unix_token *unix_token,
258 uint32_t *pacc_requested)
260 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
263 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
265 /* At least try for generic read|execute - Everyone gets that. */
266 *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
268 /* root gets anything. */
269 if (unix_token->uid == sec_initial_uid()) {
270 *pacc_requested |= GENERIC_ALL_ACCESS;
274 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
276 if (security_token_has_sid(nt_token, &global_sid_Builtin_Administrators) ||
277 security_token_has_sid(nt_token, &global_sid_Builtin_Account_Operators)) {
278 *pacc_requested |= GENERIC_ALL_ACCESS;
282 /* Full access for DOMAIN\Domain Admins. */
284 struct dom_sid domadmin_sid;
285 sid_compose(&domadmin_sid, get_global_sam_sid(),
287 if (security_token_has_sid(nt_token, &domadmin_sid)) {
288 *pacc_requested |= GENERIC_ALL_ACCESS;
292 /* TODO ! Check privileges. */
295 /*******************************************************************
296 Fetch or create a dispinfo struct.
297 ********************************************************************/
299 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
302 * We do a static cache for DISP_INFO's here. Explanation can be found
303 * in Jeremy's checkin message to r11793:
305 * Fix the SAMR cache so it works across completely insane
306 * client behaviour (ie.:
307 * open pipe/open SAMR handle/enumerate 0 - 1024
308 * close SAMR handle, close pipe.
309 * open pipe/open SAMR handle/enumerate 1024 - 2048...
310 * close SAMR handle, close pipe.
311 * And on ad-nausium. Amazing.... probably object-oriented
312 * client side programming in action yet again.
313 * This change should *massively* improve performance when
314 * enumerating users from an LDAP database.
317 * "Our" and the builtin domain are the only ones where we ever
318 * enumerate stuff, so just cache 2 entries.
321 static struct disp_info *builtin_dispinfo;
322 static struct disp_info *domain_dispinfo;
324 /* There are two cases to consider here:
325 1) The SID is a domain SID and we look for an equality match, or
326 2) This is an account SID and so we return the DISP_INFO* for our
333 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
335 * Necessary only once, but it does not really hurt.
337 if (builtin_dispinfo == NULL) {
338 builtin_dispinfo = talloc_zero(NULL, struct disp_info);
339 if (builtin_dispinfo == NULL) {
343 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
345 return builtin_dispinfo;
348 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
350 * Necessary only once, but it does not really hurt.
352 if (domain_dispinfo == NULL) {
353 domain_dispinfo = talloc_zero(NULL, struct disp_info);
354 if (domain_dispinfo == NULL) {
358 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
360 return domain_dispinfo;
366 /*******************************************************************
367 Function to free the per SID data.
368 ********************************************************************/
370 static void free_samr_cache(DISP_INFO *disp_info)
372 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
373 sid_string_dbg(&disp_info->sid)));
375 /* We need to become root here because the paged search might have to
376 * tell the LDAP server we're not interested in the rest anymore. */
380 TALLOC_FREE(disp_info->users);
381 TALLOC_FREE(disp_info->machines);
382 TALLOC_FREE(disp_info->groups);
383 TALLOC_FREE(disp_info->aliases);
384 TALLOC_FREE(disp_info->enum_users);
389 /*******************************************************************
390 Idle event handler. Throw away the disp info cache.
391 ********************************************************************/
393 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
394 struct timed_event *te,
398 DISP_INFO *disp_info = (DISP_INFO *)private_data;
400 TALLOC_FREE(disp_info->cache_timeout_event);
402 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
404 free_samr_cache(disp_info);
407 /*******************************************************************
408 Setup cache removal idle event handler.
409 ********************************************************************/
411 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
413 /* Remove any pending timeout and update. */
415 TALLOC_FREE(disp_info->cache_timeout_event);
417 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
418 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
419 (unsigned int)secs_fromnow ));
421 disp_info->cache_timeout_event = event_add_timed(
422 server_event_context(), NULL,
423 timeval_current_ofs(secs_fromnow, 0),
424 disp_info_cache_idle_timeout_handler, (void *)disp_info);
427 /*******************************************************************
428 Force flush any cache. We do this on any samr_set_xxx call.
429 We must also remove the timeout handler.
430 ********************************************************************/
432 static void force_flush_samr_cache(const struct dom_sid *sid)
434 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
436 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
440 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
441 TALLOC_FREE(disp_info->cache_timeout_event);
442 free_samr_cache(disp_info);
445 /*******************************************************************
446 Ensure password info is never given out. Paranioa... JRA.
447 ********************************************************************/
449 static void samr_clear_sam_passwd(struct samu *sam_pass)
455 /* These now zero out the old password */
457 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
458 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
461 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
463 struct samr_displayentry *entry;
465 if (sid_check_is_builtin(&info->sid)) {
466 /* No users in builtin. */
470 if (info->users == NULL) {
471 info->users = pdb_search_users(info, acct_flags);
472 if (info->users == NULL) {
476 /* Fetch the last possible entry, thus trigger an enumeration */
477 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
479 /* Ensure we cache this enumeration. */
480 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
482 return info->users->num_entries;
485 static uint32 count_sam_groups(struct disp_info *info)
487 struct samr_displayentry *entry;
489 if (sid_check_is_builtin(&info->sid)) {
490 /* No groups in builtin. */
494 if (info->groups == NULL) {
495 info->groups = pdb_search_groups(info);
496 if (info->groups == NULL) {
500 /* Fetch the last possible entry, thus trigger an enumeration */
501 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
503 /* Ensure we cache this enumeration. */
504 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
506 return info->groups->num_entries;
509 static uint32 count_sam_aliases(struct disp_info *info)
511 struct samr_displayentry *entry;
513 if (info->aliases == NULL) {
514 info->aliases = pdb_search_aliases(info, &info->sid);
515 if (info->aliases == NULL) {
519 /* Fetch the last possible entry, thus trigger an enumeration */
520 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
522 /* Ensure we cache this enumeration. */
523 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
525 return info->aliases->num_entries;
528 /*******************************************************************
530 ********************************************************************/
532 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
534 if (!close_policy_hnd(p, r->in.handle)) {
535 return NT_STATUS_INVALID_HANDLE;
538 ZERO_STRUCTP(r->out.handle);
543 /*******************************************************************
545 ********************************************************************/
547 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
548 struct samr_OpenDomain *r)
550 struct samr_connect_info *cinfo;
551 struct samr_domain_info *dinfo;
552 struct security_descriptor *psd = NULL;
554 uint32 des_access = r->in.access_mask;
557 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
559 /* find the connection policy handle. */
561 cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
562 struct samr_connect_info, &status);
563 if (!NT_STATUS_IS_OK(status)) {
567 /*check if access can be granted as requested by client. */
568 map_max_allowed_access(p->session_info->security_token,
569 &p->session_info->utok,
572 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
573 se_map_generic( &des_access, &dom_generic_mapping );
576 * Users with SeAddUser get the ability to manipulate groups
579 if (security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS)) {
580 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
581 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
582 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
583 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
584 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
588 * Users with SeMachineAccount or SeAddUser get additional
589 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
592 status = access_check_object( psd, p->session_info->security_token,
593 SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
594 extra_access, des_access,
595 &acc_granted, "_samr_OpenDomain" );
597 if ( !NT_STATUS_IS_OK(status) )
600 if (!sid_check_is_domain(r->in.sid) &&
601 !sid_check_is_builtin(r->in.sid)) {
602 return NT_STATUS_NO_SUCH_DOMAIN;
605 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
606 struct samr_domain_info, &status);
607 if (!NT_STATUS_IS_OK(status)) {
610 dinfo->sid = *r->in.sid;
611 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
613 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
618 /*******************************************************************
620 ********************************************************************/
622 NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
623 struct samr_GetUserPwInfo *r)
625 struct samr_user_info *uinfo;
626 enum lsa_SidType sid_type;
627 uint32_t min_password_length = 0;
628 uint32_t password_properties = 0;
632 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
634 uinfo = policy_handle_find(p, r->in.user_handle,
635 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
636 struct samr_user_info, &status);
637 if (!NT_STATUS_IS_OK(status)) {
641 if (!sid_check_is_in_our_domain(&uinfo->sid)) {
642 return NT_STATUS_OBJECT_TYPE_MISMATCH;
646 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
649 return NT_STATUS_NO_SUCH_USER;
655 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
656 &min_password_length);
657 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
658 &password_properties);
661 if (lp_check_password_script() && *lp_check_password_script()) {
662 password_properties |= DOMAIN_PASSWORD_COMPLEX;
670 r->out.info->min_password_length = min_password_length;
671 r->out.info->password_properties = password_properties;
673 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
678 /*******************************************************************
680 ********************************************************************/
682 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
683 struct samr_SetSecurity *r)
685 struct samr_user_info *uinfo;
687 struct security_acl *dacl;
689 struct samu *sampass=NULL;
692 uinfo = policy_handle_find(p, r->in.handle,
693 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
694 struct samr_user_info, &status);
695 if (!NT_STATUS_IS_OK(status)) {
699 if (!(sampass = samu_new( p->mem_ctx))) {
700 DEBUG(0,("No memory!\n"));
701 return NT_STATUS_NO_MEMORY;
704 /* get the user record */
706 ret = pdb_getsampwsid(sampass, &uinfo->sid);
710 DEBUG(4, ("User %s not found\n",
711 sid_string_dbg(&uinfo->sid)));
712 TALLOC_FREE(sampass);
713 return NT_STATUS_INVALID_HANDLE;
716 dacl = r->in.sdbuf->sd->dacl;
717 for (i=0; i < dacl->num_aces; i++) {
718 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
719 ret = pdb_set_pass_can_change(sampass,
720 (dacl->aces[i].access_mask &
721 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
728 TALLOC_FREE(sampass);
729 return NT_STATUS_ACCESS_DENIED;
733 status = pdb_update_sam_account(sampass);
736 TALLOC_FREE(sampass);
741 /*******************************************************************
742 build correct perms based on policies and password times for _samr_query_sec_obj
743 *******************************************************************/
744 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
746 struct samu *sampass=NULL;
749 if ( !(sampass = samu_new( mem_ctx )) ) {
750 DEBUG(0,("No memory!\n"));
755 ret = pdb_getsampwsid(sampass, user_sid);
759 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
760 TALLOC_FREE(sampass);
764 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
766 if (pdb_get_pass_can_change(sampass)) {
767 TALLOC_FREE(sampass);
770 TALLOC_FREE(sampass);
775 /*******************************************************************
777 ********************************************************************/
779 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
780 struct samr_QuerySecurity *r)
782 struct samr_connect_info *cinfo;
783 struct samr_domain_info *dinfo;
784 struct samr_user_info *uinfo;
785 struct samr_group_info *ginfo;
786 struct samr_alias_info *ainfo;
788 struct security_descriptor * psd = NULL;
791 cinfo = policy_handle_find(p, r->in.handle,
792 SEC_STD_READ_CONTROL, NULL,
793 struct samr_connect_info, &status);
794 if (NT_STATUS_IS_OK(status)) {
795 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
796 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
797 &sam_generic_mapping, NULL, 0);
801 dinfo = policy_handle_find(p, r->in.handle,
802 SEC_STD_READ_CONTROL, NULL,
803 struct samr_domain_info, &status);
804 if (NT_STATUS_IS_OK(status)) {
805 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
806 "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
808 * TODO: Builtin probably needs a different SD with restricted
811 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
812 &dom_generic_mapping, NULL, 0);
816 uinfo = policy_handle_find(p, r->in.handle,
817 SEC_STD_READ_CONTROL, NULL,
818 struct samr_user_info, &status);
819 if (NT_STATUS_IS_OK(status)) {
820 DEBUG(10,("_samr_QuerySecurity: querying security on user "
821 "Object with SID: %s\n",
822 sid_string_dbg(&uinfo->sid)));
823 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
824 status = make_samr_object_sd(
825 p->mem_ctx, &psd, &sd_size,
826 &usr_generic_mapping,
827 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
829 status = make_samr_object_sd(
830 p->mem_ctx, &psd, &sd_size,
831 &usr_nopwchange_generic_mapping,
832 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
837 ginfo = policy_handle_find(p, r->in.handle,
838 SEC_STD_READ_CONTROL, NULL,
839 struct samr_group_info, &status);
840 if (NT_STATUS_IS_OK(status)) {
842 * TODO: different SDs have to be generated for aliases groups
843 * and users. Currently all three get a default user SD
845 DEBUG(10,("_samr_QuerySecurity: querying security on group "
846 "Object with SID: %s\n",
847 sid_string_dbg(&ginfo->sid)));
848 status = make_samr_object_sd(
849 p->mem_ctx, &psd, &sd_size,
850 &usr_nopwchange_generic_mapping,
851 &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
855 ainfo = policy_handle_find(p, r->in.handle,
856 SEC_STD_READ_CONTROL, NULL,
857 struct samr_alias_info, &status);
858 if (NT_STATUS_IS_OK(status)) {
860 * TODO: different SDs have to be generated for aliases groups
861 * and users. Currently all three get a default user SD
863 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
864 "Object with SID: %s\n",
865 sid_string_dbg(&ainfo->sid)));
866 status = make_samr_object_sd(
867 p->mem_ctx, &psd, &sd_size,
868 &usr_nopwchange_generic_mapping,
869 &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
873 return NT_STATUS_OBJECT_TYPE_MISMATCH;
875 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
876 return NT_STATUS_NO_MEMORY;
881 /*******************************************************************
882 makes a SAM_ENTRY / UNISTR2* structure from a user list.
883 ********************************************************************/
885 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
886 struct samr_SamEntry **sam_pp,
887 uint32_t num_entries,
889 struct samr_displayentry *entries)
892 struct samr_SamEntry *sam;
896 if (num_entries == 0) {
900 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
902 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
903 return NT_STATUS_NO_MEMORY;
906 for (i = 0; i < num_entries; i++) {
909 * usrmgr expects a non-NULL terminated string with
910 * trust relationships
912 if (entries[i].acct_flags & ACB_DOMTRUST) {
913 init_unistr2(&uni_temp_name, entries[i].account_name,
916 init_unistr2(&uni_temp_name, entries[i].account_name,
920 init_lsa_String(&sam[i].name, entries[i].account_name);
921 sam[i].idx = entries[i].rid;
929 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
931 /*******************************************************************
932 _samr_EnumDomainUsers
933 ********************************************************************/
935 NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
936 struct samr_EnumDomainUsers *r)
939 struct samr_domain_info *dinfo;
941 uint32 enum_context = *r->in.resume_handle;
942 enum remote_arch_types ra_type = get_remote_arch();
943 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
944 uint32 max_entries = max_sam_entries;
945 struct samr_displayentry *entries = NULL;
946 struct samr_SamArray *samr_array = NULL;
947 struct samr_SamEntry *samr_entries = NULL;
949 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
951 dinfo = policy_handle_find(p, r->in.domain_handle,
952 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
953 struct samr_domain_info, &status);
954 if (!NT_STATUS_IS_OK(status)) {
958 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
960 return NT_STATUS_NO_MEMORY;
962 *r->out.sam = samr_array;
964 if (sid_check_is_builtin(&dinfo->sid)) {
965 /* No users in builtin. */
966 *r->out.resume_handle = *r->in.resume_handle;
967 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
975 if ((dinfo->disp_info->enum_users != NULL) &&
976 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
977 TALLOC_FREE(dinfo->disp_info->enum_users);
980 if (dinfo->disp_info->enum_users == NULL) {
981 dinfo->disp_info->enum_users = pdb_search_users(
982 dinfo->disp_info, r->in.acct_flags);
983 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
986 if (dinfo->disp_info->enum_users == NULL) {
987 /* END AS ROOT !!!! */
989 return NT_STATUS_ACCESS_DENIED;
992 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
993 enum_context, max_entries,
996 /* END AS ROOT !!!! */
1000 if (num_account == 0) {
1001 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1002 "total entries\n"));
1003 *r->out.resume_handle = *r->in.resume_handle;
1004 return NT_STATUS_OK;
1007 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1008 num_account, enum_context,
1010 if (!NT_STATUS_IS_OK(status)) {
1014 if (max_entries <= num_account) {
1015 status = STATUS_MORE_ENTRIES;
1017 status = NT_STATUS_OK;
1020 /* Ensure we cache this enumeration. */
1021 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1023 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1025 samr_array->count = num_account;
1026 samr_array->entries = samr_entries;
1028 *r->out.resume_handle = *r->in.resume_handle + num_account;
1029 *r->out.num_entries = num_account;
1031 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1036 /*******************************************************************
1037 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1038 ********************************************************************/
1040 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1041 struct samr_SamEntry **sam_pp,
1042 uint32_t num_sam_entries,
1043 struct samr_displayentry *entries)
1045 struct samr_SamEntry *sam;
1050 if (num_sam_entries == 0) {
1054 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1059 for (i = 0; i < num_sam_entries; i++) {
1061 * JRA. I think this should include the null. TNG does not.
1063 init_lsa_String(&sam[i].name, entries[i].account_name);
1064 sam[i].idx = entries[i].rid;
1070 /*******************************************************************
1071 _samr_EnumDomainGroups
1072 ********************************************************************/
1074 NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
1075 struct samr_EnumDomainGroups *r)
1078 struct samr_domain_info *dinfo;
1079 struct samr_displayentry *groups;
1081 struct samr_SamArray *samr_array = NULL;
1082 struct samr_SamEntry *samr_entries = NULL;
1084 dinfo = policy_handle_find(p, r->in.domain_handle,
1085 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1086 struct samr_domain_info, &status);
1087 if (!NT_STATUS_IS_OK(status)) {
1091 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1093 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1095 return NT_STATUS_NO_MEMORY;
1097 *r->out.sam = samr_array;
1099 if (sid_check_is_builtin(&dinfo->sid)) {
1100 /* No groups in builtin. */
1101 *r->out.resume_handle = *r->in.resume_handle;
1102 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1106 /* the domain group array is being allocated in the function below */
1110 if (dinfo->disp_info->groups == NULL) {
1111 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1113 if (dinfo->disp_info->groups == NULL) {
1115 return NT_STATUS_ACCESS_DENIED;
1119 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1120 *r->in.resume_handle,
1121 MAX_SAM_ENTRIES, &groups);
1124 /* Ensure we cache this enumeration. */
1125 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1127 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1128 num_groups, groups);
1130 if (MAX_SAM_ENTRIES <= num_groups) {
1131 status = STATUS_MORE_ENTRIES;
1133 status = NT_STATUS_OK;
1136 samr_array->count = num_groups;
1137 samr_array->entries = samr_entries;
1139 *r->out.num_entries = num_groups;
1140 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1142 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1147 /*******************************************************************
1148 _samr_EnumDomainAliases
1149 ********************************************************************/
1151 NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1152 struct samr_EnumDomainAliases *r)
1155 struct samr_domain_info *dinfo;
1156 struct samr_displayentry *aliases;
1157 uint32 num_aliases = 0;
1158 struct samr_SamArray *samr_array = NULL;
1159 struct samr_SamEntry *samr_entries = NULL;
1161 dinfo = policy_handle_find(p, r->in.domain_handle,
1162 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1163 struct samr_domain_info, &status);
1164 if (!NT_STATUS_IS_OK(status)) {
1168 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1169 sid_string_dbg(&dinfo->sid)));
1171 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1173 return NT_STATUS_NO_MEMORY;
1178 if (dinfo->disp_info->aliases == NULL) {
1179 dinfo->disp_info->aliases = pdb_search_aliases(
1180 dinfo->disp_info, &dinfo->sid);
1181 if (dinfo->disp_info->aliases == NULL) {
1183 return NT_STATUS_ACCESS_DENIED;
1187 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1188 *r->in.resume_handle,
1189 MAX_SAM_ENTRIES, &aliases);
1192 /* Ensure we cache this enumeration. */
1193 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1195 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1196 num_aliases, aliases);
1198 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1200 if (MAX_SAM_ENTRIES <= num_aliases) {
1201 status = STATUS_MORE_ENTRIES;
1203 status = NT_STATUS_OK;
1206 samr_array->count = num_aliases;
1207 samr_array->entries = samr_entries;
1209 *r->out.sam = samr_array;
1210 *r->out.num_entries = num_aliases;
1211 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1216 /*******************************************************************
1217 inits a samr_DispInfoGeneral structure.
1218 ********************************************************************/
1220 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1221 struct samr_DispInfoGeneral *r,
1222 uint32_t num_entries,
1224 struct samr_displayentry *entries)
1228 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1230 if (num_entries == 0) {
1231 return NT_STATUS_OK;
1234 r->count = num_entries;
1236 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1238 return NT_STATUS_NO_MEMORY;
1241 for (i = 0; i < num_entries ; i++) {
1243 init_lsa_String(&r->entries[i].account_name,
1244 entries[i].account_name);
1246 init_lsa_String(&r->entries[i].description,
1247 entries[i].description);
1249 init_lsa_String(&r->entries[i].full_name,
1250 entries[i].fullname);
1252 r->entries[i].rid = entries[i].rid;
1253 r->entries[i].acct_flags = entries[i].acct_flags;
1254 r->entries[i].idx = start_idx+i+1;
1257 return NT_STATUS_OK;
1260 /*******************************************************************
1261 inits a samr_DispInfoFull structure.
1262 ********************************************************************/
1264 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1265 struct samr_DispInfoFull *r,
1266 uint32_t num_entries,
1268 struct samr_displayentry *entries)
1272 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1274 if (num_entries == 0) {
1275 return NT_STATUS_OK;
1278 r->count = num_entries;
1280 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1282 return NT_STATUS_NO_MEMORY;
1285 for (i = 0; i < num_entries ; i++) {
1287 init_lsa_String(&r->entries[i].account_name,
1288 entries[i].account_name);
1290 init_lsa_String(&r->entries[i].description,
1291 entries[i].description);
1293 r->entries[i].rid = entries[i].rid;
1294 r->entries[i].acct_flags = entries[i].acct_flags;
1295 r->entries[i].idx = start_idx+i+1;
1298 return NT_STATUS_OK;
1301 /*******************************************************************
1302 inits a samr_DispInfoFullGroups structure.
1303 ********************************************************************/
1305 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1306 struct samr_DispInfoFullGroups *r,
1307 uint32_t num_entries,
1309 struct samr_displayentry *entries)
1313 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1315 if (num_entries == 0) {
1316 return NT_STATUS_OK;
1319 r->count = num_entries;
1321 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1323 return NT_STATUS_NO_MEMORY;
1326 for (i = 0; i < num_entries ; i++) {
1328 init_lsa_String(&r->entries[i].account_name,
1329 entries[i].account_name);
1331 init_lsa_String(&r->entries[i].description,
1332 entries[i].description);
1334 r->entries[i].rid = entries[i].rid;
1335 r->entries[i].acct_flags = entries[i].acct_flags;
1336 r->entries[i].idx = start_idx+i+1;
1339 return NT_STATUS_OK;
1342 /*******************************************************************
1343 inits a samr_DispInfoAscii structure.
1344 ********************************************************************/
1346 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1347 struct samr_DispInfoAscii *r,
1348 uint32_t num_entries,
1350 struct samr_displayentry *entries)
1354 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1356 if (num_entries == 0) {
1357 return NT_STATUS_OK;
1360 r->count = num_entries;
1362 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1364 return NT_STATUS_NO_MEMORY;
1367 for (i = 0; i < num_entries ; i++) {
1369 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1370 entries[i].account_name);
1372 r->entries[i].idx = start_idx+i+1;
1375 return NT_STATUS_OK;
1378 /*******************************************************************
1379 inits a samr_DispInfoAscii structure.
1380 ********************************************************************/
1382 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1383 struct samr_DispInfoAscii *r,
1384 uint32_t num_entries,
1386 struct samr_displayentry *entries)
1390 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1392 if (num_entries == 0) {
1393 return NT_STATUS_OK;
1396 r->count = num_entries;
1398 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1400 return NT_STATUS_NO_MEMORY;
1403 for (i = 0; i < num_entries ; i++) {
1405 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1406 entries[i].account_name);
1408 r->entries[i].idx = start_idx+i+1;
1411 return NT_STATUS_OK;
1414 /*******************************************************************
1415 _samr_QueryDisplayInfo
1416 ********************************************************************/
1418 NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1419 struct samr_QueryDisplayInfo *r)
1422 struct samr_domain_info *dinfo;
1423 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1425 uint32 max_entries = r->in.max_entries;
1427 union samr_DispInfo *disp_info = r->out.info;
1430 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1431 uint32 num_account = 0;
1432 enum remote_arch_types ra_type = get_remote_arch();
1433 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1434 struct samr_displayentry *entries = NULL;
1436 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1438 dinfo = policy_handle_find(p, r->in.domain_handle,
1439 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1440 struct samr_domain_info, &status);
1441 if (!NT_STATUS_IS_OK(status)) {
1445 if (sid_check_is_builtin(&dinfo->sid)) {
1446 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1447 return NT_STATUS_OK;
1451 * calculate how many entries we will return.
1453 * - the number of entries the client asked
1454 * - our limit on that
1455 * - the starting point (enumeration context)
1456 * - the buffer size the client will accept
1460 * We are a lot more like W2K. Instead of reading the SAM
1461 * each time to find the records we need to send back,
1462 * we read it once and link that copy to the sam handle.
1463 * For large user list (over the MAX_SAM_ENTRIES)
1464 * it's a definitive win.
1465 * second point to notice: between enumerations
1466 * our sam is now the same as it's a snapshoot.
1467 * third point: got rid of the static SAM_USER_21 struct
1468 * no more intermediate.
1469 * con: it uses much more memory, as a full copy is stored
1472 * If you want to change it, think twice and think
1473 * of the second point , that's really important.
1478 if ((r->in.level < 1) || (r->in.level > 5)) {
1479 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1480 (unsigned int)r->in.level ));
1481 return NT_STATUS_INVALID_INFO_CLASS;
1484 /* first limit the number of entries we will return */
1485 if (r->in.max_entries > max_sam_entries) {
1486 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1487 "entries, limiting to %d\n", r->in.max_entries,
1489 max_entries = max_sam_entries;
1492 /* calculate the size and limit on the number of entries we will
1495 temp_size=max_entries*struct_size;
1497 if (temp_size > r->in.buf_size) {
1498 max_entries = MIN((r->in.buf_size / struct_size),max_entries);
1499 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1500 "only %d entries\n", max_entries));
1505 /* THe following done as ROOT. Don't return without unbecome_root(). */
1507 switch (r->in.level) {
1510 if (dinfo->disp_info->users == NULL) {
1511 dinfo->disp_info->users = pdb_search_users(
1512 dinfo->disp_info, ACB_NORMAL);
1513 if (dinfo->disp_info->users == NULL) {
1515 return NT_STATUS_ACCESS_DENIED;
1517 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1518 (unsigned int)r->in.start_idx));
1520 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1521 (unsigned int)r->in.start_idx));
1524 num_account = pdb_search_entries(dinfo->disp_info->users,
1525 r->in.start_idx, max_entries,
1529 if (dinfo->disp_info->machines == NULL) {
1530 dinfo->disp_info->machines = pdb_search_users(
1531 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1532 if (dinfo->disp_info->machines == NULL) {
1534 return NT_STATUS_ACCESS_DENIED;
1536 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1537 (unsigned int)r->in.start_idx));
1539 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1540 (unsigned int)r->in.start_idx));
1543 num_account = pdb_search_entries(dinfo->disp_info->machines,
1544 r->in.start_idx, max_entries,
1549 if (dinfo->disp_info->groups == NULL) {
1550 dinfo->disp_info->groups = pdb_search_groups(
1552 if (dinfo->disp_info->groups == NULL) {
1554 return NT_STATUS_ACCESS_DENIED;
1556 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1557 (unsigned int)r->in.start_idx));
1559 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1560 (unsigned int)r->in.start_idx));
1563 num_account = pdb_search_entries(dinfo->disp_info->groups,
1564 r->in.start_idx, max_entries,
1569 smb_panic("info class changed");
1575 /* Now create reply structure */
1576 switch (r->in.level) {
1578 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1579 num_account, r->in.start_idx,
1583 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1584 num_account, r->in.start_idx,
1588 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1589 num_account, r->in.start_idx,
1593 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1594 num_account, r->in.start_idx,
1598 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1599 num_account, r->in.start_idx,
1603 smb_panic("info class changed");
1607 if (!NT_STATUS_IS_OK(disp_ret))
1610 if (max_entries <= num_account) {
1611 status = STATUS_MORE_ENTRIES;
1613 status = NT_STATUS_OK;
1616 /* Ensure we cache this enumeration. */
1617 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1619 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1621 *r->out.total_size = num_account * struct_size;
1622 *r->out.returned_size = num_account ? temp_size : 0;
1627 /****************************************************************
1628 _samr_QueryDisplayInfo2
1629 ****************************************************************/
1631 NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1632 struct samr_QueryDisplayInfo2 *r)
1634 struct samr_QueryDisplayInfo q;
1636 q.in.domain_handle = r->in.domain_handle;
1637 q.in.level = r->in.level;
1638 q.in.start_idx = r->in.start_idx;
1639 q.in.max_entries = r->in.max_entries;
1640 q.in.buf_size = r->in.buf_size;
1642 q.out.total_size = r->out.total_size;
1643 q.out.returned_size = r->out.returned_size;
1644 q.out.info = r->out.info;
1646 return _samr_QueryDisplayInfo(p, &q);
1649 /****************************************************************
1650 _samr_QueryDisplayInfo3
1651 ****************************************************************/
1653 NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1654 struct samr_QueryDisplayInfo3 *r)
1656 struct samr_QueryDisplayInfo q;
1658 q.in.domain_handle = r->in.domain_handle;
1659 q.in.level = r->in.level;
1660 q.in.start_idx = r->in.start_idx;
1661 q.in.max_entries = r->in.max_entries;
1662 q.in.buf_size = r->in.buf_size;
1664 q.out.total_size = r->out.total_size;
1665 q.out.returned_size = r->out.returned_size;
1666 q.out.info = r->out.info;
1668 return _samr_QueryDisplayInfo(p, &q);
1671 /*******************************************************************
1672 _samr_QueryAliasInfo
1673 ********************************************************************/
1675 NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1676 struct samr_QueryAliasInfo *r)
1678 struct samr_alias_info *ainfo;
1679 struct acct_info info;
1681 union samr_AliasInfo *alias_info = NULL;
1682 const char *alias_name = NULL;
1683 const char *alias_description = NULL;
1685 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1687 ainfo = policy_handle_find(p, r->in.alias_handle,
1688 SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1689 struct samr_alias_info, &status);
1690 if (!NT_STATUS_IS_OK(status)) {
1694 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1696 return NT_STATUS_NO_MEMORY;
1700 status = pdb_get_aliasinfo(&ainfo->sid, &info);
1703 if ( !NT_STATUS_IS_OK(status))
1706 /* FIXME: info contains fstrings */
1707 alias_name = talloc_strdup(r, info.acct_name);
1708 alias_description = talloc_strdup(r, info.acct_desc);
1710 switch (r->in.level) {
1712 alias_info->all.name.string = alias_name;
1713 alias_info->all.num_members = 1; /* ??? */
1714 alias_info->all.description.string = alias_description;
1717 alias_info->name.string = alias_name;
1719 case ALIASINFODESCRIPTION:
1720 alias_info->description.string = alias_description;
1723 return NT_STATUS_INVALID_INFO_CLASS;
1726 *r->out.info = alias_info;
1728 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1730 return NT_STATUS_OK;
1733 /*******************************************************************
1735 ********************************************************************/
1737 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1738 struct samr_LookupNames *r)
1740 struct samr_domain_info *dinfo;
1743 enum lsa_SidType *type;
1745 int num_rids = r->in.num_names;
1746 struct samr_Ids rids, types;
1747 uint32_t num_mapped = 0;
1749 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1751 dinfo = policy_handle_find(p, r->in.domain_handle,
1752 0 /* Don't know the acc_bits yet */, NULL,
1753 struct samr_domain_info, &status);
1754 if (!NT_STATUS_IS_OK(status)) {
1758 if (num_rids > MAX_SAM_ENTRIES) {
1759 num_rids = MAX_SAM_ENTRIES;
1760 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1763 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1764 NT_STATUS_HAVE_NO_MEMORY(rid);
1766 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1767 NT_STATUS_HAVE_NO_MEMORY(type);
1769 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1770 sid_string_dbg(&dinfo->sid)));
1772 for (i = 0; i < num_rids; i++) {
1774 status = NT_STATUS_NONE_MAPPED;
1775 type[i] = SID_NAME_UNKNOWN;
1777 rid[i] = 0xffffffff;
1779 if (sid_check_is_builtin(&dinfo->sid)) {
1780 if (lookup_builtin_name(r->in.names[i].string,
1783 type[i] = SID_NAME_ALIAS;
1786 lookup_global_sam_name(r->in.names[i].string, 0,
1790 if (type[i] != SID_NAME_UNKNOWN) {
1795 if (num_mapped == num_rids) {
1796 status = NT_STATUS_OK;
1797 } else if (num_mapped == 0) {
1798 status = NT_STATUS_NONE_MAPPED;
1800 status = STATUS_SOME_UNMAPPED;
1803 rids.count = num_rids;
1806 types.count = num_rids;
1807 types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1808 NT_STATUS_HAVE_NO_MEMORY(type);
1809 for (i = 0; i < num_rids; i++) {
1810 types.ids[i] = (type[i] & 0xffffffff);
1813 *r->out.rids = rids;
1814 *r->out.types = types;
1816 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1821 /****************************************************************
1822 _samr_ChangePasswordUser
1823 ****************************************************************/
1825 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1826 struct samr_ChangePasswordUser *r)
1830 struct samr_user_info *uinfo;
1832 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1833 struct samr_Password lm_pwd, nt_pwd;
1835 uinfo = policy_handle_find(p, r->in.user_handle,
1836 SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1837 struct samr_user_info, &status);
1838 if (!NT_STATUS_IS_OK(status)) {
1842 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1843 sid_string_dbg(&uinfo->sid)));
1845 if (!(pwd = samu_new(NULL))) {
1846 return NT_STATUS_NO_MEMORY;
1850 ret = pdb_getsampwsid(pwd, &uinfo->sid);
1855 return NT_STATUS_WRONG_PASSWORD;
1859 const uint8_t *lm_pass, *nt_pass;
1861 lm_pass = pdb_get_lanman_passwd(pwd);
1862 nt_pass = pdb_get_nt_passwd(pwd);
1864 if (!lm_pass || !nt_pass) {
1865 status = NT_STATUS_WRONG_PASSWORD;
1869 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1870 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1873 /* basic sanity checking on parameters. Do this before any database ops */
1874 if (!r->in.lm_present || !r->in.nt_present ||
1875 !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1876 !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1877 /* we should really handle a change with lm not
1879 status = NT_STATUS_INVALID_PARAMETER_MIX;
1883 /* decrypt and check the new lm hash */
1884 D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1885 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1886 if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1887 status = NT_STATUS_WRONG_PASSWORD;
1891 /* decrypt and check the new nt hash */
1892 D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1893 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1894 if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1895 status = NT_STATUS_WRONG_PASSWORD;
1899 /* The NT Cross is not required by Win2k3 R2, but if present
1900 check the nt cross hash */
1901 if (r->in.cross1_present && r->in.nt_cross) {
1902 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1903 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1904 status = NT_STATUS_WRONG_PASSWORD;
1909 /* The LM Cross is not required by Win2k3 R2, but if present
1910 check the lm cross hash */
1911 if (r->in.cross2_present && r->in.lm_cross) {
1912 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1913 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1914 status = NT_STATUS_WRONG_PASSWORD;
1919 if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1920 !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1921 status = NT_STATUS_ACCESS_DENIED;
1925 status = pdb_update_sam_account(pwd);
1932 /*******************************************************************
1933 _samr_ChangePasswordUser2
1934 ********************************************************************/
1936 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1937 struct samr_ChangePasswordUser2 *r)
1940 char *user_name = NULL;
1943 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1945 if (!r->in.account->string) {
1946 return NT_STATUS_INVALID_PARAMETER;
1948 fstrcpy(wks, r->in.server->string);
1950 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1953 * Pass the user through the NT -> unix user mapping
1957 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1959 return NT_STATUS_NO_MEMORY;
1963 * UNIX username case mangling not required, pass_oem_change
1964 * is case insensitive.
1967 status = pass_oem_change(user_name,
1969 r->in.lm_password->data,
1970 r->in.lm_verifier->hash,
1971 r->in.nt_password->data,
1972 r->in.nt_verifier->hash,
1975 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1977 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1978 return NT_STATUS_WRONG_PASSWORD;
1984 /****************************************************************
1985 _samr_OemChangePasswordUser2
1986 ****************************************************************/
1988 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1989 struct samr_OemChangePasswordUser2 *r)
1992 char *user_name = NULL;
1993 const char *wks = NULL;
1995 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1997 if (!r->in.account->string) {
1998 return NT_STATUS_INVALID_PARAMETER;
2000 if (r->in.server && r->in.server->string) {
2001 wks = r->in.server->string;
2004 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
2007 * Pass the user through the NT -> unix user mapping
2011 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
2013 return NT_STATUS_NO_MEMORY;
2017 * UNIX username case mangling not required, pass_oem_change
2018 * is case insensitive.
2021 if (!r->in.hash || !r->in.password) {
2022 return NT_STATUS_INVALID_PARAMETER;
2025 status = pass_oem_change(user_name,
2027 r->in.password->data,
2033 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2034 return NT_STATUS_WRONG_PASSWORD;
2037 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2042 /*******************************************************************
2043 _samr_ChangePasswordUser3
2044 ********************************************************************/
2046 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
2047 struct samr_ChangePasswordUser3 *r)
2050 char *user_name = NULL;
2051 const char *wks = NULL;
2052 enum samPwdChangeReason reject_reason;
2053 struct samr_DomInfo1 *dominfo = NULL;
2054 struct userPwdChangeFailureInformation *reject = NULL;
2057 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2059 if (!r->in.account->string) {
2060 return NT_STATUS_INVALID_PARAMETER;
2062 if (r->in.server && r->in.server->string) {
2063 wks = r->in.server->string;
2066 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2069 * Pass the user through the NT -> unix user mapping
2073 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
2075 return NT_STATUS_NO_MEMORY;
2079 * UNIX username case mangling not required, pass_oem_change
2080 * is case insensitive.
2083 status = pass_oem_change(user_name,
2085 r->in.lm_password->data,
2086 r->in.lm_verifier->hash,
2087 r->in.nt_password->data,
2088 r->in.nt_verifier->hash,
2090 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2091 return NT_STATUS_WRONG_PASSWORD;
2094 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2095 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2097 time_t u_expire, u_min_age;
2098 uint32 account_policy_temp;
2100 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2102 return NT_STATUS_NO_MEMORY;
2105 reject = TALLOC_ZERO_P(p->mem_ctx,
2106 struct userPwdChangeFailureInformation);
2108 return NT_STATUS_NO_MEMORY;
2115 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2116 dominfo->min_password_length = tmp;
2118 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2119 dominfo->password_history_length = tmp;
2121 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2122 &dominfo->password_properties);
2124 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2125 u_expire = account_policy_temp;
2127 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2128 u_min_age = account_policy_temp;
2134 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2135 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2137 if (lp_check_password_script() && *lp_check_password_script()) {
2138 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2141 reject->extendedFailureReason = reject_reason;
2143 *r->out.dominfo = dominfo;
2144 *r->out.reject = reject;
2147 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2152 /*******************************************************************
2153 makes a SAMR_R_LOOKUP_RIDS structure.
2154 ********************************************************************/
2156 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2158 struct lsa_String **lsa_name_array_p)
2160 struct lsa_String *lsa_name_array = NULL;
2163 *lsa_name_array_p = NULL;
2165 if (num_names != 0) {
2166 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2167 if (!lsa_name_array) {
2172 for (i = 0; i < num_names; i++) {
2173 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2174 init_lsa_String(&lsa_name_array[i], names[i]);
2177 *lsa_name_array_p = lsa_name_array;
2182 /*******************************************************************
2184 ********************************************************************/
2186 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2187 struct samr_LookupRids *r)
2189 struct samr_domain_info *dinfo;
2192 enum lsa_SidType *attrs = NULL;
2193 uint32 *wire_attrs = NULL;
2194 int num_rids = (int)r->in.num_rids;
2196 struct lsa_Strings names_array;
2197 struct samr_Ids types_array;
2198 struct lsa_String *lsa_names = NULL;
2200 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2202 dinfo = policy_handle_find(p, r->in.domain_handle,
2203 0 /* Don't know the acc_bits yet */, NULL,
2204 struct samr_domain_info, &status);
2205 if (!NT_STATUS_IS_OK(status)) {
2209 if (num_rids > 1000) {
2210 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2211 "to samba4 idl this is not possible\n", num_rids));
2212 return NT_STATUS_UNSUCCESSFUL;
2216 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2217 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2218 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2220 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2221 return NT_STATUS_NO_MEMORY;
2228 become_root(); /* lookup_sid can require root privs */
2229 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2233 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2234 status = NT_STATUS_OK;
2237 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2239 return NT_STATUS_NO_MEMORY;
2242 /* Convert from enum lsa_SidType to uint32 for wire format. */
2243 for (i = 0; i < num_rids; i++) {
2244 wire_attrs[i] = (uint32)attrs[i];
2247 names_array.count = num_rids;
2248 names_array.names = lsa_names;
2250 types_array.count = num_rids;
2251 types_array.ids = wire_attrs;
2253 *r->out.names = names_array;
2254 *r->out.types = types_array;
2256 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2261 /*******************************************************************
2263 ********************************************************************/
2265 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2266 struct samr_OpenUser *r)
2268 struct samu *sampass=NULL;
2270 struct samr_domain_info *dinfo;
2271 struct samr_user_info *uinfo;
2272 struct security_descriptor *psd = NULL;
2274 uint32 des_access = r->in.access_mask;
2275 uint32_t extra_access = 0;
2280 /* These two privileges, if != SEC_PRIV_INVALID, indicate
2281 * privileges that the user must have to complete this
2282 * operation in defience of the fixed ACL */
2283 enum sec_privilege needed_priv_1, needed_priv_2;
2286 dinfo = policy_handle_find(p, r->in.domain_handle,
2287 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2288 struct samr_domain_info, &status);
2289 if (!NT_STATUS_IS_OK(status)) {
2293 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2294 return NT_STATUS_NO_MEMORY;
2297 /* append the user's RID to it */
2299 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2300 return NT_STATUS_NO_SUCH_USER;
2302 /* check if access can be granted as requested by client. */
2303 map_max_allowed_access(p->session_info->security_token,
2304 &p->session_info->utok,
2307 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2308 se_map_generic(&des_access, &usr_generic_mapping);
2311 * Get the sampass first as we need to check privileges
2312 * based on what kind of user object this is.
2313 * But don't reveal info too early if it didn't exist.
2317 ret=pdb_getsampwsid(sampass, &sid);
2320 needed_priv_1 = SEC_PRIV_INVALID;
2321 needed_priv_2 = SEC_PRIV_INVALID;
2323 * We do the override access checks on *open*, not at
2327 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2329 if (acb_info & ACB_WSTRUST) {
2331 * SeMachineAccount is needed to add
2332 * GENERIC_RIGHTS_USER_WRITE to a machine
2335 needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2337 if (acb_info & ACB_NORMAL) {
2339 * SeAddUsers is needed to add
2340 * GENERIC_RIGHTS_USER_WRITE to a normal
2343 needed_priv_1 = SEC_PRIV_ADD_USERS;
2346 * Cheat - we have not set a specific privilege for
2347 * server (BDC) or domain trust account, so allow
2348 * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2349 * DOMAIN_RID_ADMINS.
2351 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2352 if (lp_enable_privileges() && nt_token_check_domain_rid(p->session_info->security_token,
2353 DOMAIN_RID_ADMINS)) {
2354 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2355 extra_access = GENERIC_RIGHTS_USER_WRITE;
2356 DEBUG(4,("_samr_OpenUser: Allowing "
2357 "GENERIC_RIGHTS_USER_WRITE for "
2363 TALLOC_FREE(sampass);
2365 nt_status = access_check_object(psd, p->session_info->security_token,
2366 needed_priv_1, needed_priv_2,
2367 GENERIC_RIGHTS_USER_WRITE, des_access,
2368 &acc_granted, "_samr_OpenUser");
2370 if ( !NT_STATUS_IS_OK(nt_status) )
2373 /* check that the SID exists in our domain. */
2375 return NT_STATUS_NO_SUCH_USER;
2378 /* If we did the rid admins hack above, allow access. */
2379 acc_granted |= extra_access;
2381 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2382 struct samr_user_info, &nt_status);
2383 if (!NT_STATUS_IS_OK(nt_status)) {
2388 return NT_STATUS_OK;
2391 /*************************************************************************
2392 *************************************************************************/
2394 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2396 struct lsa_BinaryString **_r)
2398 struct lsa_BinaryString *r;
2401 return NT_STATUS_INVALID_PARAMETER;
2404 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2406 return NT_STATUS_NO_MEMORY;
2409 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2411 return NT_STATUS_NO_MEMORY;
2413 memcpy(r->array, blob->data, blob->length);
2414 r->size = blob->length;
2415 r->length = blob->length;
2418 return NT_STATUS_NO_MEMORY;
2423 return NT_STATUS_OK;
2426 /*************************************************************************
2427 *************************************************************************/
2429 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2432 struct samr_LogonHours hours;
2433 const int units_per_week = 168;
2436 hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2441 hours.units_per_week = units_per_week;
2442 memset(hours.bits, 0xFF, units_per_week);
2444 if (pdb_get_hours(pw)) {
2445 memcpy(hours.bits, pdb_get_hours(pw),
2446 MIN(pdb_get_hours_len(pw), units_per_week));
2452 /*************************************************************************
2454 *************************************************************************/
2456 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2457 struct samr_UserInfo1 *r,
2459 struct dom_sid *domain_sid)
2461 const struct dom_sid *sid_group;
2462 uint32_t primary_gid;
2465 sid_group = pdb_get_group_sid(pw);
2468 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2469 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2470 "which conflicts with the domain sid %s. Failing operation.\n",
2471 pdb_get_username(pw), sid_string_dbg(sid_group),
2472 sid_string_dbg(domain_sid)));
2473 return NT_STATUS_UNSUCCESSFUL;
2476 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2477 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2478 r->primary_gid = primary_gid;
2479 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2480 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2482 return NT_STATUS_OK;
2485 /*************************************************************************
2487 *************************************************************************/
2489 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2490 struct samr_UserInfo2 *r,
2493 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2494 r->reserved.string = NULL;
2495 r->country_code = pdb_get_country_code(pw);
2496 r->code_page = pdb_get_code_page(pw);
2498 return NT_STATUS_OK;
2501 /*************************************************************************
2503 *************************************************************************/
2505 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2506 struct samr_UserInfo3 *r,
2508 struct dom_sid *domain_sid)
2510 const struct dom_sid *sid_user, *sid_group;
2511 uint32_t rid, primary_gid;
2513 sid_user = pdb_get_user_sid(pw);
2515 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2516 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2517 "the domain sid %s. Failing operation.\n",
2518 pdb_get_username(pw), sid_string_dbg(sid_user),
2519 sid_string_dbg(domain_sid)));
2520 return NT_STATUS_UNSUCCESSFUL;
2524 sid_group = pdb_get_group_sid(pw);
2527 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2528 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2529 "which conflicts with the domain sid %s. Failing operation.\n",
2530 pdb_get_username(pw), sid_string_dbg(sid_group),
2531 sid_string_dbg(domain_sid)));
2532 return NT_STATUS_UNSUCCESSFUL;
2535 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2536 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2537 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2538 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2539 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2541 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2542 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2543 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2544 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2545 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2546 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2547 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2549 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2551 r->primary_gid = primary_gid;
2552 r->acct_flags = pdb_get_acct_ctrl(pw);
2553 r->bad_password_count = pdb_get_bad_password_count(pw);
2554 r->logon_count = pdb_get_logon_count(pw);
2556 return NT_STATUS_OK;
2559 /*************************************************************************
2561 *************************************************************************/
2563 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2564 struct samr_UserInfo4 *r,
2567 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2569 return NT_STATUS_OK;
2572 /*************************************************************************
2574 *************************************************************************/
2576 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2577 struct samr_UserInfo5 *r,
2579 struct dom_sid *domain_sid)
2581 const struct dom_sid *sid_user, *sid_group;
2582 uint32_t rid, primary_gid;
2584 sid_user = pdb_get_user_sid(pw);
2586 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2587 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2588 "the domain sid %s. Failing operation.\n",
2589 pdb_get_username(pw), sid_string_dbg(sid_user),
2590 sid_string_dbg(domain_sid)));
2591 return NT_STATUS_UNSUCCESSFUL;
2595 sid_group = pdb_get_group_sid(pw);
2598 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2599 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2600 "which conflicts with the domain sid %s. Failing operation.\n",
2601 pdb_get_username(pw), sid_string_dbg(sid_group),
2602 sid_string_dbg(domain_sid)));
2603 return NT_STATUS_UNSUCCESSFUL;
2606 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2607 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2608 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2609 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2611 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2612 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2613 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2614 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2615 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2616 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2617 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2618 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2620 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2622 r->primary_gid = primary_gid;
2623 r->acct_flags = pdb_get_acct_ctrl(pw);
2624 r->bad_password_count = pdb_get_bad_password_count(pw);
2625 r->logon_count = pdb_get_logon_count(pw);
2627 return NT_STATUS_OK;
2630 /*************************************************************************
2632 *************************************************************************/
2634 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2635 struct samr_UserInfo6 *r,
2638 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2639 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2641 return NT_STATUS_OK;
2644 /*************************************************************************
2645 get_user_info_7. Safe. Only gives out account_name.
2646 *************************************************************************/
2648 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2649 struct samr_UserInfo7 *r,
2650 struct samu *smbpass)
2652 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2653 if (!r->account_name.string) {
2654 return NT_STATUS_NO_MEMORY;
2657 return NT_STATUS_OK;
2660 /*************************************************************************
2662 *************************************************************************/
2664 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2665 struct samr_UserInfo8 *r,
2668 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2670 return NT_STATUS_OK;
2673 /*************************************************************************
2674 get_user_info_9. Only gives out primary group SID.
2675 *************************************************************************/
2677 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2678 struct samr_UserInfo9 *r,
2679 struct samu *smbpass)
2681 r->primary_gid = pdb_get_group_rid(smbpass);
2683 return NT_STATUS_OK;
2686 /*************************************************************************
2688 *************************************************************************/
2690 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2691 struct samr_UserInfo10 *r,
2694 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2695 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2697 return NT_STATUS_OK;
2700 /*************************************************************************
2702 *************************************************************************/
2704 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2705 struct samr_UserInfo11 *r,
2708 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2710 return NT_STATUS_OK;
2713 /*************************************************************************
2715 *************************************************************************/
2717 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2718 struct samr_UserInfo12 *r,
2721 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2723 return NT_STATUS_OK;
2726 /*************************************************************************
2728 *************************************************************************/
2730 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2731 struct samr_UserInfo13 *r,
2734 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2736 return NT_STATUS_OK;
2739 /*************************************************************************
2741 *************************************************************************/
2743 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2744 struct samr_UserInfo14 *r,
2747 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2749 return NT_STATUS_OK;
2752 /*************************************************************************
2753 get_user_info_16. Safe. Only gives out acb bits.
2754 *************************************************************************/
2756 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2757 struct samr_UserInfo16 *r,
2758 struct samu *smbpass)
2760 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2762 return NT_STATUS_OK;
2765 /*************************************************************************
2767 *************************************************************************/
2769 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2770 struct samr_UserInfo17 *r,
2773 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2775 return NT_STATUS_OK;
2778 /*************************************************************************
2779 get_user_info_18. OK - this is the killer as it gives out password info.
2780 Ensure that this is only allowed on an encrypted connection with a root
2782 *************************************************************************/
2784 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2785 TALLOC_CTX *mem_ctx,
2786 struct samr_UserInfo18 *r,
2787 struct dom_sid *user_sid)
2789 struct samu *smbpass=NULL;
2791 const uint8_t *nt_pass = NULL;
2792 const uint8_t *lm_pass = NULL;
2796 if (p->session_info->system) {
2800 if ((p->auth.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) ||
2801 (p->auth.auth_type != DCERPC_AUTH_TYPE_KRB5) ||
2802 (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO)) {
2803 return NT_STATUS_ACCESS_DENIED;
2806 if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2807 return NT_STATUS_ACCESS_DENIED;
2812 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2815 if ( !(smbpass = samu_new( mem_ctx )) ) {
2816 return NT_STATUS_NO_MEMORY;
2819 ret = pdb_getsampwsid(smbpass, user_sid);
2822 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2823 TALLOC_FREE(smbpass);
2824 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2827 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2829 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2830 TALLOC_FREE(smbpass);
2831 return NT_STATUS_ACCOUNT_DISABLED;
2834 lm_pass = pdb_get_lanman_passwd(smbpass);
2835 if (lm_pass != NULL) {
2836 memcpy(r->lm_pwd.hash, lm_pass, 16);
2837 r->lm_pwd_active = true;
2840 nt_pass = pdb_get_nt_passwd(smbpass);
2841 if (nt_pass != NULL) {
2842 memcpy(r->nt_pwd.hash, nt_pass, 16);
2843 r->nt_pwd_active = true;
2845 r->password_expired = 0; /* FIXME */
2847 TALLOC_FREE(smbpass);
2849 return NT_STATUS_OK;
2852 /*************************************************************************
2854 *************************************************************************/
2856 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2857 struct samr_UserInfo20 *r,
2858 struct samu *sampass)
2860 const char *munged_dial = NULL;
2863 struct lsa_BinaryString *parameters = NULL;
2867 munged_dial = pdb_get_munged_dial(sampass);
2869 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2870 munged_dial, (int)strlen(munged_dial)));
2873 blob = base64_decode_data_blob(munged_dial);
2875 blob = data_blob_string_const_null("");
2878 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2879 data_blob_free(&blob);
2880 if (!NT_STATUS_IS_OK(status)) {
2884 r->parameters = *parameters;
2886 return NT_STATUS_OK;
2890 /*************************************************************************
2892 *************************************************************************/
2894 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2895 struct samr_UserInfo21 *r,
2897 struct dom_sid *domain_sid,
2898 uint32_t acc_granted)
2901 const struct dom_sid *sid_user, *sid_group;
2902 uint32_t rid, primary_gid;
2903 NTTIME force_password_change;
2904 time_t must_change_time;
2905 struct lsa_BinaryString *parameters = NULL;
2906 const char *munged_dial = NULL;
2911 sid_user = pdb_get_user_sid(pw);
2913 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2914 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2915 "the domain sid %s. Failing operation.\n",
2916 pdb_get_username(pw), sid_string_dbg(sid_user),
2917 sid_string_dbg(domain_sid)));
2918 return NT_STATUS_UNSUCCESSFUL;
2922 sid_group = pdb_get_group_sid(pw);
2925 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2926 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2927 "which conflicts with the domain sid %s. Failing operation.\n",
2928 pdb_get_username(pw), sid_string_dbg(sid_group),
2929 sid_string_dbg(domain_sid)));
2930 return NT_STATUS_UNSUCCESSFUL;
2933 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2934 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2935 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2936 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2937 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2939 must_change_time = pdb_get_pass_must_change_time(pw);
2940 if (must_change_time == get_time_t_max()) {
2941 unix_to_nt_time_abs(&force_password_change, must_change_time);
2943 unix_to_nt_time(&force_password_change, must_change_time);
2946 munged_dial = pdb_get_munged_dial(pw);
2948 blob = base64_decode_data_blob(munged_dial);
2950 blob = data_blob_string_const_null("");
2953 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2954 data_blob_free(&blob);
2955 if (!NT_STATUS_IS_OK(status)) {
2959 r->force_password_change = force_password_change;
2961 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2962 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2963 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2964 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2965 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2966 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2967 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2968 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2969 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2971 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2972 r->parameters = *parameters;
2974 r->primary_gid = primary_gid;
2975 r->acct_flags = pdb_get_acct_ctrl(pw);
2976 r->bad_password_count = pdb_get_bad_password_count(pw);
2977 r->logon_count = pdb_get_logon_count(pw);
2978 r->fields_present = pdb_build_fields_present(pw);
2979 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2980 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2981 r->country_code = pdb_get_country_code(pw);
2982 r->code_page = pdb_get_code_page(pw);
2983 r->lm_password_set = 0;
2984 r->nt_password_set = 0;
2989 Look at a user on a real NT4 PDC with usrmgr, press
2990 'ok'. Then you will see that fields_present is set to
2991 0x08f827fa. Look at the user immediately after that again,
2992 and you will see that 0x00fffff is returned. This solves
2993 the problem that you get access denied after having looked
3001 return NT_STATUS_OK;
3004 /*******************************************************************
3006 ********************************************************************/
3008 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
3009 struct samr_QueryUserInfo *r)
3012 union samr_UserInfo *user_info = NULL;
3013 struct samr_user_info *uinfo;
3014 struct dom_sid domain_sid;
3017 struct samu *pwd = NULL;
3018 uint32_t acc_required, acc_granted;
3020 switch (r->in.level) {
3021 case 1: /* UserGeneralInformation */
3022 /* USER_READ_GENERAL */
3023 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3025 case 2: /* UserPreferencesInformation */
3026 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
3027 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
3028 SAMR_USER_ACCESS_GET_NAME_ETC;
3030 case 3: /* UserLogonInformation */
3031 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3032 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3033 SAMR_USER_ACCESS_GET_LOCALE |
3034 SAMR_USER_ACCESS_GET_LOGONINFO |
3035 SAMR_USER_ACCESS_GET_ATTRIBUTES;
3037 case 4: /* UserLogonHoursInformation */
3038 /* USER_READ_LOGON */
3039 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3041 case 5: /* UserAccountInformation */
3042 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3043 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3044 SAMR_USER_ACCESS_GET_LOCALE |
3045 SAMR_USER_ACCESS_GET_LOGONINFO |
3046 SAMR_USER_ACCESS_GET_ATTRIBUTES;
3048 case 6: /* UserNameInformation */
3049 case 7: /* UserAccountNameInformation */
3050 case 8: /* UserFullNameInformation */
3051 case 9: /* UserPrimaryGroupInformation */
3052 case 13: /* UserAdminCommentInformation */
3053 /* USER_READ_GENERAL */
3054 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3056 case 10: /* UserHomeInformation */
3057 case 11: /* UserScriptInformation */
3058 case 12: /* UserProfileInformation */
3059 case 14: /* UserWorkStationsInformation */
3060 /* USER_READ_LOGON */
3061 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3063 case 16: /* UserControlInformation */
3064 case 17: /* UserExpiresInformation */
3065 case 20: /* UserParametersInformation */
3066 /* USER_READ_ACCOUNT */
3067 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3069 case 21: /* UserAllInformation */
3071 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3073 case 18: /* UserInternal1Information */
3075 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3077 case 23: /* UserInternal4Information */
3078 case 24: /* UserInternal4InformationNew */
3079 case 25: /* UserInternal4InformationNew */
3080 case 26: /* UserInternal5InformationNew */
3082 return NT_STATUS_INVALID_INFO_CLASS;
3086 uinfo = policy_handle_find(p, r->in.user_handle,
3087 acc_required, &acc_granted,
3088 struct samr_user_info, &status);
3089 if (!NT_STATUS_IS_OK(status)) {
3093 domain_sid = uinfo->sid;
3095 sid_split_rid(&domain_sid, &rid);
3097 if (!sid_check_is_in_our_domain(&uinfo->sid))
3098 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3100 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3101 sid_string_dbg(&uinfo->sid)));
3103 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3105 return NT_STATUS_NO_MEMORY;
3108 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3110 if (!(pwd = samu_new(p->mem_ctx))) {
3111 return NT_STATUS_NO_MEMORY;
3115 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3119 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3121 return NT_STATUS_NO_SUCH_USER;
3124 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3126 samr_clear_sam_passwd(pwd);
3128 switch (r->in.level) {
3130 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3133 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3136 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3139 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3142 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3145 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3148 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3151 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3154 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3157 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3160 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3163 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3166 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3169 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3172 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3175 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3178 /* level 18 is special */
3179 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3183 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3186 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3189 status = NT_STATUS_INVALID_INFO_CLASS;
3193 if (!NT_STATUS_IS_OK(status)) {
3197 *r->out.info = user_info;
3202 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3207 /****************************************************************
3208 ****************************************************************/
3210 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3211 struct samr_QueryUserInfo2 *r)
3213 struct samr_QueryUserInfo u;
3215 u.in.user_handle = r->in.user_handle;
3216 u.in.level = r->in.level;
3217 u.out.info = r->out.info;
3219 return _samr_QueryUserInfo(p, &u);
3222 /*******************************************************************
3223 _samr_GetGroupsForUser
3224 ********************************************************************/
3226 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3227 struct samr_GetGroupsForUser *r)
3229 struct samr_user_info *uinfo;
3230 struct samu *sam_pass=NULL;
3231 struct dom_sid *sids;
3232 struct samr_RidWithAttribute dom_gid;
3233 struct samr_RidWithAttribute *gids = NULL;
3234 uint32 primary_group_rid;
3235 uint32_t num_groups = 0;
3237 uint32_t i, num_gids;
3240 bool success = False;
3242 struct samr_RidWithAttributeArray *rids = NULL;
3245 * from the SID in the request:
3246 * we should send back the list of DOMAIN GROUPS
3247 * the user is a member of
3249 * and only the DOMAIN GROUPS
3250 * no ALIASES !!! neither aliases of the domain
3251 * nor aliases of the builtin SID
3256 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3258 uinfo = policy_handle_find(p, r->in.user_handle,
3259 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3260 struct samr_user_info, &result);
3261 if (!NT_STATUS_IS_OK(result)) {
3265 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3267 return NT_STATUS_NO_MEMORY;
3270 if (!sid_check_is_in_our_domain(&uinfo->sid))
3271 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3273 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3274 return NT_STATUS_NO_MEMORY;
3278 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3282 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3283 sid_string_dbg(&uinfo->sid)));
3284 return NT_STATUS_NO_SUCH_USER;
3289 /* make both calls inside the root block */
3291 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3292 &sids, &unix_gids, &num_groups);
3293 if ( NT_STATUS_IS_OK(result) ) {
3294 success = sid_peek_check_rid(get_global_sam_sid(),
3295 pdb_get_group_sid(sam_pass),
3296 &primary_group_rid);
3300 if (!NT_STATUS_IS_OK(result)) {
3301 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3302 sid_string_dbg(&uinfo->sid)));
3307 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3308 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3309 pdb_get_username(sam_pass)));
3310 TALLOC_FREE(sam_pass);
3311 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3317 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3319 dom_gid.rid = primary_group_rid;
3320 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3322 for (i=0; i<num_groups; i++) {
3324 if (!sid_peek_check_rid(get_global_sam_sid(),
3325 &(sids[i]), &dom_gid.rid)) {
3326 DEBUG(10, ("Found sid %s not in our domain\n",
3327 sid_string_dbg(&sids[i])));
3331 if (dom_gid.rid == primary_group_rid) {
3332 /* We added the primary group directly from the
3333 * sam_account. The other SIDs are unique from
3334 * enum_group_memberships */
3338 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3341 rids->count = num_gids;
3344 *r->out.rids = rids;
3346 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3351 /*******************************************************************
3352 ********************************************************************/
3354 static uint32_t samr_get_server_role(void)
3356 uint32_t role = ROLE_DOMAIN_PDC;
3358 if (lp_server_role() == ROLE_DOMAIN_BDC) {
3359 role = ROLE_DOMAIN_BDC;
3365 /*******************************************************************
3366 ********************************************************************/
3368 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3369 struct samr_DomInfo1 *r)
3371 uint32_t account_policy_temp;
3372 time_t u_expire, u_min_age;
3378 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3379 r->min_password_length = account_policy_temp;
3381 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3382 r->password_history_length = account_policy_temp;
3384 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3385 &r->password_properties);
3387 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3388 u_expire = account_policy_temp;
3390 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3391 u_min_age = account_policy_temp;
3397 unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3398 unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3400 if (lp_check_password_script() && *lp_check_password_script()) {
3401 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3404 return NT_STATUS_OK;
3407 /*******************************************************************
3408 ********************************************************************/
3410 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3411 struct samr_DomGeneralInformation *r,
3412 struct samr_domain_info *dinfo)
3421 r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3422 r->num_groups = count_sam_groups(dinfo->disp_info);
3423 r->num_aliases = count_sam_aliases(dinfo->disp_info);
3425 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3427 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3429 if (!pdb_get_seq_num(&seq_num)) {
3430 seq_num = time(NULL);
3437 r->oem_information.string = lp_serverstring();
3438 r->domain_name.string = lp_workgroup();
3439 r->primary.string = global_myname();
3440 r->sequence_num = seq_num;
3441 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3442 r->role = (enum samr_Role) samr_get_server_role();
3445 return NT_STATUS_OK;
3448 /*******************************************************************
3449 ********************************************************************/
3451 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3452 struct samr_DomInfo3 *r)
3462 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3463 u_logout = (time_t)ul;
3470 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3472 return NT_STATUS_OK;
3475 /*******************************************************************
3476 ********************************************************************/
3478 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3479 struct samr_DomOEMInformation *r)
3481 r->oem_information.string = lp_serverstring();
3483 return NT_STATUS_OK;
3486 /*******************************************************************
3487 ********************************************************************/
3489 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3490 struct samr_DomInfo5 *r)
3492 r->domain_name.string = get_global_sam_name();
3494 return NT_STATUS_OK;
3497 /*******************************************************************
3498 ********************************************************************/
3500 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3501 struct samr_DomInfo6 *r)
3503 /* NT returns its own name when a PDC. win2k and later
3504 * only the name of the PDC if itself is a BDC (samba4
3506 r->primary.string = global_myname();
3508 return NT_STATUS_OK;
3511 /*******************************************************************
3512 ********************************************************************/
3514 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3515 struct samr_DomInfo7 *r)
3517 r->role = (enum samr_Role) samr_get_server_role();
3519 return NT_STATUS_OK;
3522 /*******************************************************************
3523 ********************************************************************/
3525 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3526 struct samr_DomInfo8 *r)
3534 if (!pdb_get_seq_num(&seq_num)) {
3535 seq_num = time(NULL);
3542 r->sequence_num = seq_num;
3543 r->domain_create_time = 0;
3545 return NT_STATUS_OK;
3548 /*******************************************************************
3549 ********************************************************************/
3551 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3552 struct samr_DomInfo9 *r)
3554 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3556 return NT_STATUS_OK;
3559 /*******************************************************************
3560 ********************************************************************/
3562 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3563 struct samr_DomGeneralInformation2 *r,
3564 struct samr_domain_info *dinfo)
3567 uint32_t account_policy_temp;
3568 time_t u_lock_duration, u_reset_time;
3570 status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3571 if (!NT_STATUS_IS_OK(status)) {
3579 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3580 u_lock_duration = account_policy_temp;
3581 if (u_lock_duration != -1) {
3582 u_lock_duration *= 60;
3585 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3586 u_reset_time = account_policy_temp * 60;
3588 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3589 r->lockout_threshold = account_policy_temp;
3595 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3596 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3598 return NT_STATUS_OK;
3601 /*******************************************************************
3602 ********************************************************************/
3604 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3605 struct samr_DomInfo12 *r)
3607 uint32_t account_policy_temp;
3608 time_t u_lock_duration, u_reset_time;
3614 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3615 u_lock_duration = account_policy_temp;
3616 if (u_lock_duration != -1) {
3617 u_lock_duration *= 60;
3620 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3621 u_reset_time = account_policy_temp * 60;
3623 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3624 r->lockout_threshold = account_policy_temp;
3630 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3631 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3633 return NT_STATUS_OK;
3636 /*******************************************************************
3637 ********************************************************************/
3639 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3640 struct samr_DomInfo13 *r)
3648 if (!pdb_get_seq_num(&seq_num)) {
3649 seq_num = time(NULL);
3656 r->sequence_num = seq_num;
3657 r->domain_create_time = 0;
3658 r->modified_count_at_last_promotion = 0;
3660 return NT_STATUS_OK;
3663 /*******************************************************************
3664 _samr_QueryDomainInfo
3665 ********************************************************************/
3667 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3668 struct samr_QueryDomainInfo *r)
3670 NTSTATUS status = NT_STATUS_OK;
3671 struct samr_domain_info *dinfo;
3672 union samr_DomainInfo *dom_info;
3674 uint32_t acc_required;
3676 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3678 switch (r->in.level) {
3679 case 1: /* DomainPasswordInformation */
3680 case 12: /* DomainLockoutInformation */
3681 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3682 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3684 case 11: /* DomainGeneralInformation2 */
3685 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3686 * DOMAIN_READ_OTHER_PARAMETERS */
3687 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3688 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3690 case 2: /* DomainGeneralInformation */
3691 case 3: /* DomainLogoffInformation */
3692 case 4: /* DomainOemInformation */
3693 case 5: /* DomainReplicationInformation */
3694 case 6: /* DomainReplicationInformation */
3695 case 7: /* DomainServerRoleInformation */
3696 case 8: /* DomainModifiedInformation */
3697 case 9: /* DomainStateInformation */
3698 case 10: /* DomainUasInformation */
3699 case 13: /* DomainModifiedInformation2 */
3700 /* DOMAIN_READ_OTHER_PARAMETERS */
3701 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3704 return NT_STATUS_INVALID_INFO_CLASS;
3707 dinfo = policy_handle_find(p, r->in.domain_handle,
3709 struct samr_domain_info, &status);
3710 if (!NT_STATUS_IS_OK(status)) {
3714 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3716 return NT_STATUS_NO_MEMORY;
3719 switch (r->in.level) {
3721 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3724 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3727 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3730 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3733 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3736 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3739 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3742 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3745 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3748 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3751 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3754 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3757 return NT_STATUS_INVALID_INFO_CLASS;
3760 if (!NT_STATUS_IS_OK(status)) {
3764 *r->out.info = dom_info;
3766 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3771 /* W2k3 seems to use the same check for all 3 objects that can be created via
3772 * SAMR, if you try to create for example "Dialup" as an alias it says
3773 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3776 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3778 enum lsa_SidType type;
3781 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3784 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3785 * whether the name already exists */
3786 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3787 NULL, NULL, NULL, &type);
3791 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3792 return NT_STATUS_OK;
3795 DEBUG(5, ("trying to create %s, exists as %s\n",
3796 new_name, sid_type_lookup(type)));
3798 if (type == SID_NAME_DOM_GRP) {
3799 return NT_STATUS_GROUP_EXISTS;
3801 if (type == SID_NAME_ALIAS) {
3802 return NT_STATUS_ALIAS_EXISTS;
3805 /* Yes, the default is NT_STATUS_USER_EXISTS */
3806 return NT_STATUS_USER_EXISTS;
3809 /*******************************************************************
3811 ********************************************************************/
3813 NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3814 struct samr_CreateUser2 *r)
3816 const char *account = NULL;
3818 uint32_t acb_info = r->in.acct_flags;
3819 struct samr_domain_info *dinfo;
3820 struct samr_user_info *uinfo;
3823 struct security_descriptor *psd;
3825 /* check this, when giving away 'add computer to domain' privs */
3826 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3827 bool can_add_account = False;
3829 /* Which privilege is needed to override the ACL? */
3830 enum sec_privilege needed_priv = SEC_PRIV_INVALID;
3832 dinfo = policy_handle_find(p, r->in.domain_handle,
3833 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3834 struct samr_domain_info, &nt_status);
3835 if (!NT_STATUS_IS_OK(nt_status)) {
3839 if (sid_check_is_builtin(&dinfo->sid)) {
3840 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3841 return NT_STATUS_ACCESS_DENIED;
3844 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3845 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3846 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3847 this parameter is not an account type */
3848 return NT_STATUS_INVALID_PARAMETER;
3851 account = r->in.account_name->string;
3852 if (account == NULL) {
3853 return NT_STATUS_NO_MEMORY;
3856 nt_status = can_create(p->mem_ctx, account);
3857 if (!NT_STATUS_IS_OK(nt_status)) {
3861 /* determine which user right we need to check based on the acb_info */
3863 if (geteuid() == sec_initial_uid()) {
3864 can_add_account = true;
3865 } else if (acb_info & ACB_WSTRUST) {
3866 needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
3867 can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_MACHINE_ACCOUNT);
3868 } else if (acb_info & ACB_NORMAL &&
3869 (account[strlen(account)-1] != '$')) {
3870 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3871 account for domain trusts and changes the ACB flags later */
3872 needed_priv = SEC_PRIV_ADD_USERS;
3873 can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS);
3874 } else if (lp_enable_privileges()) {
3875 /* implicit assumption of a BDC or domain trust account here
3876 * (we already check the flags earlier) */
3877 /* only Domain Admins can add a BDC or domain trust */
3878 can_add_account = nt_token_check_domain_rid(
3879 p->session_info->security_token,
3880 DOMAIN_RID_ADMINS );
3883 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3884 uidtoname(p->session_info->utok.uid),
3885 can_add_account ? "True":"False" ));
3887 if (!can_add_account) {
3888 return NT_STATUS_ACCESS_DENIED;
3891 /********** BEGIN Admin BLOCK **********/
3894 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3898 /********** END Admin BLOCK **********/
3900 /* now check for failure */
3902 if ( !NT_STATUS_IS_OK(nt_status) )
3905 /* Get the user's SID */
3907 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3909 map_max_allowed_access(p->session_info->security_token,
3910 &p->session_info->utok,
3913 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3914 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3915 se_map_generic(&des_access, &usr_generic_mapping);
3918 * JRA - TESTME. We just created this user so we
3919 * had rights to create them. Do we need to check
3920 * any further access on this object ? Can't we
3921 * just assume we have all the rights we need ?
3924 nt_status = access_check_object(psd, p->session_info->security_token,
3925 needed_priv, SEC_PRIV_INVALID,
3926 GENERIC_RIGHTS_USER_WRITE, des_access,
3927 &acc_granted, "_samr_CreateUser2");
3929 if ( !NT_STATUS_IS_OK(nt_status) ) {
3933 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3934 struct samr_user_info, &nt_status);
3935 if (!NT_STATUS_IS_OK(nt_status)) {
3940 /* After a "set" ensure we have no cached display info. */
3941 force_flush_samr_cache(&sid);
3943 *r->out.access_granted = acc_granted;
3945 return NT_STATUS_OK;
3948 /****************************************************************
3949 ****************************************************************/
3951 NTSTATUS _samr_CreateUser(struct pipes_struct *p,
3952 struct samr_CreateUser *r)
3954 struct samr_CreateUser2 c;
3955 uint32_t access_granted;
3957 c.in.domain_handle = r->in.domain_handle;
3958 c.in.account_name = r->in.account_name;
3959 c.in.acct_flags = ACB_NORMAL;
3960 c.in.access_mask = r->in.access_mask;
3961 c.out.user_handle = r->out.user_handle;
3962 c.out.access_granted = &access_granted;
3963 c.out.rid = r->out.rid;
3965 return _samr_CreateUser2(p, &c);
3968 /*******************************************************************
3970 ********************************************************************/
3972 NTSTATUS _samr_Connect(struct pipes_struct *p,
3973 struct samr_Connect *r)
3975 struct samr_connect_info *info;
3976 uint32_t acc_granted;
3977 struct policy_handle hnd;
3978 uint32 des_access = r->in.access_mask;
3983 if (!pipe_access_check(p)) {
3984 DEBUG(3, ("access denied to _samr_Connect\n"));
3985 return NT_STATUS_ACCESS_DENIED;
3988 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3989 was observed from a win98 client trying to enumerate users (when configured
3990 user level access control on shares) --jerry */
3992 map_max_allowed_access(p->session_info->security_token,
3993 &p->session_info->utok,
3996 se_map_generic( &des_access, &sam_generic_mapping );
3998 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3999 |SAMR_ACCESS_LOOKUP_DOMAIN);
4001 /* set up the SAMR connect_anon response */
4003 info = policy_handle_create(p, &hnd, acc_granted,
4004 struct samr_connect_info,
4006 if (!NT_STATUS_IS_OK(status)) {
4010 *r->out.connect_handle = hnd;
4011 return NT_STATUS_OK;
4014 /*******************************************************************
4016 ********************************************************************/
4018 NTSTATUS _samr_Connect2(struct pipes_struct *p,
4019 struct samr_Connect2 *r)
4021 struct samr_connect_info *info = NULL;
4022 struct policy_handle hnd;
4023 struct security_descriptor *psd = NULL;
4025 uint32 des_access = r->in.access_mask;
4028 const char *fn = "_samr_Connect2";
4031 case NDR_SAMR_CONNECT2:
4032 fn = "_samr_Connect2";
4034 case NDR_SAMR_CONNECT3:
4035 fn = "_samr_Connect3";
4037 case NDR_SAMR_CONNECT4:
4038 fn = "_samr_Connect4";
4040 case NDR_SAMR_CONNECT5:
4041 fn = "_samr_Connect5";
4045 DEBUG(5,("%s: %d\n", fn, __LINE__));
4049 if (!pipe_access_check(p)) {
4050 DEBUG(3, ("access denied to %s\n", fn));
4051 return NT_STATUS_ACCESS_DENIED;
4054 map_max_allowed_access(p->session_info->security_token,
4055 &p->session_info->utok,
4058 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
4059 se_map_generic(&des_access, &sam_generic_mapping);
4061 nt_status = access_check_object(psd, p->session_info->security_token,
4062 SEC_PRIV_INVALID, SEC_PRIV_INVALID,
4063 0, des_access, &acc_granted, fn);
4065 if ( !NT_STATUS_IS_OK(nt_status) )
4068 info = policy_handle_create(p, &hnd, acc_granted,
4069 struct samr_connect_info, &nt_status);
4070 if (!NT_STATUS_IS_OK(nt_status)) {
4074 DEBUG(5,("%s: %d\n", fn, __LINE__));
4076 *r->out.connect_handle = hnd;
4077 return NT_STATUS_OK;
4080 /****************************************************************
4082 ****************************************************************/
4084 NTSTATUS _samr_Connect3(struct pipes_struct *p,
4085 struct samr_Connect3 *r)
4087 struct samr_Connect2 c;
4089 c.in.system_name = r->in.system_name;
4090 c.in.access_mask = r->in.access_mask;
4091 c.out.connect_handle = r->out.connect_handle;
4093 return _samr_Connect2(p, &c);
4096 /*******************************************************************
4098 ********************************************************************/
4100 NTSTATUS _samr_Connect4(struct pipes_struct *p,
4101 struct samr_Connect4 *r)
4103 struct samr_Connect2 c;
4105 c.in.system_name = r->in.system_name;
4106 c.in.access_mask = r->in.access_mask;
4107 c.out.connect_handle = r->out.connect_handle;
4109 return _samr_Connect2(p, &c);
4112 /*******************************************************************
4114 ********************************************************************/
4116 NTSTATUS _samr_Connect5(struct pipes_struct *p,
4117 struct samr_Connect5 *r)
4120 struct samr_Connect2 c;
4121 struct samr_ConnectInfo1 info1;
4123 info1.client_version = SAMR_CONNECT_AFTER_W2K;
4126 c.in.system_name = r->in.system_name;
4127 c.in.access_mask = r->in.access_mask;
4128 c.out.connect_handle = r->out.connect_handle;
4130 *r->out.level_out = 1;
4132 status = _samr_Connect2(p, &c);
4133 if (!NT_STATUS_IS_OK(status)) {
4137 r->out.info_out->info1 = info1;
4139 return NT_STATUS_OK;
4142 /**********************************************************************
4144 **********************************************************************/
4146 NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
4147 struct samr_LookupDomain *r)
4150 struct samr_connect_info *info;
4151 const char *domain_name;
4152 struct dom_sid *sid = NULL;
4154 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4155 Reverted that change so we will work with RAS servers again */
4157 info = policy_handle_find(p, r->in.connect_handle,
4158 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4159 struct samr_connect_info,
4161 if (!NT_STATUS_IS_OK(status)) {
4165 domain_name = r->in.domain_name->string;
4167 return NT_STATUS_INVALID_PARAMETER;
4170 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
4172 return NT_STATUS_NO_MEMORY;
4175 if (strequal(domain_name, builtin_domain_name())) {
4176 sid_copy(sid, &global_sid_Builtin);
4178 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4179 status = NT_STATUS_NO_SUCH_DOMAIN;
4183 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4184 sid_string_dbg(sid)));
4191 /**********************************************************************
4193 **********************************************************************/
4195 NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4196 struct samr_EnumDomains *r)
4199 struct samr_connect_info *info;
4200 uint32_t num_entries = 2;
4201 struct samr_SamEntry *entry_array = NULL;
4202 struct samr_SamArray *sam;
4204 info = policy_handle_find(p, r->in.connect_handle,
4205 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4206 struct samr_connect_info, &status);
4207 if (!NT_STATUS_IS_OK(status)) {
4211 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4213 return NT_STATUS_NO_MEMORY;
4216 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4217 struct samr_SamEntry,
4220 return NT_STATUS_NO_MEMORY;
4223 entry_array[0].idx = 0;
4224 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4226 entry_array[1].idx = 1;
4227 init_lsa_String(&entry_array[1].name, "Builtin");
4229 sam->count = num_entries;
4230 sam->entries = entry_array;
4233 *r->out.num_entries = num_entries;
4238 /*******************************************************************
4240 ********************************************************************/
4242 NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4243 struct samr_OpenAlias *r)
4246 uint32 alias_rid = r->in.rid;
4247 struct samr_alias_info *ainfo;
4248 struct samr_domain_info *dinfo;
4249 struct security_descriptor *psd = NULL;
4251 uint32 des_access = r->in.access_mask;
4255 dinfo = policy_handle_find(p, r->in.domain_handle,
4256 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4257 struct samr_domain_info, &status);
4258 if (!NT_STATUS_IS_OK(status)) {
4262 /* append the alias' RID to it */
4264 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4265 return NT_STATUS_NO_SUCH_ALIAS;
4267 /*check if access can be granted as requested by client. */
4269 map_max_allowed_access(p->session_info->security_token,
4270 &p->session_info->utok,
4273 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4274 se_map_generic(&des_access,&ali_generic_mapping);
4276 status = access_check_object(psd, p->session_info->security_token,
4277 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
4278 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4279 des_access, &acc_granted, "_samr_OpenAlias");
4281 if ( !NT_STATUS_IS_OK(status) )
4285 /* Check we actually have the requested alias */
4286 enum lsa_SidType type;
4291 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4294 if (!result || (type != SID_NAME_ALIAS)) {
4295 return NT_STATUS_NO_SUCH_ALIAS;
4298 /* make sure there is a mapping */
4300 if ( !sid_to_gid( &sid, &gid ) ) {
4301 return NT_STATUS_NO_SUCH_ALIAS;
4306 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4307 struct samr_alias_info, &status);
4308 if (!NT_STATUS_IS_OK(status)) {
4313 return NT_STATUS_OK;
4316 /*******************************************************************
4318 ********************************************************************/
4320 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4321 struct samr_UserInfo2 *id2,
4325 DEBUG(5,("set_user_info_2: NULL id2\n"));
4326 return NT_STATUS_ACCESS_DENIED;
4329 copy_id2_to_sam_passwd(pwd, id2);
4331 return pdb_update_sam_account(pwd);
4334 /*******************************************************************
4336 ********************************************************************/
4338 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4339 struct samr_UserInfo4 *id4,
4343 DEBUG(5,("set_user_info_2: NULL id4\n"));
4344 return NT_STATUS_ACCESS_DENIED;
4347 copy_id4_to_sam_passwd(pwd, id4);
4349 return pdb_update_sam_account(pwd);
4352 /*******************************************************************
4354 ********************************************************************/
4356 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4357 struct samr_UserInfo6 *id6,
4361 DEBUG(5,("set_user_info_6: NULL id6\n"));
4362 return NT_STATUS_ACCESS_DENIED;
4365 copy_id6_to_sam_passwd(pwd, id6);
4367 return pdb_update_sam_account(pwd);
4370 /*******************************************************************
4372 ********************************************************************/
4374 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4375 struct samr_UserInfo7 *id7,
4381 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4382 return NT_STATUS_ACCESS_DENIED;
4385 if (!id7->account_name.string) {
4386 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4387 return NT_STATUS_ACCESS_DENIED;
4390 /* check to see if the new username already exists. Note: we can't
4391 reliably lock all backends, so there is potentially the
4392 possibility that a user can be created in between this check and
4393 the rename. The rename should fail, but may not get the
4394 exact same failure status code. I think this is small enough
4395 of a window for this type of operation and the results are
4396 simply that the rename fails with a slightly different status
4397 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4399 rc = can_create(mem_ctx, id7->account_name.string);
4401 /* when there is nothing to change, we're done here */
4402 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4403 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4404 return NT_STATUS_OK;
4406 if (!NT_STATUS_IS_OK(rc)) {
4410 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4415 /*******************************************************************
4417 ********************************************************************/
4419 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4420 struct samr_UserInfo8 *id8,
4424 DEBUG(5,("set_user_info_8: NULL id8\n"));
4425 return NT_STATUS_ACCESS_DENIED;
4428 copy_id8_to_sam_passwd(pwd, id8);
4430 return pdb_update_sam_account(pwd);
4433 /*******************************************************************
4435 ********************************************************************/
4437 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4438 struct samr_UserInfo10 *id10,
4442 DEBUG(5,("set_user_info_8: NULL id10\n"));
4443 return NT_STATUS_ACCESS_DENIED;
4446 copy_id10_to_sam_passwd(pwd, id10);
4448 return pdb_update_sam_account(pwd);
4451 /*******************************************************************
4453 ********************************************************************/
4455 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4456 struct samr_UserInfo11 *id11,
4460 DEBUG(5,("set_user_info_11: NULL id11\n"));
4461 return NT_STATUS_ACCESS_DENIED;
4464 copy_id11_to_sam_passwd(pwd, id11);
4466 return pdb_update_sam_account(pwd);
4469 /*******************************************************************
4471 ********************************************************************/
4473 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4474 struct samr_UserInfo12 *id12,
4478 DEBUG(5,("set_user_info_12: NULL id12\n"));
4479 return NT_STATUS_ACCESS_DENIED;
4482 copy_id12_to_sam_passwd(pwd, id12);
4484 return pdb_update_sam_account(pwd);
4487 /*******************************************************************
4489 ********************************************************************/
4491 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4492 struct samr_UserInfo13 *id13,
4496 DEBUG(5,("set_user_info_13: NULL id13\n"));
4497 return NT_STATUS_ACCESS_DENIED;
4500 copy_id13_to_sam_passwd(pwd, id13);
4502 return pdb_update_sam_account(pwd);
4505 /*******************************************************************
4507 ********************************************************************/
4509 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4510 struct samr_UserInfo14 *id14,
4514 DEBUG(5,("set_user_info_14: NULL id14\n"));
4515 return NT_STATUS_ACCESS_DENIED;
4518 copy_id14_to_sam_passwd(pwd, id14);
4520 return pdb_update_sam_account(pwd);
4523 /*******************************************************************
4525 ********************************************************************/
4527 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4528 struct samr_UserInfo16 *id16,
4532 DEBUG(5,("set_user_info_16: NULL id16\n"));
4533 return NT_STATUS_ACCESS_DENIED;
4536 copy_id16_to_sam_passwd(pwd, id16);
4538 return pdb_update_sam_account(pwd);
4541 /*******************************************************************
4543 ********************************************************************/
4545 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4546 struct samr_UserInfo17 *id17,
4550 DEBUG(5,("set_user_info_17: NULL id17\n"));
4551 return NT_STATUS_ACCESS_DENIED;
4554 copy_id17_to_sam_passwd(pwd, id17);
4556 return pdb_update_sam_account(pwd);
4559 /*******************************************************************
4561 ********************************************************************/
4563 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4564 TALLOC_CTX *mem_ctx,
4565 DATA_BLOB *session_key,
4569 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4570 return NT_STATUS_INVALID_PARAMETER;
4573 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4574 if (!session_key->length) {
4575 return NT_STATUS_NO_USER_SESSION_KEY;
4579 if (id18->nt_pwd_active) {
4583 in = data_blob_const(id18->nt_pwd.hash, 16);
4584 out = data_blob_talloc_zero(mem_ctx, 16);
4586 sess_crypt_blob(&out, &in, session_key, false);
4588 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4589 return NT_STATUS_ACCESS_DENIED;
4592 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4595 if (id18->lm_pwd_active) {
4599 in = data_blob_const(id18->lm_pwd.hash, 16);
4600 out = data_blob_talloc_zero(mem_ctx, 16);
4602 sess_crypt_blob(&out, &in, session_key, false);
4604 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4605 return NT_STATUS_ACCESS_DENIED;
4608 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4611 copy_id18_to_sam_passwd(pwd, id18);
4613 return pdb_update_sam_account(pwd);
4616 /*******************************************************************
4618 ********************************************************************/
4620 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4621 struct samr_UserInfo20 *id20,
4625 DEBUG(5,("set_user_info_20: NULL id20\n"));
4626 return NT_STATUS_ACCESS_DENIED;
4629 copy_id20_to_sam_passwd(pwd, id20);
4631 return pdb_update_sam_account(pwd);
4634 /*******************************************************************
4636 ********************************************************************/
4638 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4639 TALLOC_CTX *mem_ctx,
4640 DATA_BLOB *session_key,
4646 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4647 return NT_STATUS_INVALID_PARAMETER;
4650 if (id21->fields_present == 0) {
4651 return NT_STATUS_INVALID_PARAMETER;
4654 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4655 return NT_STATUS_ACCESS_DENIED;
4658 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4659 if (id21->nt_password_set) {
4662 if ((id21->nt_owf_password.length != 16) ||
4663 (id21->nt_owf_password.size != 16)) {
4664 return NT_STATUS_INVALID_PARAMETER;
4667 if (!session_key->length) {
4668 return NT_STATUS_NO_USER_SESSION_KEY;
4671 in = data_blob_const(id21->nt_owf_password.array, 16);
4672 out = data_blob_talloc_zero(mem_ctx, 16);
4674 sess_crypt_blob(&out, &in, session_key, false);
4676 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4677 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4681 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4682 if (id21->lm_password_set) {
4685 if ((id21->lm_owf_password.length != 16) ||
4686 (id21->lm_owf_password.size != 16)) {
4687 return NT_STATUS_INVALID_PARAMETER;
4690 if (!session_key->length) {
4691 return NT_STATUS_NO_USER_SESSION_KEY;
4694 in = data_blob_const(id21->lm_owf_password.array, 16);
4695 out = data_blob_talloc_zero(mem_ctx, 16);
4697 sess_crypt_blob(&out, &in, session_key, false);
4699 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4700 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4704 /* we need to separately check for an account rename first */
4706 if (id21->account_name.string &&
4707 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4710 /* check to see if the new username already exists. Note: we can't
4711 reliably lock all backends, so there is potentially the
4712 possibility that a user can be created in between this check and
4713 the rename. The rename should fail, but may not get the
4714 exact same failure status code. I think this is small enough
4715 of a window for this type of operation and the results are
4716 simply that the rename fails with a slightly different status
4717 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4719 status = can_create(mem_ctx, id21->account_name.string);
4720 if (!NT_STATUS_IS_OK(status)) {
4724 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4726 if (!NT_STATUS_IS_OK(status)) {
4727 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4728 nt_errstr(status)));
4732 /* set the new username so that later
4733 functions can work on the new account */
4734 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4737 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4740 * The funny part about the previous two calls is
4741 * that pwd still has the password hashes from the
4742 * passdb entry. These have not been updated from
4743 * id21. I don't know if they need to be set. --jerry
4746 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4747 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4748 if ( !NT_STATUS_IS_OK(status) ) {
4753 /* Don't worry about writing out the user account since the
4754 primary group SID is generated solely from the user's Unix
4757 /* write the change out */
4758 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4762 return NT_STATUS_OK;
4765 /*******************************************************************
4767 ********************************************************************/
4769 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4770 struct samr_UserInfo23 *id23,
4774 char *plaintext_buf = NULL;
4780 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4781 return NT_STATUS_INVALID_PARAMETER;
4784 if (id23->info.fields_present == 0) {
4785 return NT_STATUS_INVALID_PARAMETER;
4788 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4789 return NT_STATUS_ACCESS_DENIED;
4792 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4793 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4795 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4796 pdb_get_username(pwd)));
4798 if (!decode_pw_buffer(mem_ctx,
4799 id23->password.data,
4803 return NT_STATUS_WRONG_PASSWORD;
4806 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4807 return NT_STATUS_ACCESS_DENIED;
4811 copy_id23_to_sam_passwd(pwd, id23);
4813 acct_ctrl = pdb_get_acct_ctrl(pwd);
4815 /* if it's a trust account, don't update /etc/passwd */
4816 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4817 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4818 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4819 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4820 } else if (plaintext_buf) {
4821 /* update the UNIX password */
4822 if (lp_unix_password_sync() ) {
4823 struct passwd *passwd;
4824 if (pdb_get_username(pwd) == NULL) {
4825 DEBUG(1, ("chgpasswd: User without name???\n"));
4826 return NT_STATUS_ACCESS_DENIED;
4829 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4830 if (passwd == NULL) {
4831 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4834 if(!chgpasswd(pdb_get_username(pwd), rhost,
4835 passwd, "", plaintext_buf, True)) {
4836 return NT_STATUS_ACCESS_DENIED;
4838 TALLOC_FREE(passwd);
4842 if (plaintext_buf) {
4843 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4846 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4847 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4852 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4856 return NT_STATUS_OK;
4859 /*******************************************************************
4861 ********************************************************************/
4863 static bool set_user_info_pw(uint8 *pass, const char *rhost, struct samu *pwd)
4866 char *plaintext_buf = NULL;
4869 DEBUG(5, ("Attempting administrator password change for user %s\n",
4870 pdb_get_username(pwd)));
4872 acct_ctrl = pdb_get_acct_ctrl(pwd);
4874 if (!decode_pw_buffer(talloc_tos(),
4882 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4886 /* if it's a trust account, don't update /etc/passwd */
4887 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4888 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4889 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4890 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4892 /* update the UNIX password */
4893 if (lp_unix_password_sync()) {
4894 struct passwd *passwd;
4896 if (pdb_get_username(pwd) == NULL) {
4897 DEBUG(1, ("chgpasswd: User without name???\n"));
4901 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4902 if (passwd == NULL) {
4903 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4906 if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
4907 "", plaintext_buf, True)) {
4910 TALLOC_FREE(passwd);
4914 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4916 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4921 /*******************************************************************
4923 ********************************************************************/
4925 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4927 struct samr_UserInfo24 *id24,
4933 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4934 return NT_STATUS_INVALID_PARAMETER;
4937 if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
4938 return NT_STATUS_WRONG_PASSWORD;
4941 copy_id24_to_sam_passwd(pwd, id24);
4943 status = pdb_update_sam_account(pwd);
4944 if (!NT_STATUS_IS_OK(status)) {
4948 return NT_STATUS_OK;
4951 /*******************************************************************
4953 ********************************************************************/
4955 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4957 struct samr_UserInfo25 *id25,
4963 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4964 return NT_STATUS_INVALID_PARAMETER;
4967 if (id25->info.fields_present == 0) {
4968 return NT_STATUS_INVALID_PARAMETER;
4971 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4972 return NT_STATUS_ACCESS_DENIED;
4975 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4976 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4978 if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
4979 return NT_STATUS_WRONG_PASSWORD;
4983 copy_id25_to_sam_passwd(pwd, id25);
4985 /* write the change out */
4986 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4991 * We need to "pdb_update_sam_account" before the unix primary group
4992 * is set, because the idealx scripts would also change the
4993 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4994 * the delete explicit / add explicit, which would then fail to find
4995 * the previous primaryGroupSid value.
4998 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4999 status = pdb_set_unix_primary_group(mem_ctx, pwd);
5000 if ( !NT_STATUS_IS_OK(status) ) {
5005 return NT_STATUS_OK;
5008 /*******************************************************************
5010 ********************************************************************/
5012 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
5014 struct samr_UserInfo26 *id26,
5020 DEBUG(5, ("set_user_info_26: NULL id26\n"));
5021 return NT_STATUS_INVALID_PARAMETER;
5024 if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
5025 return NT_STATUS_WRONG_PASSWORD;
5028 copy_id26_to_sam_passwd(pwd, id26);
5030 status = pdb_update_sam_account(pwd);
5031 if (!NT_STATUS_IS_OK(status)) {
5035 return NT_STATUS_OK;
5038 /*************************************************************
5039 **************************************************************/
5041 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
5043 uint32_t acc_required = 0;
5045 /* USER_ALL_USERNAME */
5046 if (fields & SAMR_FIELD_ACCOUNT_NAME)
5047 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5048 /* USER_ALL_FULLNAME */
5049 if (fields & SAMR_FIELD_FULL_NAME)
5050 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5051 /* USER_ALL_PRIMARYGROUPID */
5052 if (fields & SAMR_FIELD_PRIMARY_GID)
5053 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5054 /* USER_ALL_HOMEDIRECTORY */
5055 if (fields & SAMR_FIELD_HOME_DIRECTORY)
5056 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5057 /* USER_ALL_HOMEDIRECTORYDRIVE */
5058 if (fields & SAMR_FIELD_HOME_DRIVE)
5059 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5060 /* USER_ALL_SCRIPTPATH */
5061 if (fields & SAMR_FIELD_LOGON_SCRIPT)
5062 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5063 /* USER_ALL_PROFILEPATH */
5064 if (fields & SAMR_FIELD_PROFILE_PATH)
5065 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5066 /* USER_ALL_ADMINCOMMENT */
5067 if (fields & SAMR_FIELD_COMMENT)
5068 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5069 /* USER_ALL_WORKSTATIONS */
5070 if (fields & SAMR_FIELD_WORKSTATIONS)
5071 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5072 /* USER_ALL_LOGONHOURS */
5073 if (fields & SAMR_FIELD_LOGON_HOURS)
5074 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5075 /* USER_ALL_ACCOUNTEXPIRES */
5076 if (fields & SAMR_FIELD_ACCT_EXPIRY)
5077 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5078 /* USER_ALL_USERACCOUNTCONTROL */
5079 if (fields & SAMR_FIELD_ACCT_FLAGS)
5080 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5081 /* USER_ALL_PARAMETERS */
5082 if (fields & SAMR_FIELD_PARAMETERS)
5083 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5084 /* USER_ALL_USERCOMMENT */
5085 if (fields & SAMR_FIELD_COMMENT)
5086 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5087 /* USER_ALL_COUNTRYCODE */
5088 if (fields & SAMR_FIELD_COUNTRY_CODE)
5089 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5090 /* USER_ALL_CODEPAGE */
5091 if (fields & SAMR_FIELD_CODE_PAGE)
5092 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5093 /* USER_ALL_NTPASSWORDPRESENT */
5094 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
5095 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5096 /* USER_ALL_LMPASSWORDPRESENT */
5097 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
5098 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5099 /* USER_ALL_PASSWORDEXPIRED */
5100 if (fields & SAMR_FIELD_EXPIRED_FLAG)
5101 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5103 return acc_required;
5106 /*******************************************************************
5108 ********************************************************************/
5110 NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
5111 struct samr_SetUserInfo *r)
5113 struct samr_user_info *uinfo;
5115 struct samu *pwd = NULL;
5116 union samr_UserInfo *info = r->in.info;
5117 uint32_t acc_required = 0;
5118 uint32_t fields = 0;
5121 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
5123 /* This is tricky. A WinXP domain join sets
5124 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5125 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
5126 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5127 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
5128 we'll use the set from the WinXP join as the basis. */
5130 switch (r->in.level) {
5131 case 2: /* UserPreferencesInformation */
5132 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5133 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5135 case 4: /* UserLogonHoursInformation */
5136 case 6: /* UserNameInformation */
5137 case 7: /* UserAccountNameInformation */
5138 case 8: /* UserFullNameInformation */
5139 case 9: /* UserPrimaryGroupInformation */
5140 case 10: /* UserHomeInformation */
5141 case 11: /* UserScriptInformation */
5142 case 12: /* UserProfileInformation */
5143 case 13: /* UserAdminCommentInformation */
5144 case 14: /* UserWorkStationsInformation */
5145 case 16: /* UserControlInformation */
5146 case 17: /* UserExpiresInformation */
5147 case 20: /* UserParametersInformation */
5148 /* USER_WRITE_ACCOUNT */
5149 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5151 case 18: /* UserInternal1Information */
5152 /* FIXME: gd, this is a guess */
5153 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5155 case 21: /* UserAllInformation */
5156 fields = info->info21.fields_present;
5157 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5159 case 23: /* UserInternal4Information */
5160 fields = info->info23.info.fields_present;
5161 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5163 case 25: /* UserInternal4InformationNew */
5164 fields = info->info25.info.fields_present;
5165 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5167 case 24: /* UserInternal5Information */
5168 case 26: /* UserInternal5InformationNew */
5169 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5172 return NT_STATUS_INVALID_INFO_CLASS;
5175 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5176 struct samr_user_info, &status);
5177 if (!NT_STATUS_IS_OK(status)) {
5181 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5182 sid_string_dbg(&uinfo->sid), r->in.level));
5185 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5186 return NT_STATUS_INVALID_INFO_CLASS;
5189 if (!(pwd = samu_new(NULL))) {
5190 return NT_STATUS_NO_MEMORY;
5194 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5199 return NT_STATUS_NO_SUCH_USER;
5202 /* ================ BEGIN Privilege BLOCK ================ */
5206 /* ok! user info levels (lots: see MSDEV help), off we go... */
5208 switch (r->in.level) {
5211 status = set_user_info_2(p->mem_ctx,
5216 status = set_user_info_4(p->mem_ctx,
5221 status = set_user_info_6(p->mem_ctx,
5226 status = set_user_info_7(p->mem_ctx,
5231 status = set_user_info_8(p->mem_ctx,
5236 status = set_user_info_10(p->mem_ctx,
5237 &info->info10, pwd);
5241 status = set_user_info_11(p->mem_ctx,
5242 &info->info11, pwd);
5246 status = set_user_info_12(p->mem_ctx,
5247 &info->info12, pwd);
5251 status = set_user_info_13(p->mem_ctx,
5252 &info->info13, pwd);
5256 status = set_user_info_14(p->mem_ctx,
5257 &info->info14, pwd);
5261 status = set_user_info_16(p->mem_ctx,
5262 &info->info16, pwd);
5266 status = set_user_info_17(p->mem_ctx,
5267 &info->info17, pwd);
5271 /* Used by AS/U JRA. */
5272 status = set_user_info_18(&info->info18,
5274 &p->session_info->user_session_key,
5279 status = set_user_info_20(p->mem_ctx,
5280 &info->info20, pwd);
5284 status = set_user_info_21(&info->info21,
5286 &p->session_info->user_session_key,
5291 if (!p->session_info->user_session_key.length) {
5292 status = NT_STATUS_NO_USER_SESSION_KEY;
5294 arcfour_crypt_blob(info->info23.password.data, 516,
5295 &p->session_info->user_session_key);
5297 dump_data(100, info->info23.password.data, 516);
5299 status = set_user_info_23(p->mem_ctx,
5306 if (!p->session_info->user_session_key.length) {
5307 status = NT_STATUS_NO_USER_SESSION_KEY;
5309 arcfour_crypt_blob(info->info24.password.data,
5311 &p->session_info->user_session_key);
5313 dump_data(100, info->info24.password.data, 516);
5315 status = set_user_info_24(p->mem_ctx,
5317 &info->info24, pwd);
5321 if (!p->session_info->user_session_key.length) {
5322 status = NT_STATUS_NO_USER_SESSION_KEY;
5324 encode_or_decode_arc4_passwd_buffer(
5325 info->info25.password.data,
5326 &p->session_info->user_session_key);
5328 dump_data(100, info->info25.password.data, 532);
5330 status = set_user_info_25(p->mem_ctx,
5332 &info->info25, pwd);
5336 if (!p->session_info->user_session_key.length) {
5337 status = NT_STATUS_NO_USER_SESSION_KEY;
5339 encode_or_decode_arc4_passwd_buffer(
5340 info->info26.password.data,
5341 &p->session_info->user_session_key);
5343 dump_data(100, info->info26.password.data, 516);
5345 status = set_user_info_26(p->mem_ctx,
5347 &info->info26, pwd);
5351 status = NT_STATUS_INVALID_INFO_CLASS;
5358 /* ================ END Privilege BLOCK ================ */
5360 if (NT_STATUS_IS_OK(status)) {
5361 force_flush_samr_cache(&uinfo->sid);
5367 /*******************************************************************
5369 ********************************************************************/
5371 NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
5372 struct samr_SetUserInfo2 *r)
5374 struct samr_SetUserInfo q;
5376 q.in.user_handle = r->in.user_handle;
5377 q.in.level = r->in.level;
5378 q.in.info = r->in.info;
5380 return _samr_SetUserInfo(p, &q);
5383 /*********************************************************************
5384 _samr_GetAliasMembership
5385 *********************************************************************/
5387 NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
5388 struct samr_GetAliasMembership *r)
5390 size_t num_alias_rids;
5392 struct samr_domain_info *dinfo;
5397 struct dom_sid *members;
5399 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5401 dinfo = policy_handle_find(p, r->in.domain_handle,
5402 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5403 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5404 struct samr_domain_info, &status);
5405 if (!NT_STATUS_IS_OK(status)) {
5409 if (!sid_check_is_domain(&dinfo->sid) &&
5410 !sid_check_is_builtin(&dinfo->sid))
5411 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5413 if (r->in.sids->num_sids) {
5414 members = TALLOC_ARRAY(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
5416 if (members == NULL)
5417 return NT_STATUS_NO_MEMORY;
5422 for (i=0; i<r->in.sids->num_sids; i++)
5423 sid_copy(&members[i], r->in.sids->sids[i].sid);
5429 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5430 r->in.sids->num_sids,
5431 &alias_rids, &num_alias_rids);
5434 if (!NT_STATUS_IS_OK(status)) {
5438 r->out.rids->count = num_alias_rids;
5439 r->out.rids->ids = alias_rids;
5441 if (r->out.rids->ids == NULL) {
5442 /* Windows domain clients don't accept a NULL ptr here */
5443 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5445 if (r->out.rids->ids == NULL) {
5446 return NT_STATUS_NO_MEMORY;
5449 return NT_STATUS_OK;
5452 /*********************************************************************
5453 _samr_GetMembersInAlias
5454 *********************************************************************/
5456 NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
5457 struct samr_GetMembersInAlias *r)
5459 struct samr_alias_info *ainfo;
5462 size_t num_sids = 0;
5463 struct lsa_SidPtr *sids = NULL;
5464 struct dom_sid *pdb_sids = NULL;
5466 ainfo = policy_handle_find(p, r->in.alias_handle,
5467 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5468 struct samr_alias_info, &status);
5469 if (!NT_STATUS_IS_OK(status)) {
5473 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5476 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5480 if (!NT_STATUS_IS_OK(status)) {
5485 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5487 TALLOC_FREE(pdb_sids);
5488 return NT_STATUS_NO_MEMORY;
5492 for (i = 0; i < num_sids; i++) {
5493 sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
5495 TALLOC_FREE(pdb_sids);
5496 return NT_STATUS_NO_MEMORY;
5500 r->out.sids->num_sids = num_sids;
5501 r->out.sids->sids = sids;
5503 TALLOC_FREE(pdb_sids);
5505 return NT_STATUS_OK;
5508 /*********************************************************************
5509 _samr_QueryGroupMember
5510 *********************************************************************/
5512 NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
5513 struct samr_QueryGroupMember *r)
5515 struct samr_group_info *ginfo;
5516 size_t i, num_members;
5522 struct samr_RidAttrArray *rids = NULL;
5524 ginfo = policy_handle_find(p, r->in.group_handle,
5525 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5526 struct samr_group_info, &status);
5527 if (!NT_STATUS_IS_OK(status)) {
5531 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidAttrArray);
5533 return NT_STATUS_NO_MEMORY;
5536 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5538 if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5539 DEBUG(3, ("sid %s is not in our domain\n",
5540 sid_string_dbg(&ginfo->sid)));
5541 return NT_STATUS_NO_SUCH_GROUP;
5544 DEBUG(10, ("lookup on Domain SID\n"));
5547 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5548 &rid, &num_members);
5551 if (!NT_STATUS_IS_OK(status))
5555 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5557 return NT_STATUS_NO_MEMORY;
5563 for (i=0; i<num_members; i++) {
5564 attr[i] = SE_GROUP_MANDATORY |
5565 SE_GROUP_ENABLED_BY_DEFAULT |
5569 rids->count = num_members;
5570 rids->attributes = attr;
5573 *r->out.rids = rids;
5575 return NT_STATUS_OK;
5578 /*********************************************************************
5579 _samr_AddAliasMember
5580 *********************************************************************/
5582 NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
5583 struct samr_AddAliasMember *r)
5585 struct samr_alias_info *ainfo;
5588 ainfo = policy_handle_find(p, r->in.alias_handle,
5589 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5590 struct samr_alias_info, &status);
5591 if (!NT_STATUS_IS_OK(status)) {
5595 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5597 /******** BEGIN SeAddUsers BLOCK *********/
5600 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5603 /******** END SeAddUsers BLOCK *********/
5605 if (NT_STATUS_IS_OK(status)) {
5606 force_flush_samr_cache(&ainfo->sid);
5612 /*********************************************************************
5613 _samr_DeleteAliasMember
5614 *********************************************************************/
5616 NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
5617 struct samr_DeleteAliasMember *r)
5619 struct samr_alias_info *ainfo;
5622 ainfo = policy_handle_find(p, r->in.alias_handle,
5623 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5624 struct samr_alias_info, &status);
5625 if (!NT_STATUS_IS_OK(status)) {
5629 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5630 sid_string_dbg(&ainfo->sid)));
5632 /******** BEGIN SeAddUsers BLOCK *********/
5635 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5638 /******** END SeAddUsers BLOCK *********/
5640 if (NT_STATUS_IS_OK(status)) {
5641 force_flush_samr_cache(&ainfo->sid);
5647 /*********************************************************************
5648 _samr_AddGroupMember
5649 *********************************************************************/
5651 NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
5652 struct samr_AddGroupMember *r)
5654 struct samr_group_info *ginfo;
5658 ginfo = policy_handle_find(p, r->in.group_handle,
5659 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5660 struct samr_group_info, &status);
5661 if (!NT_STATUS_IS_OK(status)) {
5665 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5667 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5669 return NT_STATUS_INVALID_HANDLE;
5672 /******** BEGIN SeAddUsers BLOCK *********/
5675 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5678 /******** END SeAddUsers BLOCK *********/
5680 force_flush_samr_cache(&ginfo->sid);
5685 /*********************************************************************
5686 _samr_DeleteGroupMember
5687 *********************************************************************/
5689 NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
5690 struct samr_DeleteGroupMember *r)
5693 struct samr_group_info *ginfo;
5698 * delete the group member named r->in.rid
5699 * who is a member of the sid associated with the handle
5700 * the rid is a user's rid as the group is a domain group.
5703 ginfo = policy_handle_find(p, r->in.group_handle,
5704 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5705 struct samr_group_info, &status);
5706 if (!NT_STATUS_IS_OK(status)) {
5710 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5712 return NT_STATUS_INVALID_HANDLE;
5715 /******** BEGIN SeAddUsers BLOCK *********/
5718 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5721 /******** END SeAddUsers BLOCK *********/
5723 force_flush_samr_cache(&ginfo->sid);
5728 /*********************************************************************
5730 *********************************************************************/
5732 NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
5733 struct samr_DeleteUser *r)
5735 struct samr_user_info *uinfo;
5737 struct samu *sam_pass=NULL;
5740 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5742 uinfo = policy_handle_find(p, r->in.user_handle,
5743 SEC_STD_DELETE, NULL,
5744 struct samr_user_info, &status);
5745 if (!NT_STATUS_IS_OK(status)) {
5749 if (!sid_check_is_in_our_domain(&uinfo->sid))
5750 return NT_STATUS_CANNOT_DELETE;
5752 /* check if the user exists before trying to delete */
5753 if ( !(sam_pass = samu_new( NULL )) ) {
5754 return NT_STATUS_NO_MEMORY;
5758 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5762 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5763 sid_string_dbg(&uinfo->sid)));
5764 TALLOC_FREE(sam_pass);
5765 return NT_STATUS_NO_SUCH_USER;
5768 /******** BEGIN SeAddUsers BLOCK *********/
5771 status = pdb_delete_user(p->mem_ctx, sam_pass);
5774 /******** END SeAddUsers BLOCK *********/
5776 if ( !NT_STATUS_IS_OK(status) ) {
5777 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5778 "user %s: %s.\n", pdb_get_username(sam_pass),
5779 nt_errstr(status)));
5780 TALLOC_FREE(sam_pass);
5785 TALLOC_FREE(sam_pass);
5787 force_flush_samr_cache(&uinfo->sid);
5789 if (!close_policy_hnd(p, r->in.user_handle))
5790 return NT_STATUS_OBJECT_NAME_INVALID;
5792 ZERO_STRUCTP(r->out.user_handle);
5794 return NT_STATUS_OK;
5797 /*********************************************************************
5798 _samr_DeleteDomainGroup
5799 *********************************************************************/
5801 NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
5802 struct samr_DeleteDomainGroup *r)
5804 struct samr_group_info *ginfo;
5808 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5810 ginfo = policy_handle_find(p, r->in.group_handle,
5811 SEC_STD_DELETE, NULL,
5812 struct samr_group_info, &status);
5813 if (!NT_STATUS_IS_OK(status)) {
5817 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5819 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5821 return NT_STATUS_NO_SUCH_GROUP;
5824 /******** BEGIN SeAddUsers BLOCK *********/
5827 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5830 /******** END SeAddUsers BLOCK *********/
5832 if ( !NT_STATUS_IS_OK(status) ) {
5833 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5834 "entry for group %s: %s\n",
5835 sid_string_dbg(&ginfo->sid),
5836 nt_errstr(status)));
5840 force_flush_samr_cache(&ginfo->sid);
5842 if (!close_policy_hnd(p, r->in.group_handle))
5843 return NT_STATUS_OBJECT_NAME_INVALID;
5845 return NT_STATUS_OK;
5848 /*********************************************************************
5849 _samr_DeleteDomAlias
5850 *********************************************************************/
5852 NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
5853 struct samr_DeleteDomAlias *r)
5855 struct samr_alias_info *ainfo;
5858 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5860 ainfo = policy_handle_find(p, r->in.alias_handle,
5861 SEC_STD_DELETE, NULL,
5862 struct samr_alias_info, &status);
5863 if (!NT_STATUS_IS_OK(status)) {
5867 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5869 /* Don't let Windows delete builtin groups */
5871 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5872 return NT_STATUS_SPECIAL_ACCOUNT;
5875 if (!sid_check_is_in_our_domain(&ainfo->sid))
5876 return NT_STATUS_NO_SUCH_ALIAS;
5878 DEBUG(10, ("lookup on Local SID\n"));
5880 /******** BEGIN SeAddUsers BLOCK *********/
5883 /* Have passdb delete the alias */
5884 status = pdb_delete_alias(&ainfo->sid);
5887 /******** END SeAddUsers BLOCK *********/
5889 if ( !NT_STATUS_IS_OK(status))
5892 force_flush_samr_cache(&ainfo->sid);
5894 if (!close_policy_hnd(p, r->in.alias_handle))
5895 return NT_STATUS_OBJECT_NAME_INVALID;
5897 return NT_STATUS_OK;
5900 /*********************************************************************
5901 _samr_CreateDomainGroup
5902 *********************************************************************/
5904 NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
5905 struct samr_CreateDomainGroup *r)
5910 struct samr_domain_info *dinfo;
5911 struct samr_group_info *ginfo;
5913 dinfo = policy_handle_find(p, r->in.domain_handle,
5914 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5915 struct samr_domain_info, &status);
5916 if (!NT_STATUS_IS_OK(status)) {
5920 if (!sid_check_is_domain(&dinfo->sid)) {
5921 return NT_STATUS_ACCESS_DENIED;
5924 name = r->in.name->string;
5926 return NT_STATUS_NO_MEMORY;
5929 status = can_create(p->mem_ctx, name);
5930 if (!NT_STATUS_IS_OK(status)) {
5934 /******** BEGIN SeAddUsers BLOCK *********/
5937 /* check that we successfully create the UNIX group */
5938 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5941 /******** END SeAddUsers BLOCK *********/
5943 /* check if we should bail out here */
5945 if ( !NT_STATUS_IS_OK(status) )
5948 ginfo = policy_handle_create(p, r->out.group_handle,
5949 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5950 struct samr_group_info, &status);
5951 if (!NT_STATUS_IS_OK(status)) {
5954 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5956 force_flush_samr_cache(&dinfo->sid);
5958 return NT_STATUS_OK;
5961 /*********************************************************************
5962 _samr_CreateDomAlias
5963 *********************************************************************/
5965 NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
5966 struct samr_CreateDomAlias *r)
5968 struct dom_sid info_sid;
5969 const char *name = NULL;
5970 struct samr_domain_info *dinfo;
5971 struct samr_alias_info *ainfo;
5975 dinfo = policy_handle_find(p, r->in.domain_handle,
5976 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5977 struct samr_domain_info, &result);
5978 if (!NT_STATUS_IS_OK(result)) {
5982 if (!sid_check_is_domain(&dinfo->sid)) {
5983 return NT_STATUS_ACCESS_DENIED;
5986 name = r->in.alias_name->string;
5988 result = can_create(p->mem_ctx, name);
5989 if (!NT_STATUS_IS_OK(result)) {
5993 /******** BEGIN SeAddUsers BLOCK *********/
5996 /* Have passdb create the alias */
5997 result = pdb_create_alias(name, r->out.rid);
6000 /******** END SeAddUsers BLOCK *********/
6002 if (!NT_STATUS_IS_OK(result)) {
6003 DEBUG(10, ("pdb_create_alias failed: %s\n",
6004 nt_errstr(result)));
6008 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
6010 if (!sid_to_gid(&info_sid, &gid)) {
6011 DEBUG(10, ("Could not find alias just created\n"));
6012 return NT_STATUS_ACCESS_DENIED;
6015 /* check if the group has been successfully created */
6016 if ( getgrgid(gid) == NULL ) {
6017 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
6018 (unsigned int)gid));
6019 return NT_STATUS_ACCESS_DENIED;
6022 ainfo = policy_handle_create(p, r->out.alias_handle,
6023 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
6024 struct samr_alias_info, &result);
6025 if (!NT_STATUS_IS_OK(result)) {
6028 ainfo->sid = info_sid;
6030 force_flush_samr_cache(&info_sid);
6032 return NT_STATUS_OK;
6035 /*********************************************************************
6036 _samr_QueryGroupInfo
6037 *********************************************************************/
6039 NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
6040 struct samr_QueryGroupInfo *r)
6042 struct samr_group_info *ginfo;
6045 union samr_GroupInfo *info = NULL;
6047 uint32_t attributes = SE_GROUP_MANDATORY |
6048 SE_GROUP_ENABLED_BY_DEFAULT |
6050 const char *group_name = NULL;
6051 const char *group_description = NULL;
6053 ginfo = policy_handle_find(p, r->in.group_handle,
6054 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
6055 struct samr_group_info, &status);
6056 if (!NT_STATUS_IS_OK(status)) {
6061 ret = get_domain_group_from_sid(ginfo->sid, &map);
6064 return NT_STATUS_INVALID_HANDLE;
6066 /* FIXME: map contains fstrings */
6067 group_name = talloc_strdup(r, map.nt_name);
6068 group_description = talloc_strdup(r, map.comment);
6070 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
6072 return NT_STATUS_NO_MEMORY;
6075 switch (r->in.level) {
6081 status = pdb_enum_group_members(
6082 p->mem_ctx, &ginfo->sid, &members,
6086 if (!NT_STATUS_IS_OK(status)) {
6090 info->all.name.string = group_name;
6091 info->all.attributes = attributes;
6092 info->all.num_members = num_members;
6093 info->all.description.string = group_description;
6097 info->name.string = group_name;
6100 info->attributes.attributes = attributes;
6103 info->description.string = group_description;
6113 status = pdb_enum_group_members(
6114 p->mem_ctx, &ginfo->sid, &members,
6118 if (!NT_STATUS_IS_OK(status)) {
6122 info->all2.name.string = group_name;
6123 info->all2.attributes = attributes;
6124 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
6125 info->all2.description.string = group_description;
6130 return NT_STATUS_INVALID_INFO_CLASS;
6133 *r->out.info = info;
6135 return NT_STATUS_OK;
6138 /*********************************************************************
6140 *********************************************************************/
6142 NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
6143 struct samr_SetGroupInfo *r)
6145 struct samr_group_info *ginfo;
6150 ginfo = policy_handle_find(p, r->in.group_handle,
6151 SAMR_GROUP_ACCESS_SET_INFO, NULL,
6152 struct samr_group_info, &status);
6153 if (!NT_STATUS_IS_OK(status)) {
6158 ret = get_domain_group_from_sid(ginfo->sid, &map);
6161 return NT_STATUS_NO_SUCH_GROUP;
6163 switch (r->in.level) {
6165 fstrcpy(map.nt_name, r->in.info->name.string);
6170 fstrcpy(map.comment, r->in.info->description.string);
6173 return NT_STATUS_INVALID_INFO_CLASS;
6176 /******** BEGIN SeAddUsers BLOCK *********/
6179 status = pdb_update_group_mapping_entry(&map);
6182 /******** End SeAddUsers BLOCK *********/
6184 if (NT_STATUS_IS_OK(status)) {
6185 force_flush_samr_cache(&ginfo->sid);
6191 /*********************************************************************
6193 *********************************************************************/
6195 NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
6196 struct samr_SetAliasInfo *r)
6198 struct samr_alias_info *ainfo;
6199 struct acct_info info;
6202 ainfo = policy_handle_find(p, r->in.alias_handle,
6203 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6204 struct samr_alias_info, &status);
6205 if (!NT_STATUS_IS_OK(status)) {
6209 /* get the current group information */
6212 status = pdb_get_aliasinfo( &ainfo->sid, &info );
6215 if ( !NT_STATUS_IS_OK(status))
6218 switch (r->in.level) {
6223 /* We currently do not support renaming groups in the
6224 the BUILTIN domain. Refer to util_builtin.c to understand
6225 why. The eventually needs to be fixed to be like Windows
6226 where you can rename builtin groups, just not delete them */
6228 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6229 return NT_STATUS_SPECIAL_ACCOUNT;
6232 /* There has to be a valid name (and it has to be different) */
6234 if ( !r->in.info->name.string )
6235 return NT_STATUS_INVALID_PARAMETER;
6237 /* If the name is the same just reply "ok". Yes this
6238 doesn't allow you to change the case of a group name. */
6240 if ( strequal( r->in.info->name.string, info.acct_name ) )
6241 return NT_STATUS_OK;
6243 fstrcpy( info.acct_name, r->in.info->name.string);
6245 /* make sure the name doesn't already exist as a user
6248 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6249 status = can_create( p->mem_ctx, group_name );
6250 if ( !NT_STATUS_IS_OK( status ) )
6254 case ALIASINFODESCRIPTION:
6255 if (r->in.info->description.string) {
6256 fstrcpy(info.acct_desc,
6257 r->in.info->description.string);
6259 fstrcpy( info.acct_desc, "" );
6263 return NT_STATUS_INVALID_INFO_CLASS;
6266 /******** BEGIN SeAddUsers BLOCK *********/
6269 status = pdb_set_aliasinfo( &ainfo->sid, &info );
6272 /******** End SeAddUsers BLOCK *********/
6274 if (NT_STATUS_IS_OK(status))
6275 force_flush_samr_cache(&ainfo->sid);
6280 /****************************************************************
6282 ****************************************************************/
6284 NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
6285 struct samr_GetDomPwInfo *r)
6287 uint32_t min_password_length = 0;
6288 uint32_t password_properties = 0;
6290 /* Perform access check. Since this rpc does not require a
6291 policy handle it will not be caught by the access checks on
6292 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6294 if (!pipe_access_check(p)) {
6295 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6296 return NT_STATUS_ACCESS_DENIED;
6300 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6301 &min_password_length);
6302 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6303 &password_properties);
6306 if (lp_check_password_script() && *lp_check_password_script()) {
6307 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6310 r->out.info->min_password_length = min_password_length;
6311 r->out.info->password_properties = password_properties;
6313 return NT_STATUS_OK;
6316 /*********************************************************************
6318 *********************************************************************/
6320 NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
6321 struct samr_OpenGroup *r)
6324 struct dom_sid info_sid;
6326 struct samr_domain_info *dinfo;
6327 struct samr_group_info *ginfo;
6328 struct security_descriptor *psd = NULL;
6330 uint32 des_access = r->in.access_mask;
6335 dinfo = policy_handle_find(p, r->in.domain_handle,
6336 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6337 struct samr_domain_info, &status);
6338 if (!NT_STATUS_IS_OK(status)) {
6342 /*check if access can be granted as requested by client. */
6343 map_max_allowed_access(p->session_info->security_token,
6344 &p->session_info->utok,
6347 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6348 se_map_generic(&des_access,&grp_generic_mapping);
6350 status = access_check_object(psd, p->session_info->security_token,
6351 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6352 des_access, &acc_granted, "_samr_OpenGroup");
6354 if ( !NT_STATUS_IS_OK(status) )
6357 /* this should not be hard-coded like this */
6359 if (!sid_check_is_domain(&dinfo->sid)) {
6360 return NT_STATUS_ACCESS_DENIED;
6363 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6365 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6366 sid_string_dbg(&info_sid)));
6368 /* check if that group really exists */
6370 ret = get_domain_group_from_sid(info_sid, &map);
6373 return NT_STATUS_NO_SUCH_GROUP;
6375 ginfo = policy_handle_create(p, r->out.group_handle,
6377 struct samr_group_info, &status);
6378 if (!NT_STATUS_IS_OK(status)) {
6381 ginfo->sid = info_sid;
6383 return NT_STATUS_OK;
6386 /*********************************************************************
6387 _samr_RemoveMemberFromForeignDomain
6388 *********************************************************************/
6390 NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
6391 struct samr_RemoveMemberFromForeignDomain *r)
6393 struct samr_domain_info *dinfo;
6396 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6397 sid_string_dbg(r->in.sid)));
6399 /* Find the policy handle. Open a policy on it. */
6401 dinfo = policy_handle_find(p, r->in.domain_handle,
6402 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6403 struct samr_domain_info, &result);
6404 if (!NT_STATUS_IS_OK(result)) {
6408 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6409 sid_string_dbg(&dinfo->sid)));
6411 /* we can only delete a user from a group since we don't have
6412 nested groups anyways. So in the latter case, just say OK */
6414 /* TODO: The above comment nowadays is bogus. Since we have nested
6415 * groups now, and aliases members are never reported out of the unix
6416 * group membership, the "just say OK" makes this call a no-op. For
6417 * us. This needs fixing however. */
6419 /* I've only ever seen this in the wild when deleting a user from
6420 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6421 * is the user about to be deleted. I very much suspect this is the
6422 * only application of this call. To verify this, let people report
6425 if (!sid_check_is_builtin(&dinfo->sid)) {
6426 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6427 "global_sam_sid() = %s\n",
6428 sid_string_dbg(&dinfo->sid),
6429 sid_string_dbg(get_global_sam_sid())));
6430 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6431 return NT_STATUS_OK;
6434 force_flush_samr_cache(&dinfo->sid);
6436 result = NT_STATUS_OK;
6441 /*******************************************************************
6442 _samr_QueryDomainInfo2
6443 ********************************************************************/
6445 NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
6446 struct samr_QueryDomainInfo2 *r)
6448 struct samr_QueryDomainInfo q;
6450 q.in.domain_handle = r->in.domain_handle;
6451 q.in.level = r->in.level;
6453 q.out.info = r->out.info;
6455 return _samr_QueryDomainInfo(p, &q);
6458 /*******************************************************************
6459 ********************************************************************/
6461 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6462 struct samr_DomInfo1 *r)
6464 time_t u_expire, u_min_age;
6466 u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6467 u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6469 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6470 (uint32_t)r->min_password_length);
6471 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6472 (uint32_t)r->password_history_length);
6473 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6474 (uint32_t)r->password_properties);
6475 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6476 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6478 return NT_STATUS_OK;
6481 /*******************************************************************
6482 ********************************************************************/
6484 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6485 struct samr_DomInfo3 *r)
6489 u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6491 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6493 return NT_STATUS_OK;
6496 /*******************************************************************
6497 ********************************************************************/
6499 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6500 struct samr_DomInfo12 *r)
6502 time_t u_lock_duration, u_reset_time;
6504 u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6505 if (u_lock_duration != -1) {
6506 u_lock_duration /= 60;
6509 u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6511 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6512 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6513 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6514 (uint32_t)r->lockout_threshold);
6516 return NT_STATUS_OK;
6519 /*******************************************************************
6521 ********************************************************************/
6523 NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
6524 struct samr_SetDomainInfo *r)
6526 struct samr_domain_info *dinfo;
6528 uint32_t acc_required = 0;
6530 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6532 switch (r->in.level) {
6533 case 1: /* DomainPasswordInformation */
6534 case 12: /* DomainLockoutInformation */
6535 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6536 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6538 case 3: /* DomainLogoffInformation */
6539 case 4: /* DomainOemInformation */
6540 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6541 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6543 case 6: /* DomainReplicationInformation */
6544 case 9: /* DomainStateInformation */
6545 case 7: /* DomainServerRoleInformation */
6546 /* DOMAIN_ADMINISTER_SERVER */
6547 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6550 return NT_STATUS_INVALID_INFO_CLASS;
6553 dinfo = policy_handle_find(p, r->in.domain_handle,
6555 struct samr_domain_info, &status);
6556 if (!NT_STATUS_IS_OK(status)) {
6560 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6562 switch (r->in.level) {
6564 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6567 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6578 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6581 return NT_STATUS_INVALID_INFO_CLASS;
6584 if (!NT_STATUS_IS_OK(status)) {
6588 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6590 return NT_STATUS_OK;
6593 /****************************************************************
6594 _samr_GetDisplayEnumerationIndex
6595 ****************************************************************/
6597 NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
6598 struct samr_GetDisplayEnumerationIndex *r)
6600 struct samr_domain_info *dinfo;
6601 uint32_t max_entries = (uint32_t) -1;
6602 uint32_t enum_context = 0;
6604 uint32_t num_account = 0;
6605 struct samr_displayentry *entries = NULL;
6608 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6610 dinfo = policy_handle_find(p, r->in.domain_handle,
6611 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6612 struct samr_domain_info, &status);
6613 if (!NT_STATUS_IS_OK(status)) {
6617 if ((r->in.level < 1) || (r->in.level > 3)) {
6618 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6619 "Unknown info level (%u)\n",
6621 return NT_STATUS_INVALID_INFO_CLASS;
6626 /* The following done as ROOT. Don't return without unbecome_root(). */
6628 switch (r->in.level) {
6630 if (dinfo->disp_info->users == NULL) {
6631 dinfo->disp_info->users = pdb_search_users(
6632 dinfo->disp_info, ACB_NORMAL);
6633 if (dinfo->disp_info->users == NULL) {
6635 return NT_STATUS_ACCESS_DENIED;
6637 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6638 "starting user enumeration at index %u\n",
6639 (unsigned int)enum_context));
6641 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6642 "using cached user enumeration at index %u\n",
6643 (unsigned int)enum_context));
6645 num_account = pdb_search_entries(dinfo->disp_info->users,
6646 enum_context, max_entries,
6650 if (dinfo->disp_info->machines == NULL) {
6651 dinfo->disp_info->machines = pdb_search_users(
6652 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6653 if (dinfo->disp_info->machines == NULL) {
6655 return NT_STATUS_ACCESS_DENIED;
6657 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6658 "starting machine enumeration at index %u\n",
6659 (unsigned int)enum_context));
6661 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6662 "using cached machine enumeration at index %u\n",
6663 (unsigned int)enum_context));
6665 num_account = pdb_search_entries(dinfo->disp_info->machines,
6666 enum_context, max_entries,
6670 if (dinfo->disp_info->groups == NULL) {
6671 dinfo->disp_info->groups = pdb_search_groups(
6673 if (dinfo->disp_info->groups == NULL) {
6675 return NT_STATUS_ACCESS_DENIED;
6677 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6678 "starting group enumeration at index %u\n",
6679 (unsigned int)enum_context));
6681 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6682 "using cached group enumeration at index %u\n",
6683 (unsigned int)enum_context));
6685 num_account = pdb_search_entries(dinfo->disp_info->groups,
6686 enum_context, max_entries,
6691 smb_panic("info class changed");
6697 /* Ensure we cache this enumeration. */
6698 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6700 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6701 r->in.name->string));
6703 for (i=0; i<num_account; i++) {
6704 if (strequal(entries[i].account_name, r->in.name->string)) {
6705 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6706 "found %s at idx %d\n",
6707 r->in.name->string, i));
6709 return NT_STATUS_OK;
6713 /* assuming account_name lives at the very end */
6714 *r->out.idx = num_account;
6716 return NT_STATUS_NO_MORE_ENTRIES;
6719 /****************************************************************
6720 _samr_GetDisplayEnumerationIndex2
6721 ****************************************************************/
6723 NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
6724 struct samr_GetDisplayEnumerationIndex2 *r)
6726 struct samr_GetDisplayEnumerationIndex q;
6728 q.in.domain_handle = r->in.domain_handle;
6729 q.in.level = r->in.level;
6730 q.in.name = r->in.name;
6732 q.out.idx = r->out.idx;
6734 return _samr_GetDisplayEnumerationIndex(p, &q);
6737 /****************************************************************
6739 ****************************************************************/
6741 NTSTATUS _samr_RidToSid(struct pipes_struct *p,
6742 struct samr_RidToSid *r)
6744 struct samr_domain_info *dinfo;
6748 dinfo = policy_handle_find(p, r->in.domain_handle,
6750 struct samr_domain_info, &status);
6751 if (!NT_STATUS_IS_OK(status)) {
6755 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6756 return NT_STATUS_NO_MEMORY;
6759 *r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
6761 return NT_STATUS_NO_MEMORY;
6764 return NT_STATUS_OK;
6767 /****************************************************************
6768 ****************************************************************/
6770 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
6771 const struct samr_PwInfo *dom_pw_info,
6772 const struct samr_ValidatePasswordReq2 *req,
6773 struct samr_ValidatePasswordRepCtr *rep)
6777 if (req->password.string == NULL) {
6778 return SAMR_VALIDATION_STATUS_SUCCESS;
6780 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6781 ZERO_STRUCT(rep->info);
6782 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6784 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6785 status = check_password_complexity(req->account.string,
6786 req->password.string,
6788 if (!NT_STATUS_IS_OK(status)) {
6789 ZERO_STRUCT(rep->info);
6790 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6794 return SAMR_VALIDATION_STATUS_SUCCESS;
6797 /****************************************************************
6798 ****************************************************************/
6800 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
6801 const struct samr_PwInfo *dom_pw_info,
6802 const struct samr_ValidatePasswordReq3 *req,
6803 struct samr_ValidatePasswordRepCtr *rep)
6807 if (req->password.string == NULL) {
6808 return SAMR_VALIDATION_STATUS_SUCCESS;
6810 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6811 ZERO_STRUCT(rep->info);
6812 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6814 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6815 status = check_password_complexity(req->account.string,
6816 req->password.string,
6818 if (!NT_STATUS_IS_OK(status)) {
6819 ZERO_STRUCT(rep->info);
6820 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6824 return SAMR_VALIDATION_STATUS_SUCCESS;
6827 /****************************************************************
6828 _samr_ValidatePassword
6829 ****************************************************************/
6831 NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
6832 struct samr_ValidatePassword *r)
6834 union samr_ValidatePasswordRep *rep;
6836 struct samr_GetDomPwInfo pw;
6837 struct samr_PwInfo dom_pw_info;
6839 if (r->in.level < 1 || r->in.level > 3) {
6840 return NT_STATUS_INVALID_INFO_CLASS;
6843 pw.in.domain_name = NULL;
6844 pw.out.info = &dom_pw_info;
6846 status = _samr_GetDomPwInfo(p, &pw);
6847 if (!NT_STATUS_IS_OK(status)) {
6851 rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
6853 return NT_STATUS_NO_MEMORY;
6856 switch (r->in.level) {
6858 status = NT_STATUS_NOT_SUPPORTED;
6861 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
6867 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
6873 status = NT_STATUS_INVALID_INFO_CLASS;
6877 if (!NT_STATUS_IS_OK(status)) {
6884 return NT_STATUS_OK;
6887 /****************************************************************
6888 ****************************************************************/
6890 NTSTATUS _samr_Shutdown(struct pipes_struct *p,
6891 struct samr_Shutdown *r)
6893 p->rng_fault_state = true;
6894 return NT_STATUS_NOT_IMPLEMENTED;
6897 /****************************************************************
6898 ****************************************************************/
6900 NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
6901 struct samr_SetMemberAttributesOfGroup *r)
6903 p->rng_fault_state = true;
6904 return NT_STATUS_NOT_IMPLEMENTED;
6907 /****************************************************************
6908 ****************************************************************/
6910 NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
6911 struct samr_TestPrivateFunctionsDomain *r)
6913 return NT_STATUS_NOT_IMPLEMENTED;
6916 /****************************************************************
6917 ****************************************************************/
6919 NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
6920 struct samr_TestPrivateFunctionsUser *r)
6922 return NT_STATUS_NOT_IMPLEMENTED;
6925 /****************************************************************
6926 ****************************************************************/
6928 NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
6929 struct samr_AddMultipleMembersToAlias *r)
6931 p->rng_fault_state = true;
6932 return NT_STATUS_NOT_IMPLEMENTED;
6935 /****************************************************************
6936 ****************************************************************/
6938 NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
6939 struct samr_RemoveMultipleMembersFromAlias *r)
6941 p->rng_fault_state = true;
6942 return NT_STATUS_NOT_IMPLEMENTED;
6945 /****************************************************************
6946 ****************************************************************/
6948 NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
6949 struct samr_SetBootKeyInformation *r)
6951 p->rng_fault_state = true;
6952 return NT_STATUS_NOT_IMPLEMENTED;
6955 /****************************************************************
6956 ****************************************************************/
6958 NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
6959 struct samr_GetBootKeyInformation *r)
6961 p->rng_fault_state = true;
6962 return NT_STATUS_NOT_IMPLEMENTED;
6965 /****************************************************************
6966 ****************************************************************/
6968 NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
6969 struct samr_SetDsrmPassword *r)
6971 p->rng_fault_state = true;
6972 return NT_STATUS_NOT_IMPLEMENTED;