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 "smbd/globals.h"
36 #include "../libcli/auth/libcli_auth.h"
39 #define DBGC_CLASS DBGC_RPC_SRV
41 #define SAMR_USR_RIGHTS_WRITE_PW \
42 ( READ_CONTROL_ACCESS | \
43 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
44 SAMR_USER_ACCESS_SET_LOC_COM)
45 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
46 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
48 #define DISP_INFO_CACHE_TIMEOUT 10
50 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
51 #define MAX_SAM_ENTRIES_W95 50
53 struct samr_connect_info {
57 struct samr_domain_info {
59 struct disp_info *disp_info;
62 struct samr_user_info {
66 struct samr_group_info {
70 struct samr_alias_info {
74 typedef struct disp_info {
75 DOM_SID sid; /* identify which domain this is. */
76 struct pdb_search *users; /* querydispinfo 1 and 4 */
77 struct pdb_search *machines; /* querydispinfo 2 */
78 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
79 struct pdb_search *aliases; /* enumaliases */
81 uint32_t enum_acb_mask;
82 struct pdb_search *enum_users; /* enumusers with a mask */
84 struct timed_event *cache_timeout_event; /* cache idle timeout
88 static const struct generic_mapping sam_generic_mapping = {
89 GENERIC_RIGHTS_SAM_READ,
90 GENERIC_RIGHTS_SAM_WRITE,
91 GENERIC_RIGHTS_SAM_EXECUTE,
92 GENERIC_RIGHTS_SAM_ALL_ACCESS};
93 static const struct generic_mapping dom_generic_mapping = {
94 GENERIC_RIGHTS_DOMAIN_READ,
95 GENERIC_RIGHTS_DOMAIN_WRITE,
96 GENERIC_RIGHTS_DOMAIN_EXECUTE,
97 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
98 static const struct generic_mapping usr_generic_mapping = {
99 GENERIC_RIGHTS_USER_READ,
100 GENERIC_RIGHTS_USER_WRITE,
101 GENERIC_RIGHTS_USER_EXECUTE,
102 GENERIC_RIGHTS_USER_ALL_ACCESS};
103 static const struct generic_mapping usr_nopwchange_generic_mapping = {
104 GENERIC_RIGHTS_USER_READ,
105 GENERIC_RIGHTS_USER_WRITE,
106 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
107 GENERIC_RIGHTS_USER_ALL_ACCESS};
108 static const struct generic_mapping grp_generic_mapping = {
109 GENERIC_RIGHTS_GROUP_READ,
110 GENERIC_RIGHTS_GROUP_WRITE,
111 GENERIC_RIGHTS_GROUP_EXECUTE,
112 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
113 static const struct generic_mapping ali_generic_mapping = {
114 GENERIC_RIGHTS_ALIAS_READ,
115 GENERIC_RIGHTS_ALIAS_WRITE,
116 GENERIC_RIGHTS_ALIAS_EXECUTE,
117 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
119 /*******************************************************************
120 *******************************************************************/
122 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
123 const struct generic_mapping *map,
124 DOM_SID *sid, uint32 sid_access )
126 DOM_SID domadmin_sid;
127 SEC_ACE ace[5]; /* at most 5 entries */
132 /* basic access for Everyone */
134 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
135 map->generic_execute | map->generic_read, 0);
137 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
139 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
140 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
141 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
142 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
144 /* Add Full Access for Domain Admins if we are a DC */
147 sid_copy( &domadmin_sid, get_global_sam_sid() );
148 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
149 init_sec_ace(&ace[i++], &domadmin_sid,
150 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
153 /* if we have a sid, give it some special access */
156 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
159 /* create the security descriptor */
161 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
162 return NT_STATUS_NO_MEMORY;
164 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
165 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
166 psa, sd_size)) == NULL)
167 return NT_STATUS_NO_MEMORY;
172 /*******************************************************************
173 Checks if access to an object should be granted, and returns that
174 level of access for further checks.
175 ********************************************************************/
177 NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token,
178 SE_PRIV *rights, uint32 rights_mask,
179 uint32 des_access, uint32 *acc_granted,
182 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
183 uint32 saved_mask = 0;
185 /* check privileges; certain SAM access bits should be overridden
186 by privileges (mostly having to do with creating/modifying/deleting
189 if (rights && !se_priv_equal(rights, &se_priv_none) &&
190 user_has_any_privilege(token, rights)) {
192 saved_mask = (des_access & rights_mask);
193 des_access &= ~saved_mask;
195 DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
200 /* check the security descriptor first */
202 status = se_access_check(psd, token, des_access, acc_granted);
203 if (NT_STATUS_IS_OK(status)) {
207 /* give root a free pass */
209 if ( geteuid() == sec_initial_uid() ) {
211 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
212 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
214 *acc_granted = des_access;
216 status = NT_STATUS_OK;
222 /* add in any bits saved during the privilege check (only
223 matters is status is ok) */
225 *acc_granted |= rights_mask;
227 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
228 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
229 des_access, *acc_granted));
235 /*******************************************************************
236 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
237 ********************************************************************/
239 void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
240 const struct unix_user_token *unix_token,
241 uint32_t *pacc_requested)
243 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
246 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
248 /* At least try for generic read|execute - Everyone gets that. */
249 *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
251 /* root gets anything. */
252 if (unix_token->uid == sec_initial_uid()) {
253 *pacc_requested |= GENERIC_ALL_ACCESS;
257 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
259 if (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) ||
260 is_sid_in_token(nt_token, &global_sid_Builtin_Account_Operators)) {
261 *pacc_requested |= GENERIC_ALL_ACCESS;
265 /* Full access for DOMAIN\Domain Admins. */
267 DOM_SID domadmin_sid;
268 sid_copy( &domadmin_sid, get_global_sam_sid() );
269 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
270 if (is_sid_in_token(nt_token, &domadmin_sid)) {
271 *pacc_requested |= GENERIC_ALL_ACCESS;
275 /* TODO ! Check privileges. */
278 /*******************************************************************
279 Fetch or create a dispinfo struct.
280 ********************************************************************/
282 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
285 * We do a static cache for DISP_INFO's here. Explanation can be found
286 * in Jeremy's checkin message to r11793:
288 * Fix the SAMR cache so it works across completely insane
289 * client behaviour (ie.:
290 * open pipe/open SAMR handle/enumerate 0 - 1024
291 * close SAMR handle, close pipe.
292 * open pipe/open SAMR handle/enumerate 1024 - 2048...
293 * close SAMR handle, close pipe.
294 * And on ad-nausium. Amazing.... probably object-oriented
295 * client side programming in action yet again.
296 * This change should *massively* improve performance when
297 * enumerating users from an LDAP database.
300 * "Our" and the builtin domain are the only ones where we ever
301 * enumerate stuff, so just cache 2 entries.
304 static struct disp_info *builtin_dispinfo;
305 static struct disp_info *domain_dispinfo;
307 /* There are two cases to consider here:
308 1) The SID is a domain SID and we look for an equality match, or
309 2) This is an account SID and so we return the DISP_INFO* for our
316 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
318 * Necessary only once, but it does not really hurt.
320 if (builtin_dispinfo == NULL) {
321 builtin_dispinfo = talloc_zero(
322 talloc_autofree_context(), struct disp_info);
323 if (builtin_dispinfo == NULL) {
327 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
329 return builtin_dispinfo;
332 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
334 * Necessary only once, but it does not really hurt.
336 if (domain_dispinfo == NULL) {
337 domain_dispinfo = talloc_zero(
338 talloc_autofree_context(), struct disp_info);
339 if (domain_dispinfo == NULL) {
343 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
345 return domain_dispinfo;
351 /*******************************************************************
352 Function to free the per SID data.
353 ********************************************************************/
355 static void free_samr_cache(DISP_INFO *disp_info)
357 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
358 sid_string_dbg(&disp_info->sid)));
360 /* We need to become root here because the paged search might have to
361 * tell the LDAP server we're not interested in the rest anymore. */
365 TALLOC_FREE(disp_info->users);
366 TALLOC_FREE(disp_info->machines);
367 TALLOC_FREE(disp_info->groups);
368 TALLOC_FREE(disp_info->aliases);
369 TALLOC_FREE(disp_info->enum_users);
374 /*******************************************************************
375 Idle event handler. Throw away the disp info cache.
376 ********************************************************************/
378 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
379 struct timed_event *te,
383 DISP_INFO *disp_info = (DISP_INFO *)private_data;
385 TALLOC_FREE(disp_info->cache_timeout_event);
387 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
389 free_samr_cache(disp_info);
392 /*******************************************************************
393 Setup cache removal idle event handler.
394 ********************************************************************/
396 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
398 /* Remove any pending timeout and update. */
400 TALLOC_FREE(disp_info->cache_timeout_event);
402 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
403 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
404 (unsigned int)secs_fromnow ));
406 disp_info->cache_timeout_event = event_add_timed(
407 smbd_event_context(), NULL,
408 timeval_current_ofs(secs_fromnow, 0),
409 disp_info_cache_idle_timeout_handler, (void *)disp_info);
412 /*******************************************************************
413 Force flush any cache. We do this on any samr_set_xxx call.
414 We must also remove the timeout handler.
415 ********************************************************************/
417 static void force_flush_samr_cache(const struct dom_sid *sid)
419 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
421 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
425 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
426 TALLOC_FREE(disp_info->cache_timeout_event);
427 free_samr_cache(disp_info);
430 /*******************************************************************
431 Ensure password info is never given out. Paranioa... JRA.
432 ********************************************************************/
434 static void samr_clear_sam_passwd(struct samu *sam_pass)
440 /* These now zero out the old password */
442 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
443 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
446 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
448 struct samr_displayentry *entry;
450 if (sid_check_is_builtin(&info->sid)) {
451 /* No users in builtin. */
455 if (info->users == NULL) {
456 info->users = pdb_search_users(info, acct_flags);
457 if (info->users == NULL) {
461 /* Fetch the last possible entry, thus trigger an enumeration */
462 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
464 /* Ensure we cache this enumeration. */
465 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
467 return info->users->num_entries;
470 static uint32 count_sam_groups(struct disp_info *info)
472 struct samr_displayentry *entry;
474 if (sid_check_is_builtin(&info->sid)) {
475 /* No groups in builtin. */
479 if (info->groups == NULL) {
480 info->groups = pdb_search_groups(info);
481 if (info->groups == NULL) {
485 /* Fetch the last possible entry, thus trigger an enumeration */
486 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
488 /* Ensure we cache this enumeration. */
489 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
491 return info->groups->num_entries;
494 static uint32 count_sam_aliases(struct disp_info *info)
496 struct samr_displayentry *entry;
498 if (info->aliases == NULL) {
499 info->aliases = pdb_search_aliases(info, &info->sid);
500 if (info->aliases == NULL) {
504 /* Fetch the last possible entry, thus trigger an enumeration */
505 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
507 /* Ensure we cache this enumeration. */
508 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
510 return info->aliases->num_entries;
513 /*******************************************************************
515 ********************************************************************/
517 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
519 if (!close_policy_hnd(p, r->in.handle)) {
520 return NT_STATUS_INVALID_HANDLE;
523 ZERO_STRUCTP(r->out.handle);
528 /*******************************************************************
530 ********************************************************************/
532 NTSTATUS _samr_OpenDomain(pipes_struct *p,
533 struct samr_OpenDomain *r)
535 struct samr_connect_info *cinfo;
536 struct samr_domain_info *dinfo;
537 SEC_DESC *psd = NULL;
539 uint32 des_access = r->in.access_mask;
542 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
545 /* find the connection policy handle. */
547 cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
548 struct samr_connect_info, &status);
549 if (!NT_STATUS_IS_OK(status)) {
553 /*check if access can be granted as requested by client. */
554 map_max_allowed_access(p->server_info->ptok,
555 &p->server_info->utok,
558 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
559 se_map_generic( &des_access, &dom_generic_mapping );
562 * Users with SeMachineAccount or SeAddUser get additional
563 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
565 se_priv_copy( &se_rights, &se_machine_account );
566 se_priv_add( &se_rights, &se_add_users );
569 * Users with SeAddUser get the ability to manipulate groups
572 if (user_has_any_privilege(p->server_info->ptok, &se_add_users)) {
573 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
574 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
575 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
576 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
577 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
580 status = access_check_object( psd, p->server_info->ptok,
581 &se_rights, extra_access, des_access,
582 &acc_granted, "_samr_OpenDomain" );
584 if ( !NT_STATUS_IS_OK(status) )
587 if (!sid_check_is_domain(r->in.sid) &&
588 !sid_check_is_builtin(r->in.sid)) {
589 return NT_STATUS_NO_SUCH_DOMAIN;
592 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
593 struct samr_domain_info, &status);
594 if (!NT_STATUS_IS_OK(status)) {
597 dinfo->sid = *r->in.sid;
598 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
600 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
605 /*******************************************************************
607 ********************************************************************/
609 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
610 struct samr_GetUserPwInfo *r)
612 struct samr_user_info *uinfo;
613 enum lsa_SidType sid_type;
614 uint32_t min_password_length = 0;
615 uint32_t password_properties = 0;
619 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
621 uinfo = policy_handle_find(p, r->in.user_handle,
622 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
623 struct samr_user_info, &status);
624 if (!NT_STATUS_IS_OK(status)) {
628 if (!sid_check_is_in_our_domain(&uinfo->sid)) {
629 return NT_STATUS_OBJECT_TYPE_MISMATCH;
633 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
636 return NT_STATUS_NO_SUCH_USER;
642 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
643 &min_password_length);
644 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
645 &password_properties);
648 if (lp_check_password_script() && *lp_check_password_script()) {
649 password_properties |= DOMAIN_PASSWORD_COMPLEX;
657 r->out.info->min_password_length = min_password_length;
658 r->out.info->password_properties = password_properties;
660 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
665 /*******************************************************************
667 ********************************************************************/
669 NTSTATUS _samr_SetSecurity(pipes_struct *p,
670 struct samr_SetSecurity *r)
672 struct samr_user_info *uinfo;
676 struct samu *sampass=NULL;
679 uinfo = policy_handle_find(p, r->in.handle,
680 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
681 struct samr_user_info, &status);
682 if (!NT_STATUS_IS_OK(status)) {
686 if (!(sampass = samu_new( p->mem_ctx))) {
687 DEBUG(0,("No memory!\n"));
688 return NT_STATUS_NO_MEMORY;
691 /* get the user record */
693 ret = pdb_getsampwsid(sampass, &uinfo->sid);
697 DEBUG(4, ("User %s not found\n",
698 sid_string_dbg(&uinfo->sid)));
699 TALLOC_FREE(sampass);
700 return NT_STATUS_INVALID_HANDLE;
703 dacl = r->in.sdbuf->sd->dacl;
704 for (i=0; i < dacl->num_aces; i++) {
705 if (sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
706 ret = pdb_set_pass_can_change(sampass,
707 (dacl->aces[i].access_mask &
708 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
715 TALLOC_FREE(sampass);
716 return NT_STATUS_ACCESS_DENIED;
720 status = pdb_update_sam_account(sampass);
723 TALLOC_FREE(sampass);
728 /*******************************************************************
729 build correct perms based on policies and password times for _samr_query_sec_obj
730 *******************************************************************/
731 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
733 struct samu *sampass=NULL;
736 if ( !(sampass = samu_new( mem_ctx )) ) {
737 DEBUG(0,("No memory!\n"));
742 ret = pdb_getsampwsid(sampass, user_sid);
746 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
747 TALLOC_FREE(sampass);
751 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
753 if (pdb_get_pass_can_change(sampass)) {
754 TALLOC_FREE(sampass);
757 TALLOC_FREE(sampass);
762 /*******************************************************************
764 ********************************************************************/
766 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
767 struct samr_QuerySecurity *r)
769 struct samr_connect_info *cinfo;
770 struct samr_domain_info *dinfo;
771 struct samr_user_info *uinfo;
772 struct samr_group_info *ginfo;
773 struct samr_alias_info *ainfo;
775 SEC_DESC * psd = NULL;
778 cinfo = policy_handle_find(p, r->in.handle,
779 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
780 struct samr_connect_info, &status);
781 if (NT_STATUS_IS_OK(status)) {
782 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
783 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
784 &sam_generic_mapping, NULL, 0);
788 dinfo = policy_handle_find(p, r->in.handle,
789 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
790 struct samr_domain_info, &status);
791 if (NT_STATUS_IS_OK(status)) {
792 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
793 "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
795 * TODO: Builtin probably needs a different SD with restricted
798 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
799 &dom_generic_mapping, NULL, 0);
803 uinfo = policy_handle_find(p, r->in.handle,
804 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
805 struct samr_user_info, &status);
806 if (NT_STATUS_IS_OK(status)) {
807 DEBUG(10,("_samr_QuerySecurity: querying security on user "
808 "Object with SID: %s\n",
809 sid_string_dbg(&uinfo->sid)));
810 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
811 status = make_samr_object_sd(
812 p->mem_ctx, &psd, &sd_size,
813 &usr_generic_mapping,
814 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
816 status = make_samr_object_sd(
817 p->mem_ctx, &psd, &sd_size,
818 &usr_nopwchange_generic_mapping,
819 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
824 ginfo = policy_handle_find(p, r->in.handle,
825 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
826 struct samr_group_info, &status);
827 if (NT_STATUS_IS_OK(status)) {
829 * TODO: different SDs have to be generated for aliases groups
830 * and users. Currently all three get a default user SD
832 DEBUG(10,("_samr_QuerySecurity: querying security on group "
833 "Object with SID: %s\n",
834 sid_string_dbg(&ginfo->sid)));
835 status = make_samr_object_sd(
836 p->mem_ctx, &psd, &sd_size,
837 &usr_nopwchange_generic_mapping,
838 &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
842 ainfo = policy_handle_find(p, r->in.handle,
843 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
844 struct samr_alias_info, &status);
845 if (NT_STATUS_IS_OK(status)) {
847 * TODO: different SDs have to be generated for aliases groups
848 * and users. Currently all three get a default user SD
850 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
851 "Object with SID: %s\n",
852 sid_string_dbg(&ainfo->sid)));
853 status = make_samr_object_sd(
854 p->mem_ctx, &psd, &sd_size,
855 &usr_nopwchange_generic_mapping,
856 &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
860 return NT_STATUS_OBJECT_TYPE_MISMATCH;
862 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
863 return NT_STATUS_NO_MEMORY;
868 /*******************************************************************
869 makes a SAM_ENTRY / UNISTR2* structure from a user list.
870 ********************************************************************/
872 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
873 struct samr_SamEntry **sam_pp,
874 uint32_t num_entries,
876 struct samr_displayentry *entries)
879 struct samr_SamEntry *sam;
883 if (num_entries == 0) {
887 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
889 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
890 return NT_STATUS_NO_MEMORY;
893 for (i = 0; i < num_entries; i++) {
896 * usrmgr expects a non-NULL terminated string with
897 * trust relationships
899 if (entries[i].acct_flags & ACB_DOMTRUST) {
900 init_unistr2(&uni_temp_name, entries[i].account_name,
903 init_unistr2(&uni_temp_name, entries[i].account_name,
907 init_lsa_String(&sam[i].name, entries[i].account_name);
908 sam[i].idx = entries[i].rid;
916 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
918 /*******************************************************************
919 _samr_EnumDomainUsers
920 ********************************************************************/
922 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
923 struct samr_EnumDomainUsers *r)
926 struct samr_domain_info *dinfo;
928 uint32 enum_context = *r->in.resume_handle;
929 enum remote_arch_types ra_type = get_remote_arch();
930 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
931 uint32 max_entries = max_sam_entries;
932 struct samr_displayentry *entries = NULL;
933 struct samr_SamArray *samr_array = NULL;
934 struct samr_SamEntry *samr_entries = NULL;
936 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
938 dinfo = policy_handle_find(p, r->in.domain_handle,
939 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
940 struct samr_domain_info, &status);
941 if (!NT_STATUS_IS_OK(status)) {
945 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
947 return NT_STATUS_NO_MEMORY;
949 *r->out.sam = samr_array;
951 if (sid_check_is_builtin(&dinfo->sid)) {
952 /* No users in builtin. */
953 *r->out.resume_handle = *r->in.resume_handle;
954 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
962 if ((dinfo->disp_info->enum_users != NULL) &&
963 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
964 TALLOC_FREE(dinfo->disp_info->enum_users);
967 if (dinfo->disp_info->enum_users == NULL) {
968 dinfo->disp_info->enum_users = pdb_search_users(
969 dinfo->disp_info, r->in.acct_flags);
970 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
973 if (dinfo->disp_info->enum_users == NULL) {
974 /* END AS ROOT !!!! */
976 return NT_STATUS_ACCESS_DENIED;
979 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
980 enum_context, max_entries,
983 /* END AS ROOT !!!! */
987 if (num_account == 0) {
988 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
990 *r->out.resume_handle = *r->in.resume_handle;
994 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
995 num_account, enum_context,
997 if (!NT_STATUS_IS_OK(status)) {
1001 if (max_entries <= num_account) {
1002 status = STATUS_MORE_ENTRIES;
1004 status = NT_STATUS_OK;
1007 /* Ensure we cache this enumeration. */
1008 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1010 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1012 samr_array->count = num_account;
1013 samr_array->entries = samr_entries;
1015 *r->out.resume_handle = *r->in.resume_handle + num_account;
1016 *r->out.num_entries = num_account;
1018 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1023 /*******************************************************************
1024 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1025 ********************************************************************/
1027 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1028 struct samr_SamEntry **sam_pp,
1029 uint32_t num_sam_entries,
1030 struct samr_displayentry *entries)
1032 struct samr_SamEntry *sam;
1037 if (num_sam_entries == 0) {
1041 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1046 for (i = 0; i < num_sam_entries; i++) {
1048 * JRA. I think this should include the null. TNG does not.
1050 init_lsa_String(&sam[i].name, entries[i].account_name);
1051 sam[i].idx = entries[i].rid;
1057 /*******************************************************************
1058 _samr_EnumDomainGroups
1059 ********************************************************************/
1061 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1062 struct samr_EnumDomainGroups *r)
1065 struct samr_domain_info *dinfo;
1066 struct samr_displayentry *groups;
1068 struct samr_SamArray *samr_array = NULL;
1069 struct samr_SamEntry *samr_entries = NULL;
1071 dinfo = policy_handle_find(p, r->in.domain_handle,
1072 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1073 struct samr_domain_info, &status);
1074 if (!NT_STATUS_IS_OK(status)) {
1078 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1080 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1082 return NT_STATUS_NO_MEMORY;
1084 *r->out.sam = samr_array;
1086 if (sid_check_is_builtin(&dinfo->sid)) {
1087 /* No groups in builtin. */
1088 *r->out.resume_handle = *r->in.resume_handle;
1089 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1093 /* the domain group array is being allocated in the function below */
1097 if (dinfo->disp_info->groups == NULL) {
1098 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1100 if (dinfo->disp_info->groups == NULL) {
1102 return NT_STATUS_ACCESS_DENIED;
1106 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1107 *r->in.resume_handle,
1108 MAX_SAM_ENTRIES, &groups);
1111 /* Ensure we cache this enumeration. */
1112 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1114 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1115 num_groups, groups);
1117 if (MAX_SAM_ENTRIES <= num_groups) {
1118 status = STATUS_MORE_ENTRIES;
1120 status = NT_STATUS_OK;
1123 samr_array->count = num_groups;
1124 samr_array->entries = samr_entries;
1126 *r->out.num_entries = num_groups;
1127 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1129 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1134 /*******************************************************************
1135 _samr_EnumDomainAliases
1136 ********************************************************************/
1138 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1139 struct samr_EnumDomainAliases *r)
1142 struct samr_domain_info *dinfo;
1143 struct samr_displayentry *aliases;
1144 uint32 num_aliases = 0;
1145 struct samr_SamArray *samr_array = NULL;
1146 struct samr_SamEntry *samr_entries = NULL;
1148 dinfo = policy_handle_find(p, r->in.domain_handle,
1149 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1150 struct samr_domain_info, &status);
1151 if (!NT_STATUS_IS_OK(status)) {
1155 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1156 sid_string_dbg(&dinfo->sid)));
1158 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1160 return NT_STATUS_NO_MEMORY;
1165 if (dinfo->disp_info->aliases == NULL) {
1166 dinfo->disp_info->aliases = pdb_search_aliases(
1167 dinfo->disp_info, &dinfo->sid);
1168 if (dinfo->disp_info->aliases == NULL) {
1170 return NT_STATUS_ACCESS_DENIED;
1174 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1175 *r->in.resume_handle,
1176 MAX_SAM_ENTRIES, &aliases);
1179 /* Ensure we cache this enumeration. */
1180 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1182 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1183 num_aliases, aliases);
1185 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1187 if (MAX_SAM_ENTRIES <= num_aliases) {
1188 status = STATUS_MORE_ENTRIES;
1190 status = NT_STATUS_OK;
1193 samr_array->count = num_aliases;
1194 samr_array->entries = samr_entries;
1196 *r->out.sam = samr_array;
1197 *r->out.num_entries = num_aliases;
1198 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1203 /*******************************************************************
1204 inits a samr_DispInfoGeneral structure.
1205 ********************************************************************/
1207 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1208 struct samr_DispInfoGeneral *r,
1209 uint32_t num_entries,
1211 struct samr_displayentry *entries)
1215 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1217 if (num_entries == 0) {
1218 return NT_STATUS_OK;
1221 r->count = num_entries;
1223 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1225 return NT_STATUS_NO_MEMORY;
1228 for (i = 0; i < num_entries ; i++) {
1230 init_lsa_String(&r->entries[i].account_name,
1231 entries[i].account_name);
1233 init_lsa_String(&r->entries[i].description,
1234 entries[i].description);
1236 init_lsa_String(&r->entries[i].full_name,
1237 entries[i].fullname);
1239 r->entries[i].rid = entries[i].rid;
1240 r->entries[i].acct_flags = entries[i].acct_flags;
1241 r->entries[i].idx = start_idx+i+1;
1244 return NT_STATUS_OK;
1247 /*******************************************************************
1248 inits a samr_DispInfoFull structure.
1249 ********************************************************************/
1251 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1252 struct samr_DispInfoFull *r,
1253 uint32_t num_entries,
1255 struct samr_displayentry *entries)
1259 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1261 if (num_entries == 0) {
1262 return NT_STATUS_OK;
1265 r->count = num_entries;
1267 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1269 return NT_STATUS_NO_MEMORY;
1272 for (i = 0; i < num_entries ; i++) {
1274 init_lsa_String(&r->entries[i].account_name,
1275 entries[i].account_name);
1277 init_lsa_String(&r->entries[i].description,
1278 entries[i].description);
1280 r->entries[i].rid = entries[i].rid;
1281 r->entries[i].acct_flags = entries[i].acct_flags;
1282 r->entries[i].idx = start_idx+i+1;
1285 return NT_STATUS_OK;
1288 /*******************************************************************
1289 inits a samr_DispInfoFullGroups structure.
1290 ********************************************************************/
1292 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1293 struct samr_DispInfoFullGroups *r,
1294 uint32_t num_entries,
1296 struct samr_displayentry *entries)
1300 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1302 if (num_entries == 0) {
1303 return NT_STATUS_OK;
1306 r->count = num_entries;
1308 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1310 return NT_STATUS_NO_MEMORY;
1313 for (i = 0; i < num_entries ; i++) {
1315 init_lsa_String(&r->entries[i].account_name,
1316 entries[i].account_name);
1318 init_lsa_String(&r->entries[i].description,
1319 entries[i].description);
1321 r->entries[i].rid = entries[i].rid;
1322 r->entries[i].acct_flags = entries[i].acct_flags;
1323 r->entries[i].idx = start_idx+i+1;
1326 return NT_STATUS_OK;
1329 /*******************************************************************
1330 inits a samr_DispInfoAscii structure.
1331 ********************************************************************/
1333 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1334 struct samr_DispInfoAscii *r,
1335 uint32_t num_entries,
1337 struct samr_displayentry *entries)
1341 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1343 if (num_entries == 0) {
1344 return NT_STATUS_OK;
1347 r->count = num_entries;
1349 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1351 return NT_STATUS_NO_MEMORY;
1354 for (i = 0; i < num_entries ; i++) {
1356 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1357 entries[i].account_name);
1359 r->entries[i].idx = start_idx+i+1;
1362 return NT_STATUS_OK;
1365 /*******************************************************************
1366 inits a samr_DispInfoAscii structure.
1367 ********************************************************************/
1369 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1370 struct samr_DispInfoAscii *r,
1371 uint32_t num_entries,
1373 struct samr_displayentry *entries)
1377 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1379 if (num_entries == 0) {
1380 return NT_STATUS_OK;
1383 r->count = num_entries;
1385 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1387 return NT_STATUS_NO_MEMORY;
1390 for (i = 0; i < num_entries ; i++) {
1392 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1393 entries[i].account_name);
1395 r->entries[i].idx = start_idx+i+1;
1398 return NT_STATUS_OK;
1401 /*******************************************************************
1402 _samr_QueryDisplayInfo
1403 ********************************************************************/
1405 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1406 struct samr_QueryDisplayInfo *r)
1409 struct samr_domain_info *dinfo;
1410 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1412 uint32 max_entries = r->in.max_entries;
1414 union samr_DispInfo *disp_info = r->out.info;
1417 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1418 uint32 num_account = 0;
1419 enum remote_arch_types ra_type = get_remote_arch();
1420 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1421 struct samr_displayentry *entries = NULL;
1423 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1425 dinfo = policy_handle_find(p, r->in.domain_handle,
1426 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1427 struct samr_domain_info, &status);
1428 if (!NT_STATUS_IS_OK(status)) {
1432 if (sid_check_is_builtin(&dinfo->sid)) {
1433 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1434 return NT_STATUS_OK;
1438 * calculate how many entries we will return.
1440 * - the number of entries the client asked
1441 * - our limit on that
1442 * - the starting point (enumeration context)
1443 * - the buffer size the client will accept
1447 * We are a lot more like W2K. Instead of reading the SAM
1448 * each time to find the records we need to send back,
1449 * we read it once and link that copy to the sam handle.
1450 * For large user list (over the MAX_SAM_ENTRIES)
1451 * it's a definitive win.
1452 * second point to notice: between enumerations
1453 * our sam is now the same as it's a snapshoot.
1454 * third point: got rid of the static SAM_USER_21 struct
1455 * no more intermediate.
1456 * con: it uses much more memory, as a full copy is stored
1459 * If you want to change it, think twice and think
1460 * of the second point , that's really important.
1465 if ((r->in.level < 1) || (r->in.level > 5)) {
1466 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1467 (unsigned int)r->in.level ));
1468 return NT_STATUS_INVALID_INFO_CLASS;
1471 /* first limit the number of entries we will return */
1472 if (r->in.max_entries > max_sam_entries) {
1473 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1474 "entries, limiting to %d\n", r->in.max_entries,
1476 max_entries = max_sam_entries;
1479 /* calculate the size and limit on the number of entries we will
1482 temp_size=max_entries*struct_size;
1484 if (temp_size > r->in.buf_size) {
1485 max_entries = MIN((r->in.buf_size / struct_size),max_entries);;
1486 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1487 "only %d entries\n", max_entries));
1492 /* THe following done as ROOT. Don't return without unbecome_root(). */
1494 switch (r->in.level) {
1497 if (dinfo->disp_info->users == NULL) {
1498 dinfo->disp_info->users = pdb_search_users(
1499 dinfo->disp_info, ACB_NORMAL);
1500 if (dinfo->disp_info->users == NULL) {
1502 return NT_STATUS_ACCESS_DENIED;
1504 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1505 (unsigned int)r->in.start_idx));
1507 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1508 (unsigned int)r->in.start_idx));
1511 num_account = pdb_search_entries(dinfo->disp_info->users,
1512 r->in.start_idx, max_entries,
1516 if (dinfo->disp_info->machines == NULL) {
1517 dinfo->disp_info->machines = pdb_search_users(
1518 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1519 if (dinfo->disp_info->machines == NULL) {
1521 return NT_STATUS_ACCESS_DENIED;
1523 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1524 (unsigned int)r->in.start_idx));
1526 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1527 (unsigned int)r->in.start_idx));
1530 num_account = pdb_search_entries(dinfo->disp_info->machines,
1531 r->in.start_idx, max_entries,
1536 if (dinfo->disp_info->groups == NULL) {
1537 dinfo->disp_info->groups = pdb_search_groups(
1539 if (dinfo->disp_info->groups == NULL) {
1541 return NT_STATUS_ACCESS_DENIED;
1543 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1544 (unsigned int)r->in.start_idx));
1546 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1547 (unsigned int)r->in.start_idx));
1550 num_account = pdb_search_entries(dinfo->disp_info->groups,
1551 r->in.start_idx, max_entries,
1556 smb_panic("info class changed");
1562 /* Now create reply structure */
1563 switch (r->in.level) {
1565 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1566 num_account, r->in.start_idx,
1570 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1571 num_account, r->in.start_idx,
1575 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1576 num_account, r->in.start_idx,
1580 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1581 num_account, r->in.start_idx,
1585 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1586 num_account, r->in.start_idx,
1590 smb_panic("info class changed");
1594 if (!NT_STATUS_IS_OK(disp_ret))
1597 if (max_entries <= num_account) {
1598 status = STATUS_MORE_ENTRIES;
1600 status = NT_STATUS_OK;
1603 /* Ensure we cache this enumeration. */
1604 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1606 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1608 *r->out.total_size = num_account * struct_size;
1609 *r->out.returned_size = num_account ? temp_size : 0;
1614 /****************************************************************
1615 _samr_QueryDisplayInfo2
1616 ****************************************************************/
1618 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1619 struct samr_QueryDisplayInfo2 *r)
1621 struct samr_QueryDisplayInfo q;
1623 q.in.domain_handle = r->in.domain_handle;
1624 q.in.level = r->in.level;
1625 q.in.start_idx = r->in.start_idx;
1626 q.in.max_entries = r->in.max_entries;
1627 q.in.buf_size = r->in.buf_size;
1629 q.out.total_size = r->out.total_size;
1630 q.out.returned_size = r->out.returned_size;
1631 q.out.info = r->out.info;
1633 return _samr_QueryDisplayInfo(p, &q);
1636 /****************************************************************
1637 _samr_QueryDisplayInfo3
1638 ****************************************************************/
1640 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1641 struct samr_QueryDisplayInfo3 *r)
1643 struct samr_QueryDisplayInfo q;
1645 q.in.domain_handle = r->in.domain_handle;
1646 q.in.level = r->in.level;
1647 q.in.start_idx = r->in.start_idx;
1648 q.in.max_entries = r->in.max_entries;
1649 q.in.buf_size = r->in.buf_size;
1651 q.out.total_size = r->out.total_size;
1652 q.out.returned_size = r->out.returned_size;
1653 q.out.info = r->out.info;
1655 return _samr_QueryDisplayInfo(p, &q);
1658 /*******************************************************************
1659 _samr_QueryAliasInfo
1660 ********************************************************************/
1662 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1663 struct samr_QueryAliasInfo *r)
1665 struct samr_alias_info *ainfo;
1666 struct acct_info info;
1668 union samr_AliasInfo *alias_info = NULL;
1669 const char *alias_name = NULL;
1670 const char *alias_description = NULL;
1672 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1674 ainfo = policy_handle_find(p, r->in.alias_handle,
1675 SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1676 struct samr_alias_info, &status);
1677 if (!NT_STATUS_IS_OK(status)) {
1681 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1683 return NT_STATUS_NO_MEMORY;
1687 status = pdb_get_aliasinfo(&ainfo->sid, &info);
1690 if ( !NT_STATUS_IS_OK(status))
1693 /* FIXME: info contains fstrings */
1694 alias_name = talloc_strdup(r, info.acct_name);
1695 alias_description = talloc_strdup(r, info.acct_desc);
1697 switch (r->in.level) {
1699 alias_info->all.name.string = alias_name;
1700 alias_info->all.num_members = 1; /* ??? */
1701 alias_info->all.description.string = alias_description;
1704 alias_info->name.string = alias_name;
1706 case ALIASINFODESCRIPTION:
1707 alias_info->description.string = alias_description;
1710 return NT_STATUS_INVALID_INFO_CLASS;
1713 *r->out.info = alias_info;
1715 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1717 return NT_STATUS_OK;
1720 /*******************************************************************
1722 ********************************************************************/
1724 NTSTATUS _samr_LookupNames(pipes_struct *p,
1725 struct samr_LookupNames *r)
1727 struct samr_domain_info *dinfo;
1730 enum lsa_SidType *type;
1732 int num_rids = r->in.num_names;
1733 struct samr_Ids rids, types;
1734 uint32_t num_mapped = 0;
1736 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1738 dinfo = policy_handle_find(p, r->in.domain_handle,
1739 0 /* Don't know the acc_bits yet */, NULL,
1740 struct samr_domain_info, &status);
1741 if (!NT_STATUS_IS_OK(status)) {
1745 if (num_rids > MAX_SAM_ENTRIES) {
1746 num_rids = MAX_SAM_ENTRIES;
1747 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1750 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1751 NT_STATUS_HAVE_NO_MEMORY(rid);
1753 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1754 NT_STATUS_HAVE_NO_MEMORY(type);
1756 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1757 sid_string_dbg(&dinfo->sid)));
1759 for (i = 0; i < num_rids; i++) {
1761 status = NT_STATUS_NONE_MAPPED;
1762 type[i] = SID_NAME_UNKNOWN;
1764 rid[i] = 0xffffffff;
1766 if (sid_check_is_builtin(&dinfo->sid)) {
1767 if (lookup_builtin_name(r->in.names[i].string,
1770 type[i] = SID_NAME_ALIAS;
1773 lookup_global_sam_name(r->in.names[i].string, 0,
1777 if (type[i] != SID_NAME_UNKNOWN) {
1782 if (num_mapped == num_rids) {
1783 status = NT_STATUS_OK;
1784 } else if (num_mapped == 0) {
1785 status = NT_STATUS_NONE_MAPPED;
1787 status = STATUS_SOME_UNMAPPED;
1790 rids.count = num_rids;
1793 types.count = num_rids;
1796 *r->out.rids = rids;
1797 *r->out.types = types;
1799 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1804 /****************************************************************
1805 _samr_ChangePasswordUser
1806 ****************************************************************/
1808 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1809 struct samr_ChangePasswordUser *r)
1813 struct samr_user_info *uinfo;
1815 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1816 struct samr_Password lm_pwd, nt_pwd;
1818 uinfo = policy_handle_find(p, r->in.user_handle,
1819 SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1820 struct samr_user_info, &status);
1821 if (!NT_STATUS_IS_OK(status)) {
1825 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1826 sid_string_dbg(&uinfo->sid)));
1828 if (!(pwd = samu_new(NULL))) {
1829 return NT_STATUS_NO_MEMORY;
1833 ret = pdb_getsampwsid(pwd, &uinfo->sid);
1838 return NT_STATUS_WRONG_PASSWORD;
1842 const uint8_t *lm_pass, *nt_pass;
1844 lm_pass = pdb_get_lanman_passwd(pwd);
1845 nt_pass = pdb_get_nt_passwd(pwd);
1847 if (!lm_pass || !nt_pass) {
1848 status = NT_STATUS_WRONG_PASSWORD;
1852 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1853 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1856 /* basic sanity checking on parameters. Do this before any database ops */
1857 if (!r->in.lm_present || !r->in.nt_present ||
1858 !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1859 !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1860 /* we should really handle a change with lm not
1862 status = NT_STATUS_INVALID_PARAMETER_MIX;
1866 /* decrypt and check the new lm hash */
1867 D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1868 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1869 if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1870 status = NT_STATUS_WRONG_PASSWORD;
1874 /* decrypt and check the new nt hash */
1875 D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1876 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1877 if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1878 status = NT_STATUS_WRONG_PASSWORD;
1882 /* The NT Cross is not required by Win2k3 R2, but if present
1883 check the nt cross hash */
1884 if (r->in.cross1_present && r->in.nt_cross) {
1885 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1886 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1887 status = NT_STATUS_WRONG_PASSWORD;
1892 /* The LM Cross is not required by Win2k3 R2, but if present
1893 check the lm cross hash */
1894 if (r->in.cross2_present && r->in.lm_cross) {
1895 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1896 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1897 status = NT_STATUS_WRONG_PASSWORD;
1902 if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1903 !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1904 status = NT_STATUS_ACCESS_DENIED;
1908 status = pdb_update_sam_account(pwd);
1915 /*******************************************************************
1916 _samr_ChangePasswordUser2
1917 ********************************************************************/
1919 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1920 struct samr_ChangePasswordUser2 *r)
1922 struct smbd_server_connection *sconn = smbd_server_conn;
1927 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1929 fstrcpy(user_name, r->in.account->string);
1930 fstrcpy(wks, r->in.server->string);
1932 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1935 * Pass the user through the NT -> unix user mapping
1939 (void)map_username(sconn, user_name);
1942 * UNIX username case mangling not required, pass_oem_change
1943 * is case insensitive.
1946 status = pass_oem_change(user_name,
1947 r->in.lm_password->data,
1948 r->in.lm_verifier->hash,
1949 r->in.nt_password->data,
1950 r->in.nt_verifier->hash,
1953 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1955 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1956 return NT_STATUS_WRONG_PASSWORD;
1962 /****************************************************************
1963 _samr_OemChangePasswordUser2
1964 ****************************************************************/
1966 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
1967 struct samr_OemChangePasswordUser2 *r)
1969 struct smbd_server_connection *sconn = smbd_server_conn;
1972 const char *wks = NULL;
1974 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1976 fstrcpy(user_name, r->in.account->string);
1977 if (r->in.server && r->in.server->string) {
1978 wks = r->in.server->string;
1981 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1984 * Pass the user through the NT -> unix user mapping
1988 (void)map_username(sconn, user_name);
1991 * UNIX username case mangling not required, pass_oem_change
1992 * is case insensitive.
1995 if (!r->in.hash || !r->in.password) {
1996 return NT_STATUS_INVALID_PARAMETER;
1999 status = pass_oem_change(user_name,
2000 r->in.password->data,
2006 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2007 return NT_STATUS_WRONG_PASSWORD;
2010 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2015 /*******************************************************************
2016 _samr_ChangePasswordUser3
2017 ********************************************************************/
2019 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
2020 struct samr_ChangePasswordUser3 *r)
2022 struct smbd_server_connection *sconn = smbd_server_conn;
2025 const char *wks = NULL;
2026 uint32 reject_reason;
2027 struct samr_DomInfo1 *dominfo = NULL;
2028 struct samr_ChangeReject *reject = NULL;
2031 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2033 fstrcpy(user_name, r->in.account->string);
2034 if (r->in.server && r->in.server->string) {
2035 wks = r->in.server->string;
2038 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2041 * Pass the user through the NT -> unix user mapping
2045 (void)map_username(sconn, user_name);
2048 * UNIX username case mangling not required, pass_oem_change
2049 * is case insensitive.
2052 status = pass_oem_change(user_name,
2053 r->in.lm_password->data,
2054 r->in.lm_verifier->hash,
2055 r->in.nt_password->data,
2056 r->in.nt_verifier->hash,
2058 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2059 return NT_STATUS_WRONG_PASSWORD;
2062 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2063 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2065 time_t u_expire, u_min_age;
2066 uint32 account_policy_temp;
2068 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2070 return NT_STATUS_NO_MEMORY;
2073 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2075 return NT_STATUS_NO_MEMORY;
2082 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2083 dominfo->min_password_length = tmp;
2085 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2086 dominfo->password_history_length = tmp;
2088 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2089 &dominfo->password_properties);
2091 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2092 u_expire = account_policy_temp;
2094 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2095 u_min_age = account_policy_temp;
2101 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2102 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2104 if (lp_check_password_script() && *lp_check_password_script()) {
2105 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2108 reject->reason = reject_reason;
2110 *r->out.dominfo = dominfo;
2111 *r->out.reject = reject;
2114 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2119 /*******************************************************************
2120 makes a SAMR_R_LOOKUP_RIDS structure.
2121 ********************************************************************/
2123 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2125 struct lsa_String **lsa_name_array_p)
2127 struct lsa_String *lsa_name_array = NULL;
2130 *lsa_name_array_p = NULL;
2132 if (num_names != 0) {
2133 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2134 if (!lsa_name_array) {
2139 for (i = 0; i < num_names; i++) {
2140 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2141 init_lsa_String(&lsa_name_array[i], names[i]);
2144 *lsa_name_array_p = lsa_name_array;
2149 /*******************************************************************
2151 ********************************************************************/
2153 NTSTATUS _samr_LookupRids(pipes_struct *p,
2154 struct samr_LookupRids *r)
2156 struct samr_domain_info *dinfo;
2159 enum lsa_SidType *attrs = NULL;
2160 uint32 *wire_attrs = NULL;
2161 int num_rids = (int)r->in.num_rids;
2163 struct lsa_Strings names_array;
2164 struct samr_Ids types_array;
2165 struct lsa_String *lsa_names = NULL;
2167 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2169 dinfo = policy_handle_find(p, r->in.domain_handle,
2170 0 /* Don't know the acc_bits yet */, NULL,
2171 struct samr_domain_info, &status);
2172 if (!NT_STATUS_IS_OK(status)) {
2176 if (num_rids > 1000) {
2177 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2178 "to samba4 idl this is not possible\n", num_rids));
2179 return NT_STATUS_UNSUCCESSFUL;
2183 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2184 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2185 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2187 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2188 return NT_STATUS_NO_MEMORY;
2195 become_root(); /* lookup_sid can require root privs */
2196 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2200 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2201 status = NT_STATUS_OK;
2204 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2206 return NT_STATUS_NO_MEMORY;
2209 /* Convert from enum lsa_SidType to uint32 for wire format. */
2210 for (i = 0; i < num_rids; i++) {
2211 wire_attrs[i] = (uint32)attrs[i];
2214 names_array.count = num_rids;
2215 names_array.names = lsa_names;
2217 types_array.count = num_rids;
2218 types_array.ids = wire_attrs;
2220 *r->out.names = names_array;
2221 *r->out.types = types_array;
2223 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2228 /*******************************************************************
2230 ********************************************************************/
2232 NTSTATUS _samr_OpenUser(pipes_struct *p,
2233 struct samr_OpenUser *r)
2235 struct samu *sampass=NULL;
2237 struct samr_domain_info *dinfo;
2238 struct samr_user_info *uinfo;
2239 SEC_DESC *psd = NULL;
2241 uint32 des_access = r->in.access_mask;
2242 uint32_t extra_access = 0;
2249 dinfo = policy_handle_find(p, r->in.domain_handle,
2250 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2251 struct samr_domain_info, &status);
2252 if (!NT_STATUS_IS_OK(status)) {
2256 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2257 return NT_STATUS_NO_MEMORY;
2260 /* append the user's RID to it */
2262 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2263 return NT_STATUS_NO_SUCH_USER;
2265 /* check if access can be granted as requested by client. */
2266 map_max_allowed_access(p->server_info->ptok,
2267 &p->server_info->utok,
2270 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2271 se_map_generic(&des_access, &usr_generic_mapping);
2274 * Get the sampass first as we need to check privilages
2275 * based on what kind of user object this is.
2276 * But don't reveal info too early if it didn't exist.
2280 ret=pdb_getsampwsid(sampass, &sid);
2283 se_priv_copy(&se_rights, &se_priv_none);
2286 * We do the override access checks on *open*, not at
2290 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2292 if ((acb_info & ACB_WSTRUST) &&
2293 user_has_any_privilege(p->server_info->ptok,
2294 &se_machine_account)) {
2296 * SeMachineAccount is needed to add
2297 * GENERIC_RIGHTS_USER_WRITE to a machine
2300 se_priv_add(&se_rights, &se_machine_account);
2301 DEBUG(10,("_samr_OpenUser: adding machine account "
2302 "rights to handle for user %s\n",
2303 pdb_get_username(sampass) ));
2305 if ((acb_info & ACB_NORMAL) &&
2306 user_has_any_privilege(p->server_info->ptok,
2309 * SeAddUsers is needed to add
2310 * GENERIC_RIGHTS_USER_WRITE to a normal
2313 se_priv_add(&se_rights, &se_add_users);
2314 DEBUG(10,("_samr_OpenUser: adding add user "
2315 "rights to handle for user %s\n",
2316 pdb_get_username(sampass) ));
2319 * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
2320 * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not
2321 * what Windows does but is a hack for people who haven't
2322 * set up privilages on groups in Samba.
2324 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2325 if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2326 DOMAIN_GROUP_RID_ADMINS)) {
2327 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2328 extra_access = GENERIC_RIGHTS_USER_WRITE;
2329 DEBUG(4,("_samr_OpenUser: Allowing "
2330 "GENERIC_RIGHTS_USER_WRITE for "
2336 TALLOC_FREE(sampass);
2338 nt_status = access_check_object(psd, p->server_info->ptok,
2339 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2340 &acc_granted, "_samr_OpenUser");
2342 if ( !NT_STATUS_IS_OK(nt_status) )
2345 /* check that the SID exists in our domain. */
2347 return NT_STATUS_NO_SUCH_USER;
2350 /* If we did the rid admins hack above, allow access. */
2351 acc_granted |= extra_access;
2353 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2354 struct samr_user_info, &nt_status);
2355 if (!NT_STATUS_IS_OK(nt_status)) {
2360 return NT_STATUS_OK;
2363 /*************************************************************************
2364 *************************************************************************/
2366 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2368 struct lsa_BinaryString **_r)
2370 struct lsa_BinaryString *r;
2373 return NT_STATUS_INVALID_PARAMETER;
2376 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2378 return NT_STATUS_NO_MEMORY;
2381 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2383 return NT_STATUS_NO_MEMORY;
2385 memcpy(r->array, blob->data, blob->length);
2386 r->size = blob->length;
2387 r->length = blob->length;
2390 return NT_STATUS_NO_MEMORY;
2395 return NT_STATUS_OK;
2398 /*************************************************************************
2400 *************************************************************************/
2402 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2403 struct samr_UserInfo1 *r,
2405 DOM_SID *domain_sid)
2407 const DOM_SID *sid_group;
2408 uint32_t primary_gid;
2411 sid_group = pdb_get_group_sid(pw);
2414 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2415 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2416 "which conflicts with the domain sid %s. Failing operation.\n",
2417 pdb_get_username(pw), sid_string_dbg(sid_group),
2418 sid_string_dbg(domain_sid)));
2419 return NT_STATUS_UNSUCCESSFUL;
2422 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2423 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2424 r->primary_gid = primary_gid;
2425 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2426 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2428 return NT_STATUS_OK;
2431 /*************************************************************************
2433 *************************************************************************/
2435 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2436 struct samr_UserInfo2 *r,
2439 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2440 r->unknown.string = NULL;
2441 r->country_code = 0;
2444 return NT_STATUS_OK;
2447 /*************************************************************************
2449 *************************************************************************/
2451 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2452 struct samr_UserInfo3 *r,
2454 DOM_SID *domain_sid)
2456 const DOM_SID *sid_user, *sid_group;
2457 uint32_t rid, primary_gid;
2459 sid_user = pdb_get_user_sid(pw);
2461 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2462 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2463 "the domain sid %s. Failing operation.\n",
2464 pdb_get_username(pw), sid_string_dbg(sid_user),
2465 sid_string_dbg(domain_sid)));
2466 return NT_STATUS_UNSUCCESSFUL;
2470 sid_group = pdb_get_group_sid(pw);
2473 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2474 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2475 "which conflicts with the domain sid %s. Failing operation.\n",
2476 pdb_get_username(pw), sid_string_dbg(sid_group),
2477 sid_string_dbg(domain_sid)));
2478 return NT_STATUS_UNSUCCESSFUL;
2481 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2482 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2483 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2484 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2485 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2487 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2488 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2489 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2490 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2491 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2492 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2493 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2495 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2497 r->primary_gid = primary_gid;
2498 r->acct_flags = pdb_get_acct_ctrl(pw);
2499 r->bad_password_count = pdb_get_bad_password_count(pw);
2500 r->logon_count = pdb_get_logon_count(pw);
2502 return NT_STATUS_OK;
2505 /*************************************************************************
2507 *************************************************************************/
2509 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2510 struct samr_UserInfo4 *r,
2513 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2515 return NT_STATUS_OK;
2518 /*************************************************************************
2520 *************************************************************************/
2522 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2523 struct samr_UserInfo5 *r,
2525 DOM_SID *domain_sid)
2527 const DOM_SID *sid_user, *sid_group;
2528 uint32_t rid, primary_gid;
2530 sid_user = pdb_get_user_sid(pw);
2532 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2533 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2534 "the domain sid %s. Failing operation.\n",
2535 pdb_get_username(pw), sid_string_dbg(sid_user),
2536 sid_string_dbg(domain_sid)));
2537 return NT_STATUS_UNSUCCESSFUL;
2541 sid_group = pdb_get_group_sid(pw);
2544 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2545 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2546 "which conflicts with the domain sid %s. Failing operation.\n",
2547 pdb_get_username(pw), sid_string_dbg(sid_group),
2548 sid_string_dbg(domain_sid)));
2549 return NT_STATUS_UNSUCCESSFUL;
2552 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2553 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2554 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2555 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2557 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2558 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2559 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2560 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2561 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2562 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2563 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2564 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2566 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2568 r->primary_gid = primary_gid;
2569 r->acct_flags = pdb_get_acct_ctrl(pw);
2570 r->bad_password_count = pdb_get_bad_password_count(pw);
2571 r->logon_count = pdb_get_logon_count(pw);
2573 return NT_STATUS_OK;
2576 /*************************************************************************
2578 *************************************************************************/
2580 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2581 struct samr_UserInfo6 *r,
2584 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2585 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2587 return NT_STATUS_OK;
2590 /*************************************************************************
2591 get_user_info_7. Safe. Only gives out account_name.
2592 *************************************************************************/
2594 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2595 struct samr_UserInfo7 *r,
2596 struct samu *smbpass)
2598 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2599 if (!r->account_name.string) {
2600 return NT_STATUS_NO_MEMORY;
2603 return NT_STATUS_OK;
2606 /*************************************************************************
2608 *************************************************************************/
2610 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2611 struct samr_UserInfo8 *r,
2614 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2616 return NT_STATUS_OK;
2619 /*************************************************************************
2620 get_user_info_9. Only gives out primary group SID.
2621 *************************************************************************/
2623 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2624 struct samr_UserInfo9 *r,
2625 struct samu *smbpass)
2627 r->primary_gid = pdb_get_group_rid(smbpass);
2629 return NT_STATUS_OK;
2632 /*************************************************************************
2634 *************************************************************************/
2636 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2637 struct samr_UserInfo10 *r,
2640 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2641 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2643 return NT_STATUS_OK;
2646 /*************************************************************************
2648 *************************************************************************/
2650 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2651 struct samr_UserInfo11 *r,
2654 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2656 return NT_STATUS_OK;
2659 /*************************************************************************
2661 *************************************************************************/
2663 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2664 struct samr_UserInfo12 *r,
2667 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2669 return NT_STATUS_OK;
2672 /*************************************************************************
2674 *************************************************************************/
2676 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2677 struct samr_UserInfo13 *r,
2680 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2682 return NT_STATUS_OK;
2685 /*************************************************************************
2687 *************************************************************************/
2689 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2690 struct samr_UserInfo14 *r,
2693 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2695 return NT_STATUS_OK;
2698 /*************************************************************************
2699 get_user_info_16. Safe. Only gives out acb bits.
2700 *************************************************************************/
2702 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2703 struct samr_UserInfo16 *r,
2704 struct samu *smbpass)
2706 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2708 return NT_STATUS_OK;
2711 /*************************************************************************
2713 *************************************************************************/
2715 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2716 struct samr_UserInfo17 *r,
2719 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2721 return NT_STATUS_OK;
2724 /*************************************************************************
2725 get_user_info_18. OK - this is the killer as it gives out password info.
2726 Ensure that this is only allowed on an encrypted connection with a root
2728 *************************************************************************/
2730 static NTSTATUS get_user_info_18(pipes_struct *p,
2731 TALLOC_CTX *mem_ctx,
2732 struct samr_UserInfo18 *r,
2735 struct samu *smbpass=NULL;
2740 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2741 return NT_STATUS_ACCESS_DENIED;
2744 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2745 return NT_STATUS_ACCESS_DENIED;
2749 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2752 if ( !(smbpass = samu_new( mem_ctx )) ) {
2753 return NT_STATUS_NO_MEMORY;
2756 ret = pdb_getsampwsid(smbpass, user_sid);
2759 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2760 TALLOC_FREE(smbpass);
2761 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2764 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2766 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2767 TALLOC_FREE(smbpass);
2768 return NT_STATUS_ACCOUNT_DISABLED;
2771 r->lm_pwd_active = true;
2772 r->nt_pwd_active = true;
2773 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2774 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2775 r->password_expired = 0; /* FIXME */
2777 TALLOC_FREE(smbpass);
2779 return NT_STATUS_OK;
2782 /*************************************************************************
2784 *************************************************************************/
2786 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2787 struct samr_UserInfo20 *r,
2788 struct samu *sampass)
2790 const char *munged_dial = NULL;
2793 struct lsa_BinaryString *parameters = NULL;
2797 munged_dial = pdb_get_munged_dial(sampass);
2799 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2800 munged_dial, (int)strlen(munged_dial)));
2803 blob = base64_decode_data_blob(munged_dial);
2805 blob = data_blob_string_const_null("");
2808 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2809 data_blob_free(&blob);
2810 if (!NT_STATUS_IS_OK(status)) {
2814 r->parameters = *parameters;
2816 return NT_STATUS_OK;
2820 /*************************************************************************
2822 *************************************************************************/
2824 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2825 struct samr_UserInfo21 *r,
2827 DOM_SID *domain_sid,
2828 uint32_t acc_granted)
2831 const DOM_SID *sid_user, *sid_group;
2832 uint32_t rid, primary_gid;
2833 NTTIME force_password_change;
2834 time_t must_change_time;
2835 struct lsa_BinaryString *parameters = NULL;
2836 const char *munged_dial = NULL;
2841 sid_user = pdb_get_user_sid(pw);
2843 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2844 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2845 "the domain sid %s. Failing operation.\n",
2846 pdb_get_username(pw), sid_string_dbg(sid_user),
2847 sid_string_dbg(domain_sid)));
2848 return NT_STATUS_UNSUCCESSFUL;
2852 sid_group = pdb_get_group_sid(pw);
2855 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2856 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2857 "which conflicts with the domain sid %s. Failing operation.\n",
2858 pdb_get_username(pw), sid_string_dbg(sid_group),
2859 sid_string_dbg(domain_sid)));
2860 return NT_STATUS_UNSUCCESSFUL;
2863 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2864 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2865 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2866 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2867 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2869 must_change_time = pdb_get_pass_must_change_time(pw);
2870 if (must_change_time == get_time_t_max()) {
2871 unix_to_nt_time_abs(&force_password_change, must_change_time);
2873 unix_to_nt_time(&force_password_change, must_change_time);
2876 munged_dial = pdb_get_munged_dial(pw);
2878 blob = base64_decode_data_blob(munged_dial);
2880 blob = data_blob_string_const_null("");
2883 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2884 data_blob_free(&blob);
2885 if (!NT_STATUS_IS_OK(status)) {
2889 r->force_password_change = force_password_change;
2891 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2892 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2893 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2894 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2895 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2896 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2897 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2898 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2899 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2901 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2902 r->parameters = *parameters;
2904 r->primary_gid = primary_gid;
2905 r->acct_flags = pdb_get_acct_ctrl(pw);
2906 r->bad_password_count = pdb_get_bad_password_count(pw);
2907 r->logon_count = pdb_get_logon_count(pw);
2908 r->fields_present = pdb_build_fields_present(pw);
2909 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2910 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2911 r->country_code = 0;
2913 r->lm_password_set = 0;
2914 r->nt_password_set = 0;
2919 Look at a user on a real NT4 PDC with usrmgr, press
2920 'ok'. Then you will see that fields_present is set to
2921 0x08f827fa. Look at the user immediately after that again,
2922 and you will see that 0x00fffff is returned. This solves
2923 the problem that you get access denied after having looked
2931 return NT_STATUS_OK;
2934 /*******************************************************************
2936 ********************************************************************/
2938 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2939 struct samr_QueryUserInfo *r)
2942 union samr_UserInfo *user_info = NULL;
2943 struct samr_user_info *uinfo;
2947 struct samu *pwd = NULL;
2948 uint32_t acc_required, acc_granted;
2950 switch (r->in.level) {
2951 case 1: /* UserGeneralInformation */
2952 /* USER_READ_GENERAL */
2953 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2955 case 2: /* UserPreferencesInformation */
2956 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2957 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2958 SAMR_USER_ACCESS_GET_NAME_ETC;
2960 case 3: /* UserLogonInformation */
2961 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2962 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2963 SAMR_USER_ACCESS_GET_LOCALE |
2964 SAMR_USER_ACCESS_GET_LOGONINFO |
2965 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2967 case 4: /* UserLogonHoursInformation */
2968 /* USER_READ_LOGON */
2969 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2971 case 5: /* UserAccountInformation */
2972 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2973 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2974 SAMR_USER_ACCESS_GET_LOCALE |
2975 SAMR_USER_ACCESS_GET_LOGONINFO |
2976 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2978 case 6: /* UserNameInformation */
2979 case 7: /* UserAccountNameInformation */
2980 case 8: /* UserFullNameInformation */
2981 case 9: /* UserPrimaryGroupInformation */
2982 case 13: /* UserAdminCommentInformation */
2983 /* USER_READ_GENERAL */
2984 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2986 case 10: /* UserHomeInformation */
2987 case 11: /* UserScriptInformation */
2988 case 12: /* UserProfileInformation */
2989 case 14: /* UserWorkStationsInformation */
2990 /* USER_READ_LOGON */
2991 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2993 case 16: /* UserControlInformation */
2994 case 17: /* UserExpiresInformation */
2995 case 20: /* UserParametersInformation */
2996 /* USER_READ_ACCOUNT */
2997 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2999 case 21: /* UserAllInformation */
3001 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3003 case 18: /* UserInternal1Information */
3005 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3007 case 23: /* UserInternal4Information */
3008 case 24: /* UserInternal4InformationNew */
3009 case 25: /* UserInternal4InformationNew */
3010 case 26: /* UserInternal5InformationNew */
3012 return NT_STATUS_INVALID_INFO_CLASS;
3016 uinfo = policy_handle_find(p, r->in.user_handle,
3017 acc_required, &acc_granted,
3018 struct samr_user_info, &status);
3019 if (!NT_STATUS_IS_OK(status)) {
3023 domain_sid = uinfo->sid;
3025 sid_split_rid(&domain_sid, &rid);
3027 if (!sid_check_is_in_our_domain(&uinfo->sid))
3028 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3030 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3031 sid_string_dbg(&uinfo->sid)));
3033 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3035 return NT_STATUS_NO_MEMORY;
3038 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3040 if (!(pwd = samu_new(p->mem_ctx))) {
3041 return NT_STATUS_NO_MEMORY;
3045 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3049 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3051 return NT_STATUS_NO_SUCH_USER;
3054 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3056 samr_clear_sam_passwd(pwd);
3058 switch (r->in.level) {
3060 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3063 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3066 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3069 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3072 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3075 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3078 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3081 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3084 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3087 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3090 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3093 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3096 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3099 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3102 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3105 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3108 /* level 18 is special */
3109 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3113 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3116 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3119 status = NT_STATUS_INVALID_INFO_CLASS;
3123 if (!NT_STATUS_IS_OK(status)) {
3127 *r->out.info = user_info;
3132 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3137 /****************************************************************
3138 ****************************************************************/
3140 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3141 struct samr_QueryUserInfo2 *r)
3143 struct samr_QueryUserInfo u;
3145 u.in.user_handle = r->in.user_handle;
3146 u.in.level = r->in.level;
3147 u.out.info = r->out.info;
3149 return _samr_QueryUserInfo(p, &u);
3152 /*******************************************************************
3153 _samr_GetGroupsForUser
3154 ********************************************************************/
3156 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3157 struct samr_GetGroupsForUser *r)
3159 struct samr_user_info *uinfo;
3160 struct samu *sam_pass=NULL;
3162 struct samr_RidWithAttribute dom_gid;
3163 struct samr_RidWithAttribute *gids = NULL;
3164 uint32 primary_group_rid;
3165 size_t num_groups = 0;
3170 bool success = False;
3172 struct samr_RidWithAttributeArray *rids = NULL;
3175 * from the SID in the request:
3176 * we should send back the list of DOMAIN GROUPS
3177 * the user is a member of
3179 * and only the DOMAIN GROUPS
3180 * no ALIASES !!! neither aliases of the domain
3181 * nor aliases of the builtin SID
3186 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3188 uinfo = policy_handle_find(p, r->in.user_handle,
3189 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3190 struct samr_user_info, &result);
3191 if (!NT_STATUS_IS_OK(result)) {
3195 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3197 return NT_STATUS_NO_MEMORY;
3200 if (!sid_check_is_in_our_domain(&uinfo->sid))
3201 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3203 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3204 return NT_STATUS_NO_MEMORY;
3208 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3212 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3213 sid_string_dbg(&uinfo->sid)));
3214 return NT_STATUS_NO_SUCH_USER;
3219 /* make both calls inside the root block */
3221 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3222 &sids, &unix_gids, &num_groups);
3223 if ( NT_STATUS_IS_OK(result) ) {
3224 success = sid_peek_check_rid(get_global_sam_sid(),
3225 pdb_get_group_sid(sam_pass),
3226 &primary_group_rid);
3230 if (!NT_STATUS_IS_OK(result)) {
3231 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3232 sid_string_dbg(&uinfo->sid)));
3237 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3238 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3239 pdb_get_username(sam_pass)));
3240 TALLOC_FREE(sam_pass);
3241 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3247 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3249 dom_gid.rid = primary_group_rid;
3250 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3252 for (i=0; i<num_groups; i++) {
3254 if (!sid_peek_check_rid(get_global_sam_sid(),
3255 &(sids[i]), &dom_gid.rid)) {
3256 DEBUG(10, ("Found sid %s not in our domain\n",
3257 sid_string_dbg(&sids[i])));
3261 if (dom_gid.rid == primary_group_rid) {
3262 /* We added the primary group directly from the
3263 * sam_account. The other SIDs are unique from
3264 * enum_group_memberships */
3268 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3271 rids->count = num_gids;
3274 *r->out.rids = rids;
3276 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3281 /*******************************************************************
3282 ********************************************************************/
3284 static uint32_t samr_get_server_role(void)
3286 uint32_t role = ROLE_DOMAIN_PDC;
3288 if (lp_server_role() == ROLE_DOMAIN_BDC) {
3289 role = ROLE_DOMAIN_BDC;
3295 /*******************************************************************
3296 ********************************************************************/
3298 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3299 struct samr_DomInfo1 *r)
3301 uint32_t account_policy_temp;
3302 time_t u_expire, u_min_age;
3308 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3309 r->min_password_length = account_policy_temp;
3311 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3312 r->password_history_length = account_policy_temp;
3314 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3315 &r->password_properties);
3317 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3318 u_expire = account_policy_temp;
3320 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3321 u_min_age = account_policy_temp;
3327 unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3328 unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3330 if (lp_check_password_script() && *lp_check_password_script()) {
3331 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3334 return NT_STATUS_OK;
3337 /*******************************************************************
3338 ********************************************************************/
3340 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3341 struct samr_DomGeneralInformation *r,
3342 struct samr_domain_info *dinfo)
3351 r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3352 r->num_groups = count_sam_groups(dinfo->disp_info);
3353 r->num_aliases = count_sam_aliases(dinfo->disp_info);
3355 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3357 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3359 if (!pdb_get_seq_num(&seq_num)) {
3360 seq_num = time(NULL);
3367 r->oem_information.string = lp_serverstring();
3368 r->domain_name.string = lp_workgroup();
3369 r->primary.string = global_myname();
3370 r->sequence_num = seq_num;
3371 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3372 r->role = samr_get_server_role();
3375 return NT_STATUS_OK;
3378 /*******************************************************************
3379 ********************************************************************/
3381 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3382 struct samr_DomInfo3 *r)
3392 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3393 u_logout = (time_t)ul;
3400 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3402 return NT_STATUS_OK;
3405 /*******************************************************************
3406 ********************************************************************/
3408 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3409 struct samr_DomOEMInformation *r)
3411 r->oem_information.string = lp_serverstring();
3413 return NT_STATUS_OK;
3416 /*******************************************************************
3417 ********************************************************************/
3419 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3420 struct samr_DomInfo5 *r)
3422 r->domain_name.string = get_global_sam_name();
3424 return NT_STATUS_OK;
3427 /*******************************************************************
3428 ********************************************************************/
3430 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3431 struct samr_DomInfo6 *r)
3433 /* NT returns its own name when a PDC. win2k and later
3434 * only the name of the PDC if itself is a BDC (samba4
3436 r->primary.string = global_myname();
3438 return NT_STATUS_OK;
3441 /*******************************************************************
3442 ********************************************************************/
3444 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3445 struct samr_DomInfo7 *r)
3447 r->role = samr_get_server_role();
3449 return NT_STATUS_OK;
3452 /*******************************************************************
3453 ********************************************************************/
3455 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3456 struct samr_DomInfo8 *r)
3464 if (!pdb_get_seq_num(&seq_num)) {
3465 seq_num = time(NULL);
3472 r->sequence_num = seq_num;
3473 r->domain_create_time = 0;
3475 return NT_STATUS_OK;
3478 /*******************************************************************
3479 ********************************************************************/
3481 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3482 struct samr_DomInfo9 *r)
3484 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3486 return NT_STATUS_OK;
3489 /*******************************************************************
3490 ********************************************************************/
3492 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3493 struct samr_DomGeneralInformation2 *r,
3494 struct samr_domain_info *dinfo)
3497 uint32_t account_policy_temp;
3498 time_t u_lock_duration, u_reset_time;
3500 status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3501 if (!NT_STATUS_IS_OK(status)) {
3509 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3510 u_lock_duration = account_policy_temp;
3511 if (u_lock_duration != -1) {
3512 u_lock_duration *= 60;
3515 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3516 u_reset_time = account_policy_temp * 60;
3518 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3519 r->lockout_threshold = account_policy_temp;
3525 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3526 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3528 return NT_STATUS_OK;
3531 /*******************************************************************
3532 ********************************************************************/
3534 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3535 struct samr_DomInfo12 *r)
3537 uint32_t account_policy_temp;
3538 time_t u_lock_duration, u_reset_time;
3544 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3545 u_lock_duration = account_policy_temp;
3546 if (u_lock_duration != -1) {
3547 u_lock_duration *= 60;
3550 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3551 u_reset_time = account_policy_temp * 60;
3553 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3554 r->lockout_threshold = account_policy_temp;
3560 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3561 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3563 return NT_STATUS_OK;
3566 /*******************************************************************
3567 ********************************************************************/
3569 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3570 struct samr_DomInfo13 *r)
3578 if (!pdb_get_seq_num(&seq_num)) {
3579 seq_num = time(NULL);
3586 r->sequence_num = seq_num;
3587 r->domain_create_time = 0;
3588 r->modified_count_at_last_promotion = 0;
3590 return NT_STATUS_OK;
3593 /*******************************************************************
3594 _samr_QueryDomainInfo
3595 ********************************************************************/
3597 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3598 struct samr_QueryDomainInfo *r)
3600 NTSTATUS status = NT_STATUS_OK;
3601 struct samr_domain_info *dinfo;
3602 union samr_DomainInfo *dom_info;
3604 uint32_t acc_required;
3606 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3608 switch (r->in.level) {
3609 case 1: /* DomainPasswordInformation */
3610 case 12: /* DomainLockoutInformation */
3611 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3612 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3614 case 11: /* DomainGeneralInformation2 */
3615 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3616 * DOMAIN_READ_OTHER_PARAMETERS */
3617 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3618 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3620 case 2: /* DomainGeneralInformation */
3621 case 3: /* DomainLogoffInformation */
3622 case 4: /* DomainOemInformation */
3623 case 5: /* DomainReplicationInformation */
3624 case 6: /* DomainReplicationInformation */
3625 case 7: /* DomainServerRoleInformation */
3626 case 8: /* DomainModifiedInformation */
3627 case 9: /* DomainStateInformation */
3628 case 10: /* DomainUasInformation */
3629 case 13: /* DomainModifiedInformation2 */
3630 /* DOMAIN_READ_OTHER_PARAMETERS */
3631 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3634 return NT_STATUS_INVALID_INFO_CLASS;
3637 dinfo = policy_handle_find(p, r->in.domain_handle,
3639 struct samr_domain_info, &status);
3640 if (!NT_STATUS_IS_OK(status)) {
3644 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3646 return NT_STATUS_NO_MEMORY;
3649 switch (r->in.level) {
3651 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3654 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3657 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3660 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3663 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3666 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3669 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3672 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3675 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3678 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3681 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3684 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3687 return NT_STATUS_INVALID_INFO_CLASS;
3690 if (!NT_STATUS_IS_OK(status)) {
3694 *r->out.info = dom_info;
3696 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3701 /* W2k3 seems to use the same check for all 3 objects that can be created via
3702 * SAMR, if you try to create for example "Dialup" as an alias it says
3703 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3706 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3708 enum lsa_SidType type;
3711 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3714 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3715 * whether the name already exists */
3716 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3717 NULL, NULL, NULL, &type);
3721 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3722 return NT_STATUS_OK;
3725 DEBUG(5, ("trying to create %s, exists as %s\n",
3726 new_name, sid_type_lookup(type)));
3728 if (type == SID_NAME_DOM_GRP) {
3729 return NT_STATUS_GROUP_EXISTS;
3731 if (type == SID_NAME_ALIAS) {
3732 return NT_STATUS_ALIAS_EXISTS;
3735 /* Yes, the default is NT_STATUS_USER_EXISTS */
3736 return NT_STATUS_USER_EXISTS;
3739 /*******************************************************************
3741 ********************************************************************/
3743 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3744 struct samr_CreateUser2 *r)
3746 const char *account = NULL;
3748 uint32_t acb_info = r->in.acct_flags;
3749 struct samr_domain_info *dinfo;
3750 struct samr_user_info *uinfo;
3755 /* check this, when giving away 'add computer to domain' privs */
3756 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3757 bool can_add_account = False;
3760 dinfo = policy_handle_find(p, r->in.domain_handle,
3761 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3762 struct samr_domain_info, &nt_status);
3763 if (!NT_STATUS_IS_OK(nt_status)) {
3767 if (sid_check_is_builtin(&dinfo->sid)) {
3768 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3769 return NT_STATUS_ACCESS_DENIED;
3772 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3773 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3774 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3775 this parameter is not an account type */
3776 return NT_STATUS_INVALID_PARAMETER;
3779 account = r->in.account_name->string;
3780 if (account == NULL) {
3781 return NT_STATUS_NO_MEMORY;
3784 nt_status = can_create(p->mem_ctx, account);
3785 if (!NT_STATUS_IS_OK(nt_status)) {
3789 /* determine which user right we need to check based on the acb_info */
3791 if (geteuid() == sec_initial_uid()) {
3792 se_priv_copy(&se_rights, &se_priv_none);
3793 can_add_account = true;
3794 } else if (acb_info & ACB_WSTRUST) {
3795 se_priv_copy(&se_rights, &se_machine_account);
3796 can_add_account = user_has_privileges(
3797 p->server_info->ptok, &se_rights );
3798 } else if (acb_info & ACB_NORMAL &&
3799 (account[strlen(account)-1] != '$')) {
3800 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3801 account for domain trusts and changes the ACB flags later */
3802 se_priv_copy(&se_rights, &se_add_users);
3803 can_add_account = user_has_privileges(
3804 p->server_info->ptok, &se_rights );
3805 } else if (lp_enable_privileges()) {
3806 /* implicit assumption of a BDC or domain trust account here
3807 * (we already check the flags earlier) */
3808 /* only Domain Admins can add a BDC or domain trust */
3809 se_priv_copy(&se_rights, &se_priv_none);
3810 can_add_account = nt_token_check_domain_rid(
3811 p->server_info->ptok,
3812 DOMAIN_GROUP_RID_ADMINS );
3815 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3816 uidtoname(p->server_info->utok.uid),
3817 can_add_account ? "True":"False" ));
3819 if (!can_add_account) {
3820 return NT_STATUS_ACCESS_DENIED;
3823 /********** BEGIN Admin BLOCK **********/
3826 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3830 /********** END Admin BLOCK **********/
3832 /* now check for failure */
3834 if ( !NT_STATUS_IS_OK(nt_status) )
3837 /* Get the user's SID */
3839 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3841 map_max_allowed_access(p->server_info->ptok,
3842 &p->server_info->utok,
3845 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3846 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3847 se_map_generic(&des_access, &usr_generic_mapping);
3850 * JRA - TESTME. We just created this user so we
3851 * had rights to create them. Do we need to check
3852 * any further access on this object ? Can't we
3853 * just assume we have all the rights we need ?
3856 nt_status = access_check_object(psd, p->server_info->ptok,
3857 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3858 &acc_granted, "_samr_CreateUser2");
3860 if ( !NT_STATUS_IS_OK(nt_status) ) {
3864 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3865 struct samr_user_info, &nt_status);
3866 if (!NT_STATUS_IS_OK(nt_status)) {
3871 /* After a "set" ensure we have no cached display info. */
3872 force_flush_samr_cache(&sid);
3874 *r->out.access_granted = acc_granted;
3876 return NT_STATUS_OK;
3879 /****************************************************************
3880 ****************************************************************/
3882 NTSTATUS _samr_CreateUser(pipes_struct *p,
3883 struct samr_CreateUser *r)
3885 struct samr_CreateUser2 c;
3886 uint32_t access_granted;
3888 c.in.domain_handle = r->in.domain_handle;
3889 c.in.account_name = r->in.account_name;
3890 c.in.acct_flags = ACB_NORMAL;
3891 c.in.access_mask = r->in.access_mask;
3892 c.out.user_handle = r->out.user_handle;
3893 c.out.access_granted = &access_granted;
3894 c.out.rid = r->out.rid;
3896 return _samr_CreateUser2(p, &c);
3899 /*******************************************************************
3901 ********************************************************************/
3903 NTSTATUS _samr_Connect(pipes_struct *p,
3904 struct samr_Connect *r)
3906 struct samr_connect_info *info;
3907 uint32_t acc_granted;
3908 struct policy_handle hnd;
3909 uint32 des_access = r->in.access_mask;
3914 if (!pipe_access_check(p)) {
3915 DEBUG(3, ("access denied to _samr_Connect\n"));
3916 return NT_STATUS_ACCESS_DENIED;
3919 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3920 was observed from a win98 client trying to enumerate users (when configured
3921 user level access control on shares) --jerry */
3923 map_max_allowed_access(p->server_info->ptok,
3924 &p->server_info->utok,
3927 se_map_generic( &des_access, &sam_generic_mapping );
3929 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3930 |SAMR_ACCESS_LOOKUP_DOMAIN);
3932 /* set up the SAMR connect_anon response */
3934 info = policy_handle_create(p, &hnd, acc_granted,
3935 struct samr_connect_info,
3937 if (!NT_STATUS_IS_OK(status)) {
3941 *r->out.connect_handle = hnd;
3942 return NT_STATUS_OK;
3945 /*******************************************************************
3947 ********************************************************************/
3949 NTSTATUS _samr_Connect2(pipes_struct *p,
3950 struct samr_Connect2 *r)
3952 struct samr_connect_info *info = NULL;
3953 struct policy_handle hnd;
3954 SEC_DESC *psd = NULL;
3956 uint32 des_access = r->in.access_mask;
3959 const char *fn = "_samr_Connect2";
3961 switch (p->hdr_req.opnum) {
3962 case NDR_SAMR_CONNECT2:
3963 fn = "_samr_Connect2";
3965 case NDR_SAMR_CONNECT3:
3966 fn = "_samr_Connect3";
3968 case NDR_SAMR_CONNECT4:
3969 fn = "_samr_Connect4";
3971 case NDR_SAMR_CONNECT5:
3972 fn = "_samr_Connect5";
3976 DEBUG(5,("%s: %d\n", fn, __LINE__));
3980 if (!pipe_access_check(p)) {
3981 DEBUG(3, ("access denied to %s\n", fn));
3982 return NT_STATUS_ACCESS_DENIED;
3985 map_max_allowed_access(p->server_info->ptok,
3986 &p->server_info->utok,
3989 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3990 se_map_generic(&des_access, &sam_generic_mapping);
3992 nt_status = access_check_object(psd, p->server_info->ptok,
3993 NULL, 0, des_access, &acc_granted, fn);
3995 if ( !NT_STATUS_IS_OK(nt_status) )
3998 info = policy_handle_create(p, &hnd, acc_granted,
3999 struct samr_connect_info, &nt_status);
4000 if (!NT_STATUS_IS_OK(nt_status)) {
4004 DEBUG(5,("%s: %d\n", fn, __LINE__));
4006 *r->out.connect_handle = hnd;
4007 return NT_STATUS_OK;
4010 /****************************************************************
4012 ****************************************************************/
4014 NTSTATUS _samr_Connect3(pipes_struct *p,
4015 struct samr_Connect3 *r)
4017 struct samr_Connect2 c;
4019 c.in.system_name = r->in.system_name;
4020 c.in.access_mask = r->in.access_mask;
4021 c.out.connect_handle = r->out.connect_handle;
4023 return _samr_Connect2(p, &c);
4026 /*******************************************************************
4028 ********************************************************************/
4030 NTSTATUS _samr_Connect4(pipes_struct *p,
4031 struct samr_Connect4 *r)
4033 struct samr_Connect2 c;
4035 c.in.system_name = r->in.system_name;
4036 c.in.access_mask = r->in.access_mask;
4037 c.out.connect_handle = r->out.connect_handle;
4039 return _samr_Connect2(p, &c);
4042 /*******************************************************************
4044 ********************************************************************/
4046 NTSTATUS _samr_Connect5(pipes_struct *p,
4047 struct samr_Connect5 *r)
4050 struct samr_Connect2 c;
4051 struct samr_ConnectInfo1 info1;
4053 info1.client_version = SAMR_CONNECT_AFTER_W2K;
4056 c.in.system_name = r->in.system_name;
4057 c.in.access_mask = r->in.access_mask;
4058 c.out.connect_handle = r->out.connect_handle;
4060 *r->out.level_out = 1;
4062 status = _samr_Connect2(p, &c);
4063 if (!NT_STATUS_IS_OK(status)) {
4067 r->out.info_out->info1 = info1;
4069 return NT_STATUS_OK;
4072 /**********************************************************************
4074 **********************************************************************/
4076 NTSTATUS _samr_LookupDomain(pipes_struct *p,
4077 struct samr_LookupDomain *r)
4080 struct samr_connect_info *info;
4081 const char *domain_name;
4082 DOM_SID *sid = NULL;
4084 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4085 Reverted that change so we will work with RAS servers again */
4087 info = policy_handle_find(p, r->in.connect_handle,
4088 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4089 struct samr_connect_info,
4091 if (!NT_STATUS_IS_OK(status)) {
4095 domain_name = r->in.domain_name->string;
4097 return NT_STATUS_INVALID_PARAMETER;
4100 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
4102 return NT_STATUS_NO_MEMORY;
4105 if (strequal(domain_name, builtin_domain_name())) {
4106 sid_copy(sid, &global_sid_Builtin);
4108 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4109 status = NT_STATUS_NO_SUCH_DOMAIN;
4113 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4114 sid_string_dbg(sid)));
4121 /**********************************************************************
4123 **********************************************************************/
4125 NTSTATUS _samr_EnumDomains(pipes_struct *p,
4126 struct samr_EnumDomains *r)
4129 struct samr_connect_info *info;
4130 uint32_t num_entries = 2;
4131 struct samr_SamEntry *entry_array = NULL;
4132 struct samr_SamArray *sam;
4134 info = policy_handle_find(p, r->in.connect_handle,
4135 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4136 struct samr_connect_info, &status);
4137 if (!NT_STATUS_IS_OK(status)) {
4141 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4143 return NT_STATUS_NO_MEMORY;
4146 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4147 struct samr_SamEntry,
4150 return NT_STATUS_NO_MEMORY;
4153 entry_array[0].idx = 0;
4154 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4156 entry_array[1].idx = 1;
4157 init_lsa_String(&entry_array[1].name, "Builtin");
4159 sam->count = num_entries;
4160 sam->entries = entry_array;
4163 *r->out.num_entries = num_entries;
4168 /*******************************************************************
4170 ********************************************************************/
4172 NTSTATUS _samr_OpenAlias(pipes_struct *p,
4173 struct samr_OpenAlias *r)
4176 uint32 alias_rid = r->in.rid;
4177 struct samr_alias_info *ainfo;
4178 struct samr_domain_info *dinfo;
4179 SEC_DESC *psd = NULL;
4181 uint32 des_access = r->in.access_mask;
4186 dinfo = policy_handle_find(p, r->in.domain_handle,
4187 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4188 struct samr_domain_info, &status);
4189 if (!NT_STATUS_IS_OK(status)) {
4193 /* append the alias' RID to it */
4195 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4196 return NT_STATUS_NO_SUCH_ALIAS;
4198 /*check if access can be granted as requested by client. */
4200 map_max_allowed_access(p->server_info->ptok,
4201 &p->server_info->utok,
4204 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4205 se_map_generic(&des_access,&ali_generic_mapping);
4207 se_priv_copy( &se_rights, &se_add_users );
4209 status = access_check_object(psd, p->server_info->ptok,
4210 &se_rights, GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4211 des_access, &acc_granted, "_samr_OpenAlias");
4213 if ( !NT_STATUS_IS_OK(status) )
4217 /* Check we actually have the requested alias */
4218 enum lsa_SidType type;
4223 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4226 if (!result || (type != SID_NAME_ALIAS)) {
4227 return NT_STATUS_NO_SUCH_ALIAS;
4230 /* make sure there is a mapping */
4232 if ( !sid_to_gid( &sid, &gid ) ) {
4233 return NT_STATUS_NO_SUCH_ALIAS;
4238 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4239 struct samr_alias_info, &status);
4240 if (!NT_STATUS_IS_OK(status)) {
4245 return NT_STATUS_OK;
4248 /*******************************************************************
4250 ********************************************************************/
4252 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4253 struct samr_UserInfo2 *id2,
4257 DEBUG(5,("set_user_info_2: NULL id2\n"));
4258 return NT_STATUS_ACCESS_DENIED;
4261 copy_id2_to_sam_passwd(pwd, id2);
4263 return pdb_update_sam_account(pwd);
4266 /*******************************************************************
4268 ********************************************************************/
4270 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4271 struct samr_UserInfo4 *id4,
4275 DEBUG(5,("set_user_info_2: NULL id4\n"));
4276 return NT_STATUS_ACCESS_DENIED;
4279 copy_id4_to_sam_passwd(pwd, id4);
4281 return pdb_update_sam_account(pwd);
4284 /*******************************************************************
4286 ********************************************************************/
4288 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4289 struct samr_UserInfo6 *id6,
4293 DEBUG(5,("set_user_info_6: NULL id6\n"));
4294 return NT_STATUS_ACCESS_DENIED;
4297 copy_id6_to_sam_passwd(pwd, id6);
4299 return pdb_update_sam_account(pwd);
4302 /*******************************************************************
4304 ********************************************************************/
4306 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4307 struct samr_UserInfo7 *id7,
4313 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4314 return NT_STATUS_ACCESS_DENIED;
4317 if (!id7->account_name.string) {
4318 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4319 return NT_STATUS_ACCESS_DENIED;
4322 /* check to see if the new username already exists. Note: we can't
4323 reliably lock all backends, so there is potentially the
4324 possibility that a user can be created in between this check and
4325 the rename. The rename should fail, but may not get the
4326 exact same failure status code. I think this is small enough
4327 of a window for this type of operation and the results are
4328 simply that the rename fails with a slightly different status
4329 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4331 rc = can_create(mem_ctx, id7->account_name.string);
4333 /* when there is nothing to change, we're done here */
4334 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4335 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4336 return NT_STATUS_OK;
4338 if (!NT_STATUS_IS_OK(rc)) {
4342 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4347 /*******************************************************************
4349 ********************************************************************/
4351 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4352 struct samr_UserInfo8 *id8,
4356 DEBUG(5,("set_user_info_8: NULL id8\n"));
4357 return NT_STATUS_ACCESS_DENIED;
4360 copy_id8_to_sam_passwd(pwd, id8);
4362 return pdb_update_sam_account(pwd);
4365 /*******************************************************************
4367 ********************************************************************/
4369 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4370 struct samr_UserInfo10 *id10,
4374 DEBUG(5,("set_user_info_8: NULL id10\n"));
4375 return NT_STATUS_ACCESS_DENIED;
4378 copy_id10_to_sam_passwd(pwd, id10);
4380 return pdb_update_sam_account(pwd);
4383 /*******************************************************************
4385 ********************************************************************/
4387 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4388 struct samr_UserInfo11 *id11,
4392 DEBUG(5,("set_user_info_11: NULL id11\n"));
4393 return NT_STATUS_ACCESS_DENIED;
4396 copy_id11_to_sam_passwd(pwd, id11);
4398 return pdb_update_sam_account(pwd);
4401 /*******************************************************************
4403 ********************************************************************/
4405 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4406 struct samr_UserInfo12 *id12,
4410 DEBUG(5,("set_user_info_12: NULL id12\n"));
4411 return NT_STATUS_ACCESS_DENIED;
4414 copy_id12_to_sam_passwd(pwd, id12);
4416 return pdb_update_sam_account(pwd);
4419 /*******************************************************************
4421 ********************************************************************/
4423 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4424 struct samr_UserInfo13 *id13,
4428 DEBUG(5,("set_user_info_13: NULL id13\n"));
4429 return NT_STATUS_ACCESS_DENIED;
4432 copy_id13_to_sam_passwd(pwd, id13);
4434 return pdb_update_sam_account(pwd);
4437 /*******************************************************************
4439 ********************************************************************/
4441 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4442 struct samr_UserInfo14 *id14,
4446 DEBUG(5,("set_user_info_14: NULL id14\n"));
4447 return NT_STATUS_ACCESS_DENIED;
4450 copy_id14_to_sam_passwd(pwd, id14);
4452 return pdb_update_sam_account(pwd);
4455 /*******************************************************************
4457 ********************************************************************/
4459 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4460 struct samr_UserInfo16 *id16,
4464 DEBUG(5,("set_user_info_16: NULL id16\n"));
4465 return NT_STATUS_ACCESS_DENIED;
4468 copy_id16_to_sam_passwd(pwd, id16);
4470 return pdb_update_sam_account(pwd);
4473 /*******************************************************************
4475 ********************************************************************/
4477 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4478 struct samr_UserInfo17 *id17,
4482 DEBUG(5,("set_user_info_17: NULL id17\n"));
4483 return NT_STATUS_ACCESS_DENIED;
4486 copy_id17_to_sam_passwd(pwd, id17);
4488 return pdb_update_sam_account(pwd);
4491 /*******************************************************************
4493 ********************************************************************/
4495 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4496 TALLOC_CTX *mem_ctx,
4497 DATA_BLOB *session_key,
4501 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4502 return NT_STATUS_INVALID_PARAMETER;
4505 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4506 if (!session_key->length) {
4507 return NT_STATUS_NO_USER_SESSION_KEY;
4511 if (id18->nt_pwd_active) {
4515 in = data_blob_const(id18->nt_pwd.hash, 16);
4516 out = data_blob_talloc_zero(mem_ctx, 16);
4518 sess_crypt_blob(&out, &in, session_key, false);
4520 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4521 return NT_STATUS_ACCESS_DENIED;
4524 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4527 if (id18->lm_pwd_active) {
4531 in = data_blob_const(id18->lm_pwd.hash, 16);
4532 out = data_blob_talloc_zero(mem_ctx, 16);
4534 sess_crypt_blob(&out, &in, session_key, false);
4536 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4537 return NT_STATUS_ACCESS_DENIED;
4540 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4543 copy_id18_to_sam_passwd(pwd, id18);
4545 return pdb_update_sam_account(pwd);
4548 /*******************************************************************
4550 ********************************************************************/
4552 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4553 struct samr_UserInfo20 *id20,
4557 DEBUG(5,("set_user_info_20: NULL id20\n"));
4558 return NT_STATUS_ACCESS_DENIED;
4561 copy_id20_to_sam_passwd(pwd, id20);
4563 return pdb_update_sam_account(pwd);
4566 /*******************************************************************
4568 ********************************************************************/
4570 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4571 TALLOC_CTX *mem_ctx,
4572 DATA_BLOB *session_key,
4578 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4579 return NT_STATUS_INVALID_PARAMETER;
4582 if (id21->fields_present == 0) {
4583 return NT_STATUS_INVALID_PARAMETER;
4586 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4587 return NT_STATUS_ACCESS_DENIED;
4590 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4591 if (id21->nt_password_set) {
4594 if ((id21->nt_owf_password.length != 16) ||
4595 (id21->nt_owf_password.size != 16)) {
4596 return NT_STATUS_INVALID_PARAMETER;
4599 if (!session_key->length) {
4600 return NT_STATUS_NO_USER_SESSION_KEY;
4603 in = data_blob_const(id21->nt_owf_password.array, 16);
4604 out = data_blob_talloc_zero(mem_ctx, 16);
4606 sess_crypt_blob(&out, &in, session_key, false);
4608 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4609 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4613 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4614 if (id21->lm_password_set) {
4617 if ((id21->lm_owf_password.length != 16) ||
4618 (id21->lm_owf_password.size != 16)) {
4619 return NT_STATUS_INVALID_PARAMETER;
4622 if (!session_key->length) {
4623 return NT_STATUS_NO_USER_SESSION_KEY;
4626 in = data_blob_const(id21->lm_owf_password.array, 16);
4627 out = data_blob_talloc_zero(mem_ctx, 16);
4629 sess_crypt_blob(&out, &in, session_key, false);
4631 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4632 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4636 /* we need to separately check for an account rename first */
4638 if (id21->account_name.string &&
4639 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4642 /* check to see if the new username already exists. Note: we can't
4643 reliably lock all backends, so there is potentially the
4644 possibility that a user can be created in between this check and
4645 the rename. The rename should fail, but may not get the
4646 exact same failure status code. I think this is small enough
4647 of a window for this type of operation and the results are
4648 simply that the rename fails with a slightly different status
4649 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4651 status = can_create(mem_ctx, id21->account_name.string);
4652 if (!NT_STATUS_IS_OK(status)) {
4656 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4658 if (!NT_STATUS_IS_OK(status)) {
4659 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4660 nt_errstr(status)));
4664 /* set the new username so that later
4665 functions can work on the new account */
4666 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4669 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4672 * The funny part about the previous two calls is
4673 * that pwd still has the password hashes from the
4674 * passdb entry. These have not been updated from
4675 * id21. I don't know if they need to be set. --jerry
4678 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4679 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4680 if ( !NT_STATUS_IS_OK(status) ) {
4685 /* Don't worry about writing out the user account since the
4686 primary group SID is generated solely from the user's Unix
4689 /* write the change out */
4690 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4694 return NT_STATUS_OK;
4697 /*******************************************************************
4699 ********************************************************************/
4701 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4702 struct samr_UserInfo23 *id23,
4705 char *plaintext_buf = NULL;
4711 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4712 return NT_STATUS_INVALID_PARAMETER;
4715 if (id23->info.fields_present == 0) {
4716 return NT_STATUS_INVALID_PARAMETER;
4719 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4720 return NT_STATUS_ACCESS_DENIED;
4723 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4724 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4726 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4727 pdb_get_username(pwd)));
4729 if (!decode_pw_buffer(mem_ctx,
4730 id23->password.data,
4734 return NT_STATUS_WRONG_PASSWORD;
4737 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4738 return NT_STATUS_ACCESS_DENIED;
4742 copy_id23_to_sam_passwd(pwd, id23);
4744 acct_ctrl = pdb_get_acct_ctrl(pwd);
4746 /* if it's a trust account, don't update /etc/passwd */
4747 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4748 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4749 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4750 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4751 } else if (plaintext_buf) {
4752 /* update the UNIX password */
4753 if (lp_unix_password_sync() ) {
4754 struct passwd *passwd;
4755 if (pdb_get_username(pwd) == NULL) {
4756 DEBUG(1, ("chgpasswd: User without name???\n"));
4757 return NT_STATUS_ACCESS_DENIED;
4760 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4761 if (passwd == NULL) {
4762 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4765 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4766 return NT_STATUS_ACCESS_DENIED;
4768 TALLOC_FREE(passwd);
4772 if (plaintext_buf) {
4773 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4776 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4777 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4782 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4786 return NT_STATUS_OK;
4789 /*******************************************************************
4791 ********************************************************************/
4793 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4796 char *plaintext_buf = NULL;
4799 DEBUG(5, ("Attempting administrator password change for user %s\n",
4800 pdb_get_username(pwd)));
4802 acct_ctrl = pdb_get_acct_ctrl(pwd);
4804 if (!decode_pw_buffer(talloc_tos(),
4812 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4816 /* if it's a trust account, don't update /etc/passwd */
4817 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4818 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4819 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4820 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4822 /* update the UNIX password */
4823 if (lp_unix_password_sync()) {
4824 struct passwd *passwd;
4826 if (pdb_get_username(pwd) == NULL) {
4827 DEBUG(1, ("chgpasswd: User without name???\n"));
4831 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4832 if (passwd == NULL) {
4833 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4836 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4839 TALLOC_FREE(passwd);
4843 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4845 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4850 /*******************************************************************
4852 ********************************************************************/
4854 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4855 struct samr_UserInfo24 *id24,
4861 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4862 return NT_STATUS_INVALID_PARAMETER;
4865 if (!set_user_info_pw(id24->password.data, pwd)) {
4866 return NT_STATUS_WRONG_PASSWORD;
4869 copy_id24_to_sam_passwd(pwd, id24);
4871 status = pdb_update_sam_account(pwd);
4872 if (!NT_STATUS_IS_OK(status)) {
4876 return NT_STATUS_OK;
4879 /*******************************************************************
4881 ********************************************************************/
4883 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4884 struct samr_UserInfo25 *id25,
4890 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4891 return NT_STATUS_INVALID_PARAMETER;
4894 if (id25->info.fields_present == 0) {
4895 return NT_STATUS_INVALID_PARAMETER;
4898 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4899 return NT_STATUS_ACCESS_DENIED;
4902 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4903 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4905 if (!set_user_info_pw(id25->password.data, pwd)) {
4906 return NT_STATUS_WRONG_PASSWORD;
4910 copy_id25_to_sam_passwd(pwd, id25);
4912 /* write the change out */
4913 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4918 * We need to "pdb_update_sam_account" before the unix primary group
4919 * is set, because the idealx scripts would also change the
4920 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4921 * the delete explicit / add explicit, which would then fail to find
4922 * the previous primaryGroupSid value.
4925 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4926 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4927 if ( !NT_STATUS_IS_OK(status) ) {
4932 return NT_STATUS_OK;
4935 /*******************************************************************
4937 ********************************************************************/
4939 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4940 struct samr_UserInfo26 *id26,
4946 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4947 return NT_STATUS_INVALID_PARAMETER;
4950 if (!set_user_info_pw(id26->password.data, pwd)) {
4951 return NT_STATUS_WRONG_PASSWORD;
4954 copy_id26_to_sam_passwd(pwd, id26);
4956 status = pdb_update_sam_account(pwd);
4957 if (!NT_STATUS_IS_OK(status)) {
4961 return NT_STATUS_OK;
4964 /*************************************************************
4965 **************************************************************/
4967 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4969 uint32_t acc_required = 0;
4971 /* USER_ALL_USERNAME */
4972 if (fields & SAMR_FIELD_ACCOUNT_NAME)
4973 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4974 /* USER_ALL_FULLNAME */
4975 if (fields & SAMR_FIELD_FULL_NAME)
4976 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4977 /* USER_ALL_PRIMARYGROUPID */
4978 if (fields & SAMR_FIELD_PRIMARY_GID)
4979 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4980 /* USER_ALL_HOMEDIRECTORY */
4981 if (fields & SAMR_FIELD_HOME_DIRECTORY)
4982 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4983 /* USER_ALL_HOMEDIRECTORYDRIVE */
4984 if (fields & SAMR_FIELD_HOME_DRIVE)
4985 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4986 /* USER_ALL_SCRIPTPATH */
4987 if (fields & SAMR_FIELD_LOGON_SCRIPT)
4988 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4989 /* USER_ALL_PROFILEPATH */
4990 if (fields & SAMR_FIELD_PROFILE_PATH)
4991 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4992 /* USER_ALL_ADMINCOMMENT */
4993 if (fields & SAMR_FIELD_COMMENT)
4994 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4995 /* USER_ALL_WORKSTATIONS */
4996 if (fields & SAMR_FIELD_WORKSTATIONS)
4997 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4998 /* USER_ALL_LOGONHOURS */
4999 if (fields & SAMR_FIELD_LOGON_HOURS)
5000 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5001 /* USER_ALL_ACCOUNTEXPIRES */
5002 if (fields & SAMR_FIELD_ACCT_EXPIRY)
5003 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5004 /* USER_ALL_USERACCOUNTCONTROL */
5005 if (fields & SAMR_FIELD_ACCT_FLAGS)
5006 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5007 /* USER_ALL_PARAMETERS */
5008 if (fields & SAMR_FIELD_PARAMETERS)
5009 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5010 /* USER_ALL_USERCOMMENT */
5011 if (fields & SAMR_FIELD_COMMENT)
5012 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5013 /* USER_ALL_COUNTRYCODE */
5014 if (fields & SAMR_FIELD_COUNTRY_CODE)
5015 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5016 /* USER_ALL_CODEPAGE */
5017 if (fields & SAMR_FIELD_CODE_PAGE)
5018 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5019 /* USER_ALL_NTPASSWORDPRESENT */
5020 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
5021 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5022 /* USER_ALL_LMPASSWORDPRESENT */
5023 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
5024 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5025 /* USER_ALL_PASSWORDEXPIRED */
5026 if (fields & SAMR_FIELD_EXPIRED_FLAG)
5027 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5029 return acc_required;
5032 /*******************************************************************
5034 ********************************************************************/
5036 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
5037 struct samr_SetUserInfo *r)
5039 struct samr_user_info *uinfo;
5041 struct samu *pwd = NULL;
5042 union samr_UserInfo *info = r->in.info;
5043 uint32_t acc_required = 0;
5044 uint32_t fields = 0;
5047 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
5049 /* This is tricky. A WinXP domain join sets
5050 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5051 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
5052 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5053 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
5054 we'll use the set from the WinXP join as the basis. */
5056 switch (r->in.level) {
5057 case 2: /* UserPreferencesInformation */
5058 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5059 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5061 case 4: /* UserLogonHoursInformation */
5062 case 6: /* UserNameInformation */
5063 case 7: /* UserAccountNameInformation */
5064 case 8: /* UserFullNameInformation */
5065 case 9: /* UserPrimaryGroupInformation */
5066 case 10: /* UserHomeInformation */
5067 case 11: /* UserScriptInformation */
5068 case 12: /* UserProfileInformation */
5069 case 13: /* UserAdminCommentInformation */
5070 case 14: /* UserWorkStationsInformation */
5071 case 16: /* UserControlInformation */
5072 case 17: /* UserExpiresInformation */
5073 case 20: /* UserParametersInformation */
5074 /* USER_WRITE_ACCOUNT */
5075 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5077 case 18: /* UserInternal1Information */
5078 /* FIXME: gd, this is a guess */
5079 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5081 case 21: /* UserAllInformation */
5082 fields = info->info21.fields_present;
5083 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5085 case 23: /* UserInternal4Information */
5086 fields = info->info23.info.fields_present;
5087 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5089 case 25: /* UserInternal4InformationNew */
5090 fields = info->info25.info.fields_present;
5091 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5093 case 24: /* UserInternal5Information */
5094 case 26: /* UserInternal5InformationNew */
5095 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5098 return NT_STATUS_INVALID_INFO_CLASS;
5101 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5102 struct samr_user_info, &status);
5103 if (!NT_STATUS_IS_OK(status)) {
5107 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5108 sid_string_dbg(&uinfo->sid), r->in.level));
5111 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5112 return NT_STATUS_INVALID_INFO_CLASS;
5115 if (!(pwd = samu_new(NULL))) {
5116 return NT_STATUS_NO_MEMORY;
5120 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5125 return NT_STATUS_NO_SUCH_USER;
5128 /* ================ BEGIN Privilege BLOCK ================ */
5132 /* ok! user info levels (lots: see MSDEV help), off we go... */
5134 switch (r->in.level) {
5137 status = set_user_info_2(p->mem_ctx,
5142 status = set_user_info_4(p->mem_ctx,
5147 status = set_user_info_6(p->mem_ctx,
5152 status = set_user_info_7(p->mem_ctx,
5157 status = set_user_info_8(p->mem_ctx,
5162 status = set_user_info_10(p->mem_ctx,
5163 &info->info10, pwd);
5167 status = set_user_info_11(p->mem_ctx,
5168 &info->info11, pwd);
5172 status = set_user_info_12(p->mem_ctx,
5173 &info->info12, pwd);
5177 status = set_user_info_13(p->mem_ctx,
5178 &info->info13, pwd);
5182 status = set_user_info_14(p->mem_ctx,
5183 &info->info14, pwd);
5187 status = set_user_info_16(p->mem_ctx,
5188 &info->info16, pwd);
5192 status = set_user_info_17(p->mem_ctx,
5193 &info->info17, pwd);
5197 /* Used by AS/U JRA. */
5198 status = set_user_info_18(&info->info18,
5200 &p->server_info->user_session_key,
5205 status = set_user_info_20(p->mem_ctx,
5206 &info->info20, pwd);
5210 status = set_user_info_21(&info->info21,
5212 &p->server_info->user_session_key,
5217 if (!p->server_info->user_session_key.length) {
5218 status = NT_STATUS_NO_USER_SESSION_KEY;
5220 arcfour_crypt_blob(info->info23.password.data, 516,
5221 &p->server_info->user_session_key);
5223 dump_data(100, info->info23.password.data, 516);
5225 status = set_user_info_23(p->mem_ctx,
5226 &info->info23, pwd);
5230 if (!p->server_info->user_session_key.length) {
5231 status = NT_STATUS_NO_USER_SESSION_KEY;
5233 arcfour_crypt_blob(info->info24.password.data,
5235 &p->server_info->user_session_key);
5237 dump_data(100, info->info24.password.data, 516);
5239 status = set_user_info_24(p->mem_ctx,
5240 &info->info24, pwd);
5244 if (!p->server_info->user_session_key.length) {
5245 status = NT_STATUS_NO_USER_SESSION_KEY;
5247 encode_or_decode_arc4_passwd_buffer(
5248 info->info25.password.data,
5249 &p->server_info->user_session_key);
5251 dump_data(100, info->info25.password.data, 532);
5253 status = set_user_info_25(p->mem_ctx,
5254 &info->info25, pwd);
5258 if (!p->server_info->user_session_key.length) {
5259 status = NT_STATUS_NO_USER_SESSION_KEY;
5261 encode_or_decode_arc4_passwd_buffer(
5262 info->info26.password.data,
5263 &p->server_info->user_session_key);
5265 dump_data(100, info->info26.password.data, 516);
5267 status = set_user_info_26(p->mem_ctx,
5268 &info->info26, pwd);
5272 status = NT_STATUS_INVALID_INFO_CLASS;
5279 /* ================ END Privilege BLOCK ================ */
5281 if (NT_STATUS_IS_OK(status)) {
5282 force_flush_samr_cache(&uinfo->sid);
5288 /*******************************************************************
5290 ********************************************************************/
5292 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
5293 struct samr_SetUserInfo2 *r)
5295 struct samr_SetUserInfo q;
5297 q.in.user_handle = r->in.user_handle;
5298 q.in.level = r->in.level;
5299 q.in.info = r->in.info;
5301 return _samr_SetUserInfo(p, &q);
5304 /*********************************************************************
5305 _samr_GetAliasMembership
5306 *********************************************************************/
5308 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
5309 struct samr_GetAliasMembership *r)
5311 size_t num_alias_rids;
5313 struct samr_domain_info *dinfo;
5320 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5322 dinfo = policy_handle_find(p, r->in.domain_handle,
5323 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5324 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5325 struct samr_domain_info, &status);
5326 if (!NT_STATUS_IS_OK(status)) {
5330 if (!sid_check_is_domain(&dinfo->sid) &&
5331 !sid_check_is_builtin(&dinfo->sid))
5332 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5334 if (r->in.sids->num_sids) {
5335 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
5337 if (members == NULL)
5338 return NT_STATUS_NO_MEMORY;
5343 for (i=0; i<r->in.sids->num_sids; i++)
5344 sid_copy(&members[i], r->in.sids->sids[i].sid);
5350 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5351 r->in.sids->num_sids,
5352 &alias_rids, &num_alias_rids);
5355 if (!NT_STATUS_IS_OK(status)) {
5359 r->out.rids->count = num_alias_rids;
5360 r->out.rids->ids = alias_rids;
5362 return NT_STATUS_OK;
5365 /*********************************************************************
5366 _samr_GetMembersInAlias
5367 *********************************************************************/
5369 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5370 struct samr_GetMembersInAlias *r)
5372 struct samr_alias_info *ainfo;
5375 size_t num_sids = 0;
5376 struct lsa_SidPtr *sids = NULL;
5377 DOM_SID *pdb_sids = NULL;
5379 ainfo = policy_handle_find(p, r->in.alias_handle,
5380 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5381 struct samr_alias_info, &status);
5382 if (!NT_STATUS_IS_OK(status)) {
5386 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5389 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5393 if (!NT_STATUS_IS_OK(status)) {
5398 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5400 TALLOC_FREE(pdb_sids);
5401 return NT_STATUS_NO_MEMORY;
5405 for (i = 0; i < num_sids; i++) {
5406 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5408 TALLOC_FREE(pdb_sids);
5409 return NT_STATUS_NO_MEMORY;
5413 r->out.sids->num_sids = num_sids;
5414 r->out.sids->sids = sids;
5416 TALLOC_FREE(pdb_sids);
5418 return NT_STATUS_OK;
5421 /*********************************************************************
5422 _samr_QueryGroupMember
5423 *********************************************************************/
5425 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5426 struct samr_QueryGroupMember *r)
5428 struct samr_group_info *ginfo;
5429 size_t i, num_members;
5435 struct samr_RidTypeArray *rids = NULL;
5437 ginfo = policy_handle_find(p, r->in.group_handle,
5438 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5439 struct samr_group_info, &status);
5440 if (!NT_STATUS_IS_OK(status)) {
5444 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5446 return NT_STATUS_NO_MEMORY;
5449 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5451 if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5452 DEBUG(3, ("sid %s is not in our domain\n",
5453 sid_string_dbg(&ginfo->sid)));
5454 return NT_STATUS_NO_SUCH_GROUP;
5457 DEBUG(10, ("lookup on Domain SID\n"));
5460 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5461 &rid, &num_members);
5464 if (!NT_STATUS_IS_OK(status))
5468 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5470 return NT_STATUS_NO_MEMORY;
5476 for (i=0; i<num_members; i++)
5477 attr[i] = SID_NAME_USER;
5479 rids->count = num_members;
5483 *r->out.rids = rids;
5485 return NT_STATUS_OK;
5488 /*********************************************************************
5489 _samr_AddAliasMember
5490 *********************************************************************/
5492 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5493 struct samr_AddAliasMember *r)
5495 struct samr_alias_info *ainfo;
5498 ainfo = policy_handle_find(p, r->in.alias_handle,
5499 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5500 struct samr_alias_info, &status);
5501 if (!NT_STATUS_IS_OK(status)) {
5505 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5507 /******** BEGIN SeAddUsers BLOCK *********/
5510 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5513 /******** END SeAddUsers BLOCK *********/
5515 if (NT_STATUS_IS_OK(status)) {
5516 force_flush_samr_cache(&ainfo->sid);
5522 /*********************************************************************
5523 _samr_DeleteAliasMember
5524 *********************************************************************/
5526 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5527 struct samr_DeleteAliasMember *r)
5529 struct samr_alias_info *ainfo;
5532 ainfo = policy_handle_find(p, r->in.alias_handle,
5533 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5534 struct samr_alias_info, &status);
5535 if (!NT_STATUS_IS_OK(status)) {
5539 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5540 sid_string_dbg(&ainfo->sid)));
5542 /******** BEGIN SeAddUsers BLOCK *********/
5545 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5548 /******** END SeAddUsers BLOCK *********/
5550 if (NT_STATUS_IS_OK(status)) {
5551 force_flush_samr_cache(&ainfo->sid);
5557 /*********************************************************************
5558 _samr_AddGroupMember
5559 *********************************************************************/
5561 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5562 struct samr_AddGroupMember *r)
5564 struct samr_group_info *ginfo;
5568 ginfo = policy_handle_find(p, r->in.group_handle,
5569 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5570 struct samr_group_info, &status);
5571 if (!NT_STATUS_IS_OK(status)) {
5575 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5577 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5579 return NT_STATUS_INVALID_HANDLE;
5582 /******** BEGIN SeAddUsers BLOCK *********/
5585 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5588 /******** END SeAddUsers BLOCK *********/
5590 force_flush_samr_cache(&ginfo->sid);
5595 /*********************************************************************
5596 _samr_DeleteGroupMember
5597 *********************************************************************/
5599 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5600 struct samr_DeleteGroupMember *r)
5603 struct samr_group_info *ginfo;
5608 * delete the group member named r->in.rid
5609 * who is a member of the sid associated with the handle
5610 * the rid is a user's rid as the group is a domain group.
5613 ginfo = policy_handle_find(p, r->in.group_handle,
5614 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5615 struct samr_group_info, &status);
5616 if (!NT_STATUS_IS_OK(status)) {
5620 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5622 return NT_STATUS_INVALID_HANDLE;
5625 /******** BEGIN SeAddUsers BLOCK *********/
5628 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5631 /******** END SeAddUsers BLOCK *********/
5633 force_flush_samr_cache(&ginfo->sid);
5638 /*********************************************************************
5640 *********************************************************************/
5642 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5643 struct samr_DeleteUser *r)
5645 struct samr_user_info *uinfo;
5647 struct samu *sam_pass=NULL;
5650 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5652 uinfo = policy_handle_find(p, r->in.user_handle,
5653 STD_RIGHT_DELETE_ACCESS, NULL,
5654 struct samr_user_info, &status);
5655 if (!NT_STATUS_IS_OK(status)) {
5659 if (!sid_check_is_in_our_domain(&uinfo->sid))
5660 return NT_STATUS_CANNOT_DELETE;
5662 /* check if the user exists before trying to delete */
5663 if ( !(sam_pass = samu_new( NULL )) ) {
5664 return NT_STATUS_NO_MEMORY;
5668 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5672 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5673 sid_string_dbg(&uinfo->sid)));
5674 TALLOC_FREE(sam_pass);
5675 return NT_STATUS_NO_SUCH_USER;
5678 /******** BEGIN SeAddUsers BLOCK *********/
5681 status = pdb_delete_user(p->mem_ctx, sam_pass);
5684 /******** END SeAddUsers BLOCK *********/
5686 if ( !NT_STATUS_IS_OK(status) ) {
5687 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5688 "user %s: %s.\n", pdb_get_username(sam_pass),
5689 nt_errstr(status)));
5690 TALLOC_FREE(sam_pass);
5695 TALLOC_FREE(sam_pass);
5697 force_flush_samr_cache(&uinfo->sid);
5699 if (!close_policy_hnd(p, r->in.user_handle))
5700 return NT_STATUS_OBJECT_NAME_INVALID;
5702 ZERO_STRUCTP(r->out.user_handle);
5704 return NT_STATUS_OK;
5707 /*********************************************************************
5708 _samr_DeleteDomainGroup
5709 *********************************************************************/
5711 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5712 struct samr_DeleteDomainGroup *r)
5714 struct samr_group_info *ginfo;
5718 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5720 ginfo = policy_handle_find(p, r->in.group_handle,
5721 STD_RIGHT_DELETE_ACCESS, NULL,
5722 struct samr_group_info, &status);
5723 if (!NT_STATUS_IS_OK(status)) {
5727 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5729 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5731 return NT_STATUS_NO_SUCH_GROUP;
5734 /******** BEGIN SeAddUsers BLOCK *********/
5737 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5740 /******** END SeAddUsers BLOCK *********/
5742 if ( !NT_STATUS_IS_OK(status) ) {
5743 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5744 "entry for group %s: %s\n",
5745 sid_string_dbg(&ginfo->sid),
5746 nt_errstr(status)));
5750 force_flush_samr_cache(&ginfo->sid);
5752 if (!close_policy_hnd(p, r->in.group_handle))
5753 return NT_STATUS_OBJECT_NAME_INVALID;
5755 return NT_STATUS_OK;
5758 /*********************************************************************
5759 _samr_DeleteDomAlias
5760 *********************************************************************/
5762 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5763 struct samr_DeleteDomAlias *r)
5765 struct samr_alias_info *ainfo;
5768 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5770 ainfo = policy_handle_find(p, r->in.alias_handle,
5771 STD_RIGHT_DELETE_ACCESS, NULL,
5772 struct samr_alias_info, &status);
5773 if (!NT_STATUS_IS_OK(status)) {
5777 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5779 /* Don't let Windows delete builtin groups */
5781 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5782 return NT_STATUS_SPECIAL_ACCOUNT;
5785 if (!sid_check_is_in_our_domain(&ainfo->sid))
5786 return NT_STATUS_NO_SUCH_ALIAS;
5788 DEBUG(10, ("lookup on Local SID\n"));
5790 /******** BEGIN SeAddUsers BLOCK *********/
5793 /* Have passdb delete the alias */
5794 status = pdb_delete_alias(&ainfo->sid);
5797 /******** END SeAddUsers BLOCK *********/
5799 if ( !NT_STATUS_IS_OK(status))
5802 force_flush_samr_cache(&ainfo->sid);
5804 if (!close_policy_hnd(p, r->in.alias_handle))
5805 return NT_STATUS_OBJECT_NAME_INVALID;
5807 return NT_STATUS_OK;
5810 /*********************************************************************
5811 _samr_CreateDomainGroup
5812 *********************************************************************/
5814 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5815 struct samr_CreateDomainGroup *r)
5820 struct samr_domain_info *dinfo;
5821 struct samr_group_info *ginfo;
5823 dinfo = policy_handle_find(p, r->in.domain_handle,
5824 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5825 struct samr_domain_info, &status);
5826 if (!NT_STATUS_IS_OK(status)) {
5830 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5831 return NT_STATUS_ACCESS_DENIED;
5833 name = r->in.name->string;
5835 return NT_STATUS_NO_MEMORY;
5838 status = can_create(p->mem_ctx, name);
5839 if (!NT_STATUS_IS_OK(status)) {
5843 /******** BEGIN SeAddUsers BLOCK *********/
5846 /* check that we successfully create the UNIX group */
5847 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5850 /******** END SeAddUsers BLOCK *********/
5852 /* check if we should bail out here */
5854 if ( !NT_STATUS_IS_OK(status) )
5857 ginfo = policy_handle_create(p, r->out.group_handle,
5858 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5859 struct samr_group_info, &status);
5860 if (!NT_STATUS_IS_OK(status)) {
5863 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5865 force_flush_samr_cache(&dinfo->sid);
5867 return NT_STATUS_OK;
5870 /*********************************************************************
5871 _samr_CreateDomAlias
5872 *********************************************************************/
5874 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5875 struct samr_CreateDomAlias *r)
5878 const char *name = NULL;
5879 struct samr_domain_info *dinfo;
5880 struct samr_alias_info *ainfo;
5884 dinfo = policy_handle_find(p, r->in.domain_handle,
5885 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5886 struct samr_domain_info, &result);
5887 if (!NT_STATUS_IS_OK(result)) {
5891 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5892 return NT_STATUS_ACCESS_DENIED;
5894 name = r->in.alias_name->string;
5896 result = can_create(p->mem_ctx, name);
5897 if (!NT_STATUS_IS_OK(result)) {
5901 /******** BEGIN SeAddUsers BLOCK *********/
5904 /* Have passdb create the alias */
5905 result = pdb_create_alias(name, r->out.rid);
5908 /******** END SeAddUsers BLOCK *********/
5910 if (!NT_STATUS_IS_OK(result)) {
5911 DEBUG(10, ("pdb_create_alias failed: %s\n",
5912 nt_errstr(result)));
5916 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5918 if (!sid_to_gid(&info_sid, &gid)) {
5919 DEBUG(10, ("Could not find alias just created\n"));
5920 return NT_STATUS_ACCESS_DENIED;
5923 /* check if the group has been successfully created */
5924 if ( getgrgid(gid) == NULL ) {
5925 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5926 (unsigned int)gid));
5927 return NT_STATUS_ACCESS_DENIED;
5930 ainfo = policy_handle_create(p, r->out.alias_handle,
5931 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5932 struct samr_alias_info, &result);
5933 if (!NT_STATUS_IS_OK(result)) {
5936 ainfo->sid = info_sid;
5938 force_flush_samr_cache(&info_sid);
5940 return NT_STATUS_OK;
5943 /*********************************************************************
5944 _samr_QueryGroupInfo
5945 *********************************************************************/
5947 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5948 struct samr_QueryGroupInfo *r)
5950 struct samr_group_info *ginfo;
5953 union samr_GroupInfo *info = NULL;
5955 uint32_t attributes = SE_GROUP_MANDATORY |
5956 SE_GROUP_ENABLED_BY_DEFAULT |
5958 const char *group_name = NULL;
5959 const char *group_description = NULL;
5961 ginfo = policy_handle_find(p, r->in.group_handle,
5962 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5963 struct samr_group_info, &status);
5964 if (!NT_STATUS_IS_OK(status)) {
5969 ret = get_domain_group_from_sid(ginfo->sid, &map);
5972 return NT_STATUS_INVALID_HANDLE;
5974 /* FIXME: map contains fstrings */
5975 group_name = talloc_strdup(r, map.nt_name);
5976 group_description = talloc_strdup(r, map.comment);
5978 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5980 return NT_STATUS_NO_MEMORY;
5983 switch (r->in.level) {
5989 status = pdb_enum_group_members(
5990 p->mem_ctx, &ginfo->sid, &members,
5994 if (!NT_STATUS_IS_OK(status)) {
5998 info->all.name.string = group_name;
5999 info->all.attributes = attributes;
6000 info->all.num_members = num_members;
6001 info->all.description.string = group_description;
6005 info->name.string = group_name;
6008 info->attributes.attributes = attributes;
6011 info->description.string = group_description;
6021 status = pdb_enum_group_members(
6022 p->mem_ctx, &ginfo->sid, &members,
6026 if (!NT_STATUS_IS_OK(status)) {
6030 info->all2.name.string = group_name;
6031 info->all2.attributes = attributes;
6032 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
6033 info->all2.description.string = group_description;
6038 return NT_STATUS_INVALID_INFO_CLASS;
6041 *r->out.info = info;
6043 return NT_STATUS_OK;
6046 /*********************************************************************
6048 *********************************************************************/
6050 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
6051 struct samr_SetGroupInfo *r)
6053 struct samr_group_info *ginfo;
6058 ginfo = policy_handle_find(p, r->in.group_handle,
6059 SAMR_GROUP_ACCESS_SET_INFO, NULL,
6060 struct samr_group_info, &status);
6061 if (!NT_STATUS_IS_OK(status)) {
6066 ret = get_domain_group_from_sid(ginfo->sid, &map);
6069 return NT_STATUS_NO_SUCH_GROUP;
6071 switch (r->in.level) {
6073 fstrcpy(map.nt_name, r->in.info->name.string);
6078 fstrcpy(map.comment, r->in.info->description.string);
6081 return NT_STATUS_INVALID_INFO_CLASS;
6084 /******** BEGIN SeAddUsers BLOCK *********/
6087 status = pdb_update_group_mapping_entry(&map);
6090 /******** End SeAddUsers BLOCK *********/
6092 if (NT_STATUS_IS_OK(status)) {
6093 force_flush_samr_cache(&ginfo->sid);
6099 /*********************************************************************
6101 *********************************************************************/
6103 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
6104 struct samr_SetAliasInfo *r)
6106 struct samr_alias_info *ainfo;
6107 struct acct_info info;
6110 ainfo = policy_handle_find(p, r->in.alias_handle,
6111 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6112 struct samr_alias_info, &status);
6113 if (!NT_STATUS_IS_OK(status)) {
6117 /* get the current group information */
6120 status = pdb_get_aliasinfo( &ainfo->sid, &info );
6123 if ( !NT_STATUS_IS_OK(status))
6126 switch (r->in.level) {
6131 /* We currently do not support renaming groups in the
6132 the BUILTIN domain. Refer to util_builtin.c to understand
6133 why. The eventually needs to be fixed to be like Windows
6134 where you can rename builtin groups, just not delete them */
6136 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6137 return NT_STATUS_SPECIAL_ACCOUNT;
6140 /* There has to be a valid name (and it has to be different) */
6142 if ( !r->in.info->name.string )
6143 return NT_STATUS_INVALID_PARAMETER;
6145 /* If the name is the same just reply "ok". Yes this
6146 doesn't allow you to change the case of a group name. */
6148 if ( strequal( r->in.info->name.string, info.acct_name ) )
6149 return NT_STATUS_OK;
6151 fstrcpy( info.acct_name, r->in.info->name.string);
6153 /* make sure the name doesn't already exist as a user
6156 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6157 status = can_create( p->mem_ctx, group_name );
6158 if ( !NT_STATUS_IS_OK( status ) )
6162 case ALIASINFODESCRIPTION:
6163 if (r->in.info->description.string) {
6164 fstrcpy(info.acct_desc,
6165 r->in.info->description.string);
6167 fstrcpy( info.acct_desc, "" );
6171 return NT_STATUS_INVALID_INFO_CLASS;
6174 /******** BEGIN SeAddUsers BLOCK *********/
6177 status = pdb_set_aliasinfo( &ainfo->sid, &info );
6180 /******** End SeAddUsers BLOCK *********/
6182 if (NT_STATUS_IS_OK(status))
6183 force_flush_samr_cache(&ainfo->sid);
6188 /****************************************************************
6190 ****************************************************************/
6192 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
6193 struct samr_GetDomPwInfo *r)
6195 uint32_t min_password_length = 0;
6196 uint32_t password_properties = 0;
6198 /* Perform access check. Since this rpc does not require a
6199 policy handle it will not be caught by the access checks on
6200 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6202 if (!pipe_access_check(p)) {
6203 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6204 return NT_STATUS_ACCESS_DENIED;
6208 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6209 &min_password_length);
6210 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6211 &password_properties);
6214 if (lp_check_password_script() && *lp_check_password_script()) {
6215 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6218 r->out.info->min_password_length = min_password_length;
6219 r->out.info->password_properties = password_properties;
6221 return NT_STATUS_OK;
6224 /*********************************************************************
6226 *********************************************************************/
6228 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6229 struct samr_OpenGroup *r)
6234 struct samr_domain_info *dinfo;
6235 struct samr_group_info *ginfo;
6236 SEC_DESC *psd = NULL;
6238 uint32 des_access = r->in.access_mask;
6244 dinfo = policy_handle_find(p, r->in.domain_handle,
6245 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6246 struct samr_domain_info, &status);
6247 if (!NT_STATUS_IS_OK(status)) {
6251 /*check if access can be granted as requested by client. */
6252 map_max_allowed_access(p->server_info->ptok,
6253 &p->server_info->utok,
6256 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6257 se_map_generic(&des_access,&grp_generic_mapping);
6259 se_priv_copy( &se_rights, &se_add_users );
6261 status = access_check_object(psd, p->server_info->ptok,
6262 &se_rights, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6263 des_access, &acc_granted, "_samr_OpenGroup");
6265 if ( !NT_STATUS_IS_OK(status) )
6268 /* this should not be hard-coded like this */
6270 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
6271 return NT_STATUS_ACCESS_DENIED;
6273 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6275 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6276 sid_string_dbg(&info_sid)));
6278 /* check if that group really exists */
6280 ret = get_domain_group_from_sid(info_sid, &map);
6283 return NT_STATUS_NO_SUCH_GROUP;
6285 ginfo = policy_handle_create(p, r->out.group_handle,
6287 struct samr_group_info, &status);
6288 if (!NT_STATUS_IS_OK(status)) {
6291 ginfo->sid = info_sid;
6293 return NT_STATUS_OK;
6296 /*********************************************************************
6297 _samr_RemoveMemberFromForeignDomain
6298 *********************************************************************/
6300 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6301 struct samr_RemoveMemberFromForeignDomain *r)
6303 struct samr_domain_info *dinfo;
6306 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6307 sid_string_dbg(r->in.sid)));
6309 /* Find the policy handle. Open a policy on it. */
6311 dinfo = policy_handle_find(p, r->in.domain_handle,
6312 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6313 struct samr_domain_info, &result);
6314 if (!NT_STATUS_IS_OK(result)) {
6318 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6319 sid_string_dbg(&dinfo->sid)));
6321 /* we can only delete a user from a group since we don't have
6322 nested groups anyways. So in the latter case, just say OK */
6324 /* TODO: The above comment nowadays is bogus. Since we have nested
6325 * groups now, and aliases members are never reported out of the unix
6326 * group membership, the "just say OK" makes this call a no-op. For
6327 * us. This needs fixing however. */
6329 /* I've only ever seen this in the wild when deleting a user from
6330 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6331 * is the user about to be deleted. I very much suspect this is the
6332 * only application of this call. To verify this, let people report
6335 if (!sid_check_is_builtin(&dinfo->sid)) {
6336 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6337 "global_sam_sid() = %s\n",
6338 sid_string_dbg(&dinfo->sid),
6339 sid_string_dbg(get_global_sam_sid())));
6340 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6341 return NT_STATUS_OK;
6344 force_flush_samr_cache(&dinfo->sid);
6346 result = NT_STATUS_OK;
6351 /*******************************************************************
6352 _samr_QueryDomainInfo2
6353 ********************************************************************/
6355 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6356 struct samr_QueryDomainInfo2 *r)
6358 struct samr_QueryDomainInfo q;
6360 q.in.domain_handle = r->in.domain_handle;
6361 q.in.level = r->in.level;
6363 q.out.info = r->out.info;
6365 return _samr_QueryDomainInfo(p, &q);
6368 /*******************************************************************
6369 ********************************************************************/
6371 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6372 struct samr_DomInfo1 *r)
6374 time_t u_expire, u_min_age;
6376 u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6377 u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6379 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6380 (uint32_t)r->min_password_length);
6381 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6382 (uint32_t)r->password_history_length);
6383 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6384 (uint32_t)r->password_properties);
6385 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6386 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6388 return NT_STATUS_OK;
6391 /*******************************************************************
6392 ********************************************************************/
6394 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6395 struct samr_DomInfo3 *r)
6399 u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6401 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6403 return NT_STATUS_OK;
6406 /*******************************************************************
6407 ********************************************************************/
6409 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6410 struct samr_DomInfo12 *r)
6412 time_t u_lock_duration, u_reset_time;
6414 u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6415 if (u_lock_duration != -1) {
6416 u_lock_duration /= 60;
6419 u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6421 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6422 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6423 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6424 (uint32_t)r->lockout_threshold);
6426 return NT_STATUS_OK;
6429 /*******************************************************************
6431 ********************************************************************/
6433 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6434 struct samr_SetDomainInfo *r)
6436 struct samr_domain_info *dinfo;
6438 uint32_t acc_required = 0;
6440 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6442 switch (r->in.level) {
6443 case 1: /* DomainPasswordInformation */
6444 case 12: /* DomainLockoutInformation */
6445 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6446 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6448 case 3: /* DomainLogoffInformation */
6449 case 4: /* DomainOemInformation */
6450 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6451 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6453 case 6: /* DomainReplicationInformation */
6454 case 9: /* DomainStateInformation */
6455 case 7: /* DomainServerRoleInformation */
6456 /* DOMAIN_ADMINISTER_SERVER */
6457 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6460 return NT_STATUS_INVALID_INFO_CLASS;
6463 dinfo = policy_handle_find(p, r->in.domain_handle,
6465 struct samr_domain_info, &status);
6466 if (!NT_STATUS_IS_OK(status)) {
6470 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6472 switch (r->in.level) {
6474 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6477 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6488 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6491 return NT_STATUS_INVALID_INFO_CLASS;
6494 if (!NT_STATUS_IS_OK(status)) {
6498 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6500 return NT_STATUS_OK;
6503 /****************************************************************
6504 _samr_GetDisplayEnumerationIndex
6505 ****************************************************************/
6507 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6508 struct samr_GetDisplayEnumerationIndex *r)
6510 struct samr_domain_info *dinfo;
6511 uint32_t max_entries = (uint32_t) -1;
6512 uint32_t enum_context = 0;
6514 uint32_t num_account = 0;
6515 struct samr_displayentry *entries = NULL;
6518 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6520 dinfo = policy_handle_find(p, r->in.domain_handle,
6521 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6522 struct samr_domain_info, &status);
6523 if (!NT_STATUS_IS_OK(status)) {
6527 if ((r->in.level < 1) || (r->in.level > 3)) {
6528 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6529 "Unknown info level (%u)\n",
6531 return NT_STATUS_INVALID_INFO_CLASS;
6536 /* The following done as ROOT. Don't return without unbecome_root(). */
6538 switch (r->in.level) {
6540 if (dinfo->disp_info->users == NULL) {
6541 dinfo->disp_info->users = pdb_search_users(
6542 dinfo->disp_info, ACB_NORMAL);
6543 if (dinfo->disp_info->users == NULL) {
6545 return NT_STATUS_ACCESS_DENIED;
6547 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6548 "starting user enumeration at index %u\n",
6549 (unsigned int)enum_context));
6551 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6552 "using cached user enumeration at index %u\n",
6553 (unsigned int)enum_context));
6555 num_account = pdb_search_entries(dinfo->disp_info->users,
6556 enum_context, max_entries,
6560 if (dinfo->disp_info->machines == NULL) {
6561 dinfo->disp_info->machines = pdb_search_users(
6562 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6563 if (dinfo->disp_info->machines == NULL) {
6565 return NT_STATUS_ACCESS_DENIED;
6567 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6568 "starting machine enumeration at index %u\n",
6569 (unsigned int)enum_context));
6571 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6572 "using cached machine enumeration at index %u\n",
6573 (unsigned int)enum_context));
6575 num_account = pdb_search_entries(dinfo->disp_info->machines,
6576 enum_context, max_entries,
6580 if (dinfo->disp_info->groups == NULL) {
6581 dinfo->disp_info->groups = pdb_search_groups(
6583 if (dinfo->disp_info->groups == NULL) {
6585 return NT_STATUS_ACCESS_DENIED;
6587 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6588 "starting group enumeration at index %u\n",
6589 (unsigned int)enum_context));
6591 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6592 "using cached group enumeration at index %u\n",
6593 (unsigned int)enum_context));
6595 num_account = pdb_search_entries(dinfo->disp_info->groups,
6596 enum_context, max_entries,
6601 smb_panic("info class changed");
6607 /* Ensure we cache this enumeration. */
6608 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6610 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6611 r->in.name->string));
6613 for (i=0; i<num_account; i++) {
6614 if (strequal(entries[i].account_name, r->in.name->string)) {
6615 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6616 "found %s at idx %d\n",
6617 r->in.name->string, i));
6619 return NT_STATUS_OK;
6623 /* assuming account_name lives at the very end */
6624 *r->out.idx = num_account;
6626 return NT_STATUS_NO_MORE_ENTRIES;
6629 /****************************************************************
6630 _samr_GetDisplayEnumerationIndex2
6631 ****************************************************************/
6633 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6634 struct samr_GetDisplayEnumerationIndex2 *r)
6636 struct samr_GetDisplayEnumerationIndex q;
6638 q.in.domain_handle = r->in.domain_handle;
6639 q.in.level = r->in.level;
6640 q.in.name = r->in.name;
6642 q.out.idx = r->out.idx;
6644 return _samr_GetDisplayEnumerationIndex(p, &q);
6647 /****************************************************************
6649 ****************************************************************/
6651 NTSTATUS _samr_RidToSid(pipes_struct *p,
6652 struct samr_RidToSid *r)
6654 struct samr_domain_info *dinfo;
6658 dinfo = policy_handle_find(p, r->in.domain_handle,
6660 struct samr_domain_info, &status);
6661 if (!NT_STATUS_IS_OK(status)) {
6665 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6666 return NT_STATUS_NO_MEMORY;
6669 *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
6671 return NT_STATUS_NO_MEMORY;
6674 return NT_STATUS_OK;
6677 /****************************************************************
6678 ****************************************************************/
6680 NTSTATUS _samr_Shutdown(pipes_struct *p,
6681 struct samr_Shutdown *r)
6683 p->rng_fault_state = true;
6684 return NT_STATUS_NOT_IMPLEMENTED;
6687 /****************************************************************
6688 ****************************************************************/
6690 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6691 struct samr_SetMemberAttributesOfGroup *r)
6693 p->rng_fault_state = true;
6694 return NT_STATUS_NOT_IMPLEMENTED;
6697 /****************************************************************
6698 ****************************************************************/
6700 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6701 struct samr_TestPrivateFunctionsDomain *r)
6703 return NT_STATUS_NOT_IMPLEMENTED;
6706 /****************************************************************
6707 ****************************************************************/
6709 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6710 struct samr_TestPrivateFunctionsUser *r)
6712 return NT_STATUS_NOT_IMPLEMENTED;
6715 /****************************************************************
6716 ****************************************************************/
6718 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6719 struct samr_AddMultipleMembersToAlias *r)
6721 p->rng_fault_state = true;
6722 return NT_STATUS_NOT_IMPLEMENTED;
6725 /****************************************************************
6726 ****************************************************************/
6728 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6729 struct samr_RemoveMultipleMembersFromAlias *r)
6731 p->rng_fault_state = true;
6732 return NT_STATUS_NOT_IMPLEMENTED;
6735 /****************************************************************
6736 ****************************************************************/
6738 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6739 struct samr_SetBootKeyInformation *r)
6741 p->rng_fault_state = true;
6742 return NT_STATUS_NOT_IMPLEMENTED;
6745 /****************************************************************
6746 ****************************************************************/
6748 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6749 struct samr_GetBootKeyInformation *r)
6751 p->rng_fault_state = true;
6752 return NT_STATUS_NOT_IMPLEMENTED;
6755 /****************************************************************
6756 ****************************************************************/
6758 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6759 struct samr_SetDsrmPassword *r)
6761 p->rng_fault_state = true;
6762 return NT_STATUS_NOT_IMPLEMENTED;
6765 /****************************************************************
6766 ****************************************************************/
6768 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6769 struct samr_ValidatePassword *r)
6771 p->rng_fault_state = true;
6772 return NT_STATUS_NOT_IMPLEMENTED;