Fix the core of the SAMR access functions. This passes make test, but
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_samr_nt.c
blobd27924f2d34e1bf4fff8a80bbea12e7eac2080fe
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 "../libcli/auth/libcli_auth.h"
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_RPC_SRV
40 #define SAMR_USR_RIGHTS_WRITE_PW \
41 ( READ_CONTROL_ACCESS | \
42 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
43 SAMR_USER_ACCESS_SET_LOC_COM)
44 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
45 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
47 #define DISP_INFO_CACHE_TIMEOUT 10
49 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
50 #define MAX_SAM_ENTRIES_W95 50
52 struct samr_connect_info {
53 uint8_t dummy;
56 struct samr_domain_info {
57 struct dom_sid sid;
58 struct disp_info *disp_info;
61 struct samr_user_info {
62 struct dom_sid sid;
65 struct samr_group_info {
66 struct dom_sid sid;
69 struct samr_alias_info {
70 struct dom_sid sid;
73 typedef struct disp_info {
74 DOM_SID sid; /* identify which domain this is. */
75 struct pdb_search *users; /* querydispinfo 1 and 4 */
76 struct pdb_search *machines; /* querydispinfo 2 */
77 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
78 struct pdb_search *aliases; /* enumaliases */
80 uint16 enum_acb_mask;
81 struct pdb_search *enum_users; /* enumusers with a mask */
83 struct timed_event *cache_timeout_event; /* cache idle timeout
84 * handler. */
85 } DISP_INFO;
87 static const struct generic_mapping sam_generic_mapping = {
88 GENERIC_RIGHTS_SAM_READ,
89 GENERIC_RIGHTS_SAM_WRITE,
90 GENERIC_RIGHTS_SAM_EXECUTE,
91 GENERIC_RIGHTS_SAM_ALL_ACCESS};
92 static const struct generic_mapping dom_generic_mapping = {
93 GENERIC_RIGHTS_DOMAIN_READ,
94 GENERIC_RIGHTS_DOMAIN_WRITE,
95 GENERIC_RIGHTS_DOMAIN_EXECUTE,
96 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
97 static const struct generic_mapping usr_generic_mapping = {
98 GENERIC_RIGHTS_USER_READ,
99 GENERIC_RIGHTS_USER_WRITE,
100 GENERIC_RIGHTS_USER_EXECUTE,
101 GENERIC_RIGHTS_USER_ALL_ACCESS};
102 static const struct generic_mapping usr_nopwchange_generic_mapping = {
103 GENERIC_RIGHTS_USER_READ,
104 GENERIC_RIGHTS_USER_WRITE,
105 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
106 GENERIC_RIGHTS_USER_ALL_ACCESS};
107 static const struct generic_mapping grp_generic_mapping = {
108 GENERIC_RIGHTS_GROUP_READ,
109 GENERIC_RIGHTS_GROUP_WRITE,
110 GENERIC_RIGHTS_GROUP_EXECUTE,
111 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
112 static const struct generic_mapping ali_generic_mapping = {
113 GENERIC_RIGHTS_ALIAS_READ,
114 GENERIC_RIGHTS_ALIAS_WRITE,
115 GENERIC_RIGHTS_ALIAS_EXECUTE,
116 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
118 /*******************************************************************
119 *******************************************************************/
121 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
122 const struct generic_mapping *map,
123 DOM_SID *sid, uint32 sid_access )
125 DOM_SID domadmin_sid;
126 SEC_ACE ace[5]; /* at most 5 entries */
127 size_t i = 0;
129 SEC_ACL *psa = NULL;
131 /* basic access for Everyone */
133 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
134 map->generic_execute | map->generic_read, 0);
136 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
138 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
139 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
140 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
141 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
143 /* Add Full Access for Domain Admins if we are a DC */
145 if ( IS_DC ) {
146 sid_copy( &domadmin_sid, get_global_sam_sid() );
147 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
148 init_sec_ace(&ace[i++], &domadmin_sid,
149 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
152 /* if we have a sid, give it some special access */
154 if ( sid ) {
155 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
158 /* create the security descriptor */
160 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
161 return NT_STATUS_NO_MEMORY;
163 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
164 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
165 psa, sd_size)) == NULL)
166 return NT_STATUS_NO_MEMORY;
168 return NT_STATUS_OK;
171 /*******************************************************************
172 Checks if access to an object should be granted, and returns that
173 level of access for further checks.
174 ********************************************************************/
176 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
177 SE_PRIV *rights, uint32 rights_mask,
178 uint32 des_access, uint32 *acc_granted,
179 const char *debug )
181 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
182 uint32 saved_mask = 0;
184 /* check privileges; certain SAM access bits should be overridden
185 by privileges (mostly having to do with creating/modifying/deleting
186 users and groups) */
188 if (rights && !se_priv_equal(rights, &se_priv_none) &&
189 user_has_any_privilege(token, rights)) {
191 saved_mask = (des_access & rights_mask);
192 des_access &= ~saved_mask;
194 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
195 rights_mask));
199 /* check the security descriptor first */
201 status = se_access_check(psd, token, des_access, acc_granted);
202 if (NT_STATUS_IS_OK(status)) {
203 goto done;
206 /* give root a free pass */
208 if ( geteuid() == sec_initial_uid() ) {
210 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
211 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
213 *acc_granted = des_access;
215 status = NT_STATUS_OK;
216 goto done;
220 done:
221 /* add in any bits saved during the privilege check (only
222 matters is status is ok) */
224 *acc_granted |= rights_mask;
226 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
227 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
228 des_access, *acc_granted));
230 return status;
234 /*******************************************************************
235 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
236 ********************************************************************/
238 static void map_max_allowed_access(const NT_USER_TOKEN *token,
239 uint32_t *pacc_requested)
241 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
242 return;
244 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
246 /* At least try for generic read. */
247 *pacc_requested = GENERIC_READ_ACCESS;
249 /* root gets anything. */
250 if (geteuid() == sec_initial_uid()) {
251 *pacc_requested |= GENERIC_ALL_ACCESS;
252 return;
255 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
257 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
258 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
259 *pacc_requested |= GENERIC_ALL_ACCESS;
260 return;
263 /* Full access for DOMAIN\Domain Admins. */
264 if ( IS_DC ) {
265 DOM_SID domadmin_sid;
266 sid_copy( &domadmin_sid, get_global_sam_sid() );
267 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
268 if (is_sid_in_token(token, &domadmin_sid)) {
269 *pacc_requested |= GENERIC_ALL_ACCESS;
270 return;
273 /* TODO ! Check privileges. */
276 /*******************************************************************
277 Fetch or create a dispinfo struct.
278 ********************************************************************/
280 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
283 * We do a static cache for DISP_INFO's here. Explanation can be found
284 * in Jeremy's checkin message to r11793:
286 * Fix the SAMR cache so it works across completely insane
287 * client behaviour (ie.:
288 * open pipe/open SAMR handle/enumerate 0 - 1024
289 * close SAMR handle, close pipe.
290 * open pipe/open SAMR handle/enumerate 1024 - 2048...
291 * close SAMR handle, close pipe.
292 * And on ad-nausium. Amazing.... probably object-oriented
293 * client side programming in action yet again.
294 * This change should *massively* improve performance when
295 * enumerating users from an LDAP database.
296 * Jeremy.
298 * "Our" and the builtin domain are the only ones where we ever
299 * enumerate stuff, so just cache 2 entries.
302 static struct disp_info *builtin_dispinfo;
303 static struct disp_info *domain_dispinfo;
305 /* There are two cases to consider here:
306 1) The SID is a domain SID and we look for an equality match, or
307 2) This is an account SID and so we return the DISP_INFO* for our
308 domain */
310 if (psid == NULL) {
311 return NULL;
314 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
316 * Necessary only once, but it does not really hurt.
318 if (builtin_dispinfo == NULL) {
319 builtin_dispinfo = talloc_zero(
320 talloc_autofree_context(), struct disp_info);
321 if (builtin_dispinfo == NULL) {
322 return NULL;
325 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
327 return builtin_dispinfo;
330 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
332 * Necessary only once, but it does not really hurt.
334 if (domain_dispinfo == NULL) {
335 domain_dispinfo = talloc_zero(
336 talloc_autofree_context(), struct disp_info);
337 if (domain_dispinfo == NULL) {
338 return NULL;
341 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
343 return domain_dispinfo;
346 return NULL;
349 /*******************************************************************
350 Function to free the per SID data.
351 ********************************************************************/
353 static void free_samr_cache(DISP_INFO *disp_info)
355 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
356 sid_string_dbg(&disp_info->sid)));
358 /* We need to become root here because the paged search might have to
359 * tell the LDAP server we're not interested in the rest anymore. */
361 become_root();
363 TALLOC_FREE(disp_info->users);
364 TALLOC_FREE(disp_info->machines);
365 TALLOC_FREE(disp_info->groups);
366 TALLOC_FREE(disp_info->aliases);
367 TALLOC_FREE(disp_info->enum_users);
369 unbecome_root();
372 /*******************************************************************
373 Idle event handler. Throw away the disp info cache.
374 ********************************************************************/
376 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
377 struct timed_event *te,
378 struct timeval now,
379 void *private_data)
381 DISP_INFO *disp_info = (DISP_INFO *)private_data;
383 TALLOC_FREE(disp_info->cache_timeout_event);
385 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
386 "out\n"));
387 free_samr_cache(disp_info);
390 /*******************************************************************
391 Setup cache removal idle event handler.
392 ********************************************************************/
394 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
396 /* Remove any pending timeout and update. */
398 TALLOC_FREE(disp_info->cache_timeout_event);
400 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
401 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
402 (unsigned int)secs_fromnow ));
404 disp_info->cache_timeout_event = event_add_timed(
405 smbd_event_context(), NULL,
406 timeval_current_ofs(secs_fromnow, 0),
407 disp_info_cache_idle_timeout_handler, (void *)disp_info);
410 /*******************************************************************
411 Force flush any cache. We do this on any samr_set_xxx call.
412 We must also remove the timeout handler.
413 ********************************************************************/
415 static void force_flush_samr_cache(const struct dom_sid *sid)
417 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
419 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
420 return;
423 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
424 TALLOC_FREE(disp_info->cache_timeout_event);
425 free_samr_cache(disp_info);
428 /*******************************************************************
429 Ensure password info is never given out. Paranioa... JRA.
430 ********************************************************************/
432 static void samr_clear_sam_passwd(struct samu *sam_pass)
435 if (!sam_pass)
436 return;
438 /* These now zero out the old password */
440 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
441 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
444 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
446 struct samr_displayentry *entry;
448 if (sid_check_is_builtin(&info->sid)) {
449 /* No users in builtin. */
450 return 0;
453 if (info->users == NULL) {
454 info->users = pdb_search_users(info, acct_flags);
455 if (info->users == NULL) {
456 return 0;
459 /* Fetch the last possible entry, thus trigger an enumeration */
460 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
462 /* Ensure we cache this enumeration. */
463 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
465 return info->users->num_entries;
468 static uint32 count_sam_groups(struct disp_info *info)
470 struct samr_displayentry *entry;
472 if (sid_check_is_builtin(&info->sid)) {
473 /* No groups in builtin. */
474 return 0;
477 if (info->groups == NULL) {
478 info->groups = pdb_search_groups(info);
479 if (info->groups == NULL) {
480 return 0;
483 /* Fetch the last possible entry, thus trigger an enumeration */
484 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
486 /* Ensure we cache this enumeration. */
487 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
489 return info->groups->num_entries;
492 static uint32 count_sam_aliases(struct disp_info *info)
494 struct samr_displayentry *entry;
496 if (info->aliases == NULL) {
497 info->aliases = pdb_search_aliases(info, &info->sid);
498 if (info->aliases == NULL) {
499 return 0;
502 /* Fetch the last possible entry, thus trigger an enumeration */
503 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
505 /* Ensure we cache this enumeration. */
506 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
508 return info->aliases->num_entries;
511 /*******************************************************************
512 _samr_Close
513 ********************************************************************/
515 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
517 if (!close_policy_hnd(p, r->in.handle)) {
518 return NT_STATUS_INVALID_HANDLE;
521 ZERO_STRUCTP(r->out.handle);
523 return NT_STATUS_OK;
526 /*******************************************************************
527 _samr_OpenDomain
528 ********************************************************************/
530 NTSTATUS _samr_OpenDomain(pipes_struct *p,
531 struct samr_OpenDomain *r)
533 struct samr_connect_info *cinfo;
534 struct samr_domain_info *dinfo;
535 SEC_DESC *psd = NULL;
536 uint32 acc_granted;
537 uint32 des_access = r->in.access_mask;
538 NTSTATUS status;
539 size_t sd_size;
540 SE_PRIV se_rights;
542 /* find the connection policy handle. */
544 cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
545 struct samr_connect_info, &status);
546 if (!NT_STATUS_IS_OK(status)) {
547 return status;
550 /*check if access can be granted as requested by client. */
551 map_max_allowed_access(p->server_info->ptok, &des_access);
553 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
554 se_map_generic( &des_access, &dom_generic_mapping );
557 * Users with SeMachineAccount or SeAddUser get additional
558 * SAMR_DOMAIN_ACCESS_CREATE_USER access, but no more.
560 se_priv_copy( &se_rights, &se_machine_account );
561 se_priv_add( &se_rights, &se_add_users );
563 status = access_check_samr_object( psd, p->server_info->ptok,
564 &se_rights, SAMR_DOMAIN_ACCESS_CREATE_USER, des_access,
565 &acc_granted, "_samr_OpenDomain" );
567 if ( !NT_STATUS_IS_OK(status) )
568 return status;
570 if (!sid_check_is_domain(r->in.sid) &&
571 !sid_check_is_builtin(r->in.sid)) {
572 return NT_STATUS_NO_SUCH_DOMAIN;
575 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
576 struct samr_domain_info, &status);
577 if (!NT_STATUS_IS_OK(status)) {
578 return status;
580 dinfo->sid = *r->in.sid;
581 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
583 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
585 return NT_STATUS_OK;
588 /*******************************************************************
589 _samr_GetUserPwInfo
590 ********************************************************************/
592 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
593 struct samr_GetUserPwInfo *r)
595 struct samr_user_info *uinfo;
596 enum lsa_SidType sid_type;
597 uint32_t min_password_length = 0;
598 uint32_t password_properties = 0;
599 bool ret = false;
600 NTSTATUS status;
602 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
604 uinfo = policy_handle_find(p, r->in.user_handle,
605 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
606 struct samr_user_info, &status);
607 if (!NT_STATUS_IS_OK(status)) {
608 return status;
611 if (!sid_check_is_in_our_domain(&uinfo->sid)) {
612 return NT_STATUS_OBJECT_TYPE_MISMATCH;
615 become_root();
616 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
617 unbecome_root();
618 if (ret == false) {
619 return NT_STATUS_NO_SUCH_USER;
622 switch (sid_type) {
623 case SID_NAME_USER:
624 become_root();
625 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
626 &min_password_length);
627 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
628 &password_properties);
629 unbecome_root();
631 if (lp_check_password_script() && *lp_check_password_script()) {
632 password_properties |= DOMAIN_PASSWORD_COMPLEX;
635 break;
636 default:
637 break;
640 r->out.info->min_password_length = min_password_length;
641 r->out.info->password_properties = password_properties;
643 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
645 return NT_STATUS_OK;
648 /*******************************************************************
649 _samr_SetSecurity
650 ********************************************************************/
652 NTSTATUS _samr_SetSecurity(pipes_struct *p,
653 struct samr_SetSecurity *r)
655 struct samr_user_info *uinfo;
656 uint32 i;
657 SEC_ACL *dacl;
658 bool ret;
659 struct samu *sampass=NULL;
660 NTSTATUS status;
662 uinfo = policy_handle_find(p, r->in.handle,
663 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
664 struct samr_user_info, &status);
665 if (!NT_STATUS_IS_OK(status)) {
666 return status;
669 if (!(sampass = samu_new( p->mem_ctx))) {
670 DEBUG(0,("No memory!\n"));
671 return NT_STATUS_NO_MEMORY;
674 /* get the user record */
675 become_root();
676 ret = pdb_getsampwsid(sampass, &uinfo->sid);
677 unbecome_root();
679 if (!ret) {
680 DEBUG(4, ("User %s not found\n",
681 sid_string_dbg(&uinfo->sid)));
682 TALLOC_FREE(sampass);
683 return NT_STATUS_INVALID_HANDLE;
686 dacl = r->in.sdbuf->sd->dacl;
687 for (i=0; i < dacl->num_aces; i++) {
688 if (sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
689 ret = pdb_set_pass_can_change(sampass,
690 (dacl->aces[i].access_mask &
691 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
692 True: False);
693 break;
697 if (!ret) {
698 TALLOC_FREE(sampass);
699 return NT_STATUS_ACCESS_DENIED;
702 become_root();
703 status = pdb_update_sam_account(sampass);
704 unbecome_root();
706 TALLOC_FREE(sampass);
708 return status;
711 /*******************************************************************
712 build correct perms based on policies and password times for _samr_query_sec_obj
713 *******************************************************************/
714 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
716 struct samu *sampass=NULL;
717 bool ret;
719 if ( !(sampass = samu_new( mem_ctx )) ) {
720 DEBUG(0,("No memory!\n"));
721 return False;
724 become_root();
725 ret = pdb_getsampwsid(sampass, user_sid);
726 unbecome_root();
728 if (ret == False) {
729 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
730 TALLOC_FREE(sampass);
731 return False;
734 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
736 if (pdb_get_pass_can_change(sampass)) {
737 TALLOC_FREE(sampass);
738 return True;
740 TALLOC_FREE(sampass);
741 return False;
745 /*******************************************************************
746 _samr_QuerySecurity
747 ********************************************************************/
749 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
750 struct samr_QuerySecurity *r)
752 struct samr_connect_info *cinfo;
753 struct samr_domain_info *dinfo;
754 struct samr_user_info *uinfo;
755 struct samr_group_info *ginfo;
756 struct samr_alias_info *ainfo;
757 NTSTATUS status;
758 SEC_DESC * psd = NULL;
759 size_t sd_size;
761 cinfo = policy_handle_find(p, r->in.handle,
762 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
763 struct samr_connect_info, &status);
764 if (NT_STATUS_IS_OK(status)) {
765 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
766 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
767 &sam_generic_mapping, NULL, 0);
768 goto done;
771 dinfo = policy_handle_find(p, r->in.handle,
772 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
773 struct samr_domain_info, &status);
774 if (NT_STATUS_IS_OK(status)) {
775 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
776 "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
778 * TODO: Builtin probably needs a different SD with restricted
779 * write access
781 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
782 &dom_generic_mapping, NULL, 0);
783 goto done;
786 uinfo = policy_handle_find(p, r->in.handle,
787 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
788 struct samr_user_info, &status);
789 if (NT_STATUS_IS_OK(status)) {
790 DEBUG(10,("_samr_QuerySecurity: querying security on user "
791 "Object with SID: %s\n",
792 sid_string_dbg(&uinfo->sid)));
793 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
794 status = make_samr_object_sd(
795 p->mem_ctx, &psd, &sd_size,
796 &usr_generic_mapping,
797 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
798 } else {
799 status = make_samr_object_sd(
800 p->mem_ctx, &psd, &sd_size,
801 &usr_nopwchange_generic_mapping,
802 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
804 goto done;
807 ginfo = policy_handle_find(p, r->in.handle,
808 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
809 struct samr_group_info, &status);
810 if (NT_STATUS_IS_OK(status)) {
812 * TODO: different SDs have to be generated for aliases groups
813 * and users. Currently all three get a default user SD
815 DEBUG(10,("_samr_QuerySecurity: querying security on group "
816 "Object with SID: %s\n",
817 sid_string_dbg(&ginfo->sid)));
818 status = make_samr_object_sd(
819 p->mem_ctx, &psd, &sd_size,
820 &usr_nopwchange_generic_mapping,
821 &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
822 goto done;
825 ainfo = policy_handle_find(p, r->in.handle,
826 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
827 struct samr_alias_info, &status);
828 if (NT_STATUS_IS_OK(status)) {
830 * TODO: different SDs have to be generated for aliases groups
831 * and users. Currently all three get a default user SD
833 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
834 "Object with SID: %s\n",
835 sid_string_dbg(&ainfo->sid)));
836 status = make_samr_object_sd(
837 p->mem_ctx, &psd, &sd_size,
838 &usr_nopwchange_generic_mapping,
839 &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
840 goto done;
843 return NT_STATUS_OBJECT_TYPE_MISMATCH;
844 done:
845 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
846 return NT_STATUS_NO_MEMORY;
848 return status;
851 /*******************************************************************
852 makes a SAM_ENTRY / UNISTR2* structure from a user list.
853 ********************************************************************/
855 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
856 struct samr_SamEntry **sam_pp,
857 uint32_t num_entries,
858 uint32_t start_idx,
859 struct samr_displayentry *entries)
861 uint32_t i;
862 struct samr_SamEntry *sam;
864 *sam_pp = NULL;
866 if (num_entries == 0) {
867 return NT_STATUS_OK;
870 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
871 if (sam == NULL) {
872 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
873 return NT_STATUS_NO_MEMORY;
876 for (i = 0; i < num_entries; i++) {
877 #if 0
879 * usrmgr expects a non-NULL terminated string with
880 * trust relationships
882 if (entries[i].acct_flags & ACB_DOMTRUST) {
883 init_unistr2(&uni_temp_name, entries[i].account_name,
884 UNI_FLAGS_NONE);
885 } else {
886 init_unistr2(&uni_temp_name, entries[i].account_name,
887 UNI_STR_TERMINATE);
889 #endif
890 init_lsa_String(&sam[i].name, entries[i].account_name);
891 sam[i].idx = entries[i].rid;
894 *sam_pp = sam;
896 return NT_STATUS_OK;
899 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
901 /*******************************************************************
902 _samr_EnumDomainUsers
903 ********************************************************************/
905 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
906 struct samr_EnumDomainUsers *r)
908 NTSTATUS status;
909 struct samr_domain_info *dinfo;
910 int num_account;
911 uint32 enum_context = *r->in.resume_handle;
912 enum remote_arch_types ra_type = get_remote_arch();
913 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
914 uint32 max_entries = max_sam_entries;
915 struct samr_displayentry *entries = NULL;
916 struct samr_SamArray *samr_array = NULL;
917 struct samr_SamEntry *samr_entries = NULL;
919 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
921 dinfo = policy_handle_find(p, r->in.domain_handle,
922 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
923 struct samr_domain_info, &status);
924 if (!NT_STATUS_IS_OK(status)) {
925 return status;
928 if (sid_check_is_builtin(&dinfo->sid)) {
929 /* No users in builtin. */
930 *r->out.resume_handle = *r->in.resume_handle;
931 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
932 return status;
935 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
936 if (!samr_array) {
937 return NT_STATUS_NO_MEMORY;
939 *r->out.sam = samr_array;
941 become_root();
943 /* AS ROOT !!!! */
945 if ((dinfo->disp_info->enum_users != NULL) &&
946 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
947 TALLOC_FREE(dinfo->disp_info->enum_users);
950 if (dinfo->disp_info->enum_users == NULL) {
951 dinfo->disp_info->enum_users = pdb_search_users(
952 dinfo->disp_info, r->in.acct_flags);
953 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
956 if (dinfo->disp_info->enum_users == NULL) {
957 /* END AS ROOT !!!! */
958 unbecome_root();
959 return NT_STATUS_ACCESS_DENIED;
962 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
963 enum_context, max_entries,
964 &entries);
966 /* END AS ROOT !!!! */
968 unbecome_root();
970 if (num_account == 0) {
971 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
972 "total entries\n"));
973 *r->out.resume_handle = *r->in.resume_handle;
974 return NT_STATUS_OK;
977 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
978 num_account, enum_context,
979 entries);
980 if (!NT_STATUS_IS_OK(status)) {
981 return status;
984 if (max_entries <= num_account) {
985 status = STATUS_MORE_ENTRIES;
986 } else {
987 status = NT_STATUS_OK;
990 /* Ensure we cache this enumeration. */
991 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
993 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
995 samr_array->count = num_account;
996 samr_array->entries = samr_entries;
998 *r->out.resume_handle = *r->in.resume_handle + num_account;
999 *r->out.num_entries = num_account;
1001 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1003 return status;
1006 /*******************************************************************
1007 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1008 ********************************************************************/
1010 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1011 struct samr_SamEntry **sam_pp,
1012 uint32_t num_sam_entries,
1013 struct samr_displayentry *entries)
1015 struct samr_SamEntry *sam;
1016 uint32_t i;
1018 *sam_pp = NULL;
1020 if (num_sam_entries == 0) {
1021 return;
1024 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1025 if (sam == NULL) {
1026 return;
1029 for (i = 0; i < num_sam_entries; i++) {
1031 * JRA. I think this should include the null. TNG does not.
1033 init_lsa_String(&sam[i].name, entries[i].account_name);
1034 sam[i].idx = entries[i].rid;
1037 *sam_pp = sam;
1040 /*******************************************************************
1041 _samr_EnumDomainGroups
1042 ********************************************************************/
1044 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1045 struct samr_EnumDomainGroups *r)
1047 NTSTATUS status;
1048 struct samr_domain_info *dinfo;
1049 struct samr_displayentry *groups;
1050 uint32 num_groups;
1051 struct samr_SamArray *samr_array = NULL;
1052 struct samr_SamEntry *samr_entries = NULL;
1054 dinfo = policy_handle_find(p, r->in.domain_handle,
1055 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1056 struct samr_domain_info, &status);
1057 if (!NT_STATUS_IS_OK(status)) {
1058 return status;
1061 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1063 if (sid_check_is_builtin(&dinfo->sid)) {
1064 /* No groups in builtin. */
1065 *r->out.resume_handle = *r->in.resume_handle;
1066 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1067 return status;
1070 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1071 if (!samr_array) {
1072 return NT_STATUS_NO_MEMORY;
1075 /* the domain group array is being allocated in the function below */
1077 become_root();
1079 if (dinfo->disp_info->groups == NULL) {
1080 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1082 if (dinfo->disp_info->groups == NULL) {
1083 unbecome_root();
1084 return NT_STATUS_ACCESS_DENIED;
1088 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1089 *r->in.resume_handle,
1090 MAX_SAM_ENTRIES, &groups);
1091 unbecome_root();
1093 /* Ensure we cache this enumeration. */
1094 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1096 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1097 num_groups, groups);
1099 samr_array->count = num_groups;
1100 samr_array->entries = samr_entries;
1102 *r->out.sam = samr_array;
1103 *r->out.num_entries = num_groups;
1104 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1106 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1108 return status;
1111 /*******************************************************************
1112 _samr_EnumDomainAliases
1113 ********************************************************************/
1115 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1116 struct samr_EnumDomainAliases *r)
1118 NTSTATUS status;
1119 struct samr_domain_info *dinfo;
1120 struct samr_displayentry *aliases;
1121 uint32 num_aliases = 0;
1122 struct samr_SamArray *samr_array = NULL;
1123 struct samr_SamEntry *samr_entries = NULL;
1125 dinfo = policy_handle_find(p, r->in.domain_handle,
1126 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1127 struct samr_domain_info, &status);
1128 if (!NT_STATUS_IS_OK(status)) {
1129 return status;
1132 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1133 sid_string_dbg(&dinfo->sid)));
1135 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1136 if (!samr_array) {
1137 return NT_STATUS_NO_MEMORY;
1140 become_root();
1142 if (dinfo->disp_info->aliases == NULL) {
1143 dinfo->disp_info->aliases = pdb_search_aliases(
1144 dinfo->disp_info, &dinfo->sid);
1145 if (dinfo->disp_info->aliases == NULL) {
1146 unbecome_root();
1147 return NT_STATUS_ACCESS_DENIED;
1151 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1152 *r->in.resume_handle,
1153 MAX_SAM_ENTRIES, &aliases);
1154 unbecome_root();
1156 /* Ensure we cache this enumeration. */
1157 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1159 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1160 num_aliases, aliases);
1162 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1164 samr_array->count = num_aliases;
1165 samr_array->entries = samr_entries;
1167 *r->out.sam = samr_array;
1168 *r->out.num_entries = num_aliases;
1169 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1171 return status;
1174 /*******************************************************************
1175 inits a samr_DispInfoGeneral structure.
1176 ********************************************************************/
1178 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1179 struct samr_DispInfoGeneral *r,
1180 uint32_t num_entries,
1181 uint32_t start_idx,
1182 struct samr_displayentry *entries)
1184 uint32 i;
1186 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1188 if (num_entries == 0) {
1189 return NT_STATUS_OK;
1192 r->count = num_entries;
1194 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1195 if (!r->entries) {
1196 return NT_STATUS_NO_MEMORY;
1199 for (i = 0; i < num_entries ; i++) {
1201 init_lsa_String(&r->entries[i].account_name,
1202 entries[i].account_name);
1204 init_lsa_String(&r->entries[i].description,
1205 entries[i].description);
1207 init_lsa_String(&r->entries[i].full_name,
1208 entries[i].fullname);
1210 r->entries[i].rid = entries[i].rid;
1211 r->entries[i].acct_flags = entries[i].acct_flags;
1212 r->entries[i].idx = start_idx+i+1;
1215 return NT_STATUS_OK;
1218 /*******************************************************************
1219 inits a samr_DispInfoFull structure.
1220 ********************************************************************/
1222 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1223 struct samr_DispInfoFull *r,
1224 uint32_t num_entries,
1225 uint32_t start_idx,
1226 struct samr_displayentry *entries)
1228 uint32_t i;
1230 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1232 if (num_entries == 0) {
1233 return NT_STATUS_OK;
1236 r->count = num_entries;
1238 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1239 if (!r->entries) {
1240 return NT_STATUS_NO_MEMORY;
1243 for (i = 0; i < num_entries ; i++) {
1245 init_lsa_String(&r->entries[i].account_name,
1246 entries[i].account_name);
1248 init_lsa_String(&r->entries[i].description,
1249 entries[i].description);
1251 r->entries[i].rid = entries[i].rid;
1252 r->entries[i].acct_flags = entries[i].acct_flags;
1253 r->entries[i].idx = start_idx+i+1;
1256 return NT_STATUS_OK;
1259 /*******************************************************************
1260 inits a samr_DispInfoFullGroups structure.
1261 ********************************************************************/
1263 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1264 struct samr_DispInfoFullGroups *r,
1265 uint32_t num_entries,
1266 uint32_t start_idx,
1267 struct samr_displayentry *entries)
1269 uint32_t i;
1271 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1273 if (num_entries == 0) {
1274 return NT_STATUS_OK;
1277 r->count = num_entries;
1279 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1280 if (!r->entries) {
1281 return NT_STATUS_NO_MEMORY;
1284 for (i = 0; i < num_entries ; i++) {
1286 init_lsa_String(&r->entries[i].account_name,
1287 entries[i].account_name);
1289 init_lsa_String(&r->entries[i].description,
1290 entries[i].description);
1292 r->entries[i].rid = entries[i].rid;
1293 r->entries[i].acct_flags = entries[i].acct_flags;
1294 r->entries[i].idx = start_idx+i+1;
1297 return NT_STATUS_OK;
1300 /*******************************************************************
1301 inits a samr_DispInfoAscii structure.
1302 ********************************************************************/
1304 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1305 struct samr_DispInfoAscii *r,
1306 uint32_t num_entries,
1307 uint32_t start_idx,
1308 struct samr_displayentry *entries)
1310 uint32_t i;
1312 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1314 if (num_entries == 0) {
1315 return NT_STATUS_OK;
1318 r->count = num_entries;
1320 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1321 if (!r->entries) {
1322 return NT_STATUS_NO_MEMORY;
1325 for (i = 0; i < num_entries ; i++) {
1327 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1328 entries[i].account_name);
1330 r->entries[i].idx = start_idx+i+1;
1333 return NT_STATUS_OK;
1336 /*******************************************************************
1337 inits a samr_DispInfoAscii structure.
1338 ********************************************************************/
1340 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1341 struct samr_DispInfoAscii *r,
1342 uint32_t num_entries,
1343 uint32_t start_idx,
1344 struct samr_displayentry *entries)
1346 uint32_t i;
1348 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1350 if (num_entries == 0) {
1351 return NT_STATUS_OK;
1354 r->count = num_entries;
1356 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1357 if (!r->entries) {
1358 return NT_STATUS_NO_MEMORY;
1361 for (i = 0; i < num_entries ; i++) {
1363 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1364 entries[i].account_name);
1366 r->entries[i].idx = start_idx+i+1;
1369 return NT_STATUS_OK;
1372 /*******************************************************************
1373 _samr_QueryDisplayInfo
1374 ********************************************************************/
1376 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1377 struct samr_QueryDisplayInfo *r)
1379 NTSTATUS status;
1380 struct samr_domain_info *dinfo;
1381 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1383 uint32 max_entries = r->in.max_entries;
1384 uint32 enum_context = r->in.start_idx;
1385 uint32 max_size = r->in.buf_size;
1387 union samr_DispInfo *disp_info = r->out.info;
1389 uint32 temp_size=0, total_data_size=0;
1390 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1391 uint32 num_account = 0;
1392 enum remote_arch_types ra_type = get_remote_arch();
1393 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1394 struct samr_displayentry *entries = NULL;
1396 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1398 dinfo = policy_handle_find(p, r->in.domain_handle,
1399 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1400 struct samr_domain_info, &status);
1401 if (!NT_STATUS_IS_OK(status)) {
1402 return status;
1405 if (sid_check_is_builtin(&dinfo->sid)) {
1406 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1407 return NT_STATUS_OK;
1411 * calculate how many entries we will return.
1412 * based on
1413 * - the number of entries the client asked
1414 * - our limit on that
1415 * - the starting point (enumeration context)
1416 * - the buffer size the client will accept
1420 * We are a lot more like W2K. Instead of reading the SAM
1421 * each time to find the records we need to send back,
1422 * we read it once and link that copy to the sam handle.
1423 * For large user list (over the MAX_SAM_ENTRIES)
1424 * it's a definitive win.
1425 * second point to notice: between enumerations
1426 * our sam is now the same as it's a snapshoot.
1427 * third point: got rid of the static SAM_USER_21 struct
1428 * no more intermediate.
1429 * con: it uses much more memory, as a full copy is stored
1430 * in memory.
1432 * If you want to change it, think twice and think
1433 * of the second point , that's really important.
1435 * JFM, 12/20/2001
1438 if ((r->in.level < 1) || (r->in.level > 5)) {
1439 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1440 (unsigned int)r->in.level ));
1441 return NT_STATUS_INVALID_INFO_CLASS;
1444 /* first limit the number of entries we will return */
1445 if(max_entries > max_sam_entries) {
1446 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1447 "entries, limiting to %d\n", max_entries,
1448 max_sam_entries));
1449 max_entries = max_sam_entries;
1452 /* calculate the size and limit on the number of entries we will
1453 * return */
1455 temp_size=max_entries*struct_size;
1457 if (temp_size>max_size) {
1458 max_entries=MIN((max_size/struct_size),max_entries);;
1459 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1460 "only %d entries\n", max_entries));
1463 become_root();
1465 /* THe following done as ROOT. Don't return without unbecome_root(). */
1467 switch (r->in.level) {
1468 case 0x1:
1469 case 0x4:
1470 if (dinfo->disp_info->users == NULL) {
1471 dinfo->disp_info->users = pdb_search_users(
1472 dinfo->disp_info, ACB_NORMAL);
1473 if (dinfo->disp_info->users == NULL) {
1474 unbecome_root();
1475 return NT_STATUS_ACCESS_DENIED;
1477 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1478 (unsigned int)enum_context ));
1479 } else {
1480 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1481 (unsigned int)enum_context ));
1484 num_account = pdb_search_entries(dinfo->disp_info->users,
1485 enum_context, max_entries,
1486 &entries);
1487 break;
1488 case 0x2:
1489 if (dinfo->disp_info->machines == NULL) {
1490 dinfo->disp_info->machines = pdb_search_users(
1491 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1492 if (dinfo->disp_info->machines == NULL) {
1493 unbecome_root();
1494 return NT_STATUS_ACCESS_DENIED;
1496 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1497 (unsigned int)enum_context ));
1498 } else {
1499 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1500 (unsigned int)enum_context ));
1503 num_account = pdb_search_entries(dinfo->disp_info->machines,
1504 enum_context, max_entries,
1505 &entries);
1506 break;
1507 case 0x3:
1508 case 0x5:
1509 if (dinfo->disp_info->groups == NULL) {
1510 dinfo->disp_info->groups = pdb_search_groups(
1511 dinfo->disp_info);
1512 if (dinfo->disp_info->groups == NULL) {
1513 unbecome_root();
1514 return NT_STATUS_ACCESS_DENIED;
1516 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1517 (unsigned int)enum_context ));
1518 } else {
1519 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1520 (unsigned int)enum_context ));
1523 num_account = pdb_search_entries(dinfo->disp_info->groups,
1524 enum_context, max_entries,
1525 &entries);
1526 break;
1527 default:
1528 unbecome_root();
1529 smb_panic("info class changed");
1530 break;
1532 unbecome_root();
1535 /* Now create reply structure */
1536 switch (r->in.level) {
1537 case 0x1:
1538 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1539 num_account, enum_context,
1540 entries);
1541 break;
1542 case 0x2:
1543 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1544 num_account, enum_context,
1545 entries);
1546 break;
1547 case 0x3:
1548 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1549 num_account, enum_context,
1550 entries);
1551 break;
1552 case 0x4:
1553 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1554 num_account, enum_context,
1555 entries);
1556 break;
1557 case 0x5:
1558 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1559 num_account, enum_context,
1560 entries);
1561 break;
1562 default:
1563 smb_panic("info class changed");
1564 break;
1567 if (!NT_STATUS_IS_OK(disp_ret))
1568 return disp_ret;
1570 /* calculate the total size */
1571 total_data_size=num_account*struct_size;
1573 if (max_entries <= num_account) {
1574 status = STATUS_MORE_ENTRIES;
1575 } else {
1576 status = NT_STATUS_OK;
1579 /* Ensure we cache this enumeration. */
1580 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1582 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1584 *r->out.total_size = total_data_size;
1585 *r->out.returned_size = temp_size;
1587 return status;
1590 /****************************************************************
1591 _samr_QueryDisplayInfo2
1592 ****************************************************************/
1594 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1595 struct samr_QueryDisplayInfo2 *r)
1597 struct samr_QueryDisplayInfo q;
1599 q.in.domain_handle = r->in.domain_handle;
1600 q.in.level = r->in.level;
1601 q.in.start_idx = r->in.start_idx;
1602 q.in.max_entries = r->in.max_entries;
1603 q.in.buf_size = r->in.buf_size;
1605 q.out.total_size = r->out.total_size;
1606 q.out.returned_size = r->out.returned_size;
1607 q.out.info = r->out.info;
1609 return _samr_QueryDisplayInfo(p, &q);
1612 /****************************************************************
1613 _samr_QueryDisplayInfo3
1614 ****************************************************************/
1616 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1617 struct samr_QueryDisplayInfo3 *r)
1619 struct samr_QueryDisplayInfo q;
1621 q.in.domain_handle = r->in.domain_handle;
1622 q.in.level = r->in.level;
1623 q.in.start_idx = r->in.start_idx;
1624 q.in.max_entries = r->in.max_entries;
1625 q.in.buf_size = r->in.buf_size;
1627 q.out.total_size = r->out.total_size;
1628 q.out.returned_size = r->out.returned_size;
1629 q.out.info = r->out.info;
1631 return _samr_QueryDisplayInfo(p, &q);
1634 /*******************************************************************
1635 _samr_QueryAliasInfo
1636 ********************************************************************/
1638 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1639 struct samr_QueryAliasInfo *r)
1641 struct samr_alias_info *ainfo;
1642 struct acct_info info;
1643 NTSTATUS status;
1644 union samr_AliasInfo *alias_info = NULL;
1645 const char *alias_name = NULL;
1646 const char *alias_description = NULL;
1648 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1650 ainfo = policy_handle_find(p, r->in.alias_handle,
1651 SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1652 struct samr_alias_info, &status);
1653 if (!NT_STATUS_IS_OK(status)) {
1654 return status;
1657 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1658 if (!alias_info) {
1659 return NT_STATUS_NO_MEMORY;
1662 become_root();
1663 status = pdb_get_aliasinfo(&ainfo->sid, &info);
1664 unbecome_root();
1666 if ( !NT_STATUS_IS_OK(status))
1667 return status;
1669 /* FIXME: info contains fstrings */
1670 alias_name = talloc_strdup(r, info.acct_name);
1671 alias_description = talloc_strdup(r, info.acct_desc);
1673 switch (r->in.level) {
1674 case ALIASINFOALL:
1675 alias_info->all.name.string = alias_name;
1676 alias_info->all.num_members = 1; /* ??? */
1677 alias_info->all.description.string = alias_description;
1678 break;
1679 case ALIASINFONAME:
1680 alias_info->name.string = alias_name;
1681 break;
1682 case ALIASINFODESCRIPTION:
1683 alias_info->description.string = alias_description;
1684 break;
1685 default:
1686 return NT_STATUS_INVALID_INFO_CLASS;
1689 *r->out.info = alias_info;
1691 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1693 return NT_STATUS_OK;
1696 /*******************************************************************
1697 _samr_LookupNames
1698 ********************************************************************/
1700 NTSTATUS _samr_LookupNames(pipes_struct *p,
1701 struct samr_LookupNames *r)
1703 struct samr_domain_info *dinfo;
1704 NTSTATUS status;
1705 uint32 *rid;
1706 enum lsa_SidType *type;
1707 int i;
1708 int num_rids = r->in.num_names;
1709 struct samr_Ids rids, types;
1710 uint32_t num_mapped = 0;
1712 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1714 dinfo = policy_handle_find(p, r->in.domain_handle,
1715 0 /* Don't know the acc_bits yet */, NULL,
1716 struct samr_domain_info, &status);
1717 if (!NT_STATUS_IS_OK(status)) {
1718 return status;
1721 if (num_rids > MAX_SAM_ENTRIES) {
1722 num_rids = MAX_SAM_ENTRIES;
1723 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1726 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1727 NT_STATUS_HAVE_NO_MEMORY(rid);
1729 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1730 NT_STATUS_HAVE_NO_MEMORY(type);
1732 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1733 sid_string_dbg(&dinfo->sid)));
1735 for (i = 0; i < num_rids; i++) {
1737 status = NT_STATUS_NONE_MAPPED;
1738 type[i] = SID_NAME_UNKNOWN;
1740 rid[i] = 0xffffffff;
1742 if (sid_check_is_builtin(&dinfo->sid)) {
1743 if (lookup_builtin_name(r->in.names[i].string,
1744 &rid[i]))
1746 type[i] = SID_NAME_ALIAS;
1748 } else {
1749 lookup_global_sam_name(r->in.names[i].string, 0,
1750 &rid[i], &type[i]);
1753 if (type[i] != SID_NAME_UNKNOWN) {
1754 num_mapped++;
1758 if (num_mapped == num_rids) {
1759 status = NT_STATUS_OK;
1760 } else if (num_mapped == 0) {
1761 status = NT_STATUS_NONE_MAPPED;
1762 } else {
1763 status = STATUS_SOME_UNMAPPED;
1766 rids.count = num_rids;
1767 rids.ids = rid;
1769 types.count = num_rids;
1770 types.ids = type;
1772 *r->out.rids = rids;
1773 *r->out.types = types;
1775 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1777 return status;
1780 /****************************************************************
1781 _samr_ChangePasswordUser
1782 ****************************************************************/
1784 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1785 struct samr_ChangePasswordUser *r)
1787 NTSTATUS status;
1788 bool ret = false;
1789 struct samr_user_info *uinfo;
1790 struct samu *pwd;
1791 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1792 struct samr_Password lm_pwd, nt_pwd;
1794 uinfo = policy_handle_find(p, r->in.user_handle,
1795 SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1796 struct samr_user_info, &status);
1797 if (!NT_STATUS_IS_OK(status)) {
1798 return status;
1801 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1802 sid_string_dbg(&uinfo->sid)));
1804 if (!(pwd = samu_new(NULL))) {
1805 return NT_STATUS_NO_MEMORY;
1808 become_root();
1809 ret = pdb_getsampwsid(pwd, &uinfo->sid);
1810 unbecome_root();
1812 if (!ret) {
1813 TALLOC_FREE(pwd);
1814 return NT_STATUS_WRONG_PASSWORD;
1818 const uint8_t *lm_pass, *nt_pass;
1820 lm_pass = pdb_get_lanman_passwd(pwd);
1821 nt_pass = pdb_get_nt_passwd(pwd);
1823 if (!lm_pass || !nt_pass) {
1824 status = NT_STATUS_WRONG_PASSWORD;
1825 goto out;
1828 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1829 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1832 /* basic sanity checking on parameters. Do this before any database ops */
1833 if (!r->in.lm_present || !r->in.nt_present ||
1834 !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1835 !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1836 /* we should really handle a change with lm not
1837 present */
1838 status = NT_STATUS_INVALID_PARAMETER_MIX;
1839 goto out;
1842 /* decrypt and check the new lm hash */
1843 D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1844 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1845 if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1846 status = NT_STATUS_WRONG_PASSWORD;
1847 goto out;
1850 /* decrypt and check the new nt hash */
1851 D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1852 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1853 if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1854 status = NT_STATUS_WRONG_PASSWORD;
1855 goto out;
1858 /* The NT Cross is not required by Win2k3 R2, but if present
1859 check the nt cross hash */
1860 if (r->in.cross1_present && r->in.nt_cross) {
1861 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1862 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1863 status = NT_STATUS_WRONG_PASSWORD;
1864 goto out;
1868 /* The LM Cross is not required by Win2k3 R2, but if present
1869 check the lm cross hash */
1870 if (r->in.cross2_present && r->in.lm_cross) {
1871 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1872 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1873 status = NT_STATUS_WRONG_PASSWORD;
1874 goto out;
1878 if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1879 !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1880 status = NT_STATUS_ACCESS_DENIED;
1881 goto out;
1884 status = pdb_update_sam_account(pwd);
1885 out:
1886 TALLOC_FREE(pwd);
1888 return status;
1891 /*******************************************************************
1892 _samr_ChangePasswordUser2
1893 ********************************************************************/
1895 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1896 struct samr_ChangePasswordUser2 *r)
1898 NTSTATUS status;
1899 fstring user_name;
1900 fstring wks;
1902 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1904 fstrcpy(user_name, r->in.account->string);
1905 fstrcpy(wks, r->in.server->string);
1907 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1910 * Pass the user through the NT -> unix user mapping
1911 * function.
1914 (void)map_username(user_name);
1917 * UNIX username case mangling not required, pass_oem_change
1918 * is case insensitive.
1921 status = pass_oem_change(user_name,
1922 r->in.lm_password->data,
1923 r->in.lm_verifier->hash,
1924 r->in.nt_password->data,
1925 r->in.nt_verifier->hash,
1926 NULL);
1928 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1930 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1931 return NT_STATUS_WRONG_PASSWORD;
1934 return status;
1937 /****************************************************************
1938 _samr_OemChangePasswordUser2
1939 ****************************************************************/
1941 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
1942 struct samr_OemChangePasswordUser2 *r)
1944 NTSTATUS status;
1945 fstring user_name;
1946 const char *wks = NULL;
1948 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1950 fstrcpy(user_name, r->in.account->string);
1951 if (r->in.server && r->in.server->string) {
1952 wks = r->in.server->string;
1955 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1958 * Pass the user through the NT -> unix user mapping
1959 * function.
1962 (void)map_username(user_name);
1965 * UNIX username case mangling not required, pass_oem_change
1966 * is case insensitive.
1969 if (!r->in.hash || !r->in.password) {
1970 return NT_STATUS_INVALID_PARAMETER;
1973 status = pass_oem_change(user_name,
1974 r->in.password->data,
1975 r->in.hash->hash,
1978 NULL);
1980 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1981 return NT_STATUS_WRONG_PASSWORD;
1984 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1986 return status;
1989 /*******************************************************************
1990 _samr_ChangePasswordUser3
1991 ********************************************************************/
1993 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1994 struct samr_ChangePasswordUser3 *r)
1996 NTSTATUS status;
1997 fstring user_name;
1998 const char *wks = NULL;
1999 uint32 reject_reason;
2000 struct samr_DomInfo1 *dominfo = NULL;
2001 struct samr_ChangeReject *reject = NULL;
2002 uint32_t tmp;
2004 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2006 fstrcpy(user_name, r->in.account->string);
2007 if (r->in.server && r->in.server->string) {
2008 wks = r->in.server->string;
2011 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2014 * Pass the user through the NT -> unix user mapping
2015 * function.
2018 (void)map_username(user_name);
2021 * UNIX username case mangling not required, pass_oem_change
2022 * is case insensitive.
2025 status = pass_oem_change(user_name,
2026 r->in.lm_password->data,
2027 r->in.lm_verifier->hash,
2028 r->in.nt_password->data,
2029 r->in.nt_verifier->hash,
2030 &reject_reason);
2031 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2032 return NT_STATUS_WRONG_PASSWORD;
2035 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2036 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2038 time_t u_expire, u_min_age;
2039 uint32 account_policy_temp;
2041 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2042 if (!dominfo) {
2043 return NT_STATUS_NO_MEMORY;
2046 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2047 if (!reject) {
2048 return NT_STATUS_NO_MEMORY;
2051 become_root();
2053 /* AS ROOT !!! */
2055 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
2056 dominfo->min_password_length = tmp;
2058 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
2059 dominfo->password_history_length = tmp;
2061 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2062 &dominfo->password_properties);
2064 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2065 u_expire = account_policy_temp;
2067 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2068 u_min_age = account_policy_temp;
2070 /* !AS ROOT */
2072 unbecome_root();
2074 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2075 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2077 if (lp_check_password_script() && *lp_check_password_script()) {
2078 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2081 reject->reason = reject_reason;
2083 *r->out.dominfo = dominfo;
2084 *r->out.reject = reject;
2087 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2089 return status;
2092 /*******************************************************************
2093 makes a SAMR_R_LOOKUP_RIDS structure.
2094 ********************************************************************/
2096 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2097 const char **names,
2098 struct lsa_String **lsa_name_array_p)
2100 struct lsa_String *lsa_name_array = NULL;
2101 uint32_t i;
2103 *lsa_name_array_p = NULL;
2105 if (num_names != 0) {
2106 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2107 if (!lsa_name_array) {
2108 return false;
2112 for (i = 0; i < num_names; i++) {
2113 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2114 init_lsa_String(&lsa_name_array[i], names[i]);
2117 *lsa_name_array_p = lsa_name_array;
2119 return true;
2122 /*******************************************************************
2123 _samr_LookupRids
2124 ********************************************************************/
2126 NTSTATUS _samr_LookupRids(pipes_struct *p,
2127 struct samr_LookupRids *r)
2129 struct samr_domain_info *dinfo;
2130 NTSTATUS status;
2131 const char **names;
2132 enum lsa_SidType *attrs = NULL;
2133 uint32 *wire_attrs = NULL;
2134 int num_rids = (int)r->in.num_rids;
2135 int i;
2136 struct lsa_Strings names_array;
2137 struct samr_Ids types_array;
2138 struct lsa_String *lsa_names = NULL;
2140 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2142 dinfo = policy_handle_find(p, r->in.domain_handle,
2143 0 /* Don't know the acc_bits yet */, NULL,
2144 struct samr_domain_info, &status);
2145 if (!NT_STATUS_IS_OK(status)) {
2146 return status;
2149 if (num_rids > 1000) {
2150 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2151 "to samba4 idl this is not possible\n", num_rids));
2152 return NT_STATUS_UNSUCCESSFUL;
2155 if (num_rids) {
2156 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2157 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2158 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2160 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2161 return NT_STATUS_NO_MEMORY;
2162 } else {
2163 names = NULL;
2164 attrs = NULL;
2165 wire_attrs = NULL;
2168 become_root(); /* lookup_sid can require root privs */
2169 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2170 names, attrs);
2171 unbecome_root();
2173 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2174 status = NT_STATUS_OK;
2177 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2178 &lsa_names)) {
2179 return NT_STATUS_NO_MEMORY;
2182 /* Convert from enum lsa_SidType to uint32 for wire format. */
2183 for (i = 0; i < num_rids; i++) {
2184 wire_attrs[i] = (uint32)attrs[i];
2187 names_array.count = num_rids;
2188 names_array.names = lsa_names;
2190 types_array.count = num_rids;
2191 types_array.ids = wire_attrs;
2193 *r->out.names = names_array;
2194 *r->out.types = types_array;
2196 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2198 return status;
2201 /*******************************************************************
2202 _samr_OpenUser
2203 ********************************************************************/
2205 NTSTATUS _samr_OpenUser(pipes_struct *p,
2206 struct samr_OpenUser *r)
2208 struct samu *sampass=NULL;
2209 DOM_SID sid;
2210 struct samr_domain_info *dinfo;
2211 struct samr_user_info *uinfo;
2212 SEC_DESC *psd = NULL;
2213 uint32 acc_granted;
2214 uint32 des_access = r->in.access_mask;
2215 uint32_t extra_access = 0;
2216 size_t sd_size;
2217 bool ret;
2218 NTSTATUS nt_status;
2219 SE_PRIV se_rights;
2220 NTSTATUS status;
2222 dinfo = policy_handle_find(p, r->in.domain_handle,
2223 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2224 struct samr_domain_info, &status);
2225 if (!NT_STATUS_IS_OK(status)) {
2226 return status;
2229 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2230 return NT_STATUS_NO_MEMORY;
2233 /* append the user's RID to it */
2235 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2236 return NT_STATUS_NO_SUCH_USER;
2238 /* check if access can be granted as requested by client. */
2240 map_max_allowed_access(p->server_info->ptok, &des_access);
2242 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2243 se_map_generic(&des_access, &usr_generic_mapping);
2246 * Get the sampass first as we need to check privilages
2247 * based on what kind of user object this is.
2248 * But don't reveal info too early if it didn't exist.
2251 become_root();
2252 ret=pdb_getsampwsid(sampass, &sid);
2253 unbecome_root();
2255 se_priv_copy(&se_rights, &se_priv_none);
2258 * We do the override access checks on *open*, not at
2259 * SetUserInfo time.
2261 if (ret) {
2262 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2264 if ((acb_info & ACB_WSTRUST) &&
2265 user_has_any_privilege(p->server_info->ptok,
2266 &se_machine_account)) {
2268 * SeMachineAccount is needed to add
2269 * GENERIC_RIGHTS_USER_WRITE to a machine
2270 * account.
2272 se_priv_add(&se_rights, &se_machine_account);
2273 DEBUG(10,("_samr_OpenUser: adding machine account "
2274 "rights to handle for user %s\n",
2275 pdb_get_username(sampass) ));
2277 if ((acb_info & ACB_NORMAL) &&
2278 user_has_any_privilege(p->server_info->ptok,
2279 &se_add_users)) {
2281 * SeAddUsers is needed to add
2282 * GENERIC_RIGHTS_USER_WRITE to a normal
2283 * account.
2285 se_priv_add(&se_rights, &se_add_users);
2286 DEBUG(10,("_samr_OpenUser: adding add user "
2287 "rights to handle for user %s\n",
2288 pdb_get_username(sampass) ));
2291 * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
2292 * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not
2293 * what Windows does but is a hack for people who haven't
2294 * set up privilages on groups in Samba.
2296 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2297 if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2298 DOMAIN_GROUP_RID_ADMINS)) {
2299 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2300 extra_access = GENERIC_RIGHTS_USER_WRITE;
2301 DEBUG(4,("_samr_OpenUser: Allowing "
2302 "GENERIC_RIGHTS_USER_WRITE for "
2303 "rid admins\n"));
2308 TALLOC_FREE(sampass);
2310 nt_status = access_check_samr_object(psd, p->server_info->ptok,
2311 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2312 &acc_granted, "_samr_OpenUser");
2314 if ( !NT_STATUS_IS_OK(nt_status) )
2315 return nt_status;
2317 /* check that the SID exists in our domain. */
2318 if (ret == False) {
2319 return NT_STATUS_NO_SUCH_USER;
2322 /* If we did the rid admins hack above, allow access. */
2323 acc_granted |= extra_access;
2325 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2326 struct samr_user_info, &nt_status);
2327 if (!NT_STATUS_IS_OK(nt_status)) {
2328 return nt_status;
2330 uinfo->sid = sid;
2332 return NT_STATUS_OK;
2335 /*************************************************************************
2336 *************************************************************************/
2338 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2339 DATA_BLOB *blob,
2340 struct lsa_BinaryString **_r)
2342 struct lsa_BinaryString *r;
2344 if (!blob || !_r) {
2345 return NT_STATUS_INVALID_PARAMETER;
2348 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2349 if (!r) {
2350 return NT_STATUS_NO_MEMORY;
2353 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2354 if (!r->array) {
2355 return NT_STATUS_NO_MEMORY;
2357 memcpy(r->array, blob->data, blob->length);
2358 r->size = blob->length;
2359 r->length = blob->length;
2361 if (!r->array) {
2362 return NT_STATUS_NO_MEMORY;
2365 *_r = r;
2367 return NT_STATUS_OK;
2370 /*************************************************************************
2371 get_user_info_1.
2372 *************************************************************************/
2374 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2375 struct samr_UserInfo1 *r,
2376 struct samu *pw,
2377 DOM_SID *domain_sid)
2379 const DOM_SID *sid_group;
2380 uint32_t primary_gid;
2382 become_root();
2383 sid_group = pdb_get_group_sid(pw);
2384 unbecome_root();
2386 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2387 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2388 "which conflicts with the domain sid %s. Failing operation.\n",
2389 pdb_get_username(pw), sid_string_dbg(sid_group),
2390 sid_string_dbg(domain_sid)));
2391 return NT_STATUS_UNSUCCESSFUL;
2394 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2395 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2396 r->primary_gid = primary_gid;
2397 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2398 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2400 return NT_STATUS_OK;
2403 /*************************************************************************
2404 get_user_info_2.
2405 *************************************************************************/
2407 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2408 struct samr_UserInfo2 *r,
2409 struct samu *pw)
2411 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2412 r->unknown.string = NULL;
2413 r->country_code = 0;
2414 r->code_page = 0;
2416 return NT_STATUS_OK;
2419 /*************************************************************************
2420 get_user_info_3.
2421 *************************************************************************/
2423 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2424 struct samr_UserInfo3 *r,
2425 struct samu *pw,
2426 DOM_SID *domain_sid)
2428 const DOM_SID *sid_user, *sid_group;
2429 uint32_t rid, primary_gid;
2431 sid_user = pdb_get_user_sid(pw);
2433 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2434 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2435 "the domain sid %s. Failing operation.\n",
2436 pdb_get_username(pw), sid_string_dbg(sid_user),
2437 sid_string_dbg(domain_sid)));
2438 return NT_STATUS_UNSUCCESSFUL;
2441 become_root();
2442 sid_group = pdb_get_group_sid(pw);
2443 unbecome_root();
2445 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2446 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2447 "which conflicts with the domain sid %s. Failing operation.\n",
2448 pdb_get_username(pw), sid_string_dbg(sid_group),
2449 sid_string_dbg(domain_sid)));
2450 return NT_STATUS_UNSUCCESSFUL;
2453 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2454 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2455 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2456 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2457 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2459 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2460 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2461 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2462 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2463 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2464 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2465 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2467 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2468 r->rid = rid;
2469 r->primary_gid = primary_gid;
2470 r->acct_flags = pdb_get_acct_ctrl(pw);
2471 r->bad_password_count = pdb_get_bad_password_count(pw);
2472 r->logon_count = pdb_get_logon_count(pw);
2474 return NT_STATUS_OK;
2477 /*************************************************************************
2478 get_user_info_4.
2479 *************************************************************************/
2481 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2482 struct samr_UserInfo4 *r,
2483 struct samu *pw)
2485 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2487 return NT_STATUS_OK;
2490 /*************************************************************************
2491 get_user_info_5.
2492 *************************************************************************/
2494 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2495 struct samr_UserInfo5 *r,
2496 struct samu *pw,
2497 DOM_SID *domain_sid)
2499 const DOM_SID *sid_user, *sid_group;
2500 uint32_t rid, primary_gid;
2502 sid_user = pdb_get_user_sid(pw);
2504 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2505 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2506 "the domain sid %s. Failing operation.\n",
2507 pdb_get_username(pw), sid_string_dbg(sid_user),
2508 sid_string_dbg(domain_sid)));
2509 return NT_STATUS_UNSUCCESSFUL;
2512 become_root();
2513 sid_group = pdb_get_group_sid(pw);
2514 unbecome_root();
2516 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2517 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2518 "which conflicts with the domain sid %s. Failing operation.\n",
2519 pdb_get_username(pw), sid_string_dbg(sid_group),
2520 sid_string_dbg(domain_sid)));
2521 return NT_STATUS_UNSUCCESSFUL;
2524 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2525 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2526 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2527 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2529 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2530 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2531 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2532 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2533 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2534 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2535 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2536 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2538 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2539 r->rid = rid;
2540 r->primary_gid = primary_gid;
2541 r->acct_flags = pdb_get_acct_ctrl(pw);
2542 r->bad_password_count = pdb_get_bad_password_count(pw);
2543 r->logon_count = pdb_get_logon_count(pw);
2545 return NT_STATUS_OK;
2548 /*************************************************************************
2549 get_user_info_6.
2550 *************************************************************************/
2552 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2553 struct samr_UserInfo6 *r,
2554 struct samu *pw)
2556 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2557 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2559 return NT_STATUS_OK;
2562 /*************************************************************************
2563 get_user_info_7. Safe. Only gives out account_name.
2564 *************************************************************************/
2566 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2567 struct samr_UserInfo7 *r,
2568 struct samu *smbpass)
2570 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2571 if (!r->account_name.string) {
2572 return NT_STATUS_NO_MEMORY;
2575 return NT_STATUS_OK;
2578 /*************************************************************************
2579 get_user_info_8.
2580 *************************************************************************/
2582 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2583 struct samr_UserInfo8 *r,
2584 struct samu *pw)
2586 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2588 return NT_STATUS_OK;
2591 /*************************************************************************
2592 get_user_info_9. Only gives out primary group SID.
2593 *************************************************************************/
2595 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2596 struct samr_UserInfo9 *r,
2597 struct samu *smbpass)
2599 r->primary_gid = pdb_get_group_rid(smbpass);
2601 return NT_STATUS_OK;
2604 /*************************************************************************
2605 get_user_info_10.
2606 *************************************************************************/
2608 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2609 struct samr_UserInfo10 *r,
2610 struct samu *pw)
2612 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2613 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2615 return NT_STATUS_OK;
2618 /*************************************************************************
2619 get_user_info_11.
2620 *************************************************************************/
2622 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2623 struct samr_UserInfo11 *r,
2624 struct samu *pw)
2626 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2628 return NT_STATUS_OK;
2631 /*************************************************************************
2632 get_user_info_12.
2633 *************************************************************************/
2635 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2636 struct samr_UserInfo12 *r,
2637 struct samu *pw)
2639 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2641 return NT_STATUS_OK;
2644 /*************************************************************************
2645 get_user_info_13.
2646 *************************************************************************/
2648 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2649 struct samr_UserInfo13 *r,
2650 struct samu *pw)
2652 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2654 return NT_STATUS_OK;
2657 /*************************************************************************
2658 get_user_info_14.
2659 *************************************************************************/
2661 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2662 struct samr_UserInfo14 *r,
2663 struct samu *pw)
2665 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2667 return NT_STATUS_OK;
2670 /*************************************************************************
2671 get_user_info_16. Safe. Only gives out acb bits.
2672 *************************************************************************/
2674 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2675 struct samr_UserInfo16 *r,
2676 struct samu *smbpass)
2678 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2680 return NT_STATUS_OK;
2683 /*************************************************************************
2684 get_user_info_17.
2685 *************************************************************************/
2687 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2688 struct samr_UserInfo17 *r,
2689 struct samu *pw)
2691 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2693 return NT_STATUS_OK;
2696 /*************************************************************************
2697 get_user_info_18. OK - this is the killer as it gives out password info.
2698 Ensure that this is only allowed on an encrypted connection with a root
2699 user. JRA.
2700 *************************************************************************/
2702 static NTSTATUS get_user_info_18(pipes_struct *p,
2703 TALLOC_CTX *mem_ctx,
2704 struct samr_UserInfo18 *r,
2705 DOM_SID *user_sid)
2707 struct samu *smbpass=NULL;
2708 bool ret;
2710 ZERO_STRUCTP(r);
2712 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2713 return NT_STATUS_ACCESS_DENIED;
2716 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2717 return NT_STATUS_ACCESS_DENIED;
2721 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2724 if ( !(smbpass = samu_new( mem_ctx )) ) {
2725 return NT_STATUS_NO_MEMORY;
2728 ret = pdb_getsampwsid(smbpass, user_sid);
2730 if (ret == False) {
2731 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2732 TALLOC_FREE(smbpass);
2733 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2736 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2738 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2739 TALLOC_FREE(smbpass);
2740 return NT_STATUS_ACCOUNT_DISABLED;
2743 r->lm_pwd_active = true;
2744 r->nt_pwd_active = true;
2745 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2746 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2747 r->password_expired = 0; /* FIXME */
2749 TALLOC_FREE(smbpass);
2751 return NT_STATUS_OK;
2754 /*************************************************************************
2755 get_user_info_20
2756 *************************************************************************/
2758 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2759 struct samr_UserInfo20 *r,
2760 struct samu *sampass)
2762 const char *munged_dial = NULL;
2763 DATA_BLOB blob;
2764 NTSTATUS status;
2765 struct lsa_BinaryString *parameters = NULL;
2767 ZERO_STRUCTP(r);
2769 munged_dial = pdb_get_munged_dial(sampass);
2771 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2772 munged_dial, (int)strlen(munged_dial)));
2774 if (munged_dial) {
2775 blob = base64_decode_data_blob(munged_dial);
2776 } else {
2777 blob = data_blob_string_const_null("");
2780 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2781 data_blob_free(&blob);
2782 if (!NT_STATUS_IS_OK(status)) {
2783 return status;
2786 r->parameters = *parameters;
2788 return NT_STATUS_OK;
2792 /*************************************************************************
2793 get_user_info_21
2794 *************************************************************************/
2796 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2797 struct samr_UserInfo21 *r,
2798 struct samu *pw,
2799 DOM_SID *domain_sid)
2801 NTSTATUS status;
2802 const DOM_SID *sid_user, *sid_group;
2803 uint32_t rid, primary_gid;
2804 NTTIME force_password_change;
2805 time_t must_change_time;
2806 struct lsa_BinaryString *parameters = NULL;
2807 const char *munged_dial = NULL;
2808 DATA_BLOB blob;
2810 ZERO_STRUCTP(r);
2812 sid_user = pdb_get_user_sid(pw);
2814 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2815 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2816 "the domain sid %s. Failing operation.\n",
2817 pdb_get_username(pw), sid_string_dbg(sid_user),
2818 sid_string_dbg(domain_sid)));
2819 return NT_STATUS_UNSUCCESSFUL;
2822 become_root();
2823 sid_group = pdb_get_group_sid(pw);
2824 unbecome_root();
2826 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2827 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2828 "which conflicts with the domain sid %s. Failing operation.\n",
2829 pdb_get_username(pw), sid_string_dbg(sid_group),
2830 sid_string_dbg(domain_sid)));
2831 return NT_STATUS_UNSUCCESSFUL;
2834 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2835 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2836 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2837 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2838 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2840 must_change_time = pdb_get_pass_must_change_time(pw);
2841 if (must_change_time == get_time_t_max()) {
2842 unix_to_nt_time_abs(&force_password_change, must_change_time);
2843 } else {
2844 unix_to_nt_time(&force_password_change, must_change_time);
2847 munged_dial = pdb_get_munged_dial(pw);
2848 if (munged_dial) {
2849 blob = base64_decode_data_blob(munged_dial);
2850 } else {
2851 blob = data_blob_string_const_null("");
2854 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2855 data_blob_free(&blob);
2856 if (!NT_STATUS_IS_OK(status)) {
2857 return status;
2860 r->force_password_change = force_password_change;
2862 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2863 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2864 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2865 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2866 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2867 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2868 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2869 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2870 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2872 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2873 r->parameters = *parameters;
2874 r->rid = rid;
2875 r->primary_gid = primary_gid;
2876 r->acct_flags = pdb_get_acct_ctrl(pw);
2877 r->bad_password_count = pdb_get_bad_password_count(pw);
2878 r->logon_count = pdb_get_logon_count(pw);
2879 r->fields_present = pdb_build_fields_present(pw);
2880 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2881 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2882 r->country_code = 0;
2883 r->code_page = 0;
2884 r->lm_password_set = 0;
2885 r->nt_password_set = 0;
2887 #if 0
2890 Look at a user on a real NT4 PDC with usrmgr, press
2891 'ok'. Then you will see that fields_present is set to
2892 0x08f827fa. Look at the user immediately after that again,
2893 and you will see that 0x00fffff is returned. This solves
2894 the problem that you get access denied after having looked
2895 at the user.
2896 -- Volker
2899 #endif
2902 return NT_STATUS_OK;
2905 /*******************************************************************
2906 _samr_QueryUserInfo
2907 ********************************************************************/
2909 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2910 struct samr_QueryUserInfo *r)
2912 NTSTATUS status;
2913 union samr_UserInfo *user_info = NULL;
2914 struct samr_user_info *uinfo;
2915 DOM_SID domain_sid;
2916 uint32 rid;
2917 bool ret = false;
2918 struct samu *pwd = NULL;
2920 uinfo = policy_handle_find(p, r->in.user_handle,
2921 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
2922 struct samr_user_info, &status);
2923 if (!NT_STATUS_IS_OK(status)) {
2924 return status;
2927 domain_sid = uinfo->sid;
2929 sid_split_rid(&domain_sid, &rid);
2931 if (!sid_check_is_in_our_domain(&uinfo->sid))
2932 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2934 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2935 sid_string_dbg(&uinfo->sid)));
2937 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2938 if (!user_info) {
2939 return NT_STATUS_NO_MEMORY;
2942 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2944 if (!(pwd = samu_new(p->mem_ctx))) {
2945 return NT_STATUS_NO_MEMORY;
2948 become_root();
2949 ret = pdb_getsampwsid(pwd, &uinfo->sid);
2950 unbecome_root();
2952 if (ret == false) {
2953 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
2954 TALLOC_FREE(pwd);
2955 return NT_STATUS_NO_SUCH_USER;
2958 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2960 samr_clear_sam_passwd(pwd);
2962 switch (r->in.level) {
2963 case 1:
2964 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
2965 break;
2966 case 2:
2967 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
2968 break;
2969 case 3:
2970 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
2971 break;
2972 case 4:
2973 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
2974 break;
2975 case 5:
2976 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2977 break;
2978 case 6:
2979 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
2980 break;
2981 case 7:
2982 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2983 break;
2984 case 8:
2985 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
2986 break;
2987 case 9:
2988 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2989 break;
2990 case 10:
2991 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
2992 break;
2993 case 11:
2994 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
2995 break;
2996 case 12:
2997 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
2998 break;
2999 case 13:
3000 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3001 break;
3002 case 14:
3003 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3004 break;
3005 case 16:
3006 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3007 break;
3008 case 17:
3009 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3010 break;
3011 case 18:
3012 /* level 18 is special */
3013 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3014 &uinfo->sid);
3015 break;
3016 case 20:
3017 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3018 break;
3019 case 21:
3020 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
3021 break;
3022 default:
3023 status = NT_STATUS_INVALID_INFO_CLASS;
3024 break;
3027 TALLOC_FREE(pwd);
3029 *r->out.info = user_info;
3031 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3033 return status;
3036 /****************************************************************
3037 ****************************************************************/
3039 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3040 struct samr_QueryUserInfo2 *r)
3042 struct samr_QueryUserInfo u;
3044 u.in.user_handle = r->in.user_handle;
3045 u.in.level = r->in.level;
3046 u.out.info = r->out.info;
3048 return _samr_QueryUserInfo(p, &u);
3051 /*******************************************************************
3052 _samr_GetGroupsForUser
3053 ********************************************************************/
3055 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3056 struct samr_GetGroupsForUser *r)
3058 struct samr_user_info *uinfo;
3059 struct samu *sam_pass=NULL;
3060 DOM_SID *sids;
3061 struct samr_RidWithAttribute dom_gid;
3062 struct samr_RidWithAttribute *gids = NULL;
3063 uint32 primary_group_rid;
3064 size_t num_groups = 0;
3065 gid_t *unix_gids;
3066 size_t i, num_gids;
3067 bool ret;
3068 NTSTATUS result;
3069 bool success = False;
3071 struct samr_RidWithAttributeArray *rids = NULL;
3074 * from the SID in the request:
3075 * we should send back the list of DOMAIN GROUPS
3076 * the user is a member of
3078 * and only the DOMAIN GROUPS
3079 * no ALIASES !!! neither aliases of the domain
3080 * nor aliases of the builtin SID
3082 * JFM, 12/2/2001
3085 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3087 uinfo = policy_handle_find(p, r->in.user_handle,
3088 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3089 struct samr_user_info, &result);
3090 if (!NT_STATUS_IS_OK(result)) {
3091 return result;
3094 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3095 if (!rids) {
3096 return NT_STATUS_NO_MEMORY;
3099 if (!sid_check_is_in_our_domain(&uinfo->sid))
3100 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3102 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3103 return NT_STATUS_NO_MEMORY;
3106 become_root();
3107 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3108 unbecome_root();
3110 if (!ret) {
3111 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3112 sid_string_dbg(&uinfo->sid)));
3113 return NT_STATUS_NO_SUCH_USER;
3116 sids = NULL;
3118 /* make both calls inside the root block */
3119 become_root();
3120 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3121 &sids, &unix_gids, &num_groups);
3122 if ( NT_STATUS_IS_OK(result) ) {
3123 success = sid_peek_check_rid(get_global_sam_sid(),
3124 pdb_get_group_sid(sam_pass),
3125 &primary_group_rid);
3127 unbecome_root();
3129 if (!NT_STATUS_IS_OK(result)) {
3130 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3131 sid_string_dbg(&uinfo->sid)));
3132 return result;
3135 if ( !success ) {
3136 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3137 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3138 pdb_get_username(sam_pass)));
3139 TALLOC_FREE(sam_pass);
3140 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3143 gids = NULL;
3144 num_gids = 0;
3146 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3147 SE_GROUP_ENABLED);
3148 dom_gid.rid = primary_group_rid;
3149 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3151 for (i=0; i<num_groups; i++) {
3153 if (!sid_peek_check_rid(get_global_sam_sid(),
3154 &(sids[i]), &dom_gid.rid)) {
3155 DEBUG(10, ("Found sid %s not in our domain\n",
3156 sid_string_dbg(&sids[i])));
3157 continue;
3160 if (dom_gid.rid == primary_group_rid) {
3161 /* We added the primary group directly from the
3162 * sam_account. The other SIDs are unique from
3163 * enum_group_memberships */
3164 continue;
3167 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3170 rids->count = num_gids;
3171 rids->rids = gids;
3173 *r->out.rids = rids;
3175 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3177 return result;
3180 /*******************************************************************
3181 _samr_QueryDomainInfo
3182 ********************************************************************/
3184 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3185 struct samr_QueryDomainInfo *r)
3187 NTSTATUS status = NT_STATUS_OK;
3188 struct samr_domain_info *dinfo;
3189 union samr_DomainInfo *dom_info;
3190 time_t u_expire, u_min_age;
3192 time_t u_lock_duration, u_reset_time;
3193 uint32_t u_logout;
3195 uint32 account_policy_temp;
3197 time_t seq_num;
3198 uint32 server_role;
3200 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3202 dinfo = policy_handle_find(p, r->in.domain_handle,
3203 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3204 struct samr_domain_info, &status);
3205 if (!NT_STATUS_IS_OK(status)) {
3206 return status;
3209 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3210 if (!dom_info) {
3211 return NT_STATUS_NO_MEMORY;
3214 switch (r->in.level) {
3215 case 0x01:
3217 become_root();
3219 /* AS ROOT !!! */
3221 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
3222 &account_policy_temp);
3223 dom_info->info1.min_password_length = account_policy_temp;
3225 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
3226 dom_info->info1.password_history_length = account_policy_temp;
3228 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
3229 &dom_info->info1.password_properties);
3231 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
3232 u_expire = account_policy_temp;
3234 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
3235 u_min_age = account_policy_temp;
3237 /* !AS ROOT */
3239 unbecome_root();
3241 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
3242 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
3244 if (lp_check_password_script() && *lp_check_password_script()) {
3245 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
3248 break;
3249 case 0x02:
3251 become_root();
3253 /* AS ROOT !!! */
3255 dom_info->general.num_users = count_sam_users(
3256 dinfo->disp_info, ACB_NORMAL);
3257 dom_info->general.num_groups = count_sam_groups(
3258 dinfo->disp_info);
3259 dom_info->general.num_aliases = count_sam_aliases(
3260 dinfo->disp_info);
3262 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3264 unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
3266 if (!pdb_get_seq_num(&seq_num))
3267 seq_num = time(NULL);
3269 /* !AS ROOT */
3271 unbecome_root();
3273 server_role = ROLE_DOMAIN_PDC;
3274 if (lp_server_role() == ROLE_DOMAIN_BDC)
3275 server_role = ROLE_DOMAIN_BDC;
3277 dom_info->general.oem_information.string = lp_serverstring();
3278 dom_info->general.domain_name.string = lp_workgroup();
3279 dom_info->general.primary.string = global_myname();
3280 dom_info->general.sequence_num = seq_num;
3281 dom_info->general.domain_server_state = DOMAIN_SERVER_ENABLED;
3282 dom_info->general.role = server_role;
3283 dom_info->general.unknown3 = 1;
3285 break;
3286 case 0x03:
3288 become_root();
3290 /* AS ROOT !!! */
3293 uint32 ul;
3294 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3295 u_logout = (time_t)ul;
3298 /* !AS ROOT */
3300 unbecome_root();
3302 unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
3304 break;
3305 case 0x04:
3306 dom_info->oem.oem_information.string = lp_serverstring();
3307 break;
3308 case 0x05:
3309 dom_info->info5.domain_name.string = get_global_sam_name();
3310 break;
3311 case 0x06:
3312 /* NT returns its own name when a PDC. win2k and later
3313 * only the name of the PDC if itself is a BDC (samba4
3314 * idl) */
3315 dom_info->info6.primary.string = global_myname();
3316 break;
3317 case 0x07:
3318 server_role = ROLE_DOMAIN_PDC;
3319 if (lp_server_role() == ROLE_DOMAIN_BDC)
3320 server_role = ROLE_DOMAIN_BDC;
3322 dom_info->info7.role = server_role;
3323 break;
3324 case 0x08:
3326 become_root();
3328 /* AS ROOT !!! */
3330 if (!pdb_get_seq_num(&seq_num)) {
3331 seq_num = time(NULL);
3334 /* !AS ROOT */
3336 unbecome_root();
3338 dom_info->info8.sequence_num = seq_num;
3339 dom_info->info8.domain_create_time = 0;
3341 break;
3342 case 0x09:
3344 dom_info->info9.domain_server_state = DOMAIN_SERVER_ENABLED;
3346 break;
3347 case 0x0b:
3349 /* AS ROOT !!! */
3351 become_root();
3353 dom_info->general2.general.num_users = count_sam_users(
3354 dinfo->disp_info, ACB_NORMAL);
3355 dom_info->general2.general.num_groups = count_sam_groups(
3356 dinfo->disp_info);
3357 dom_info->general2.general.num_aliases = count_sam_aliases(
3358 dinfo->disp_info);
3360 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3362 unix_to_nt_time_abs(&dom_info->general2.general.force_logoff_time, u_logout);
3364 if (!pdb_get_seq_num(&seq_num))
3365 seq_num = time(NULL);
3367 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3368 u_lock_duration = account_policy_temp;
3369 if (u_lock_duration != -1) {
3370 u_lock_duration *= 60;
3373 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3374 u_reset_time = account_policy_temp * 60;
3376 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3377 &account_policy_temp);
3378 dom_info->general2.lockout_threshold = account_policy_temp;
3380 /* !AS ROOT */
3382 unbecome_root();
3384 server_role = ROLE_DOMAIN_PDC;
3385 if (lp_server_role() == ROLE_DOMAIN_BDC)
3386 server_role = ROLE_DOMAIN_BDC;
3388 dom_info->general2.general.oem_information.string = lp_serverstring();
3389 dom_info->general2.general.domain_name.string = lp_workgroup();
3390 dom_info->general2.general.primary.string = global_myname();
3391 dom_info->general2.general.sequence_num = seq_num;
3392 dom_info->general2.general.domain_server_state = DOMAIN_SERVER_ENABLED;
3393 dom_info->general2.general.role = server_role;
3394 dom_info->general2.general.unknown3 = 1;
3396 unix_to_nt_time_abs(&dom_info->general2.lockout_duration,
3397 u_lock_duration);
3398 unix_to_nt_time_abs(&dom_info->general2.lockout_window,
3399 u_reset_time);
3401 break;
3402 case 0x0c:
3404 become_root();
3406 /* AS ROOT !!! */
3408 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3409 u_lock_duration = account_policy_temp;
3410 if (u_lock_duration != -1) {
3411 u_lock_duration *= 60;
3414 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3415 u_reset_time = account_policy_temp * 60;
3417 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3418 &account_policy_temp);
3419 dom_info->info12.lockout_threshold = account_policy_temp;
3421 /* !AS ROOT */
3423 unbecome_root();
3425 unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
3426 u_lock_duration);
3427 unix_to_nt_time_abs(&dom_info->info12.lockout_window,
3428 u_reset_time);
3430 break;
3431 case 0x0d:
3433 become_root();
3435 /* AS ROOT !!! */
3437 if (!pdb_get_seq_num(&seq_num)) {
3438 seq_num = time(NULL);
3441 /* !AS ROOT */
3443 unbecome_root();
3445 dom_info->info13.sequence_num = seq_num;
3446 dom_info->info13.domain_create_time = 0;
3447 dom_info->info13.modified_count_at_last_promotion = 0;
3449 break;
3450 default:
3451 return NT_STATUS_INVALID_INFO_CLASS;
3454 *r->out.info = dom_info;
3456 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3458 return status;
3461 /* W2k3 seems to use the same check for all 3 objects that can be created via
3462 * SAMR, if you try to create for example "Dialup" as an alias it says
3463 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3464 * database. */
3466 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3468 enum lsa_SidType type;
3469 bool result;
3471 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3473 become_root();
3474 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3475 * whether the name already exists */
3476 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3477 NULL, NULL, NULL, &type);
3478 unbecome_root();
3480 if (!result) {
3481 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3482 return NT_STATUS_OK;
3485 DEBUG(5, ("trying to create %s, exists as %s\n",
3486 new_name, sid_type_lookup(type)));
3488 if (type == SID_NAME_DOM_GRP) {
3489 return NT_STATUS_GROUP_EXISTS;
3491 if (type == SID_NAME_ALIAS) {
3492 return NT_STATUS_ALIAS_EXISTS;
3495 /* Yes, the default is NT_STATUS_USER_EXISTS */
3496 return NT_STATUS_USER_EXISTS;
3499 /*******************************************************************
3500 _samr_CreateUser2
3501 ********************************************************************/
3503 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3504 struct samr_CreateUser2 *r)
3506 const char *account = NULL;
3507 DOM_SID sid;
3508 uint32_t acb_info = r->in.acct_flags;
3509 struct samr_domain_info *dinfo;
3510 struct samr_user_info *uinfo;
3511 NTSTATUS nt_status;
3512 uint32 acc_granted;
3513 SEC_DESC *psd;
3514 size_t sd_size;
3515 /* check this, when giving away 'add computer to domain' privs */
3516 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3517 bool can_add_account = False;
3518 SE_PRIV se_rights;
3520 dinfo = policy_handle_find(p, r->in.domain_handle,
3521 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3522 struct samr_domain_info, &nt_status);
3523 if (!NT_STATUS_IS_OK(nt_status)) {
3524 return nt_status;
3527 if (sid_check_is_builtin(&dinfo->sid)) {
3528 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3529 return NT_STATUS_ACCESS_DENIED;
3532 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3533 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3534 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3535 this parameter is not an account type */
3536 return NT_STATUS_INVALID_PARAMETER;
3539 account = r->in.account_name->string;
3540 if (account == NULL) {
3541 return NT_STATUS_NO_MEMORY;
3544 nt_status = can_create(p->mem_ctx, account);
3545 if (!NT_STATUS_IS_OK(nt_status)) {
3546 return nt_status;
3549 /* determine which user right we need to check based on the acb_info */
3551 if (geteuid() == sec_initial_uid()) {
3552 se_priv_copy(&se_rights, &se_priv_none);
3553 can_add_account = true;
3554 } else if (acb_info & ACB_WSTRUST) {
3555 se_priv_copy(&se_rights, &se_machine_account);
3556 can_add_account = user_has_privileges(
3557 p->server_info->ptok, &se_rights );
3558 } else if (acb_info & ACB_NORMAL &&
3559 (account[strlen(account)-1] != '$')) {
3560 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3561 account for domain trusts and changes the ACB flags later */
3562 se_priv_copy(&se_rights, &se_add_users);
3563 can_add_account = user_has_privileges(
3564 p->server_info->ptok, &se_rights );
3565 } else if (lp_enable_privileges()) {
3566 /* implicit assumption of a BDC or domain trust account here
3567 * (we already check the flags earlier) */
3568 /* only Domain Admins can add a BDC or domain trust */
3569 se_priv_copy(&se_rights, &se_priv_none);
3570 can_add_account = nt_token_check_domain_rid(
3571 p->server_info->ptok,
3572 DOMAIN_GROUP_RID_ADMINS );
3575 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3576 uidtoname(p->server_info->utok.uid),
3577 can_add_account ? "True":"False" ));
3579 if (!can_add_account) {
3580 return NT_STATUS_ACCESS_DENIED;
3583 /********** BEGIN Admin BLOCK **********/
3585 become_root();
3586 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3587 r->out.rid);
3588 unbecome_root();
3590 /********** END Admin BLOCK **********/
3592 /* now check for failure */
3594 if ( !NT_STATUS_IS_OK(nt_status) )
3595 return nt_status;
3597 /* Get the user's SID */
3599 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3601 map_max_allowed_access(p->server_info->ptok, &des_access);
3603 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3604 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3605 se_map_generic(&des_access, &usr_generic_mapping);
3608 * JRA - TESTME. We just created this user so we
3609 * had rights to create them. Do we need to check
3610 * any further access on this object ? Can't we
3611 * just assume we have all the rights we need ?
3614 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3615 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3616 &acc_granted, "_samr_CreateUser2");
3618 if ( !NT_STATUS_IS_OK(nt_status) ) {
3619 return nt_status;
3622 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3623 struct samr_user_info, &nt_status);
3624 if (!NT_STATUS_IS_OK(nt_status)) {
3625 return nt_status;
3627 uinfo->sid = sid;
3629 /* After a "set" ensure we have no cached display info. */
3630 force_flush_samr_cache(&sid);
3632 *r->out.access_granted = acc_granted;
3634 return NT_STATUS_OK;
3637 /****************************************************************
3638 ****************************************************************/
3640 NTSTATUS _samr_CreateUser(pipes_struct *p,
3641 struct samr_CreateUser *r)
3643 struct samr_CreateUser2 c;
3644 uint32_t access_granted;
3646 c.in.domain_handle = r->in.domain_handle;
3647 c.in.account_name = r->in.account_name;
3648 c.in.acct_flags = ACB_NORMAL;
3649 c.in.access_mask = r->in.access_mask;
3650 c.out.user_handle = r->out.user_handle;
3651 c.out.access_granted = &access_granted;
3652 c.out.rid = r->out.rid;
3654 return _samr_CreateUser2(p, &c);
3657 /*******************************************************************
3658 _samr_Connect
3659 ********************************************************************/
3661 NTSTATUS _samr_Connect(pipes_struct *p,
3662 struct samr_Connect *r)
3664 struct samr_connect_info *info;
3665 uint32_t acc_granted;
3666 struct policy_handle hnd;
3667 uint32 des_access = r->in.access_mask;
3668 NTSTATUS status;
3670 /* Access check */
3672 if (!pipe_access_check(p)) {
3673 DEBUG(3, ("access denied to _samr_Connect\n"));
3674 return NT_STATUS_ACCESS_DENIED;
3677 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3678 was observed from a win98 client trying to enumerate users (when configured
3679 user level access control on shares) --jerry */
3681 map_max_allowed_access(p->server_info->ptok, &des_access);
3683 se_map_generic( &des_access, &sam_generic_mapping );
3685 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3686 |SAMR_ACCESS_LOOKUP_DOMAIN);
3688 /* set up the SAMR connect_anon response */
3690 info = policy_handle_create(p, &hnd, acc_granted,
3691 struct samr_connect_info,
3692 &status);
3693 if (!NT_STATUS_IS_OK(status)) {
3694 return status;
3697 *r->out.connect_handle = hnd;
3698 return NT_STATUS_OK;
3701 /*******************************************************************
3702 _samr_Connect2
3703 ********************************************************************/
3705 NTSTATUS _samr_Connect2(pipes_struct *p,
3706 struct samr_Connect2 *r)
3708 struct samr_connect_info *info = NULL;
3709 struct policy_handle hnd;
3710 SEC_DESC *psd = NULL;
3711 uint32 acc_granted;
3712 uint32 des_access = r->in.access_mask;
3713 NTSTATUS nt_status;
3714 size_t sd_size;
3715 const char *fn = "_samr_Connect2";
3717 switch (p->hdr_req.opnum) {
3718 case NDR_SAMR_CONNECT2:
3719 fn = "_samr_Connect2";
3720 break;
3721 case NDR_SAMR_CONNECT3:
3722 fn = "_samr_Connect3";
3723 break;
3724 case NDR_SAMR_CONNECT4:
3725 fn = "_samr_Connect4";
3726 break;
3727 case NDR_SAMR_CONNECT5:
3728 fn = "_samr_Connect5";
3729 break;
3732 DEBUG(5,("%s: %d\n", fn, __LINE__));
3734 /* Access check */
3736 if (!pipe_access_check(p)) {
3737 DEBUG(3, ("access denied to %s\n", fn));
3738 return NT_STATUS_ACCESS_DENIED;
3741 map_max_allowed_access(p->server_info->ptok, &des_access);
3743 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3744 se_map_generic(&des_access, &sam_generic_mapping);
3746 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3747 NULL, 0, des_access, &acc_granted, fn);
3749 if ( !NT_STATUS_IS_OK(nt_status) )
3750 return nt_status;
3752 info = policy_handle_create(p, &hnd, acc_granted,
3753 struct samr_connect_info, &nt_status);
3754 if (!NT_STATUS_IS_OK(nt_status)) {
3755 return nt_status;
3758 DEBUG(5,("%s: %d\n", fn, __LINE__));
3760 *r->out.connect_handle = hnd;
3761 return NT_STATUS_OK;
3764 /****************************************************************
3765 _samr_Connect3
3766 ****************************************************************/
3768 NTSTATUS _samr_Connect3(pipes_struct *p,
3769 struct samr_Connect3 *r)
3771 struct samr_Connect2 c;
3773 c.in.system_name = r->in.system_name;
3774 c.in.access_mask = r->in.access_mask;
3775 c.out.connect_handle = r->out.connect_handle;
3777 return _samr_Connect2(p, &c);
3780 /*******************************************************************
3781 _samr_Connect4
3782 ********************************************************************/
3784 NTSTATUS _samr_Connect4(pipes_struct *p,
3785 struct samr_Connect4 *r)
3787 struct samr_Connect2 c;
3789 c.in.system_name = r->in.system_name;
3790 c.in.access_mask = r->in.access_mask;
3791 c.out.connect_handle = r->out.connect_handle;
3793 return _samr_Connect2(p, &c);
3796 /*******************************************************************
3797 _samr_Connect5
3798 ********************************************************************/
3800 NTSTATUS _samr_Connect5(pipes_struct *p,
3801 struct samr_Connect5 *r)
3803 NTSTATUS status;
3804 struct samr_Connect2 c;
3805 struct samr_ConnectInfo1 info1;
3807 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3808 info1.unknown2 = 0;
3810 c.in.system_name = r->in.system_name;
3811 c.in.access_mask = r->in.access_mask;
3812 c.out.connect_handle = r->out.connect_handle;
3814 *r->out.level_out = 1;
3816 status = _samr_Connect2(p, &c);
3817 if (!NT_STATUS_IS_OK(status)) {
3818 return status;
3821 r->out.info_out->info1 = info1;
3823 return NT_STATUS_OK;
3826 /**********************************************************************
3827 _samr_LookupDomain
3828 **********************************************************************/
3830 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3831 struct samr_LookupDomain *r)
3833 NTSTATUS status;
3834 struct samr_connect_info *info;
3835 const char *domain_name;
3836 DOM_SID *sid = NULL;
3838 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3839 Reverted that change so we will work with RAS servers again */
3841 info = policy_handle_find(p, r->in.connect_handle,
3842 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3843 struct samr_connect_info,
3844 &status);
3845 if (!NT_STATUS_IS_OK(status)) {
3846 return status;
3849 domain_name = r->in.domain_name->string;
3850 if (!domain_name) {
3851 return NT_STATUS_INVALID_PARAMETER;
3854 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3855 if (!sid) {
3856 return NT_STATUS_NO_MEMORY;
3859 if (strequal(domain_name, builtin_domain_name())) {
3860 sid_copy(sid, &global_sid_Builtin);
3861 } else {
3862 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3863 status = NT_STATUS_NO_SUCH_DOMAIN;
3867 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3868 sid_string_dbg(sid)));
3870 *r->out.sid = sid;
3872 return status;
3875 /**********************************************************************
3876 _samr_EnumDomains
3877 **********************************************************************/
3879 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3880 struct samr_EnumDomains *r)
3882 NTSTATUS status;
3883 struct samr_connect_info *info;
3884 uint32_t num_entries = 2;
3885 struct samr_SamEntry *entry_array = NULL;
3886 struct samr_SamArray *sam;
3888 info = policy_handle_find(p, r->in.connect_handle,
3889 SAMR_ACCESS_ENUM_DOMAINS, NULL,
3890 struct samr_connect_info, &status);
3891 if (!NT_STATUS_IS_OK(status)) {
3892 return status;
3895 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3896 if (!sam) {
3897 return NT_STATUS_NO_MEMORY;
3900 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3901 struct samr_SamEntry,
3902 num_entries);
3903 if (!entry_array) {
3904 return NT_STATUS_NO_MEMORY;
3907 entry_array[0].idx = 0;
3908 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3910 entry_array[1].idx = 1;
3911 init_lsa_String(&entry_array[1].name, "Builtin");
3913 sam->count = num_entries;
3914 sam->entries = entry_array;
3916 *r->out.sam = sam;
3917 *r->out.num_entries = num_entries;
3919 return status;
3922 /*******************************************************************
3923 _samr_OpenAlias
3924 ********************************************************************/
3926 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3927 struct samr_OpenAlias *r)
3929 DOM_SID sid;
3930 uint32 alias_rid = r->in.rid;
3931 struct samr_alias_info *ainfo;
3932 struct samr_domain_info *dinfo;
3933 SEC_DESC *psd = NULL;
3934 uint32 acc_granted;
3935 uint32 des_access = r->in.access_mask;
3936 size_t sd_size;
3937 NTSTATUS status;
3938 SE_PRIV se_rights;
3940 dinfo = policy_handle_find(p, r->in.domain_handle,
3941 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
3942 struct samr_domain_info, &status);
3943 if (!NT_STATUS_IS_OK(status)) {
3944 return status;
3947 /* append the alias' RID to it */
3949 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
3950 return NT_STATUS_NO_SUCH_ALIAS;
3952 /*check if access can be granted as requested by client. */
3954 map_max_allowed_access(p->server_info->ptok, &des_access);
3956 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3957 se_map_generic(&des_access,&ali_generic_mapping);
3959 se_priv_copy( &se_rights, &se_add_users );
3961 status = access_check_samr_object(psd, p->server_info->ptok,
3962 &se_rights, SAMR_ALIAS_ACCESS_ADD_MEMBER,
3963 des_access, &acc_granted, "_samr_OpenAlias");
3965 if ( !NT_STATUS_IS_OK(status) )
3966 return status;
3969 /* Check we actually have the requested alias */
3970 enum lsa_SidType type;
3971 bool result;
3972 gid_t gid;
3974 become_root();
3975 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3976 unbecome_root();
3978 if (!result || (type != SID_NAME_ALIAS)) {
3979 return NT_STATUS_NO_SUCH_ALIAS;
3982 /* make sure there is a mapping */
3984 if ( !sid_to_gid( &sid, &gid ) ) {
3985 return NT_STATUS_NO_SUCH_ALIAS;
3990 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
3991 struct samr_alias_info, &status);
3992 if (!NT_STATUS_IS_OK(status)) {
3993 return status;
3995 ainfo->sid = sid;
3997 return NT_STATUS_OK;
4000 /*******************************************************************
4001 set_user_info_2
4002 ********************************************************************/
4004 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4005 struct samr_UserInfo2 *id2,
4006 struct samu *pwd)
4008 if (id2 == NULL) {
4009 DEBUG(5,("set_user_info_2: NULL id2\n"));
4010 return NT_STATUS_ACCESS_DENIED;
4013 copy_id2_to_sam_passwd(pwd, id2);
4015 return pdb_update_sam_account(pwd);
4018 /*******************************************************************
4019 set_user_info_4
4020 ********************************************************************/
4022 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4023 struct samr_UserInfo4 *id4,
4024 struct samu *pwd)
4026 if (id4 == NULL) {
4027 DEBUG(5,("set_user_info_2: NULL id4\n"));
4028 return NT_STATUS_ACCESS_DENIED;
4031 copy_id4_to_sam_passwd(pwd, id4);
4033 return pdb_update_sam_account(pwd);
4036 /*******************************************************************
4037 set_user_info_6
4038 ********************************************************************/
4040 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4041 struct samr_UserInfo6 *id6,
4042 struct samu *pwd)
4044 if (id6 == NULL) {
4045 DEBUG(5,("set_user_info_6: NULL id6\n"));
4046 return NT_STATUS_ACCESS_DENIED;
4049 copy_id6_to_sam_passwd(pwd, id6);
4051 return pdb_update_sam_account(pwd);
4054 /*******************************************************************
4055 set_user_info_7
4056 ********************************************************************/
4058 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4059 struct samr_UserInfo7 *id7,
4060 struct samu *pwd)
4062 NTSTATUS rc;
4064 if (id7 == NULL) {
4065 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4066 return NT_STATUS_ACCESS_DENIED;
4069 if (!id7->account_name.string) {
4070 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4071 return NT_STATUS_ACCESS_DENIED;
4074 /* check to see if the new username already exists. Note: we can't
4075 reliably lock all backends, so there is potentially the
4076 possibility that a user can be created in between this check and
4077 the rename. The rename should fail, but may not get the
4078 exact same failure status code. I think this is small enough
4079 of a window for this type of operation and the results are
4080 simply that the rename fails with a slightly different status
4081 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4083 rc = can_create(mem_ctx, id7->account_name.string);
4085 /* when there is nothing to change, we're done here */
4086 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4087 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4088 return NT_STATUS_OK;
4090 if (!NT_STATUS_IS_OK(rc)) {
4091 return rc;
4094 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4096 return rc;
4099 /*******************************************************************
4100 set_user_info_8
4101 ********************************************************************/
4103 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4104 struct samr_UserInfo8 *id8,
4105 struct samu *pwd)
4107 if (id8 == NULL) {
4108 DEBUG(5,("set_user_info_8: NULL id8\n"));
4109 return NT_STATUS_ACCESS_DENIED;
4112 copy_id8_to_sam_passwd(pwd, id8);
4114 return pdb_update_sam_account(pwd);
4117 /*******************************************************************
4118 set_user_info_10
4119 ********************************************************************/
4121 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4122 struct samr_UserInfo10 *id10,
4123 struct samu *pwd)
4125 if (id10 == NULL) {
4126 DEBUG(5,("set_user_info_8: NULL id10\n"));
4127 return NT_STATUS_ACCESS_DENIED;
4130 copy_id10_to_sam_passwd(pwd, id10);
4132 return pdb_update_sam_account(pwd);
4135 /*******************************************************************
4136 set_user_info_11
4137 ********************************************************************/
4139 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4140 struct samr_UserInfo11 *id11,
4141 struct samu *pwd)
4143 if (id11 == NULL) {
4144 DEBUG(5,("set_user_info_11: NULL id11\n"));
4145 return NT_STATUS_ACCESS_DENIED;
4148 copy_id11_to_sam_passwd(pwd, id11);
4150 return pdb_update_sam_account(pwd);
4153 /*******************************************************************
4154 set_user_info_12
4155 ********************************************************************/
4157 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4158 struct samr_UserInfo12 *id12,
4159 struct samu *pwd)
4161 if (id12 == NULL) {
4162 DEBUG(5,("set_user_info_12: NULL id12\n"));
4163 return NT_STATUS_ACCESS_DENIED;
4166 copy_id12_to_sam_passwd(pwd, id12);
4168 return pdb_update_sam_account(pwd);
4171 /*******************************************************************
4172 set_user_info_13
4173 ********************************************************************/
4175 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4176 struct samr_UserInfo13 *id13,
4177 struct samu *pwd)
4179 if (id13 == NULL) {
4180 DEBUG(5,("set_user_info_13: NULL id13\n"));
4181 return NT_STATUS_ACCESS_DENIED;
4184 copy_id13_to_sam_passwd(pwd, id13);
4186 return pdb_update_sam_account(pwd);
4189 /*******************************************************************
4190 set_user_info_14
4191 ********************************************************************/
4193 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4194 struct samr_UserInfo14 *id14,
4195 struct samu *pwd)
4197 if (id14 == NULL) {
4198 DEBUG(5,("set_user_info_14: NULL id14\n"));
4199 return NT_STATUS_ACCESS_DENIED;
4202 copy_id14_to_sam_passwd(pwd, id14);
4204 return pdb_update_sam_account(pwd);
4207 /*******************************************************************
4208 set_user_info_16
4209 ********************************************************************/
4211 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4212 struct samr_UserInfo16 *id16,
4213 struct samu *pwd)
4215 if (id16 == NULL) {
4216 DEBUG(5,("set_user_info_16: NULL id16\n"));
4217 return NT_STATUS_ACCESS_DENIED;
4220 copy_id16_to_sam_passwd(pwd, id16);
4222 return pdb_update_sam_account(pwd);
4225 /*******************************************************************
4226 set_user_info_17
4227 ********************************************************************/
4229 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4230 struct samr_UserInfo17 *id17,
4231 struct samu *pwd)
4233 if (id17 == NULL) {
4234 DEBUG(5,("set_user_info_17: NULL id17\n"));
4235 return NT_STATUS_ACCESS_DENIED;
4238 copy_id17_to_sam_passwd(pwd, id17);
4240 return pdb_update_sam_account(pwd);
4243 /*******************************************************************
4244 set_user_info_18
4245 ********************************************************************/
4247 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4248 TALLOC_CTX *mem_ctx,
4249 DATA_BLOB *session_key,
4250 struct samu *pwd)
4252 if (id18 == NULL) {
4253 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4254 return NT_STATUS_INVALID_PARAMETER;
4257 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4258 if (!session_key->length) {
4259 return NT_STATUS_NO_USER_SESSION_KEY;
4263 if (id18->nt_pwd_active) {
4265 DATA_BLOB in, out;
4267 in = data_blob_const(id18->nt_pwd.hash, 16);
4268 out = data_blob_talloc_zero(mem_ctx, 16);
4270 sess_crypt_blob(&out, &in, session_key, false);
4272 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4273 return NT_STATUS_ACCESS_DENIED;
4276 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4279 if (id18->lm_pwd_active) {
4281 DATA_BLOB in, out;
4283 in = data_blob_const(id18->lm_pwd.hash, 16);
4284 out = data_blob_talloc_zero(mem_ctx, 16);
4286 sess_crypt_blob(&out, &in, session_key, false);
4288 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4289 return NT_STATUS_ACCESS_DENIED;
4292 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4295 copy_id18_to_sam_passwd(pwd, id18);
4297 return pdb_update_sam_account(pwd);
4300 /*******************************************************************
4301 set_user_info_20
4302 ********************************************************************/
4304 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4305 struct samr_UserInfo20 *id20,
4306 struct samu *pwd)
4308 if (id20 == NULL) {
4309 DEBUG(5,("set_user_info_20: NULL id20\n"));
4310 return NT_STATUS_ACCESS_DENIED;
4313 copy_id20_to_sam_passwd(pwd, id20);
4315 return pdb_update_sam_account(pwd);
4318 /*******************************************************************
4319 set_user_info_21
4320 ********************************************************************/
4322 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4323 TALLOC_CTX *mem_ctx,
4324 DATA_BLOB *session_key,
4325 struct samu *pwd)
4327 NTSTATUS status;
4329 if (id21 == NULL) {
4330 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4331 return NT_STATUS_INVALID_PARAMETER;
4334 if (id21->fields_present == 0) {
4335 return NT_STATUS_INVALID_PARAMETER;
4338 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4339 return NT_STATUS_ACCESS_DENIED;
4342 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4343 if (id21->nt_password_set) {
4344 DATA_BLOB in, out;
4346 if ((id21->nt_owf_password.length != 16) ||
4347 (id21->nt_owf_password.size != 16)) {
4348 return NT_STATUS_INVALID_PARAMETER;
4351 if (!session_key->length) {
4352 return NT_STATUS_NO_USER_SESSION_KEY;
4355 in = data_blob_const(id21->nt_owf_password.array, 16);
4356 out = data_blob_talloc_zero(mem_ctx, 16);
4358 sess_crypt_blob(&out, &in, session_key, false);
4360 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4361 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4365 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4366 if (id21->lm_password_set) {
4367 DATA_BLOB in, out;
4369 if ((id21->lm_owf_password.length != 16) ||
4370 (id21->lm_owf_password.size != 16)) {
4371 return NT_STATUS_INVALID_PARAMETER;
4374 if (!session_key->length) {
4375 return NT_STATUS_NO_USER_SESSION_KEY;
4378 in = data_blob_const(id21->lm_owf_password.array, 16);
4379 out = data_blob_talloc_zero(mem_ctx, 16);
4381 sess_crypt_blob(&out, &in, session_key, false);
4383 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4384 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4388 /* we need to separately check for an account rename first */
4390 if (id21->account_name.string &&
4391 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4394 /* check to see if the new username already exists. Note: we can't
4395 reliably lock all backends, so there is potentially the
4396 possibility that a user can be created in between this check and
4397 the rename. The rename should fail, but may not get the
4398 exact same failure status code. I think this is small enough
4399 of a window for this type of operation and the results are
4400 simply that the rename fails with a slightly different status
4401 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4403 status = can_create(mem_ctx, id21->account_name.string);
4404 if (!NT_STATUS_IS_OK(status)) {
4405 return status;
4408 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4410 if (!NT_STATUS_IS_OK(status)) {
4411 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4412 nt_errstr(status)));
4413 return status;
4416 /* set the new username so that later
4417 functions can work on the new account */
4418 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4421 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4424 * The funny part about the previous two calls is
4425 * that pwd still has the password hashes from the
4426 * passdb entry. These have not been updated from
4427 * id21. I don't know if they need to be set. --jerry
4430 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4431 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4432 if ( !NT_STATUS_IS_OK(status) ) {
4433 return status;
4437 /* Don't worry about writing out the user account since the
4438 primary group SID is generated solely from the user's Unix
4439 primary group. */
4441 /* write the change out */
4442 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4443 return status;
4446 return NT_STATUS_OK;
4449 /*******************************************************************
4450 set_user_info_23
4451 ********************************************************************/
4453 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4454 struct samr_UserInfo23 *id23,
4455 struct samu *pwd)
4457 char *plaintext_buf = NULL;
4458 size_t len = 0;
4459 uint32_t acct_ctrl;
4460 NTSTATUS status;
4462 if (id23 == NULL) {
4463 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4464 return NT_STATUS_INVALID_PARAMETER;
4467 if (id23->info.fields_present == 0) {
4468 return NT_STATUS_INVALID_PARAMETER;
4471 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4472 return NT_STATUS_ACCESS_DENIED;
4475 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4476 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4478 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4479 pdb_get_username(pwd)));
4481 if (!decode_pw_buffer(mem_ctx,
4482 id23->password.data,
4483 &plaintext_buf,
4484 &len,
4485 CH_UTF16)) {
4486 return NT_STATUS_WRONG_PASSWORD;
4489 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4490 return NT_STATUS_ACCESS_DENIED;
4494 copy_id23_to_sam_passwd(pwd, id23);
4496 acct_ctrl = pdb_get_acct_ctrl(pwd);
4498 /* if it's a trust account, don't update /etc/passwd */
4499 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4500 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4501 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4502 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4503 } else if (plaintext_buf) {
4504 /* update the UNIX password */
4505 if (lp_unix_password_sync() ) {
4506 struct passwd *passwd;
4507 if (pdb_get_username(pwd) == NULL) {
4508 DEBUG(1, ("chgpasswd: User without name???\n"));
4509 return NT_STATUS_ACCESS_DENIED;
4512 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4513 if (passwd == NULL) {
4514 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4517 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4518 return NT_STATUS_ACCESS_DENIED;
4520 TALLOC_FREE(passwd);
4524 if (plaintext_buf) {
4525 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4528 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4529 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4530 pwd)))) {
4531 return status;
4534 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4535 return status;
4538 return NT_STATUS_OK;
4541 /*******************************************************************
4542 set_user_info_pw
4543 ********************************************************************/
4545 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4547 size_t len = 0;
4548 char *plaintext_buf = NULL;
4549 uint32 acct_ctrl;
4551 DEBUG(5, ("Attempting administrator password change for user %s\n",
4552 pdb_get_username(pwd)));
4554 acct_ctrl = pdb_get_acct_ctrl(pwd);
4556 if (!decode_pw_buffer(talloc_tos(),
4557 pass,
4558 &plaintext_buf,
4559 &len,
4560 CH_UTF16)) {
4561 return False;
4564 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4565 return False;
4568 /* if it's a trust account, don't update /etc/passwd */
4569 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4570 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4571 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4572 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4573 } else {
4574 /* update the UNIX password */
4575 if (lp_unix_password_sync()) {
4576 struct passwd *passwd;
4578 if (pdb_get_username(pwd) == NULL) {
4579 DEBUG(1, ("chgpasswd: User without name???\n"));
4580 return False;
4583 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4584 if (passwd == NULL) {
4585 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4588 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4589 return False;
4591 TALLOC_FREE(passwd);
4595 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4597 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4599 return True;
4602 /*******************************************************************
4603 set_user_info_24
4604 ********************************************************************/
4606 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4607 struct samr_UserInfo24 *id24,
4608 struct samu *pwd)
4610 NTSTATUS status;
4612 if (id24 == NULL) {
4613 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4614 return NT_STATUS_INVALID_PARAMETER;
4617 if (!set_user_info_pw(id24->password.data, pwd)) {
4618 return NT_STATUS_WRONG_PASSWORD;
4621 copy_id24_to_sam_passwd(pwd, id24);
4623 status = pdb_update_sam_account(pwd);
4624 if (!NT_STATUS_IS_OK(status)) {
4625 return status;
4628 return NT_STATUS_OK;
4631 /*******************************************************************
4632 set_user_info_25
4633 ********************************************************************/
4635 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4636 struct samr_UserInfo25 *id25,
4637 struct samu *pwd)
4639 NTSTATUS status;
4641 if (id25 == NULL) {
4642 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4643 return NT_STATUS_INVALID_PARAMETER;
4646 if (id25->info.fields_present == 0) {
4647 return NT_STATUS_INVALID_PARAMETER;
4650 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4651 return NT_STATUS_ACCESS_DENIED;
4654 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4655 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4657 if (!set_user_info_pw(id25->password.data, pwd)) {
4658 return NT_STATUS_WRONG_PASSWORD;
4662 copy_id25_to_sam_passwd(pwd, id25);
4664 /* write the change out */
4665 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4666 return status;
4670 * We need to "pdb_update_sam_account" before the unix primary group
4671 * is set, because the idealx scripts would also change the
4672 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4673 * the delete explicit / add explicit, which would then fail to find
4674 * the previous primaryGroupSid value.
4677 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4678 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4679 if ( !NT_STATUS_IS_OK(status) ) {
4680 return status;
4684 return NT_STATUS_OK;
4687 /*******************************************************************
4688 set_user_info_26
4689 ********************************************************************/
4691 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4692 struct samr_UserInfo26 *id26,
4693 struct samu *pwd)
4695 NTSTATUS status;
4697 if (id26 == NULL) {
4698 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4699 return NT_STATUS_INVALID_PARAMETER;
4702 if (!set_user_info_pw(id26->password.data, pwd)) {
4703 return NT_STATUS_WRONG_PASSWORD;
4706 copy_id26_to_sam_passwd(pwd, id26);
4708 status = pdb_update_sam_account(pwd);
4709 if (!NT_STATUS_IS_OK(status)) {
4710 return status;
4713 return NT_STATUS_OK;
4717 /*******************************************************************
4718 samr_SetUserInfo
4719 ********************************************************************/
4721 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4722 struct samr_SetUserInfo *r)
4724 struct samr_user_info *uinfo;
4725 NTSTATUS status;
4726 struct samu *pwd = NULL;
4727 union samr_UserInfo *info = r->in.info;
4728 uint16_t switch_value = r->in.level;
4729 uint32_t acc_required;
4730 bool ret;
4732 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4734 /* This is tricky. A WinXP domain join sets
4735 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4736 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4737 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4738 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4739 we'll use the set from the WinXP join as the basis. */
4741 switch (switch_value) {
4742 case 7:
4743 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
4744 break;
4745 case 18:
4746 case 24:
4747 case 25:
4748 case 26:
4749 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4750 break;
4751 default:
4752 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4753 SAMR_USER_ACCESS_SET_ATTRIBUTES |
4754 SAMR_USER_ACCESS_GET_ATTRIBUTES;
4755 break;
4758 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
4759 struct samr_user_info, &status);
4760 if (!NT_STATUS_IS_OK(status)) {
4761 return status;
4764 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4765 sid_string_dbg(&uinfo->sid), switch_value));
4767 if (info == NULL) {
4768 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4769 return NT_STATUS_INVALID_INFO_CLASS;
4772 if (!(pwd = samu_new(NULL))) {
4773 return NT_STATUS_NO_MEMORY;
4776 become_root();
4777 ret = pdb_getsampwsid(pwd, &uinfo->sid);
4778 unbecome_root();
4780 if (!ret) {
4781 TALLOC_FREE(pwd);
4782 return NT_STATUS_NO_SUCH_USER;
4785 /* ================ BEGIN Privilege BLOCK ================ */
4787 become_root();
4789 /* ok! user info levels (lots: see MSDEV help), off we go... */
4791 switch (switch_value) {
4793 case 2:
4794 status = set_user_info_2(p->mem_ctx,
4795 &info->info2, pwd);
4796 break;
4798 case 4:
4799 status = set_user_info_4(p->mem_ctx,
4800 &info->info4, pwd);
4801 break;
4803 case 6:
4804 status = set_user_info_6(p->mem_ctx,
4805 &info->info6, pwd);
4806 break;
4808 case 7:
4809 status = set_user_info_7(p->mem_ctx,
4810 &info->info7, pwd);
4811 break;
4813 case 8:
4814 status = set_user_info_8(p->mem_ctx,
4815 &info->info8, pwd);
4816 break;
4818 case 10:
4819 status = set_user_info_10(p->mem_ctx,
4820 &info->info10, pwd);
4821 break;
4823 case 11:
4824 status = set_user_info_11(p->mem_ctx,
4825 &info->info11, pwd);
4826 break;
4828 case 12:
4829 status = set_user_info_12(p->mem_ctx,
4830 &info->info12, pwd);
4831 break;
4833 case 13:
4834 status = set_user_info_13(p->mem_ctx,
4835 &info->info13, pwd);
4836 break;
4838 case 14:
4839 status = set_user_info_14(p->mem_ctx,
4840 &info->info14, pwd);
4841 break;
4843 case 16:
4844 status = set_user_info_16(p->mem_ctx,
4845 &info->info16, pwd);
4846 break;
4848 case 17:
4849 status = set_user_info_17(p->mem_ctx,
4850 &info->info17, pwd);
4851 break;
4853 case 18:
4854 /* Used by AS/U JRA. */
4855 status = set_user_info_18(&info->info18,
4856 p->mem_ctx,
4857 &p->server_info->user_session_key,
4858 pwd);
4859 break;
4861 case 20:
4862 status = set_user_info_20(p->mem_ctx,
4863 &info->info20, pwd);
4864 break;
4866 case 21:
4867 status = set_user_info_21(&info->info21,
4868 p->mem_ctx,
4869 &p->server_info->user_session_key,
4870 pwd);
4871 break;
4873 case 23:
4874 if (!p->server_info->user_session_key.length) {
4875 status = NT_STATUS_NO_USER_SESSION_KEY;
4877 arcfour_crypt_blob(info->info23.password.data, 516,
4878 &p->server_info->user_session_key);
4880 dump_data(100, info->info23.password.data, 516);
4882 status = set_user_info_23(p->mem_ctx,
4883 &info->info23, pwd);
4884 break;
4886 case 24:
4887 if (!p->server_info->user_session_key.length) {
4888 status = NT_STATUS_NO_USER_SESSION_KEY;
4890 arcfour_crypt_blob(info->info24.password.data,
4891 516,
4892 &p->server_info->user_session_key);
4894 dump_data(100, info->info24.password.data, 516);
4896 status = set_user_info_24(p->mem_ctx,
4897 &info->info24, pwd);
4898 break;
4900 case 25:
4901 if (!p->server_info->user_session_key.length) {
4902 status = NT_STATUS_NO_USER_SESSION_KEY;
4904 encode_or_decode_arc4_passwd_buffer(
4905 info->info25.password.data,
4906 &p->server_info->user_session_key);
4908 dump_data(100, info->info25.password.data, 532);
4910 status = set_user_info_25(p->mem_ctx,
4911 &info->info25, pwd);
4912 break;
4914 case 26:
4915 if (!p->server_info->user_session_key.length) {
4916 status = NT_STATUS_NO_USER_SESSION_KEY;
4918 encode_or_decode_arc4_passwd_buffer(
4919 info->info26.password.data,
4920 &p->server_info->user_session_key);
4922 dump_data(100, info->info26.password.data, 516);
4924 status = set_user_info_26(p->mem_ctx,
4925 &info->info26, pwd);
4926 break;
4928 default:
4929 status = NT_STATUS_INVALID_INFO_CLASS;
4932 TALLOC_FREE(pwd);
4934 unbecome_root();
4936 /* ================ END Privilege BLOCK ================ */
4938 if (NT_STATUS_IS_OK(status)) {
4939 force_flush_samr_cache(&uinfo->sid);
4942 return status;
4945 /*******************************************************************
4946 _samr_SetUserInfo2
4947 ********************************************************************/
4949 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4950 struct samr_SetUserInfo2 *r)
4952 struct samr_SetUserInfo q;
4954 q.in.user_handle = r->in.user_handle;
4955 q.in.level = r->in.level;
4956 q.in.info = r->in.info;
4958 return _samr_SetUserInfo(p, &q);
4961 /*********************************************************************
4962 _samr_GetAliasMembership
4963 *********************************************************************/
4965 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4966 struct samr_GetAliasMembership *r)
4968 size_t num_alias_rids;
4969 uint32 *alias_rids;
4970 struct samr_domain_info *dinfo;
4971 size_t i;
4973 NTSTATUS status;
4975 DOM_SID *members;
4977 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4979 dinfo = policy_handle_find(p, r->in.domain_handle,
4980 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
4981 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4982 struct samr_domain_info, &status);
4983 if (!NT_STATUS_IS_OK(status)) {
4984 return status;
4987 if (!sid_check_is_domain(&dinfo->sid) &&
4988 !sid_check_is_builtin(&dinfo->sid))
4989 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4991 if (r->in.sids->num_sids) {
4992 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4994 if (members == NULL)
4995 return NT_STATUS_NO_MEMORY;
4996 } else {
4997 members = NULL;
5000 for (i=0; i<r->in.sids->num_sids; i++)
5001 sid_copy(&members[i], r->in.sids->sids[i].sid);
5003 alias_rids = NULL;
5004 num_alias_rids = 0;
5006 become_root();
5007 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5008 r->in.sids->num_sids,
5009 &alias_rids, &num_alias_rids);
5010 unbecome_root();
5012 if (!NT_STATUS_IS_OK(status)) {
5013 return status;
5016 r->out.rids->count = num_alias_rids;
5017 r->out.rids->ids = alias_rids;
5019 return NT_STATUS_OK;
5022 /*********************************************************************
5023 _samr_GetMembersInAlias
5024 *********************************************************************/
5026 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5027 struct samr_GetMembersInAlias *r)
5029 struct samr_alias_info *ainfo;
5030 NTSTATUS status;
5031 size_t i;
5032 size_t num_sids = 0;
5033 struct lsa_SidPtr *sids = NULL;
5034 DOM_SID *pdb_sids = NULL;
5036 ainfo = policy_handle_find(p, r->in.alias_handle,
5037 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5038 struct samr_alias_info, &status);
5039 if (!NT_STATUS_IS_OK(status)) {
5040 return status;
5043 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5045 become_root();
5046 status = pdb_enum_aliasmem(&ainfo->sid, &pdb_sids, &num_sids);
5047 unbecome_root();
5049 if (!NT_STATUS_IS_OK(status)) {
5050 return status;
5053 if (num_sids) {
5054 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5055 if (sids == NULL) {
5056 TALLOC_FREE(pdb_sids);
5057 return NT_STATUS_NO_MEMORY;
5061 for (i = 0; i < num_sids; i++) {
5062 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5063 if (!sids[i].sid) {
5064 TALLOC_FREE(pdb_sids);
5065 return NT_STATUS_NO_MEMORY;
5069 r->out.sids->num_sids = num_sids;
5070 r->out.sids->sids = sids;
5072 TALLOC_FREE(pdb_sids);
5074 return NT_STATUS_OK;
5077 /*********************************************************************
5078 _samr_QueryGroupMember
5079 *********************************************************************/
5081 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5082 struct samr_QueryGroupMember *r)
5084 struct samr_group_info *ginfo;
5085 size_t i, num_members;
5087 uint32 *rid=NULL;
5088 uint32 *attr=NULL;
5090 NTSTATUS status;
5091 struct samr_RidTypeArray *rids = NULL;
5093 ginfo = policy_handle_find(p, r->in.group_handle,
5094 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5095 struct samr_group_info, &status);
5096 if (!NT_STATUS_IS_OK(status)) {
5097 return status;
5100 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5101 if (!rids) {
5102 return NT_STATUS_NO_MEMORY;
5105 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5107 if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5108 DEBUG(3, ("sid %s is not in our domain\n",
5109 sid_string_dbg(&ginfo->sid)));
5110 return NT_STATUS_NO_SUCH_GROUP;
5113 DEBUG(10, ("lookup on Domain SID\n"));
5115 become_root();
5116 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5117 &rid, &num_members);
5118 unbecome_root();
5120 if (!NT_STATUS_IS_OK(status))
5121 return status;
5123 if (num_members) {
5124 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5125 if (attr == NULL) {
5126 return NT_STATUS_NO_MEMORY;
5128 } else {
5129 attr = NULL;
5132 for (i=0; i<num_members; i++)
5133 attr[i] = SID_NAME_USER;
5135 rids->count = num_members;
5136 rids->types = attr;
5137 rids->rids = rid;
5139 *r->out.rids = rids;
5141 return NT_STATUS_OK;
5144 /*********************************************************************
5145 _samr_AddAliasMember
5146 *********************************************************************/
5148 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5149 struct samr_AddAliasMember *r)
5151 struct samr_alias_info *ainfo;
5152 NTSTATUS status;
5154 ainfo = policy_handle_find(p, r->in.alias_handle,
5155 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5156 struct samr_alias_info, &status);
5157 if (!NT_STATUS_IS_OK(status)) {
5158 return status;
5161 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5163 /******** BEGIN SeAddUsers BLOCK *********/
5165 become_root();
5166 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5167 unbecome_root();
5169 /******** END SeAddUsers BLOCK *********/
5171 if (NT_STATUS_IS_OK(status)) {
5172 force_flush_samr_cache(&ainfo->sid);
5175 return status;
5178 /*********************************************************************
5179 _samr_DeleteAliasMember
5180 *********************************************************************/
5182 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5183 struct samr_DeleteAliasMember *r)
5185 struct samr_alias_info *ainfo;
5186 NTSTATUS status;
5188 ainfo = policy_handle_find(p, r->in.alias_handle,
5189 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5190 struct samr_alias_info, &status);
5191 if (!NT_STATUS_IS_OK(status)) {
5192 return status;
5195 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5196 sid_string_dbg(&ainfo->sid)));
5198 /******** BEGIN SeAddUsers BLOCK *********/
5200 become_root();
5201 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5202 unbecome_root();
5204 /******** END SeAddUsers BLOCK *********/
5206 if (NT_STATUS_IS_OK(status)) {
5207 force_flush_samr_cache(&ainfo->sid);
5210 return status;
5213 /*********************************************************************
5214 _samr_AddGroupMember
5215 *********************************************************************/
5217 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5218 struct samr_AddGroupMember *r)
5220 struct samr_group_info *ginfo;
5221 NTSTATUS status;
5222 uint32 group_rid;
5224 ginfo = policy_handle_find(p, r->in.group_handle,
5225 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5226 struct samr_group_info, &status);
5227 if (!NT_STATUS_IS_OK(status)) {
5228 return status;
5231 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5233 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5234 &group_rid)) {
5235 return NT_STATUS_INVALID_HANDLE;
5238 /******** BEGIN SeAddUsers BLOCK *********/
5240 become_root();
5241 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5242 unbecome_root();
5244 /******** END SeAddUsers BLOCK *********/
5246 force_flush_samr_cache(&ginfo->sid);
5248 return status;
5251 /*********************************************************************
5252 _samr_DeleteGroupMember
5253 *********************************************************************/
5255 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5256 struct samr_DeleteGroupMember *r)
5259 struct samr_group_info *ginfo;
5260 NTSTATUS status;
5261 uint32 group_rid;
5264 * delete the group member named r->in.rid
5265 * who is a member of the sid associated with the handle
5266 * the rid is a user's rid as the group is a domain group.
5269 ginfo = policy_handle_find(p, r->in.group_handle,
5270 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5271 struct samr_group_info, &status);
5272 if (!NT_STATUS_IS_OK(status)) {
5273 return status;
5276 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5277 &group_rid)) {
5278 return NT_STATUS_INVALID_HANDLE;
5281 /******** BEGIN SeAddUsers BLOCK *********/
5283 become_root();
5284 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5285 unbecome_root();
5287 /******** END SeAddUsers BLOCK *********/
5289 force_flush_samr_cache(&ginfo->sid);
5291 return status;
5294 /*********************************************************************
5295 _samr_DeleteUser
5296 *********************************************************************/
5298 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5299 struct samr_DeleteUser *r)
5301 struct samr_user_info *uinfo;
5302 NTSTATUS status;
5303 struct samu *sam_pass=NULL;
5304 bool can_del_accounts = false;
5305 uint32 acb_info = 0;
5306 bool ret;
5308 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5310 uinfo = policy_handle_find(p, r->in.user_handle,
5311 STD_RIGHT_DELETE_ACCESS, NULL,
5312 struct samr_user_info, &status);
5313 if (!NT_STATUS_IS_OK(status)) {
5314 return status;
5317 if (!sid_check_is_in_our_domain(&uinfo->sid))
5318 return NT_STATUS_CANNOT_DELETE;
5320 /* check if the user exists before trying to delete */
5321 if ( !(sam_pass = samu_new( NULL )) ) {
5322 return NT_STATUS_NO_MEMORY;
5325 become_root();
5326 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5327 unbecome_root();
5329 if (ret) {
5330 acb_info = pdb_get_acct_ctrl(sam_pass);
5333 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
5334 if (geteuid() == sec_initial_uid()) {
5335 can_del_accounts = true;
5336 } else if (acb_info & ACB_WSTRUST) {
5337 can_del_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
5338 } else {
5339 can_del_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5342 if (!can_del_accounts) {
5343 TALLOC_FREE(sam_pass);
5344 return NT_STATUS_ACCESS_DENIED;
5347 if(!ret) {
5348 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5349 sid_string_dbg(&uinfo->sid)));
5350 TALLOC_FREE(sam_pass);
5351 return NT_STATUS_NO_SUCH_USER;
5354 /******** BEGIN SeAddUsers BLOCK *********/
5356 become_root();
5357 status = pdb_delete_user(p->mem_ctx, sam_pass);
5358 unbecome_root();
5360 /******** END SeAddUsers BLOCK *********/
5362 if ( !NT_STATUS_IS_OK(status) ) {
5363 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5364 "user %s: %s.\n", pdb_get_username(sam_pass),
5365 nt_errstr(status)));
5366 TALLOC_FREE(sam_pass);
5367 return status;
5371 TALLOC_FREE(sam_pass);
5373 if (!close_policy_hnd(p, r->in.user_handle))
5374 return NT_STATUS_OBJECT_NAME_INVALID;
5376 ZERO_STRUCTP(r->out.user_handle);
5378 force_flush_samr_cache(&uinfo->sid);
5380 return NT_STATUS_OK;
5383 /*********************************************************************
5384 _samr_DeleteDomainGroup
5385 *********************************************************************/
5387 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5388 struct samr_DeleteDomainGroup *r)
5390 struct samr_group_info *ginfo;
5391 NTSTATUS status;
5392 uint32 group_rid;
5394 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5396 ginfo = policy_handle_find(p, r->in.group_handle,
5397 STD_RIGHT_DELETE_ACCESS, NULL,
5398 struct samr_group_info, &status);
5399 if (!NT_STATUS_IS_OK(status)) {
5400 return status;
5403 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5405 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5406 &group_rid)) {
5407 return NT_STATUS_NO_SUCH_GROUP;
5410 /******** BEGIN SeAddUsers BLOCK *********/
5412 become_root();
5413 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5414 unbecome_root();
5416 /******** END SeAddUsers BLOCK *********/
5418 if ( !NT_STATUS_IS_OK(status) ) {
5419 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5420 "entry for group %s: %s\n",
5421 sid_string_dbg(&ginfo->sid),
5422 nt_errstr(status)));
5423 return status;
5426 if (!close_policy_hnd(p, r->in.group_handle))
5427 return NT_STATUS_OBJECT_NAME_INVALID;
5429 force_flush_samr_cache(&ginfo->sid);
5431 return NT_STATUS_OK;
5434 /*********************************************************************
5435 _samr_DeleteDomAlias
5436 *********************************************************************/
5438 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5439 struct samr_DeleteDomAlias *r)
5441 struct samr_alias_info *ainfo;
5442 NTSTATUS status;
5444 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5446 ainfo = policy_handle_find(p, r->in.alias_handle,
5447 STD_RIGHT_DELETE_ACCESS, NULL,
5448 struct samr_alias_info, &status);
5449 if (!NT_STATUS_IS_OK(status)) {
5450 return status;
5453 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5455 /* Don't let Windows delete builtin groups */
5457 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5458 return NT_STATUS_SPECIAL_ACCOUNT;
5461 if (!sid_check_is_in_our_domain(&ainfo->sid))
5462 return NT_STATUS_NO_SUCH_ALIAS;
5464 DEBUG(10, ("lookup on Local SID\n"));
5466 /******** BEGIN SeAddUsers BLOCK *********/
5468 become_root();
5469 /* Have passdb delete the alias */
5470 status = pdb_delete_alias(&ainfo->sid);
5471 unbecome_root();
5473 /******** END SeAddUsers BLOCK *********/
5475 if ( !NT_STATUS_IS_OK(status))
5476 return status;
5478 if (!close_policy_hnd(p, r->in.alias_handle))
5479 return NT_STATUS_OBJECT_NAME_INVALID;
5481 force_flush_samr_cache(&ainfo->sid);
5483 return NT_STATUS_OK;
5486 /*********************************************************************
5487 _samr_CreateDomainGroup
5488 *********************************************************************/
5490 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5491 struct samr_CreateDomainGroup *r)
5494 NTSTATUS status;
5495 const char *name;
5496 struct samr_domain_info *dinfo;
5497 struct samr_group_info *ginfo;
5499 dinfo = policy_handle_find(p, r->in.domain_handle,
5500 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5501 struct samr_domain_info, &status);
5502 if (!NT_STATUS_IS_OK(status)) {
5503 return status;
5506 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5507 return NT_STATUS_ACCESS_DENIED;
5509 name = r->in.name->string;
5510 if (name == NULL) {
5511 return NT_STATUS_NO_MEMORY;
5514 status = can_create(p->mem_ctx, name);
5515 if (!NT_STATUS_IS_OK(status)) {
5516 return status;
5519 /******** BEGIN SeAddUsers BLOCK *********/
5521 become_root();
5522 /* check that we successfully create the UNIX group */
5523 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5524 unbecome_root();
5526 /******** END SeAddUsers BLOCK *********/
5528 /* check if we should bail out here */
5530 if ( !NT_STATUS_IS_OK(status) )
5531 return status;
5533 ginfo = policy_handle_create(p, r->out.group_handle,
5534 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5535 struct samr_group_info, &status);
5536 if (!NT_STATUS_IS_OK(status)) {
5537 return status;
5539 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5541 force_flush_samr_cache(&dinfo->sid);
5543 return NT_STATUS_OK;
5546 /*********************************************************************
5547 _samr_CreateDomAlias
5548 *********************************************************************/
5550 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5551 struct samr_CreateDomAlias *r)
5553 DOM_SID info_sid;
5554 const char *name = NULL;
5555 struct samr_domain_info *dinfo;
5556 struct samr_alias_info *ainfo;
5557 gid_t gid;
5558 NTSTATUS result;
5560 dinfo = policy_handle_find(p, r->in.domain_handle,
5561 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5562 struct samr_domain_info, &result);
5563 if (!NT_STATUS_IS_OK(result)) {
5564 return result;
5567 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5568 return NT_STATUS_ACCESS_DENIED;
5570 name = r->in.alias_name->string;
5572 result = can_create(p->mem_ctx, name);
5573 if (!NT_STATUS_IS_OK(result)) {
5574 return result;
5577 /******** BEGIN SeAddUsers BLOCK *********/
5579 become_root();
5580 /* Have passdb create the alias */
5581 result = pdb_create_alias(name, r->out.rid);
5582 unbecome_root();
5584 /******** END SeAddUsers BLOCK *********/
5586 if (!NT_STATUS_IS_OK(result)) {
5587 DEBUG(10, ("pdb_create_alias failed: %s\n",
5588 nt_errstr(result)));
5589 return result;
5592 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5594 if (!sid_to_gid(&info_sid, &gid)) {
5595 DEBUG(10, ("Could not find alias just created\n"));
5596 return NT_STATUS_ACCESS_DENIED;
5599 /* check if the group has been successfully created */
5600 if ( getgrgid(gid) == NULL ) {
5601 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5602 (unsigned int)gid));
5603 return NT_STATUS_ACCESS_DENIED;
5606 ainfo = policy_handle_create(p, r->out.alias_handle,
5607 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5608 struct samr_alias_info, &result);
5609 if (!NT_STATUS_IS_OK(result)) {
5610 return result;
5612 ainfo->sid = info_sid;
5614 force_flush_samr_cache(&info_sid);
5616 return NT_STATUS_OK;
5619 /*********************************************************************
5620 _samr_QueryGroupInfo
5621 *********************************************************************/
5623 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5624 struct samr_QueryGroupInfo *r)
5626 struct samr_group_info *ginfo;
5627 NTSTATUS status;
5628 GROUP_MAP map;
5629 union samr_GroupInfo *info = NULL;
5630 bool ret;
5631 uint32_t attributes = SE_GROUP_MANDATORY |
5632 SE_GROUP_ENABLED_BY_DEFAULT |
5633 SE_GROUP_ENABLED;
5634 const char *group_name = NULL;
5635 const char *group_description = NULL;
5637 ginfo = policy_handle_find(p, r->in.group_handle,
5638 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5639 struct samr_group_info, &status);
5640 if (!NT_STATUS_IS_OK(status)) {
5641 return status;
5644 become_root();
5645 ret = get_domain_group_from_sid(ginfo->sid, &map);
5646 unbecome_root();
5647 if (!ret)
5648 return NT_STATUS_INVALID_HANDLE;
5650 /* FIXME: map contains fstrings */
5651 group_name = talloc_strdup(r, map.nt_name);
5652 group_description = talloc_strdup(r, map.comment);
5654 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5655 if (!info) {
5656 return NT_STATUS_NO_MEMORY;
5659 switch (r->in.level) {
5660 case 1: {
5661 uint32 *members;
5662 size_t num_members;
5664 become_root();
5665 status = pdb_enum_group_members(
5666 p->mem_ctx, &ginfo->sid, &members,
5667 &num_members);
5668 unbecome_root();
5670 if (!NT_STATUS_IS_OK(status)) {
5671 return status;
5674 info->all.name.string = group_name;
5675 info->all.attributes = attributes;
5676 info->all.num_members = num_members;
5677 info->all.description.string = group_description;
5678 break;
5680 case 2:
5681 info->name.string = group_name;
5682 break;
5683 case 3:
5684 info->attributes.attributes = attributes;
5685 break;
5686 case 4:
5687 info->description.string = group_description;
5688 break;
5689 case 5: {
5691 uint32 *members;
5692 size_t num_members;
5696 become_root();
5697 status = pdb_enum_group_members(
5698 p->mem_ctx, &ginfo->sid, &members,
5699 &num_members);
5700 unbecome_root();
5702 if (!NT_STATUS_IS_OK(status)) {
5703 return status;
5706 info->all2.name.string = group_name;
5707 info->all2.attributes = attributes;
5708 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5709 info->all2.description.string = group_description;
5711 break;
5713 default:
5714 return NT_STATUS_INVALID_INFO_CLASS;
5717 *r->out.info = info;
5719 return NT_STATUS_OK;
5722 /*********************************************************************
5723 _samr_SetGroupInfo
5724 *********************************************************************/
5726 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5727 struct samr_SetGroupInfo *r)
5729 struct samr_group_info *ginfo;
5730 GROUP_MAP map;
5731 NTSTATUS status;
5732 bool ret;
5734 ginfo = policy_handle_find(p, r->in.group_handle,
5735 SAMR_GROUP_ACCESS_SET_INFO, NULL,
5736 struct samr_group_info, &status);
5737 if (!NT_STATUS_IS_OK(status)) {
5738 return status;
5741 become_root();
5742 ret = get_domain_group_from_sid(ginfo->sid, &map);
5743 unbecome_root();
5744 if (!ret)
5745 return NT_STATUS_NO_SUCH_GROUP;
5747 switch (r->in.level) {
5748 case 1:
5749 fstrcpy(map.comment, r->in.info->all.description.string);
5750 break;
5751 case 2:
5752 /* group rename is not supported yet */
5753 return NT_STATUS_NOT_SUPPORTED;
5754 case 4:
5755 fstrcpy(map.comment, r->in.info->description.string);
5756 break;
5757 default:
5758 return NT_STATUS_INVALID_INFO_CLASS;
5761 /******** BEGIN SeAddUsers BLOCK *********/
5763 become_root();
5764 status = pdb_update_group_mapping_entry(&map);
5765 unbecome_root();
5767 /******** End SeAddUsers BLOCK *********/
5769 if (NT_STATUS_IS_OK(status)) {
5770 force_flush_samr_cache(&ginfo->sid);
5773 return status;
5776 /*********************************************************************
5777 _samr_SetAliasInfo
5778 *********************************************************************/
5780 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5781 struct samr_SetAliasInfo *r)
5783 struct samr_alias_info *ainfo;
5784 struct acct_info info;
5785 NTSTATUS status;
5787 ainfo = policy_handle_find(p, r->in.alias_handle,
5788 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
5789 struct samr_alias_info, &status);
5790 if (!NT_STATUS_IS_OK(status)) {
5791 return status;
5794 /* get the current group information */
5796 become_root();
5797 status = pdb_get_aliasinfo( &ainfo->sid, &info );
5798 unbecome_root();
5800 if ( !NT_STATUS_IS_OK(status))
5801 return status;
5803 switch (r->in.level) {
5804 case ALIASINFONAME:
5806 fstring group_name;
5808 /* We currently do not support renaming groups in the
5809 the BUILTIN domain. Refer to util_builtin.c to understand
5810 why. The eventually needs to be fixed to be like Windows
5811 where you can rename builtin groups, just not delete them */
5813 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5814 return NT_STATUS_SPECIAL_ACCOUNT;
5817 /* There has to be a valid name (and it has to be different) */
5819 if ( !r->in.info->name.string )
5820 return NT_STATUS_INVALID_PARAMETER;
5822 /* If the name is the same just reply "ok". Yes this
5823 doesn't allow you to change the case of a group name. */
5825 if ( strequal( r->in.info->name.string, info.acct_name ) )
5826 return NT_STATUS_OK;
5828 fstrcpy( info.acct_name, r->in.info->name.string);
5830 /* make sure the name doesn't already exist as a user
5831 or local group */
5833 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5834 status = can_create( p->mem_ctx, group_name );
5835 if ( !NT_STATUS_IS_OK( status ) )
5836 return status;
5837 break;
5839 case ALIASINFODESCRIPTION:
5840 if (r->in.info->description.string) {
5841 fstrcpy(info.acct_desc,
5842 r->in.info->description.string);
5843 } else {
5844 fstrcpy( info.acct_desc, "" );
5846 break;
5847 default:
5848 return NT_STATUS_INVALID_INFO_CLASS;
5851 /******** BEGIN SeAddUsers BLOCK *********/
5853 become_root();
5854 status = pdb_set_aliasinfo( &ainfo->sid, &info );
5855 unbecome_root();
5857 /******** End SeAddUsers BLOCK *********/
5859 if (NT_STATUS_IS_OK(status))
5860 force_flush_samr_cache(&ainfo->sid);
5862 return status;
5865 /****************************************************************
5866 _samr_GetDomPwInfo
5867 ****************************************************************/
5869 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5870 struct samr_GetDomPwInfo *r)
5872 uint32_t min_password_length = 0;
5873 uint32_t password_properties = 0;
5875 /* Perform access check. Since this rpc does not require a
5876 policy handle it will not be caught by the access checks on
5877 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5879 if (!pipe_access_check(p)) {
5880 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5881 return NT_STATUS_ACCESS_DENIED;
5884 become_root();
5885 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5886 &min_password_length);
5887 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5888 &password_properties);
5889 unbecome_root();
5891 if (lp_check_password_script() && *lp_check_password_script()) {
5892 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5895 r->out.info->min_password_length = min_password_length;
5896 r->out.info->password_properties = password_properties;
5898 return NT_STATUS_OK;
5901 /*********************************************************************
5902 _samr_OpenGroup
5903 *********************************************************************/
5905 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5906 struct samr_OpenGroup *r)
5909 DOM_SID info_sid;
5910 GROUP_MAP map;
5911 struct samr_domain_info *dinfo;
5912 struct samr_group_info *ginfo;
5913 SEC_DESC *psd = NULL;
5914 uint32 acc_granted;
5915 uint32 des_access = r->in.access_mask;
5916 size_t sd_size;
5917 NTSTATUS status;
5918 bool ret;
5919 SE_PRIV se_rights;
5921 dinfo = policy_handle_find(p, r->in.domain_handle,
5922 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5923 struct samr_domain_info, &status);
5924 if (!NT_STATUS_IS_OK(status)) {
5925 return status;
5928 /*check if access can be granted as requested by client. */
5929 map_max_allowed_access(p->server_info->ptok, &des_access);
5931 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5932 se_map_generic(&des_access,&grp_generic_mapping);
5934 se_priv_copy( &se_rights, &se_add_users );
5936 status = access_check_samr_object(psd, p->server_info->ptok,
5937 &se_rights, SAMR_GROUP_ACCESS_ADD_MEMBER,
5938 des_access, &acc_granted, "_samr_OpenGroup");
5940 if ( !NT_STATUS_IS_OK(status) )
5941 return status;
5943 /* this should not be hard-coded like this */
5945 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5946 return NT_STATUS_ACCESS_DENIED;
5948 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
5950 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
5951 sid_string_dbg(&info_sid)));
5953 /* check if that group really exists */
5954 become_root();
5955 ret = get_domain_group_from_sid(info_sid, &map);
5956 unbecome_root();
5957 if (!ret)
5958 return NT_STATUS_NO_SUCH_GROUP;
5960 ginfo = policy_handle_create(p, r->out.group_handle,
5961 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5962 struct samr_group_info, &status);
5963 if (!NT_STATUS_IS_OK(status)) {
5964 return status;
5966 ginfo->sid = info_sid;
5968 return NT_STATUS_OK;
5971 /*********************************************************************
5972 _samr_RemoveMemberFromForeignDomain
5973 *********************************************************************/
5975 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5976 struct samr_RemoveMemberFromForeignDomain *r)
5978 struct samr_domain_info *dinfo;
5979 NTSTATUS result;
5981 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5982 sid_string_dbg(r->in.sid)));
5984 /* Find the policy handle. Open a policy on it. */
5986 dinfo = policy_handle_find(p, r->in.domain_handle,
5987 STD_RIGHT_DELETE_ACCESS, NULL,
5988 struct samr_domain_info, &result);
5989 if (!NT_STATUS_IS_OK(result)) {
5990 return result;
5993 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5994 sid_string_dbg(&dinfo->sid)));
5996 /* we can only delete a user from a group since we don't have
5997 nested groups anyways. So in the latter case, just say OK */
5999 /* TODO: The above comment nowadays is bogus. Since we have nested
6000 * groups now, and aliases members are never reported out of the unix
6001 * group membership, the "just say OK" makes this call a no-op. For
6002 * us. This needs fixing however. */
6004 /* I've only ever seen this in the wild when deleting a user from
6005 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6006 * is the user about to be deleted. I very much suspect this is the
6007 * only application of this call. To verify this, let people report
6008 * other cases. */
6010 if (!sid_check_is_builtin(&dinfo->sid)) {
6011 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6012 "global_sam_sid() = %s\n",
6013 sid_string_dbg(&dinfo->sid),
6014 sid_string_dbg(get_global_sam_sid())));
6015 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6016 return NT_STATUS_OK;
6019 force_flush_samr_cache(&dinfo->sid);
6021 result = NT_STATUS_OK;
6023 return result;
6026 /*******************************************************************
6027 _samr_QueryDomainInfo2
6028 ********************************************************************/
6030 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6031 struct samr_QueryDomainInfo2 *r)
6033 struct samr_QueryDomainInfo q;
6035 q.in.domain_handle = r->in.domain_handle;
6036 q.in.level = r->in.level;
6038 q.out.info = r->out.info;
6040 return _samr_QueryDomainInfo(p, &q);
6043 /*******************************************************************
6044 _samr_SetDomainInfo
6045 ********************************************************************/
6047 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6048 struct samr_SetDomainInfo *r)
6050 struct samr_domain_info *dinfo;
6051 time_t u_expire, u_min_age;
6052 time_t u_logout;
6053 time_t u_lock_duration, u_reset_time;
6054 NTSTATUS result;
6056 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6058 /* We do have different access bits for info
6059 * levels here, but we're really just looking for
6060 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
6061 * this maps to different specific bits. So
6062 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
6063 * set we are ok. */
6065 dinfo = policy_handle_find(p, r->in.domain_handle,
6066 SAMR_DOMAIN_ACCESS_SET_INFO_1, NULL,
6067 struct samr_domain_info, &result);
6068 if (!NT_STATUS_IS_OK(result)) {
6069 return result;
6072 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6074 switch (r->in.level) {
6075 case 0x01:
6076 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
6077 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
6078 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
6079 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
6080 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
6081 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
6082 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
6083 break;
6084 case 0x03:
6085 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
6086 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
6087 break;
6088 case 0x04:
6089 break;
6090 case 0x06:
6091 break;
6092 case 0x07:
6093 break;
6094 case 0x09:
6095 break;
6096 case 0x0c:
6097 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
6098 if (u_lock_duration != -1)
6099 u_lock_duration /= 60;
6101 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
6103 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6104 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
6105 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
6106 break;
6107 default:
6108 return NT_STATUS_INVALID_INFO_CLASS;
6111 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6113 return NT_STATUS_OK;
6116 /****************************************************************
6117 _samr_GetDisplayEnumerationIndex
6118 ****************************************************************/
6120 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6121 struct samr_GetDisplayEnumerationIndex *r)
6123 struct samr_domain_info *dinfo;
6124 uint32_t max_entries = (uint32_t) -1;
6125 uint32_t enum_context = 0;
6126 int i;
6127 uint32_t num_account = 0;
6128 struct samr_displayentry *entries = NULL;
6129 NTSTATUS status;
6131 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6133 dinfo = policy_handle_find(p, r->in.domain_handle,
6134 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6135 struct samr_domain_info, &status);
6136 if (!NT_STATUS_IS_OK(status)) {
6137 return status;
6140 if ((r->in.level < 1) || (r->in.level > 3)) {
6141 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6142 "Unknown info level (%u)\n",
6143 r->in.level));
6144 return NT_STATUS_INVALID_INFO_CLASS;
6147 become_root();
6149 /* The following done as ROOT. Don't return without unbecome_root(). */
6151 switch (r->in.level) {
6152 case 1:
6153 if (dinfo->disp_info->users == NULL) {
6154 dinfo->disp_info->users = pdb_search_users(
6155 dinfo->disp_info, ACB_NORMAL);
6156 if (dinfo->disp_info->users == NULL) {
6157 unbecome_root();
6158 return NT_STATUS_ACCESS_DENIED;
6160 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6161 "starting user enumeration at index %u\n",
6162 (unsigned int)enum_context));
6163 } else {
6164 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6165 "using cached user enumeration at index %u\n",
6166 (unsigned int)enum_context));
6168 num_account = pdb_search_entries(dinfo->disp_info->users,
6169 enum_context, max_entries,
6170 &entries);
6171 break;
6172 case 2:
6173 if (dinfo->disp_info->machines == NULL) {
6174 dinfo->disp_info->machines = pdb_search_users(
6175 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6176 if (dinfo->disp_info->machines == NULL) {
6177 unbecome_root();
6178 return NT_STATUS_ACCESS_DENIED;
6180 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6181 "starting machine enumeration at index %u\n",
6182 (unsigned int)enum_context));
6183 } else {
6184 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6185 "using cached machine enumeration at index %u\n",
6186 (unsigned int)enum_context));
6188 num_account = pdb_search_entries(dinfo->disp_info->machines,
6189 enum_context, max_entries,
6190 &entries);
6191 break;
6192 case 3:
6193 if (dinfo->disp_info->groups == NULL) {
6194 dinfo->disp_info->groups = pdb_search_groups(
6195 dinfo->disp_info);
6196 if (dinfo->disp_info->groups == NULL) {
6197 unbecome_root();
6198 return NT_STATUS_ACCESS_DENIED;
6200 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6201 "starting group enumeration at index %u\n",
6202 (unsigned int)enum_context));
6203 } else {
6204 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6205 "using cached group enumeration at index %u\n",
6206 (unsigned int)enum_context));
6208 num_account = pdb_search_entries(dinfo->disp_info->groups,
6209 enum_context, max_entries,
6210 &entries);
6211 break;
6212 default:
6213 unbecome_root();
6214 smb_panic("info class changed");
6215 break;
6218 unbecome_root();
6220 /* Ensure we cache this enumeration. */
6221 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6223 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6224 r->in.name->string));
6226 for (i=0; i<num_account; i++) {
6227 if (strequal(entries[i].account_name, r->in.name->string)) {
6228 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6229 "found %s at idx %d\n",
6230 r->in.name->string, i));
6231 *r->out.idx = i;
6232 return NT_STATUS_OK;
6236 /* assuming account_name lives at the very end */
6237 *r->out.idx = num_account;
6239 return NT_STATUS_NO_MORE_ENTRIES;
6242 /****************************************************************
6243 _samr_GetDisplayEnumerationIndex2
6244 ****************************************************************/
6246 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6247 struct samr_GetDisplayEnumerationIndex2 *r)
6249 struct samr_GetDisplayEnumerationIndex q;
6251 q.in.domain_handle = r->in.domain_handle;
6252 q.in.level = r->in.level;
6253 q.in.name = r->in.name;
6255 q.out.idx = r->out.idx;
6257 return _samr_GetDisplayEnumerationIndex(p, &q);
6260 /****************************************************************
6261 _samr_RidToSid
6262 ****************************************************************/
6264 NTSTATUS _samr_RidToSid(pipes_struct *p,
6265 struct samr_RidToSid *r)
6267 struct samr_domain_info *dinfo;
6268 NTSTATUS status;
6269 struct dom_sid sid;
6271 dinfo = policy_handle_find(p, r->in.domain_handle,
6272 0, NULL,
6273 struct samr_domain_info, &status);
6274 if (!NT_STATUS_IS_OK(status)) {
6275 return status;
6278 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6279 return NT_STATUS_NO_MEMORY;
6282 *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
6283 if (!*r->out.sid) {
6284 return NT_STATUS_NO_MEMORY;
6287 return NT_STATUS_OK;
6290 /****************************************************************
6291 ****************************************************************/
6293 NTSTATUS _samr_Shutdown(pipes_struct *p,
6294 struct samr_Shutdown *r)
6296 p->rng_fault_state = true;
6297 return NT_STATUS_NOT_IMPLEMENTED;
6300 /****************************************************************
6301 ****************************************************************/
6303 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6304 struct samr_SetMemberAttributesOfGroup *r)
6306 p->rng_fault_state = true;
6307 return NT_STATUS_NOT_IMPLEMENTED;
6310 /****************************************************************
6311 ****************************************************************/
6313 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6314 struct samr_TestPrivateFunctionsDomain *r)
6316 return NT_STATUS_NOT_IMPLEMENTED;
6319 /****************************************************************
6320 ****************************************************************/
6322 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6323 struct samr_TestPrivateFunctionsUser *r)
6325 return NT_STATUS_NOT_IMPLEMENTED;
6328 /****************************************************************
6329 ****************************************************************/
6331 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6332 struct samr_AddMultipleMembersToAlias *r)
6334 p->rng_fault_state = true;
6335 return NT_STATUS_NOT_IMPLEMENTED;
6338 /****************************************************************
6339 ****************************************************************/
6341 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6342 struct samr_RemoveMultipleMembersFromAlias *r)
6344 p->rng_fault_state = true;
6345 return NT_STATUS_NOT_IMPLEMENTED;
6348 /****************************************************************
6349 ****************************************************************/
6351 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6352 struct samr_SetBootKeyInformation *r)
6354 p->rng_fault_state = true;
6355 return NT_STATUS_NOT_IMPLEMENTED;
6358 /****************************************************************
6359 ****************************************************************/
6361 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6362 struct samr_GetBootKeyInformation *r)
6364 p->rng_fault_state = true;
6365 return NT_STATUS_NOT_IMPLEMENTED;
6368 /****************************************************************
6369 ****************************************************************/
6371 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6372 struct samr_SetDsrmPassword *r)
6374 p->rng_fault_state = true;
6375 return NT_STATUS_NOT_IMPLEMENTED;
6378 /****************************************************************
6379 ****************************************************************/
6381 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6382 struct samr_ValidatePassword *r)
6384 p->rng_fault_state = true;
6385 return NT_STATUS_NOT_IMPLEMENTED;