2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
35 #include "../libcli/auth/libcli_auth.h"
38 #define DBGC_CLASS DBGC_RPC_SRV
40 #define SAMR_USR_RIGHTS_WRITE_PW \
41 ( READ_CONTROL_ACCESS | \
42 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
43 SAMR_USER_ACCESS_SET_LOC_COM)
44 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
45 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
47 #define DISP_INFO_CACHE_TIMEOUT 10
49 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
50 #define MAX_SAM_ENTRIES_W95 50
52 struct samr_connect_info {
56 struct samr_domain_info {
58 struct disp_info *disp_info;
61 struct samr_user_info {
65 struct samr_group_info {
69 struct samr_alias_info {
73 typedef struct disp_info {
74 DOM_SID sid; /* identify which domain this is. */
75 struct pdb_search *users; /* querydispinfo 1 and 4 */
76 struct pdb_search *machines; /* querydispinfo 2 */
77 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
78 struct pdb_search *aliases; /* enumaliases */
81 struct pdb_search *enum_users; /* enumusers with a mask */
83 struct timed_event *cache_timeout_event; /* cache idle timeout
87 /* We keep a static list of these by SID as modern clients close down
88 all resources between each request in a complete enumeration. */
91 /* for use by the \PIPE\samr policy */
93 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
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, SEC_DESC **psd, size_t *sd_size,
133 const struct generic_mapping *map,
134 DOM_SID *sid, uint32 sid_access )
136 DOM_SID domadmin_sid;
137 SEC_ACE ace[5]; /* at most 5 entries */
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_copy( &domadmin_sid, get_global_sam_sid() );
158 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
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.
185 ********************************************************************/
187 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
188 SE_PRIV *rights, uint32 rights_mask,
189 uint32 des_access, uint32 *acc_granted,
192 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
193 uint32 saved_mask = 0;
195 /* check privileges; certain SAM access bits should be overridden
196 by privileges (mostly having to do with creating/modifying/deleting
199 if ( rights && user_has_any_privilege( token, rights ) ) {
201 saved_mask = (des_access & rights_mask);
202 des_access &= ~saved_mask;
204 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
209 /* check the security descriptor first */
211 status = se_access_check(psd, token, des_access, acc_granted);
212 if (NT_STATUS_IS_OK(status)) {
216 /* give root a free pass */
218 if ( geteuid() == sec_initial_uid() ) {
220 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
221 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
223 *acc_granted = des_access;
225 status = NT_STATUS_OK;
231 /* add in any bits saved during the privilege check (only
232 matters is status is ok) */
234 *acc_granted |= rights_mask;
236 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
237 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
238 des_access, *acc_granted));
243 /*******************************************************************
244 Checks if access to a function can be granted
245 ********************************************************************/
247 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
249 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
250 debug, acc_granted, acc_required));
252 /* check the security descriptor first */
254 if ( (acc_granted&acc_required) == acc_required )
257 /* give root a free pass */
259 if (geteuid() == sec_initial_uid()) {
261 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
262 debug, acc_granted, acc_required));
263 DEBUGADD(4,("but overwritten by euid == 0\n"));
268 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
269 debug, acc_granted, acc_required));
271 return NT_STATUS_ACCESS_DENIED;
274 /*******************************************************************
275 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
276 ********************************************************************/
278 static void map_max_allowed_access(const NT_USER_TOKEN *token,
279 uint32_t *pacc_requested)
281 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
284 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
286 /* At least try for generic read. */
287 *pacc_requested = GENERIC_READ_ACCESS;
289 /* root gets anything. */
290 if (geteuid() == sec_initial_uid()) {
291 *pacc_requested |= GENERIC_ALL_ACCESS;
295 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
297 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
298 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
299 *pacc_requested |= GENERIC_ALL_ACCESS;
303 /* Full access for DOMAIN\Domain Admins. */
305 DOM_SID domadmin_sid;
306 sid_copy( &domadmin_sid, get_global_sam_sid() );
307 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
308 if (is_sid_in_token(token, &domadmin_sid)) {
309 *pacc_requested |= GENERIC_ALL_ACCESS;
313 /* TODO ! Check privileges. */
316 /*******************************************************************
317 Fetch or create a dispinfo struct.
318 ********************************************************************/
320 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
323 * We do a static cache for DISP_INFO's here. Explanation can be found
324 * in Jeremy's checkin message to r11793:
326 * Fix the SAMR cache so it works across completely insane
327 * client behaviour (ie.:
328 * open pipe/open SAMR handle/enumerate 0 - 1024
329 * close SAMR handle, close pipe.
330 * open pipe/open SAMR handle/enumerate 1024 - 2048...
331 * close SAMR handle, close pipe.
332 * And on ad-nausium. Amazing.... probably object-oriented
333 * client side programming in action yet again.
334 * This change should *massively* improve performance when
335 * enumerating users from an LDAP database.
338 * "Our" and the builtin domain are the only ones where we ever
339 * enumerate stuff, so just cache 2 entries.
342 static struct disp_info *builtin_dispinfo;
343 static struct disp_info *domain_dispinfo;
345 /* There are two cases to consider here:
346 1) The SID is a domain SID and we look for an equality match, or
347 2) This is an account SID and so we return the DISP_INFO* for our
354 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
356 * Necessary only once, but it does not really hurt.
358 if (builtin_dispinfo == NULL) {
359 builtin_dispinfo = talloc_zero(
360 talloc_autofree_context(), struct disp_info);
361 if (builtin_dispinfo == NULL) {
365 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
367 return builtin_dispinfo;
370 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
372 * Necessary only once, but it does not really hurt.
374 if (domain_dispinfo == NULL) {
375 domain_dispinfo = talloc_zero(
376 talloc_autofree_context(), struct disp_info);
377 if (domain_dispinfo == NULL) {
381 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
383 return domain_dispinfo;
389 /*******************************************************************
390 Create a samr_info struct.
391 ********************************************************************/
393 static int samr_info_destructor(struct samr_info *info);
395 static struct samr_info *get_samr_info_by_sid(TALLOC_CTX *mem_ctx,
398 struct samr_info *info;
400 info = talloc_zero(mem_ctx, struct samr_info);
404 talloc_set_destructor(info, samr_info_destructor);
406 DEBUG(10, ("get_samr_info_by_sid: created new info for sid %s\n",
407 sid_string_dbg(psid)));
410 sid_copy( &info->sid, psid);
412 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
415 info->disp_info = get_samr_dispinfo_by_sid(psid);
420 /*******************************************************************
421 Function to free the per SID data.
422 ********************************************************************/
424 static void free_samr_cache(DISP_INFO *disp_info)
426 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
427 sid_string_dbg(&disp_info->sid)));
429 /* We need to become root here because the paged search might have to
430 * tell the LDAP server we're not interested in the rest anymore. */
434 TALLOC_FREE(disp_info->users);
435 TALLOC_FREE(disp_info->machines);
436 TALLOC_FREE(disp_info->groups);
437 TALLOC_FREE(disp_info->aliases);
438 TALLOC_FREE(disp_info->enum_users);
443 static int samr_info_destructor(struct samr_info *info)
445 /* Only free the dispinfo cache if no one bothered to set up
448 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
449 free_samr_cache(info->disp_info);
454 /*******************************************************************
455 Idle event handler. Throw away the disp info cache.
456 ********************************************************************/
458 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
459 struct timed_event *te,
463 DISP_INFO *disp_info = (DISP_INFO *)private_data;
465 TALLOC_FREE(disp_info->cache_timeout_event);
467 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
469 free_samr_cache(disp_info);
472 /*******************************************************************
473 Setup cache removal idle event handler.
474 ********************************************************************/
476 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
478 /* Remove any pending timeout and update. */
480 TALLOC_FREE(disp_info->cache_timeout_event);
482 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
483 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
484 (unsigned int)secs_fromnow ));
486 disp_info->cache_timeout_event = event_add_timed(
487 smbd_event_context(), NULL,
488 timeval_current_ofs(secs_fromnow, 0),
489 disp_info_cache_idle_timeout_handler, (void *)disp_info);
492 /*******************************************************************
493 Force flush any cache. We do this on any samr_set_xxx call.
494 We must also remove the timeout handler.
495 ********************************************************************/
497 static void force_flush_samr_cache(const struct dom_sid *sid)
499 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
501 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
505 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
506 TALLOC_FREE(disp_info->cache_timeout_event);
507 free_samr_cache(disp_info);
510 /*******************************************************************
511 Ensure password info is never given out. Paranioa... JRA.
512 ********************************************************************/
514 static void samr_clear_sam_passwd(struct samu *sam_pass)
520 /* These now zero out the old password */
522 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
523 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
526 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
528 struct samr_displayentry *entry;
530 if (sid_check_is_builtin(&info->sid)) {
531 /* No users in builtin. */
535 if (info->users == NULL) {
536 info->users = pdb_search_users(info, acct_flags);
537 if (info->users == NULL) {
541 /* Fetch the last possible entry, thus trigger an enumeration */
542 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
544 /* Ensure we cache this enumeration. */
545 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
547 return info->users->num_entries;
550 static uint32 count_sam_groups(struct disp_info *info)
552 struct samr_displayentry *entry;
554 if (sid_check_is_builtin(&info->sid)) {
555 /* No groups in builtin. */
559 if (info->groups == NULL) {
560 info->groups = pdb_search_groups(info);
561 if (info->groups == NULL) {
565 /* Fetch the last possible entry, thus trigger an enumeration */
566 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
568 /* Ensure we cache this enumeration. */
569 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
571 return info->groups->num_entries;
574 static uint32 count_sam_aliases(struct disp_info *info)
576 struct samr_displayentry *entry;
578 if (info->aliases == NULL) {
579 info->aliases = pdb_search_aliases(info, &info->sid);
580 if (info->aliases == NULL) {
584 /* Fetch the last possible entry, thus trigger an enumeration */
585 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
587 /* Ensure we cache this enumeration. */
588 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
590 return info->aliases->num_entries;
593 /*******************************************************************
595 ********************************************************************/
597 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
599 if (!close_policy_hnd(p, r->in.handle)) {
600 return NT_STATUS_INVALID_HANDLE;
603 ZERO_STRUCTP(r->out.handle);
608 /*******************************************************************
610 ********************************************************************/
612 NTSTATUS _samr_OpenDomain(pipes_struct *p,
613 struct samr_OpenDomain *r)
615 struct samr_connect_info *cinfo;
616 struct samr_domain_info *dinfo;
617 SEC_DESC *psd = NULL;
619 uint32 des_access = r->in.access_mask;
624 /* find the connection policy handle. */
626 cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
627 struct samr_connect_info, &status);
628 if (!NT_STATUS_IS_OK(status)) {
632 /*check if access can be granted as requested by client. */
633 map_max_allowed_access(p->server_info->ptok, &des_access);
635 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
636 se_map_generic( &des_access, &dom_generic_mapping );
638 se_priv_copy( &se_rights, &se_machine_account );
639 se_priv_add( &se_rights, &se_add_users );
641 status = access_check_samr_object( psd, p->server_info->ptok,
642 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
643 &acc_granted, "_samr_OpenDomain" );
645 if ( !NT_STATUS_IS_OK(status) )
648 if (!sid_check_is_domain(r->in.sid) &&
649 !sid_check_is_builtin(r->in.sid)) {
650 return NT_STATUS_NO_SUCH_DOMAIN;
653 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
654 struct samr_domain_info, &status);
655 if (!NT_STATUS_IS_OK(status)) {
658 dinfo->sid = *r->in.sid;
659 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
661 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
666 /*******************************************************************
668 ********************************************************************/
670 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
671 struct samr_GetUserPwInfo *r)
673 struct samr_user_info *uinfo;
674 enum lsa_SidType sid_type;
675 uint32_t min_password_length = 0;
676 uint32_t password_properties = 0;
680 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
682 uinfo = policy_handle_find(p, r->in.user_handle,
683 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
684 struct samr_user_info, &status);
685 if (!NT_STATUS_IS_OK(status)) {
689 if (!sid_check_is_in_our_domain(&uinfo->sid)) {
690 return NT_STATUS_OBJECT_TYPE_MISMATCH;
694 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
697 return NT_STATUS_NO_SUCH_USER;
703 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
704 &min_password_length);
705 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
706 &password_properties);
709 if (lp_check_password_script() && *lp_check_password_script()) {
710 password_properties |= DOMAIN_PASSWORD_COMPLEX;
718 r->out.info->min_password_length = min_password_length;
719 r->out.info->password_properties = password_properties;
721 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
726 /*******************************************************************
727 ********************************************************************/
729 static bool get_lsa_policy_samr_sid( pipes_struct *p, struct policy_handle *pol,
730 DOM_SID *sid, uint32 *acc_granted,
731 DISP_INFO **ppdisp_info)
733 struct samr_info *info = NULL;
735 /* find the policy handle. open a policy on it. */
736 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
743 *acc_granted = info->acc_granted;
745 *ppdisp_info = info->disp_info;
751 /*******************************************************************
753 ********************************************************************/
755 NTSTATUS _samr_SetSecurity(pipes_struct *p,
756 struct samr_SetSecurity *r)
758 struct samr_user_info *uinfo;
762 struct samu *sampass=NULL;
765 uinfo = policy_handle_find(p, r->in.handle,
766 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
767 struct samr_user_info, &status);
768 if (!NT_STATUS_IS_OK(status)) {
772 if (!(sampass = samu_new( p->mem_ctx))) {
773 DEBUG(0,("No memory!\n"));
774 return NT_STATUS_NO_MEMORY;
777 /* get the user record */
779 ret = pdb_getsampwsid(sampass, &uinfo->sid);
783 DEBUG(4, ("User %s not found\n",
784 sid_string_dbg(&uinfo->sid)));
785 TALLOC_FREE(sampass);
786 return NT_STATUS_INVALID_HANDLE;
789 dacl = r->in.sdbuf->sd->dacl;
790 for (i=0; i < dacl->num_aces; i++) {
791 if (sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
792 ret = pdb_set_pass_can_change(sampass,
793 (dacl->aces[i].access_mask &
794 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
801 TALLOC_FREE(sampass);
802 return NT_STATUS_ACCESS_DENIED;
806 status = pdb_update_sam_account(sampass);
809 TALLOC_FREE(sampass);
814 /*******************************************************************
815 build correct perms based on policies and password times for _samr_query_sec_obj
816 *******************************************************************/
817 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
819 struct samu *sampass=NULL;
822 if ( !(sampass = samu_new( mem_ctx )) ) {
823 DEBUG(0,("No memory!\n"));
828 ret = pdb_getsampwsid(sampass, user_sid);
832 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
833 TALLOC_FREE(sampass);
837 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
839 if (pdb_get_pass_can_change(sampass)) {
840 TALLOC_FREE(sampass);
843 TALLOC_FREE(sampass);
848 /*******************************************************************
850 ********************************************************************/
852 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
853 struct samr_QuerySecurity *r)
855 struct samr_connect_info *cinfo;
856 struct samr_domain_info *dinfo;
857 struct samr_user_info *uinfo;
858 struct samr_group_info *ginfo;
859 struct samr_alias_info *ainfo;
861 SEC_DESC * psd = NULL;
864 cinfo = policy_handle_find(p, r->in.handle,
865 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
866 struct samr_connect_info, &status);
867 if (NT_STATUS_IS_OK(status)) {
868 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
869 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
870 &sam_generic_mapping, NULL, 0);
874 dinfo = policy_handle_find(p, r->in.handle,
875 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
876 struct samr_domain_info, &status);
877 if (NT_STATUS_IS_OK(status)) {
878 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
879 "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
881 * TODO: Builtin probably needs a different SD with restricted
884 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
885 &dom_generic_mapping, NULL, 0);
889 uinfo = policy_handle_find(p, r->in.handle,
890 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
891 struct samr_user_info, &status);
892 if (NT_STATUS_IS_OK(status)) {
893 DEBUG(10,("_samr_QuerySecurity: querying security on user "
894 "Object with SID: %s\n",
895 sid_string_dbg(&uinfo->sid)));
896 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
897 status = make_samr_object_sd(
898 p->mem_ctx, &psd, &sd_size,
899 &usr_generic_mapping,
900 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
902 status = make_samr_object_sd(
903 p->mem_ctx, &psd, &sd_size,
904 &usr_nopwchange_generic_mapping,
905 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
910 ginfo = policy_handle_find(p, r->in.handle,
911 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
912 struct samr_group_info, &status);
913 if (NT_STATUS_IS_OK(status)) {
915 * TODO: different SDs have to be generated for aliases groups
916 * and users. Currently all three get a default user SD
918 DEBUG(10,("_samr_QuerySecurity: querying security on group "
919 "Object with SID: %s\n",
920 sid_string_dbg(&ginfo->sid)));
921 status = make_samr_object_sd(
922 p->mem_ctx, &psd, &sd_size,
923 &usr_nopwchange_generic_mapping,
924 &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
928 ainfo = policy_handle_find(p, r->in.handle,
929 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
930 struct samr_alias_info, &status);
931 if (NT_STATUS_IS_OK(status)) {
933 * TODO: different SDs have to be generated for aliases groups
934 * and users. Currently all three get a default user SD
936 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
937 "Object with SID: %s\n",
938 sid_string_dbg(&ainfo->sid)));
939 status = make_samr_object_sd(
940 p->mem_ctx, &psd, &sd_size,
941 &usr_nopwchange_generic_mapping,
942 &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
946 return NT_STATUS_OBJECT_TYPE_MISMATCH;
948 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
949 return NT_STATUS_NO_MEMORY;
954 /*******************************************************************
955 makes a SAM_ENTRY / UNISTR2* structure from a user list.
956 ********************************************************************/
958 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
959 struct samr_SamEntry **sam_pp,
960 uint32_t num_entries,
962 struct samr_displayentry *entries)
965 struct samr_SamEntry *sam;
969 if (num_entries == 0) {
973 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
975 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
976 return NT_STATUS_NO_MEMORY;
979 for (i = 0; i < num_entries; i++) {
982 * usrmgr expects a non-NULL terminated string with
983 * trust relationships
985 if (entries[i].acct_flags & ACB_DOMTRUST) {
986 init_unistr2(&uni_temp_name, entries[i].account_name,
989 init_unistr2(&uni_temp_name, entries[i].account_name,
993 init_lsa_String(&sam[i].name, entries[i].account_name);
994 sam[i].idx = entries[i].rid;
1002 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
1004 /*******************************************************************
1005 _samr_EnumDomainUsers
1006 ********************************************************************/
1008 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
1009 struct samr_EnumDomainUsers *r)
1012 struct samr_domain_info *dinfo;
1014 uint32 enum_context = *r->in.resume_handle;
1015 enum remote_arch_types ra_type = get_remote_arch();
1016 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1017 uint32 max_entries = max_sam_entries;
1018 struct samr_displayentry *entries = NULL;
1019 struct samr_SamArray *samr_array = NULL;
1020 struct samr_SamEntry *samr_entries = NULL;
1022 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1024 dinfo = policy_handle_find(p, r->in.domain_handle,
1025 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1026 struct samr_domain_info, &status);
1027 if (!NT_STATUS_IS_OK(status)) {
1031 if (sid_check_is_builtin(&dinfo->sid)) {
1032 /* No users in builtin. */
1033 *r->out.resume_handle = *r->in.resume_handle;
1034 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
1038 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1040 return NT_STATUS_NO_MEMORY;
1042 *r->out.sam = samr_array;
1048 if ((dinfo->disp_info->enum_users != NULL) &&
1049 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
1050 TALLOC_FREE(dinfo->disp_info->enum_users);
1053 if (dinfo->disp_info->enum_users == NULL) {
1054 dinfo->disp_info->enum_users = pdb_search_users(
1055 dinfo->disp_info, r->in.acct_flags);
1056 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
1059 if (dinfo->disp_info->enum_users == NULL) {
1060 /* END AS ROOT !!!! */
1062 return NT_STATUS_ACCESS_DENIED;
1065 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
1066 enum_context, max_entries,
1069 /* END AS ROOT !!!! */
1073 if (num_account == 0) {
1074 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1075 "total entries\n"));
1076 *r->out.resume_handle = *r->in.resume_handle;
1077 return NT_STATUS_OK;
1080 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1081 num_account, enum_context,
1083 if (!NT_STATUS_IS_OK(status)) {
1087 if (max_entries <= num_account) {
1088 status = STATUS_MORE_ENTRIES;
1090 status = NT_STATUS_OK;
1093 /* Ensure we cache this enumeration. */
1094 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1096 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1098 samr_array->count = num_account;
1099 samr_array->entries = samr_entries;
1101 *r->out.resume_handle = *r->in.resume_handle + num_account;
1102 *r->out.num_entries = num_account;
1104 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1109 /*******************************************************************
1110 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1111 ********************************************************************/
1113 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1114 struct samr_SamEntry **sam_pp,
1115 uint32_t num_sam_entries,
1116 struct samr_displayentry *entries)
1118 struct samr_SamEntry *sam;
1123 if (num_sam_entries == 0) {
1127 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1132 for (i = 0; i < num_sam_entries; i++) {
1134 * JRA. I think this should include the null. TNG does not.
1136 init_lsa_String(&sam[i].name, entries[i].account_name);
1137 sam[i].idx = entries[i].rid;
1143 /*******************************************************************
1144 _samr_EnumDomainGroups
1145 ********************************************************************/
1147 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1148 struct samr_EnumDomainGroups *r)
1151 struct samr_domain_info *dinfo;
1152 struct samr_displayentry *groups;
1154 struct samr_SamArray *samr_array = NULL;
1155 struct samr_SamEntry *samr_entries = NULL;
1157 dinfo = policy_handle_find(p, r->in.domain_handle,
1158 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1159 struct samr_domain_info, &status);
1160 if (!NT_STATUS_IS_OK(status)) {
1164 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1166 if (sid_check_is_builtin(&dinfo->sid)) {
1167 /* No groups in builtin. */
1168 *r->out.resume_handle = *r->in.resume_handle;
1169 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1173 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1175 return NT_STATUS_NO_MEMORY;
1178 /* the domain group array is being allocated in the function below */
1182 if (dinfo->disp_info->groups == NULL) {
1183 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1185 if (dinfo->disp_info->groups == NULL) {
1187 return NT_STATUS_ACCESS_DENIED;
1191 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1192 *r->in.resume_handle,
1193 MAX_SAM_ENTRIES, &groups);
1196 /* Ensure we cache this enumeration. */
1197 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1199 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1200 num_groups, groups);
1202 samr_array->count = num_groups;
1203 samr_array->entries = samr_entries;
1205 *r->out.sam = samr_array;
1206 *r->out.num_entries = num_groups;
1207 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1209 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1214 /*******************************************************************
1215 _samr_EnumDomainAliases
1216 ********************************************************************/
1218 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1219 struct samr_EnumDomainAliases *r)
1222 struct samr_domain_info *dinfo;
1223 struct samr_displayentry *aliases;
1224 uint32 num_aliases = 0;
1225 struct samr_SamArray *samr_array = NULL;
1226 struct samr_SamEntry *samr_entries = NULL;
1228 dinfo = policy_handle_find(p, r->in.domain_handle,
1229 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1230 struct samr_domain_info, &status);
1231 if (!NT_STATUS_IS_OK(status)) {
1235 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1236 sid_string_dbg(&dinfo->sid)));
1238 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1240 return NT_STATUS_NO_MEMORY;
1245 if (dinfo->disp_info->aliases == NULL) {
1246 dinfo->disp_info->aliases = pdb_search_aliases(
1247 dinfo->disp_info, &dinfo->sid);
1248 if (dinfo->disp_info->aliases == NULL) {
1250 return NT_STATUS_ACCESS_DENIED;
1254 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1255 *r->in.resume_handle,
1256 MAX_SAM_ENTRIES, &aliases);
1259 /* Ensure we cache this enumeration. */
1260 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1262 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1263 num_aliases, aliases);
1265 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1267 samr_array->count = num_aliases;
1268 samr_array->entries = samr_entries;
1270 *r->out.sam = samr_array;
1271 *r->out.num_entries = num_aliases;
1272 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1277 /*******************************************************************
1278 inits a samr_DispInfoGeneral structure.
1279 ********************************************************************/
1281 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1282 struct samr_DispInfoGeneral *r,
1283 uint32_t num_entries,
1285 struct samr_displayentry *entries)
1289 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1291 if (num_entries == 0) {
1292 return NT_STATUS_OK;
1295 r->count = num_entries;
1297 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1299 return NT_STATUS_NO_MEMORY;
1302 for (i = 0; i < num_entries ; i++) {
1304 init_lsa_String(&r->entries[i].account_name,
1305 entries[i].account_name);
1307 init_lsa_String(&r->entries[i].description,
1308 entries[i].description);
1310 init_lsa_String(&r->entries[i].full_name,
1311 entries[i].fullname);
1313 r->entries[i].rid = entries[i].rid;
1314 r->entries[i].acct_flags = entries[i].acct_flags;
1315 r->entries[i].idx = start_idx+i+1;
1318 return NT_STATUS_OK;
1321 /*******************************************************************
1322 inits a samr_DispInfoFull structure.
1323 ********************************************************************/
1325 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1326 struct samr_DispInfoFull *r,
1327 uint32_t num_entries,
1329 struct samr_displayentry *entries)
1333 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1335 if (num_entries == 0) {
1336 return NT_STATUS_OK;
1339 r->count = num_entries;
1341 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1343 return NT_STATUS_NO_MEMORY;
1346 for (i = 0; i < num_entries ; i++) {
1348 init_lsa_String(&r->entries[i].account_name,
1349 entries[i].account_name);
1351 init_lsa_String(&r->entries[i].description,
1352 entries[i].description);
1354 r->entries[i].rid = entries[i].rid;
1355 r->entries[i].acct_flags = entries[i].acct_flags;
1356 r->entries[i].idx = start_idx+i+1;
1359 return NT_STATUS_OK;
1362 /*******************************************************************
1363 inits a samr_DispInfoFullGroups structure.
1364 ********************************************************************/
1366 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1367 struct samr_DispInfoFullGroups *r,
1368 uint32_t num_entries,
1370 struct samr_displayentry *entries)
1374 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1376 if (num_entries == 0) {
1377 return NT_STATUS_OK;
1380 r->count = num_entries;
1382 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1384 return NT_STATUS_NO_MEMORY;
1387 for (i = 0; i < num_entries ; i++) {
1389 init_lsa_String(&r->entries[i].account_name,
1390 entries[i].account_name);
1392 init_lsa_String(&r->entries[i].description,
1393 entries[i].description);
1395 r->entries[i].rid = entries[i].rid;
1396 r->entries[i].acct_flags = entries[i].acct_flags;
1397 r->entries[i].idx = start_idx+i+1;
1400 return NT_STATUS_OK;
1403 /*******************************************************************
1404 inits a samr_DispInfoAscii structure.
1405 ********************************************************************/
1407 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1408 struct samr_DispInfoAscii *r,
1409 uint32_t num_entries,
1411 struct samr_displayentry *entries)
1415 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1417 if (num_entries == 0) {
1418 return NT_STATUS_OK;
1421 r->count = num_entries;
1423 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1425 return NT_STATUS_NO_MEMORY;
1428 for (i = 0; i < num_entries ; i++) {
1430 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1431 entries[i].account_name);
1433 r->entries[i].idx = start_idx+i+1;
1436 return NT_STATUS_OK;
1439 /*******************************************************************
1440 inits a samr_DispInfoAscii structure.
1441 ********************************************************************/
1443 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1444 struct samr_DispInfoAscii *r,
1445 uint32_t num_entries,
1447 struct samr_displayentry *entries)
1451 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1453 if (num_entries == 0) {
1454 return NT_STATUS_OK;
1457 r->count = num_entries;
1459 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1461 return NT_STATUS_NO_MEMORY;
1464 for (i = 0; i < num_entries ; i++) {
1466 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1467 entries[i].account_name);
1469 r->entries[i].idx = start_idx+i+1;
1472 return NT_STATUS_OK;
1475 /*******************************************************************
1476 _samr_QueryDisplayInfo
1477 ********************************************************************/
1479 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1480 struct samr_QueryDisplayInfo *r)
1483 struct samr_domain_info *dinfo;
1484 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1486 uint32 max_entries = r->in.max_entries;
1487 uint32 enum_context = r->in.start_idx;
1488 uint32 max_size = r->in.buf_size;
1490 union samr_DispInfo *disp_info = r->out.info;
1492 uint32 temp_size=0, total_data_size=0;
1493 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1494 uint32 num_account = 0;
1495 enum remote_arch_types ra_type = get_remote_arch();
1496 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1497 struct samr_displayentry *entries = NULL;
1499 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1501 dinfo = policy_handle_find(p, r->in.domain_handle,
1502 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1503 struct samr_domain_info, &status);
1504 if (!NT_STATUS_IS_OK(status)) {
1509 * calculate how many entries we will return.
1511 * - the number of entries the client asked
1512 * - our limit on that
1513 * - the starting point (enumeration context)
1514 * - the buffer size the client will accept
1518 * We are a lot more like W2K. Instead of reading the SAM
1519 * each time to find the records we need to send back,
1520 * we read it once and link that copy to the sam handle.
1521 * For large user list (over the MAX_SAM_ENTRIES)
1522 * it's a definitive win.
1523 * second point to notice: between enumerations
1524 * our sam is now the same as it's a snapshoot.
1525 * third point: got rid of the static SAM_USER_21 struct
1526 * no more intermediate.
1527 * con: it uses much more memory, as a full copy is stored
1530 * If you want to change it, think twice and think
1531 * of the second point , that's really important.
1536 if ((r->in.level < 1) || (r->in.level > 5)) {
1537 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1538 (unsigned int)r->in.level ));
1539 return NT_STATUS_INVALID_INFO_CLASS;
1542 /* first limit the number of entries we will return */
1543 if(max_entries > max_sam_entries) {
1544 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1545 "entries, limiting to %d\n", max_entries,
1547 max_entries = max_sam_entries;
1550 /* calculate the size and limit on the number of entries we will
1553 temp_size=max_entries*struct_size;
1555 if (temp_size>max_size) {
1556 max_entries=MIN((max_size/struct_size),max_entries);;
1557 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1558 "only %d entries\n", max_entries));
1563 /* THe following done as ROOT. Don't return without unbecome_root(). */
1565 switch (r->in.level) {
1568 if (dinfo->disp_info->users == NULL) {
1569 dinfo->disp_info->users = pdb_search_users(
1570 dinfo->disp_info, ACB_NORMAL);
1571 if (dinfo->disp_info->users == NULL) {
1573 return NT_STATUS_ACCESS_DENIED;
1575 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1576 (unsigned int)enum_context ));
1578 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1579 (unsigned int)enum_context ));
1582 num_account = pdb_search_entries(dinfo->disp_info->users,
1583 enum_context, max_entries,
1587 if (dinfo->disp_info->machines == NULL) {
1588 dinfo->disp_info->machines = pdb_search_users(
1589 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1590 if (dinfo->disp_info->machines == NULL) {
1592 return NT_STATUS_ACCESS_DENIED;
1594 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1595 (unsigned int)enum_context ));
1597 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1598 (unsigned int)enum_context ));
1601 num_account = pdb_search_entries(dinfo->disp_info->machines,
1602 enum_context, max_entries,
1607 if (dinfo->disp_info->groups == NULL) {
1608 dinfo->disp_info->groups = pdb_search_groups(
1610 if (dinfo->disp_info->groups == NULL) {
1612 return NT_STATUS_ACCESS_DENIED;
1614 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1615 (unsigned int)enum_context ));
1617 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1618 (unsigned int)enum_context ));
1621 num_account = pdb_search_entries(dinfo->disp_info->groups,
1622 enum_context, max_entries,
1627 smb_panic("info class changed");
1633 /* Now create reply structure */
1634 switch (r->in.level) {
1636 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1637 num_account, enum_context,
1641 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1642 num_account, enum_context,
1646 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1647 num_account, enum_context,
1651 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1652 num_account, enum_context,
1656 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1657 num_account, enum_context,
1661 smb_panic("info class changed");
1665 if (!NT_STATUS_IS_OK(disp_ret))
1668 /* calculate the total size */
1669 total_data_size=num_account*struct_size;
1671 if (max_entries <= num_account) {
1672 status = STATUS_MORE_ENTRIES;
1674 status = NT_STATUS_OK;
1677 /* Ensure we cache this enumeration. */
1678 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1680 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1682 *r->out.total_size = total_data_size;
1683 *r->out.returned_size = temp_size;
1688 /****************************************************************
1689 _samr_QueryDisplayInfo2
1690 ****************************************************************/
1692 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1693 struct samr_QueryDisplayInfo2 *r)
1695 struct samr_QueryDisplayInfo q;
1697 q.in.domain_handle = r->in.domain_handle;
1698 q.in.level = r->in.level;
1699 q.in.start_idx = r->in.start_idx;
1700 q.in.max_entries = r->in.max_entries;
1701 q.in.buf_size = r->in.buf_size;
1703 q.out.total_size = r->out.total_size;
1704 q.out.returned_size = r->out.returned_size;
1705 q.out.info = r->out.info;
1707 return _samr_QueryDisplayInfo(p, &q);
1710 /****************************************************************
1711 _samr_QueryDisplayInfo3
1712 ****************************************************************/
1714 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1715 struct samr_QueryDisplayInfo3 *r)
1717 struct samr_QueryDisplayInfo q;
1719 q.in.domain_handle = r->in.domain_handle;
1720 q.in.level = r->in.level;
1721 q.in.start_idx = r->in.start_idx;
1722 q.in.max_entries = r->in.max_entries;
1723 q.in.buf_size = r->in.buf_size;
1725 q.out.total_size = r->out.total_size;
1726 q.out.returned_size = r->out.returned_size;
1727 q.out.info = r->out.info;
1729 return _samr_QueryDisplayInfo(p, &q);
1732 /*******************************************************************
1733 _samr_QueryAliasInfo
1734 ********************************************************************/
1736 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1737 struct samr_QueryAliasInfo *r)
1739 struct samr_alias_info *ainfo;
1740 struct acct_info info;
1742 union samr_AliasInfo *alias_info = NULL;
1743 const char *alias_name = NULL;
1744 const char *alias_description = NULL;
1746 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1748 ainfo = policy_handle_find(p, r->in.alias_handle,
1749 SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1750 struct samr_alias_info, &status);
1751 if (!NT_STATUS_IS_OK(status)) {
1755 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1757 return NT_STATUS_NO_MEMORY;
1761 status = pdb_get_aliasinfo(&ainfo->sid, &info);
1764 if ( !NT_STATUS_IS_OK(status))
1767 /* FIXME: info contains fstrings */
1768 alias_name = talloc_strdup(r, info.acct_name);
1769 alias_description = talloc_strdup(r, info.acct_desc);
1771 switch (r->in.level) {
1773 alias_info->all.name.string = alias_name;
1774 alias_info->all.num_members = 1; /* ??? */
1775 alias_info->all.description.string = alias_description;
1777 case ALIASINFODESCRIPTION:
1778 alias_info->description.string = alias_description;
1781 return NT_STATUS_INVALID_INFO_CLASS;
1784 *r->out.info = alias_info;
1786 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1788 return NT_STATUS_OK;
1791 /*******************************************************************
1793 ********************************************************************/
1795 NTSTATUS _samr_LookupNames(pipes_struct *p,
1796 struct samr_LookupNames *r)
1798 struct samr_domain_info *dinfo;
1801 enum lsa_SidType *type;
1803 int num_rids = r->in.num_names;
1804 struct samr_Ids rids, types;
1805 uint32_t num_mapped = 0;
1807 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1809 dinfo = policy_handle_find(p, r->in.domain_handle,
1810 0 /* Don't know the acc_bits yet */, NULL,
1811 struct samr_domain_info, &status);
1812 if (!NT_STATUS_IS_OK(status)) {
1816 if (num_rids > MAX_SAM_ENTRIES) {
1817 num_rids = MAX_SAM_ENTRIES;
1818 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1821 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1822 NT_STATUS_HAVE_NO_MEMORY(rid);
1824 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1825 NT_STATUS_HAVE_NO_MEMORY(type);
1827 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1828 sid_string_dbg(&dinfo->sid)));
1830 for (i = 0; i < num_rids; i++) {
1832 status = NT_STATUS_NONE_MAPPED;
1833 type[i] = SID_NAME_UNKNOWN;
1835 rid[i] = 0xffffffff;
1837 if (sid_check_is_builtin(&dinfo->sid)) {
1838 if (lookup_builtin_name(r->in.names[i].string,
1841 type[i] = SID_NAME_ALIAS;
1844 lookup_global_sam_name(r->in.names[i].string, 0,
1848 if (type[i] != SID_NAME_UNKNOWN) {
1853 if (num_mapped == num_rids) {
1854 status = NT_STATUS_OK;
1855 } else if (num_mapped == 0) {
1856 status = NT_STATUS_NONE_MAPPED;
1858 status = STATUS_SOME_UNMAPPED;
1861 rids.count = num_rids;
1864 types.count = num_rids;
1867 *r->out.rids = rids;
1868 *r->out.types = types;
1870 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1875 /*******************************************************************
1876 _samr_ChangePasswordUser2
1877 ********************************************************************/
1879 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1880 struct samr_ChangePasswordUser2 *r)
1886 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1888 fstrcpy(user_name, r->in.account->string);
1889 fstrcpy(wks, r->in.server->string);
1891 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1894 * Pass the user through the NT -> unix user mapping
1898 (void)map_username(user_name);
1901 * UNIX username case mangling not required, pass_oem_change
1902 * is case insensitive.
1905 status = pass_oem_change(user_name,
1906 r->in.lm_password->data,
1907 r->in.lm_verifier->hash,
1908 r->in.nt_password->data,
1909 r->in.nt_verifier->hash,
1912 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1917 /*******************************************************************
1918 _samr_ChangePasswordUser3
1919 ********************************************************************/
1921 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1922 struct samr_ChangePasswordUser3 *r)
1926 const char *wks = NULL;
1927 uint32 reject_reason;
1928 struct samr_DomInfo1 *dominfo = NULL;
1929 struct samr_ChangeReject *reject = NULL;
1932 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1934 fstrcpy(user_name, r->in.account->string);
1935 if (r->in.server && r->in.server->string) {
1936 wks = r->in.server->string;
1939 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1942 * Pass the user through the NT -> unix user mapping
1946 (void)map_username(user_name);
1949 * UNIX username case mangling not required, pass_oem_change
1950 * is case insensitive.
1953 status = pass_oem_change(user_name,
1954 r->in.lm_password->data,
1955 r->in.lm_verifier->hash,
1956 r->in.nt_password->data,
1957 r->in.nt_verifier->hash,
1960 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1961 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1963 time_t u_expire, u_min_age;
1964 uint32 account_policy_temp;
1966 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1968 return NT_STATUS_NO_MEMORY;
1971 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1973 return NT_STATUS_NO_MEMORY;
1980 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
1981 dominfo->min_password_length = tmp;
1983 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
1984 dominfo->password_history_length = tmp;
1986 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
1987 &dominfo->password_properties);
1989 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1990 u_expire = account_policy_temp;
1992 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1993 u_min_age = account_policy_temp;
1999 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2000 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2002 if (lp_check_password_script() && *lp_check_password_script()) {
2003 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2006 reject->reason = reject_reason;
2008 *r->out.dominfo = dominfo;
2009 *r->out.reject = reject;
2012 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2017 /*******************************************************************
2018 makes a SAMR_R_LOOKUP_RIDS structure.
2019 ********************************************************************/
2021 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2023 struct lsa_String **lsa_name_array_p)
2025 struct lsa_String *lsa_name_array = NULL;
2028 *lsa_name_array_p = NULL;
2030 if (num_names != 0) {
2031 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2032 if (!lsa_name_array) {
2037 for (i = 0; i < num_names; i++) {
2038 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2039 init_lsa_String(&lsa_name_array[i], names[i]);
2042 *lsa_name_array_p = lsa_name_array;
2047 /*******************************************************************
2049 ********************************************************************/
2051 NTSTATUS _samr_LookupRids(pipes_struct *p,
2052 struct samr_LookupRids *r)
2054 struct samr_domain_info *dinfo;
2057 enum lsa_SidType *attrs = NULL;
2058 uint32 *wire_attrs = NULL;
2059 int num_rids = (int)r->in.num_rids;
2061 struct lsa_Strings names_array;
2062 struct samr_Ids types_array;
2063 struct lsa_String *lsa_names = NULL;
2065 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2067 dinfo = policy_handle_find(p, r->in.domain_handle,
2068 0 /* Don't know the acc_bits yet */, NULL,
2069 struct samr_domain_info, &status);
2070 if (!NT_STATUS_IS_OK(status)) {
2074 if (num_rids > 1000) {
2075 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2076 "to samba4 idl this is not possible\n", num_rids));
2077 return NT_STATUS_UNSUCCESSFUL;
2081 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2082 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2083 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2085 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2086 return NT_STATUS_NO_MEMORY;
2093 become_root(); /* lookup_sid can require root privs */
2094 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2098 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2099 status = NT_STATUS_OK;
2102 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2104 return NT_STATUS_NO_MEMORY;
2107 /* Convert from enum lsa_SidType to uint32 for wire format. */
2108 for (i = 0; i < num_rids; i++) {
2109 wire_attrs[i] = (uint32)attrs[i];
2112 names_array.count = num_rids;
2113 names_array.names = lsa_names;
2115 types_array.count = num_rids;
2116 types_array.ids = wire_attrs;
2118 *r->out.names = names_array;
2119 *r->out.types = types_array;
2121 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2126 /*******************************************************************
2128 ********************************************************************/
2130 NTSTATUS _samr_OpenUser(pipes_struct *p,
2131 struct samr_OpenUser *r)
2133 struct samu *sampass=NULL;
2135 struct samr_domain_info *dinfo;
2136 struct samr_user_info *uinfo;
2137 SEC_DESC *psd = NULL;
2139 uint32 des_access = r->in.access_mask;
2146 dinfo = policy_handle_find(p, r->in.domain_handle,
2147 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2148 struct samr_domain_info, &status);
2149 if (!NT_STATUS_IS_OK(status)) {
2153 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2154 return NT_STATUS_NO_MEMORY;
2157 /* append the user's RID to it */
2159 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2160 return NT_STATUS_NO_SUCH_USER;
2162 /* check if access can be granted as requested by client. */
2164 map_max_allowed_access(p->server_info->ptok, &des_access);
2166 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2167 se_map_generic(&des_access, &usr_generic_mapping);
2169 se_priv_copy( &se_rights, &se_machine_account );
2170 se_priv_add( &se_rights, &se_add_users );
2172 nt_status = access_check_samr_object(psd, p->server_info->ptok,
2173 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2174 &acc_granted, "_samr_OpenUser");
2176 if ( !NT_STATUS_IS_OK(nt_status) )
2180 ret=pdb_getsampwsid(sampass, &sid);
2183 /* check that the SID exists in our domain. */
2185 return NT_STATUS_NO_SUCH_USER;
2188 TALLOC_FREE(sampass);
2190 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2191 struct samr_user_info, &nt_status);
2192 if (!NT_STATUS_IS_OK(nt_status)) {
2197 return NT_STATUS_OK;
2200 /*************************************************************************
2201 *************************************************************************/
2203 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2205 struct lsa_BinaryString **_r)
2207 struct lsa_BinaryString *r;
2210 return NT_STATUS_INVALID_PARAMETER;
2213 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2215 return NT_STATUS_NO_MEMORY;
2218 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2220 return NT_STATUS_NO_MEMORY;
2222 memcpy(r->array, blob->data, blob->length);
2223 r->size = blob->length;
2224 r->length = blob->length;
2227 return NT_STATUS_NO_MEMORY;
2232 return NT_STATUS_OK;
2235 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2236 struct samr_UserInfo5 *r,
2238 DOM_SID *domain_sid)
2240 const DOM_SID *sid_user, *sid_group;
2241 uint32_t rid, primary_gid;
2243 sid_user = pdb_get_user_sid(pw);
2245 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2246 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2247 "the domain sid %s. Failing operation.\n",
2248 pdb_get_username(pw), sid_string_dbg(sid_user),
2249 sid_string_dbg(domain_sid)));
2250 return NT_STATUS_UNSUCCESSFUL;
2254 sid_group = pdb_get_group_sid(pw);
2257 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2258 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2259 "which conflicts with the domain sid %s. Failing operation.\n",
2260 pdb_get_username(pw), sid_string_dbg(sid_group),
2261 sid_string_dbg(domain_sid)));
2262 return NT_STATUS_UNSUCCESSFUL;
2265 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2266 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2267 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2268 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2270 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2271 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2272 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2273 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2274 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2275 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2276 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2277 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2279 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2281 r->primary_gid = primary_gid;
2282 r->acct_flags = pdb_get_acct_ctrl(pw);
2283 r->bad_password_count = pdb_get_bad_password_count(pw);
2284 r->logon_count = pdb_get_logon_count(pw);
2286 return NT_STATUS_OK;
2289 /*************************************************************************
2290 get_user_info_7. Safe. Only gives out account_name.
2291 *************************************************************************/
2293 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2294 struct samr_UserInfo7 *r,
2295 struct samu *smbpass)
2297 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2298 if (!r->account_name.string) {
2299 return NT_STATUS_NO_MEMORY;
2302 return NT_STATUS_OK;
2305 /*************************************************************************
2306 get_user_info_9. Only gives out primary group SID.
2307 *************************************************************************/
2309 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2310 struct samr_UserInfo9 *r,
2311 struct samu *smbpass)
2313 r->primary_gid = pdb_get_group_rid(smbpass);
2315 return NT_STATUS_OK;
2318 /*************************************************************************
2319 get_user_info_16. Safe. Only gives out acb bits.
2320 *************************************************************************/
2322 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2323 struct samr_UserInfo16 *r,
2324 struct samu *smbpass)
2326 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2328 return NT_STATUS_OK;
2331 /*************************************************************************
2332 get_user_info_18. OK - this is the killer as it gives out password info.
2333 Ensure that this is only allowed on an encrypted connection with a root
2335 *************************************************************************/
2337 static NTSTATUS get_user_info_18(pipes_struct *p,
2338 TALLOC_CTX *mem_ctx,
2339 struct samr_UserInfo18 *r,
2342 struct samu *smbpass=NULL;
2347 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2348 return NT_STATUS_ACCESS_DENIED;
2351 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2352 return NT_STATUS_ACCESS_DENIED;
2356 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2359 if ( !(smbpass = samu_new( mem_ctx )) ) {
2360 return NT_STATUS_NO_MEMORY;
2363 ret = pdb_getsampwsid(smbpass, user_sid);
2366 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2367 TALLOC_FREE(smbpass);
2368 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2371 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2373 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2374 TALLOC_FREE(smbpass);
2375 return NT_STATUS_ACCOUNT_DISABLED;
2378 r->lm_pwd_active = true;
2379 r->nt_pwd_active = true;
2380 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2381 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2382 r->password_expired = 0; /* FIXME */
2384 TALLOC_FREE(smbpass);
2386 return NT_STATUS_OK;
2389 /*************************************************************************
2391 *************************************************************************/
2393 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2394 struct samr_UserInfo20 *r,
2395 struct samu *sampass)
2397 const char *munged_dial = NULL;
2400 struct lsa_BinaryString *parameters = NULL;
2404 munged_dial = pdb_get_munged_dial(sampass);
2406 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2407 munged_dial, (int)strlen(munged_dial)));
2410 blob = base64_decode_data_blob(munged_dial);
2412 blob = data_blob_string_const_null("");
2415 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2416 data_blob_free(&blob);
2417 if (!NT_STATUS_IS_OK(status)) {
2421 r->parameters = *parameters;
2423 return NT_STATUS_OK;
2427 /*************************************************************************
2429 *************************************************************************/
2431 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2432 struct samr_UserInfo21 *r,
2434 DOM_SID *domain_sid)
2437 const DOM_SID *sid_user, *sid_group;
2438 uint32_t rid, primary_gid;
2439 NTTIME force_password_change;
2440 time_t must_change_time;
2441 struct lsa_BinaryString *parameters = NULL;
2442 const char *munged_dial = NULL;
2447 sid_user = pdb_get_user_sid(pw);
2449 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2450 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2451 "the domain sid %s. Failing operation.\n",
2452 pdb_get_username(pw), sid_string_dbg(sid_user),
2453 sid_string_dbg(domain_sid)));
2454 return NT_STATUS_UNSUCCESSFUL;
2458 sid_group = pdb_get_group_sid(pw);
2461 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2462 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2463 "which conflicts with the domain sid %s. Failing operation.\n",
2464 pdb_get_username(pw), sid_string_dbg(sid_group),
2465 sid_string_dbg(domain_sid)));
2466 return NT_STATUS_UNSUCCESSFUL;
2469 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2470 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2471 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2472 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2473 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2475 must_change_time = pdb_get_pass_must_change_time(pw);
2476 if (must_change_time == get_time_t_max()) {
2477 unix_to_nt_time_abs(&force_password_change, must_change_time);
2479 unix_to_nt_time(&force_password_change, must_change_time);
2482 munged_dial = pdb_get_munged_dial(pw);
2484 blob = base64_decode_data_blob(munged_dial);
2486 blob = data_blob_string_const_null("");
2489 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2490 data_blob_free(&blob);
2491 if (!NT_STATUS_IS_OK(status)) {
2495 r->force_password_change = force_password_change;
2497 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2498 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2499 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2500 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2501 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2502 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2503 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2504 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2505 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2507 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2508 r->parameters = *parameters;
2510 r->primary_gid = primary_gid;
2511 r->acct_flags = pdb_get_acct_ctrl(pw);
2512 r->bad_password_count = pdb_get_bad_password_count(pw);
2513 r->logon_count = pdb_get_logon_count(pw);
2514 r->fields_present = pdb_build_fields_present(pw);
2515 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2516 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2517 r->country_code = 0;
2519 r->lm_password_set = 0;
2520 r->nt_password_set = 0;
2525 Look at a user on a real NT4 PDC with usrmgr, press
2526 'ok'. Then you will see that fields_present is set to
2527 0x08f827fa. Look at the user immediately after that again,
2528 and you will see that 0x00fffff is returned. This solves
2529 the problem that you get access denied after having looked
2537 return NT_STATUS_OK;
2540 /*******************************************************************
2542 ********************************************************************/
2544 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2545 struct samr_QueryUserInfo *r)
2548 union samr_UserInfo *user_info = NULL;
2549 struct samr_user_info *uinfo;
2553 struct samu *pwd = NULL;
2555 uinfo = policy_handle_find(p, r->in.user_handle,
2556 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
2557 struct samr_user_info, &status);
2558 if (!NT_STATUS_IS_OK(status)) {
2562 domain_sid = uinfo->sid;
2564 sid_split_rid(&domain_sid, &rid);
2566 if (!sid_check_is_in_our_domain(&uinfo->sid))
2567 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2569 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2570 sid_string_dbg(&uinfo->sid)));
2572 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2574 return NT_STATUS_NO_MEMORY;
2577 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2579 if (!(pwd = samu_new(p->mem_ctx))) {
2580 return NT_STATUS_NO_MEMORY;
2584 ret = pdb_getsampwsid(pwd, &uinfo->sid);
2588 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
2590 return NT_STATUS_NO_SUCH_USER;
2593 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2595 samr_clear_sam_passwd(pwd);
2597 switch (r->in.level) {
2599 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2602 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2605 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2608 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2611 /* level 18 is special */
2612 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
2616 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
2619 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
2622 status = NT_STATUS_INVALID_INFO_CLASS;
2628 *r->out.info = user_info;
2630 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2635 /****************************************************************
2636 ****************************************************************/
2638 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2639 struct samr_QueryUserInfo2 *r)
2641 struct samr_QueryUserInfo u;
2643 u.in.user_handle = r->in.user_handle;
2644 u.in.level = r->in.level;
2645 u.out.info = r->out.info;
2647 return _samr_QueryUserInfo(p, &u);
2650 /*******************************************************************
2651 _samr_GetGroupsForUser
2652 ********************************************************************/
2654 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2655 struct samr_GetGroupsForUser *r)
2657 struct samr_user_info *uinfo;
2658 struct samu *sam_pass=NULL;
2660 struct samr_RidWithAttribute dom_gid;
2661 struct samr_RidWithAttribute *gids = NULL;
2662 uint32 primary_group_rid;
2663 size_t num_groups = 0;
2668 bool success = False;
2670 struct samr_RidWithAttributeArray *rids = NULL;
2673 * from the SID in the request:
2674 * we should send back the list of DOMAIN GROUPS
2675 * the user is a member of
2677 * and only the DOMAIN GROUPS
2678 * no ALIASES !!! neither aliases of the domain
2679 * nor aliases of the builtin SID
2684 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2686 uinfo = policy_handle_find(p, r->in.user_handle,
2687 SAMR_USER_ACCESS_GET_GROUPS, NULL,
2688 struct samr_user_info, &result);
2689 if (!NT_STATUS_IS_OK(result)) {
2693 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2695 return NT_STATUS_NO_MEMORY;
2698 if (!sid_check_is_in_our_domain(&uinfo->sid))
2699 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2701 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2702 return NT_STATUS_NO_MEMORY;
2706 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
2710 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2711 sid_string_dbg(&uinfo->sid)));
2712 return NT_STATUS_NO_SUCH_USER;
2717 /* make both calls inside the root block */
2719 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2720 &sids, &unix_gids, &num_groups);
2721 if ( NT_STATUS_IS_OK(result) ) {
2722 success = sid_peek_check_rid(get_global_sam_sid(),
2723 pdb_get_group_sid(sam_pass),
2724 &primary_group_rid);
2728 if (!NT_STATUS_IS_OK(result)) {
2729 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2730 sid_string_dbg(&uinfo->sid)));
2735 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2736 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2737 pdb_get_username(sam_pass)));
2738 TALLOC_FREE(sam_pass);
2739 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2745 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2747 dom_gid.rid = primary_group_rid;
2748 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2750 for (i=0; i<num_groups; i++) {
2752 if (!sid_peek_check_rid(get_global_sam_sid(),
2753 &(sids[i]), &dom_gid.rid)) {
2754 DEBUG(10, ("Found sid %s not in our domain\n",
2755 sid_string_dbg(&sids[i])));
2759 if (dom_gid.rid == primary_group_rid) {
2760 /* We added the primary group directly from the
2761 * sam_account. The other SIDs are unique from
2762 * enum_group_memberships */
2766 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2769 rids->count = num_gids;
2772 *r->out.rids = rids;
2774 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2779 /*******************************************************************
2780 _samr_QueryDomainInfo
2781 ********************************************************************/
2783 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2784 struct samr_QueryDomainInfo *r)
2786 NTSTATUS status = NT_STATUS_OK;
2787 struct samr_domain_info *dinfo;
2788 union samr_DomainInfo *dom_info;
2789 time_t u_expire, u_min_age;
2791 time_t u_lock_duration, u_reset_time;
2794 uint32 account_policy_temp;
2799 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2801 dinfo = policy_handle_find(p, r->in.domain_handle,
2802 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
2803 struct samr_domain_info, &status);
2804 if (!NT_STATUS_IS_OK(status)) {
2808 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2810 return NT_STATUS_NO_MEMORY;
2813 switch (r->in.level) {
2820 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
2821 &account_policy_temp);
2822 dom_info->info1.min_password_length = account_policy_temp;
2824 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2825 dom_info->info1.password_history_length = account_policy_temp;
2827 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2828 &dom_info->info1.password_properties);
2830 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2831 u_expire = account_policy_temp;
2833 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2834 u_min_age = account_policy_temp;
2840 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
2841 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
2843 if (lp_check_password_script() && *lp_check_password_script()) {
2844 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
2854 dom_info->general.num_users = count_sam_users(
2855 dinfo->disp_info, ACB_NORMAL);
2856 dom_info->general.num_groups = count_sam_groups(
2858 dom_info->general.num_aliases = count_sam_aliases(
2861 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
2863 unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
2865 if (!pdb_get_seq_num(&seq_num))
2866 seq_num = time(NULL);
2872 server_role = ROLE_DOMAIN_PDC;
2873 if (lp_server_role() == ROLE_DOMAIN_BDC)
2874 server_role = ROLE_DOMAIN_BDC;
2876 dom_info->general.oem_information.string = lp_serverstring();
2877 dom_info->general.domain_name.string = lp_workgroup();
2878 dom_info->general.primary.string = global_myname();
2879 dom_info->general.sequence_num = seq_num;
2880 dom_info->general.domain_server_state = DOMAIN_SERVER_ENABLED;
2881 dom_info->general.role = server_role;
2882 dom_info->general.unknown3 = 1;
2893 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2894 u_logout = (time_t)ul;
2901 unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
2905 dom_info->oem.oem_information.string = lp_serverstring();
2908 dom_info->info5.domain_name.string = get_global_sam_name();
2911 /* NT returns its own name when a PDC. win2k and later
2912 * only the name of the PDC if itself is a BDC (samba4
2914 dom_info->info6.primary.string = global_myname();
2917 server_role = ROLE_DOMAIN_PDC;
2918 if (lp_server_role() == ROLE_DOMAIN_BDC)
2919 server_role = ROLE_DOMAIN_BDC;
2921 dom_info->info7.role = server_role;
2929 if (!pdb_get_seq_num(&seq_num)) {
2930 seq_num = time(NULL);
2937 dom_info->info8.sequence_num = seq_num;
2938 dom_info->info8.domain_create_time = 0;
2947 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2948 u_lock_duration = account_policy_temp;
2949 if (u_lock_duration != -1) {
2950 u_lock_duration *= 60;
2953 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2954 u_reset_time = account_policy_temp * 60;
2956 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
2957 &account_policy_temp);
2958 dom_info->info12.lockout_threshold = account_policy_temp;
2964 unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
2966 unix_to_nt_time_abs(&dom_info->info12.lockout_window,
2971 return NT_STATUS_INVALID_INFO_CLASS;
2974 *r->out.info = dom_info;
2976 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2981 /* W2k3 seems to use the same check for all 3 objects that can be created via
2982 * SAMR, if you try to create for example "Dialup" as an alias it says
2983 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
2986 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
2988 enum lsa_SidType type;
2991 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
2994 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
2995 * whether the name already exists */
2996 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
2997 NULL, NULL, NULL, &type);
3001 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3002 return NT_STATUS_OK;
3005 DEBUG(5, ("trying to create %s, exists as %s\n",
3006 new_name, sid_type_lookup(type)));
3008 if (type == SID_NAME_DOM_GRP) {
3009 return NT_STATUS_GROUP_EXISTS;
3011 if (type == SID_NAME_ALIAS) {
3012 return NT_STATUS_ALIAS_EXISTS;
3015 /* Yes, the default is NT_STATUS_USER_EXISTS */
3016 return NT_STATUS_USER_EXISTS;
3019 /*******************************************************************
3021 ********************************************************************/
3023 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3024 struct samr_CreateUser2 *r)
3026 const char *account = NULL;
3028 uint32_t acb_info = r->in.acct_flags;
3029 struct samr_domain_info *dinfo;
3030 struct samr_user_info *uinfo;
3035 /* check this, when giving away 'add computer to domain' privs */
3036 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3037 bool can_add_account = False;
3040 dinfo = policy_handle_find(p, r->in.domain_handle,
3041 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3042 struct samr_domain_info, &nt_status);
3043 if (!NT_STATUS_IS_OK(nt_status)) {
3047 if (sid_check_is_builtin(&dinfo->sid)) {
3048 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3049 return NT_STATUS_ACCESS_DENIED;
3052 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3053 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3054 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3055 this parameter is not an account type */
3056 return NT_STATUS_INVALID_PARAMETER;
3059 account = r->in.account_name->string;
3060 if (account == NULL) {
3061 return NT_STATUS_NO_MEMORY;
3064 nt_status = can_create(p->mem_ctx, account);
3065 if (!NT_STATUS_IS_OK(nt_status)) {
3069 /* determine which user right we need to check based on the acb_info */
3071 if ( acb_info & ACB_WSTRUST )
3073 se_priv_copy( &se_rights, &se_machine_account );
3074 can_add_account = user_has_privileges(
3075 p->server_info->ptok, &se_rights );
3077 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3078 account for domain trusts and changes the ACB flags later */
3079 else if ( acb_info & ACB_NORMAL &&
3080 (account[strlen(account)-1] != '$') )
3082 se_priv_copy( &se_rights, &se_add_users );
3083 can_add_account = user_has_privileges(
3084 p->server_info->ptok, &se_rights );
3086 else /* implicit assumption of a BDC or domain trust account here
3087 * (we already check the flags earlier) */
3089 if ( lp_enable_privileges() ) {
3090 /* only Domain Admins can add a BDC or domain trust */
3091 se_priv_copy( &se_rights, &se_priv_none );
3092 can_add_account = nt_token_check_domain_rid(
3093 p->server_info->ptok,
3094 DOMAIN_GROUP_RID_ADMINS );
3098 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3099 uidtoname(p->server_info->utok.uid),
3100 can_add_account ? "True":"False" ));
3102 /********** BEGIN Admin BLOCK **********/
3104 if ( can_add_account )
3107 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3110 if ( can_add_account )
3113 /********** END Admin BLOCK **********/
3115 /* now check for failure */
3117 if ( !NT_STATUS_IS_OK(nt_status) )
3120 /* Get the user's SID */
3122 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3124 map_max_allowed_access(p->server_info->ptok, &des_access);
3126 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3127 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3128 se_map_generic(&des_access, &usr_generic_mapping);
3130 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3131 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3132 &acc_granted, "_samr_CreateUser2");
3134 if ( !NT_STATUS_IS_OK(nt_status) ) {
3138 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3139 struct samr_user_info, &nt_status);
3140 if (!NT_STATUS_IS_OK(nt_status)) {
3145 /* After a "set" ensure we have no cached display info. */
3146 force_flush_samr_cache(&sid);
3148 *r->out.access_granted = acc_granted;
3150 return NT_STATUS_OK;
3153 /****************************************************************
3154 ****************************************************************/
3156 NTSTATUS _samr_CreateUser(pipes_struct *p,
3157 struct samr_CreateUser *r)
3159 struct samr_CreateUser2 c;
3160 uint32_t access_granted;
3162 c.in.domain_handle = r->in.domain_handle;
3163 c.in.account_name = r->in.account_name;
3164 c.in.acct_flags = ACB_NORMAL;
3165 c.in.access_mask = r->in.access_mask;
3166 c.out.user_handle = r->out.user_handle;
3167 c.out.access_granted = &access_granted;
3168 c.out.rid = r->out.rid;
3170 return _samr_CreateUser2(p, &c);
3173 /*******************************************************************
3175 ********************************************************************/
3177 NTSTATUS _samr_Connect(pipes_struct *p,
3178 struct samr_Connect *r)
3180 struct samr_connect_info *info;
3181 uint32_t acc_granted;
3182 struct policy_handle hnd;
3183 uint32 des_access = r->in.access_mask;
3188 if (!pipe_access_check(p)) {
3189 DEBUG(3, ("access denied to _samr_Connect\n"));
3190 return NT_STATUS_ACCESS_DENIED;
3193 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3194 was observed from a win98 client trying to enumerate users (when configured
3195 user level access control on shares) --jerry */
3197 map_max_allowed_access(p->server_info->ptok, &des_access);
3199 se_map_generic( &des_access, &sam_generic_mapping );
3201 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3202 |SAMR_ACCESS_LOOKUP_DOMAIN);
3204 /* set up the SAMR connect_anon response */
3206 info = policy_handle_create(p, &hnd, acc_granted,
3207 struct samr_connect_info,
3209 if (!NT_STATUS_IS_OK(status)) {
3213 *r->out.connect_handle = hnd;
3214 return NT_STATUS_OK;
3217 /*******************************************************************
3219 ********************************************************************/
3221 NTSTATUS _samr_Connect2(pipes_struct *p,
3222 struct samr_Connect2 *r)
3224 struct samr_connect_info *info = NULL;
3225 struct policy_handle hnd;
3226 SEC_DESC *psd = NULL;
3228 uint32 des_access = r->in.access_mask;
3231 const char *fn = "_samr_Connect2";
3233 switch (p->hdr_req.opnum) {
3234 case NDR_SAMR_CONNECT2:
3235 fn = "_samr_Connect2";
3237 case NDR_SAMR_CONNECT3:
3238 fn = "_samr_Connect3";
3240 case NDR_SAMR_CONNECT4:
3241 fn = "_samr_Connect4";
3243 case NDR_SAMR_CONNECT5:
3244 fn = "_samr_Connect5";
3248 DEBUG(5,("%s: %d\n", fn, __LINE__));
3252 if (!pipe_access_check(p)) {
3253 DEBUG(3, ("access denied to %s\n", fn));
3254 return NT_STATUS_ACCESS_DENIED;
3257 map_max_allowed_access(p->server_info->ptok, &des_access);
3259 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3260 se_map_generic(&des_access, &sam_generic_mapping);
3262 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3263 NULL, 0, des_access, &acc_granted, fn);
3265 if ( !NT_STATUS_IS_OK(nt_status) )
3268 info = policy_handle_create(p, &hnd, acc_granted,
3269 struct samr_connect_info, &nt_status);
3270 if (!NT_STATUS_IS_OK(nt_status)) {
3274 DEBUG(5,("%s: %d\n", fn, __LINE__));
3276 *r->out.connect_handle = hnd;
3277 return NT_STATUS_OK;
3280 /****************************************************************
3282 ****************************************************************/
3284 NTSTATUS _samr_Connect3(pipes_struct *p,
3285 struct samr_Connect3 *r)
3287 struct samr_Connect2 c;
3289 c.in.system_name = r->in.system_name;
3290 c.in.access_mask = r->in.access_mask;
3291 c.out.connect_handle = r->out.connect_handle;
3293 return _samr_Connect2(p, &c);
3296 /*******************************************************************
3298 ********************************************************************/
3300 NTSTATUS _samr_Connect4(pipes_struct *p,
3301 struct samr_Connect4 *r)
3303 struct samr_Connect2 c;
3305 c.in.system_name = r->in.system_name;
3306 c.in.access_mask = r->in.access_mask;
3307 c.out.connect_handle = r->out.connect_handle;
3309 return _samr_Connect2(p, &c);
3312 /*******************************************************************
3314 ********************************************************************/
3316 NTSTATUS _samr_Connect5(pipes_struct *p,
3317 struct samr_Connect5 *r)
3320 struct samr_Connect2 c;
3321 struct samr_ConnectInfo1 info1;
3323 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3326 c.in.system_name = r->in.system_name;
3327 c.in.access_mask = r->in.access_mask;
3328 c.out.connect_handle = r->out.connect_handle;
3330 status = _samr_Connect2(p, &c);
3331 if (!NT_STATUS_IS_OK(status)) {
3335 *r->out.level_out = 1;
3336 r->out.info_out->info1 = info1;
3338 return NT_STATUS_OK;
3341 /**********************************************************************
3343 **********************************************************************/
3345 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3346 struct samr_LookupDomain *r)
3349 struct samr_connect_info *info;
3350 const char *domain_name;
3351 DOM_SID *sid = NULL;
3353 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3354 Reverted that change so we will work with RAS servers again */
3356 info = policy_handle_find(p, r->in.connect_handle,
3357 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3358 struct samr_connect_info,
3360 if (!NT_STATUS_IS_OK(status)) {
3364 domain_name = r->in.domain_name->string;
3366 return NT_STATUS_INVALID_PARAMETER;
3369 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3371 return NT_STATUS_NO_MEMORY;
3374 if (strequal(domain_name, builtin_domain_name())) {
3375 sid_copy(sid, &global_sid_Builtin);
3377 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3378 status = NT_STATUS_NO_SUCH_DOMAIN;
3382 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3383 sid_string_dbg(sid)));
3390 /**********************************************************************
3392 **********************************************************************/
3394 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3395 struct samr_EnumDomains *r)
3398 struct samr_connect_info *info;
3399 uint32_t num_entries = 2;
3400 struct samr_SamEntry *entry_array = NULL;
3401 struct samr_SamArray *sam;
3403 info = policy_handle_find(p, r->in.connect_handle,
3404 SAMR_ACCESS_ENUM_DOMAINS, NULL,
3405 struct samr_connect_info, &status);
3406 if (!NT_STATUS_IS_OK(status)) {
3410 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3412 return NT_STATUS_NO_MEMORY;
3415 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3416 struct samr_SamEntry,
3419 return NT_STATUS_NO_MEMORY;
3422 entry_array[0].idx = 0;
3423 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3425 entry_array[1].idx = 1;
3426 init_lsa_String(&entry_array[1].name, "Builtin");
3428 sam->count = num_entries;
3429 sam->entries = entry_array;
3432 *r->out.num_entries = num_entries;
3437 /*******************************************************************
3439 ********************************************************************/
3441 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3442 struct samr_OpenAlias *r)
3445 uint32 alias_rid = r->in.rid;
3446 struct samr_alias_info *ainfo;
3447 struct samr_domain_info *dinfo;
3448 SEC_DESC *psd = NULL;
3450 uint32 des_access = r->in.access_mask;
3455 dinfo = policy_handle_find(p, r->in.domain_handle,
3456 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
3457 struct samr_domain_info, &status);
3458 if (!NT_STATUS_IS_OK(status)) {
3462 /* append the alias' RID to it */
3464 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
3465 return NT_STATUS_NO_SUCH_ALIAS;
3467 /*check if access can be granted as requested by client. */
3469 map_max_allowed_access(p->server_info->ptok, &des_access);
3471 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3472 se_map_generic(&des_access,&ali_generic_mapping);
3474 se_priv_copy( &se_rights, &se_add_users );
3477 status = access_check_samr_object(psd, p->server_info->ptok,
3478 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3479 &acc_granted, "_samr_OpenAlias");
3481 if ( !NT_STATUS_IS_OK(status) )
3485 /* Check we actually have the requested alias */
3486 enum lsa_SidType type;
3491 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3494 if (!result || (type != SID_NAME_ALIAS)) {
3495 return NT_STATUS_NO_SUCH_ALIAS;
3498 /* make sure there is a mapping */
3500 if ( !sid_to_gid( &sid, &gid ) ) {
3501 return NT_STATUS_NO_SUCH_ALIAS;
3506 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
3507 struct samr_alias_info, &status);
3508 if (!NT_STATUS_IS_OK(status)) {
3513 return NT_STATUS_OK;
3516 /*******************************************************************
3518 ********************************************************************/
3520 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3521 struct samr_UserInfo7 *id7,
3527 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3528 return NT_STATUS_ACCESS_DENIED;
3531 if (!id7->account_name.string) {
3532 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3533 return NT_STATUS_ACCESS_DENIED;
3536 /* check to see if the new username already exists. Note: we can't
3537 reliably lock all backends, so there is potentially the
3538 possibility that a user can be created in between this check and
3539 the rename. The rename should fail, but may not get the
3540 exact same failure status code. I think this is small enough
3541 of a window for this type of operation and the results are
3542 simply that the rename fails with a slightly different status
3543 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3545 rc = can_create(mem_ctx, id7->account_name.string);
3546 if (!NT_STATUS_IS_OK(rc)) {
3550 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3555 /*******************************************************************
3557 ********************************************************************/
3559 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3563 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3567 /* FIX ME: check if the value is really changed --metze */
3568 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3572 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3579 /*******************************************************************
3581 ********************************************************************/
3583 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
3584 TALLOC_CTX *mem_ctx,
3585 DATA_BLOB *session_key,
3589 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3590 return NT_STATUS_INVALID_PARAMETER;
3593 if (id18->nt_pwd_active || id18->lm_pwd_active) {
3594 if (!session_key->length) {
3595 return NT_STATUS_NO_USER_SESSION_KEY;
3599 if (id18->nt_pwd_active) {
3603 in = data_blob_const(id18->nt_pwd.hash, 16);
3604 out = data_blob_talloc_zero(mem_ctx, 16);
3606 sess_crypt_blob(&out, &in, session_key, false);
3608 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
3609 return NT_STATUS_ACCESS_DENIED;
3612 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3615 if (id18->lm_pwd_active) {
3619 in = data_blob_const(id18->lm_pwd.hash, 16);
3620 out = data_blob_talloc_zero(mem_ctx, 16);
3622 sess_crypt_blob(&out, &in, session_key, false);
3624 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
3625 return NT_STATUS_ACCESS_DENIED;
3628 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3631 copy_id18_to_sam_passwd(pwd, id18);
3633 return pdb_update_sam_account(pwd);
3636 /*******************************************************************
3638 ********************************************************************/
3640 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3644 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3648 copy_id20_to_sam_passwd(pwd, id20);
3650 /* write the change out */
3651 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3658 /*******************************************************************
3660 ********************************************************************/
3662 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
3663 TALLOC_CTX *mem_ctx,
3664 DATA_BLOB *session_key,
3670 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3671 return NT_STATUS_INVALID_PARAMETER;
3674 if (id21->fields_present == 0) {
3675 return NT_STATUS_INVALID_PARAMETER;
3678 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3679 return NT_STATUS_ACCESS_DENIED;
3682 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
3683 if (id21->nt_password_set) {
3686 if ((id21->nt_owf_password.length != 16) ||
3687 (id21->nt_owf_password.size != 16)) {
3688 return NT_STATUS_INVALID_PARAMETER;
3691 if (!session_key->length) {
3692 return NT_STATUS_NO_USER_SESSION_KEY;
3695 in = data_blob_const(id21->nt_owf_password.array, 16);
3696 out = data_blob_talloc_zero(mem_ctx, 16);
3698 sess_crypt_blob(&out, &in, session_key, false);
3700 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
3701 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3705 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
3706 if (id21->lm_password_set) {
3709 if ((id21->lm_owf_password.length != 16) ||
3710 (id21->lm_owf_password.size != 16)) {
3711 return NT_STATUS_INVALID_PARAMETER;
3714 if (!session_key->length) {
3715 return NT_STATUS_NO_USER_SESSION_KEY;
3718 in = data_blob_const(id21->lm_owf_password.array, 16);
3719 out = data_blob_talloc_zero(mem_ctx, 16);
3721 sess_crypt_blob(&out, &in, session_key, false);
3723 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
3724 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3728 /* we need to separately check for an account rename first */
3730 if (id21->account_name.string &&
3731 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3734 /* check to see if the new username already exists. Note: we can't
3735 reliably lock all backends, so there is potentially the
3736 possibility that a user can be created in between this check and
3737 the rename. The rename should fail, but may not get the
3738 exact same failure status code. I think this is small enough
3739 of a window for this type of operation and the results are
3740 simply that the rename fails with a slightly different status
3741 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3743 status = can_create(mem_ctx, id21->account_name.string);
3744 if (!NT_STATUS_IS_OK(status)) {
3748 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3750 if (!NT_STATUS_IS_OK(status)) {
3751 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3752 nt_errstr(status)));
3756 /* set the new username so that later
3757 functions can work on the new account */
3758 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3761 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3764 * The funny part about the previous two calls is
3765 * that pwd still has the password hashes from the
3766 * passdb entry. These have not been updated from
3767 * id21. I don't know if they need to be set. --jerry
3770 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3771 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3772 if ( !NT_STATUS_IS_OK(status) ) {
3777 /* Don't worry about writing out the user account since the
3778 primary group SID is generated solely from the user's Unix
3781 /* write the change out */
3782 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3786 return NT_STATUS_OK;
3789 /*******************************************************************
3791 ********************************************************************/
3793 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3794 struct samr_UserInfo23 *id23,
3797 char *plaintext_buf = NULL;
3803 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3804 return NT_STATUS_INVALID_PARAMETER;
3807 if (id23->info.fields_present == 0) {
3808 return NT_STATUS_INVALID_PARAMETER;
3811 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3812 return NT_STATUS_ACCESS_DENIED;
3815 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3816 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
3818 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3819 pdb_get_username(pwd)));
3821 if (!decode_pw_buffer(mem_ctx,
3822 id23->password.data,
3826 return NT_STATUS_WRONG_PASSWORD;
3829 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3830 return NT_STATUS_ACCESS_DENIED;
3834 copy_id23_to_sam_passwd(pwd, id23);
3836 acct_ctrl = pdb_get_acct_ctrl(pwd);
3838 /* if it's a trust account, don't update /etc/passwd */
3839 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3840 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3841 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3842 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3843 } else if (plaintext_buf) {
3844 /* update the UNIX password */
3845 if (lp_unix_password_sync() ) {
3846 struct passwd *passwd;
3847 if (pdb_get_username(pwd) == NULL) {
3848 DEBUG(1, ("chgpasswd: User without name???\n"));
3849 return NT_STATUS_ACCESS_DENIED;
3852 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3853 if (passwd == NULL) {
3854 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3857 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3858 return NT_STATUS_ACCESS_DENIED;
3860 TALLOC_FREE(passwd);
3864 if (plaintext_buf) {
3865 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3868 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3869 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3874 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3878 return NT_STATUS_OK;
3881 /*******************************************************************
3883 ********************************************************************/
3885 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
3888 char *plaintext_buf = NULL;
3891 DEBUG(5, ("Attempting administrator password change for user %s\n",
3892 pdb_get_username(pwd)));
3894 acct_ctrl = pdb_get_acct_ctrl(pwd);
3896 if (!decode_pw_buffer(talloc_tos(),
3904 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3908 /* if it's a trust account, don't update /etc/passwd */
3909 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3910 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3911 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3912 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3914 /* update the UNIX password */
3915 if (lp_unix_password_sync()) {
3916 struct passwd *passwd;
3918 if (pdb_get_username(pwd) == NULL) {
3919 DEBUG(1, ("chgpasswd: User without name???\n"));
3923 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3924 if (passwd == NULL) {
3925 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3928 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3931 TALLOC_FREE(passwd);
3935 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3937 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3942 /*******************************************************************
3944 ********************************************************************/
3946 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
3947 struct samr_UserInfo24 *id24,
3953 DEBUG(5, ("set_user_info_24: NULL id24\n"));
3954 return NT_STATUS_INVALID_PARAMETER;
3957 if (!set_user_info_pw(id24->password.data, pwd)) {
3958 return NT_STATUS_WRONG_PASSWORD;
3961 copy_id24_to_sam_passwd(pwd, id24);
3963 status = pdb_update_sam_account(pwd);
3964 if (!NT_STATUS_IS_OK(status)) {
3968 return NT_STATUS_OK;
3971 /*******************************************************************
3973 ********************************************************************/
3975 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
3976 struct samr_UserInfo25 *id25,
3982 DEBUG(5, ("set_user_info_25: NULL id25\n"));
3983 return NT_STATUS_INVALID_PARAMETER;
3986 if (id25->info.fields_present == 0) {
3987 return NT_STATUS_INVALID_PARAMETER;
3990 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3991 return NT_STATUS_ACCESS_DENIED;
3994 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3995 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
3997 if (!set_user_info_pw(id25->password.data, pwd)) {
3998 return NT_STATUS_WRONG_PASSWORD;
4002 copy_id25_to_sam_passwd(pwd, id25);
4004 /* write the change out */
4005 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4010 * We need to "pdb_update_sam_account" before the unix primary group
4011 * is set, because the idealx scripts would also change the
4012 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4013 * the delete explicit / add explicit, which would then fail to find
4014 * the previous primaryGroupSid value.
4017 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4018 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4019 if ( !NT_STATUS_IS_OK(status) ) {
4024 return NT_STATUS_OK;
4027 /*******************************************************************
4029 ********************************************************************/
4031 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4032 struct samr_UserInfo26 *id26,
4038 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4039 return NT_STATUS_INVALID_PARAMETER;
4042 if (!set_user_info_pw(id26->password.data, pwd)) {
4043 return NT_STATUS_WRONG_PASSWORD;
4046 copy_id26_to_sam_passwd(pwd, id26);
4048 status = pdb_update_sam_account(pwd);
4049 if (!NT_STATUS_IS_OK(status)) {
4053 return NT_STATUS_OK;
4057 /*******************************************************************
4059 ********************************************************************/
4061 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4062 struct samr_SetUserInfo *r)
4064 struct samr_user_info *uinfo;
4066 struct samu *pwd = NULL;
4067 union samr_UserInfo *info = r->in.info;
4068 uint16_t switch_value = r->in.level;
4069 uint32_t acc_required;
4071 bool has_enough_rights = False;
4074 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4076 /* This is tricky. A WinXP domain join sets
4077 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4078 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4079 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4080 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4081 we'll use the set from the WinXP join as the basis. */
4083 switch (switch_value) {
4088 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4091 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4092 SAMR_USER_ACCESS_SET_ATTRIBUTES |
4093 SAMR_USER_ACCESS_GET_ATTRIBUTES;
4097 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
4098 struct samr_user_info, &status);
4099 if (!NT_STATUS_IS_OK(status)) {
4103 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4104 sid_string_dbg(&uinfo->sid), switch_value));
4107 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4108 return NT_STATUS_INVALID_INFO_CLASS;
4111 if (!(pwd = samu_new(NULL))) {
4112 return NT_STATUS_NO_MEMORY;
4116 ret = pdb_getsampwsid(pwd, &uinfo->sid);
4121 return NT_STATUS_NO_SUCH_USER;
4124 /* deal with machine password changes differently from userinfo changes */
4125 /* check to see if we have the sufficient rights */
4127 acb_info = pdb_get_acct_ctrl(pwd);
4128 if (acb_info & ACB_WSTRUST)
4129 has_enough_rights = user_has_privileges(p->server_info->ptok,
4130 &se_machine_account);
4131 else if (acb_info & ACB_NORMAL)
4132 has_enough_rights = user_has_privileges(p->server_info->ptok,
4134 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4135 if (lp_enable_privileges()) {
4136 has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
4137 DOMAIN_GROUP_RID_ADMINS);
4141 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4142 uidtoname(p->server_info->utok.uid),
4143 has_enough_rights ? "" : " not"));
4145 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4147 if (has_enough_rights) {
4151 /* ok! user info levels (lots: see MSDEV help), off we go... */
4153 switch (switch_value) {
4156 status = set_user_info_7(p->mem_ctx,
4161 if (!set_user_info_16(&info->info16, pwd)) {
4162 status = NT_STATUS_ACCESS_DENIED;
4167 /* Used by AS/U JRA. */
4168 status = set_user_info_18(&info->info18,
4170 &p->server_info->user_session_key,
4175 if (!set_user_info_20(&info->info20, pwd)) {
4176 status = NT_STATUS_ACCESS_DENIED;
4181 status = set_user_info_21(&info->info21,
4183 &p->server_info->user_session_key,
4188 if (!p->server_info->user_session_key.length) {
4189 status = NT_STATUS_NO_USER_SESSION_KEY;
4191 arcfour_crypt_blob(info->info23.password.data, 516,
4192 &p->server_info->user_session_key);
4194 dump_data(100, info->info23.password.data, 516);
4196 status = set_user_info_23(p->mem_ctx,
4197 &info->info23, pwd);
4201 if (!p->server_info->user_session_key.length) {
4202 status = NT_STATUS_NO_USER_SESSION_KEY;
4204 arcfour_crypt_blob(info->info24.password.data,
4206 &p->server_info->user_session_key);
4208 dump_data(100, info->info24.password.data, 516);
4210 status = set_user_info_24(p->mem_ctx,
4211 &info->info24, pwd);
4215 if (!p->server_info->user_session_key.length) {
4216 status = NT_STATUS_NO_USER_SESSION_KEY;
4218 encode_or_decode_arc4_passwd_buffer(
4219 info->info25.password.data,
4220 &p->server_info->user_session_key);
4222 dump_data(100, info->info25.password.data, 532);
4224 status = set_user_info_25(p->mem_ctx,
4225 &info->info25, pwd);
4229 if (!p->server_info->user_session_key.length) {
4230 status = NT_STATUS_NO_USER_SESSION_KEY;
4232 encode_or_decode_arc4_passwd_buffer(
4233 info->info26.password.data,
4234 &p->server_info->user_session_key);
4236 dump_data(100, info->info26.password.data, 516);
4238 status = set_user_info_26(p->mem_ctx,
4239 &info->info26, pwd);
4243 status = NT_STATUS_INVALID_INFO_CLASS;
4248 if (has_enough_rights) {
4252 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4254 if (NT_STATUS_IS_OK(status)) {
4255 force_flush_samr_cache(&uinfo->sid);
4261 /*******************************************************************
4263 ********************************************************************/
4265 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4266 struct samr_SetUserInfo2 *r)
4268 struct samr_SetUserInfo q;
4270 q.in.user_handle = r->in.user_handle;
4271 q.in.level = r->in.level;
4272 q.in.info = r->in.info;
4274 return _samr_SetUserInfo(p, &q);
4277 /*********************************************************************
4278 _samr_GetAliasMembership
4279 *********************************************************************/
4281 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4282 struct samr_GetAliasMembership *r)
4284 size_t num_alias_rids;
4286 struct samr_domain_info *dinfo;
4293 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4295 dinfo = policy_handle_find(p, r->in.domain_handle,
4296 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
4297 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4298 struct samr_domain_info, &status);
4299 if (!NT_STATUS_IS_OK(status)) {
4303 if (!sid_check_is_domain(&dinfo->sid) &&
4304 !sid_check_is_builtin(&dinfo->sid))
4305 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4307 if (r->in.sids->num_sids) {
4308 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4310 if (members == NULL)
4311 return NT_STATUS_NO_MEMORY;
4316 for (i=0; i<r->in.sids->num_sids; i++)
4317 sid_copy(&members[i], r->in.sids->sids[i].sid);
4323 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
4324 r->in.sids->num_sids,
4325 &alias_rids, &num_alias_rids);
4328 if (!NT_STATUS_IS_OK(status)) {
4332 r->out.rids->count = num_alias_rids;
4333 r->out.rids->ids = alias_rids;
4335 return NT_STATUS_OK;
4338 /*********************************************************************
4339 _samr_GetMembersInAlias
4340 *********************************************************************/
4342 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4343 struct samr_GetMembersInAlias *r)
4345 struct samr_alias_info *ainfo;
4348 size_t num_sids = 0;
4349 struct lsa_SidPtr *sids = NULL;
4350 DOM_SID *pdb_sids = NULL;
4352 ainfo = policy_handle_find(p, r->in.alias_handle,
4353 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
4354 struct samr_alias_info, &status);
4355 if (!NT_STATUS_IS_OK(status)) {
4359 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
4362 status = pdb_enum_aliasmem(&ainfo->sid, &pdb_sids, &num_sids);
4365 if (!NT_STATUS_IS_OK(status)) {
4370 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4372 TALLOC_FREE(pdb_sids);
4373 return NT_STATUS_NO_MEMORY;
4377 for (i = 0; i < num_sids; i++) {
4378 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4380 TALLOC_FREE(pdb_sids);
4381 return NT_STATUS_NO_MEMORY;
4385 r->out.sids->num_sids = num_sids;
4386 r->out.sids->sids = sids;
4388 TALLOC_FREE(pdb_sids);
4390 return NT_STATUS_OK;
4393 /*********************************************************************
4394 _samr_QueryGroupMember
4395 *********************************************************************/
4397 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4398 struct samr_QueryGroupMember *r)
4400 struct samr_group_info *ginfo;
4401 size_t i, num_members;
4407 struct samr_RidTypeArray *rids = NULL;
4409 ginfo = policy_handle_find(p, r->in.group_handle,
4410 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
4411 struct samr_group_info, &status);
4412 if (!NT_STATUS_IS_OK(status)) {
4416 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4418 return NT_STATUS_NO_MEMORY;
4421 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
4423 if (!sid_check_is_in_our_domain(&ginfo->sid)) {
4424 DEBUG(3, ("sid %s is not in our domain\n",
4425 sid_string_dbg(&ginfo->sid)));
4426 return NT_STATUS_NO_SUCH_GROUP;
4429 DEBUG(10, ("lookup on Domain SID\n"));
4432 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
4433 &rid, &num_members);
4436 if (!NT_STATUS_IS_OK(status))
4440 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4442 return NT_STATUS_NO_MEMORY;
4448 for (i=0; i<num_members; i++)
4449 attr[i] = SID_NAME_USER;
4451 rids->count = num_members;
4455 *r->out.rids = rids;
4457 return NT_STATUS_OK;
4460 /*********************************************************************
4461 _samr_AddAliasMember
4462 *********************************************************************/
4464 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4465 struct samr_AddAliasMember *r)
4467 struct samr_alias_info *ainfo;
4469 bool can_add_accounts;
4472 ainfo = policy_handle_find(p, r->in.alias_handle,
4473 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
4474 struct samr_alias_info, &status);
4475 if (!NT_STATUS_IS_OK(status)) {
4479 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
4481 se_priv_copy( &se_rights, &se_add_users );
4482 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4484 /******** BEGIN SeAddUsers BLOCK *********/
4486 if ( can_add_accounts )
4489 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
4491 if ( can_add_accounts )
4494 /******** END SeAddUsers BLOCK *********/
4496 if (NT_STATUS_IS_OK(status)) {
4497 force_flush_samr_cache(&ainfo->sid);
4503 /*********************************************************************
4504 _samr_DeleteAliasMember
4505 *********************************************************************/
4507 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4508 struct samr_DeleteAliasMember *r)
4510 struct samr_alias_info *ainfo;
4512 bool can_add_accounts;
4515 ainfo = policy_handle_find(p, r->in.alias_handle,
4516 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
4517 struct samr_alias_info, &status);
4518 if (!NT_STATUS_IS_OK(status)) {
4522 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4523 sid_string_dbg(&ainfo->sid)));
4525 se_priv_copy( &se_rights, &se_add_users );
4526 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4528 /******** BEGIN SeAddUsers BLOCK *********/
4530 if ( can_add_accounts )
4533 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
4535 if ( can_add_accounts )
4538 /******** END SeAddUsers BLOCK *********/
4540 if (NT_STATUS_IS_OK(status)) {
4541 force_flush_samr_cache(&ainfo->sid);
4547 /*********************************************************************
4548 _samr_AddGroupMember
4549 *********************************************************************/
4551 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4552 struct samr_AddGroupMember *r)
4554 struct samr_group_info *ginfo;
4558 bool can_add_accounts;
4560 ginfo = policy_handle_find(p, r->in.group_handle,
4561 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
4562 struct samr_group_info, &status);
4563 if (!NT_STATUS_IS_OK(status)) {
4567 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
4569 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
4571 return NT_STATUS_INVALID_HANDLE;
4574 se_priv_copy( &se_rights, &se_add_users );
4575 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4577 /******** BEGIN SeAddUsers BLOCK *********/
4579 if ( can_add_accounts )
4582 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4584 if ( can_add_accounts )
4587 /******** END SeAddUsers BLOCK *********/
4589 force_flush_samr_cache(&ginfo->sid);
4594 /*********************************************************************
4595 _samr_DeleteGroupMember
4596 *********************************************************************/
4598 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4599 struct samr_DeleteGroupMember *r)
4602 struct samr_group_info *ginfo;
4606 bool can_add_accounts;
4609 * delete the group member named r->in.rid
4610 * who is a member of the sid associated with the handle
4611 * the rid is a user's rid as the group is a domain group.
4614 ginfo = policy_handle_find(p, r->in.group_handle,
4615 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
4616 struct samr_group_info, &status);
4617 if (!NT_STATUS_IS_OK(status)) {
4621 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
4623 return NT_STATUS_INVALID_HANDLE;
4626 se_priv_copy( &se_rights, &se_add_users );
4627 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4629 /******** BEGIN SeAddUsers BLOCK *********/
4631 if ( can_add_accounts )
4634 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4636 if ( can_add_accounts )
4639 /******** END SeAddUsers BLOCK *********/
4641 force_flush_samr_cache(&ginfo->sid);
4646 /*********************************************************************
4648 *********************************************************************/
4650 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4651 struct samr_DeleteUser *r)
4653 struct samr_user_info *uinfo;
4655 struct samu *sam_pass=NULL;
4656 bool can_add_accounts;
4660 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4662 uinfo = policy_handle_find(p, r->in.user_handle,
4663 STD_RIGHT_DELETE_ACCESS, NULL,
4664 struct samr_user_info, &status);
4665 if (!NT_STATUS_IS_OK(status)) {
4669 if (!sid_check_is_in_our_domain(&uinfo->sid))
4670 return NT_STATUS_CANNOT_DELETE;
4672 /* check if the user exists before trying to delete */
4673 if ( !(sam_pass = samu_new( NULL )) ) {
4674 return NT_STATUS_NO_MEMORY;
4678 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
4682 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4683 sid_string_dbg(&uinfo->sid)));
4684 TALLOC_FREE(sam_pass);
4685 return NT_STATUS_NO_SUCH_USER;
4688 acb_info = pdb_get_acct_ctrl(sam_pass);
4690 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4691 if ( acb_info & ACB_WSTRUST ) {
4692 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
4694 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
4697 /******** BEGIN SeAddUsers BLOCK *********/
4699 if ( can_add_accounts )
4702 status = pdb_delete_user(p->mem_ctx, sam_pass);
4704 if ( can_add_accounts )
4707 /******** END SeAddUsers BLOCK *********/
4709 if ( !NT_STATUS_IS_OK(status) ) {
4710 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4711 "user %s: %s.\n", pdb_get_username(sam_pass),
4712 nt_errstr(status)));
4713 TALLOC_FREE(sam_pass);
4718 TALLOC_FREE(sam_pass);
4720 if (!close_policy_hnd(p, r->in.user_handle))
4721 return NT_STATUS_OBJECT_NAME_INVALID;
4723 ZERO_STRUCTP(r->out.user_handle);
4725 force_flush_samr_cache(&uinfo->sid);
4727 return NT_STATUS_OK;
4730 /*********************************************************************
4731 _samr_DeleteDomainGroup
4732 *********************************************************************/
4734 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4735 struct samr_DeleteDomainGroup *r)
4737 struct samr_group_info *ginfo;
4741 bool can_add_accounts;
4743 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4745 ginfo = policy_handle_find(p, r->in.group_handle,
4746 STD_RIGHT_DELETE_ACCESS, NULL,
4747 struct samr_group_info, &status);
4748 if (!NT_STATUS_IS_OK(status)) {
4752 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
4754 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
4756 return NT_STATUS_NO_SUCH_GROUP;
4759 se_priv_copy( &se_rights, &se_add_users );
4760 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4762 /******** BEGIN SeAddUsers BLOCK *********/
4764 if ( can_add_accounts )
4767 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4769 if ( can_add_accounts )
4772 /******** END SeAddUsers BLOCK *********/
4774 if ( !NT_STATUS_IS_OK(status) ) {
4775 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4776 "entry for group %s: %s\n",
4777 sid_string_dbg(&ginfo->sid),
4778 nt_errstr(status)));
4782 if (!close_policy_hnd(p, r->in.group_handle))
4783 return NT_STATUS_OBJECT_NAME_INVALID;
4785 force_flush_samr_cache(&ginfo->sid);
4787 return NT_STATUS_OK;
4790 /*********************************************************************
4791 _samr_DeleteDomAlias
4792 *********************************************************************/
4794 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4795 struct samr_DeleteDomAlias *r)
4797 struct samr_alias_info *ainfo;
4799 bool can_add_accounts;
4802 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4804 ainfo = policy_handle_find(p, r->in.alias_handle,
4805 STD_RIGHT_DELETE_ACCESS, NULL,
4806 struct samr_alias_info, &status);
4807 if (!NT_STATUS_IS_OK(status)) {
4811 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
4813 /* Don't let Windows delete builtin groups */
4815 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
4816 return NT_STATUS_SPECIAL_ACCOUNT;
4819 if (!sid_check_is_in_our_domain(&ainfo->sid))
4820 return NT_STATUS_NO_SUCH_ALIAS;
4822 DEBUG(10, ("lookup on Local SID\n"));
4824 se_priv_copy( &se_rights, &se_add_users );
4825 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4827 /******** BEGIN SeAddUsers BLOCK *********/
4829 if ( can_add_accounts )
4832 /* Have passdb delete the alias */
4833 status = pdb_delete_alias(&ainfo->sid);
4835 if ( can_add_accounts )
4838 /******** END SeAddUsers BLOCK *********/
4840 if ( !NT_STATUS_IS_OK(status))
4843 if (!close_policy_hnd(p, r->in.alias_handle))
4844 return NT_STATUS_OBJECT_NAME_INVALID;
4846 force_flush_samr_cache(&ainfo->sid);
4848 return NT_STATUS_OK;
4851 /*********************************************************************
4852 _samr_CreateDomainGroup
4853 *********************************************************************/
4855 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4856 struct samr_CreateDomainGroup *r)
4861 struct samr_domain_info *dinfo;
4862 struct samr_group_info *ginfo;
4864 bool can_add_accounts;
4866 dinfo = policy_handle_find(p, r->in.domain_handle,
4867 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
4868 struct samr_domain_info, &status);
4869 if (!NT_STATUS_IS_OK(status)) {
4873 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
4874 return NT_STATUS_ACCESS_DENIED;
4876 name = r->in.name->string;
4878 return NT_STATUS_NO_MEMORY;
4881 status = can_create(p->mem_ctx, name);
4882 if (!NT_STATUS_IS_OK(status)) {
4886 se_priv_copy( &se_rights, &se_add_users );
4887 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4889 /******** BEGIN SeAddUsers BLOCK *********/
4891 if ( can_add_accounts )
4894 /* check that we successfully create the UNIX group */
4896 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
4898 if ( can_add_accounts )
4901 /******** END SeAddUsers BLOCK *********/
4903 /* check if we should bail out here */
4905 if ( !NT_STATUS_IS_OK(status) )
4908 ginfo = policy_handle_create(p, r->out.group_handle,
4909 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
4910 struct samr_group_info, &status);
4911 if (!NT_STATUS_IS_OK(status)) {
4914 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
4916 force_flush_samr_cache(&dinfo->sid);
4918 return NT_STATUS_OK;
4921 /*********************************************************************
4922 _samr_CreateDomAlias
4923 *********************************************************************/
4925 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
4926 struct samr_CreateDomAlias *r)
4929 const char *name = NULL;
4930 struct samr_domain_info *dinfo;
4931 struct samr_alias_info *ainfo;
4935 bool can_add_accounts;
4937 dinfo = policy_handle_find(p, r->in.domain_handle,
4938 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
4939 struct samr_domain_info, &result);
4940 if (!NT_STATUS_IS_OK(result)) {
4944 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
4945 return NT_STATUS_ACCESS_DENIED;
4947 name = r->in.alias_name->string;
4949 se_priv_copy( &se_rights, &se_add_users );
4950 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4952 result = can_create(p->mem_ctx, name);
4953 if (!NT_STATUS_IS_OK(result)) {
4957 /******** BEGIN SeAddUsers BLOCK *********/
4959 if ( can_add_accounts )
4962 /* Have passdb create the alias */
4963 result = pdb_create_alias(name, r->out.rid);
4965 if ( can_add_accounts )
4968 /******** END SeAddUsers BLOCK *********/
4970 if (!NT_STATUS_IS_OK(result)) {
4971 DEBUG(10, ("pdb_create_alias failed: %s\n",
4972 nt_errstr(result)));
4976 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
4978 if (!sid_to_gid(&info_sid, &gid)) {
4979 DEBUG(10, ("Could not find alias just created\n"));
4980 return NT_STATUS_ACCESS_DENIED;
4983 /* check if the group has been successfully created */
4984 if ( getgrgid(gid) == NULL ) {
4985 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
4987 return NT_STATUS_ACCESS_DENIED;
4990 ainfo = policy_handle_create(p, r->out.alias_handle,
4991 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4992 struct samr_alias_info, &result);
4993 if (!NT_STATUS_IS_OK(result)) {
4996 ainfo->sid = info_sid;
4998 force_flush_samr_cache(&info_sid);
5000 return NT_STATUS_OK;
5003 /*********************************************************************
5004 _samr_QueryGroupInfo
5005 *********************************************************************/
5007 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5008 struct samr_QueryGroupInfo *r)
5010 struct samr_group_info *ginfo;
5013 union samr_GroupInfo *info = NULL;
5015 uint32_t attributes = SE_GROUP_MANDATORY |
5016 SE_GROUP_ENABLED_BY_DEFAULT |
5018 const char *group_name = NULL;
5019 const char *group_description = NULL;
5021 ginfo = policy_handle_find(p, r->in.group_handle,
5022 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5023 struct samr_group_info, &status);
5024 if (!NT_STATUS_IS_OK(status)) {
5029 ret = get_domain_group_from_sid(ginfo->sid, &map);
5032 return NT_STATUS_INVALID_HANDLE;
5034 /* FIXME: map contains fstrings */
5035 group_name = talloc_strdup(r, map.nt_name);
5036 group_description = talloc_strdup(r, map.comment);
5038 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5040 return NT_STATUS_NO_MEMORY;
5043 switch (r->in.level) {
5049 status = pdb_enum_group_members(
5050 p->mem_ctx, &ginfo->sid, &members,
5054 if (!NT_STATUS_IS_OK(status)) {
5058 info->all.name.string = group_name;
5059 info->all.attributes = attributes;
5060 info->all.num_members = num_members;
5061 info->all.description.string = group_description;
5065 info->name.string = group_name;
5068 info->attributes.attributes = attributes;
5071 info->description.string = group_description;
5081 status = pdb_enum_group_members(
5082 p->mem_ctx, &ginfo->sid, &members,
5086 if (!NT_STATUS_IS_OK(status)) {
5090 info->all2.name.string = group_name;
5091 info->all2.attributes = attributes;
5092 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5093 info->all2.description.string = group_description;
5098 return NT_STATUS_INVALID_INFO_CLASS;
5101 *r->out.info = info;
5103 return NT_STATUS_OK;
5106 /*********************************************************************
5108 *********************************************************************/
5110 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5111 struct samr_SetGroupInfo *r)
5113 struct samr_group_info *ginfo;
5117 bool can_mod_accounts;
5119 ginfo = policy_handle_find(p, r->in.group_handle,
5120 SAMR_GROUP_ACCESS_SET_INFO, NULL,
5121 struct samr_group_info, &status);
5122 if (!NT_STATUS_IS_OK(status)) {
5127 ret = get_domain_group_from_sid(ginfo->sid, &map);
5130 return NT_STATUS_NO_SUCH_GROUP;
5132 switch (r->in.level) {
5134 fstrcpy(map.comment, r->in.info->all.description.string);
5137 /* group rename is not supported yet */
5138 return NT_STATUS_NOT_SUPPORTED;
5140 fstrcpy(map.comment, r->in.info->description.string);
5143 return NT_STATUS_INVALID_INFO_CLASS;
5146 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5148 /******** BEGIN SeAddUsers BLOCK *********/
5150 if ( can_mod_accounts )
5153 status = pdb_update_group_mapping_entry(&map);
5155 if ( can_mod_accounts )
5158 /******** End SeAddUsers BLOCK *********/
5160 if (NT_STATUS_IS_OK(status)) {
5161 force_flush_samr_cache(&ginfo->sid);
5167 /*********************************************************************
5169 *********************************************************************/
5171 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5172 struct samr_SetAliasInfo *r)
5174 struct samr_alias_info *ainfo;
5175 struct acct_info info;
5176 bool can_mod_accounts;
5179 ainfo = policy_handle_find(p, r->in.alias_handle,
5180 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
5181 struct samr_alias_info, &status);
5182 if (!NT_STATUS_IS_OK(status)) {
5186 /* get the current group information */
5189 status = pdb_get_aliasinfo( &ainfo->sid, &info );
5192 if ( !NT_STATUS_IS_OK(status))
5195 switch (r->in.level) {
5200 /* We currently do not support renaming groups in the
5201 the BUILTIN domain. Refer to util_builtin.c to understand
5202 why. The eventually needs to be fixed to be like Windows
5203 where you can rename builtin groups, just not delete them */
5205 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5206 return NT_STATUS_SPECIAL_ACCOUNT;
5209 /* There has to be a valid name (and it has to be different) */
5211 if ( !r->in.info->name.string )
5212 return NT_STATUS_INVALID_PARAMETER;
5214 /* If the name is the same just reply "ok". Yes this
5215 doesn't allow you to change the case of a group name. */
5217 if ( strequal( r->in.info->name.string, info.acct_name ) )
5218 return NT_STATUS_OK;
5220 fstrcpy( info.acct_name, r->in.info->name.string);
5222 /* make sure the name doesn't already exist as a user
5225 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5226 status = can_create( p->mem_ctx, group_name );
5227 if ( !NT_STATUS_IS_OK( status ) )
5231 case ALIASINFODESCRIPTION:
5232 if (r->in.info->description.string) {
5233 fstrcpy(info.acct_desc,
5234 r->in.info->description.string);
5236 fstrcpy( info.acct_desc, "" );
5240 return NT_STATUS_INVALID_INFO_CLASS;
5243 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5245 /******** BEGIN SeAddUsers BLOCK *********/
5247 if ( can_mod_accounts )
5250 status = pdb_set_aliasinfo( &ainfo->sid, &info );
5252 if ( can_mod_accounts )
5255 /******** End SeAddUsers BLOCK *********/
5257 if (NT_STATUS_IS_OK(status))
5258 force_flush_samr_cache(&ainfo->sid);
5263 /****************************************************************
5265 ****************************************************************/
5267 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5268 struct samr_GetDomPwInfo *r)
5270 uint32_t min_password_length = 0;
5271 uint32_t password_properties = 0;
5273 /* Perform access check. Since this rpc does not require a
5274 policy handle it will not be caught by the access checks on
5275 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5277 if (!pipe_access_check(p)) {
5278 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5279 return NT_STATUS_ACCESS_DENIED;
5283 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5284 &min_password_length);
5285 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5286 &password_properties);
5289 if (lp_check_password_script() && *lp_check_password_script()) {
5290 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5293 r->out.info->min_password_length = min_password_length;
5294 r->out.info->password_properties = password_properties;
5296 return NT_STATUS_OK;
5299 /*********************************************************************
5301 *********************************************************************/
5303 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5304 struct samr_OpenGroup *r)
5309 struct samr_domain_info *dinfo;
5310 struct samr_group_info *ginfo;
5311 SEC_DESC *psd = NULL;
5313 uint32 des_access = r->in.access_mask;
5319 dinfo = policy_handle_find(p, r->in.domain_handle,
5320 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5321 struct samr_domain_info, &status);
5322 if (!NT_STATUS_IS_OK(status)) {
5326 /*check if access can be granted as requested by client. */
5327 map_max_allowed_access(p->server_info->ptok, &des_access);
5329 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5330 se_map_generic(&des_access,&grp_generic_mapping);
5332 se_priv_copy( &se_rights, &se_add_users );
5334 status = access_check_samr_object(psd, p->server_info->ptok,
5335 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5336 &acc_granted, "_samr_OpenGroup");
5338 if ( !NT_STATUS_IS_OK(status) )
5341 /* this should not be hard-coded like this */
5343 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5344 return NT_STATUS_ACCESS_DENIED;
5346 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
5348 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
5349 sid_string_dbg(&info_sid)));
5351 /* check if that group really exists */
5353 ret = get_domain_group_from_sid(info_sid, &map);
5356 return NT_STATUS_NO_SUCH_GROUP;
5358 ginfo = policy_handle_create(p, r->out.group_handle,
5359 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5360 struct samr_group_info, &status);
5361 if (!NT_STATUS_IS_OK(status)) {
5364 ginfo->sid = info_sid;
5366 return NT_STATUS_OK;
5369 /*********************************************************************
5370 _samr_RemoveMemberFromForeignDomain
5371 *********************************************************************/
5373 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5374 struct samr_RemoveMemberFromForeignDomain *r)
5376 struct samr_domain_info *dinfo;
5379 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5380 sid_string_dbg(r->in.sid)));
5382 /* Find the policy handle. Open a policy on it. */
5384 dinfo = policy_handle_find(p, r->in.domain_handle,
5385 STD_RIGHT_DELETE_ACCESS, NULL,
5386 struct samr_domain_info, &result);
5387 if (!NT_STATUS_IS_OK(result)) {
5391 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5392 sid_string_dbg(&dinfo->sid)));
5394 /* we can only delete a user from a group since we don't have
5395 nested groups anyways. So in the latter case, just say OK */
5397 /* TODO: The above comment nowadays is bogus. Since we have nested
5398 * groups now, and aliases members are never reported out of the unix
5399 * group membership, the "just say OK" makes this call a no-op. For
5400 * us. This needs fixing however. */
5402 /* I've only ever seen this in the wild when deleting a user from
5403 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5404 * is the user about to be deleted. I very much suspect this is the
5405 * only application of this call. To verify this, let people report
5408 if (!sid_check_is_builtin(&dinfo->sid)) {
5409 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5410 "global_sam_sid() = %s\n",
5411 sid_string_dbg(&dinfo->sid),
5412 sid_string_dbg(get_global_sam_sid())));
5413 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5414 return NT_STATUS_OK;
5417 force_flush_samr_cache(&dinfo->sid);
5419 result = NT_STATUS_OK;
5424 /*******************************************************************
5425 _samr_QueryDomainInfo2
5426 ********************************************************************/
5428 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5429 struct samr_QueryDomainInfo2 *r)
5431 struct samr_QueryDomainInfo q;
5433 q.in.domain_handle = r->in.domain_handle;
5434 q.in.level = r->in.level;
5436 q.out.info = r->out.info;
5438 return _samr_QueryDomainInfo(p, &q);
5441 /*******************************************************************
5443 ********************************************************************/
5445 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5446 struct samr_SetDomainInfo *r)
5448 struct samr_domain_info *dinfo;
5449 time_t u_expire, u_min_age;
5451 time_t u_lock_duration, u_reset_time;
5454 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5456 /* We do have different access bits for info
5457 * levels here, but we're really just looking for
5458 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5459 * this maps to different specific bits. So
5460 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
5463 dinfo = policy_handle_find(p, r->in.domain_handle,
5464 SAMR_DOMAIN_ACCESS_SET_INFO_1, NULL,
5465 struct samr_domain_info, &result);
5466 if (!NT_STATUS_IS_OK(result)) {
5470 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5472 switch (r->in.level) {
5474 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5475 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5476 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5477 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5478 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5479 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5480 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5485 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5486 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5495 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5496 if (u_lock_duration != -1)
5497 u_lock_duration /= 60;
5499 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5501 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5502 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5503 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5506 return NT_STATUS_INVALID_INFO_CLASS;
5509 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5511 return NT_STATUS_OK;
5514 /****************************************************************
5515 _samr_GetDisplayEnumerationIndex
5516 ****************************************************************/
5518 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5519 struct samr_GetDisplayEnumerationIndex *r)
5521 struct samr_domain_info *dinfo;
5522 uint32_t max_entries = (uint32_t) -1;
5523 uint32_t enum_context = 0;
5525 uint32_t num_account = 0;
5526 struct samr_displayentry *entries = NULL;
5529 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5531 dinfo = policy_handle_find(p, r->in.domain_handle,
5532 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
5533 struct samr_domain_info, &status);
5534 if (!NT_STATUS_IS_OK(status)) {
5538 if ((r->in.level < 1) || (r->in.level > 3)) {
5539 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5540 "Unknown info level (%u)\n",
5542 return NT_STATUS_INVALID_INFO_CLASS;
5547 /* The following done as ROOT. Don't return without unbecome_root(). */
5549 switch (r->in.level) {
5551 if (dinfo->disp_info->users == NULL) {
5552 dinfo->disp_info->users = pdb_search_users(
5553 dinfo->disp_info, ACB_NORMAL);
5554 if (dinfo->disp_info->users == NULL) {
5556 return NT_STATUS_ACCESS_DENIED;
5558 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5559 "starting user enumeration at index %u\n",
5560 (unsigned int)enum_context));
5562 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5563 "using cached user enumeration at index %u\n",
5564 (unsigned int)enum_context));
5566 num_account = pdb_search_entries(dinfo->disp_info->users,
5567 enum_context, max_entries,
5571 if (dinfo->disp_info->machines == NULL) {
5572 dinfo->disp_info->machines = pdb_search_users(
5573 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
5574 if (dinfo->disp_info->machines == NULL) {
5576 return NT_STATUS_ACCESS_DENIED;
5578 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5579 "starting machine enumeration at index %u\n",
5580 (unsigned int)enum_context));
5582 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5583 "using cached machine enumeration at index %u\n",
5584 (unsigned int)enum_context));
5586 num_account = pdb_search_entries(dinfo->disp_info->machines,
5587 enum_context, max_entries,
5591 if (dinfo->disp_info->groups == NULL) {
5592 dinfo->disp_info->groups = pdb_search_groups(
5594 if (dinfo->disp_info->groups == NULL) {
5596 return NT_STATUS_ACCESS_DENIED;
5598 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5599 "starting group enumeration at index %u\n",
5600 (unsigned int)enum_context));
5602 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5603 "using cached group enumeration at index %u\n",
5604 (unsigned int)enum_context));
5606 num_account = pdb_search_entries(dinfo->disp_info->groups,
5607 enum_context, max_entries,
5612 smb_panic("info class changed");
5618 /* Ensure we cache this enumeration. */
5619 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
5621 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5622 r->in.name->string));
5624 for (i=0; i<num_account; i++) {
5625 if (strequal(entries[i].account_name, r->in.name->string)) {
5626 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5627 "found %s at idx %d\n",
5628 r->in.name->string, i));
5630 return NT_STATUS_OK;
5634 /* assuming account_name lives at the very end */
5635 *r->out.idx = num_account;
5637 return NT_STATUS_NO_MORE_ENTRIES;
5640 /****************************************************************
5641 _samr_GetDisplayEnumerationIndex2
5642 ****************************************************************/
5644 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5645 struct samr_GetDisplayEnumerationIndex2 *r)
5647 struct samr_GetDisplayEnumerationIndex q;
5649 q.in.domain_handle = r->in.domain_handle;
5650 q.in.level = r->in.level;
5651 q.in.name = r->in.name;
5653 q.out.idx = r->out.idx;
5655 return _samr_GetDisplayEnumerationIndex(p, &q);
5658 /****************************************************************
5659 ****************************************************************/
5661 NTSTATUS _samr_Shutdown(pipes_struct *p,
5662 struct samr_Shutdown *r)
5664 p->rng_fault_state = true;
5665 return NT_STATUS_NOT_IMPLEMENTED;
5668 /****************************************************************
5669 ****************************************************************/
5671 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5672 struct samr_SetMemberAttributesOfGroup *r)
5674 p->rng_fault_state = true;
5675 return NT_STATUS_NOT_IMPLEMENTED;
5678 /****************************************************************
5679 ****************************************************************/
5681 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5682 struct samr_ChangePasswordUser *r)
5684 p->rng_fault_state = true;
5685 return NT_STATUS_NOT_IMPLEMENTED;
5688 /****************************************************************
5689 ****************************************************************/
5691 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5692 struct samr_TestPrivateFunctionsDomain *r)
5694 p->rng_fault_state = true;
5695 return NT_STATUS_NOT_IMPLEMENTED;
5698 /****************************************************************
5699 ****************************************************************/
5701 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5702 struct samr_TestPrivateFunctionsUser *r)
5704 p->rng_fault_state = true;
5705 return NT_STATUS_NOT_IMPLEMENTED;
5708 /****************************************************************
5709 ****************************************************************/
5711 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5712 struct samr_AddMultipleMembersToAlias *r)
5714 p->rng_fault_state = true;
5715 return NT_STATUS_NOT_IMPLEMENTED;
5718 /****************************************************************
5719 ****************************************************************/
5721 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5722 struct samr_RemoveMultipleMembersFromAlias *r)
5724 p->rng_fault_state = true;
5725 return NT_STATUS_NOT_IMPLEMENTED;
5728 /****************************************************************
5729 ****************************************************************/
5731 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5732 struct samr_OemChangePasswordUser2 *r)
5734 p->rng_fault_state = true;
5735 return NT_STATUS_NOT_IMPLEMENTED;
5738 /****************************************************************
5739 ****************************************************************/
5741 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5742 struct samr_SetBootKeyInformation *r)
5744 p->rng_fault_state = true;
5745 return NT_STATUS_NOT_IMPLEMENTED;
5748 /****************************************************************
5749 ****************************************************************/
5751 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5752 struct samr_GetBootKeyInformation *r)
5754 p->rng_fault_state = true;
5755 return NT_STATUS_NOT_IMPLEMENTED;
5758 /****************************************************************
5759 ****************************************************************/
5761 NTSTATUS _samr_RidToSid(pipes_struct *p,
5762 struct samr_RidToSid *r)
5764 p->rng_fault_state = true;
5765 return NT_STATUS_NOT_IMPLEMENTED;
5768 /****************************************************************
5769 ****************************************************************/
5771 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5772 struct samr_SetDsrmPassword *r)
5774 p->rng_fault_state = true;
5775 return NT_STATUS_NOT_IMPLEMENTED;
5778 /****************************************************************
5779 ****************************************************************/
5781 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5782 struct samr_ValidatePassword *r)
5784 p->rng_fault_state = true;
5785 return NT_STATUS_NOT_IMPLEMENTED;