s3: Rename new parameter "ldap ref follow" to "ldap follow referral".
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_samr_nt.c
blob9af141b6f87f9624e13d64f4a4c58a9e0f811602
1 /*
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.
34 #include "includes.h"
35 #include "smbd/globals.h"
36 #include "../libcli/auth/libcli_auth.h"
38 #undef DBGC_CLASS
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 {
54 uint8_t dummy;
57 struct samr_domain_info {
58 struct dom_sid sid;
59 struct disp_info *disp_info;
62 struct samr_user_info {
63 struct dom_sid sid;
66 struct samr_group_info {
67 struct dom_sid sid;
70 struct samr_alias_info {
71 struct dom_sid sid;
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
85 * handler. */
86 } DISP_INFO;
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 */
128 size_t i = 0;
130 SEC_ACL *psa = NULL;
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 */
146 if ( IS_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 */
155 if ( sid ) {
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;
169 return NT_STATUS_OK;
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,
180 const char *debug )
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
187 users and groups) */
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",
196 rights_mask));
200 /* check the security descriptor first */
202 status = se_access_check(psd, token, des_access, acc_granted);
203 if (NT_STATUS_IS_OK(status)) {
204 goto done;
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;
217 goto done;
221 done:
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));
231 return status;
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)) {
244 return;
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;
254 return;
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;
262 return;
265 /* Full access for DOMAIN\Domain Admins. */
266 if ( IS_DC ) {
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;
272 return;
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.
298 * Jeremy.
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
310 domain */
312 if (psid == NULL) {
313 return NULL;
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) {
324 return 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) {
340 return NULL;
343 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
345 return domain_dispinfo;
348 return NULL;
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. */
363 become_root();
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);
371 unbecome_root();
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,
380 struct timeval now,
381 void *private_data)
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 "
388 "out\n"));
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)) {
422 return;
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)
437 if (!sam_pass)
438 return;
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. */
452 return 0;
455 if (info->users == NULL) {
456 info->users = pdb_search_users(info, acct_flags);
457 if (info->users == NULL) {
458 return 0;
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. */
476 return 0;
479 if (info->groups == NULL) {
480 info->groups = pdb_search_groups(info);
481 if (info->groups == NULL) {
482 return 0;
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) {
501 return 0;
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 /*******************************************************************
514 _samr_Close
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);
525 return NT_STATUS_OK;
528 /*******************************************************************
529 _samr_OpenDomain
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;
538 uint32 acc_granted;
539 uint32 des_access = r->in.access_mask;
540 NTSTATUS status;
541 size_t sd_size;
542 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
543 SE_PRIV se_rights;
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)) {
550 return 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,
556 &des_access);
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
570 * and aliases.
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) )
585 return 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)) {
595 return 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__));
602 return NT_STATUS_OK;
605 /*******************************************************************
606 _samr_GetUserPwInfo
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;
616 bool ret = false;
617 NTSTATUS status;
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)) {
625 return status;
628 if (!sid_check_is_in_our_domain(&uinfo->sid)) {
629 return NT_STATUS_OBJECT_TYPE_MISMATCH;
632 become_root();
633 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
634 unbecome_root();
635 if (ret == false) {
636 return NT_STATUS_NO_SUCH_USER;
639 switch (sid_type) {
640 case SID_NAME_USER:
641 become_root();
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);
646 unbecome_root();
648 if (lp_check_password_script() && *lp_check_password_script()) {
649 password_properties |= DOMAIN_PASSWORD_COMPLEX;
652 break;
653 default:
654 break;
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__));
662 return NT_STATUS_OK;
665 /*******************************************************************
666 _samr_SetSecurity
667 ********************************************************************/
669 NTSTATUS _samr_SetSecurity(pipes_struct *p,
670 struct samr_SetSecurity *r)
672 struct samr_user_info *uinfo;
673 uint32 i;
674 SEC_ACL *dacl;
675 bool ret;
676 struct samu *sampass=NULL;
677 NTSTATUS status;
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)) {
683 return 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 */
692 become_root();
693 ret = pdb_getsampwsid(sampass, &uinfo->sid);
694 unbecome_root();
696 if (!ret) {
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) ?
709 True: False);
710 break;
714 if (!ret) {
715 TALLOC_FREE(sampass);
716 return NT_STATUS_ACCESS_DENIED;
719 become_root();
720 status = pdb_update_sam_account(sampass);
721 unbecome_root();
723 TALLOC_FREE(sampass);
725 return status;
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;
734 bool ret;
736 if ( !(sampass = samu_new( mem_ctx )) ) {
737 DEBUG(0,("No memory!\n"));
738 return False;
741 become_root();
742 ret = pdb_getsampwsid(sampass, user_sid);
743 unbecome_root();
745 if (ret == False) {
746 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
747 TALLOC_FREE(sampass);
748 return False;
751 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
753 if (pdb_get_pass_can_change(sampass)) {
754 TALLOC_FREE(sampass);
755 return True;
757 TALLOC_FREE(sampass);
758 return False;
762 /*******************************************************************
763 _samr_QuerySecurity
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;
774 NTSTATUS status;
775 SEC_DESC * psd = NULL;
776 size_t sd_size = 0;
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);
785 goto done;
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
796 * write access
798 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
799 &dom_generic_mapping, NULL, 0);
800 goto done;
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);
815 } else {
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);
821 goto done;
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);
839 goto done;
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);
857 goto done;
860 return NT_STATUS_OBJECT_TYPE_MISMATCH;
861 done:
862 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
863 return NT_STATUS_NO_MEMORY;
865 return status;
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,
875 uint32_t start_idx,
876 struct samr_displayentry *entries)
878 uint32_t i;
879 struct samr_SamEntry *sam;
881 *sam_pp = NULL;
883 if (num_entries == 0) {
884 return NT_STATUS_OK;
887 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
888 if (sam == NULL) {
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++) {
894 #if 0
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,
901 UNI_FLAGS_NONE);
902 } else {
903 init_unistr2(&uni_temp_name, entries[i].account_name,
904 UNI_STR_TERMINATE);
906 #endif
907 init_lsa_String(&sam[i].name, entries[i].account_name);
908 sam[i].idx = entries[i].rid;
911 *sam_pp = sam;
913 return NT_STATUS_OK;
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)
925 NTSTATUS status;
926 struct samr_domain_info *dinfo;
927 int num_account;
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)) {
942 return status;
945 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
946 if (!samr_array) {
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"));
955 return status;
958 become_root();
960 /* AS ROOT !!!! */
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 !!!! */
975 unbecome_root();
976 return NT_STATUS_ACCESS_DENIED;
979 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
980 enum_context, max_entries,
981 &entries);
983 /* END AS ROOT !!!! */
985 unbecome_root();
987 if (num_account == 0) {
988 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
989 "total entries\n"));
990 *r->out.resume_handle = *r->in.resume_handle;
991 return NT_STATUS_OK;
994 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
995 num_account, enum_context,
996 entries);
997 if (!NT_STATUS_IS_OK(status)) {
998 return status;
1001 if (max_entries <= num_account) {
1002 status = STATUS_MORE_ENTRIES;
1003 } else {
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__));
1020 return status;
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;
1033 uint32_t i;
1035 *sam_pp = NULL;
1037 if (num_sam_entries == 0) {
1038 return;
1041 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1042 if (sam == NULL) {
1043 return;
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;
1054 *sam_pp = sam;
1057 /*******************************************************************
1058 _samr_EnumDomainGroups
1059 ********************************************************************/
1061 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1062 struct samr_EnumDomainGroups *r)
1064 NTSTATUS status;
1065 struct samr_domain_info *dinfo;
1066 struct samr_displayentry *groups;
1067 uint32 num_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)) {
1075 return status;
1078 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1080 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1081 if (!samr_array) {
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"));
1090 return status;
1093 /* the domain group array is being allocated in the function below */
1095 become_root();
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) {
1101 unbecome_root();
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);
1109 unbecome_root();
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;
1119 } else {
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__));
1131 return status;
1134 /*******************************************************************
1135 _samr_EnumDomainAliases
1136 ********************************************************************/
1138 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1139 struct samr_EnumDomainAliases *r)
1141 NTSTATUS status;
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)) {
1152 return 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);
1159 if (!samr_array) {
1160 return NT_STATUS_NO_MEMORY;
1163 become_root();
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) {
1169 unbecome_root();
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);
1177 unbecome_root();
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;
1189 } else {
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;
1200 return status;
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,
1210 uint32_t start_idx,
1211 struct samr_displayentry *entries)
1213 uint32 i;
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);
1224 if (!r->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,
1254 uint32_t start_idx,
1255 struct samr_displayentry *entries)
1257 uint32_t i;
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);
1268 if (!r->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,
1295 uint32_t start_idx,
1296 struct samr_displayentry *entries)
1298 uint32_t i;
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);
1309 if (!r->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,
1336 uint32_t start_idx,
1337 struct samr_displayentry *entries)
1339 uint32_t i;
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);
1350 if (!r->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,
1372 uint32_t start_idx,
1373 struct samr_displayentry *entries)
1375 uint32_t i;
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);
1386 if (!r->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)
1408 NTSTATUS status;
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;
1416 uint32 temp_size=0;
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)) {
1429 return 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.
1439 * based on
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
1457 * in memory.
1459 * If you want to change it, think twice and think
1460 * of the second point , that's really important.
1462 * JFM, 12/20/2001
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,
1475 max_sam_entries));
1476 max_entries = max_sam_entries;
1479 /* calculate the size and limit on the number of entries we will
1480 * return */
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));
1490 become_root();
1492 /* THe following done as ROOT. Don't return without unbecome_root(). */
1494 switch (r->in.level) {
1495 case 1:
1496 case 4:
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) {
1501 unbecome_root();
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));
1506 } else {
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,
1513 &entries);
1514 break;
1515 case 2:
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) {
1520 unbecome_root();
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));
1525 } else {
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,
1532 &entries);
1533 break;
1534 case 3:
1535 case 5:
1536 if (dinfo->disp_info->groups == NULL) {
1537 dinfo->disp_info->groups = pdb_search_groups(
1538 dinfo->disp_info);
1539 if (dinfo->disp_info->groups == NULL) {
1540 unbecome_root();
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));
1545 } else {
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,
1552 &entries);
1553 break;
1554 default:
1555 unbecome_root();
1556 smb_panic("info class changed");
1557 break;
1559 unbecome_root();
1562 /* Now create reply structure */
1563 switch (r->in.level) {
1564 case 1:
1565 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1566 num_account, r->in.start_idx,
1567 entries);
1568 break;
1569 case 2:
1570 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1571 num_account, r->in.start_idx,
1572 entries);
1573 break;
1574 case 3:
1575 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1576 num_account, r->in.start_idx,
1577 entries);
1578 break;
1579 case 4:
1580 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1581 num_account, r->in.start_idx,
1582 entries);
1583 break;
1584 case 5:
1585 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1586 num_account, r->in.start_idx,
1587 entries);
1588 break;
1589 default:
1590 smb_panic("info class changed");
1591 break;
1594 if (!NT_STATUS_IS_OK(disp_ret))
1595 return disp_ret;
1597 if (max_entries <= num_account) {
1598 status = STATUS_MORE_ENTRIES;
1599 } else {
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;
1611 return status;
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;
1667 NTSTATUS status;
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)) {
1678 return status;
1681 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1682 if (!alias_info) {
1683 return NT_STATUS_NO_MEMORY;
1686 become_root();
1687 status = pdb_get_aliasinfo(&ainfo->sid, &info);
1688 unbecome_root();
1690 if ( !NT_STATUS_IS_OK(status))
1691 return 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) {
1698 case ALIASINFOALL:
1699 alias_info->all.name.string = alias_name;
1700 alias_info->all.num_members = 1; /* ??? */
1701 alias_info->all.description.string = alias_description;
1702 break;
1703 case ALIASINFONAME:
1704 alias_info->name.string = alias_name;
1705 break;
1706 case ALIASINFODESCRIPTION:
1707 alias_info->description.string = alias_description;
1708 break;
1709 default:
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 /*******************************************************************
1721 _samr_LookupNames
1722 ********************************************************************/
1724 NTSTATUS _samr_LookupNames(pipes_struct *p,
1725 struct samr_LookupNames *r)
1727 struct samr_domain_info *dinfo;
1728 NTSTATUS status;
1729 uint32 *rid;
1730 enum lsa_SidType *type;
1731 int i;
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)) {
1742 return 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,
1768 &rid[i]))
1770 type[i] = SID_NAME_ALIAS;
1772 } else {
1773 lookup_global_sam_name(r->in.names[i].string, 0,
1774 &rid[i], &type[i]);
1777 if (type[i] != SID_NAME_UNKNOWN) {
1778 num_mapped++;
1782 if (num_mapped == num_rids) {
1783 status = NT_STATUS_OK;
1784 } else if (num_mapped == 0) {
1785 status = NT_STATUS_NONE_MAPPED;
1786 } else {
1787 status = STATUS_SOME_UNMAPPED;
1790 rids.count = num_rids;
1791 rids.ids = rid;
1793 types.count = num_rids;
1794 types.ids = type;
1796 *r->out.rids = rids;
1797 *r->out.types = types;
1799 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1801 return status;
1804 /****************************************************************
1805 _samr_ChangePasswordUser
1806 ****************************************************************/
1808 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1809 struct samr_ChangePasswordUser *r)
1811 NTSTATUS status;
1812 bool ret = false;
1813 struct samr_user_info *uinfo;
1814 struct samu *pwd;
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)) {
1822 return 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;
1832 become_root();
1833 ret = pdb_getsampwsid(pwd, &uinfo->sid);
1834 unbecome_root();
1836 if (!ret) {
1837 TALLOC_FREE(pwd);
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;
1849 goto out;
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
1861 present */
1862 status = NT_STATUS_INVALID_PARAMETER_MIX;
1863 goto out;
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;
1871 goto out;
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;
1879 goto out;
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;
1888 goto out;
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;
1898 goto out;
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;
1905 goto out;
1908 status = pdb_update_sam_account(pwd);
1909 out:
1910 TALLOC_FREE(pwd);
1912 return status;
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;
1923 NTSTATUS status;
1924 fstring user_name;
1925 fstring wks;
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
1936 * function.
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,
1951 NULL);
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;
1959 return status;
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;
1970 NTSTATUS status;
1971 fstring user_name;
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
1985 * function.
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,
2001 r->in.hash->hash,
2004 NULL);
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__));
2012 return status;
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;
2023 NTSTATUS status;
2024 fstring user_name;
2025 const char *wks = NULL;
2026 enum samPwdChangeReason reject_reason;
2027 struct samr_DomInfo1 *dominfo = NULL;
2028 struct userPwdChangeFailureInformation *reject = NULL;
2029 uint32_t tmp;
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
2042 * function.
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,
2057 &reject_reason);
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);
2069 if (!dominfo) {
2070 return NT_STATUS_NO_MEMORY;
2073 reject = TALLOC_ZERO_P(p->mem_ctx,
2074 struct userPwdChangeFailureInformation);
2075 if (!reject) {
2076 return NT_STATUS_NO_MEMORY;
2079 become_root();
2081 /* AS ROOT !!! */
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;
2098 /* !AS ROOT */
2100 unbecome_root();
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__));
2117 return status;
2120 /*******************************************************************
2121 makes a SAMR_R_LOOKUP_RIDS structure.
2122 ********************************************************************/
2124 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2125 const char **names,
2126 struct lsa_String **lsa_name_array_p)
2128 struct lsa_String *lsa_name_array = NULL;
2129 uint32_t i;
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) {
2136 return false;
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;
2147 return true;
2150 /*******************************************************************
2151 _samr_LookupRids
2152 ********************************************************************/
2154 NTSTATUS _samr_LookupRids(pipes_struct *p,
2155 struct samr_LookupRids *r)
2157 struct samr_domain_info *dinfo;
2158 NTSTATUS status;
2159 const char **names;
2160 enum lsa_SidType *attrs = NULL;
2161 uint32 *wire_attrs = NULL;
2162 int num_rids = (int)r->in.num_rids;
2163 int i;
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)) {
2174 return 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;
2183 if (num_rids) {
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;
2190 } else {
2191 names = NULL;
2192 attrs = NULL;
2193 wire_attrs = NULL;
2196 become_root(); /* lookup_sid can require root privs */
2197 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2198 names, attrs);
2199 unbecome_root();
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,
2206 &lsa_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__));
2226 return status;
2229 /*******************************************************************
2230 _samr_OpenUser
2231 ********************************************************************/
2233 NTSTATUS _samr_OpenUser(pipes_struct *p,
2234 struct samr_OpenUser *r)
2236 struct samu *sampass=NULL;
2237 DOM_SID sid;
2238 struct samr_domain_info *dinfo;
2239 struct samr_user_info *uinfo;
2240 SEC_DESC *psd = NULL;
2241 uint32 acc_granted;
2242 uint32 des_access = r->in.access_mask;
2243 uint32_t extra_access = 0;
2244 size_t sd_size;
2245 bool ret;
2246 NTSTATUS nt_status;
2247 SE_PRIV se_rights;
2248 NTSTATUS status;
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)) {
2254 return 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,
2269 &des_access);
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.
2280 become_root();
2281 ret=pdb_getsampwsid(sampass, &sid);
2282 unbecome_root();
2284 se_priv_copy(&se_rights, &se_priv_none);
2287 * We do the override access checks on *open*, not at
2288 * SetUserInfo time.
2290 if (ret) {
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
2299 * account.
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,
2308 &se_add_users)) {
2310 * SeAddUsers is needed to add
2311 * GENERIC_RIGHTS_USER_WRITE to a normal
2312 * account.
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 "
2332 "rid admins\n"));
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) )
2344 return nt_status;
2346 /* check that the SID exists in our domain. */
2347 if (ret == False) {
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)) {
2357 return nt_status;
2359 uinfo->sid = sid;
2361 return NT_STATUS_OK;
2364 /*************************************************************************
2365 *************************************************************************/
2367 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2368 DATA_BLOB *blob,
2369 struct lsa_BinaryString **_r)
2371 struct lsa_BinaryString *r;
2373 if (!blob || !_r) {
2374 return NT_STATUS_INVALID_PARAMETER;
2377 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2378 if (!r) {
2379 return NT_STATUS_NO_MEMORY;
2382 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2383 if (!r->array) {
2384 return NT_STATUS_NO_MEMORY;
2386 memcpy(r->array, blob->data, blob->length);
2387 r->size = blob->length;
2388 r->length = blob->length;
2390 if (!r->array) {
2391 return NT_STATUS_NO_MEMORY;
2394 *_r = r;
2396 return NT_STATUS_OK;
2399 /*************************************************************************
2400 get_user_info_1.
2401 *************************************************************************/
2403 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2404 struct samr_UserInfo1 *r,
2405 struct samu *pw,
2406 DOM_SID *domain_sid)
2408 const DOM_SID *sid_group;
2409 uint32_t primary_gid;
2411 become_root();
2412 sid_group = pdb_get_group_sid(pw);
2413 unbecome_root();
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 /*************************************************************************
2433 get_user_info_2.
2434 *************************************************************************/
2436 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2437 struct samr_UserInfo2 *r,
2438 struct samu *pw)
2440 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2441 r->unknown.string = NULL;
2442 r->country_code = 0;
2443 r->code_page = 0;
2445 return NT_STATUS_OK;
2448 /*************************************************************************
2449 get_user_info_3.
2450 *************************************************************************/
2452 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2453 struct samr_UserInfo3 *r,
2454 struct samu *pw,
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;
2470 become_root();
2471 sid_group = pdb_get_group_sid(pw);
2472 unbecome_root();
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);
2497 r->rid = rid;
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 /*************************************************************************
2507 get_user_info_4.
2508 *************************************************************************/
2510 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2511 struct samr_UserInfo4 *r,
2512 struct samu *pw)
2514 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2516 return NT_STATUS_OK;
2519 /*************************************************************************
2520 get_user_info_5.
2521 *************************************************************************/
2523 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2524 struct samr_UserInfo5 *r,
2525 struct samu *pw,
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;
2541 become_root();
2542 sid_group = pdb_get_group_sid(pw);
2543 unbecome_root();
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);
2568 r->rid = rid;
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 /*************************************************************************
2578 get_user_info_6.
2579 *************************************************************************/
2581 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2582 struct samr_UserInfo6 *r,
2583 struct samu *pw)
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 /*************************************************************************
2608 get_user_info_8.
2609 *************************************************************************/
2611 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2612 struct samr_UserInfo8 *r,
2613 struct samu *pw)
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 /*************************************************************************
2634 get_user_info_10.
2635 *************************************************************************/
2637 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2638 struct samr_UserInfo10 *r,
2639 struct samu *pw)
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 /*************************************************************************
2648 get_user_info_11.
2649 *************************************************************************/
2651 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2652 struct samr_UserInfo11 *r,
2653 struct samu *pw)
2655 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2657 return NT_STATUS_OK;
2660 /*************************************************************************
2661 get_user_info_12.
2662 *************************************************************************/
2664 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2665 struct samr_UserInfo12 *r,
2666 struct samu *pw)
2668 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2670 return NT_STATUS_OK;
2673 /*************************************************************************
2674 get_user_info_13.
2675 *************************************************************************/
2677 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2678 struct samr_UserInfo13 *r,
2679 struct samu *pw)
2681 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2683 return NT_STATUS_OK;
2686 /*************************************************************************
2687 get_user_info_14.
2688 *************************************************************************/
2690 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2691 struct samr_UserInfo14 *r,
2692 struct samu *pw)
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 /*************************************************************************
2713 get_user_info_17.
2714 *************************************************************************/
2716 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2717 struct samr_UserInfo17 *r,
2718 struct samu *pw)
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
2728 user. JRA.
2729 *************************************************************************/
2731 static NTSTATUS get_user_info_18(pipes_struct *p,
2732 TALLOC_CTX *mem_ctx,
2733 struct samr_UserInfo18 *r,
2734 DOM_SID *user_sid)
2736 struct samu *smbpass=NULL;
2737 bool ret;
2739 ZERO_STRUCTP(r);
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);
2759 if (ret == False) {
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 /*************************************************************************
2784 get_user_info_20
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;
2792 DATA_BLOB blob;
2793 NTSTATUS status;
2794 struct lsa_BinaryString *parameters = NULL;
2796 ZERO_STRUCTP(r);
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)));
2803 if (munged_dial) {
2804 blob = base64_decode_data_blob(munged_dial);
2805 } else {
2806 blob = data_blob_string_const_null("");
2809 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2810 data_blob_free(&blob);
2811 if (!NT_STATUS_IS_OK(status)) {
2812 return status;
2815 r->parameters = *parameters;
2817 return NT_STATUS_OK;
2821 /*************************************************************************
2822 get_user_info_21
2823 *************************************************************************/
2825 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2826 struct samr_UserInfo21 *r,
2827 struct samu *pw,
2828 DOM_SID *domain_sid,
2829 uint32_t acc_granted)
2831 NTSTATUS status;
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;
2838 DATA_BLOB blob;
2840 ZERO_STRUCTP(r);
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;
2852 become_root();
2853 sid_group = pdb_get_group_sid(pw);
2854 unbecome_root();
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);
2873 } else {
2874 unix_to_nt_time(&force_password_change, must_change_time);
2877 munged_dial = pdb_get_munged_dial(pw);
2878 if (munged_dial) {
2879 blob = base64_decode_data_blob(munged_dial);
2880 } else {
2881 blob = data_blob_string_const_null("");
2884 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2885 data_blob_free(&blob);
2886 if (!NT_STATUS_IS_OK(status)) {
2887 return 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;
2904 r->rid = rid;
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;
2913 r->code_page = 0;
2914 r->lm_password_set = 0;
2915 r->nt_password_set = 0;
2917 #if 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
2925 at the user.
2926 -- Volker
2929 #endif
2932 return NT_STATUS_OK;
2935 /*******************************************************************
2936 _samr_QueryUserInfo
2937 ********************************************************************/
2939 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2940 struct samr_QueryUserInfo *r)
2942 NTSTATUS status;
2943 union samr_UserInfo *user_info = NULL;
2944 struct samr_user_info *uinfo;
2945 DOM_SID domain_sid;
2946 uint32 rid;
2947 bool ret = false;
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;
2955 break;
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;
2960 break;
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;
2967 break;
2968 case 4: /* UserLogonHoursInformation */
2969 /* USER_READ_LOGON */
2970 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2971 break;
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;
2978 break;
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;
2986 break;
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;
2993 break;
2994 case 16: /* UserControlInformation */
2995 case 17: /* UserExpiresInformation */
2996 case 20: /* UserParametersInformation */
2997 /* USER_READ_ACCOUNT */
2998 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2999 break;
3000 case 21: /* UserAllInformation */
3001 /* FIXME! - gd */
3002 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3003 break;
3004 case 18: /* UserInternal1Information */
3005 /* FIXME! - gd */
3006 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3007 break;
3008 case 23: /* UserInternal4Information */
3009 case 24: /* UserInternal4InformationNew */
3010 case 25: /* UserInternal4InformationNew */
3011 case 26: /* UserInternal5InformationNew */
3012 default:
3013 return NT_STATUS_INVALID_INFO_CLASS;
3014 break;
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)) {
3021 return 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);
3035 if (!user_info) {
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;
3045 become_root();
3046 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3047 unbecome_root();
3049 if (ret == false) {
3050 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3051 TALLOC_FREE(pwd);
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) {
3060 case 1:
3061 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3062 break;
3063 case 2:
3064 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3065 break;
3066 case 3:
3067 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3068 break;
3069 case 4:
3070 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3071 break;
3072 case 5:
3073 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3074 break;
3075 case 6:
3076 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3077 break;
3078 case 7:
3079 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3080 break;
3081 case 8:
3082 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3083 break;
3084 case 9:
3085 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3086 break;
3087 case 10:
3088 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3089 break;
3090 case 11:
3091 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3092 break;
3093 case 12:
3094 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3095 break;
3096 case 13:
3097 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3098 break;
3099 case 14:
3100 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3101 break;
3102 case 16:
3103 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3104 break;
3105 case 17:
3106 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3107 break;
3108 case 18:
3109 /* level 18 is special */
3110 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3111 &uinfo->sid);
3112 break;
3113 case 20:
3114 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3115 break;
3116 case 21:
3117 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3118 break;
3119 default:
3120 status = NT_STATUS_INVALID_INFO_CLASS;
3121 break;
3124 if (!NT_STATUS_IS_OK(status)) {
3125 goto done;
3128 *r->out.info = user_info;
3130 done:
3131 TALLOC_FREE(pwd);
3133 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3135 return status;
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;
3162 DOM_SID *sids;
3163 struct samr_RidWithAttribute dom_gid;
3164 struct samr_RidWithAttribute *gids = NULL;
3165 uint32 primary_group_rid;
3166 size_t num_groups = 0;
3167 gid_t *unix_gids;
3168 size_t i, num_gids;
3169 bool ret;
3170 NTSTATUS result;
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
3184 * JFM, 12/2/2001
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)) {
3193 return result;
3196 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3197 if (!rids) {
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;
3208 become_root();
3209 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3210 unbecome_root();
3212 if (!ret) {
3213 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3214 sid_string_dbg(&uinfo->sid)));
3215 return NT_STATUS_NO_SUCH_USER;
3218 sids = NULL;
3220 /* make both calls inside the root block */
3221 become_root();
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);
3229 unbecome_root();
3231 if (!NT_STATUS_IS_OK(result)) {
3232 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3233 sid_string_dbg(&uinfo->sid)));
3234 return result;
3237 if ( !success ) {
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;
3245 gids = NULL;
3246 num_gids = 0;
3248 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3249 SE_GROUP_ENABLED);
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])));
3259 continue;
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 */
3266 continue;
3269 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3272 rids->count = num_gids;
3273 rids->rids = gids;
3275 *r->out.rids = rids;
3277 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3279 return result;
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;
3293 return role;
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;
3305 become_root();
3307 /* AS ROOT !!! */
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;
3324 /* !AS ROOT */
3326 unbecome_root();
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)
3345 uint32_t u_logout;
3346 time_t seq_num;
3348 become_root();
3350 /* AS ROOT !!! */
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);
3364 /* !AS ROOT */
3366 unbecome_root();
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();
3374 r->unknown3 = 1;
3376 return NT_STATUS_OK;
3379 /*******************************************************************
3380 ********************************************************************/
3382 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3383 struct samr_DomInfo3 *r)
3385 uint32_t u_logout;
3387 become_root();
3389 /* AS ROOT !!! */
3392 uint32_t ul;
3393 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3394 u_logout = (time_t)ul;
3397 /* !AS ROOT */
3399 unbecome_root();
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
3436 * idl) */
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)
3459 time_t seq_num;
3461 become_root();
3463 /* AS ROOT !!! */
3465 if (!pdb_get_seq_num(&seq_num)) {
3466 seq_num = time(NULL);
3469 /* !AS ROOT */
3471 unbecome_root();
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)
3497 NTSTATUS status;
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)) {
3503 return status;
3506 /* AS ROOT !!! */
3508 become_root();
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;
3522 /* !AS ROOT */
3524 unbecome_root();
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;
3541 become_root();
3543 /* AS ROOT !!! */
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;
3557 /* !AS ROOT */
3559 unbecome_root();
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)
3573 time_t seq_num;
3575 become_root();
3577 /* AS ROOT !!! */
3579 if (!pdb_get_seq_num(&seq_num)) {
3580 seq_num = time(NULL);
3583 /* !AS ROOT */
3585 unbecome_root();
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;
3614 break;
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;
3620 break;
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;
3633 break;
3634 default:
3635 return NT_STATUS_INVALID_INFO_CLASS;
3638 dinfo = policy_handle_find(p, r->in.domain_handle,
3639 acc_required, NULL,
3640 struct samr_domain_info, &status);
3641 if (!NT_STATUS_IS_OK(status)) {
3642 return status;
3645 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3646 if (!dom_info) {
3647 return NT_STATUS_NO_MEMORY;
3650 switch (r->in.level) {
3651 case 1:
3652 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3653 break;
3654 case 2:
3655 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3656 break;
3657 case 3:
3658 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3659 break;
3660 case 4:
3661 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3662 break;
3663 case 5:
3664 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3665 break;
3666 case 6:
3667 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3668 break;
3669 case 7:
3670 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3671 break;
3672 case 8:
3673 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3674 break;
3675 case 9:
3676 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3677 break;
3678 case 11:
3679 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3680 break;
3681 case 12:
3682 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3683 break;
3684 case 13:
3685 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3686 break;
3687 default:
3688 return NT_STATUS_INVALID_INFO_CLASS;
3691 if (!NT_STATUS_IS_OK(status)) {
3692 return status;
3695 *r->out.info = dom_info;
3697 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3699 return status;
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
3705 * database. */
3707 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3709 enum lsa_SidType type;
3710 bool result;
3712 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3714 become_root();
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);
3719 unbecome_root();
3721 if (!result) {
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 /*******************************************************************
3741 _samr_CreateUser2
3742 ********************************************************************/
3744 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3745 struct samr_CreateUser2 *r)
3747 const char *account = NULL;
3748 DOM_SID sid;
3749 uint32_t acb_info = r->in.acct_flags;
3750 struct samr_domain_info *dinfo;
3751 struct samr_user_info *uinfo;
3752 NTSTATUS nt_status;
3753 uint32 acc_granted;
3754 SEC_DESC *psd;
3755 size_t sd_size;
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;
3759 SE_PRIV se_rights;
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)) {
3765 return 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)) {
3787 return 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 **********/
3826 become_root();
3827 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3828 r->out.rid);
3829 unbecome_root();
3831 /********** END Admin BLOCK **********/
3833 /* now check for failure */
3835 if ( !NT_STATUS_IS_OK(nt_status) )
3836 return 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,
3844 &des_access);
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) ) {
3862 return 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)) {
3868 return nt_status;
3870 uinfo->sid = sid;
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 /*******************************************************************
3901 _samr_Connect
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;
3911 NTSTATUS status;
3913 /* Access check */
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,
3926 &des_access);
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,
3937 &status);
3938 if (!NT_STATUS_IS_OK(status)) {
3939 return status;
3942 *r->out.connect_handle = hnd;
3943 return NT_STATUS_OK;
3946 /*******************************************************************
3947 _samr_Connect2
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;
3956 uint32 acc_granted;
3957 uint32 des_access = r->in.access_mask;
3958 NTSTATUS nt_status;
3959 size_t sd_size;
3960 const char *fn = "_samr_Connect2";
3962 switch (p->hdr_req.opnum) {
3963 case NDR_SAMR_CONNECT2:
3964 fn = "_samr_Connect2";
3965 break;
3966 case NDR_SAMR_CONNECT3:
3967 fn = "_samr_Connect3";
3968 break;
3969 case NDR_SAMR_CONNECT4:
3970 fn = "_samr_Connect4";
3971 break;
3972 case NDR_SAMR_CONNECT5:
3973 fn = "_samr_Connect5";
3974 break;
3977 DEBUG(5,("%s: %d\n", fn, __LINE__));
3979 /* Access check */
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,
3988 &des_access);
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) )
3997 return 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)) {
4002 return nt_status;
4005 DEBUG(5,("%s: %d\n", fn, __LINE__));
4007 *r->out.connect_handle = hnd;
4008 return NT_STATUS_OK;
4011 /****************************************************************
4012 _samr_Connect3
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 /*******************************************************************
4028 _samr_Connect4
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 /*******************************************************************
4044 _samr_Connect5
4045 ********************************************************************/
4047 NTSTATUS _samr_Connect5(pipes_struct *p,
4048 struct samr_Connect5 *r)
4050 NTSTATUS status;
4051 struct samr_Connect2 c;
4052 struct samr_ConnectInfo1 info1;
4054 info1.client_version = SAMR_CONNECT_AFTER_W2K;
4055 info1.unknown2 = 0;
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)) {
4065 return status;
4068 r->out.info_out->info1 = info1;
4070 return NT_STATUS_OK;
4073 /**********************************************************************
4074 _samr_LookupDomain
4075 **********************************************************************/
4077 NTSTATUS _samr_LookupDomain(pipes_struct *p,
4078 struct samr_LookupDomain *r)
4080 NTSTATUS status;
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,
4091 &status);
4092 if (!NT_STATUS_IS_OK(status)) {
4093 return status;
4096 domain_name = r->in.domain_name->string;
4097 if (!domain_name) {
4098 return NT_STATUS_INVALID_PARAMETER;
4101 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
4102 if (!sid) {
4103 return NT_STATUS_NO_MEMORY;
4106 if (strequal(domain_name, builtin_domain_name())) {
4107 sid_copy(sid, &global_sid_Builtin);
4108 } else {
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)));
4117 *r->out.sid = sid;
4119 return status;
4122 /**********************************************************************
4123 _samr_EnumDomains
4124 **********************************************************************/
4126 NTSTATUS _samr_EnumDomains(pipes_struct *p,
4127 struct samr_EnumDomains *r)
4129 NTSTATUS status;
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)) {
4139 return status;
4142 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4143 if (!sam) {
4144 return NT_STATUS_NO_MEMORY;
4147 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4148 struct samr_SamEntry,
4149 num_entries);
4150 if (!entry_array) {
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;
4163 *r->out.sam = sam;
4164 *r->out.num_entries = num_entries;
4166 return status;
4169 /*******************************************************************
4170 _samr_OpenAlias
4171 ********************************************************************/
4173 NTSTATUS _samr_OpenAlias(pipes_struct *p,
4174 struct samr_OpenAlias *r)
4176 DOM_SID sid;
4177 uint32 alias_rid = r->in.rid;
4178 struct samr_alias_info *ainfo;
4179 struct samr_domain_info *dinfo;
4180 SEC_DESC *psd = NULL;
4181 uint32 acc_granted;
4182 uint32 des_access = r->in.access_mask;
4183 size_t sd_size;
4184 NTSTATUS status;
4185 SE_PRIV se_rights;
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)) {
4191 return 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,
4203 &des_access);
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) )
4215 return status;
4218 /* Check we actually have the requested alias */
4219 enum lsa_SidType type;
4220 bool result;
4221 gid_t gid;
4223 become_root();
4224 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4225 unbecome_root();
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)) {
4242 return status;
4244 ainfo->sid = sid;
4246 return NT_STATUS_OK;
4249 /*******************************************************************
4250 set_user_info_2
4251 ********************************************************************/
4253 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4254 struct samr_UserInfo2 *id2,
4255 struct samu *pwd)
4257 if (id2 == NULL) {
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 /*******************************************************************
4268 set_user_info_4
4269 ********************************************************************/
4271 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4272 struct samr_UserInfo4 *id4,
4273 struct samu *pwd)
4275 if (id4 == NULL) {
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 /*******************************************************************
4286 set_user_info_6
4287 ********************************************************************/
4289 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4290 struct samr_UserInfo6 *id6,
4291 struct samu *pwd)
4293 if (id6 == NULL) {
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 /*******************************************************************
4304 set_user_info_7
4305 ********************************************************************/
4307 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4308 struct samr_UserInfo7 *id7,
4309 struct samu *pwd)
4311 NTSTATUS rc;
4313 if (id7 == NULL) {
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)) {
4340 return rc;
4343 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4345 return rc;
4348 /*******************************************************************
4349 set_user_info_8
4350 ********************************************************************/
4352 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4353 struct samr_UserInfo8 *id8,
4354 struct samu *pwd)
4356 if (id8 == NULL) {
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 /*******************************************************************
4367 set_user_info_10
4368 ********************************************************************/
4370 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4371 struct samr_UserInfo10 *id10,
4372 struct samu *pwd)
4374 if (id10 == NULL) {
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 /*******************************************************************
4385 set_user_info_11
4386 ********************************************************************/
4388 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4389 struct samr_UserInfo11 *id11,
4390 struct samu *pwd)
4392 if (id11 == NULL) {
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 /*******************************************************************
4403 set_user_info_12
4404 ********************************************************************/
4406 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4407 struct samr_UserInfo12 *id12,
4408 struct samu *pwd)
4410 if (id12 == NULL) {
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 /*******************************************************************
4421 set_user_info_13
4422 ********************************************************************/
4424 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4425 struct samr_UserInfo13 *id13,
4426 struct samu *pwd)
4428 if (id13 == NULL) {
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 /*******************************************************************
4439 set_user_info_14
4440 ********************************************************************/
4442 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4443 struct samr_UserInfo14 *id14,
4444 struct samu *pwd)
4446 if (id14 == NULL) {
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 /*******************************************************************
4457 set_user_info_16
4458 ********************************************************************/
4460 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4461 struct samr_UserInfo16 *id16,
4462 struct samu *pwd)
4464 if (id16 == NULL) {
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 /*******************************************************************
4475 set_user_info_17
4476 ********************************************************************/
4478 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4479 struct samr_UserInfo17 *id17,
4480 struct samu *pwd)
4482 if (id17 == NULL) {
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 /*******************************************************************
4493 set_user_info_18
4494 ********************************************************************/
4496 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4497 TALLOC_CTX *mem_ctx,
4498 DATA_BLOB *session_key,
4499 struct samu *pwd)
4501 if (id18 == NULL) {
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) {
4514 DATA_BLOB in, out;
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) {
4530 DATA_BLOB in, out;
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 /*******************************************************************
4550 set_user_info_20
4551 ********************************************************************/
4553 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4554 struct samr_UserInfo20 *id20,
4555 struct samu *pwd)
4557 if (id20 == NULL) {
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 /*******************************************************************
4568 set_user_info_21
4569 ********************************************************************/
4571 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4572 TALLOC_CTX *mem_ctx,
4573 DATA_BLOB *session_key,
4574 struct samu *pwd)
4576 NTSTATUS status;
4578 if (id21 == NULL) {
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) {
4593 DATA_BLOB in, out;
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) {
4616 DATA_BLOB in, out;
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)) {
4654 return 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)));
4662 return 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) ) {
4682 return 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
4688 primary group. */
4690 /* write the change out */
4691 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4692 return status;
4695 return NT_STATUS_OK;
4698 /*******************************************************************
4699 set_user_info_23
4700 ********************************************************************/
4702 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4703 struct samr_UserInfo23 *id23,
4704 struct samu *pwd)
4706 char *plaintext_buf = NULL;
4707 size_t len = 0;
4708 uint32_t acct_ctrl;
4709 NTSTATUS status;
4711 if (id23 == 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,
4732 &plaintext_buf,
4733 &len,
4734 CH_UTF16)) {
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,
4779 pwd)))) {
4780 return status;
4783 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4784 return status;
4787 return NT_STATUS_OK;
4790 /*******************************************************************
4791 set_user_info_pw
4792 ********************************************************************/
4794 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4796 size_t len = 0;
4797 char *plaintext_buf = NULL;
4798 uint32 acct_ctrl;
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(),
4806 pass,
4807 &plaintext_buf,
4808 &len,
4809 CH_UTF16)) {
4810 return False;
4813 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4814 return False;
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"));
4822 } else {
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"));
4829 return False;
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)) {
4838 return False;
4840 TALLOC_FREE(passwd);
4844 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4846 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4848 return True;
4851 /*******************************************************************
4852 set_user_info_24
4853 ********************************************************************/
4855 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4856 struct samr_UserInfo24 *id24,
4857 struct samu *pwd)
4859 NTSTATUS status;
4861 if (id24 == NULL) {
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)) {
4874 return status;
4877 return NT_STATUS_OK;
4880 /*******************************************************************
4881 set_user_info_25
4882 ********************************************************************/
4884 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4885 struct samr_UserInfo25 *id25,
4886 struct samu *pwd)
4888 NTSTATUS status;
4890 if (id25 == NULL) {
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))) {
4915 return status;
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) ) {
4929 return status;
4933 return NT_STATUS_OK;
4936 /*******************************************************************
4937 set_user_info_26
4938 ********************************************************************/
4940 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4941 struct samr_UserInfo26 *id26,
4942 struct samu *pwd)
4944 NTSTATUS status;
4946 if (id26 == NULL) {
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)) {
4959 return 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 /*******************************************************************
5034 samr_SetUserInfo
5035 ********************************************************************/
5037 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
5038 struct samr_SetUserInfo *r)
5040 struct samr_user_info *uinfo;
5041 NTSTATUS status;
5042 struct samu *pwd = NULL;
5043 union samr_UserInfo *info = r->in.info;
5044 uint32_t acc_required = 0;
5045 uint32_t fields = 0;
5046 bool ret;
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;
5061 break;
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;
5077 break;
5078 case 18: /* UserInternal1Information */
5079 /* FIXME: gd, this is a guess */
5080 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5081 break;
5082 case 21: /* UserAllInformation */
5083 fields = info->info21.fields_present;
5084 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5085 break;
5086 case 23: /* UserInternal4Information */
5087 fields = info->info23.info.fields_present;
5088 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5089 break;
5090 case 25: /* UserInternal4InformationNew */
5091 fields = info->info25.info.fields_present;
5092 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5093 break;
5094 case 24: /* UserInternal5Information */
5095 case 26: /* UserInternal5InformationNew */
5096 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5097 break;
5098 default:
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)) {
5105 return status;
5108 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5109 sid_string_dbg(&uinfo->sid), r->in.level));
5111 if (info == NULL) {
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;
5120 become_root();
5121 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5122 unbecome_root();
5124 if (!ret) {
5125 TALLOC_FREE(pwd);
5126 return NT_STATUS_NO_SUCH_USER;
5129 /* ================ BEGIN Privilege BLOCK ================ */
5131 become_root();
5133 /* ok! user info levels (lots: see MSDEV help), off we go... */
5135 switch (r->in.level) {
5137 case 2:
5138 status = set_user_info_2(p->mem_ctx,
5139 &info->info2, pwd);
5140 break;
5142 case 4:
5143 status = set_user_info_4(p->mem_ctx,
5144 &info->info4, pwd);
5145 break;
5147 case 6:
5148 status = set_user_info_6(p->mem_ctx,
5149 &info->info6, pwd);
5150 break;
5152 case 7:
5153 status = set_user_info_7(p->mem_ctx,
5154 &info->info7, pwd);
5155 break;
5157 case 8:
5158 status = set_user_info_8(p->mem_ctx,
5159 &info->info8, pwd);
5160 break;
5162 case 10:
5163 status = set_user_info_10(p->mem_ctx,
5164 &info->info10, pwd);
5165 break;
5167 case 11:
5168 status = set_user_info_11(p->mem_ctx,
5169 &info->info11, pwd);
5170 break;
5172 case 12:
5173 status = set_user_info_12(p->mem_ctx,
5174 &info->info12, pwd);
5175 break;
5177 case 13:
5178 status = set_user_info_13(p->mem_ctx,
5179 &info->info13, pwd);
5180 break;
5182 case 14:
5183 status = set_user_info_14(p->mem_ctx,
5184 &info->info14, pwd);
5185 break;
5187 case 16:
5188 status = set_user_info_16(p->mem_ctx,
5189 &info->info16, pwd);
5190 break;
5192 case 17:
5193 status = set_user_info_17(p->mem_ctx,
5194 &info->info17, pwd);
5195 break;
5197 case 18:
5198 /* Used by AS/U JRA. */
5199 status = set_user_info_18(&info->info18,
5200 p->mem_ctx,
5201 &p->server_info->user_session_key,
5202 pwd);
5203 break;
5205 case 20:
5206 status = set_user_info_20(p->mem_ctx,
5207 &info->info20, pwd);
5208 break;
5210 case 21:
5211 status = set_user_info_21(&info->info21,
5212 p->mem_ctx,
5213 &p->server_info->user_session_key,
5214 pwd);
5215 break;
5217 case 23:
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);
5228 break;
5230 case 24:
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,
5235 516,
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);
5242 break;
5244 case 25:
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);
5256 break;
5258 case 26:
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);
5270 break;
5272 default:
5273 status = NT_STATUS_INVALID_INFO_CLASS;
5276 TALLOC_FREE(pwd);
5278 unbecome_root();
5280 /* ================ END Privilege BLOCK ================ */
5282 if (NT_STATUS_IS_OK(status)) {
5283 force_flush_samr_cache(&uinfo->sid);
5286 return status;
5289 /*******************************************************************
5290 _samr_SetUserInfo2
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;
5313 uint32 *alias_rids;
5314 struct samr_domain_info *dinfo;
5315 size_t i;
5317 NTSTATUS status;
5319 DOM_SID *members;
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)) {
5328 return 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;
5340 } else {
5341 members = NULL;
5344 for (i=0; i<r->in.sids->num_sids; i++)
5345 sid_copy(&members[i], r->in.sids->sids[i].sid);
5347 alias_rids = NULL;
5348 num_alias_rids = 0;
5350 become_root();
5351 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5352 r->in.sids->num_sids,
5353 &alias_rids, &num_alias_rids);
5354 unbecome_root();
5356 if (!NT_STATUS_IS_OK(status)) {
5357 return 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;
5374 NTSTATUS status;
5375 size_t i;
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)) {
5384 return status;
5387 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5389 become_root();
5390 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5391 &num_sids);
5392 unbecome_root();
5394 if (!NT_STATUS_IS_OK(status)) {
5395 return status;
5398 if (num_sids) {
5399 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5400 if (sids == NULL) {
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]);
5408 if (!sids[i].sid) {
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;
5432 uint32 *rid=NULL;
5433 uint32 *attr=NULL;
5435 NTSTATUS status;
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)) {
5442 return status;
5445 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5446 if (!rids) {
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"));
5460 become_root();
5461 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5462 &rid, &num_members);
5463 unbecome_root();
5465 if (!NT_STATUS_IS_OK(status))
5466 return status;
5468 if (num_members) {
5469 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5470 if (attr == NULL) {
5471 return NT_STATUS_NO_MEMORY;
5473 } else {
5474 attr = NULL;
5477 for (i=0; i<num_members; i++)
5478 attr[i] = SID_NAME_USER;
5480 rids->count = num_members;
5481 rids->types = attr;
5482 rids->rids = rid;
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;
5497 NTSTATUS status;
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)) {
5503 return status;
5506 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5508 /******** BEGIN SeAddUsers BLOCK *********/
5510 become_root();
5511 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5512 unbecome_root();
5514 /******** END SeAddUsers BLOCK *********/
5516 if (NT_STATUS_IS_OK(status)) {
5517 force_flush_samr_cache(&ainfo->sid);
5520 return status;
5523 /*********************************************************************
5524 _samr_DeleteAliasMember
5525 *********************************************************************/
5527 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5528 struct samr_DeleteAliasMember *r)
5530 struct samr_alias_info *ainfo;
5531 NTSTATUS status;
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)) {
5537 return status;
5540 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5541 sid_string_dbg(&ainfo->sid)));
5543 /******** BEGIN SeAddUsers BLOCK *********/
5545 become_root();
5546 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5547 unbecome_root();
5549 /******** END SeAddUsers BLOCK *********/
5551 if (NT_STATUS_IS_OK(status)) {
5552 force_flush_samr_cache(&ainfo->sid);
5555 return status;
5558 /*********************************************************************
5559 _samr_AddGroupMember
5560 *********************************************************************/
5562 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5563 struct samr_AddGroupMember *r)
5565 struct samr_group_info *ginfo;
5566 NTSTATUS status;
5567 uint32 group_rid;
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)) {
5573 return 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,
5579 &group_rid)) {
5580 return NT_STATUS_INVALID_HANDLE;
5583 /******** BEGIN SeAddUsers BLOCK *********/
5585 become_root();
5586 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5587 unbecome_root();
5589 /******** END SeAddUsers BLOCK *********/
5591 force_flush_samr_cache(&ginfo->sid);
5593 return status;
5596 /*********************************************************************
5597 _samr_DeleteGroupMember
5598 *********************************************************************/
5600 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5601 struct samr_DeleteGroupMember *r)
5604 struct samr_group_info *ginfo;
5605 NTSTATUS status;
5606 uint32 group_rid;
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)) {
5618 return status;
5621 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5622 &group_rid)) {
5623 return NT_STATUS_INVALID_HANDLE;
5626 /******** BEGIN SeAddUsers BLOCK *********/
5628 become_root();
5629 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5630 unbecome_root();
5632 /******** END SeAddUsers BLOCK *********/
5634 force_flush_samr_cache(&ginfo->sid);
5636 return status;
5639 /*********************************************************************
5640 _samr_DeleteUser
5641 *********************************************************************/
5643 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5644 struct samr_DeleteUser *r)
5646 struct samr_user_info *uinfo;
5647 NTSTATUS status;
5648 struct samu *sam_pass=NULL;
5649 bool ret;
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)) {
5657 return 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;
5668 become_root();
5669 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5670 unbecome_root();
5672 if(!ret) {
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 *********/
5681 become_root();
5682 status = pdb_delete_user(p->mem_ctx, sam_pass);
5683 unbecome_root();
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);
5692 return status;
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;
5716 NTSTATUS status;
5717 uint32 group_rid;
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)) {
5725 return 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,
5731 &group_rid)) {
5732 return NT_STATUS_NO_SUCH_GROUP;
5735 /******** BEGIN SeAddUsers BLOCK *********/
5737 become_root();
5738 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5739 unbecome_root();
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)));
5748 return 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;
5767 NTSTATUS status;
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)) {
5775 return 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 *********/
5793 become_root();
5794 /* Have passdb delete the alias */
5795 status = pdb_delete_alias(&ainfo->sid);
5796 unbecome_root();
5798 /******** END SeAddUsers BLOCK *********/
5800 if ( !NT_STATUS_IS_OK(status))
5801 return 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)
5819 NTSTATUS status;
5820 const char *name;
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)) {
5828 return status;
5831 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5832 return NT_STATUS_ACCESS_DENIED;
5834 name = r->in.name->string;
5835 if (name == NULL) {
5836 return NT_STATUS_NO_MEMORY;
5839 status = can_create(p->mem_ctx, name);
5840 if (!NT_STATUS_IS_OK(status)) {
5841 return status;
5844 /******** BEGIN SeAddUsers BLOCK *********/
5846 become_root();
5847 /* check that we successfully create the UNIX group */
5848 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5849 unbecome_root();
5851 /******** END SeAddUsers BLOCK *********/
5853 /* check if we should bail out here */
5855 if ( !NT_STATUS_IS_OK(status) )
5856 return 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)) {
5862 return 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)
5878 DOM_SID info_sid;
5879 const char *name = NULL;
5880 struct samr_domain_info *dinfo;
5881 struct samr_alias_info *ainfo;
5882 gid_t gid;
5883 NTSTATUS result;
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)) {
5889 return 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)) {
5899 return result;
5902 /******** BEGIN SeAddUsers BLOCK *********/
5904 become_root();
5905 /* Have passdb create the alias */
5906 result = pdb_create_alias(name, r->out.rid);
5907 unbecome_root();
5909 /******** END SeAddUsers BLOCK *********/
5911 if (!NT_STATUS_IS_OK(result)) {
5912 DEBUG(10, ("pdb_create_alias failed: %s\n",
5913 nt_errstr(result)));
5914 return 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)) {
5935 return 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;
5952 NTSTATUS status;
5953 GROUP_MAP map;
5954 union samr_GroupInfo *info = NULL;
5955 bool ret;
5956 uint32_t attributes = SE_GROUP_MANDATORY |
5957 SE_GROUP_ENABLED_BY_DEFAULT |
5958 SE_GROUP_ENABLED;
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)) {
5966 return status;
5969 become_root();
5970 ret = get_domain_group_from_sid(ginfo->sid, &map);
5971 unbecome_root();
5972 if (!ret)
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);
5980 if (!info) {
5981 return NT_STATUS_NO_MEMORY;
5984 switch (r->in.level) {
5985 case 1: {
5986 uint32 *members;
5987 size_t num_members;
5989 become_root();
5990 status = pdb_enum_group_members(
5991 p->mem_ctx, &ginfo->sid, &members,
5992 &num_members);
5993 unbecome_root();
5995 if (!NT_STATUS_IS_OK(status)) {
5996 return 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;
6003 break;
6005 case 2:
6006 info->name.string = group_name;
6007 break;
6008 case 3:
6009 info->attributes.attributes = attributes;
6010 break;
6011 case 4:
6012 info->description.string = group_description;
6013 break;
6014 case 5: {
6016 uint32 *members;
6017 size_t num_members;
6021 become_root();
6022 status = pdb_enum_group_members(
6023 p->mem_ctx, &ginfo->sid, &members,
6024 &num_members);
6025 unbecome_root();
6027 if (!NT_STATUS_IS_OK(status)) {
6028 return 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;
6036 break;
6038 default:
6039 return NT_STATUS_INVALID_INFO_CLASS;
6042 *r->out.info = info;
6044 return NT_STATUS_OK;
6047 /*********************************************************************
6048 _samr_SetGroupInfo
6049 *********************************************************************/
6051 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
6052 struct samr_SetGroupInfo *r)
6054 struct samr_group_info *ginfo;
6055 GROUP_MAP map;
6056 NTSTATUS status;
6057 bool ret;
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)) {
6063 return status;
6066 become_root();
6067 ret = get_domain_group_from_sid(ginfo->sid, &map);
6068 unbecome_root();
6069 if (!ret)
6070 return NT_STATUS_NO_SUCH_GROUP;
6072 switch (r->in.level) {
6073 case 2:
6074 fstrcpy(map.nt_name, r->in.info->name.string);
6075 break;
6076 case 3:
6077 break;
6078 case 4:
6079 fstrcpy(map.comment, r->in.info->description.string);
6080 break;
6081 default:
6082 return NT_STATUS_INVALID_INFO_CLASS;
6085 /******** BEGIN SeAddUsers BLOCK *********/
6087 become_root();
6088 status = pdb_update_group_mapping_entry(&map);
6089 unbecome_root();
6091 /******** End SeAddUsers BLOCK *********/
6093 if (NT_STATUS_IS_OK(status)) {
6094 force_flush_samr_cache(&ginfo->sid);
6097 return status;
6100 /*********************************************************************
6101 _samr_SetAliasInfo
6102 *********************************************************************/
6104 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
6105 struct samr_SetAliasInfo *r)
6107 struct samr_alias_info *ainfo;
6108 struct acct_info info;
6109 NTSTATUS status;
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)) {
6115 return status;
6118 /* get the current group information */
6120 become_root();
6121 status = pdb_get_aliasinfo( &ainfo->sid, &info );
6122 unbecome_root();
6124 if ( !NT_STATUS_IS_OK(status))
6125 return status;
6127 switch (r->in.level) {
6128 case ALIASINFONAME:
6130 fstring group_name;
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
6155 or local group */
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 ) )
6160 return status;
6161 break;
6163 case ALIASINFODESCRIPTION:
6164 if (r->in.info->description.string) {
6165 fstrcpy(info.acct_desc,
6166 r->in.info->description.string);
6167 } else {
6168 fstrcpy( info.acct_desc, "" );
6170 break;
6171 default:
6172 return NT_STATUS_INVALID_INFO_CLASS;
6175 /******** BEGIN SeAddUsers BLOCK *********/
6177 become_root();
6178 status = pdb_set_aliasinfo( &ainfo->sid, &info );
6179 unbecome_root();
6181 /******** End SeAddUsers BLOCK *********/
6183 if (NT_STATUS_IS_OK(status))
6184 force_flush_samr_cache(&ainfo->sid);
6186 return status;
6189 /****************************************************************
6190 _samr_GetDomPwInfo
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;
6208 become_root();
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);
6213 unbecome_root();
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 /*********************************************************************
6226 _samr_OpenGroup
6227 *********************************************************************/
6229 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6230 struct samr_OpenGroup *r)
6233 DOM_SID info_sid;
6234 GROUP_MAP map;
6235 struct samr_domain_info *dinfo;
6236 struct samr_group_info *ginfo;
6237 SEC_DESC *psd = NULL;
6238 uint32 acc_granted;
6239 uint32 des_access = r->in.access_mask;
6240 size_t sd_size;
6241 NTSTATUS status;
6242 bool ret;
6243 SE_PRIV se_rights;
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)) {
6249 return 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,
6255 &des_access);
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) )
6267 return 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 */
6280 become_root();
6281 ret = get_domain_group_from_sid(info_sid, &map);
6282 unbecome_root();
6283 if (!ret)
6284 return NT_STATUS_NO_SUCH_GROUP;
6286 ginfo = policy_handle_create(p, r->out.group_handle,
6287 acc_granted,
6288 struct samr_group_info, &status);
6289 if (!NT_STATUS_IS_OK(status)) {
6290 return 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;
6305 NTSTATUS result;
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)) {
6316 return 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
6334 * other cases. */
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;
6349 return result;
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)
6398 time_t u_logout;
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 /*******************************************************************
6431 _samr_SetDomainInfo
6432 ********************************************************************/
6434 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6435 struct samr_SetDomainInfo *r)
6437 struct samr_domain_info *dinfo;
6438 NTSTATUS status;
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;
6448 break;
6449 case 3: /* DomainLogoffInformation */
6450 case 4: /* DomainOemInformation */
6451 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6452 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6453 break;
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;
6459 break;
6460 default:
6461 return NT_STATUS_INVALID_INFO_CLASS;
6464 dinfo = policy_handle_find(p, r->in.domain_handle,
6465 acc_required, NULL,
6466 struct samr_domain_info, &status);
6467 if (!NT_STATUS_IS_OK(status)) {
6468 return status;
6471 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6473 switch (r->in.level) {
6474 case 1:
6475 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6476 break;
6477 case 3:
6478 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6479 break;
6480 case 4:
6481 break;
6482 case 6:
6483 break;
6484 case 7:
6485 break;
6486 case 9:
6487 break;
6488 case 12:
6489 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6490 break;
6491 default:
6492 return NT_STATUS_INVALID_INFO_CLASS;
6495 if (!NT_STATUS_IS_OK(status)) {
6496 return 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;
6514 int i;
6515 uint32_t num_account = 0;
6516 struct samr_displayentry *entries = NULL;
6517 NTSTATUS status;
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)) {
6525 return status;
6528 if ((r->in.level < 1) || (r->in.level > 3)) {
6529 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6530 "Unknown info level (%u)\n",
6531 r->in.level));
6532 return NT_STATUS_INVALID_INFO_CLASS;
6535 become_root();
6537 /* The following done as ROOT. Don't return without unbecome_root(). */
6539 switch (r->in.level) {
6540 case 1:
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) {
6545 unbecome_root();
6546 return NT_STATUS_ACCESS_DENIED;
6548 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6549 "starting user enumeration at index %u\n",
6550 (unsigned int)enum_context));
6551 } else {
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,
6558 &entries);
6559 break;
6560 case 2:
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) {
6565 unbecome_root();
6566 return NT_STATUS_ACCESS_DENIED;
6568 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6569 "starting machine enumeration at index %u\n",
6570 (unsigned int)enum_context));
6571 } else {
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,
6578 &entries);
6579 break;
6580 case 3:
6581 if (dinfo->disp_info->groups == NULL) {
6582 dinfo->disp_info->groups = pdb_search_groups(
6583 dinfo->disp_info);
6584 if (dinfo->disp_info->groups == NULL) {
6585 unbecome_root();
6586 return NT_STATUS_ACCESS_DENIED;
6588 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6589 "starting group enumeration at index %u\n",
6590 (unsigned int)enum_context));
6591 } else {
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,
6598 &entries);
6599 break;
6600 default:
6601 unbecome_root();
6602 smb_panic("info class changed");
6603 break;
6606 unbecome_root();
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));
6619 *r->out.idx = 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 /****************************************************************
6649 _samr_RidToSid
6650 ****************************************************************/
6652 NTSTATUS _samr_RidToSid(pipes_struct *p,
6653 struct samr_RidToSid *r)
6655 struct samr_domain_info *dinfo;
6656 NTSTATUS status;
6657 struct dom_sid sid;
6659 dinfo = policy_handle_find(p, r->in.domain_handle,
6660 0, NULL,
6661 struct samr_domain_info, &status);
6662 if (!NT_STATUS_IS_OK(status)) {
6663 return 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);
6671 if (!*r->out.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;