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 enum samPwdChangeReason reject_reason;
2027 struct samr_DomInfo1 *dominfo = NULL;
2028 struct userPwdChangeFailureInformation *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,
2074 struct userPwdChangeFailureInformation);
2076 return NT_STATUS_NO_MEMORY;
2083 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2084 dominfo->min_password_length = tmp;
2086 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2087 dominfo->password_history_length = tmp;
2089 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2090 &dominfo->password_properties);
2092 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2093 u_expire = account_policy_temp;
2095 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2096 u_min_age = account_policy_temp;
2102 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2103 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2105 if (lp_check_password_script() && *lp_check_password_script()) {
2106 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2109 reject->extendedFailureReason = reject_reason;
2111 *r->out.dominfo = dominfo;
2112 *r->out.reject = reject;
2115 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2120 /*******************************************************************
2121 makes a SAMR_R_LOOKUP_RIDS structure.
2122 ********************************************************************/
2124 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2126 struct lsa_String **lsa_name_array_p)
2128 struct lsa_String *lsa_name_array = NULL;
2131 *lsa_name_array_p = NULL;
2133 if (num_names != 0) {
2134 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2135 if (!lsa_name_array) {
2140 for (i = 0; i < num_names; i++) {
2141 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2142 init_lsa_String(&lsa_name_array[i], names[i]);
2145 *lsa_name_array_p = lsa_name_array;
2150 /*******************************************************************
2152 ********************************************************************/
2154 NTSTATUS _samr_LookupRids(pipes_struct *p,
2155 struct samr_LookupRids *r)
2157 struct samr_domain_info *dinfo;
2160 enum lsa_SidType *attrs = NULL;
2161 uint32 *wire_attrs = NULL;
2162 int num_rids = (int)r->in.num_rids;
2164 struct lsa_Strings names_array;
2165 struct samr_Ids types_array;
2166 struct lsa_String *lsa_names = NULL;
2168 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2170 dinfo = policy_handle_find(p, r->in.domain_handle,
2171 0 /* Don't know the acc_bits yet */, NULL,
2172 struct samr_domain_info, &status);
2173 if (!NT_STATUS_IS_OK(status)) {
2177 if (num_rids > 1000) {
2178 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2179 "to samba4 idl this is not possible\n", num_rids));
2180 return NT_STATUS_UNSUCCESSFUL;
2184 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2185 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2186 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2188 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2189 return NT_STATUS_NO_MEMORY;
2196 become_root(); /* lookup_sid can require root privs */
2197 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2201 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2202 status = NT_STATUS_OK;
2205 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2207 return NT_STATUS_NO_MEMORY;
2210 /* Convert from enum lsa_SidType to uint32 for wire format. */
2211 for (i = 0; i < num_rids; i++) {
2212 wire_attrs[i] = (uint32)attrs[i];
2215 names_array.count = num_rids;
2216 names_array.names = lsa_names;
2218 types_array.count = num_rids;
2219 types_array.ids = wire_attrs;
2221 *r->out.names = names_array;
2222 *r->out.types = types_array;
2224 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2229 /*******************************************************************
2231 ********************************************************************/
2233 NTSTATUS _samr_OpenUser(pipes_struct *p,
2234 struct samr_OpenUser *r)
2236 struct samu *sampass=NULL;
2238 struct samr_domain_info *dinfo;
2239 struct samr_user_info *uinfo;
2240 SEC_DESC *psd = NULL;
2242 uint32 des_access = r->in.access_mask;
2243 uint32_t extra_access = 0;
2250 dinfo = policy_handle_find(p, r->in.domain_handle,
2251 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2252 struct samr_domain_info, &status);
2253 if (!NT_STATUS_IS_OK(status)) {
2257 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2258 return NT_STATUS_NO_MEMORY;
2261 /* append the user's RID to it */
2263 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2264 return NT_STATUS_NO_SUCH_USER;
2266 /* check if access can be granted as requested by client. */
2267 map_max_allowed_access(p->server_info->ptok,
2268 &p->server_info->utok,
2271 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2272 se_map_generic(&des_access, &usr_generic_mapping);
2275 * Get the sampass first as we need to check privileges
2276 * based on what kind of user object this is.
2277 * But don't reveal info too early if it didn't exist.
2281 ret=pdb_getsampwsid(sampass, &sid);
2284 se_priv_copy(&se_rights, &se_priv_none);
2287 * We do the override access checks on *open*, not at
2291 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2293 if ((acb_info & ACB_WSTRUST) &&
2294 user_has_any_privilege(p->server_info->ptok,
2295 &se_machine_account)) {
2297 * SeMachineAccount is needed to add
2298 * GENERIC_RIGHTS_USER_WRITE to a machine
2301 se_priv_add(&se_rights, &se_machine_account);
2302 DEBUG(10,("_samr_OpenUser: adding machine account "
2303 "rights to handle for user %s\n",
2304 pdb_get_username(sampass) ));
2306 if ((acb_info & ACB_NORMAL) &&
2307 user_has_any_privilege(p->server_info->ptok,
2310 * SeAddUsers is needed to add
2311 * GENERIC_RIGHTS_USER_WRITE to a normal
2314 se_priv_add(&se_rights, &se_add_users);
2315 DEBUG(10,("_samr_OpenUser: adding add user "
2316 "rights to handle for user %s\n",
2317 pdb_get_username(sampass) ));
2320 * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
2321 * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not
2322 * what Windows does but is a hack for people who haven't
2323 * set up privileges on groups in Samba.
2325 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2326 if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2327 DOMAIN_GROUP_RID_ADMINS)) {
2328 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2329 extra_access = GENERIC_RIGHTS_USER_WRITE;
2330 DEBUG(4,("_samr_OpenUser: Allowing "
2331 "GENERIC_RIGHTS_USER_WRITE for "
2337 TALLOC_FREE(sampass);
2339 nt_status = access_check_object(psd, p->server_info->ptok,
2340 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2341 &acc_granted, "_samr_OpenUser");
2343 if ( !NT_STATUS_IS_OK(nt_status) )
2346 /* check that the SID exists in our domain. */
2348 return NT_STATUS_NO_SUCH_USER;
2351 /* If we did the rid admins hack above, allow access. */
2352 acc_granted |= extra_access;
2354 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2355 struct samr_user_info, &nt_status);
2356 if (!NT_STATUS_IS_OK(nt_status)) {
2361 return NT_STATUS_OK;
2364 /*************************************************************************
2365 *************************************************************************/
2367 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2369 struct lsa_BinaryString **_r)
2371 struct lsa_BinaryString *r;
2374 return NT_STATUS_INVALID_PARAMETER;
2377 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2379 return NT_STATUS_NO_MEMORY;
2382 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2384 return NT_STATUS_NO_MEMORY;
2386 memcpy(r->array, blob->data, blob->length);
2387 r->size = blob->length;
2388 r->length = blob->length;
2391 return NT_STATUS_NO_MEMORY;
2396 return NT_STATUS_OK;
2399 /*************************************************************************
2401 *************************************************************************/
2403 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2404 struct samr_UserInfo1 *r,
2406 DOM_SID *domain_sid)
2408 const DOM_SID *sid_group;
2409 uint32_t primary_gid;
2412 sid_group = pdb_get_group_sid(pw);
2415 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2416 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2417 "which conflicts with the domain sid %s. Failing operation.\n",
2418 pdb_get_username(pw), sid_string_dbg(sid_group),
2419 sid_string_dbg(domain_sid)));
2420 return NT_STATUS_UNSUCCESSFUL;
2423 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2424 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2425 r->primary_gid = primary_gid;
2426 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2427 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2429 return NT_STATUS_OK;
2432 /*************************************************************************
2434 *************************************************************************/
2436 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2437 struct samr_UserInfo2 *r,
2440 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2441 r->unknown.string = NULL;
2442 r->country_code = 0;
2445 return NT_STATUS_OK;
2448 /*************************************************************************
2450 *************************************************************************/
2452 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2453 struct samr_UserInfo3 *r,
2455 DOM_SID *domain_sid)
2457 const DOM_SID *sid_user, *sid_group;
2458 uint32_t rid, primary_gid;
2460 sid_user = pdb_get_user_sid(pw);
2462 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2463 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2464 "the domain sid %s. Failing operation.\n",
2465 pdb_get_username(pw), sid_string_dbg(sid_user),
2466 sid_string_dbg(domain_sid)));
2467 return NT_STATUS_UNSUCCESSFUL;
2471 sid_group = pdb_get_group_sid(pw);
2474 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2475 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2476 "which conflicts with the domain sid %s. Failing operation.\n",
2477 pdb_get_username(pw), sid_string_dbg(sid_group),
2478 sid_string_dbg(domain_sid)));
2479 return NT_STATUS_UNSUCCESSFUL;
2482 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2483 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2484 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2485 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2486 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2488 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2489 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2490 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2491 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2492 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2493 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2494 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2496 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2498 r->primary_gid = primary_gid;
2499 r->acct_flags = pdb_get_acct_ctrl(pw);
2500 r->bad_password_count = pdb_get_bad_password_count(pw);
2501 r->logon_count = pdb_get_logon_count(pw);
2503 return NT_STATUS_OK;
2506 /*************************************************************************
2508 *************************************************************************/
2510 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2511 struct samr_UserInfo4 *r,
2514 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2516 return NT_STATUS_OK;
2519 /*************************************************************************
2521 *************************************************************************/
2523 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2524 struct samr_UserInfo5 *r,
2526 DOM_SID *domain_sid)
2528 const DOM_SID *sid_user, *sid_group;
2529 uint32_t rid, primary_gid;
2531 sid_user = pdb_get_user_sid(pw);
2533 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2534 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2535 "the domain sid %s. Failing operation.\n",
2536 pdb_get_username(pw), sid_string_dbg(sid_user),
2537 sid_string_dbg(domain_sid)));
2538 return NT_STATUS_UNSUCCESSFUL;
2542 sid_group = pdb_get_group_sid(pw);
2545 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2546 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2547 "which conflicts with the domain sid %s. Failing operation.\n",
2548 pdb_get_username(pw), sid_string_dbg(sid_group),
2549 sid_string_dbg(domain_sid)));
2550 return NT_STATUS_UNSUCCESSFUL;
2553 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2554 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2555 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2556 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2558 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2559 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2560 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2561 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2562 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2563 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2564 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2565 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2567 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2569 r->primary_gid = primary_gid;
2570 r->acct_flags = pdb_get_acct_ctrl(pw);
2571 r->bad_password_count = pdb_get_bad_password_count(pw);
2572 r->logon_count = pdb_get_logon_count(pw);
2574 return NT_STATUS_OK;
2577 /*************************************************************************
2579 *************************************************************************/
2581 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2582 struct samr_UserInfo6 *r,
2585 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2586 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2588 return NT_STATUS_OK;
2591 /*************************************************************************
2592 get_user_info_7. Safe. Only gives out account_name.
2593 *************************************************************************/
2595 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2596 struct samr_UserInfo7 *r,
2597 struct samu *smbpass)
2599 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2600 if (!r->account_name.string) {
2601 return NT_STATUS_NO_MEMORY;
2604 return NT_STATUS_OK;
2607 /*************************************************************************
2609 *************************************************************************/
2611 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2612 struct samr_UserInfo8 *r,
2615 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2617 return NT_STATUS_OK;
2620 /*************************************************************************
2621 get_user_info_9. Only gives out primary group SID.
2622 *************************************************************************/
2624 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2625 struct samr_UserInfo9 *r,
2626 struct samu *smbpass)
2628 r->primary_gid = pdb_get_group_rid(smbpass);
2630 return NT_STATUS_OK;
2633 /*************************************************************************
2635 *************************************************************************/
2637 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2638 struct samr_UserInfo10 *r,
2641 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2642 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2644 return NT_STATUS_OK;
2647 /*************************************************************************
2649 *************************************************************************/
2651 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2652 struct samr_UserInfo11 *r,
2655 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2657 return NT_STATUS_OK;
2660 /*************************************************************************
2662 *************************************************************************/
2664 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2665 struct samr_UserInfo12 *r,
2668 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2670 return NT_STATUS_OK;
2673 /*************************************************************************
2675 *************************************************************************/
2677 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2678 struct samr_UserInfo13 *r,
2681 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2683 return NT_STATUS_OK;
2686 /*************************************************************************
2688 *************************************************************************/
2690 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2691 struct samr_UserInfo14 *r,
2694 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2696 return NT_STATUS_OK;
2699 /*************************************************************************
2700 get_user_info_16. Safe. Only gives out acb bits.
2701 *************************************************************************/
2703 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2704 struct samr_UserInfo16 *r,
2705 struct samu *smbpass)
2707 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2709 return NT_STATUS_OK;
2712 /*************************************************************************
2714 *************************************************************************/
2716 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2717 struct samr_UserInfo17 *r,
2720 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2722 return NT_STATUS_OK;
2725 /*************************************************************************
2726 get_user_info_18. OK - this is the killer as it gives out password info.
2727 Ensure that this is only allowed on an encrypted connection with a root
2729 *************************************************************************/
2731 static NTSTATUS get_user_info_18(pipes_struct *p,
2732 TALLOC_CTX *mem_ctx,
2733 struct samr_UserInfo18 *r,
2736 struct samu *smbpass=NULL;
2741 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2742 return NT_STATUS_ACCESS_DENIED;
2745 if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2746 return NT_STATUS_ACCESS_DENIED;
2750 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2753 if ( !(smbpass = samu_new( mem_ctx )) ) {
2754 return NT_STATUS_NO_MEMORY;
2757 ret = pdb_getsampwsid(smbpass, user_sid);
2760 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2761 TALLOC_FREE(smbpass);
2762 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2765 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2767 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2768 TALLOC_FREE(smbpass);
2769 return NT_STATUS_ACCOUNT_DISABLED;
2772 r->lm_pwd_active = true;
2773 r->nt_pwd_active = true;
2774 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2775 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2776 r->password_expired = 0; /* FIXME */
2778 TALLOC_FREE(smbpass);
2780 return NT_STATUS_OK;
2783 /*************************************************************************
2785 *************************************************************************/
2787 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2788 struct samr_UserInfo20 *r,
2789 struct samu *sampass)
2791 const char *munged_dial = NULL;
2794 struct lsa_BinaryString *parameters = NULL;
2798 munged_dial = pdb_get_munged_dial(sampass);
2800 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2801 munged_dial, (int)strlen(munged_dial)));
2804 blob = base64_decode_data_blob(munged_dial);
2806 blob = data_blob_string_const_null("");
2809 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2810 data_blob_free(&blob);
2811 if (!NT_STATUS_IS_OK(status)) {
2815 r->parameters = *parameters;
2817 return NT_STATUS_OK;
2821 /*************************************************************************
2823 *************************************************************************/
2825 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2826 struct samr_UserInfo21 *r,
2828 DOM_SID *domain_sid,
2829 uint32_t acc_granted)
2832 const DOM_SID *sid_user, *sid_group;
2833 uint32_t rid, primary_gid;
2834 NTTIME force_password_change;
2835 time_t must_change_time;
2836 struct lsa_BinaryString *parameters = NULL;
2837 const char *munged_dial = NULL;
2842 sid_user = pdb_get_user_sid(pw);
2844 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2845 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2846 "the domain sid %s. Failing operation.\n",
2847 pdb_get_username(pw), sid_string_dbg(sid_user),
2848 sid_string_dbg(domain_sid)));
2849 return NT_STATUS_UNSUCCESSFUL;
2853 sid_group = pdb_get_group_sid(pw);
2856 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2857 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2858 "which conflicts with the domain sid %s. Failing operation.\n",
2859 pdb_get_username(pw), sid_string_dbg(sid_group),
2860 sid_string_dbg(domain_sid)));
2861 return NT_STATUS_UNSUCCESSFUL;
2864 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2865 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2866 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2867 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2868 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2870 must_change_time = pdb_get_pass_must_change_time(pw);
2871 if (must_change_time == get_time_t_max()) {
2872 unix_to_nt_time_abs(&force_password_change, must_change_time);
2874 unix_to_nt_time(&force_password_change, must_change_time);
2877 munged_dial = pdb_get_munged_dial(pw);
2879 blob = base64_decode_data_blob(munged_dial);
2881 blob = data_blob_string_const_null("");
2884 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2885 data_blob_free(&blob);
2886 if (!NT_STATUS_IS_OK(status)) {
2890 r->force_password_change = force_password_change;
2892 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2893 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2894 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2895 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2896 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2897 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2898 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2899 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2900 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2902 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2903 r->parameters = *parameters;
2905 r->primary_gid = primary_gid;
2906 r->acct_flags = pdb_get_acct_ctrl(pw);
2907 r->bad_password_count = pdb_get_bad_password_count(pw);
2908 r->logon_count = pdb_get_logon_count(pw);
2909 r->fields_present = pdb_build_fields_present(pw);
2910 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2911 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2912 r->country_code = 0;
2914 r->lm_password_set = 0;
2915 r->nt_password_set = 0;
2920 Look at a user on a real NT4 PDC with usrmgr, press
2921 'ok'. Then you will see that fields_present is set to
2922 0x08f827fa. Look at the user immediately after that again,
2923 and you will see that 0x00fffff is returned. This solves
2924 the problem that you get access denied after having looked
2932 return NT_STATUS_OK;
2935 /*******************************************************************
2937 ********************************************************************/
2939 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2940 struct samr_QueryUserInfo *r)
2943 union samr_UserInfo *user_info = NULL;
2944 struct samr_user_info *uinfo;
2948 struct samu *pwd = NULL;
2949 uint32_t acc_required, acc_granted;
2951 switch (r->in.level) {
2952 case 1: /* UserGeneralInformation */
2953 /* USER_READ_GENERAL */
2954 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2956 case 2: /* UserPreferencesInformation */
2957 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2958 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2959 SAMR_USER_ACCESS_GET_NAME_ETC;
2961 case 3: /* UserLogonInformation */
2962 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2963 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2964 SAMR_USER_ACCESS_GET_LOCALE |
2965 SAMR_USER_ACCESS_GET_LOGONINFO |
2966 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2968 case 4: /* UserLogonHoursInformation */
2969 /* USER_READ_LOGON */
2970 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2972 case 5: /* UserAccountInformation */
2973 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2974 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2975 SAMR_USER_ACCESS_GET_LOCALE |
2976 SAMR_USER_ACCESS_GET_LOGONINFO |
2977 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2979 case 6: /* UserNameInformation */
2980 case 7: /* UserAccountNameInformation */
2981 case 8: /* UserFullNameInformation */
2982 case 9: /* UserPrimaryGroupInformation */
2983 case 13: /* UserAdminCommentInformation */
2984 /* USER_READ_GENERAL */
2985 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2987 case 10: /* UserHomeInformation */
2988 case 11: /* UserScriptInformation */
2989 case 12: /* UserProfileInformation */
2990 case 14: /* UserWorkStationsInformation */
2991 /* USER_READ_LOGON */
2992 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2994 case 16: /* UserControlInformation */
2995 case 17: /* UserExpiresInformation */
2996 case 20: /* UserParametersInformation */
2997 /* USER_READ_ACCOUNT */
2998 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3000 case 21: /* UserAllInformation */
3002 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3004 case 18: /* UserInternal1Information */
3006 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3008 case 23: /* UserInternal4Information */
3009 case 24: /* UserInternal4InformationNew */
3010 case 25: /* UserInternal4InformationNew */
3011 case 26: /* UserInternal5InformationNew */
3013 return NT_STATUS_INVALID_INFO_CLASS;
3017 uinfo = policy_handle_find(p, r->in.user_handle,
3018 acc_required, &acc_granted,
3019 struct samr_user_info, &status);
3020 if (!NT_STATUS_IS_OK(status)) {
3024 domain_sid = uinfo->sid;
3026 sid_split_rid(&domain_sid, &rid);
3028 if (!sid_check_is_in_our_domain(&uinfo->sid))
3029 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3031 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3032 sid_string_dbg(&uinfo->sid)));
3034 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3036 return NT_STATUS_NO_MEMORY;
3039 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3041 if (!(pwd = samu_new(p->mem_ctx))) {
3042 return NT_STATUS_NO_MEMORY;
3046 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3050 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3052 return NT_STATUS_NO_SUCH_USER;
3055 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3057 samr_clear_sam_passwd(pwd);
3059 switch (r->in.level) {
3061 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3064 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3067 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3070 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3073 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3076 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3079 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3082 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3085 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3088 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3091 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3094 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3097 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3100 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3103 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3106 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3109 /* level 18 is special */
3110 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3114 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3117 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3120 status = NT_STATUS_INVALID_INFO_CLASS;
3124 if (!NT_STATUS_IS_OK(status)) {
3128 *r->out.info = user_info;
3133 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3138 /****************************************************************
3139 ****************************************************************/
3141 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3142 struct samr_QueryUserInfo2 *r)
3144 struct samr_QueryUserInfo u;
3146 u.in.user_handle = r->in.user_handle;
3147 u.in.level = r->in.level;
3148 u.out.info = r->out.info;
3150 return _samr_QueryUserInfo(p, &u);
3153 /*******************************************************************
3154 _samr_GetGroupsForUser
3155 ********************************************************************/
3157 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3158 struct samr_GetGroupsForUser *r)
3160 struct samr_user_info *uinfo;
3161 struct samu *sam_pass=NULL;
3163 struct samr_RidWithAttribute dom_gid;
3164 struct samr_RidWithAttribute *gids = NULL;
3165 uint32 primary_group_rid;
3166 size_t num_groups = 0;
3171 bool success = False;
3173 struct samr_RidWithAttributeArray *rids = NULL;
3176 * from the SID in the request:
3177 * we should send back the list of DOMAIN GROUPS
3178 * the user is a member of
3180 * and only the DOMAIN GROUPS
3181 * no ALIASES !!! neither aliases of the domain
3182 * nor aliases of the builtin SID
3187 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3189 uinfo = policy_handle_find(p, r->in.user_handle,
3190 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3191 struct samr_user_info, &result);
3192 if (!NT_STATUS_IS_OK(result)) {
3196 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3198 return NT_STATUS_NO_MEMORY;
3201 if (!sid_check_is_in_our_domain(&uinfo->sid))
3202 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3204 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3205 return NT_STATUS_NO_MEMORY;
3209 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3213 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3214 sid_string_dbg(&uinfo->sid)));
3215 return NT_STATUS_NO_SUCH_USER;
3220 /* make both calls inside the root block */
3222 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3223 &sids, &unix_gids, &num_groups);
3224 if ( NT_STATUS_IS_OK(result) ) {
3225 success = sid_peek_check_rid(get_global_sam_sid(),
3226 pdb_get_group_sid(sam_pass),
3227 &primary_group_rid);
3231 if (!NT_STATUS_IS_OK(result)) {
3232 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3233 sid_string_dbg(&uinfo->sid)));
3238 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3239 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3240 pdb_get_username(sam_pass)));
3241 TALLOC_FREE(sam_pass);
3242 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3248 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3250 dom_gid.rid = primary_group_rid;
3251 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3253 for (i=0; i<num_groups; i++) {
3255 if (!sid_peek_check_rid(get_global_sam_sid(),
3256 &(sids[i]), &dom_gid.rid)) {
3257 DEBUG(10, ("Found sid %s not in our domain\n",
3258 sid_string_dbg(&sids[i])));
3262 if (dom_gid.rid == primary_group_rid) {
3263 /* We added the primary group directly from the
3264 * sam_account. The other SIDs are unique from
3265 * enum_group_memberships */
3269 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3272 rids->count = num_gids;
3275 *r->out.rids = rids;
3277 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3282 /*******************************************************************
3283 ********************************************************************/
3285 static uint32_t samr_get_server_role(void)
3287 uint32_t role = ROLE_DOMAIN_PDC;
3289 if (lp_server_role() == ROLE_DOMAIN_BDC) {
3290 role = ROLE_DOMAIN_BDC;
3296 /*******************************************************************
3297 ********************************************************************/
3299 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3300 struct samr_DomInfo1 *r)
3302 uint32_t account_policy_temp;
3303 time_t u_expire, u_min_age;
3309 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3310 r->min_password_length = account_policy_temp;
3312 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3313 r->password_history_length = account_policy_temp;
3315 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3316 &r->password_properties);
3318 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3319 u_expire = account_policy_temp;
3321 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3322 u_min_age = account_policy_temp;
3328 unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3329 unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3331 if (lp_check_password_script() && *lp_check_password_script()) {
3332 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3335 return NT_STATUS_OK;
3338 /*******************************************************************
3339 ********************************************************************/
3341 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3342 struct samr_DomGeneralInformation *r,
3343 struct samr_domain_info *dinfo)
3352 r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3353 r->num_groups = count_sam_groups(dinfo->disp_info);
3354 r->num_aliases = count_sam_aliases(dinfo->disp_info);
3356 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3358 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3360 if (!pdb_get_seq_num(&seq_num)) {
3361 seq_num = time(NULL);
3368 r->oem_information.string = lp_serverstring();
3369 r->domain_name.string = lp_workgroup();
3370 r->primary.string = global_myname();
3371 r->sequence_num = seq_num;
3372 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3373 r->role = samr_get_server_role();
3376 return NT_STATUS_OK;
3379 /*******************************************************************
3380 ********************************************************************/
3382 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3383 struct samr_DomInfo3 *r)
3393 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3394 u_logout = (time_t)ul;
3401 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3403 return NT_STATUS_OK;
3406 /*******************************************************************
3407 ********************************************************************/
3409 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3410 struct samr_DomOEMInformation *r)
3412 r->oem_information.string = lp_serverstring();
3414 return NT_STATUS_OK;
3417 /*******************************************************************
3418 ********************************************************************/
3420 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3421 struct samr_DomInfo5 *r)
3423 r->domain_name.string = get_global_sam_name();
3425 return NT_STATUS_OK;
3428 /*******************************************************************
3429 ********************************************************************/
3431 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3432 struct samr_DomInfo6 *r)
3434 /* NT returns its own name when a PDC. win2k and later
3435 * only the name of the PDC if itself is a BDC (samba4
3437 r->primary.string = global_myname();
3439 return NT_STATUS_OK;
3442 /*******************************************************************
3443 ********************************************************************/
3445 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3446 struct samr_DomInfo7 *r)
3448 r->role = samr_get_server_role();
3450 return NT_STATUS_OK;
3453 /*******************************************************************
3454 ********************************************************************/
3456 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3457 struct samr_DomInfo8 *r)
3465 if (!pdb_get_seq_num(&seq_num)) {
3466 seq_num = time(NULL);
3473 r->sequence_num = seq_num;
3474 r->domain_create_time = 0;
3476 return NT_STATUS_OK;
3479 /*******************************************************************
3480 ********************************************************************/
3482 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3483 struct samr_DomInfo9 *r)
3485 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3487 return NT_STATUS_OK;
3490 /*******************************************************************
3491 ********************************************************************/
3493 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3494 struct samr_DomGeneralInformation2 *r,
3495 struct samr_domain_info *dinfo)
3498 uint32_t account_policy_temp;
3499 time_t u_lock_duration, u_reset_time;
3501 status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3502 if (!NT_STATUS_IS_OK(status)) {
3510 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3511 u_lock_duration = account_policy_temp;
3512 if (u_lock_duration != -1) {
3513 u_lock_duration *= 60;
3516 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3517 u_reset_time = account_policy_temp * 60;
3519 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3520 r->lockout_threshold = account_policy_temp;
3526 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3527 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3529 return NT_STATUS_OK;
3532 /*******************************************************************
3533 ********************************************************************/
3535 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3536 struct samr_DomInfo12 *r)
3538 uint32_t account_policy_temp;
3539 time_t u_lock_duration, u_reset_time;
3545 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3546 u_lock_duration = account_policy_temp;
3547 if (u_lock_duration != -1) {
3548 u_lock_duration *= 60;
3551 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3552 u_reset_time = account_policy_temp * 60;
3554 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3555 r->lockout_threshold = account_policy_temp;
3561 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3562 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3564 return NT_STATUS_OK;
3567 /*******************************************************************
3568 ********************************************************************/
3570 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3571 struct samr_DomInfo13 *r)
3579 if (!pdb_get_seq_num(&seq_num)) {
3580 seq_num = time(NULL);
3587 r->sequence_num = seq_num;
3588 r->domain_create_time = 0;
3589 r->modified_count_at_last_promotion = 0;
3591 return NT_STATUS_OK;
3594 /*******************************************************************
3595 _samr_QueryDomainInfo
3596 ********************************************************************/
3598 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3599 struct samr_QueryDomainInfo *r)
3601 NTSTATUS status = NT_STATUS_OK;
3602 struct samr_domain_info *dinfo;
3603 union samr_DomainInfo *dom_info;
3605 uint32_t acc_required;
3607 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3609 switch (r->in.level) {
3610 case 1: /* DomainPasswordInformation */
3611 case 12: /* DomainLockoutInformation */
3612 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3613 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3615 case 11: /* DomainGeneralInformation2 */
3616 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3617 * DOMAIN_READ_OTHER_PARAMETERS */
3618 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3619 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3621 case 2: /* DomainGeneralInformation */
3622 case 3: /* DomainLogoffInformation */
3623 case 4: /* DomainOemInformation */
3624 case 5: /* DomainReplicationInformation */
3625 case 6: /* DomainReplicationInformation */
3626 case 7: /* DomainServerRoleInformation */
3627 case 8: /* DomainModifiedInformation */
3628 case 9: /* DomainStateInformation */
3629 case 10: /* DomainUasInformation */
3630 case 13: /* DomainModifiedInformation2 */
3631 /* DOMAIN_READ_OTHER_PARAMETERS */
3632 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3635 return NT_STATUS_INVALID_INFO_CLASS;
3638 dinfo = policy_handle_find(p, r->in.domain_handle,
3640 struct samr_domain_info, &status);
3641 if (!NT_STATUS_IS_OK(status)) {
3645 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3647 return NT_STATUS_NO_MEMORY;
3650 switch (r->in.level) {
3652 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3655 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3658 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3661 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3664 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3667 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3670 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3673 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3676 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3679 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3682 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3685 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3688 return NT_STATUS_INVALID_INFO_CLASS;
3691 if (!NT_STATUS_IS_OK(status)) {
3695 *r->out.info = dom_info;
3697 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3702 /* W2k3 seems to use the same check for all 3 objects that can be created via
3703 * SAMR, if you try to create for example "Dialup" as an alias it says
3704 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3707 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3709 enum lsa_SidType type;
3712 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3715 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3716 * whether the name already exists */
3717 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3718 NULL, NULL, NULL, &type);
3722 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3723 return NT_STATUS_OK;
3726 DEBUG(5, ("trying to create %s, exists as %s\n",
3727 new_name, sid_type_lookup(type)));
3729 if (type == SID_NAME_DOM_GRP) {
3730 return NT_STATUS_GROUP_EXISTS;
3732 if (type == SID_NAME_ALIAS) {
3733 return NT_STATUS_ALIAS_EXISTS;
3736 /* Yes, the default is NT_STATUS_USER_EXISTS */
3737 return NT_STATUS_USER_EXISTS;
3740 /*******************************************************************
3742 ********************************************************************/
3744 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3745 struct samr_CreateUser2 *r)
3747 const char *account = NULL;
3749 uint32_t acb_info = r->in.acct_flags;
3750 struct samr_domain_info *dinfo;
3751 struct samr_user_info *uinfo;
3756 /* check this, when giving away 'add computer to domain' privs */
3757 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3758 bool can_add_account = False;
3761 dinfo = policy_handle_find(p, r->in.domain_handle,
3762 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3763 struct samr_domain_info, &nt_status);
3764 if (!NT_STATUS_IS_OK(nt_status)) {
3768 if (sid_check_is_builtin(&dinfo->sid)) {
3769 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3770 return NT_STATUS_ACCESS_DENIED;
3773 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3774 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3775 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3776 this parameter is not an account type */
3777 return NT_STATUS_INVALID_PARAMETER;
3780 account = r->in.account_name->string;
3781 if (account == NULL) {
3782 return NT_STATUS_NO_MEMORY;
3785 nt_status = can_create(p->mem_ctx, account);
3786 if (!NT_STATUS_IS_OK(nt_status)) {
3790 /* determine which user right we need to check based on the acb_info */
3792 if (geteuid() == sec_initial_uid()) {
3793 se_priv_copy(&se_rights, &se_priv_none);
3794 can_add_account = true;
3795 } else if (acb_info & ACB_WSTRUST) {
3796 se_priv_copy(&se_rights, &se_machine_account);
3797 can_add_account = user_has_privileges(
3798 p->server_info->ptok, &se_rights );
3799 } else if (acb_info & ACB_NORMAL &&
3800 (account[strlen(account)-1] != '$')) {
3801 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3802 account for domain trusts and changes the ACB flags later */
3803 se_priv_copy(&se_rights, &se_add_users);
3804 can_add_account = user_has_privileges(
3805 p->server_info->ptok, &se_rights );
3806 } else if (lp_enable_privileges()) {
3807 /* implicit assumption of a BDC or domain trust account here
3808 * (we already check the flags earlier) */
3809 /* only Domain Admins can add a BDC or domain trust */
3810 se_priv_copy(&se_rights, &se_priv_none);
3811 can_add_account = nt_token_check_domain_rid(
3812 p->server_info->ptok,
3813 DOMAIN_GROUP_RID_ADMINS );
3816 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3817 uidtoname(p->server_info->utok.uid),
3818 can_add_account ? "True":"False" ));
3820 if (!can_add_account) {
3821 return NT_STATUS_ACCESS_DENIED;
3824 /********** BEGIN Admin BLOCK **********/
3827 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3831 /********** END Admin BLOCK **********/
3833 /* now check for failure */
3835 if ( !NT_STATUS_IS_OK(nt_status) )
3838 /* Get the user's SID */
3840 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3842 map_max_allowed_access(p->server_info->ptok,
3843 &p->server_info->utok,
3846 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3847 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3848 se_map_generic(&des_access, &usr_generic_mapping);
3851 * JRA - TESTME. We just created this user so we
3852 * had rights to create them. Do we need to check
3853 * any further access on this object ? Can't we
3854 * just assume we have all the rights we need ?
3857 nt_status = access_check_object(psd, p->server_info->ptok,
3858 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3859 &acc_granted, "_samr_CreateUser2");
3861 if ( !NT_STATUS_IS_OK(nt_status) ) {
3865 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3866 struct samr_user_info, &nt_status);
3867 if (!NT_STATUS_IS_OK(nt_status)) {
3872 /* After a "set" ensure we have no cached display info. */
3873 force_flush_samr_cache(&sid);
3875 *r->out.access_granted = acc_granted;
3877 return NT_STATUS_OK;
3880 /****************************************************************
3881 ****************************************************************/
3883 NTSTATUS _samr_CreateUser(pipes_struct *p,
3884 struct samr_CreateUser *r)
3886 struct samr_CreateUser2 c;
3887 uint32_t access_granted;
3889 c.in.domain_handle = r->in.domain_handle;
3890 c.in.account_name = r->in.account_name;
3891 c.in.acct_flags = ACB_NORMAL;
3892 c.in.access_mask = r->in.access_mask;
3893 c.out.user_handle = r->out.user_handle;
3894 c.out.access_granted = &access_granted;
3895 c.out.rid = r->out.rid;
3897 return _samr_CreateUser2(p, &c);
3900 /*******************************************************************
3902 ********************************************************************/
3904 NTSTATUS _samr_Connect(pipes_struct *p,
3905 struct samr_Connect *r)
3907 struct samr_connect_info *info;
3908 uint32_t acc_granted;
3909 struct policy_handle hnd;
3910 uint32 des_access = r->in.access_mask;
3915 if (!pipe_access_check(p)) {
3916 DEBUG(3, ("access denied to _samr_Connect\n"));
3917 return NT_STATUS_ACCESS_DENIED;
3920 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3921 was observed from a win98 client trying to enumerate users (when configured
3922 user level access control on shares) --jerry */
3924 map_max_allowed_access(p->server_info->ptok,
3925 &p->server_info->utok,
3928 se_map_generic( &des_access, &sam_generic_mapping );
3930 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3931 |SAMR_ACCESS_LOOKUP_DOMAIN);
3933 /* set up the SAMR connect_anon response */
3935 info = policy_handle_create(p, &hnd, acc_granted,
3936 struct samr_connect_info,
3938 if (!NT_STATUS_IS_OK(status)) {
3942 *r->out.connect_handle = hnd;
3943 return NT_STATUS_OK;
3946 /*******************************************************************
3948 ********************************************************************/
3950 NTSTATUS _samr_Connect2(pipes_struct *p,
3951 struct samr_Connect2 *r)
3953 struct samr_connect_info *info = NULL;
3954 struct policy_handle hnd;
3955 SEC_DESC *psd = NULL;
3957 uint32 des_access = r->in.access_mask;
3960 const char *fn = "_samr_Connect2";
3962 switch (p->hdr_req.opnum) {
3963 case NDR_SAMR_CONNECT2:
3964 fn = "_samr_Connect2";
3966 case NDR_SAMR_CONNECT3:
3967 fn = "_samr_Connect3";
3969 case NDR_SAMR_CONNECT4:
3970 fn = "_samr_Connect4";
3972 case NDR_SAMR_CONNECT5:
3973 fn = "_samr_Connect5";
3977 DEBUG(5,("%s: %d\n", fn, __LINE__));
3981 if (!pipe_access_check(p)) {
3982 DEBUG(3, ("access denied to %s\n", fn));
3983 return NT_STATUS_ACCESS_DENIED;
3986 map_max_allowed_access(p->server_info->ptok,
3987 &p->server_info->utok,
3990 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3991 se_map_generic(&des_access, &sam_generic_mapping);
3993 nt_status = access_check_object(psd, p->server_info->ptok,
3994 NULL, 0, des_access, &acc_granted, fn);
3996 if ( !NT_STATUS_IS_OK(nt_status) )
3999 info = policy_handle_create(p, &hnd, acc_granted,
4000 struct samr_connect_info, &nt_status);
4001 if (!NT_STATUS_IS_OK(nt_status)) {
4005 DEBUG(5,("%s: %d\n", fn, __LINE__));
4007 *r->out.connect_handle = hnd;
4008 return NT_STATUS_OK;
4011 /****************************************************************
4013 ****************************************************************/
4015 NTSTATUS _samr_Connect3(pipes_struct *p,
4016 struct samr_Connect3 *r)
4018 struct samr_Connect2 c;
4020 c.in.system_name = r->in.system_name;
4021 c.in.access_mask = r->in.access_mask;
4022 c.out.connect_handle = r->out.connect_handle;
4024 return _samr_Connect2(p, &c);
4027 /*******************************************************************
4029 ********************************************************************/
4031 NTSTATUS _samr_Connect4(pipes_struct *p,
4032 struct samr_Connect4 *r)
4034 struct samr_Connect2 c;
4036 c.in.system_name = r->in.system_name;
4037 c.in.access_mask = r->in.access_mask;
4038 c.out.connect_handle = r->out.connect_handle;
4040 return _samr_Connect2(p, &c);
4043 /*******************************************************************
4045 ********************************************************************/
4047 NTSTATUS _samr_Connect5(pipes_struct *p,
4048 struct samr_Connect5 *r)
4051 struct samr_Connect2 c;
4052 struct samr_ConnectInfo1 info1;
4054 info1.client_version = SAMR_CONNECT_AFTER_W2K;
4057 c.in.system_name = r->in.system_name;
4058 c.in.access_mask = r->in.access_mask;
4059 c.out.connect_handle = r->out.connect_handle;
4061 *r->out.level_out = 1;
4063 status = _samr_Connect2(p, &c);
4064 if (!NT_STATUS_IS_OK(status)) {
4068 r->out.info_out->info1 = info1;
4070 return NT_STATUS_OK;
4073 /**********************************************************************
4075 **********************************************************************/
4077 NTSTATUS _samr_LookupDomain(pipes_struct *p,
4078 struct samr_LookupDomain *r)
4081 struct samr_connect_info *info;
4082 const char *domain_name;
4083 DOM_SID *sid = NULL;
4085 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4086 Reverted that change so we will work with RAS servers again */
4088 info = policy_handle_find(p, r->in.connect_handle,
4089 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4090 struct samr_connect_info,
4092 if (!NT_STATUS_IS_OK(status)) {
4096 domain_name = r->in.domain_name->string;
4098 return NT_STATUS_INVALID_PARAMETER;
4101 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
4103 return NT_STATUS_NO_MEMORY;
4106 if (strequal(domain_name, builtin_domain_name())) {
4107 sid_copy(sid, &global_sid_Builtin);
4109 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4110 status = NT_STATUS_NO_SUCH_DOMAIN;
4114 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4115 sid_string_dbg(sid)));
4122 /**********************************************************************
4124 **********************************************************************/
4126 NTSTATUS _samr_EnumDomains(pipes_struct *p,
4127 struct samr_EnumDomains *r)
4130 struct samr_connect_info *info;
4131 uint32_t num_entries = 2;
4132 struct samr_SamEntry *entry_array = NULL;
4133 struct samr_SamArray *sam;
4135 info = policy_handle_find(p, r->in.connect_handle,
4136 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4137 struct samr_connect_info, &status);
4138 if (!NT_STATUS_IS_OK(status)) {
4142 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4144 return NT_STATUS_NO_MEMORY;
4147 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4148 struct samr_SamEntry,
4151 return NT_STATUS_NO_MEMORY;
4154 entry_array[0].idx = 0;
4155 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4157 entry_array[1].idx = 1;
4158 init_lsa_String(&entry_array[1].name, "Builtin");
4160 sam->count = num_entries;
4161 sam->entries = entry_array;
4164 *r->out.num_entries = num_entries;
4169 /*******************************************************************
4171 ********************************************************************/
4173 NTSTATUS _samr_OpenAlias(pipes_struct *p,
4174 struct samr_OpenAlias *r)
4177 uint32 alias_rid = r->in.rid;
4178 struct samr_alias_info *ainfo;
4179 struct samr_domain_info *dinfo;
4180 SEC_DESC *psd = NULL;
4182 uint32 des_access = r->in.access_mask;
4187 dinfo = policy_handle_find(p, r->in.domain_handle,
4188 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4189 struct samr_domain_info, &status);
4190 if (!NT_STATUS_IS_OK(status)) {
4194 /* append the alias' RID to it */
4196 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4197 return NT_STATUS_NO_SUCH_ALIAS;
4199 /*check if access can be granted as requested by client. */
4201 map_max_allowed_access(p->server_info->ptok,
4202 &p->server_info->utok,
4205 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4206 se_map_generic(&des_access,&ali_generic_mapping);
4208 se_priv_copy( &se_rights, &se_add_users );
4210 status = access_check_object(psd, p->server_info->ptok,
4211 &se_rights, GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4212 des_access, &acc_granted, "_samr_OpenAlias");
4214 if ( !NT_STATUS_IS_OK(status) )
4218 /* Check we actually have the requested alias */
4219 enum lsa_SidType type;
4224 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4227 if (!result || (type != SID_NAME_ALIAS)) {
4228 return NT_STATUS_NO_SUCH_ALIAS;
4231 /* make sure there is a mapping */
4233 if ( !sid_to_gid( &sid, &gid ) ) {
4234 return NT_STATUS_NO_SUCH_ALIAS;
4239 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4240 struct samr_alias_info, &status);
4241 if (!NT_STATUS_IS_OK(status)) {
4246 return NT_STATUS_OK;
4249 /*******************************************************************
4251 ********************************************************************/
4253 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4254 struct samr_UserInfo2 *id2,
4258 DEBUG(5,("set_user_info_2: NULL id2\n"));
4259 return NT_STATUS_ACCESS_DENIED;
4262 copy_id2_to_sam_passwd(pwd, id2);
4264 return pdb_update_sam_account(pwd);
4267 /*******************************************************************
4269 ********************************************************************/
4271 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4272 struct samr_UserInfo4 *id4,
4276 DEBUG(5,("set_user_info_2: NULL id4\n"));
4277 return NT_STATUS_ACCESS_DENIED;
4280 copy_id4_to_sam_passwd(pwd, id4);
4282 return pdb_update_sam_account(pwd);
4285 /*******************************************************************
4287 ********************************************************************/
4289 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4290 struct samr_UserInfo6 *id6,
4294 DEBUG(5,("set_user_info_6: NULL id6\n"));
4295 return NT_STATUS_ACCESS_DENIED;
4298 copy_id6_to_sam_passwd(pwd, id6);
4300 return pdb_update_sam_account(pwd);
4303 /*******************************************************************
4305 ********************************************************************/
4307 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4308 struct samr_UserInfo7 *id7,
4314 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4315 return NT_STATUS_ACCESS_DENIED;
4318 if (!id7->account_name.string) {
4319 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4320 return NT_STATUS_ACCESS_DENIED;
4323 /* check to see if the new username already exists. Note: we can't
4324 reliably lock all backends, so there is potentially the
4325 possibility that a user can be created in between this check and
4326 the rename. The rename should fail, but may not get the
4327 exact same failure status code. I think this is small enough
4328 of a window for this type of operation and the results are
4329 simply that the rename fails with a slightly different status
4330 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4332 rc = can_create(mem_ctx, id7->account_name.string);
4334 /* when there is nothing to change, we're done here */
4335 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4336 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4337 return NT_STATUS_OK;
4339 if (!NT_STATUS_IS_OK(rc)) {
4343 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4348 /*******************************************************************
4350 ********************************************************************/
4352 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4353 struct samr_UserInfo8 *id8,
4357 DEBUG(5,("set_user_info_8: NULL id8\n"));
4358 return NT_STATUS_ACCESS_DENIED;
4361 copy_id8_to_sam_passwd(pwd, id8);
4363 return pdb_update_sam_account(pwd);
4366 /*******************************************************************
4368 ********************************************************************/
4370 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4371 struct samr_UserInfo10 *id10,
4375 DEBUG(5,("set_user_info_8: NULL id10\n"));
4376 return NT_STATUS_ACCESS_DENIED;
4379 copy_id10_to_sam_passwd(pwd, id10);
4381 return pdb_update_sam_account(pwd);
4384 /*******************************************************************
4386 ********************************************************************/
4388 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4389 struct samr_UserInfo11 *id11,
4393 DEBUG(5,("set_user_info_11: NULL id11\n"));
4394 return NT_STATUS_ACCESS_DENIED;
4397 copy_id11_to_sam_passwd(pwd, id11);
4399 return pdb_update_sam_account(pwd);
4402 /*******************************************************************
4404 ********************************************************************/
4406 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4407 struct samr_UserInfo12 *id12,
4411 DEBUG(5,("set_user_info_12: NULL id12\n"));
4412 return NT_STATUS_ACCESS_DENIED;
4415 copy_id12_to_sam_passwd(pwd, id12);
4417 return pdb_update_sam_account(pwd);
4420 /*******************************************************************
4422 ********************************************************************/
4424 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4425 struct samr_UserInfo13 *id13,
4429 DEBUG(5,("set_user_info_13: NULL id13\n"));
4430 return NT_STATUS_ACCESS_DENIED;
4433 copy_id13_to_sam_passwd(pwd, id13);
4435 return pdb_update_sam_account(pwd);
4438 /*******************************************************************
4440 ********************************************************************/
4442 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4443 struct samr_UserInfo14 *id14,
4447 DEBUG(5,("set_user_info_14: NULL id14\n"));
4448 return NT_STATUS_ACCESS_DENIED;
4451 copy_id14_to_sam_passwd(pwd, id14);
4453 return pdb_update_sam_account(pwd);
4456 /*******************************************************************
4458 ********************************************************************/
4460 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4461 struct samr_UserInfo16 *id16,
4465 DEBUG(5,("set_user_info_16: NULL id16\n"));
4466 return NT_STATUS_ACCESS_DENIED;
4469 copy_id16_to_sam_passwd(pwd, id16);
4471 return pdb_update_sam_account(pwd);
4474 /*******************************************************************
4476 ********************************************************************/
4478 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4479 struct samr_UserInfo17 *id17,
4483 DEBUG(5,("set_user_info_17: NULL id17\n"));
4484 return NT_STATUS_ACCESS_DENIED;
4487 copy_id17_to_sam_passwd(pwd, id17);
4489 return pdb_update_sam_account(pwd);
4492 /*******************************************************************
4494 ********************************************************************/
4496 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4497 TALLOC_CTX *mem_ctx,
4498 DATA_BLOB *session_key,
4502 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4503 return NT_STATUS_INVALID_PARAMETER;
4506 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4507 if (!session_key->length) {
4508 return NT_STATUS_NO_USER_SESSION_KEY;
4512 if (id18->nt_pwd_active) {
4516 in = data_blob_const(id18->nt_pwd.hash, 16);
4517 out = data_blob_talloc_zero(mem_ctx, 16);
4519 sess_crypt_blob(&out, &in, session_key, false);
4521 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4522 return NT_STATUS_ACCESS_DENIED;
4525 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4528 if (id18->lm_pwd_active) {
4532 in = data_blob_const(id18->lm_pwd.hash, 16);
4533 out = data_blob_talloc_zero(mem_ctx, 16);
4535 sess_crypt_blob(&out, &in, session_key, false);
4537 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4538 return NT_STATUS_ACCESS_DENIED;
4541 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4544 copy_id18_to_sam_passwd(pwd, id18);
4546 return pdb_update_sam_account(pwd);
4549 /*******************************************************************
4551 ********************************************************************/
4553 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4554 struct samr_UserInfo20 *id20,
4558 DEBUG(5,("set_user_info_20: NULL id20\n"));
4559 return NT_STATUS_ACCESS_DENIED;
4562 copy_id20_to_sam_passwd(pwd, id20);
4564 return pdb_update_sam_account(pwd);
4567 /*******************************************************************
4569 ********************************************************************/
4571 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4572 TALLOC_CTX *mem_ctx,
4573 DATA_BLOB *session_key,
4579 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4580 return NT_STATUS_INVALID_PARAMETER;
4583 if (id21->fields_present == 0) {
4584 return NT_STATUS_INVALID_PARAMETER;
4587 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4588 return NT_STATUS_ACCESS_DENIED;
4591 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4592 if (id21->nt_password_set) {
4595 if ((id21->nt_owf_password.length != 16) ||
4596 (id21->nt_owf_password.size != 16)) {
4597 return NT_STATUS_INVALID_PARAMETER;
4600 if (!session_key->length) {
4601 return NT_STATUS_NO_USER_SESSION_KEY;
4604 in = data_blob_const(id21->nt_owf_password.array, 16);
4605 out = data_blob_talloc_zero(mem_ctx, 16);
4607 sess_crypt_blob(&out, &in, session_key, false);
4609 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4610 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4614 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4615 if (id21->lm_password_set) {
4618 if ((id21->lm_owf_password.length != 16) ||
4619 (id21->lm_owf_password.size != 16)) {
4620 return NT_STATUS_INVALID_PARAMETER;
4623 if (!session_key->length) {
4624 return NT_STATUS_NO_USER_SESSION_KEY;
4627 in = data_blob_const(id21->lm_owf_password.array, 16);
4628 out = data_blob_talloc_zero(mem_ctx, 16);
4630 sess_crypt_blob(&out, &in, session_key, false);
4632 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4633 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4637 /* we need to separately check for an account rename first */
4639 if (id21->account_name.string &&
4640 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4643 /* check to see if the new username already exists. Note: we can't
4644 reliably lock all backends, so there is potentially the
4645 possibility that a user can be created in between this check and
4646 the rename. The rename should fail, but may not get the
4647 exact same failure status code. I think this is small enough
4648 of a window for this type of operation and the results are
4649 simply that the rename fails with a slightly different status
4650 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4652 status = can_create(mem_ctx, id21->account_name.string);
4653 if (!NT_STATUS_IS_OK(status)) {
4657 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4659 if (!NT_STATUS_IS_OK(status)) {
4660 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4661 nt_errstr(status)));
4665 /* set the new username so that later
4666 functions can work on the new account */
4667 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4670 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4673 * The funny part about the previous two calls is
4674 * that pwd still has the password hashes from the
4675 * passdb entry. These have not been updated from
4676 * id21. I don't know if they need to be set. --jerry
4679 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4680 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4681 if ( !NT_STATUS_IS_OK(status) ) {
4686 /* Don't worry about writing out the user account since the
4687 primary group SID is generated solely from the user's Unix
4690 /* write the change out */
4691 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4695 return NT_STATUS_OK;
4698 /*******************************************************************
4700 ********************************************************************/
4702 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4703 struct samr_UserInfo23 *id23,
4706 char *plaintext_buf = NULL;
4712 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4713 return NT_STATUS_INVALID_PARAMETER;
4716 if (id23->info.fields_present == 0) {
4717 return NT_STATUS_INVALID_PARAMETER;
4720 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4721 return NT_STATUS_ACCESS_DENIED;
4724 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4725 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4727 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4728 pdb_get_username(pwd)));
4730 if (!decode_pw_buffer(mem_ctx,
4731 id23->password.data,
4735 return NT_STATUS_WRONG_PASSWORD;
4738 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4739 return NT_STATUS_ACCESS_DENIED;
4743 copy_id23_to_sam_passwd(pwd, id23);
4745 acct_ctrl = pdb_get_acct_ctrl(pwd);
4747 /* if it's a trust account, don't update /etc/passwd */
4748 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4749 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4750 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4751 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4752 } else if (plaintext_buf) {
4753 /* update the UNIX password */
4754 if (lp_unix_password_sync() ) {
4755 struct passwd *passwd;
4756 if (pdb_get_username(pwd) == NULL) {
4757 DEBUG(1, ("chgpasswd: User without name???\n"));
4758 return NT_STATUS_ACCESS_DENIED;
4761 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4762 if (passwd == NULL) {
4763 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4766 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4767 return NT_STATUS_ACCESS_DENIED;
4769 TALLOC_FREE(passwd);
4773 if (plaintext_buf) {
4774 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4777 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4778 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4783 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4787 return NT_STATUS_OK;
4790 /*******************************************************************
4792 ********************************************************************/
4794 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4797 char *plaintext_buf = NULL;
4800 DEBUG(5, ("Attempting administrator password change for user %s\n",
4801 pdb_get_username(pwd)));
4803 acct_ctrl = pdb_get_acct_ctrl(pwd);
4805 if (!decode_pw_buffer(talloc_tos(),
4813 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4817 /* if it's a trust account, don't update /etc/passwd */
4818 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4819 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4820 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4821 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4823 /* update the UNIX password */
4824 if (lp_unix_password_sync()) {
4825 struct passwd *passwd;
4827 if (pdb_get_username(pwd) == NULL) {
4828 DEBUG(1, ("chgpasswd: User without name???\n"));
4832 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4833 if (passwd == NULL) {
4834 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4837 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4840 TALLOC_FREE(passwd);
4844 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4846 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4851 /*******************************************************************
4853 ********************************************************************/
4855 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4856 struct samr_UserInfo24 *id24,
4862 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4863 return NT_STATUS_INVALID_PARAMETER;
4866 if (!set_user_info_pw(id24->password.data, pwd)) {
4867 return NT_STATUS_WRONG_PASSWORD;
4870 copy_id24_to_sam_passwd(pwd, id24);
4872 status = pdb_update_sam_account(pwd);
4873 if (!NT_STATUS_IS_OK(status)) {
4877 return NT_STATUS_OK;
4880 /*******************************************************************
4882 ********************************************************************/
4884 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4885 struct samr_UserInfo25 *id25,
4891 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4892 return NT_STATUS_INVALID_PARAMETER;
4895 if (id25->info.fields_present == 0) {
4896 return NT_STATUS_INVALID_PARAMETER;
4899 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4900 return NT_STATUS_ACCESS_DENIED;
4903 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4904 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4906 if (!set_user_info_pw(id25->password.data, pwd)) {
4907 return NT_STATUS_WRONG_PASSWORD;
4911 copy_id25_to_sam_passwd(pwd, id25);
4913 /* write the change out */
4914 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4919 * We need to "pdb_update_sam_account" before the unix primary group
4920 * is set, because the idealx scripts would also change the
4921 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4922 * the delete explicit / add explicit, which would then fail to find
4923 * the previous primaryGroupSid value.
4926 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4927 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4928 if ( !NT_STATUS_IS_OK(status) ) {
4933 return NT_STATUS_OK;
4936 /*******************************************************************
4938 ********************************************************************/
4940 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4941 struct samr_UserInfo26 *id26,
4947 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4948 return NT_STATUS_INVALID_PARAMETER;
4951 if (!set_user_info_pw(id26->password.data, pwd)) {
4952 return NT_STATUS_WRONG_PASSWORD;
4955 copy_id26_to_sam_passwd(pwd, id26);
4957 status = pdb_update_sam_account(pwd);
4958 if (!NT_STATUS_IS_OK(status)) {
4962 return NT_STATUS_OK;
4965 /*************************************************************
4966 **************************************************************/
4968 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4970 uint32_t acc_required = 0;
4972 /* USER_ALL_USERNAME */
4973 if (fields & SAMR_FIELD_ACCOUNT_NAME)
4974 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4975 /* USER_ALL_FULLNAME */
4976 if (fields & SAMR_FIELD_FULL_NAME)
4977 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4978 /* USER_ALL_PRIMARYGROUPID */
4979 if (fields & SAMR_FIELD_PRIMARY_GID)
4980 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4981 /* USER_ALL_HOMEDIRECTORY */
4982 if (fields & SAMR_FIELD_HOME_DIRECTORY)
4983 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4984 /* USER_ALL_HOMEDIRECTORYDRIVE */
4985 if (fields & SAMR_FIELD_HOME_DRIVE)
4986 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4987 /* USER_ALL_SCRIPTPATH */
4988 if (fields & SAMR_FIELD_LOGON_SCRIPT)
4989 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4990 /* USER_ALL_PROFILEPATH */
4991 if (fields & SAMR_FIELD_PROFILE_PATH)
4992 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4993 /* USER_ALL_ADMINCOMMENT */
4994 if (fields & SAMR_FIELD_COMMENT)
4995 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4996 /* USER_ALL_WORKSTATIONS */
4997 if (fields & SAMR_FIELD_WORKSTATIONS)
4998 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4999 /* USER_ALL_LOGONHOURS */
5000 if (fields & SAMR_FIELD_LOGON_HOURS)
5001 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5002 /* USER_ALL_ACCOUNTEXPIRES */
5003 if (fields & SAMR_FIELD_ACCT_EXPIRY)
5004 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5005 /* USER_ALL_USERACCOUNTCONTROL */
5006 if (fields & SAMR_FIELD_ACCT_FLAGS)
5007 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5008 /* USER_ALL_PARAMETERS */
5009 if (fields & SAMR_FIELD_PARAMETERS)
5010 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5011 /* USER_ALL_USERCOMMENT */
5012 if (fields & SAMR_FIELD_COMMENT)
5013 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5014 /* USER_ALL_COUNTRYCODE */
5015 if (fields & SAMR_FIELD_COUNTRY_CODE)
5016 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5017 /* USER_ALL_CODEPAGE */
5018 if (fields & SAMR_FIELD_CODE_PAGE)
5019 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5020 /* USER_ALL_NTPASSWORDPRESENT */
5021 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
5022 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5023 /* USER_ALL_LMPASSWORDPRESENT */
5024 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
5025 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5026 /* USER_ALL_PASSWORDEXPIRED */
5027 if (fields & SAMR_FIELD_EXPIRED_FLAG)
5028 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5030 return acc_required;
5033 /*******************************************************************
5035 ********************************************************************/
5037 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
5038 struct samr_SetUserInfo *r)
5040 struct samr_user_info *uinfo;
5042 struct samu *pwd = NULL;
5043 union samr_UserInfo *info = r->in.info;
5044 uint32_t acc_required = 0;
5045 uint32_t fields = 0;
5048 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
5050 /* This is tricky. A WinXP domain join sets
5051 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5052 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
5053 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5054 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
5055 we'll use the set from the WinXP join as the basis. */
5057 switch (r->in.level) {
5058 case 2: /* UserPreferencesInformation */
5059 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5060 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5062 case 4: /* UserLogonHoursInformation */
5063 case 6: /* UserNameInformation */
5064 case 7: /* UserAccountNameInformation */
5065 case 8: /* UserFullNameInformation */
5066 case 9: /* UserPrimaryGroupInformation */
5067 case 10: /* UserHomeInformation */
5068 case 11: /* UserScriptInformation */
5069 case 12: /* UserProfileInformation */
5070 case 13: /* UserAdminCommentInformation */
5071 case 14: /* UserWorkStationsInformation */
5072 case 16: /* UserControlInformation */
5073 case 17: /* UserExpiresInformation */
5074 case 20: /* UserParametersInformation */
5075 /* USER_WRITE_ACCOUNT */
5076 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5078 case 18: /* UserInternal1Information */
5079 /* FIXME: gd, this is a guess */
5080 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5082 case 21: /* UserAllInformation */
5083 fields = info->info21.fields_present;
5084 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5086 case 23: /* UserInternal4Information */
5087 fields = info->info23.info.fields_present;
5088 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5090 case 25: /* UserInternal4InformationNew */
5091 fields = info->info25.info.fields_present;
5092 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5094 case 24: /* UserInternal5Information */
5095 case 26: /* UserInternal5InformationNew */
5096 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5099 return NT_STATUS_INVALID_INFO_CLASS;
5102 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5103 struct samr_user_info, &status);
5104 if (!NT_STATUS_IS_OK(status)) {
5108 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5109 sid_string_dbg(&uinfo->sid), r->in.level));
5112 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5113 return NT_STATUS_INVALID_INFO_CLASS;
5116 if (!(pwd = samu_new(NULL))) {
5117 return NT_STATUS_NO_MEMORY;
5121 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5126 return NT_STATUS_NO_SUCH_USER;
5129 /* ================ BEGIN Privilege BLOCK ================ */
5133 /* ok! user info levels (lots: see MSDEV help), off we go... */
5135 switch (r->in.level) {
5138 status = set_user_info_2(p->mem_ctx,
5143 status = set_user_info_4(p->mem_ctx,
5148 status = set_user_info_6(p->mem_ctx,
5153 status = set_user_info_7(p->mem_ctx,
5158 status = set_user_info_8(p->mem_ctx,
5163 status = set_user_info_10(p->mem_ctx,
5164 &info->info10, pwd);
5168 status = set_user_info_11(p->mem_ctx,
5169 &info->info11, pwd);
5173 status = set_user_info_12(p->mem_ctx,
5174 &info->info12, pwd);
5178 status = set_user_info_13(p->mem_ctx,
5179 &info->info13, pwd);
5183 status = set_user_info_14(p->mem_ctx,
5184 &info->info14, pwd);
5188 status = set_user_info_16(p->mem_ctx,
5189 &info->info16, pwd);
5193 status = set_user_info_17(p->mem_ctx,
5194 &info->info17, pwd);
5198 /* Used by AS/U JRA. */
5199 status = set_user_info_18(&info->info18,
5201 &p->server_info->user_session_key,
5206 status = set_user_info_20(p->mem_ctx,
5207 &info->info20, pwd);
5211 status = set_user_info_21(&info->info21,
5213 &p->server_info->user_session_key,
5218 if (!p->server_info->user_session_key.length) {
5219 status = NT_STATUS_NO_USER_SESSION_KEY;
5221 arcfour_crypt_blob(info->info23.password.data, 516,
5222 &p->server_info->user_session_key);
5224 dump_data(100, info->info23.password.data, 516);
5226 status = set_user_info_23(p->mem_ctx,
5227 &info->info23, pwd);
5231 if (!p->server_info->user_session_key.length) {
5232 status = NT_STATUS_NO_USER_SESSION_KEY;
5234 arcfour_crypt_blob(info->info24.password.data,
5236 &p->server_info->user_session_key);
5238 dump_data(100, info->info24.password.data, 516);
5240 status = set_user_info_24(p->mem_ctx,
5241 &info->info24, pwd);
5245 if (!p->server_info->user_session_key.length) {
5246 status = NT_STATUS_NO_USER_SESSION_KEY;
5248 encode_or_decode_arc4_passwd_buffer(
5249 info->info25.password.data,
5250 &p->server_info->user_session_key);
5252 dump_data(100, info->info25.password.data, 532);
5254 status = set_user_info_25(p->mem_ctx,
5255 &info->info25, pwd);
5259 if (!p->server_info->user_session_key.length) {
5260 status = NT_STATUS_NO_USER_SESSION_KEY;
5262 encode_or_decode_arc4_passwd_buffer(
5263 info->info26.password.data,
5264 &p->server_info->user_session_key);
5266 dump_data(100, info->info26.password.data, 516);
5268 status = set_user_info_26(p->mem_ctx,
5269 &info->info26, pwd);
5273 status = NT_STATUS_INVALID_INFO_CLASS;
5280 /* ================ END Privilege BLOCK ================ */
5282 if (NT_STATUS_IS_OK(status)) {
5283 force_flush_samr_cache(&uinfo->sid);
5289 /*******************************************************************
5291 ********************************************************************/
5293 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
5294 struct samr_SetUserInfo2 *r)
5296 struct samr_SetUserInfo q;
5298 q.in.user_handle = r->in.user_handle;
5299 q.in.level = r->in.level;
5300 q.in.info = r->in.info;
5302 return _samr_SetUserInfo(p, &q);
5305 /*********************************************************************
5306 _samr_GetAliasMembership
5307 *********************************************************************/
5309 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
5310 struct samr_GetAliasMembership *r)
5312 size_t num_alias_rids;
5314 struct samr_domain_info *dinfo;
5321 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5323 dinfo = policy_handle_find(p, r->in.domain_handle,
5324 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5325 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5326 struct samr_domain_info, &status);
5327 if (!NT_STATUS_IS_OK(status)) {
5331 if (!sid_check_is_domain(&dinfo->sid) &&
5332 !sid_check_is_builtin(&dinfo->sid))
5333 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5335 if (r->in.sids->num_sids) {
5336 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
5338 if (members == NULL)
5339 return NT_STATUS_NO_MEMORY;
5344 for (i=0; i<r->in.sids->num_sids; i++)
5345 sid_copy(&members[i], r->in.sids->sids[i].sid);
5351 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5352 r->in.sids->num_sids,
5353 &alias_rids, &num_alias_rids);
5356 if (!NT_STATUS_IS_OK(status)) {
5360 r->out.rids->count = num_alias_rids;
5361 r->out.rids->ids = alias_rids;
5363 return NT_STATUS_OK;
5366 /*********************************************************************
5367 _samr_GetMembersInAlias
5368 *********************************************************************/
5370 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5371 struct samr_GetMembersInAlias *r)
5373 struct samr_alias_info *ainfo;
5376 size_t num_sids = 0;
5377 struct lsa_SidPtr *sids = NULL;
5378 DOM_SID *pdb_sids = NULL;
5380 ainfo = policy_handle_find(p, r->in.alias_handle,
5381 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5382 struct samr_alias_info, &status);
5383 if (!NT_STATUS_IS_OK(status)) {
5387 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5390 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5394 if (!NT_STATUS_IS_OK(status)) {
5399 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5401 TALLOC_FREE(pdb_sids);
5402 return NT_STATUS_NO_MEMORY;
5406 for (i = 0; i < num_sids; i++) {
5407 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5409 TALLOC_FREE(pdb_sids);
5410 return NT_STATUS_NO_MEMORY;
5414 r->out.sids->num_sids = num_sids;
5415 r->out.sids->sids = sids;
5417 TALLOC_FREE(pdb_sids);
5419 return NT_STATUS_OK;
5422 /*********************************************************************
5423 _samr_QueryGroupMember
5424 *********************************************************************/
5426 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5427 struct samr_QueryGroupMember *r)
5429 struct samr_group_info *ginfo;
5430 size_t i, num_members;
5436 struct samr_RidTypeArray *rids = NULL;
5438 ginfo = policy_handle_find(p, r->in.group_handle,
5439 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5440 struct samr_group_info, &status);
5441 if (!NT_STATUS_IS_OK(status)) {
5445 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5447 return NT_STATUS_NO_MEMORY;
5450 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5452 if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5453 DEBUG(3, ("sid %s is not in our domain\n",
5454 sid_string_dbg(&ginfo->sid)));
5455 return NT_STATUS_NO_SUCH_GROUP;
5458 DEBUG(10, ("lookup on Domain SID\n"));
5461 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5462 &rid, &num_members);
5465 if (!NT_STATUS_IS_OK(status))
5469 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5471 return NT_STATUS_NO_MEMORY;
5477 for (i=0; i<num_members; i++)
5478 attr[i] = SID_NAME_USER;
5480 rids->count = num_members;
5484 *r->out.rids = rids;
5486 return NT_STATUS_OK;
5489 /*********************************************************************
5490 _samr_AddAliasMember
5491 *********************************************************************/
5493 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5494 struct samr_AddAliasMember *r)
5496 struct samr_alias_info *ainfo;
5499 ainfo = policy_handle_find(p, r->in.alias_handle,
5500 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5501 struct samr_alias_info, &status);
5502 if (!NT_STATUS_IS_OK(status)) {
5506 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5508 /******** BEGIN SeAddUsers BLOCK *********/
5511 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5514 /******** END SeAddUsers BLOCK *********/
5516 if (NT_STATUS_IS_OK(status)) {
5517 force_flush_samr_cache(&ainfo->sid);
5523 /*********************************************************************
5524 _samr_DeleteAliasMember
5525 *********************************************************************/
5527 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5528 struct samr_DeleteAliasMember *r)
5530 struct samr_alias_info *ainfo;
5533 ainfo = policy_handle_find(p, r->in.alias_handle,
5534 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5535 struct samr_alias_info, &status);
5536 if (!NT_STATUS_IS_OK(status)) {
5540 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5541 sid_string_dbg(&ainfo->sid)));
5543 /******** BEGIN SeAddUsers BLOCK *********/
5546 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5549 /******** END SeAddUsers BLOCK *********/
5551 if (NT_STATUS_IS_OK(status)) {
5552 force_flush_samr_cache(&ainfo->sid);
5558 /*********************************************************************
5559 _samr_AddGroupMember
5560 *********************************************************************/
5562 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5563 struct samr_AddGroupMember *r)
5565 struct samr_group_info *ginfo;
5569 ginfo = policy_handle_find(p, r->in.group_handle,
5570 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5571 struct samr_group_info, &status);
5572 if (!NT_STATUS_IS_OK(status)) {
5576 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5578 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5580 return NT_STATUS_INVALID_HANDLE;
5583 /******** BEGIN SeAddUsers BLOCK *********/
5586 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5589 /******** END SeAddUsers BLOCK *********/
5591 force_flush_samr_cache(&ginfo->sid);
5596 /*********************************************************************
5597 _samr_DeleteGroupMember
5598 *********************************************************************/
5600 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5601 struct samr_DeleteGroupMember *r)
5604 struct samr_group_info *ginfo;
5609 * delete the group member named r->in.rid
5610 * who is a member of the sid associated with the handle
5611 * the rid is a user's rid as the group is a domain group.
5614 ginfo = policy_handle_find(p, r->in.group_handle,
5615 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5616 struct samr_group_info, &status);
5617 if (!NT_STATUS_IS_OK(status)) {
5621 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5623 return NT_STATUS_INVALID_HANDLE;
5626 /******** BEGIN SeAddUsers BLOCK *********/
5629 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5632 /******** END SeAddUsers BLOCK *********/
5634 force_flush_samr_cache(&ginfo->sid);
5639 /*********************************************************************
5641 *********************************************************************/
5643 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5644 struct samr_DeleteUser *r)
5646 struct samr_user_info *uinfo;
5648 struct samu *sam_pass=NULL;
5651 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5653 uinfo = policy_handle_find(p, r->in.user_handle,
5654 STD_RIGHT_DELETE_ACCESS, NULL,
5655 struct samr_user_info, &status);
5656 if (!NT_STATUS_IS_OK(status)) {
5660 if (!sid_check_is_in_our_domain(&uinfo->sid))
5661 return NT_STATUS_CANNOT_DELETE;
5663 /* check if the user exists before trying to delete */
5664 if ( !(sam_pass = samu_new( NULL )) ) {
5665 return NT_STATUS_NO_MEMORY;
5669 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5673 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5674 sid_string_dbg(&uinfo->sid)));
5675 TALLOC_FREE(sam_pass);
5676 return NT_STATUS_NO_SUCH_USER;
5679 /******** BEGIN SeAddUsers BLOCK *********/
5682 status = pdb_delete_user(p->mem_ctx, sam_pass);
5685 /******** END SeAddUsers BLOCK *********/
5687 if ( !NT_STATUS_IS_OK(status) ) {
5688 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5689 "user %s: %s.\n", pdb_get_username(sam_pass),
5690 nt_errstr(status)));
5691 TALLOC_FREE(sam_pass);
5696 TALLOC_FREE(sam_pass);
5698 force_flush_samr_cache(&uinfo->sid);
5700 if (!close_policy_hnd(p, r->in.user_handle))
5701 return NT_STATUS_OBJECT_NAME_INVALID;
5703 ZERO_STRUCTP(r->out.user_handle);
5705 return NT_STATUS_OK;
5708 /*********************************************************************
5709 _samr_DeleteDomainGroup
5710 *********************************************************************/
5712 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5713 struct samr_DeleteDomainGroup *r)
5715 struct samr_group_info *ginfo;
5719 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5721 ginfo = policy_handle_find(p, r->in.group_handle,
5722 STD_RIGHT_DELETE_ACCESS, NULL,
5723 struct samr_group_info, &status);
5724 if (!NT_STATUS_IS_OK(status)) {
5728 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5730 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5732 return NT_STATUS_NO_SUCH_GROUP;
5735 /******** BEGIN SeAddUsers BLOCK *********/
5738 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5741 /******** END SeAddUsers BLOCK *********/
5743 if ( !NT_STATUS_IS_OK(status) ) {
5744 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5745 "entry for group %s: %s\n",
5746 sid_string_dbg(&ginfo->sid),
5747 nt_errstr(status)));
5751 force_flush_samr_cache(&ginfo->sid);
5753 if (!close_policy_hnd(p, r->in.group_handle))
5754 return NT_STATUS_OBJECT_NAME_INVALID;
5756 return NT_STATUS_OK;
5759 /*********************************************************************
5760 _samr_DeleteDomAlias
5761 *********************************************************************/
5763 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5764 struct samr_DeleteDomAlias *r)
5766 struct samr_alias_info *ainfo;
5769 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5771 ainfo = policy_handle_find(p, r->in.alias_handle,
5772 STD_RIGHT_DELETE_ACCESS, NULL,
5773 struct samr_alias_info, &status);
5774 if (!NT_STATUS_IS_OK(status)) {
5778 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5780 /* Don't let Windows delete builtin groups */
5782 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5783 return NT_STATUS_SPECIAL_ACCOUNT;
5786 if (!sid_check_is_in_our_domain(&ainfo->sid))
5787 return NT_STATUS_NO_SUCH_ALIAS;
5789 DEBUG(10, ("lookup on Local SID\n"));
5791 /******** BEGIN SeAddUsers BLOCK *********/
5794 /* Have passdb delete the alias */
5795 status = pdb_delete_alias(&ainfo->sid);
5798 /******** END SeAddUsers BLOCK *********/
5800 if ( !NT_STATUS_IS_OK(status))
5803 force_flush_samr_cache(&ainfo->sid);
5805 if (!close_policy_hnd(p, r->in.alias_handle))
5806 return NT_STATUS_OBJECT_NAME_INVALID;
5808 return NT_STATUS_OK;
5811 /*********************************************************************
5812 _samr_CreateDomainGroup
5813 *********************************************************************/
5815 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5816 struct samr_CreateDomainGroup *r)
5821 struct samr_domain_info *dinfo;
5822 struct samr_group_info *ginfo;
5824 dinfo = policy_handle_find(p, r->in.domain_handle,
5825 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5826 struct samr_domain_info, &status);
5827 if (!NT_STATUS_IS_OK(status)) {
5831 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5832 return NT_STATUS_ACCESS_DENIED;
5834 name = r->in.name->string;
5836 return NT_STATUS_NO_MEMORY;
5839 status = can_create(p->mem_ctx, name);
5840 if (!NT_STATUS_IS_OK(status)) {
5844 /******** BEGIN SeAddUsers BLOCK *********/
5847 /* check that we successfully create the UNIX group */
5848 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5851 /******** END SeAddUsers BLOCK *********/
5853 /* check if we should bail out here */
5855 if ( !NT_STATUS_IS_OK(status) )
5858 ginfo = policy_handle_create(p, r->out.group_handle,
5859 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5860 struct samr_group_info, &status);
5861 if (!NT_STATUS_IS_OK(status)) {
5864 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5866 force_flush_samr_cache(&dinfo->sid);
5868 return NT_STATUS_OK;
5871 /*********************************************************************
5872 _samr_CreateDomAlias
5873 *********************************************************************/
5875 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5876 struct samr_CreateDomAlias *r)
5879 const char *name = NULL;
5880 struct samr_domain_info *dinfo;
5881 struct samr_alias_info *ainfo;
5885 dinfo = policy_handle_find(p, r->in.domain_handle,
5886 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5887 struct samr_domain_info, &result);
5888 if (!NT_STATUS_IS_OK(result)) {
5892 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5893 return NT_STATUS_ACCESS_DENIED;
5895 name = r->in.alias_name->string;
5897 result = can_create(p->mem_ctx, name);
5898 if (!NT_STATUS_IS_OK(result)) {
5902 /******** BEGIN SeAddUsers BLOCK *********/
5905 /* Have passdb create the alias */
5906 result = pdb_create_alias(name, r->out.rid);
5909 /******** END SeAddUsers BLOCK *********/
5911 if (!NT_STATUS_IS_OK(result)) {
5912 DEBUG(10, ("pdb_create_alias failed: %s\n",
5913 nt_errstr(result)));
5917 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5919 if (!sid_to_gid(&info_sid, &gid)) {
5920 DEBUG(10, ("Could not find alias just created\n"));
5921 return NT_STATUS_ACCESS_DENIED;
5924 /* check if the group has been successfully created */
5925 if ( getgrgid(gid) == NULL ) {
5926 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5927 (unsigned int)gid));
5928 return NT_STATUS_ACCESS_DENIED;
5931 ainfo = policy_handle_create(p, r->out.alias_handle,
5932 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5933 struct samr_alias_info, &result);
5934 if (!NT_STATUS_IS_OK(result)) {
5937 ainfo->sid = info_sid;
5939 force_flush_samr_cache(&info_sid);
5941 return NT_STATUS_OK;
5944 /*********************************************************************
5945 _samr_QueryGroupInfo
5946 *********************************************************************/
5948 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5949 struct samr_QueryGroupInfo *r)
5951 struct samr_group_info *ginfo;
5954 union samr_GroupInfo *info = NULL;
5956 uint32_t attributes = SE_GROUP_MANDATORY |
5957 SE_GROUP_ENABLED_BY_DEFAULT |
5959 const char *group_name = NULL;
5960 const char *group_description = NULL;
5962 ginfo = policy_handle_find(p, r->in.group_handle,
5963 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5964 struct samr_group_info, &status);
5965 if (!NT_STATUS_IS_OK(status)) {
5970 ret = get_domain_group_from_sid(ginfo->sid, &map);
5973 return NT_STATUS_INVALID_HANDLE;
5975 /* FIXME: map contains fstrings */
5976 group_name = talloc_strdup(r, map.nt_name);
5977 group_description = talloc_strdup(r, map.comment);
5979 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5981 return NT_STATUS_NO_MEMORY;
5984 switch (r->in.level) {
5990 status = pdb_enum_group_members(
5991 p->mem_ctx, &ginfo->sid, &members,
5995 if (!NT_STATUS_IS_OK(status)) {
5999 info->all.name.string = group_name;
6000 info->all.attributes = attributes;
6001 info->all.num_members = num_members;
6002 info->all.description.string = group_description;
6006 info->name.string = group_name;
6009 info->attributes.attributes = attributes;
6012 info->description.string = group_description;
6022 status = pdb_enum_group_members(
6023 p->mem_ctx, &ginfo->sid, &members,
6027 if (!NT_STATUS_IS_OK(status)) {
6031 info->all2.name.string = group_name;
6032 info->all2.attributes = attributes;
6033 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
6034 info->all2.description.string = group_description;
6039 return NT_STATUS_INVALID_INFO_CLASS;
6042 *r->out.info = info;
6044 return NT_STATUS_OK;
6047 /*********************************************************************
6049 *********************************************************************/
6051 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
6052 struct samr_SetGroupInfo *r)
6054 struct samr_group_info *ginfo;
6059 ginfo = policy_handle_find(p, r->in.group_handle,
6060 SAMR_GROUP_ACCESS_SET_INFO, NULL,
6061 struct samr_group_info, &status);
6062 if (!NT_STATUS_IS_OK(status)) {
6067 ret = get_domain_group_from_sid(ginfo->sid, &map);
6070 return NT_STATUS_NO_SUCH_GROUP;
6072 switch (r->in.level) {
6074 fstrcpy(map.nt_name, r->in.info->name.string);
6079 fstrcpy(map.comment, r->in.info->description.string);
6082 return NT_STATUS_INVALID_INFO_CLASS;
6085 /******** BEGIN SeAddUsers BLOCK *********/
6088 status = pdb_update_group_mapping_entry(&map);
6091 /******** End SeAddUsers BLOCK *********/
6093 if (NT_STATUS_IS_OK(status)) {
6094 force_flush_samr_cache(&ginfo->sid);
6100 /*********************************************************************
6102 *********************************************************************/
6104 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
6105 struct samr_SetAliasInfo *r)
6107 struct samr_alias_info *ainfo;
6108 struct acct_info info;
6111 ainfo = policy_handle_find(p, r->in.alias_handle,
6112 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6113 struct samr_alias_info, &status);
6114 if (!NT_STATUS_IS_OK(status)) {
6118 /* get the current group information */
6121 status = pdb_get_aliasinfo( &ainfo->sid, &info );
6124 if ( !NT_STATUS_IS_OK(status))
6127 switch (r->in.level) {
6132 /* We currently do not support renaming groups in the
6133 the BUILTIN domain. Refer to util_builtin.c to understand
6134 why. The eventually needs to be fixed to be like Windows
6135 where you can rename builtin groups, just not delete them */
6137 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6138 return NT_STATUS_SPECIAL_ACCOUNT;
6141 /* There has to be a valid name (and it has to be different) */
6143 if ( !r->in.info->name.string )
6144 return NT_STATUS_INVALID_PARAMETER;
6146 /* If the name is the same just reply "ok". Yes this
6147 doesn't allow you to change the case of a group name. */
6149 if ( strequal( r->in.info->name.string, info.acct_name ) )
6150 return NT_STATUS_OK;
6152 fstrcpy( info.acct_name, r->in.info->name.string);
6154 /* make sure the name doesn't already exist as a user
6157 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6158 status = can_create( p->mem_ctx, group_name );
6159 if ( !NT_STATUS_IS_OK( status ) )
6163 case ALIASINFODESCRIPTION:
6164 if (r->in.info->description.string) {
6165 fstrcpy(info.acct_desc,
6166 r->in.info->description.string);
6168 fstrcpy( info.acct_desc, "" );
6172 return NT_STATUS_INVALID_INFO_CLASS;
6175 /******** BEGIN SeAddUsers BLOCK *********/
6178 status = pdb_set_aliasinfo( &ainfo->sid, &info );
6181 /******** End SeAddUsers BLOCK *********/
6183 if (NT_STATUS_IS_OK(status))
6184 force_flush_samr_cache(&ainfo->sid);
6189 /****************************************************************
6191 ****************************************************************/
6193 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
6194 struct samr_GetDomPwInfo *r)
6196 uint32_t min_password_length = 0;
6197 uint32_t password_properties = 0;
6199 /* Perform access check. Since this rpc does not require a
6200 policy handle it will not be caught by the access checks on
6201 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6203 if (!pipe_access_check(p)) {
6204 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6205 return NT_STATUS_ACCESS_DENIED;
6209 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6210 &min_password_length);
6211 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6212 &password_properties);
6215 if (lp_check_password_script() && *lp_check_password_script()) {
6216 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6219 r->out.info->min_password_length = min_password_length;
6220 r->out.info->password_properties = password_properties;
6222 return NT_STATUS_OK;
6225 /*********************************************************************
6227 *********************************************************************/
6229 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6230 struct samr_OpenGroup *r)
6235 struct samr_domain_info *dinfo;
6236 struct samr_group_info *ginfo;
6237 SEC_DESC *psd = NULL;
6239 uint32 des_access = r->in.access_mask;
6245 dinfo = policy_handle_find(p, r->in.domain_handle,
6246 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6247 struct samr_domain_info, &status);
6248 if (!NT_STATUS_IS_OK(status)) {
6252 /*check if access can be granted as requested by client. */
6253 map_max_allowed_access(p->server_info->ptok,
6254 &p->server_info->utok,
6257 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6258 se_map_generic(&des_access,&grp_generic_mapping);
6260 se_priv_copy( &se_rights, &se_add_users );
6262 status = access_check_object(psd, p->server_info->ptok,
6263 &se_rights, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6264 des_access, &acc_granted, "_samr_OpenGroup");
6266 if ( !NT_STATUS_IS_OK(status) )
6269 /* this should not be hard-coded like this */
6271 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
6272 return NT_STATUS_ACCESS_DENIED;
6274 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6276 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6277 sid_string_dbg(&info_sid)));
6279 /* check if that group really exists */
6281 ret = get_domain_group_from_sid(info_sid, &map);
6284 return NT_STATUS_NO_SUCH_GROUP;
6286 ginfo = policy_handle_create(p, r->out.group_handle,
6288 struct samr_group_info, &status);
6289 if (!NT_STATUS_IS_OK(status)) {
6292 ginfo->sid = info_sid;
6294 return NT_STATUS_OK;
6297 /*********************************************************************
6298 _samr_RemoveMemberFromForeignDomain
6299 *********************************************************************/
6301 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6302 struct samr_RemoveMemberFromForeignDomain *r)
6304 struct samr_domain_info *dinfo;
6307 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6308 sid_string_dbg(r->in.sid)));
6310 /* Find the policy handle. Open a policy on it. */
6312 dinfo = policy_handle_find(p, r->in.domain_handle,
6313 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6314 struct samr_domain_info, &result);
6315 if (!NT_STATUS_IS_OK(result)) {
6319 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6320 sid_string_dbg(&dinfo->sid)));
6322 /* we can only delete a user from a group since we don't have
6323 nested groups anyways. So in the latter case, just say OK */
6325 /* TODO: The above comment nowadays is bogus. Since we have nested
6326 * groups now, and aliases members are never reported out of the unix
6327 * group membership, the "just say OK" makes this call a no-op. For
6328 * us. This needs fixing however. */
6330 /* I've only ever seen this in the wild when deleting a user from
6331 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6332 * is the user about to be deleted. I very much suspect this is the
6333 * only application of this call. To verify this, let people report
6336 if (!sid_check_is_builtin(&dinfo->sid)) {
6337 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6338 "global_sam_sid() = %s\n",
6339 sid_string_dbg(&dinfo->sid),
6340 sid_string_dbg(get_global_sam_sid())));
6341 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6342 return NT_STATUS_OK;
6345 force_flush_samr_cache(&dinfo->sid);
6347 result = NT_STATUS_OK;
6352 /*******************************************************************
6353 _samr_QueryDomainInfo2
6354 ********************************************************************/
6356 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6357 struct samr_QueryDomainInfo2 *r)
6359 struct samr_QueryDomainInfo q;
6361 q.in.domain_handle = r->in.domain_handle;
6362 q.in.level = r->in.level;
6364 q.out.info = r->out.info;
6366 return _samr_QueryDomainInfo(p, &q);
6369 /*******************************************************************
6370 ********************************************************************/
6372 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6373 struct samr_DomInfo1 *r)
6375 time_t u_expire, u_min_age;
6377 u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6378 u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6380 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6381 (uint32_t)r->min_password_length);
6382 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6383 (uint32_t)r->password_history_length);
6384 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6385 (uint32_t)r->password_properties);
6386 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6387 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6389 return NT_STATUS_OK;
6392 /*******************************************************************
6393 ********************************************************************/
6395 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6396 struct samr_DomInfo3 *r)
6400 u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6402 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6404 return NT_STATUS_OK;
6407 /*******************************************************************
6408 ********************************************************************/
6410 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6411 struct samr_DomInfo12 *r)
6413 time_t u_lock_duration, u_reset_time;
6415 u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6416 if (u_lock_duration != -1) {
6417 u_lock_duration /= 60;
6420 u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6422 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6423 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6424 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6425 (uint32_t)r->lockout_threshold);
6427 return NT_STATUS_OK;
6430 /*******************************************************************
6432 ********************************************************************/
6434 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6435 struct samr_SetDomainInfo *r)
6437 struct samr_domain_info *dinfo;
6439 uint32_t acc_required = 0;
6441 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6443 switch (r->in.level) {
6444 case 1: /* DomainPasswordInformation */
6445 case 12: /* DomainLockoutInformation */
6446 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6447 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6449 case 3: /* DomainLogoffInformation */
6450 case 4: /* DomainOemInformation */
6451 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6452 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6454 case 6: /* DomainReplicationInformation */
6455 case 9: /* DomainStateInformation */
6456 case 7: /* DomainServerRoleInformation */
6457 /* DOMAIN_ADMINISTER_SERVER */
6458 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6461 return NT_STATUS_INVALID_INFO_CLASS;
6464 dinfo = policy_handle_find(p, r->in.domain_handle,
6466 struct samr_domain_info, &status);
6467 if (!NT_STATUS_IS_OK(status)) {
6471 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6473 switch (r->in.level) {
6475 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6478 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6489 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6492 return NT_STATUS_INVALID_INFO_CLASS;
6495 if (!NT_STATUS_IS_OK(status)) {
6499 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6501 return NT_STATUS_OK;
6504 /****************************************************************
6505 _samr_GetDisplayEnumerationIndex
6506 ****************************************************************/
6508 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6509 struct samr_GetDisplayEnumerationIndex *r)
6511 struct samr_domain_info *dinfo;
6512 uint32_t max_entries = (uint32_t) -1;
6513 uint32_t enum_context = 0;
6515 uint32_t num_account = 0;
6516 struct samr_displayentry *entries = NULL;
6519 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6521 dinfo = policy_handle_find(p, r->in.domain_handle,
6522 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6523 struct samr_domain_info, &status);
6524 if (!NT_STATUS_IS_OK(status)) {
6528 if ((r->in.level < 1) || (r->in.level > 3)) {
6529 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6530 "Unknown info level (%u)\n",
6532 return NT_STATUS_INVALID_INFO_CLASS;
6537 /* The following done as ROOT. Don't return without unbecome_root(). */
6539 switch (r->in.level) {
6541 if (dinfo->disp_info->users == NULL) {
6542 dinfo->disp_info->users = pdb_search_users(
6543 dinfo->disp_info, ACB_NORMAL);
6544 if (dinfo->disp_info->users == NULL) {
6546 return NT_STATUS_ACCESS_DENIED;
6548 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6549 "starting user enumeration at index %u\n",
6550 (unsigned int)enum_context));
6552 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6553 "using cached user enumeration at index %u\n",
6554 (unsigned int)enum_context));
6556 num_account = pdb_search_entries(dinfo->disp_info->users,
6557 enum_context, max_entries,
6561 if (dinfo->disp_info->machines == NULL) {
6562 dinfo->disp_info->machines = pdb_search_users(
6563 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6564 if (dinfo->disp_info->machines == NULL) {
6566 return NT_STATUS_ACCESS_DENIED;
6568 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6569 "starting machine enumeration at index %u\n",
6570 (unsigned int)enum_context));
6572 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6573 "using cached machine enumeration at index %u\n",
6574 (unsigned int)enum_context));
6576 num_account = pdb_search_entries(dinfo->disp_info->machines,
6577 enum_context, max_entries,
6581 if (dinfo->disp_info->groups == NULL) {
6582 dinfo->disp_info->groups = pdb_search_groups(
6584 if (dinfo->disp_info->groups == NULL) {
6586 return NT_STATUS_ACCESS_DENIED;
6588 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6589 "starting group enumeration at index %u\n",
6590 (unsigned int)enum_context));
6592 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6593 "using cached group enumeration at index %u\n",
6594 (unsigned int)enum_context));
6596 num_account = pdb_search_entries(dinfo->disp_info->groups,
6597 enum_context, max_entries,
6602 smb_panic("info class changed");
6608 /* Ensure we cache this enumeration. */
6609 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6611 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6612 r->in.name->string));
6614 for (i=0; i<num_account; i++) {
6615 if (strequal(entries[i].account_name, r->in.name->string)) {
6616 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6617 "found %s at idx %d\n",
6618 r->in.name->string, i));
6620 return NT_STATUS_OK;
6624 /* assuming account_name lives at the very end */
6625 *r->out.idx = num_account;
6627 return NT_STATUS_NO_MORE_ENTRIES;
6630 /****************************************************************
6631 _samr_GetDisplayEnumerationIndex2
6632 ****************************************************************/
6634 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6635 struct samr_GetDisplayEnumerationIndex2 *r)
6637 struct samr_GetDisplayEnumerationIndex q;
6639 q.in.domain_handle = r->in.domain_handle;
6640 q.in.level = r->in.level;
6641 q.in.name = r->in.name;
6643 q.out.idx = r->out.idx;
6645 return _samr_GetDisplayEnumerationIndex(p, &q);
6648 /****************************************************************
6650 ****************************************************************/
6652 NTSTATUS _samr_RidToSid(pipes_struct *p,
6653 struct samr_RidToSid *r)
6655 struct samr_domain_info *dinfo;
6659 dinfo = policy_handle_find(p, r->in.domain_handle,
6661 struct samr_domain_info, &status);
6662 if (!NT_STATUS_IS_OK(status)) {
6666 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6667 return NT_STATUS_NO_MEMORY;
6670 *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
6672 return NT_STATUS_NO_MEMORY;
6675 return NT_STATUS_OK;
6678 /****************************************************************
6679 ****************************************************************/
6681 NTSTATUS _samr_Shutdown(pipes_struct *p,
6682 struct samr_Shutdown *r)
6684 p->rng_fault_state = true;
6685 return NT_STATUS_NOT_IMPLEMENTED;
6688 /****************************************************************
6689 ****************************************************************/
6691 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6692 struct samr_SetMemberAttributesOfGroup *r)
6694 p->rng_fault_state = true;
6695 return NT_STATUS_NOT_IMPLEMENTED;
6698 /****************************************************************
6699 ****************************************************************/
6701 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6702 struct samr_TestPrivateFunctionsDomain *r)
6704 return NT_STATUS_NOT_IMPLEMENTED;
6707 /****************************************************************
6708 ****************************************************************/
6710 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6711 struct samr_TestPrivateFunctionsUser *r)
6713 return NT_STATUS_NOT_IMPLEMENTED;
6716 /****************************************************************
6717 ****************************************************************/
6719 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6720 struct samr_AddMultipleMembersToAlias *r)
6722 p->rng_fault_state = true;
6723 return NT_STATUS_NOT_IMPLEMENTED;
6726 /****************************************************************
6727 ****************************************************************/
6729 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6730 struct samr_RemoveMultipleMembersFromAlias *r)
6732 p->rng_fault_state = true;
6733 return NT_STATUS_NOT_IMPLEMENTED;
6736 /****************************************************************
6737 ****************************************************************/
6739 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6740 struct samr_SetBootKeyInformation *r)
6742 p->rng_fault_state = true;
6743 return NT_STATUS_NOT_IMPLEMENTED;
6746 /****************************************************************
6747 ****************************************************************/
6749 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6750 struct samr_GetBootKeyInformation *r)
6752 p->rng_fault_state = true;
6753 return NT_STATUS_NOT_IMPLEMENTED;
6756 /****************************************************************
6757 ****************************************************************/
6759 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6760 struct samr_SetDsrmPassword *r)
6762 p->rng_fault_state = true;
6763 return NT_STATUS_NOT_IMPLEMENTED;
6766 /****************************************************************
6767 ****************************************************************/
6769 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6770 struct samr_ValidatePassword *r)
6772 p->rng_fault_state = true;
6773 return NT_STATUS_NOT_IMPLEMENTED;