s4:minschema/fullschema - add correct header comments
[Samba/aatanasov.git] / source3 / rpc_server / srv_samr_nt.c
blob9e95c480330e2bbfc579b38b84c2875fb368e53b
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 uint32 reject_reason;
2027 struct samr_DomInfo1 *dominfo = NULL;
2028 struct samr_ChangeReject *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, struct samr_ChangeReject);
2074 if (!reject) {
2075 return NT_STATUS_NO_MEMORY;
2078 become_root();
2080 /* AS ROOT !!! */
2082 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2083 dominfo->min_password_length = tmp;
2085 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2086 dominfo->password_history_length = tmp;
2088 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2089 &dominfo->password_properties);
2091 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2092 u_expire = account_policy_temp;
2094 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2095 u_min_age = account_policy_temp;
2097 /* !AS ROOT */
2099 unbecome_root();
2101 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2102 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2104 if (lp_check_password_script() && *lp_check_password_script()) {
2105 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2108 reject->reason = reject_reason;
2110 *r->out.dominfo = dominfo;
2111 *r->out.reject = reject;
2114 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2116 return status;
2119 /*******************************************************************
2120 makes a SAMR_R_LOOKUP_RIDS structure.
2121 ********************************************************************/
2123 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2124 const char **names,
2125 struct lsa_String **lsa_name_array_p)
2127 struct lsa_String *lsa_name_array = NULL;
2128 uint32_t i;
2130 *lsa_name_array_p = NULL;
2132 if (num_names != 0) {
2133 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2134 if (!lsa_name_array) {
2135 return false;
2139 for (i = 0; i < num_names; i++) {
2140 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2141 init_lsa_String(&lsa_name_array[i], names[i]);
2144 *lsa_name_array_p = lsa_name_array;
2146 return true;
2149 /*******************************************************************
2150 _samr_LookupRids
2151 ********************************************************************/
2153 NTSTATUS _samr_LookupRids(pipes_struct *p,
2154 struct samr_LookupRids *r)
2156 struct samr_domain_info *dinfo;
2157 NTSTATUS status;
2158 const char **names;
2159 enum lsa_SidType *attrs = NULL;
2160 uint32 *wire_attrs = NULL;
2161 int num_rids = (int)r->in.num_rids;
2162 int i;
2163 struct lsa_Strings names_array;
2164 struct samr_Ids types_array;
2165 struct lsa_String *lsa_names = NULL;
2167 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2169 dinfo = policy_handle_find(p, r->in.domain_handle,
2170 0 /* Don't know the acc_bits yet */, NULL,
2171 struct samr_domain_info, &status);
2172 if (!NT_STATUS_IS_OK(status)) {
2173 return status;
2176 if (num_rids > 1000) {
2177 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2178 "to samba4 idl this is not possible\n", num_rids));
2179 return NT_STATUS_UNSUCCESSFUL;
2182 if (num_rids) {
2183 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2184 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2185 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2187 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2188 return NT_STATUS_NO_MEMORY;
2189 } else {
2190 names = NULL;
2191 attrs = NULL;
2192 wire_attrs = NULL;
2195 become_root(); /* lookup_sid can require root privs */
2196 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2197 names, attrs);
2198 unbecome_root();
2200 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2201 status = NT_STATUS_OK;
2204 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2205 &lsa_names)) {
2206 return NT_STATUS_NO_MEMORY;
2209 /* Convert from enum lsa_SidType to uint32 for wire format. */
2210 for (i = 0; i < num_rids; i++) {
2211 wire_attrs[i] = (uint32)attrs[i];
2214 names_array.count = num_rids;
2215 names_array.names = lsa_names;
2217 types_array.count = num_rids;
2218 types_array.ids = wire_attrs;
2220 *r->out.names = names_array;
2221 *r->out.types = types_array;
2223 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2225 return status;
2228 /*******************************************************************
2229 _samr_OpenUser
2230 ********************************************************************/
2232 NTSTATUS _samr_OpenUser(pipes_struct *p,
2233 struct samr_OpenUser *r)
2235 struct samu *sampass=NULL;
2236 DOM_SID sid;
2237 struct samr_domain_info *dinfo;
2238 struct samr_user_info *uinfo;
2239 SEC_DESC *psd = NULL;
2240 uint32 acc_granted;
2241 uint32 des_access = r->in.access_mask;
2242 uint32_t extra_access = 0;
2243 size_t sd_size;
2244 bool ret;
2245 NTSTATUS nt_status;
2246 SE_PRIV se_rights;
2247 NTSTATUS status;
2249 dinfo = policy_handle_find(p, r->in.domain_handle,
2250 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2251 struct samr_domain_info, &status);
2252 if (!NT_STATUS_IS_OK(status)) {
2253 return status;
2256 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2257 return NT_STATUS_NO_MEMORY;
2260 /* append the user's RID to it */
2262 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2263 return NT_STATUS_NO_SUCH_USER;
2265 /* check if access can be granted as requested by client. */
2266 map_max_allowed_access(p->server_info->ptok,
2267 &p->server_info->utok,
2268 &des_access);
2270 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2271 se_map_generic(&des_access, &usr_generic_mapping);
2274 * Get the sampass first as we need to check privilages
2275 * based on what kind of user object this is.
2276 * But don't reveal info too early if it didn't exist.
2279 become_root();
2280 ret=pdb_getsampwsid(sampass, &sid);
2281 unbecome_root();
2283 se_priv_copy(&se_rights, &se_priv_none);
2286 * We do the override access checks on *open*, not at
2287 * SetUserInfo time.
2289 if (ret) {
2290 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2292 if ((acb_info & ACB_WSTRUST) &&
2293 user_has_any_privilege(p->server_info->ptok,
2294 &se_machine_account)) {
2296 * SeMachineAccount is needed to add
2297 * GENERIC_RIGHTS_USER_WRITE to a machine
2298 * account.
2300 se_priv_add(&se_rights, &se_machine_account);
2301 DEBUG(10,("_samr_OpenUser: adding machine account "
2302 "rights to handle for user %s\n",
2303 pdb_get_username(sampass) ));
2305 if ((acb_info & ACB_NORMAL) &&
2306 user_has_any_privilege(p->server_info->ptok,
2307 &se_add_users)) {
2309 * SeAddUsers is needed to add
2310 * GENERIC_RIGHTS_USER_WRITE to a normal
2311 * account.
2313 se_priv_add(&se_rights, &se_add_users);
2314 DEBUG(10,("_samr_OpenUser: adding add user "
2315 "rights to handle for user %s\n",
2316 pdb_get_username(sampass) ));
2319 * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
2320 * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not
2321 * what Windows does but is a hack for people who haven't
2322 * set up privilages on groups in Samba.
2324 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2325 if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2326 DOMAIN_GROUP_RID_ADMINS)) {
2327 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2328 extra_access = GENERIC_RIGHTS_USER_WRITE;
2329 DEBUG(4,("_samr_OpenUser: Allowing "
2330 "GENERIC_RIGHTS_USER_WRITE for "
2331 "rid admins\n"));
2336 TALLOC_FREE(sampass);
2338 nt_status = access_check_object(psd, p->server_info->ptok,
2339 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2340 &acc_granted, "_samr_OpenUser");
2342 if ( !NT_STATUS_IS_OK(nt_status) )
2343 return nt_status;
2345 /* check that the SID exists in our domain. */
2346 if (ret == False) {
2347 return NT_STATUS_NO_SUCH_USER;
2350 /* If we did the rid admins hack above, allow access. */
2351 acc_granted |= extra_access;
2353 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2354 struct samr_user_info, &nt_status);
2355 if (!NT_STATUS_IS_OK(nt_status)) {
2356 return nt_status;
2358 uinfo->sid = sid;
2360 return NT_STATUS_OK;
2363 /*************************************************************************
2364 *************************************************************************/
2366 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2367 DATA_BLOB *blob,
2368 struct lsa_BinaryString **_r)
2370 struct lsa_BinaryString *r;
2372 if (!blob || !_r) {
2373 return NT_STATUS_INVALID_PARAMETER;
2376 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2377 if (!r) {
2378 return NT_STATUS_NO_MEMORY;
2381 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2382 if (!r->array) {
2383 return NT_STATUS_NO_MEMORY;
2385 memcpy(r->array, blob->data, blob->length);
2386 r->size = blob->length;
2387 r->length = blob->length;
2389 if (!r->array) {
2390 return NT_STATUS_NO_MEMORY;
2393 *_r = r;
2395 return NT_STATUS_OK;
2398 /*************************************************************************
2399 get_user_info_1.
2400 *************************************************************************/
2402 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2403 struct samr_UserInfo1 *r,
2404 struct samu *pw,
2405 DOM_SID *domain_sid)
2407 const DOM_SID *sid_group;
2408 uint32_t primary_gid;
2410 become_root();
2411 sid_group = pdb_get_group_sid(pw);
2412 unbecome_root();
2414 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2415 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2416 "which conflicts with the domain sid %s. Failing operation.\n",
2417 pdb_get_username(pw), sid_string_dbg(sid_group),
2418 sid_string_dbg(domain_sid)));
2419 return NT_STATUS_UNSUCCESSFUL;
2422 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2423 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2424 r->primary_gid = primary_gid;
2425 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2426 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2428 return NT_STATUS_OK;
2431 /*************************************************************************
2432 get_user_info_2.
2433 *************************************************************************/
2435 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2436 struct samr_UserInfo2 *r,
2437 struct samu *pw)
2439 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2440 r->unknown.string = NULL;
2441 r->country_code = 0;
2442 r->code_page = 0;
2444 return NT_STATUS_OK;
2447 /*************************************************************************
2448 get_user_info_3.
2449 *************************************************************************/
2451 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2452 struct samr_UserInfo3 *r,
2453 struct samu *pw,
2454 DOM_SID *domain_sid)
2456 const DOM_SID *sid_user, *sid_group;
2457 uint32_t rid, primary_gid;
2459 sid_user = pdb_get_user_sid(pw);
2461 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2462 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2463 "the domain sid %s. Failing operation.\n",
2464 pdb_get_username(pw), sid_string_dbg(sid_user),
2465 sid_string_dbg(domain_sid)));
2466 return NT_STATUS_UNSUCCESSFUL;
2469 become_root();
2470 sid_group = pdb_get_group_sid(pw);
2471 unbecome_root();
2473 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2474 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2475 "which conflicts with the domain sid %s. Failing operation.\n",
2476 pdb_get_username(pw), sid_string_dbg(sid_group),
2477 sid_string_dbg(domain_sid)));
2478 return NT_STATUS_UNSUCCESSFUL;
2481 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2482 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2483 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2484 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2485 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2487 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2488 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2489 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2490 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2491 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2492 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2493 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2495 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2496 r->rid = rid;
2497 r->primary_gid = primary_gid;
2498 r->acct_flags = pdb_get_acct_ctrl(pw);
2499 r->bad_password_count = pdb_get_bad_password_count(pw);
2500 r->logon_count = pdb_get_logon_count(pw);
2502 return NT_STATUS_OK;
2505 /*************************************************************************
2506 get_user_info_4.
2507 *************************************************************************/
2509 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2510 struct samr_UserInfo4 *r,
2511 struct samu *pw)
2513 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2515 return NT_STATUS_OK;
2518 /*************************************************************************
2519 get_user_info_5.
2520 *************************************************************************/
2522 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2523 struct samr_UserInfo5 *r,
2524 struct samu *pw,
2525 DOM_SID *domain_sid)
2527 const DOM_SID *sid_user, *sid_group;
2528 uint32_t rid, primary_gid;
2530 sid_user = pdb_get_user_sid(pw);
2532 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2533 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2534 "the domain sid %s. Failing operation.\n",
2535 pdb_get_username(pw), sid_string_dbg(sid_user),
2536 sid_string_dbg(domain_sid)));
2537 return NT_STATUS_UNSUCCESSFUL;
2540 become_root();
2541 sid_group = pdb_get_group_sid(pw);
2542 unbecome_root();
2544 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2545 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2546 "which conflicts with the domain sid %s. Failing operation.\n",
2547 pdb_get_username(pw), sid_string_dbg(sid_group),
2548 sid_string_dbg(domain_sid)));
2549 return NT_STATUS_UNSUCCESSFUL;
2552 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2553 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2554 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2555 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2557 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2558 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2559 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2560 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2561 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2562 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2563 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2564 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2566 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2567 r->rid = rid;
2568 r->primary_gid = primary_gid;
2569 r->acct_flags = pdb_get_acct_ctrl(pw);
2570 r->bad_password_count = pdb_get_bad_password_count(pw);
2571 r->logon_count = pdb_get_logon_count(pw);
2573 return NT_STATUS_OK;
2576 /*************************************************************************
2577 get_user_info_6.
2578 *************************************************************************/
2580 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2581 struct samr_UserInfo6 *r,
2582 struct samu *pw)
2584 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2585 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2587 return NT_STATUS_OK;
2590 /*************************************************************************
2591 get_user_info_7. Safe. Only gives out account_name.
2592 *************************************************************************/
2594 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2595 struct samr_UserInfo7 *r,
2596 struct samu *smbpass)
2598 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2599 if (!r->account_name.string) {
2600 return NT_STATUS_NO_MEMORY;
2603 return NT_STATUS_OK;
2606 /*************************************************************************
2607 get_user_info_8.
2608 *************************************************************************/
2610 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2611 struct samr_UserInfo8 *r,
2612 struct samu *pw)
2614 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2616 return NT_STATUS_OK;
2619 /*************************************************************************
2620 get_user_info_9. Only gives out primary group SID.
2621 *************************************************************************/
2623 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2624 struct samr_UserInfo9 *r,
2625 struct samu *smbpass)
2627 r->primary_gid = pdb_get_group_rid(smbpass);
2629 return NT_STATUS_OK;
2632 /*************************************************************************
2633 get_user_info_10.
2634 *************************************************************************/
2636 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2637 struct samr_UserInfo10 *r,
2638 struct samu *pw)
2640 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2641 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2643 return NT_STATUS_OK;
2646 /*************************************************************************
2647 get_user_info_11.
2648 *************************************************************************/
2650 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2651 struct samr_UserInfo11 *r,
2652 struct samu *pw)
2654 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2656 return NT_STATUS_OK;
2659 /*************************************************************************
2660 get_user_info_12.
2661 *************************************************************************/
2663 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2664 struct samr_UserInfo12 *r,
2665 struct samu *pw)
2667 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2669 return NT_STATUS_OK;
2672 /*************************************************************************
2673 get_user_info_13.
2674 *************************************************************************/
2676 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2677 struct samr_UserInfo13 *r,
2678 struct samu *pw)
2680 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2682 return NT_STATUS_OK;
2685 /*************************************************************************
2686 get_user_info_14.
2687 *************************************************************************/
2689 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2690 struct samr_UserInfo14 *r,
2691 struct samu *pw)
2693 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2695 return NT_STATUS_OK;
2698 /*************************************************************************
2699 get_user_info_16. Safe. Only gives out acb bits.
2700 *************************************************************************/
2702 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2703 struct samr_UserInfo16 *r,
2704 struct samu *smbpass)
2706 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2708 return NT_STATUS_OK;
2711 /*************************************************************************
2712 get_user_info_17.
2713 *************************************************************************/
2715 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2716 struct samr_UserInfo17 *r,
2717 struct samu *pw)
2719 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2721 return NT_STATUS_OK;
2724 /*************************************************************************
2725 get_user_info_18. OK - this is the killer as it gives out password info.
2726 Ensure that this is only allowed on an encrypted connection with a root
2727 user. JRA.
2728 *************************************************************************/
2730 static NTSTATUS get_user_info_18(pipes_struct *p,
2731 TALLOC_CTX *mem_ctx,
2732 struct samr_UserInfo18 *r,
2733 DOM_SID *user_sid)
2735 struct samu *smbpass=NULL;
2736 bool ret;
2738 ZERO_STRUCTP(r);
2740 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2741 return NT_STATUS_ACCESS_DENIED;
2744 if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2745 return NT_STATUS_ACCESS_DENIED;
2749 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2752 if ( !(smbpass = samu_new( mem_ctx )) ) {
2753 return NT_STATUS_NO_MEMORY;
2756 ret = pdb_getsampwsid(smbpass, user_sid);
2758 if (ret == False) {
2759 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2760 TALLOC_FREE(smbpass);
2761 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2764 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2766 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2767 TALLOC_FREE(smbpass);
2768 return NT_STATUS_ACCOUNT_DISABLED;
2771 r->lm_pwd_active = true;
2772 r->nt_pwd_active = true;
2773 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2774 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2775 r->password_expired = 0; /* FIXME */
2777 TALLOC_FREE(smbpass);
2779 return NT_STATUS_OK;
2782 /*************************************************************************
2783 get_user_info_20
2784 *************************************************************************/
2786 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2787 struct samr_UserInfo20 *r,
2788 struct samu *sampass)
2790 const char *munged_dial = NULL;
2791 DATA_BLOB blob;
2792 NTSTATUS status;
2793 struct lsa_BinaryString *parameters = NULL;
2795 ZERO_STRUCTP(r);
2797 munged_dial = pdb_get_munged_dial(sampass);
2799 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2800 munged_dial, (int)strlen(munged_dial)));
2802 if (munged_dial) {
2803 blob = base64_decode_data_blob(munged_dial);
2804 } else {
2805 blob = data_blob_string_const_null("");
2808 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2809 data_blob_free(&blob);
2810 if (!NT_STATUS_IS_OK(status)) {
2811 return status;
2814 r->parameters = *parameters;
2816 return NT_STATUS_OK;
2820 /*************************************************************************
2821 get_user_info_21
2822 *************************************************************************/
2824 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2825 struct samr_UserInfo21 *r,
2826 struct samu *pw,
2827 DOM_SID *domain_sid,
2828 uint32_t acc_granted)
2830 NTSTATUS status;
2831 const DOM_SID *sid_user, *sid_group;
2832 uint32_t rid, primary_gid;
2833 NTTIME force_password_change;
2834 time_t must_change_time;
2835 struct lsa_BinaryString *parameters = NULL;
2836 const char *munged_dial = NULL;
2837 DATA_BLOB blob;
2839 ZERO_STRUCTP(r);
2841 sid_user = pdb_get_user_sid(pw);
2843 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2844 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2845 "the domain sid %s. Failing operation.\n",
2846 pdb_get_username(pw), sid_string_dbg(sid_user),
2847 sid_string_dbg(domain_sid)));
2848 return NT_STATUS_UNSUCCESSFUL;
2851 become_root();
2852 sid_group = pdb_get_group_sid(pw);
2853 unbecome_root();
2855 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2856 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2857 "which conflicts with the domain sid %s. Failing operation.\n",
2858 pdb_get_username(pw), sid_string_dbg(sid_group),
2859 sid_string_dbg(domain_sid)));
2860 return NT_STATUS_UNSUCCESSFUL;
2863 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2864 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2865 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2866 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2867 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2869 must_change_time = pdb_get_pass_must_change_time(pw);
2870 if (must_change_time == get_time_t_max()) {
2871 unix_to_nt_time_abs(&force_password_change, must_change_time);
2872 } else {
2873 unix_to_nt_time(&force_password_change, must_change_time);
2876 munged_dial = pdb_get_munged_dial(pw);
2877 if (munged_dial) {
2878 blob = base64_decode_data_blob(munged_dial);
2879 } else {
2880 blob = data_blob_string_const_null("");
2883 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2884 data_blob_free(&blob);
2885 if (!NT_STATUS_IS_OK(status)) {
2886 return status;
2889 r->force_password_change = force_password_change;
2891 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2892 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2893 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2894 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2895 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2896 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2897 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2898 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2899 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2901 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2902 r->parameters = *parameters;
2903 r->rid = rid;
2904 r->primary_gid = primary_gid;
2905 r->acct_flags = pdb_get_acct_ctrl(pw);
2906 r->bad_password_count = pdb_get_bad_password_count(pw);
2907 r->logon_count = pdb_get_logon_count(pw);
2908 r->fields_present = pdb_build_fields_present(pw);
2909 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2910 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2911 r->country_code = 0;
2912 r->code_page = 0;
2913 r->lm_password_set = 0;
2914 r->nt_password_set = 0;
2916 #if 0
2919 Look at a user on a real NT4 PDC with usrmgr, press
2920 'ok'. Then you will see that fields_present is set to
2921 0x08f827fa. Look at the user immediately after that again,
2922 and you will see that 0x00fffff is returned. This solves
2923 the problem that you get access denied after having looked
2924 at the user.
2925 -- Volker
2928 #endif
2931 return NT_STATUS_OK;
2934 /*******************************************************************
2935 _samr_QueryUserInfo
2936 ********************************************************************/
2938 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2939 struct samr_QueryUserInfo *r)
2941 NTSTATUS status;
2942 union samr_UserInfo *user_info = NULL;
2943 struct samr_user_info *uinfo;
2944 DOM_SID domain_sid;
2945 uint32 rid;
2946 bool ret = false;
2947 struct samu *pwd = NULL;
2948 uint32_t acc_required, acc_granted;
2950 switch (r->in.level) {
2951 case 1: /* UserGeneralInformation */
2952 /* USER_READ_GENERAL */
2953 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2954 break;
2955 case 2: /* UserPreferencesInformation */
2956 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2957 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2958 SAMR_USER_ACCESS_GET_NAME_ETC;
2959 break;
2960 case 3: /* UserLogonInformation */
2961 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2962 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2963 SAMR_USER_ACCESS_GET_LOCALE |
2964 SAMR_USER_ACCESS_GET_LOGONINFO |
2965 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2966 break;
2967 case 4: /* UserLogonHoursInformation */
2968 /* USER_READ_LOGON */
2969 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2970 break;
2971 case 5: /* UserAccountInformation */
2972 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2973 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2974 SAMR_USER_ACCESS_GET_LOCALE |
2975 SAMR_USER_ACCESS_GET_LOGONINFO |
2976 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2977 break;
2978 case 6: /* UserNameInformation */
2979 case 7: /* UserAccountNameInformation */
2980 case 8: /* UserFullNameInformation */
2981 case 9: /* UserPrimaryGroupInformation */
2982 case 13: /* UserAdminCommentInformation */
2983 /* USER_READ_GENERAL */
2984 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2985 break;
2986 case 10: /* UserHomeInformation */
2987 case 11: /* UserScriptInformation */
2988 case 12: /* UserProfileInformation */
2989 case 14: /* UserWorkStationsInformation */
2990 /* USER_READ_LOGON */
2991 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2992 break;
2993 case 16: /* UserControlInformation */
2994 case 17: /* UserExpiresInformation */
2995 case 20: /* UserParametersInformation */
2996 /* USER_READ_ACCOUNT */
2997 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2998 break;
2999 case 21: /* UserAllInformation */
3000 /* FIXME! - gd */
3001 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3002 break;
3003 case 18: /* UserInternal1Information */
3004 /* FIXME! - gd */
3005 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3006 break;
3007 case 23: /* UserInternal4Information */
3008 case 24: /* UserInternal4InformationNew */
3009 case 25: /* UserInternal4InformationNew */
3010 case 26: /* UserInternal5InformationNew */
3011 default:
3012 return NT_STATUS_INVALID_INFO_CLASS;
3013 break;
3016 uinfo = policy_handle_find(p, r->in.user_handle,
3017 acc_required, &acc_granted,
3018 struct samr_user_info, &status);
3019 if (!NT_STATUS_IS_OK(status)) {
3020 return status;
3023 domain_sid = uinfo->sid;
3025 sid_split_rid(&domain_sid, &rid);
3027 if (!sid_check_is_in_our_domain(&uinfo->sid))
3028 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3030 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3031 sid_string_dbg(&uinfo->sid)));
3033 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3034 if (!user_info) {
3035 return NT_STATUS_NO_MEMORY;
3038 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3040 if (!(pwd = samu_new(p->mem_ctx))) {
3041 return NT_STATUS_NO_MEMORY;
3044 become_root();
3045 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3046 unbecome_root();
3048 if (ret == false) {
3049 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3050 TALLOC_FREE(pwd);
3051 return NT_STATUS_NO_SUCH_USER;
3054 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3056 samr_clear_sam_passwd(pwd);
3058 switch (r->in.level) {
3059 case 1:
3060 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3061 break;
3062 case 2:
3063 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3064 break;
3065 case 3:
3066 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3067 break;
3068 case 4:
3069 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3070 break;
3071 case 5:
3072 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3073 break;
3074 case 6:
3075 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3076 break;
3077 case 7:
3078 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3079 break;
3080 case 8:
3081 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3082 break;
3083 case 9:
3084 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3085 break;
3086 case 10:
3087 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3088 break;
3089 case 11:
3090 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3091 break;
3092 case 12:
3093 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3094 break;
3095 case 13:
3096 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3097 break;
3098 case 14:
3099 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3100 break;
3101 case 16:
3102 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3103 break;
3104 case 17:
3105 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3106 break;
3107 case 18:
3108 /* level 18 is special */
3109 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3110 &uinfo->sid);
3111 break;
3112 case 20:
3113 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3114 break;
3115 case 21:
3116 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3117 break;
3118 default:
3119 status = NT_STATUS_INVALID_INFO_CLASS;
3120 break;
3123 if (!NT_STATUS_IS_OK(status)) {
3124 goto done;
3127 *r->out.info = user_info;
3129 done:
3130 TALLOC_FREE(pwd);
3132 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3134 return status;
3137 /****************************************************************
3138 ****************************************************************/
3140 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3141 struct samr_QueryUserInfo2 *r)
3143 struct samr_QueryUserInfo u;
3145 u.in.user_handle = r->in.user_handle;
3146 u.in.level = r->in.level;
3147 u.out.info = r->out.info;
3149 return _samr_QueryUserInfo(p, &u);
3152 /*******************************************************************
3153 _samr_GetGroupsForUser
3154 ********************************************************************/
3156 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3157 struct samr_GetGroupsForUser *r)
3159 struct samr_user_info *uinfo;
3160 struct samu *sam_pass=NULL;
3161 DOM_SID *sids;
3162 struct samr_RidWithAttribute dom_gid;
3163 struct samr_RidWithAttribute *gids = NULL;
3164 uint32 primary_group_rid;
3165 size_t num_groups = 0;
3166 gid_t *unix_gids;
3167 size_t i, num_gids;
3168 bool ret;
3169 NTSTATUS result;
3170 bool success = False;
3172 struct samr_RidWithAttributeArray *rids = NULL;
3175 * from the SID in the request:
3176 * we should send back the list of DOMAIN GROUPS
3177 * the user is a member of
3179 * and only the DOMAIN GROUPS
3180 * no ALIASES !!! neither aliases of the domain
3181 * nor aliases of the builtin SID
3183 * JFM, 12/2/2001
3186 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3188 uinfo = policy_handle_find(p, r->in.user_handle,
3189 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3190 struct samr_user_info, &result);
3191 if (!NT_STATUS_IS_OK(result)) {
3192 return result;
3195 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3196 if (!rids) {
3197 return NT_STATUS_NO_MEMORY;
3200 if (!sid_check_is_in_our_domain(&uinfo->sid))
3201 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3203 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3204 return NT_STATUS_NO_MEMORY;
3207 become_root();
3208 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3209 unbecome_root();
3211 if (!ret) {
3212 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3213 sid_string_dbg(&uinfo->sid)));
3214 return NT_STATUS_NO_SUCH_USER;
3217 sids = NULL;
3219 /* make both calls inside the root block */
3220 become_root();
3221 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3222 &sids, &unix_gids, &num_groups);
3223 if ( NT_STATUS_IS_OK(result) ) {
3224 success = sid_peek_check_rid(get_global_sam_sid(),
3225 pdb_get_group_sid(sam_pass),
3226 &primary_group_rid);
3228 unbecome_root();
3230 if (!NT_STATUS_IS_OK(result)) {
3231 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3232 sid_string_dbg(&uinfo->sid)));
3233 return result;
3236 if ( !success ) {
3237 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3238 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3239 pdb_get_username(sam_pass)));
3240 TALLOC_FREE(sam_pass);
3241 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3244 gids = NULL;
3245 num_gids = 0;
3247 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3248 SE_GROUP_ENABLED);
3249 dom_gid.rid = primary_group_rid;
3250 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3252 for (i=0; i<num_groups; i++) {
3254 if (!sid_peek_check_rid(get_global_sam_sid(),
3255 &(sids[i]), &dom_gid.rid)) {
3256 DEBUG(10, ("Found sid %s not in our domain\n",
3257 sid_string_dbg(&sids[i])));
3258 continue;
3261 if (dom_gid.rid == primary_group_rid) {
3262 /* We added the primary group directly from the
3263 * sam_account. The other SIDs are unique from
3264 * enum_group_memberships */
3265 continue;
3268 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3271 rids->count = num_gids;
3272 rids->rids = gids;
3274 *r->out.rids = rids;
3276 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3278 return result;
3281 /*******************************************************************
3282 ********************************************************************/
3284 static uint32_t samr_get_server_role(void)
3286 uint32_t role = ROLE_DOMAIN_PDC;
3288 if (lp_server_role() == ROLE_DOMAIN_BDC) {
3289 role = ROLE_DOMAIN_BDC;
3292 return role;
3295 /*******************************************************************
3296 ********************************************************************/
3298 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3299 struct samr_DomInfo1 *r)
3301 uint32_t account_policy_temp;
3302 time_t u_expire, u_min_age;
3304 become_root();
3306 /* AS ROOT !!! */
3308 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3309 r->min_password_length = account_policy_temp;
3311 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3312 r->password_history_length = account_policy_temp;
3314 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3315 &r->password_properties);
3317 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3318 u_expire = account_policy_temp;
3320 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3321 u_min_age = account_policy_temp;
3323 /* !AS ROOT */
3325 unbecome_root();
3327 unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3328 unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3330 if (lp_check_password_script() && *lp_check_password_script()) {
3331 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3334 return NT_STATUS_OK;
3337 /*******************************************************************
3338 ********************************************************************/
3340 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3341 struct samr_DomGeneralInformation *r,
3342 struct samr_domain_info *dinfo)
3344 uint32_t u_logout;
3345 time_t seq_num;
3347 become_root();
3349 /* AS ROOT !!! */
3351 r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3352 r->num_groups = count_sam_groups(dinfo->disp_info);
3353 r->num_aliases = count_sam_aliases(dinfo->disp_info);
3355 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3357 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3359 if (!pdb_get_seq_num(&seq_num)) {
3360 seq_num = time(NULL);
3363 /* !AS ROOT */
3365 unbecome_root();
3367 r->oem_information.string = lp_serverstring();
3368 r->domain_name.string = lp_workgroup();
3369 r->primary.string = global_myname();
3370 r->sequence_num = seq_num;
3371 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3372 r->role = samr_get_server_role();
3373 r->unknown3 = 1;
3375 return NT_STATUS_OK;
3378 /*******************************************************************
3379 ********************************************************************/
3381 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3382 struct samr_DomInfo3 *r)
3384 uint32_t u_logout;
3386 become_root();
3388 /* AS ROOT !!! */
3391 uint32_t ul;
3392 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3393 u_logout = (time_t)ul;
3396 /* !AS ROOT */
3398 unbecome_root();
3400 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3402 return NT_STATUS_OK;
3405 /*******************************************************************
3406 ********************************************************************/
3408 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3409 struct samr_DomOEMInformation *r)
3411 r->oem_information.string = lp_serverstring();
3413 return NT_STATUS_OK;
3416 /*******************************************************************
3417 ********************************************************************/
3419 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3420 struct samr_DomInfo5 *r)
3422 r->domain_name.string = get_global_sam_name();
3424 return NT_STATUS_OK;
3427 /*******************************************************************
3428 ********************************************************************/
3430 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3431 struct samr_DomInfo6 *r)
3433 /* NT returns its own name when a PDC. win2k and later
3434 * only the name of the PDC if itself is a BDC (samba4
3435 * idl) */
3436 r->primary.string = global_myname();
3438 return NT_STATUS_OK;
3441 /*******************************************************************
3442 ********************************************************************/
3444 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3445 struct samr_DomInfo7 *r)
3447 r->role = samr_get_server_role();
3449 return NT_STATUS_OK;
3452 /*******************************************************************
3453 ********************************************************************/
3455 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3456 struct samr_DomInfo8 *r)
3458 time_t seq_num;
3460 become_root();
3462 /* AS ROOT !!! */
3464 if (!pdb_get_seq_num(&seq_num)) {
3465 seq_num = time(NULL);
3468 /* !AS ROOT */
3470 unbecome_root();
3472 r->sequence_num = seq_num;
3473 r->domain_create_time = 0;
3475 return NT_STATUS_OK;
3478 /*******************************************************************
3479 ********************************************************************/
3481 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3482 struct samr_DomInfo9 *r)
3484 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3486 return NT_STATUS_OK;
3489 /*******************************************************************
3490 ********************************************************************/
3492 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3493 struct samr_DomGeneralInformation2 *r,
3494 struct samr_domain_info *dinfo)
3496 NTSTATUS status;
3497 uint32_t account_policy_temp;
3498 time_t u_lock_duration, u_reset_time;
3500 status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3501 if (!NT_STATUS_IS_OK(status)) {
3502 return status;
3505 /* AS ROOT !!! */
3507 become_root();
3509 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3510 u_lock_duration = account_policy_temp;
3511 if (u_lock_duration != -1) {
3512 u_lock_duration *= 60;
3515 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3516 u_reset_time = account_policy_temp * 60;
3518 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3519 r->lockout_threshold = account_policy_temp;
3521 /* !AS ROOT */
3523 unbecome_root();
3525 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3526 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3528 return NT_STATUS_OK;
3531 /*******************************************************************
3532 ********************************************************************/
3534 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3535 struct samr_DomInfo12 *r)
3537 uint32_t account_policy_temp;
3538 time_t u_lock_duration, u_reset_time;
3540 become_root();
3542 /* AS ROOT !!! */
3544 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3545 u_lock_duration = account_policy_temp;
3546 if (u_lock_duration != -1) {
3547 u_lock_duration *= 60;
3550 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3551 u_reset_time = account_policy_temp * 60;
3553 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3554 r->lockout_threshold = account_policy_temp;
3556 /* !AS ROOT */
3558 unbecome_root();
3560 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3561 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3563 return NT_STATUS_OK;
3566 /*******************************************************************
3567 ********************************************************************/
3569 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3570 struct samr_DomInfo13 *r)
3572 time_t seq_num;
3574 become_root();
3576 /* AS ROOT !!! */
3578 if (!pdb_get_seq_num(&seq_num)) {
3579 seq_num = time(NULL);
3582 /* !AS ROOT */
3584 unbecome_root();
3586 r->sequence_num = seq_num;
3587 r->domain_create_time = 0;
3588 r->modified_count_at_last_promotion = 0;
3590 return NT_STATUS_OK;
3593 /*******************************************************************
3594 _samr_QueryDomainInfo
3595 ********************************************************************/
3597 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3598 struct samr_QueryDomainInfo *r)
3600 NTSTATUS status = NT_STATUS_OK;
3601 struct samr_domain_info *dinfo;
3602 union samr_DomainInfo *dom_info;
3604 uint32_t acc_required;
3606 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3608 switch (r->in.level) {
3609 case 1: /* DomainPasswordInformation */
3610 case 12: /* DomainLockoutInformation */
3611 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3612 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3613 break;
3614 case 11: /* DomainGeneralInformation2 */
3615 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3616 * DOMAIN_READ_OTHER_PARAMETERS */
3617 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3618 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3619 break;
3620 case 2: /* DomainGeneralInformation */
3621 case 3: /* DomainLogoffInformation */
3622 case 4: /* DomainOemInformation */
3623 case 5: /* DomainReplicationInformation */
3624 case 6: /* DomainReplicationInformation */
3625 case 7: /* DomainServerRoleInformation */
3626 case 8: /* DomainModifiedInformation */
3627 case 9: /* DomainStateInformation */
3628 case 10: /* DomainUasInformation */
3629 case 13: /* DomainModifiedInformation2 */
3630 /* DOMAIN_READ_OTHER_PARAMETERS */
3631 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3632 break;
3633 default:
3634 return NT_STATUS_INVALID_INFO_CLASS;
3637 dinfo = policy_handle_find(p, r->in.domain_handle,
3638 acc_required, NULL,
3639 struct samr_domain_info, &status);
3640 if (!NT_STATUS_IS_OK(status)) {
3641 return status;
3644 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3645 if (!dom_info) {
3646 return NT_STATUS_NO_MEMORY;
3649 switch (r->in.level) {
3650 case 1:
3651 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3652 break;
3653 case 2:
3654 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3655 break;
3656 case 3:
3657 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3658 break;
3659 case 4:
3660 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3661 break;
3662 case 5:
3663 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3664 break;
3665 case 6:
3666 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3667 break;
3668 case 7:
3669 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3670 break;
3671 case 8:
3672 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3673 break;
3674 case 9:
3675 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3676 break;
3677 case 11:
3678 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3679 break;
3680 case 12:
3681 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3682 break;
3683 case 13:
3684 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3685 break;
3686 default:
3687 return NT_STATUS_INVALID_INFO_CLASS;
3690 if (!NT_STATUS_IS_OK(status)) {
3691 return status;
3694 *r->out.info = dom_info;
3696 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3698 return status;
3701 /* W2k3 seems to use the same check for all 3 objects that can be created via
3702 * SAMR, if you try to create for example "Dialup" as an alias it says
3703 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3704 * database. */
3706 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3708 enum lsa_SidType type;
3709 bool result;
3711 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3713 become_root();
3714 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3715 * whether the name already exists */
3716 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3717 NULL, NULL, NULL, &type);
3718 unbecome_root();
3720 if (!result) {
3721 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3722 return NT_STATUS_OK;
3725 DEBUG(5, ("trying to create %s, exists as %s\n",
3726 new_name, sid_type_lookup(type)));
3728 if (type == SID_NAME_DOM_GRP) {
3729 return NT_STATUS_GROUP_EXISTS;
3731 if (type == SID_NAME_ALIAS) {
3732 return NT_STATUS_ALIAS_EXISTS;
3735 /* Yes, the default is NT_STATUS_USER_EXISTS */
3736 return NT_STATUS_USER_EXISTS;
3739 /*******************************************************************
3740 _samr_CreateUser2
3741 ********************************************************************/
3743 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3744 struct samr_CreateUser2 *r)
3746 const char *account = NULL;
3747 DOM_SID sid;
3748 uint32_t acb_info = r->in.acct_flags;
3749 struct samr_domain_info *dinfo;
3750 struct samr_user_info *uinfo;
3751 NTSTATUS nt_status;
3752 uint32 acc_granted;
3753 SEC_DESC *psd;
3754 size_t sd_size;
3755 /* check this, when giving away 'add computer to domain' privs */
3756 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3757 bool can_add_account = False;
3758 SE_PRIV se_rights;
3760 dinfo = policy_handle_find(p, r->in.domain_handle,
3761 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3762 struct samr_domain_info, &nt_status);
3763 if (!NT_STATUS_IS_OK(nt_status)) {
3764 return nt_status;
3767 if (sid_check_is_builtin(&dinfo->sid)) {
3768 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3769 return NT_STATUS_ACCESS_DENIED;
3772 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3773 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3774 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3775 this parameter is not an account type */
3776 return NT_STATUS_INVALID_PARAMETER;
3779 account = r->in.account_name->string;
3780 if (account == NULL) {
3781 return NT_STATUS_NO_MEMORY;
3784 nt_status = can_create(p->mem_ctx, account);
3785 if (!NT_STATUS_IS_OK(nt_status)) {
3786 return nt_status;
3789 /* determine which user right we need to check based on the acb_info */
3791 if (geteuid() == sec_initial_uid()) {
3792 se_priv_copy(&se_rights, &se_priv_none);
3793 can_add_account = true;
3794 } else if (acb_info & ACB_WSTRUST) {
3795 se_priv_copy(&se_rights, &se_machine_account);
3796 can_add_account = user_has_privileges(
3797 p->server_info->ptok, &se_rights );
3798 } else if (acb_info & ACB_NORMAL &&
3799 (account[strlen(account)-1] != '$')) {
3800 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3801 account for domain trusts and changes the ACB flags later */
3802 se_priv_copy(&se_rights, &se_add_users);
3803 can_add_account = user_has_privileges(
3804 p->server_info->ptok, &se_rights );
3805 } else if (lp_enable_privileges()) {
3806 /* implicit assumption of a BDC or domain trust account here
3807 * (we already check the flags earlier) */
3808 /* only Domain Admins can add a BDC or domain trust */
3809 se_priv_copy(&se_rights, &se_priv_none);
3810 can_add_account = nt_token_check_domain_rid(
3811 p->server_info->ptok,
3812 DOMAIN_GROUP_RID_ADMINS );
3815 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3816 uidtoname(p->server_info->utok.uid),
3817 can_add_account ? "True":"False" ));
3819 if (!can_add_account) {
3820 return NT_STATUS_ACCESS_DENIED;
3823 /********** BEGIN Admin BLOCK **********/
3825 become_root();
3826 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3827 r->out.rid);
3828 unbecome_root();
3830 /********** END Admin BLOCK **********/
3832 /* now check for failure */
3834 if ( !NT_STATUS_IS_OK(nt_status) )
3835 return nt_status;
3837 /* Get the user's SID */
3839 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3841 map_max_allowed_access(p->server_info->ptok,
3842 &p->server_info->utok,
3843 &des_access);
3845 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3846 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3847 se_map_generic(&des_access, &usr_generic_mapping);
3850 * JRA - TESTME. We just created this user so we
3851 * had rights to create them. Do we need to check
3852 * any further access on this object ? Can't we
3853 * just assume we have all the rights we need ?
3856 nt_status = access_check_object(psd, p->server_info->ptok,
3857 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3858 &acc_granted, "_samr_CreateUser2");
3860 if ( !NT_STATUS_IS_OK(nt_status) ) {
3861 return nt_status;
3864 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3865 struct samr_user_info, &nt_status);
3866 if (!NT_STATUS_IS_OK(nt_status)) {
3867 return nt_status;
3869 uinfo->sid = sid;
3871 /* After a "set" ensure we have no cached display info. */
3872 force_flush_samr_cache(&sid);
3874 *r->out.access_granted = acc_granted;
3876 return NT_STATUS_OK;
3879 /****************************************************************
3880 ****************************************************************/
3882 NTSTATUS _samr_CreateUser(pipes_struct *p,
3883 struct samr_CreateUser *r)
3885 struct samr_CreateUser2 c;
3886 uint32_t access_granted;
3888 c.in.domain_handle = r->in.domain_handle;
3889 c.in.account_name = r->in.account_name;
3890 c.in.acct_flags = ACB_NORMAL;
3891 c.in.access_mask = r->in.access_mask;
3892 c.out.user_handle = r->out.user_handle;
3893 c.out.access_granted = &access_granted;
3894 c.out.rid = r->out.rid;
3896 return _samr_CreateUser2(p, &c);
3899 /*******************************************************************
3900 _samr_Connect
3901 ********************************************************************/
3903 NTSTATUS _samr_Connect(pipes_struct *p,
3904 struct samr_Connect *r)
3906 struct samr_connect_info *info;
3907 uint32_t acc_granted;
3908 struct policy_handle hnd;
3909 uint32 des_access = r->in.access_mask;
3910 NTSTATUS status;
3912 /* Access check */
3914 if (!pipe_access_check(p)) {
3915 DEBUG(3, ("access denied to _samr_Connect\n"));
3916 return NT_STATUS_ACCESS_DENIED;
3919 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3920 was observed from a win98 client trying to enumerate users (when configured
3921 user level access control on shares) --jerry */
3923 map_max_allowed_access(p->server_info->ptok,
3924 &p->server_info->utok,
3925 &des_access);
3927 se_map_generic( &des_access, &sam_generic_mapping );
3929 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3930 |SAMR_ACCESS_LOOKUP_DOMAIN);
3932 /* set up the SAMR connect_anon response */
3934 info = policy_handle_create(p, &hnd, acc_granted,
3935 struct samr_connect_info,
3936 &status);
3937 if (!NT_STATUS_IS_OK(status)) {
3938 return status;
3941 *r->out.connect_handle = hnd;
3942 return NT_STATUS_OK;
3945 /*******************************************************************
3946 _samr_Connect2
3947 ********************************************************************/
3949 NTSTATUS _samr_Connect2(pipes_struct *p,
3950 struct samr_Connect2 *r)
3952 struct samr_connect_info *info = NULL;
3953 struct policy_handle hnd;
3954 SEC_DESC *psd = NULL;
3955 uint32 acc_granted;
3956 uint32 des_access = r->in.access_mask;
3957 NTSTATUS nt_status;
3958 size_t sd_size;
3959 const char *fn = "_samr_Connect2";
3961 switch (p->hdr_req.opnum) {
3962 case NDR_SAMR_CONNECT2:
3963 fn = "_samr_Connect2";
3964 break;
3965 case NDR_SAMR_CONNECT3:
3966 fn = "_samr_Connect3";
3967 break;
3968 case NDR_SAMR_CONNECT4:
3969 fn = "_samr_Connect4";
3970 break;
3971 case NDR_SAMR_CONNECT5:
3972 fn = "_samr_Connect5";
3973 break;
3976 DEBUG(5,("%s: %d\n", fn, __LINE__));
3978 /* Access check */
3980 if (!pipe_access_check(p)) {
3981 DEBUG(3, ("access denied to %s\n", fn));
3982 return NT_STATUS_ACCESS_DENIED;
3985 map_max_allowed_access(p->server_info->ptok,
3986 &p->server_info->utok,
3987 &des_access);
3989 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3990 se_map_generic(&des_access, &sam_generic_mapping);
3992 nt_status = access_check_object(psd, p->server_info->ptok,
3993 NULL, 0, des_access, &acc_granted, fn);
3995 if ( !NT_STATUS_IS_OK(nt_status) )
3996 return nt_status;
3998 info = policy_handle_create(p, &hnd, acc_granted,
3999 struct samr_connect_info, &nt_status);
4000 if (!NT_STATUS_IS_OK(nt_status)) {
4001 return nt_status;
4004 DEBUG(5,("%s: %d\n", fn, __LINE__));
4006 *r->out.connect_handle = hnd;
4007 return NT_STATUS_OK;
4010 /****************************************************************
4011 _samr_Connect3
4012 ****************************************************************/
4014 NTSTATUS _samr_Connect3(pipes_struct *p,
4015 struct samr_Connect3 *r)
4017 struct samr_Connect2 c;
4019 c.in.system_name = r->in.system_name;
4020 c.in.access_mask = r->in.access_mask;
4021 c.out.connect_handle = r->out.connect_handle;
4023 return _samr_Connect2(p, &c);
4026 /*******************************************************************
4027 _samr_Connect4
4028 ********************************************************************/
4030 NTSTATUS _samr_Connect4(pipes_struct *p,
4031 struct samr_Connect4 *r)
4033 struct samr_Connect2 c;
4035 c.in.system_name = r->in.system_name;
4036 c.in.access_mask = r->in.access_mask;
4037 c.out.connect_handle = r->out.connect_handle;
4039 return _samr_Connect2(p, &c);
4042 /*******************************************************************
4043 _samr_Connect5
4044 ********************************************************************/
4046 NTSTATUS _samr_Connect5(pipes_struct *p,
4047 struct samr_Connect5 *r)
4049 NTSTATUS status;
4050 struct samr_Connect2 c;
4051 struct samr_ConnectInfo1 info1;
4053 info1.client_version = SAMR_CONNECT_AFTER_W2K;
4054 info1.unknown2 = 0;
4056 c.in.system_name = r->in.system_name;
4057 c.in.access_mask = r->in.access_mask;
4058 c.out.connect_handle = r->out.connect_handle;
4060 *r->out.level_out = 1;
4062 status = _samr_Connect2(p, &c);
4063 if (!NT_STATUS_IS_OK(status)) {
4064 return status;
4067 r->out.info_out->info1 = info1;
4069 return NT_STATUS_OK;
4072 /**********************************************************************
4073 _samr_LookupDomain
4074 **********************************************************************/
4076 NTSTATUS _samr_LookupDomain(pipes_struct *p,
4077 struct samr_LookupDomain *r)
4079 NTSTATUS status;
4080 struct samr_connect_info *info;
4081 const char *domain_name;
4082 DOM_SID *sid = NULL;
4084 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4085 Reverted that change so we will work with RAS servers again */
4087 info = policy_handle_find(p, r->in.connect_handle,
4088 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4089 struct samr_connect_info,
4090 &status);
4091 if (!NT_STATUS_IS_OK(status)) {
4092 return status;
4095 domain_name = r->in.domain_name->string;
4096 if (!domain_name) {
4097 return NT_STATUS_INVALID_PARAMETER;
4100 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
4101 if (!sid) {
4102 return NT_STATUS_NO_MEMORY;
4105 if (strequal(domain_name, builtin_domain_name())) {
4106 sid_copy(sid, &global_sid_Builtin);
4107 } else {
4108 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4109 status = NT_STATUS_NO_SUCH_DOMAIN;
4113 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4114 sid_string_dbg(sid)));
4116 *r->out.sid = sid;
4118 return status;
4121 /**********************************************************************
4122 _samr_EnumDomains
4123 **********************************************************************/
4125 NTSTATUS _samr_EnumDomains(pipes_struct *p,
4126 struct samr_EnumDomains *r)
4128 NTSTATUS status;
4129 struct samr_connect_info *info;
4130 uint32_t num_entries = 2;
4131 struct samr_SamEntry *entry_array = NULL;
4132 struct samr_SamArray *sam;
4134 info = policy_handle_find(p, r->in.connect_handle,
4135 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4136 struct samr_connect_info, &status);
4137 if (!NT_STATUS_IS_OK(status)) {
4138 return status;
4141 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4142 if (!sam) {
4143 return NT_STATUS_NO_MEMORY;
4146 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4147 struct samr_SamEntry,
4148 num_entries);
4149 if (!entry_array) {
4150 return NT_STATUS_NO_MEMORY;
4153 entry_array[0].idx = 0;
4154 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4156 entry_array[1].idx = 1;
4157 init_lsa_String(&entry_array[1].name, "Builtin");
4159 sam->count = num_entries;
4160 sam->entries = entry_array;
4162 *r->out.sam = sam;
4163 *r->out.num_entries = num_entries;
4165 return status;
4168 /*******************************************************************
4169 _samr_OpenAlias
4170 ********************************************************************/
4172 NTSTATUS _samr_OpenAlias(pipes_struct *p,
4173 struct samr_OpenAlias *r)
4175 DOM_SID sid;
4176 uint32 alias_rid = r->in.rid;
4177 struct samr_alias_info *ainfo;
4178 struct samr_domain_info *dinfo;
4179 SEC_DESC *psd = NULL;
4180 uint32 acc_granted;
4181 uint32 des_access = r->in.access_mask;
4182 size_t sd_size;
4183 NTSTATUS status;
4184 SE_PRIV se_rights;
4186 dinfo = policy_handle_find(p, r->in.domain_handle,
4187 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4188 struct samr_domain_info, &status);
4189 if (!NT_STATUS_IS_OK(status)) {
4190 return status;
4193 /* append the alias' RID to it */
4195 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4196 return NT_STATUS_NO_SUCH_ALIAS;
4198 /*check if access can be granted as requested by client. */
4200 map_max_allowed_access(p->server_info->ptok,
4201 &p->server_info->utok,
4202 &des_access);
4204 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4205 se_map_generic(&des_access,&ali_generic_mapping);
4207 se_priv_copy( &se_rights, &se_add_users );
4209 status = access_check_object(psd, p->server_info->ptok,
4210 &se_rights, GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4211 des_access, &acc_granted, "_samr_OpenAlias");
4213 if ( !NT_STATUS_IS_OK(status) )
4214 return status;
4217 /* Check we actually have the requested alias */
4218 enum lsa_SidType type;
4219 bool result;
4220 gid_t gid;
4222 become_root();
4223 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4224 unbecome_root();
4226 if (!result || (type != SID_NAME_ALIAS)) {
4227 return NT_STATUS_NO_SUCH_ALIAS;
4230 /* make sure there is a mapping */
4232 if ( !sid_to_gid( &sid, &gid ) ) {
4233 return NT_STATUS_NO_SUCH_ALIAS;
4238 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4239 struct samr_alias_info, &status);
4240 if (!NT_STATUS_IS_OK(status)) {
4241 return status;
4243 ainfo->sid = sid;
4245 return NT_STATUS_OK;
4248 /*******************************************************************
4249 set_user_info_2
4250 ********************************************************************/
4252 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4253 struct samr_UserInfo2 *id2,
4254 struct samu *pwd)
4256 if (id2 == NULL) {
4257 DEBUG(5,("set_user_info_2: NULL id2\n"));
4258 return NT_STATUS_ACCESS_DENIED;
4261 copy_id2_to_sam_passwd(pwd, id2);
4263 return pdb_update_sam_account(pwd);
4266 /*******************************************************************
4267 set_user_info_4
4268 ********************************************************************/
4270 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4271 struct samr_UserInfo4 *id4,
4272 struct samu *pwd)
4274 if (id4 == NULL) {
4275 DEBUG(5,("set_user_info_2: NULL id4\n"));
4276 return NT_STATUS_ACCESS_DENIED;
4279 copy_id4_to_sam_passwd(pwd, id4);
4281 return pdb_update_sam_account(pwd);
4284 /*******************************************************************
4285 set_user_info_6
4286 ********************************************************************/
4288 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4289 struct samr_UserInfo6 *id6,
4290 struct samu *pwd)
4292 if (id6 == NULL) {
4293 DEBUG(5,("set_user_info_6: NULL id6\n"));
4294 return NT_STATUS_ACCESS_DENIED;
4297 copy_id6_to_sam_passwd(pwd, id6);
4299 return pdb_update_sam_account(pwd);
4302 /*******************************************************************
4303 set_user_info_7
4304 ********************************************************************/
4306 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4307 struct samr_UserInfo7 *id7,
4308 struct samu *pwd)
4310 NTSTATUS rc;
4312 if (id7 == NULL) {
4313 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4314 return NT_STATUS_ACCESS_DENIED;
4317 if (!id7->account_name.string) {
4318 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4319 return NT_STATUS_ACCESS_DENIED;
4322 /* check to see if the new username already exists. Note: we can't
4323 reliably lock all backends, so there is potentially the
4324 possibility that a user can be created in between this check and
4325 the rename. The rename should fail, but may not get the
4326 exact same failure status code. I think this is small enough
4327 of a window for this type of operation and the results are
4328 simply that the rename fails with a slightly different status
4329 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4331 rc = can_create(mem_ctx, id7->account_name.string);
4333 /* when there is nothing to change, we're done here */
4334 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4335 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4336 return NT_STATUS_OK;
4338 if (!NT_STATUS_IS_OK(rc)) {
4339 return rc;
4342 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4344 return rc;
4347 /*******************************************************************
4348 set_user_info_8
4349 ********************************************************************/
4351 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4352 struct samr_UserInfo8 *id8,
4353 struct samu *pwd)
4355 if (id8 == NULL) {
4356 DEBUG(5,("set_user_info_8: NULL id8\n"));
4357 return NT_STATUS_ACCESS_DENIED;
4360 copy_id8_to_sam_passwd(pwd, id8);
4362 return pdb_update_sam_account(pwd);
4365 /*******************************************************************
4366 set_user_info_10
4367 ********************************************************************/
4369 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4370 struct samr_UserInfo10 *id10,
4371 struct samu *pwd)
4373 if (id10 == NULL) {
4374 DEBUG(5,("set_user_info_8: NULL id10\n"));
4375 return NT_STATUS_ACCESS_DENIED;
4378 copy_id10_to_sam_passwd(pwd, id10);
4380 return pdb_update_sam_account(pwd);
4383 /*******************************************************************
4384 set_user_info_11
4385 ********************************************************************/
4387 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4388 struct samr_UserInfo11 *id11,
4389 struct samu *pwd)
4391 if (id11 == NULL) {
4392 DEBUG(5,("set_user_info_11: NULL id11\n"));
4393 return NT_STATUS_ACCESS_DENIED;
4396 copy_id11_to_sam_passwd(pwd, id11);
4398 return pdb_update_sam_account(pwd);
4401 /*******************************************************************
4402 set_user_info_12
4403 ********************************************************************/
4405 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4406 struct samr_UserInfo12 *id12,
4407 struct samu *pwd)
4409 if (id12 == NULL) {
4410 DEBUG(5,("set_user_info_12: NULL id12\n"));
4411 return NT_STATUS_ACCESS_DENIED;
4414 copy_id12_to_sam_passwd(pwd, id12);
4416 return pdb_update_sam_account(pwd);
4419 /*******************************************************************
4420 set_user_info_13
4421 ********************************************************************/
4423 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4424 struct samr_UserInfo13 *id13,
4425 struct samu *pwd)
4427 if (id13 == NULL) {
4428 DEBUG(5,("set_user_info_13: NULL id13\n"));
4429 return NT_STATUS_ACCESS_DENIED;
4432 copy_id13_to_sam_passwd(pwd, id13);
4434 return pdb_update_sam_account(pwd);
4437 /*******************************************************************
4438 set_user_info_14
4439 ********************************************************************/
4441 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4442 struct samr_UserInfo14 *id14,
4443 struct samu *pwd)
4445 if (id14 == NULL) {
4446 DEBUG(5,("set_user_info_14: NULL id14\n"));
4447 return NT_STATUS_ACCESS_DENIED;
4450 copy_id14_to_sam_passwd(pwd, id14);
4452 return pdb_update_sam_account(pwd);
4455 /*******************************************************************
4456 set_user_info_16
4457 ********************************************************************/
4459 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4460 struct samr_UserInfo16 *id16,
4461 struct samu *pwd)
4463 if (id16 == NULL) {
4464 DEBUG(5,("set_user_info_16: NULL id16\n"));
4465 return NT_STATUS_ACCESS_DENIED;
4468 copy_id16_to_sam_passwd(pwd, id16);
4470 return pdb_update_sam_account(pwd);
4473 /*******************************************************************
4474 set_user_info_17
4475 ********************************************************************/
4477 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4478 struct samr_UserInfo17 *id17,
4479 struct samu *pwd)
4481 if (id17 == NULL) {
4482 DEBUG(5,("set_user_info_17: NULL id17\n"));
4483 return NT_STATUS_ACCESS_DENIED;
4486 copy_id17_to_sam_passwd(pwd, id17);
4488 return pdb_update_sam_account(pwd);
4491 /*******************************************************************
4492 set_user_info_18
4493 ********************************************************************/
4495 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4496 TALLOC_CTX *mem_ctx,
4497 DATA_BLOB *session_key,
4498 struct samu *pwd)
4500 if (id18 == NULL) {
4501 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4502 return NT_STATUS_INVALID_PARAMETER;
4505 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4506 if (!session_key->length) {
4507 return NT_STATUS_NO_USER_SESSION_KEY;
4511 if (id18->nt_pwd_active) {
4513 DATA_BLOB in, out;
4515 in = data_blob_const(id18->nt_pwd.hash, 16);
4516 out = data_blob_talloc_zero(mem_ctx, 16);
4518 sess_crypt_blob(&out, &in, session_key, false);
4520 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4521 return NT_STATUS_ACCESS_DENIED;
4524 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4527 if (id18->lm_pwd_active) {
4529 DATA_BLOB in, out;
4531 in = data_blob_const(id18->lm_pwd.hash, 16);
4532 out = data_blob_talloc_zero(mem_ctx, 16);
4534 sess_crypt_blob(&out, &in, session_key, false);
4536 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4537 return NT_STATUS_ACCESS_DENIED;
4540 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4543 copy_id18_to_sam_passwd(pwd, id18);
4545 return pdb_update_sam_account(pwd);
4548 /*******************************************************************
4549 set_user_info_20
4550 ********************************************************************/
4552 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4553 struct samr_UserInfo20 *id20,
4554 struct samu *pwd)
4556 if (id20 == NULL) {
4557 DEBUG(5,("set_user_info_20: NULL id20\n"));
4558 return NT_STATUS_ACCESS_DENIED;
4561 copy_id20_to_sam_passwd(pwd, id20);
4563 return pdb_update_sam_account(pwd);
4566 /*******************************************************************
4567 set_user_info_21
4568 ********************************************************************/
4570 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4571 TALLOC_CTX *mem_ctx,
4572 DATA_BLOB *session_key,
4573 struct samu *pwd)
4575 NTSTATUS status;
4577 if (id21 == NULL) {
4578 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4579 return NT_STATUS_INVALID_PARAMETER;
4582 if (id21->fields_present == 0) {
4583 return NT_STATUS_INVALID_PARAMETER;
4586 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4587 return NT_STATUS_ACCESS_DENIED;
4590 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4591 if (id21->nt_password_set) {
4592 DATA_BLOB in, out;
4594 if ((id21->nt_owf_password.length != 16) ||
4595 (id21->nt_owf_password.size != 16)) {
4596 return NT_STATUS_INVALID_PARAMETER;
4599 if (!session_key->length) {
4600 return NT_STATUS_NO_USER_SESSION_KEY;
4603 in = data_blob_const(id21->nt_owf_password.array, 16);
4604 out = data_blob_talloc_zero(mem_ctx, 16);
4606 sess_crypt_blob(&out, &in, session_key, false);
4608 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4609 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4613 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4614 if (id21->lm_password_set) {
4615 DATA_BLOB in, out;
4617 if ((id21->lm_owf_password.length != 16) ||
4618 (id21->lm_owf_password.size != 16)) {
4619 return NT_STATUS_INVALID_PARAMETER;
4622 if (!session_key->length) {
4623 return NT_STATUS_NO_USER_SESSION_KEY;
4626 in = data_blob_const(id21->lm_owf_password.array, 16);
4627 out = data_blob_talloc_zero(mem_ctx, 16);
4629 sess_crypt_blob(&out, &in, session_key, false);
4631 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4632 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4636 /* we need to separately check for an account rename first */
4638 if (id21->account_name.string &&
4639 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4642 /* check to see if the new username already exists. Note: we can't
4643 reliably lock all backends, so there is potentially the
4644 possibility that a user can be created in between this check and
4645 the rename. The rename should fail, but may not get the
4646 exact same failure status code. I think this is small enough
4647 of a window for this type of operation and the results are
4648 simply that the rename fails with a slightly different status
4649 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4651 status = can_create(mem_ctx, id21->account_name.string);
4652 if (!NT_STATUS_IS_OK(status)) {
4653 return status;
4656 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4658 if (!NT_STATUS_IS_OK(status)) {
4659 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4660 nt_errstr(status)));
4661 return status;
4664 /* set the new username so that later
4665 functions can work on the new account */
4666 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4669 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4672 * The funny part about the previous two calls is
4673 * that pwd still has the password hashes from the
4674 * passdb entry. These have not been updated from
4675 * id21. I don't know if they need to be set. --jerry
4678 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4679 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4680 if ( !NT_STATUS_IS_OK(status) ) {
4681 return status;
4685 /* Don't worry about writing out the user account since the
4686 primary group SID is generated solely from the user's Unix
4687 primary group. */
4689 /* write the change out */
4690 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4691 return status;
4694 return NT_STATUS_OK;
4697 /*******************************************************************
4698 set_user_info_23
4699 ********************************************************************/
4701 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4702 struct samr_UserInfo23 *id23,
4703 struct samu *pwd)
4705 char *plaintext_buf = NULL;
4706 size_t len = 0;
4707 uint32_t acct_ctrl;
4708 NTSTATUS status;
4710 if (id23 == NULL) {
4711 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4712 return NT_STATUS_INVALID_PARAMETER;
4715 if (id23->info.fields_present == 0) {
4716 return NT_STATUS_INVALID_PARAMETER;
4719 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4720 return NT_STATUS_ACCESS_DENIED;
4723 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4724 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4726 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4727 pdb_get_username(pwd)));
4729 if (!decode_pw_buffer(mem_ctx,
4730 id23->password.data,
4731 &plaintext_buf,
4732 &len,
4733 CH_UTF16)) {
4734 return NT_STATUS_WRONG_PASSWORD;
4737 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4738 return NT_STATUS_ACCESS_DENIED;
4742 copy_id23_to_sam_passwd(pwd, id23);
4744 acct_ctrl = pdb_get_acct_ctrl(pwd);
4746 /* if it's a trust account, don't update /etc/passwd */
4747 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4748 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4749 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4750 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4751 } else if (plaintext_buf) {
4752 /* update the UNIX password */
4753 if (lp_unix_password_sync() ) {
4754 struct passwd *passwd;
4755 if (pdb_get_username(pwd) == NULL) {
4756 DEBUG(1, ("chgpasswd: User without name???\n"));
4757 return NT_STATUS_ACCESS_DENIED;
4760 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4761 if (passwd == NULL) {
4762 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4765 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4766 return NT_STATUS_ACCESS_DENIED;
4768 TALLOC_FREE(passwd);
4772 if (plaintext_buf) {
4773 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4776 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4777 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4778 pwd)))) {
4779 return status;
4782 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4783 return status;
4786 return NT_STATUS_OK;
4789 /*******************************************************************
4790 set_user_info_pw
4791 ********************************************************************/
4793 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4795 size_t len = 0;
4796 char *plaintext_buf = NULL;
4797 uint32 acct_ctrl;
4799 DEBUG(5, ("Attempting administrator password change for user %s\n",
4800 pdb_get_username(pwd)));
4802 acct_ctrl = pdb_get_acct_ctrl(pwd);
4804 if (!decode_pw_buffer(talloc_tos(),
4805 pass,
4806 &plaintext_buf,
4807 &len,
4808 CH_UTF16)) {
4809 return False;
4812 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4813 return False;
4816 /* if it's a trust account, don't update /etc/passwd */
4817 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4818 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4819 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4820 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4821 } else {
4822 /* update the UNIX password */
4823 if (lp_unix_password_sync()) {
4824 struct passwd *passwd;
4826 if (pdb_get_username(pwd) == NULL) {
4827 DEBUG(1, ("chgpasswd: User without name???\n"));
4828 return False;
4831 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4832 if (passwd == NULL) {
4833 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4836 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4837 return False;
4839 TALLOC_FREE(passwd);
4843 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4845 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4847 return True;
4850 /*******************************************************************
4851 set_user_info_24
4852 ********************************************************************/
4854 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4855 struct samr_UserInfo24 *id24,
4856 struct samu *pwd)
4858 NTSTATUS status;
4860 if (id24 == NULL) {
4861 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4862 return NT_STATUS_INVALID_PARAMETER;
4865 if (!set_user_info_pw(id24->password.data, pwd)) {
4866 return NT_STATUS_WRONG_PASSWORD;
4869 copy_id24_to_sam_passwd(pwd, id24);
4871 status = pdb_update_sam_account(pwd);
4872 if (!NT_STATUS_IS_OK(status)) {
4873 return status;
4876 return NT_STATUS_OK;
4879 /*******************************************************************
4880 set_user_info_25
4881 ********************************************************************/
4883 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4884 struct samr_UserInfo25 *id25,
4885 struct samu *pwd)
4887 NTSTATUS status;
4889 if (id25 == NULL) {
4890 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4891 return NT_STATUS_INVALID_PARAMETER;
4894 if (id25->info.fields_present == 0) {
4895 return NT_STATUS_INVALID_PARAMETER;
4898 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4899 return NT_STATUS_ACCESS_DENIED;
4902 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4903 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4905 if (!set_user_info_pw(id25->password.data, pwd)) {
4906 return NT_STATUS_WRONG_PASSWORD;
4910 copy_id25_to_sam_passwd(pwd, id25);
4912 /* write the change out */
4913 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4914 return status;
4918 * We need to "pdb_update_sam_account" before the unix primary group
4919 * is set, because the idealx scripts would also change the
4920 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4921 * the delete explicit / add explicit, which would then fail to find
4922 * the previous primaryGroupSid value.
4925 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4926 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4927 if ( !NT_STATUS_IS_OK(status) ) {
4928 return status;
4932 return NT_STATUS_OK;
4935 /*******************************************************************
4936 set_user_info_26
4937 ********************************************************************/
4939 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4940 struct samr_UserInfo26 *id26,
4941 struct samu *pwd)
4943 NTSTATUS status;
4945 if (id26 == NULL) {
4946 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4947 return NT_STATUS_INVALID_PARAMETER;
4950 if (!set_user_info_pw(id26->password.data, pwd)) {
4951 return NT_STATUS_WRONG_PASSWORD;
4954 copy_id26_to_sam_passwd(pwd, id26);
4956 status = pdb_update_sam_account(pwd);
4957 if (!NT_STATUS_IS_OK(status)) {
4958 return status;
4961 return NT_STATUS_OK;
4964 /*************************************************************
4965 **************************************************************/
4967 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4969 uint32_t acc_required = 0;
4971 /* USER_ALL_USERNAME */
4972 if (fields & SAMR_FIELD_ACCOUNT_NAME)
4973 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4974 /* USER_ALL_FULLNAME */
4975 if (fields & SAMR_FIELD_FULL_NAME)
4976 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4977 /* USER_ALL_PRIMARYGROUPID */
4978 if (fields & SAMR_FIELD_PRIMARY_GID)
4979 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4980 /* USER_ALL_HOMEDIRECTORY */
4981 if (fields & SAMR_FIELD_HOME_DIRECTORY)
4982 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4983 /* USER_ALL_HOMEDIRECTORYDRIVE */
4984 if (fields & SAMR_FIELD_HOME_DRIVE)
4985 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4986 /* USER_ALL_SCRIPTPATH */
4987 if (fields & SAMR_FIELD_LOGON_SCRIPT)
4988 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4989 /* USER_ALL_PROFILEPATH */
4990 if (fields & SAMR_FIELD_PROFILE_PATH)
4991 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4992 /* USER_ALL_ADMINCOMMENT */
4993 if (fields & SAMR_FIELD_COMMENT)
4994 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4995 /* USER_ALL_WORKSTATIONS */
4996 if (fields & SAMR_FIELD_WORKSTATIONS)
4997 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4998 /* USER_ALL_LOGONHOURS */
4999 if (fields & SAMR_FIELD_LOGON_HOURS)
5000 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5001 /* USER_ALL_ACCOUNTEXPIRES */
5002 if (fields & SAMR_FIELD_ACCT_EXPIRY)
5003 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5004 /* USER_ALL_USERACCOUNTCONTROL */
5005 if (fields & SAMR_FIELD_ACCT_FLAGS)
5006 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5007 /* USER_ALL_PARAMETERS */
5008 if (fields & SAMR_FIELD_PARAMETERS)
5009 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5010 /* USER_ALL_USERCOMMENT */
5011 if (fields & SAMR_FIELD_COMMENT)
5012 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5013 /* USER_ALL_COUNTRYCODE */
5014 if (fields & SAMR_FIELD_COUNTRY_CODE)
5015 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5016 /* USER_ALL_CODEPAGE */
5017 if (fields & SAMR_FIELD_CODE_PAGE)
5018 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5019 /* USER_ALL_NTPASSWORDPRESENT */
5020 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
5021 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5022 /* USER_ALL_LMPASSWORDPRESENT */
5023 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
5024 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5025 /* USER_ALL_PASSWORDEXPIRED */
5026 if (fields & SAMR_FIELD_EXPIRED_FLAG)
5027 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5029 return acc_required;
5032 /*******************************************************************
5033 samr_SetUserInfo
5034 ********************************************************************/
5036 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
5037 struct samr_SetUserInfo *r)
5039 struct samr_user_info *uinfo;
5040 NTSTATUS status;
5041 struct samu *pwd = NULL;
5042 union samr_UserInfo *info = r->in.info;
5043 uint32_t acc_required = 0;
5044 uint32_t fields = 0;
5045 bool ret;
5047 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
5049 /* This is tricky. A WinXP domain join sets
5050 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5051 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
5052 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5053 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
5054 we'll use the set from the WinXP join as the basis. */
5056 switch (r->in.level) {
5057 case 2: /* UserPreferencesInformation */
5058 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5059 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5060 break;
5061 case 4: /* UserLogonHoursInformation */
5062 case 6: /* UserNameInformation */
5063 case 7: /* UserAccountNameInformation */
5064 case 8: /* UserFullNameInformation */
5065 case 9: /* UserPrimaryGroupInformation */
5066 case 10: /* UserHomeInformation */
5067 case 11: /* UserScriptInformation */
5068 case 12: /* UserProfileInformation */
5069 case 13: /* UserAdminCommentInformation */
5070 case 14: /* UserWorkStationsInformation */
5071 case 16: /* UserControlInformation */
5072 case 17: /* UserExpiresInformation */
5073 case 20: /* UserParametersInformation */
5074 /* USER_WRITE_ACCOUNT */
5075 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5076 break;
5077 case 18: /* UserInternal1Information */
5078 /* FIXME: gd, this is a guess */
5079 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5080 break;
5081 case 21: /* UserAllInformation */
5082 fields = info->info21.fields_present;
5083 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5084 break;
5085 case 23: /* UserInternal4Information */
5086 fields = info->info23.info.fields_present;
5087 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5088 break;
5089 case 25: /* UserInternal4InformationNew */
5090 fields = info->info25.info.fields_present;
5091 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5092 break;
5093 case 24: /* UserInternal5Information */
5094 case 26: /* UserInternal5InformationNew */
5095 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5096 break;
5097 default:
5098 return NT_STATUS_INVALID_INFO_CLASS;
5101 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5102 struct samr_user_info, &status);
5103 if (!NT_STATUS_IS_OK(status)) {
5104 return status;
5107 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5108 sid_string_dbg(&uinfo->sid), r->in.level));
5110 if (info == NULL) {
5111 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5112 return NT_STATUS_INVALID_INFO_CLASS;
5115 if (!(pwd = samu_new(NULL))) {
5116 return NT_STATUS_NO_MEMORY;
5119 become_root();
5120 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5121 unbecome_root();
5123 if (!ret) {
5124 TALLOC_FREE(pwd);
5125 return NT_STATUS_NO_SUCH_USER;
5128 /* ================ BEGIN Privilege BLOCK ================ */
5130 become_root();
5132 /* ok! user info levels (lots: see MSDEV help), off we go... */
5134 switch (r->in.level) {
5136 case 2:
5137 status = set_user_info_2(p->mem_ctx,
5138 &info->info2, pwd);
5139 break;
5141 case 4:
5142 status = set_user_info_4(p->mem_ctx,
5143 &info->info4, pwd);
5144 break;
5146 case 6:
5147 status = set_user_info_6(p->mem_ctx,
5148 &info->info6, pwd);
5149 break;
5151 case 7:
5152 status = set_user_info_7(p->mem_ctx,
5153 &info->info7, pwd);
5154 break;
5156 case 8:
5157 status = set_user_info_8(p->mem_ctx,
5158 &info->info8, pwd);
5159 break;
5161 case 10:
5162 status = set_user_info_10(p->mem_ctx,
5163 &info->info10, pwd);
5164 break;
5166 case 11:
5167 status = set_user_info_11(p->mem_ctx,
5168 &info->info11, pwd);
5169 break;
5171 case 12:
5172 status = set_user_info_12(p->mem_ctx,
5173 &info->info12, pwd);
5174 break;
5176 case 13:
5177 status = set_user_info_13(p->mem_ctx,
5178 &info->info13, pwd);
5179 break;
5181 case 14:
5182 status = set_user_info_14(p->mem_ctx,
5183 &info->info14, pwd);
5184 break;
5186 case 16:
5187 status = set_user_info_16(p->mem_ctx,
5188 &info->info16, pwd);
5189 break;
5191 case 17:
5192 status = set_user_info_17(p->mem_ctx,
5193 &info->info17, pwd);
5194 break;
5196 case 18:
5197 /* Used by AS/U JRA. */
5198 status = set_user_info_18(&info->info18,
5199 p->mem_ctx,
5200 &p->server_info->user_session_key,
5201 pwd);
5202 break;
5204 case 20:
5205 status = set_user_info_20(p->mem_ctx,
5206 &info->info20, pwd);
5207 break;
5209 case 21:
5210 status = set_user_info_21(&info->info21,
5211 p->mem_ctx,
5212 &p->server_info->user_session_key,
5213 pwd);
5214 break;
5216 case 23:
5217 if (!p->server_info->user_session_key.length) {
5218 status = NT_STATUS_NO_USER_SESSION_KEY;
5220 arcfour_crypt_blob(info->info23.password.data, 516,
5221 &p->server_info->user_session_key);
5223 dump_data(100, info->info23.password.data, 516);
5225 status = set_user_info_23(p->mem_ctx,
5226 &info->info23, pwd);
5227 break;
5229 case 24:
5230 if (!p->server_info->user_session_key.length) {
5231 status = NT_STATUS_NO_USER_SESSION_KEY;
5233 arcfour_crypt_blob(info->info24.password.data,
5234 516,
5235 &p->server_info->user_session_key);
5237 dump_data(100, info->info24.password.data, 516);
5239 status = set_user_info_24(p->mem_ctx,
5240 &info->info24, pwd);
5241 break;
5243 case 25:
5244 if (!p->server_info->user_session_key.length) {
5245 status = NT_STATUS_NO_USER_SESSION_KEY;
5247 encode_or_decode_arc4_passwd_buffer(
5248 info->info25.password.data,
5249 &p->server_info->user_session_key);
5251 dump_data(100, info->info25.password.data, 532);
5253 status = set_user_info_25(p->mem_ctx,
5254 &info->info25, pwd);
5255 break;
5257 case 26:
5258 if (!p->server_info->user_session_key.length) {
5259 status = NT_STATUS_NO_USER_SESSION_KEY;
5261 encode_or_decode_arc4_passwd_buffer(
5262 info->info26.password.data,
5263 &p->server_info->user_session_key);
5265 dump_data(100, info->info26.password.data, 516);
5267 status = set_user_info_26(p->mem_ctx,
5268 &info->info26, pwd);
5269 break;
5271 default:
5272 status = NT_STATUS_INVALID_INFO_CLASS;
5275 TALLOC_FREE(pwd);
5277 unbecome_root();
5279 /* ================ END Privilege BLOCK ================ */
5281 if (NT_STATUS_IS_OK(status)) {
5282 force_flush_samr_cache(&uinfo->sid);
5285 return status;
5288 /*******************************************************************
5289 _samr_SetUserInfo2
5290 ********************************************************************/
5292 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
5293 struct samr_SetUserInfo2 *r)
5295 struct samr_SetUserInfo q;
5297 q.in.user_handle = r->in.user_handle;
5298 q.in.level = r->in.level;
5299 q.in.info = r->in.info;
5301 return _samr_SetUserInfo(p, &q);
5304 /*********************************************************************
5305 _samr_GetAliasMembership
5306 *********************************************************************/
5308 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
5309 struct samr_GetAliasMembership *r)
5311 size_t num_alias_rids;
5312 uint32 *alias_rids;
5313 struct samr_domain_info *dinfo;
5314 size_t i;
5316 NTSTATUS status;
5318 DOM_SID *members;
5320 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5322 dinfo = policy_handle_find(p, r->in.domain_handle,
5323 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5324 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5325 struct samr_domain_info, &status);
5326 if (!NT_STATUS_IS_OK(status)) {
5327 return status;
5330 if (!sid_check_is_domain(&dinfo->sid) &&
5331 !sid_check_is_builtin(&dinfo->sid))
5332 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5334 if (r->in.sids->num_sids) {
5335 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
5337 if (members == NULL)
5338 return NT_STATUS_NO_MEMORY;
5339 } else {
5340 members = NULL;
5343 for (i=0; i<r->in.sids->num_sids; i++)
5344 sid_copy(&members[i], r->in.sids->sids[i].sid);
5346 alias_rids = NULL;
5347 num_alias_rids = 0;
5349 become_root();
5350 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5351 r->in.sids->num_sids,
5352 &alias_rids, &num_alias_rids);
5353 unbecome_root();
5355 if (!NT_STATUS_IS_OK(status)) {
5356 return status;
5359 r->out.rids->count = num_alias_rids;
5360 r->out.rids->ids = alias_rids;
5362 return NT_STATUS_OK;
5365 /*********************************************************************
5366 _samr_GetMembersInAlias
5367 *********************************************************************/
5369 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5370 struct samr_GetMembersInAlias *r)
5372 struct samr_alias_info *ainfo;
5373 NTSTATUS status;
5374 size_t i;
5375 size_t num_sids = 0;
5376 struct lsa_SidPtr *sids = NULL;
5377 DOM_SID *pdb_sids = NULL;
5379 ainfo = policy_handle_find(p, r->in.alias_handle,
5380 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5381 struct samr_alias_info, &status);
5382 if (!NT_STATUS_IS_OK(status)) {
5383 return status;
5386 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5388 become_root();
5389 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5390 &num_sids);
5391 unbecome_root();
5393 if (!NT_STATUS_IS_OK(status)) {
5394 return status;
5397 if (num_sids) {
5398 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5399 if (sids == NULL) {
5400 TALLOC_FREE(pdb_sids);
5401 return NT_STATUS_NO_MEMORY;
5405 for (i = 0; i < num_sids; i++) {
5406 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5407 if (!sids[i].sid) {
5408 TALLOC_FREE(pdb_sids);
5409 return NT_STATUS_NO_MEMORY;
5413 r->out.sids->num_sids = num_sids;
5414 r->out.sids->sids = sids;
5416 TALLOC_FREE(pdb_sids);
5418 return NT_STATUS_OK;
5421 /*********************************************************************
5422 _samr_QueryGroupMember
5423 *********************************************************************/
5425 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5426 struct samr_QueryGroupMember *r)
5428 struct samr_group_info *ginfo;
5429 size_t i, num_members;
5431 uint32 *rid=NULL;
5432 uint32 *attr=NULL;
5434 NTSTATUS status;
5435 struct samr_RidTypeArray *rids = NULL;
5437 ginfo = policy_handle_find(p, r->in.group_handle,
5438 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5439 struct samr_group_info, &status);
5440 if (!NT_STATUS_IS_OK(status)) {
5441 return status;
5444 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5445 if (!rids) {
5446 return NT_STATUS_NO_MEMORY;
5449 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5451 if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5452 DEBUG(3, ("sid %s is not in our domain\n",
5453 sid_string_dbg(&ginfo->sid)));
5454 return NT_STATUS_NO_SUCH_GROUP;
5457 DEBUG(10, ("lookup on Domain SID\n"));
5459 become_root();
5460 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5461 &rid, &num_members);
5462 unbecome_root();
5464 if (!NT_STATUS_IS_OK(status))
5465 return status;
5467 if (num_members) {
5468 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5469 if (attr == NULL) {
5470 return NT_STATUS_NO_MEMORY;
5472 } else {
5473 attr = NULL;
5476 for (i=0; i<num_members; i++)
5477 attr[i] = SID_NAME_USER;
5479 rids->count = num_members;
5480 rids->types = attr;
5481 rids->rids = rid;
5483 *r->out.rids = rids;
5485 return NT_STATUS_OK;
5488 /*********************************************************************
5489 _samr_AddAliasMember
5490 *********************************************************************/
5492 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5493 struct samr_AddAliasMember *r)
5495 struct samr_alias_info *ainfo;
5496 NTSTATUS status;
5498 ainfo = policy_handle_find(p, r->in.alias_handle,
5499 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5500 struct samr_alias_info, &status);
5501 if (!NT_STATUS_IS_OK(status)) {
5502 return status;
5505 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5507 /******** BEGIN SeAddUsers BLOCK *********/
5509 become_root();
5510 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5511 unbecome_root();
5513 /******** END SeAddUsers BLOCK *********/
5515 if (NT_STATUS_IS_OK(status)) {
5516 force_flush_samr_cache(&ainfo->sid);
5519 return status;
5522 /*********************************************************************
5523 _samr_DeleteAliasMember
5524 *********************************************************************/
5526 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5527 struct samr_DeleteAliasMember *r)
5529 struct samr_alias_info *ainfo;
5530 NTSTATUS status;
5532 ainfo = policy_handle_find(p, r->in.alias_handle,
5533 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5534 struct samr_alias_info, &status);
5535 if (!NT_STATUS_IS_OK(status)) {
5536 return status;
5539 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5540 sid_string_dbg(&ainfo->sid)));
5542 /******** BEGIN SeAddUsers BLOCK *********/
5544 become_root();
5545 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5546 unbecome_root();
5548 /******** END SeAddUsers BLOCK *********/
5550 if (NT_STATUS_IS_OK(status)) {
5551 force_flush_samr_cache(&ainfo->sid);
5554 return status;
5557 /*********************************************************************
5558 _samr_AddGroupMember
5559 *********************************************************************/
5561 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5562 struct samr_AddGroupMember *r)
5564 struct samr_group_info *ginfo;
5565 NTSTATUS status;
5566 uint32 group_rid;
5568 ginfo = policy_handle_find(p, r->in.group_handle,
5569 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5570 struct samr_group_info, &status);
5571 if (!NT_STATUS_IS_OK(status)) {
5572 return status;
5575 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5577 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5578 &group_rid)) {
5579 return NT_STATUS_INVALID_HANDLE;
5582 /******** BEGIN SeAddUsers BLOCK *********/
5584 become_root();
5585 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5586 unbecome_root();
5588 /******** END SeAddUsers BLOCK *********/
5590 force_flush_samr_cache(&ginfo->sid);
5592 return status;
5595 /*********************************************************************
5596 _samr_DeleteGroupMember
5597 *********************************************************************/
5599 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5600 struct samr_DeleteGroupMember *r)
5603 struct samr_group_info *ginfo;
5604 NTSTATUS status;
5605 uint32 group_rid;
5608 * delete the group member named r->in.rid
5609 * who is a member of the sid associated with the handle
5610 * the rid is a user's rid as the group is a domain group.
5613 ginfo = policy_handle_find(p, r->in.group_handle,
5614 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5615 struct samr_group_info, &status);
5616 if (!NT_STATUS_IS_OK(status)) {
5617 return status;
5620 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5621 &group_rid)) {
5622 return NT_STATUS_INVALID_HANDLE;
5625 /******** BEGIN SeAddUsers BLOCK *********/
5627 become_root();
5628 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5629 unbecome_root();
5631 /******** END SeAddUsers BLOCK *********/
5633 force_flush_samr_cache(&ginfo->sid);
5635 return status;
5638 /*********************************************************************
5639 _samr_DeleteUser
5640 *********************************************************************/
5642 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5643 struct samr_DeleteUser *r)
5645 struct samr_user_info *uinfo;
5646 NTSTATUS status;
5647 struct samu *sam_pass=NULL;
5648 bool ret;
5650 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5652 uinfo = policy_handle_find(p, r->in.user_handle,
5653 STD_RIGHT_DELETE_ACCESS, NULL,
5654 struct samr_user_info, &status);
5655 if (!NT_STATUS_IS_OK(status)) {
5656 return status;
5659 if (!sid_check_is_in_our_domain(&uinfo->sid))
5660 return NT_STATUS_CANNOT_DELETE;
5662 /* check if the user exists before trying to delete */
5663 if ( !(sam_pass = samu_new( NULL )) ) {
5664 return NT_STATUS_NO_MEMORY;
5667 become_root();
5668 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5669 unbecome_root();
5671 if(!ret) {
5672 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5673 sid_string_dbg(&uinfo->sid)));
5674 TALLOC_FREE(sam_pass);
5675 return NT_STATUS_NO_SUCH_USER;
5678 /******** BEGIN SeAddUsers BLOCK *********/
5680 become_root();
5681 status = pdb_delete_user(p->mem_ctx, sam_pass);
5682 unbecome_root();
5684 /******** END SeAddUsers BLOCK *********/
5686 if ( !NT_STATUS_IS_OK(status) ) {
5687 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5688 "user %s: %s.\n", pdb_get_username(sam_pass),
5689 nt_errstr(status)));
5690 TALLOC_FREE(sam_pass);
5691 return status;
5695 TALLOC_FREE(sam_pass);
5697 force_flush_samr_cache(&uinfo->sid);
5699 if (!close_policy_hnd(p, r->in.user_handle))
5700 return NT_STATUS_OBJECT_NAME_INVALID;
5702 ZERO_STRUCTP(r->out.user_handle);
5704 return NT_STATUS_OK;
5707 /*********************************************************************
5708 _samr_DeleteDomainGroup
5709 *********************************************************************/
5711 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5712 struct samr_DeleteDomainGroup *r)
5714 struct samr_group_info *ginfo;
5715 NTSTATUS status;
5716 uint32 group_rid;
5718 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5720 ginfo = policy_handle_find(p, r->in.group_handle,
5721 STD_RIGHT_DELETE_ACCESS, NULL,
5722 struct samr_group_info, &status);
5723 if (!NT_STATUS_IS_OK(status)) {
5724 return status;
5727 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5729 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5730 &group_rid)) {
5731 return NT_STATUS_NO_SUCH_GROUP;
5734 /******** BEGIN SeAddUsers BLOCK *********/
5736 become_root();
5737 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5738 unbecome_root();
5740 /******** END SeAddUsers BLOCK *********/
5742 if ( !NT_STATUS_IS_OK(status) ) {
5743 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5744 "entry for group %s: %s\n",
5745 sid_string_dbg(&ginfo->sid),
5746 nt_errstr(status)));
5747 return status;
5750 force_flush_samr_cache(&ginfo->sid);
5752 if (!close_policy_hnd(p, r->in.group_handle))
5753 return NT_STATUS_OBJECT_NAME_INVALID;
5755 return NT_STATUS_OK;
5758 /*********************************************************************
5759 _samr_DeleteDomAlias
5760 *********************************************************************/
5762 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5763 struct samr_DeleteDomAlias *r)
5765 struct samr_alias_info *ainfo;
5766 NTSTATUS status;
5768 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5770 ainfo = policy_handle_find(p, r->in.alias_handle,
5771 STD_RIGHT_DELETE_ACCESS, NULL,
5772 struct samr_alias_info, &status);
5773 if (!NT_STATUS_IS_OK(status)) {
5774 return status;
5777 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5779 /* Don't let Windows delete builtin groups */
5781 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5782 return NT_STATUS_SPECIAL_ACCOUNT;
5785 if (!sid_check_is_in_our_domain(&ainfo->sid))
5786 return NT_STATUS_NO_SUCH_ALIAS;
5788 DEBUG(10, ("lookup on Local SID\n"));
5790 /******** BEGIN SeAddUsers BLOCK *********/
5792 become_root();
5793 /* Have passdb delete the alias */
5794 status = pdb_delete_alias(&ainfo->sid);
5795 unbecome_root();
5797 /******** END SeAddUsers BLOCK *********/
5799 if ( !NT_STATUS_IS_OK(status))
5800 return status;
5802 force_flush_samr_cache(&ainfo->sid);
5804 if (!close_policy_hnd(p, r->in.alias_handle))
5805 return NT_STATUS_OBJECT_NAME_INVALID;
5807 return NT_STATUS_OK;
5810 /*********************************************************************
5811 _samr_CreateDomainGroup
5812 *********************************************************************/
5814 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5815 struct samr_CreateDomainGroup *r)
5818 NTSTATUS status;
5819 const char *name;
5820 struct samr_domain_info *dinfo;
5821 struct samr_group_info *ginfo;
5823 dinfo = policy_handle_find(p, r->in.domain_handle,
5824 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5825 struct samr_domain_info, &status);
5826 if (!NT_STATUS_IS_OK(status)) {
5827 return status;
5830 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5831 return NT_STATUS_ACCESS_DENIED;
5833 name = r->in.name->string;
5834 if (name == NULL) {
5835 return NT_STATUS_NO_MEMORY;
5838 status = can_create(p->mem_ctx, name);
5839 if (!NT_STATUS_IS_OK(status)) {
5840 return status;
5843 /******** BEGIN SeAddUsers BLOCK *********/
5845 become_root();
5846 /* check that we successfully create the UNIX group */
5847 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5848 unbecome_root();
5850 /******** END SeAddUsers BLOCK *********/
5852 /* check if we should bail out here */
5854 if ( !NT_STATUS_IS_OK(status) )
5855 return status;
5857 ginfo = policy_handle_create(p, r->out.group_handle,
5858 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5859 struct samr_group_info, &status);
5860 if (!NT_STATUS_IS_OK(status)) {
5861 return status;
5863 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5865 force_flush_samr_cache(&dinfo->sid);
5867 return NT_STATUS_OK;
5870 /*********************************************************************
5871 _samr_CreateDomAlias
5872 *********************************************************************/
5874 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5875 struct samr_CreateDomAlias *r)
5877 DOM_SID info_sid;
5878 const char *name = NULL;
5879 struct samr_domain_info *dinfo;
5880 struct samr_alias_info *ainfo;
5881 gid_t gid;
5882 NTSTATUS result;
5884 dinfo = policy_handle_find(p, r->in.domain_handle,
5885 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5886 struct samr_domain_info, &result);
5887 if (!NT_STATUS_IS_OK(result)) {
5888 return result;
5891 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5892 return NT_STATUS_ACCESS_DENIED;
5894 name = r->in.alias_name->string;
5896 result = can_create(p->mem_ctx, name);
5897 if (!NT_STATUS_IS_OK(result)) {
5898 return result;
5901 /******** BEGIN SeAddUsers BLOCK *********/
5903 become_root();
5904 /* Have passdb create the alias */
5905 result = pdb_create_alias(name, r->out.rid);
5906 unbecome_root();
5908 /******** END SeAddUsers BLOCK *********/
5910 if (!NT_STATUS_IS_OK(result)) {
5911 DEBUG(10, ("pdb_create_alias failed: %s\n",
5912 nt_errstr(result)));
5913 return result;
5916 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5918 if (!sid_to_gid(&info_sid, &gid)) {
5919 DEBUG(10, ("Could not find alias just created\n"));
5920 return NT_STATUS_ACCESS_DENIED;
5923 /* check if the group has been successfully created */
5924 if ( getgrgid(gid) == NULL ) {
5925 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5926 (unsigned int)gid));
5927 return NT_STATUS_ACCESS_DENIED;
5930 ainfo = policy_handle_create(p, r->out.alias_handle,
5931 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5932 struct samr_alias_info, &result);
5933 if (!NT_STATUS_IS_OK(result)) {
5934 return result;
5936 ainfo->sid = info_sid;
5938 force_flush_samr_cache(&info_sid);
5940 return NT_STATUS_OK;
5943 /*********************************************************************
5944 _samr_QueryGroupInfo
5945 *********************************************************************/
5947 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5948 struct samr_QueryGroupInfo *r)
5950 struct samr_group_info *ginfo;
5951 NTSTATUS status;
5952 GROUP_MAP map;
5953 union samr_GroupInfo *info = NULL;
5954 bool ret;
5955 uint32_t attributes = SE_GROUP_MANDATORY |
5956 SE_GROUP_ENABLED_BY_DEFAULT |
5957 SE_GROUP_ENABLED;
5958 const char *group_name = NULL;
5959 const char *group_description = NULL;
5961 ginfo = policy_handle_find(p, r->in.group_handle,
5962 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5963 struct samr_group_info, &status);
5964 if (!NT_STATUS_IS_OK(status)) {
5965 return status;
5968 become_root();
5969 ret = get_domain_group_from_sid(ginfo->sid, &map);
5970 unbecome_root();
5971 if (!ret)
5972 return NT_STATUS_INVALID_HANDLE;
5974 /* FIXME: map contains fstrings */
5975 group_name = talloc_strdup(r, map.nt_name);
5976 group_description = talloc_strdup(r, map.comment);
5978 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5979 if (!info) {
5980 return NT_STATUS_NO_MEMORY;
5983 switch (r->in.level) {
5984 case 1: {
5985 uint32 *members;
5986 size_t num_members;
5988 become_root();
5989 status = pdb_enum_group_members(
5990 p->mem_ctx, &ginfo->sid, &members,
5991 &num_members);
5992 unbecome_root();
5994 if (!NT_STATUS_IS_OK(status)) {
5995 return status;
5998 info->all.name.string = group_name;
5999 info->all.attributes = attributes;
6000 info->all.num_members = num_members;
6001 info->all.description.string = group_description;
6002 break;
6004 case 2:
6005 info->name.string = group_name;
6006 break;
6007 case 3:
6008 info->attributes.attributes = attributes;
6009 break;
6010 case 4:
6011 info->description.string = group_description;
6012 break;
6013 case 5: {
6015 uint32 *members;
6016 size_t num_members;
6020 become_root();
6021 status = pdb_enum_group_members(
6022 p->mem_ctx, &ginfo->sid, &members,
6023 &num_members);
6024 unbecome_root();
6026 if (!NT_STATUS_IS_OK(status)) {
6027 return status;
6030 info->all2.name.string = group_name;
6031 info->all2.attributes = attributes;
6032 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
6033 info->all2.description.string = group_description;
6035 break;
6037 default:
6038 return NT_STATUS_INVALID_INFO_CLASS;
6041 *r->out.info = info;
6043 return NT_STATUS_OK;
6046 /*********************************************************************
6047 _samr_SetGroupInfo
6048 *********************************************************************/
6050 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
6051 struct samr_SetGroupInfo *r)
6053 struct samr_group_info *ginfo;
6054 GROUP_MAP map;
6055 NTSTATUS status;
6056 bool ret;
6058 ginfo = policy_handle_find(p, r->in.group_handle,
6059 SAMR_GROUP_ACCESS_SET_INFO, NULL,
6060 struct samr_group_info, &status);
6061 if (!NT_STATUS_IS_OK(status)) {
6062 return status;
6065 become_root();
6066 ret = get_domain_group_from_sid(ginfo->sid, &map);
6067 unbecome_root();
6068 if (!ret)
6069 return NT_STATUS_NO_SUCH_GROUP;
6071 switch (r->in.level) {
6072 case 2:
6073 fstrcpy(map.nt_name, r->in.info->name.string);
6074 break;
6075 case 3:
6076 break;
6077 case 4:
6078 fstrcpy(map.comment, r->in.info->description.string);
6079 break;
6080 default:
6081 return NT_STATUS_INVALID_INFO_CLASS;
6084 /******** BEGIN SeAddUsers BLOCK *********/
6086 become_root();
6087 status = pdb_update_group_mapping_entry(&map);
6088 unbecome_root();
6090 /******** End SeAddUsers BLOCK *********/
6092 if (NT_STATUS_IS_OK(status)) {
6093 force_flush_samr_cache(&ginfo->sid);
6096 return status;
6099 /*********************************************************************
6100 _samr_SetAliasInfo
6101 *********************************************************************/
6103 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
6104 struct samr_SetAliasInfo *r)
6106 struct samr_alias_info *ainfo;
6107 struct acct_info info;
6108 NTSTATUS status;
6110 ainfo = policy_handle_find(p, r->in.alias_handle,
6111 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6112 struct samr_alias_info, &status);
6113 if (!NT_STATUS_IS_OK(status)) {
6114 return status;
6117 /* get the current group information */
6119 become_root();
6120 status = pdb_get_aliasinfo( &ainfo->sid, &info );
6121 unbecome_root();
6123 if ( !NT_STATUS_IS_OK(status))
6124 return status;
6126 switch (r->in.level) {
6127 case ALIASINFONAME:
6129 fstring group_name;
6131 /* We currently do not support renaming groups in the
6132 the BUILTIN domain. Refer to util_builtin.c to understand
6133 why. The eventually needs to be fixed to be like Windows
6134 where you can rename builtin groups, just not delete them */
6136 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6137 return NT_STATUS_SPECIAL_ACCOUNT;
6140 /* There has to be a valid name (and it has to be different) */
6142 if ( !r->in.info->name.string )
6143 return NT_STATUS_INVALID_PARAMETER;
6145 /* If the name is the same just reply "ok". Yes this
6146 doesn't allow you to change the case of a group name. */
6148 if ( strequal( r->in.info->name.string, info.acct_name ) )
6149 return NT_STATUS_OK;
6151 fstrcpy( info.acct_name, r->in.info->name.string);
6153 /* make sure the name doesn't already exist as a user
6154 or local group */
6156 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6157 status = can_create( p->mem_ctx, group_name );
6158 if ( !NT_STATUS_IS_OK( status ) )
6159 return status;
6160 break;
6162 case ALIASINFODESCRIPTION:
6163 if (r->in.info->description.string) {
6164 fstrcpy(info.acct_desc,
6165 r->in.info->description.string);
6166 } else {
6167 fstrcpy( info.acct_desc, "" );
6169 break;
6170 default:
6171 return NT_STATUS_INVALID_INFO_CLASS;
6174 /******** BEGIN SeAddUsers BLOCK *********/
6176 become_root();
6177 status = pdb_set_aliasinfo( &ainfo->sid, &info );
6178 unbecome_root();
6180 /******** End SeAddUsers BLOCK *********/
6182 if (NT_STATUS_IS_OK(status))
6183 force_flush_samr_cache(&ainfo->sid);
6185 return status;
6188 /****************************************************************
6189 _samr_GetDomPwInfo
6190 ****************************************************************/
6192 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
6193 struct samr_GetDomPwInfo *r)
6195 uint32_t min_password_length = 0;
6196 uint32_t password_properties = 0;
6198 /* Perform access check. Since this rpc does not require a
6199 policy handle it will not be caught by the access checks on
6200 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6202 if (!pipe_access_check(p)) {
6203 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6204 return NT_STATUS_ACCESS_DENIED;
6207 become_root();
6208 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6209 &min_password_length);
6210 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6211 &password_properties);
6212 unbecome_root();
6214 if (lp_check_password_script() && *lp_check_password_script()) {
6215 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6218 r->out.info->min_password_length = min_password_length;
6219 r->out.info->password_properties = password_properties;
6221 return NT_STATUS_OK;
6224 /*********************************************************************
6225 _samr_OpenGroup
6226 *********************************************************************/
6228 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6229 struct samr_OpenGroup *r)
6232 DOM_SID info_sid;
6233 GROUP_MAP map;
6234 struct samr_domain_info *dinfo;
6235 struct samr_group_info *ginfo;
6236 SEC_DESC *psd = NULL;
6237 uint32 acc_granted;
6238 uint32 des_access = r->in.access_mask;
6239 size_t sd_size;
6240 NTSTATUS status;
6241 bool ret;
6242 SE_PRIV se_rights;
6244 dinfo = policy_handle_find(p, r->in.domain_handle,
6245 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6246 struct samr_domain_info, &status);
6247 if (!NT_STATUS_IS_OK(status)) {
6248 return status;
6251 /*check if access can be granted as requested by client. */
6252 map_max_allowed_access(p->server_info->ptok,
6253 &p->server_info->utok,
6254 &des_access);
6256 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6257 se_map_generic(&des_access,&grp_generic_mapping);
6259 se_priv_copy( &se_rights, &se_add_users );
6261 status = access_check_object(psd, p->server_info->ptok,
6262 &se_rights, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6263 des_access, &acc_granted, "_samr_OpenGroup");
6265 if ( !NT_STATUS_IS_OK(status) )
6266 return status;
6268 /* this should not be hard-coded like this */
6270 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
6271 return NT_STATUS_ACCESS_DENIED;
6273 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6275 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6276 sid_string_dbg(&info_sid)));
6278 /* check if that group really exists */
6279 become_root();
6280 ret = get_domain_group_from_sid(info_sid, &map);
6281 unbecome_root();
6282 if (!ret)
6283 return NT_STATUS_NO_SUCH_GROUP;
6285 ginfo = policy_handle_create(p, r->out.group_handle,
6286 acc_granted,
6287 struct samr_group_info, &status);
6288 if (!NT_STATUS_IS_OK(status)) {
6289 return status;
6291 ginfo->sid = info_sid;
6293 return NT_STATUS_OK;
6296 /*********************************************************************
6297 _samr_RemoveMemberFromForeignDomain
6298 *********************************************************************/
6300 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6301 struct samr_RemoveMemberFromForeignDomain *r)
6303 struct samr_domain_info *dinfo;
6304 NTSTATUS result;
6306 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6307 sid_string_dbg(r->in.sid)));
6309 /* Find the policy handle. Open a policy on it. */
6311 dinfo = policy_handle_find(p, r->in.domain_handle,
6312 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6313 struct samr_domain_info, &result);
6314 if (!NT_STATUS_IS_OK(result)) {
6315 return result;
6318 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6319 sid_string_dbg(&dinfo->sid)));
6321 /* we can only delete a user from a group since we don't have
6322 nested groups anyways. So in the latter case, just say OK */
6324 /* TODO: The above comment nowadays is bogus. Since we have nested
6325 * groups now, and aliases members are never reported out of the unix
6326 * group membership, the "just say OK" makes this call a no-op. For
6327 * us. This needs fixing however. */
6329 /* I've only ever seen this in the wild when deleting a user from
6330 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6331 * is the user about to be deleted. I very much suspect this is the
6332 * only application of this call. To verify this, let people report
6333 * other cases. */
6335 if (!sid_check_is_builtin(&dinfo->sid)) {
6336 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6337 "global_sam_sid() = %s\n",
6338 sid_string_dbg(&dinfo->sid),
6339 sid_string_dbg(get_global_sam_sid())));
6340 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6341 return NT_STATUS_OK;
6344 force_flush_samr_cache(&dinfo->sid);
6346 result = NT_STATUS_OK;
6348 return result;
6351 /*******************************************************************
6352 _samr_QueryDomainInfo2
6353 ********************************************************************/
6355 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6356 struct samr_QueryDomainInfo2 *r)
6358 struct samr_QueryDomainInfo q;
6360 q.in.domain_handle = r->in.domain_handle;
6361 q.in.level = r->in.level;
6363 q.out.info = r->out.info;
6365 return _samr_QueryDomainInfo(p, &q);
6368 /*******************************************************************
6369 ********************************************************************/
6371 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6372 struct samr_DomInfo1 *r)
6374 time_t u_expire, u_min_age;
6376 u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6377 u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6379 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6380 (uint32_t)r->min_password_length);
6381 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6382 (uint32_t)r->password_history_length);
6383 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6384 (uint32_t)r->password_properties);
6385 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6386 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6388 return NT_STATUS_OK;
6391 /*******************************************************************
6392 ********************************************************************/
6394 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6395 struct samr_DomInfo3 *r)
6397 time_t u_logout;
6399 u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6401 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6403 return NT_STATUS_OK;
6406 /*******************************************************************
6407 ********************************************************************/
6409 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6410 struct samr_DomInfo12 *r)
6412 time_t u_lock_duration, u_reset_time;
6414 u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6415 if (u_lock_duration != -1) {
6416 u_lock_duration /= 60;
6419 u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6421 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6422 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6423 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6424 (uint32_t)r->lockout_threshold);
6426 return NT_STATUS_OK;
6429 /*******************************************************************
6430 _samr_SetDomainInfo
6431 ********************************************************************/
6433 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6434 struct samr_SetDomainInfo *r)
6436 struct samr_domain_info *dinfo;
6437 NTSTATUS status;
6438 uint32_t acc_required = 0;
6440 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6442 switch (r->in.level) {
6443 case 1: /* DomainPasswordInformation */
6444 case 12: /* DomainLockoutInformation */
6445 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6446 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6447 break;
6448 case 3: /* DomainLogoffInformation */
6449 case 4: /* DomainOemInformation */
6450 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6451 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6452 break;
6453 case 6: /* DomainReplicationInformation */
6454 case 9: /* DomainStateInformation */
6455 case 7: /* DomainServerRoleInformation */
6456 /* DOMAIN_ADMINISTER_SERVER */
6457 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6458 break;
6459 default:
6460 return NT_STATUS_INVALID_INFO_CLASS;
6463 dinfo = policy_handle_find(p, r->in.domain_handle,
6464 acc_required, NULL,
6465 struct samr_domain_info, &status);
6466 if (!NT_STATUS_IS_OK(status)) {
6467 return status;
6470 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6472 switch (r->in.level) {
6473 case 1:
6474 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6475 break;
6476 case 3:
6477 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6478 break;
6479 case 4:
6480 break;
6481 case 6:
6482 break;
6483 case 7:
6484 break;
6485 case 9:
6486 break;
6487 case 12:
6488 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6489 break;
6490 default:
6491 return NT_STATUS_INVALID_INFO_CLASS;
6494 if (!NT_STATUS_IS_OK(status)) {
6495 return status;
6498 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6500 return NT_STATUS_OK;
6503 /****************************************************************
6504 _samr_GetDisplayEnumerationIndex
6505 ****************************************************************/
6507 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6508 struct samr_GetDisplayEnumerationIndex *r)
6510 struct samr_domain_info *dinfo;
6511 uint32_t max_entries = (uint32_t) -1;
6512 uint32_t enum_context = 0;
6513 int i;
6514 uint32_t num_account = 0;
6515 struct samr_displayentry *entries = NULL;
6516 NTSTATUS status;
6518 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6520 dinfo = policy_handle_find(p, r->in.domain_handle,
6521 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6522 struct samr_domain_info, &status);
6523 if (!NT_STATUS_IS_OK(status)) {
6524 return status;
6527 if ((r->in.level < 1) || (r->in.level > 3)) {
6528 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6529 "Unknown info level (%u)\n",
6530 r->in.level));
6531 return NT_STATUS_INVALID_INFO_CLASS;
6534 become_root();
6536 /* The following done as ROOT. Don't return without unbecome_root(). */
6538 switch (r->in.level) {
6539 case 1:
6540 if (dinfo->disp_info->users == NULL) {
6541 dinfo->disp_info->users = pdb_search_users(
6542 dinfo->disp_info, ACB_NORMAL);
6543 if (dinfo->disp_info->users == NULL) {
6544 unbecome_root();
6545 return NT_STATUS_ACCESS_DENIED;
6547 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6548 "starting user enumeration at index %u\n",
6549 (unsigned int)enum_context));
6550 } else {
6551 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6552 "using cached user enumeration at index %u\n",
6553 (unsigned int)enum_context));
6555 num_account = pdb_search_entries(dinfo->disp_info->users,
6556 enum_context, max_entries,
6557 &entries);
6558 break;
6559 case 2:
6560 if (dinfo->disp_info->machines == NULL) {
6561 dinfo->disp_info->machines = pdb_search_users(
6562 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6563 if (dinfo->disp_info->machines == NULL) {
6564 unbecome_root();
6565 return NT_STATUS_ACCESS_DENIED;
6567 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6568 "starting machine enumeration at index %u\n",
6569 (unsigned int)enum_context));
6570 } else {
6571 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6572 "using cached machine enumeration at index %u\n",
6573 (unsigned int)enum_context));
6575 num_account = pdb_search_entries(dinfo->disp_info->machines,
6576 enum_context, max_entries,
6577 &entries);
6578 break;
6579 case 3:
6580 if (dinfo->disp_info->groups == NULL) {
6581 dinfo->disp_info->groups = pdb_search_groups(
6582 dinfo->disp_info);
6583 if (dinfo->disp_info->groups == NULL) {
6584 unbecome_root();
6585 return NT_STATUS_ACCESS_DENIED;
6587 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6588 "starting group enumeration at index %u\n",
6589 (unsigned int)enum_context));
6590 } else {
6591 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6592 "using cached group enumeration at index %u\n",
6593 (unsigned int)enum_context));
6595 num_account = pdb_search_entries(dinfo->disp_info->groups,
6596 enum_context, max_entries,
6597 &entries);
6598 break;
6599 default:
6600 unbecome_root();
6601 smb_panic("info class changed");
6602 break;
6605 unbecome_root();
6607 /* Ensure we cache this enumeration. */
6608 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6610 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6611 r->in.name->string));
6613 for (i=0; i<num_account; i++) {
6614 if (strequal(entries[i].account_name, r->in.name->string)) {
6615 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6616 "found %s at idx %d\n",
6617 r->in.name->string, i));
6618 *r->out.idx = i;
6619 return NT_STATUS_OK;
6623 /* assuming account_name lives at the very end */
6624 *r->out.idx = num_account;
6626 return NT_STATUS_NO_MORE_ENTRIES;
6629 /****************************************************************
6630 _samr_GetDisplayEnumerationIndex2
6631 ****************************************************************/
6633 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6634 struct samr_GetDisplayEnumerationIndex2 *r)
6636 struct samr_GetDisplayEnumerationIndex q;
6638 q.in.domain_handle = r->in.domain_handle;
6639 q.in.level = r->in.level;
6640 q.in.name = r->in.name;
6642 q.out.idx = r->out.idx;
6644 return _samr_GetDisplayEnumerationIndex(p, &q);
6647 /****************************************************************
6648 _samr_RidToSid
6649 ****************************************************************/
6651 NTSTATUS _samr_RidToSid(pipes_struct *p,
6652 struct samr_RidToSid *r)
6654 struct samr_domain_info *dinfo;
6655 NTSTATUS status;
6656 struct dom_sid sid;
6658 dinfo = policy_handle_find(p, r->in.domain_handle,
6659 0, NULL,
6660 struct samr_domain_info, &status);
6661 if (!NT_STATUS_IS_OK(status)) {
6662 return status;
6665 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6666 return NT_STATUS_NO_MEMORY;
6669 *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
6670 if (!*r->out.sid) {
6671 return NT_STATUS_NO_MEMORY;
6674 return NT_STATUS_OK;
6677 /****************************************************************
6678 ****************************************************************/
6680 NTSTATUS _samr_Shutdown(pipes_struct *p,
6681 struct samr_Shutdown *r)
6683 p->rng_fault_state = true;
6684 return NT_STATUS_NOT_IMPLEMENTED;
6687 /****************************************************************
6688 ****************************************************************/
6690 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6691 struct samr_SetMemberAttributesOfGroup *r)
6693 p->rng_fault_state = true;
6694 return NT_STATUS_NOT_IMPLEMENTED;
6697 /****************************************************************
6698 ****************************************************************/
6700 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6701 struct samr_TestPrivateFunctionsDomain *r)
6703 return NT_STATUS_NOT_IMPLEMENTED;
6706 /****************************************************************
6707 ****************************************************************/
6709 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6710 struct samr_TestPrivateFunctionsUser *r)
6712 return NT_STATUS_NOT_IMPLEMENTED;
6715 /****************************************************************
6716 ****************************************************************/
6718 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6719 struct samr_AddMultipleMembersToAlias *r)
6721 p->rng_fault_state = true;
6722 return NT_STATUS_NOT_IMPLEMENTED;
6725 /****************************************************************
6726 ****************************************************************/
6728 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6729 struct samr_RemoveMultipleMembersFromAlias *r)
6731 p->rng_fault_state = true;
6732 return NT_STATUS_NOT_IMPLEMENTED;
6735 /****************************************************************
6736 ****************************************************************/
6738 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6739 struct samr_SetBootKeyInformation *r)
6741 p->rng_fault_state = true;
6742 return NT_STATUS_NOT_IMPLEMENTED;
6745 /****************************************************************
6746 ****************************************************************/
6748 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6749 struct samr_GetBootKeyInformation *r)
6751 p->rng_fault_state = true;
6752 return NT_STATUS_NOT_IMPLEMENTED;
6755 /****************************************************************
6756 ****************************************************************/
6758 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6759 struct samr_SetDsrmPassword *r)
6761 p->rng_fault_state = true;
6762 return NT_STATUS_NOT_IMPLEMENTED;
6765 /****************************************************************
6766 ****************************************************************/
6768 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6769 struct samr_ValidatePassword *r)
6771 p->rng_fault_state = true;
6772 return NT_STATUS_NOT_IMPLEMENTED;