Add extra abilities for a user with SeAddUsers, so they
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_samr_nt.c
blobf1725e2454177c91bcf54cdf509a7954bb721270
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 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
541 SE_PRIV se_rights;
543 /* find the connection policy handle. */
545 cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
546 struct samr_connect_info, &status);
547 if (!NT_STATUS_IS_OK(status)) {
548 return status;
551 /*check if access can be granted as requested by client. */
552 map_max_allowed_access(p->server_info->ptok, &des_access);
554 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
555 se_map_generic( &des_access, &dom_generic_mapping );
558 * Users with SeMachineAccount or SeAddUser get additional
559 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
561 se_priv_copy( &se_rights, &se_machine_account );
562 se_priv_add( &se_rights, &se_add_users );
565 * Users with SeAddUser get the ability to manipulate groups
566 * and aliases.
568 if (user_has_any_privilege(p->server_info->ptok, &se_add_users)) {
569 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
570 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
571 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
572 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
573 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
576 status = access_check_samr_object( psd, p->server_info->ptok,
577 &se_rights, extra_access, des_access,
578 &acc_granted, "_samr_OpenDomain" );
580 if ( !NT_STATUS_IS_OK(status) )
581 return status;
583 if (!sid_check_is_domain(r->in.sid) &&
584 !sid_check_is_builtin(r->in.sid)) {
585 return NT_STATUS_NO_SUCH_DOMAIN;
588 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
589 struct samr_domain_info, &status);
590 if (!NT_STATUS_IS_OK(status)) {
591 return status;
593 dinfo->sid = *r->in.sid;
594 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
596 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
598 return NT_STATUS_OK;
601 /*******************************************************************
602 _samr_GetUserPwInfo
603 ********************************************************************/
605 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
606 struct samr_GetUserPwInfo *r)
608 struct samr_user_info *uinfo;
609 enum lsa_SidType sid_type;
610 uint32_t min_password_length = 0;
611 uint32_t password_properties = 0;
612 bool ret = false;
613 NTSTATUS status;
615 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
617 uinfo = policy_handle_find(p, r->in.user_handle,
618 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
619 struct samr_user_info, &status);
620 if (!NT_STATUS_IS_OK(status)) {
621 return status;
624 if (!sid_check_is_in_our_domain(&uinfo->sid)) {
625 return NT_STATUS_OBJECT_TYPE_MISMATCH;
628 become_root();
629 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
630 unbecome_root();
631 if (ret == false) {
632 return NT_STATUS_NO_SUCH_USER;
635 switch (sid_type) {
636 case SID_NAME_USER:
637 become_root();
638 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
639 &min_password_length);
640 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
641 &password_properties);
642 unbecome_root();
644 if (lp_check_password_script() && *lp_check_password_script()) {
645 password_properties |= DOMAIN_PASSWORD_COMPLEX;
648 break;
649 default:
650 break;
653 r->out.info->min_password_length = min_password_length;
654 r->out.info->password_properties = password_properties;
656 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
658 return NT_STATUS_OK;
661 /*******************************************************************
662 _samr_SetSecurity
663 ********************************************************************/
665 NTSTATUS _samr_SetSecurity(pipes_struct *p,
666 struct samr_SetSecurity *r)
668 struct samr_user_info *uinfo;
669 uint32 i;
670 SEC_ACL *dacl;
671 bool ret;
672 struct samu *sampass=NULL;
673 NTSTATUS status;
675 uinfo = policy_handle_find(p, r->in.handle,
676 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
677 struct samr_user_info, &status);
678 if (!NT_STATUS_IS_OK(status)) {
679 return status;
682 if (!(sampass = samu_new( p->mem_ctx))) {
683 DEBUG(0,("No memory!\n"));
684 return NT_STATUS_NO_MEMORY;
687 /* get the user record */
688 become_root();
689 ret = pdb_getsampwsid(sampass, &uinfo->sid);
690 unbecome_root();
692 if (!ret) {
693 DEBUG(4, ("User %s not found\n",
694 sid_string_dbg(&uinfo->sid)));
695 TALLOC_FREE(sampass);
696 return NT_STATUS_INVALID_HANDLE;
699 dacl = r->in.sdbuf->sd->dacl;
700 for (i=0; i < dacl->num_aces; i++) {
701 if (sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
702 ret = pdb_set_pass_can_change(sampass,
703 (dacl->aces[i].access_mask &
704 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
705 True: False);
706 break;
710 if (!ret) {
711 TALLOC_FREE(sampass);
712 return NT_STATUS_ACCESS_DENIED;
715 become_root();
716 status = pdb_update_sam_account(sampass);
717 unbecome_root();
719 TALLOC_FREE(sampass);
721 return status;
724 /*******************************************************************
725 build correct perms based on policies and password times for _samr_query_sec_obj
726 *******************************************************************/
727 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
729 struct samu *sampass=NULL;
730 bool ret;
732 if ( !(sampass = samu_new( mem_ctx )) ) {
733 DEBUG(0,("No memory!\n"));
734 return False;
737 become_root();
738 ret = pdb_getsampwsid(sampass, user_sid);
739 unbecome_root();
741 if (ret == False) {
742 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
743 TALLOC_FREE(sampass);
744 return False;
747 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
749 if (pdb_get_pass_can_change(sampass)) {
750 TALLOC_FREE(sampass);
751 return True;
753 TALLOC_FREE(sampass);
754 return False;
758 /*******************************************************************
759 _samr_QuerySecurity
760 ********************************************************************/
762 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
763 struct samr_QuerySecurity *r)
765 struct samr_connect_info *cinfo;
766 struct samr_domain_info *dinfo;
767 struct samr_user_info *uinfo;
768 struct samr_group_info *ginfo;
769 struct samr_alias_info *ainfo;
770 NTSTATUS status;
771 SEC_DESC * psd = NULL;
772 size_t sd_size;
774 cinfo = policy_handle_find(p, r->in.handle,
775 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
776 struct samr_connect_info, &status);
777 if (NT_STATUS_IS_OK(status)) {
778 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
779 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
780 &sam_generic_mapping, NULL, 0);
781 goto done;
784 dinfo = policy_handle_find(p, r->in.handle,
785 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
786 struct samr_domain_info, &status);
787 if (NT_STATUS_IS_OK(status)) {
788 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
789 "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
791 * TODO: Builtin probably needs a different SD with restricted
792 * write access
794 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
795 &dom_generic_mapping, NULL, 0);
796 goto done;
799 uinfo = policy_handle_find(p, r->in.handle,
800 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
801 struct samr_user_info, &status);
802 if (NT_STATUS_IS_OK(status)) {
803 DEBUG(10,("_samr_QuerySecurity: querying security on user "
804 "Object with SID: %s\n",
805 sid_string_dbg(&uinfo->sid)));
806 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
807 status = make_samr_object_sd(
808 p->mem_ctx, &psd, &sd_size,
809 &usr_generic_mapping,
810 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
811 } else {
812 status = make_samr_object_sd(
813 p->mem_ctx, &psd, &sd_size,
814 &usr_nopwchange_generic_mapping,
815 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
817 goto done;
820 ginfo = policy_handle_find(p, r->in.handle,
821 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
822 struct samr_group_info, &status);
823 if (NT_STATUS_IS_OK(status)) {
825 * TODO: different SDs have to be generated for aliases groups
826 * and users. Currently all three get a default user SD
828 DEBUG(10,("_samr_QuerySecurity: querying security on group "
829 "Object with SID: %s\n",
830 sid_string_dbg(&ginfo->sid)));
831 status = make_samr_object_sd(
832 p->mem_ctx, &psd, &sd_size,
833 &usr_nopwchange_generic_mapping,
834 &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
835 goto done;
838 ainfo = policy_handle_find(p, r->in.handle,
839 STD_RIGHT_READ_CONTROL_ACCESS, NULL,
840 struct samr_alias_info, &status);
841 if (NT_STATUS_IS_OK(status)) {
843 * TODO: different SDs have to be generated for aliases groups
844 * and users. Currently all three get a default user SD
846 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
847 "Object with SID: %s\n",
848 sid_string_dbg(&ainfo->sid)));
849 status = make_samr_object_sd(
850 p->mem_ctx, &psd, &sd_size,
851 &usr_nopwchange_generic_mapping,
852 &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
853 goto done;
856 return NT_STATUS_OBJECT_TYPE_MISMATCH;
857 done:
858 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
859 return NT_STATUS_NO_MEMORY;
861 return status;
864 /*******************************************************************
865 makes a SAM_ENTRY / UNISTR2* structure from a user list.
866 ********************************************************************/
868 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
869 struct samr_SamEntry **sam_pp,
870 uint32_t num_entries,
871 uint32_t start_idx,
872 struct samr_displayentry *entries)
874 uint32_t i;
875 struct samr_SamEntry *sam;
877 *sam_pp = NULL;
879 if (num_entries == 0) {
880 return NT_STATUS_OK;
883 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
884 if (sam == NULL) {
885 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
886 return NT_STATUS_NO_MEMORY;
889 for (i = 0; i < num_entries; i++) {
890 #if 0
892 * usrmgr expects a non-NULL terminated string with
893 * trust relationships
895 if (entries[i].acct_flags & ACB_DOMTRUST) {
896 init_unistr2(&uni_temp_name, entries[i].account_name,
897 UNI_FLAGS_NONE);
898 } else {
899 init_unistr2(&uni_temp_name, entries[i].account_name,
900 UNI_STR_TERMINATE);
902 #endif
903 init_lsa_String(&sam[i].name, entries[i].account_name);
904 sam[i].idx = entries[i].rid;
907 *sam_pp = sam;
909 return NT_STATUS_OK;
912 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
914 /*******************************************************************
915 _samr_EnumDomainUsers
916 ********************************************************************/
918 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
919 struct samr_EnumDomainUsers *r)
921 NTSTATUS status;
922 struct samr_domain_info *dinfo;
923 int num_account;
924 uint32 enum_context = *r->in.resume_handle;
925 enum remote_arch_types ra_type = get_remote_arch();
926 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
927 uint32 max_entries = max_sam_entries;
928 struct samr_displayentry *entries = NULL;
929 struct samr_SamArray *samr_array = NULL;
930 struct samr_SamEntry *samr_entries = NULL;
932 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
934 dinfo = policy_handle_find(p, r->in.domain_handle,
935 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
936 struct samr_domain_info, &status);
937 if (!NT_STATUS_IS_OK(status)) {
938 return status;
941 if (sid_check_is_builtin(&dinfo->sid)) {
942 /* No users in builtin. */
943 *r->out.resume_handle = *r->in.resume_handle;
944 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
945 return status;
948 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
949 if (!samr_array) {
950 return NT_STATUS_NO_MEMORY;
952 *r->out.sam = samr_array;
954 become_root();
956 /* AS ROOT !!!! */
958 if ((dinfo->disp_info->enum_users != NULL) &&
959 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
960 TALLOC_FREE(dinfo->disp_info->enum_users);
963 if (dinfo->disp_info->enum_users == NULL) {
964 dinfo->disp_info->enum_users = pdb_search_users(
965 dinfo->disp_info, r->in.acct_flags);
966 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
969 if (dinfo->disp_info->enum_users == NULL) {
970 /* END AS ROOT !!!! */
971 unbecome_root();
972 return NT_STATUS_ACCESS_DENIED;
975 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
976 enum_context, max_entries,
977 &entries);
979 /* END AS ROOT !!!! */
981 unbecome_root();
983 if (num_account == 0) {
984 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
985 "total entries\n"));
986 *r->out.resume_handle = *r->in.resume_handle;
987 return NT_STATUS_OK;
990 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
991 num_account, enum_context,
992 entries);
993 if (!NT_STATUS_IS_OK(status)) {
994 return status;
997 if (max_entries <= num_account) {
998 status = STATUS_MORE_ENTRIES;
999 } else {
1000 status = NT_STATUS_OK;
1003 /* Ensure we cache this enumeration. */
1004 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1006 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1008 samr_array->count = num_account;
1009 samr_array->entries = samr_entries;
1011 *r->out.resume_handle = *r->in.resume_handle + num_account;
1012 *r->out.num_entries = num_account;
1014 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1016 return status;
1019 /*******************************************************************
1020 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1021 ********************************************************************/
1023 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1024 struct samr_SamEntry **sam_pp,
1025 uint32_t num_sam_entries,
1026 struct samr_displayentry *entries)
1028 struct samr_SamEntry *sam;
1029 uint32_t i;
1031 *sam_pp = NULL;
1033 if (num_sam_entries == 0) {
1034 return;
1037 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1038 if (sam == NULL) {
1039 return;
1042 for (i = 0; i < num_sam_entries; i++) {
1044 * JRA. I think this should include the null. TNG does not.
1046 init_lsa_String(&sam[i].name, entries[i].account_name);
1047 sam[i].idx = entries[i].rid;
1050 *sam_pp = sam;
1053 /*******************************************************************
1054 _samr_EnumDomainGroups
1055 ********************************************************************/
1057 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1058 struct samr_EnumDomainGroups *r)
1060 NTSTATUS status;
1061 struct samr_domain_info *dinfo;
1062 struct samr_displayentry *groups;
1063 uint32 num_groups;
1064 struct samr_SamArray *samr_array = NULL;
1065 struct samr_SamEntry *samr_entries = NULL;
1067 dinfo = policy_handle_find(p, r->in.domain_handle,
1068 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1069 struct samr_domain_info, &status);
1070 if (!NT_STATUS_IS_OK(status)) {
1071 return status;
1074 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1076 if (sid_check_is_builtin(&dinfo->sid)) {
1077 /* No groups in builtin. */
1078 *r->out.resume_handle = *r->in.resume_handle;
1079 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1080 return status;
1083 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1084 if (!samr_array) {
1085 return NT_STATUS_NO_MEMORY;
1088 /* the domain group array is being allocated in the function below */
1090 become_root();
1092 if (dinfo->disp_info->groups == NULL) {
1093 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1095 if (dinfo->disp_info->groups == NULL) {
1096 unbecome_root();
1097 return NT_STATUS_ACCESS_DENIED;
1101 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1102 *r->in.resume_handle,
1103 MAX_SAM_ENTRIES, &groups);
1104 unbecome_root();
1106 /* Ensure we cache this enumeration. */
1107 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1109 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1110 num_groups, groups);
1112 samr_array->count = num_groups;
1113 samr_array->entries = samr_entries;
1115 *r->out.sam = samr_array;
1116 *r->out.num_entries = num_groups;
1117 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1119 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1121 return status;
1124 /*******************************************************************
1125 _samr_EnumDomainAliases
1126 ********************************************************************/
1128 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1129 struct samr_EnumDomainAliases *r)
1131 NTSTATUS status;
1132 struct samr_domain_info *dinfo;
1133 struct samr_displayentry *aliases;
1134 uint32 num_aliases = 0;
1135 struct samr_SamArray *samr_array = NULL;
1136 struct samr_SamEntry *samr_entries = NULL;
1138 dinfo = policy_handle_find(p, r->in.domain_handle,
1139 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1140 struct samr_domain_info, &status);
1141 if (!NT_STATUS_IS_OK(status)) {
1142 return status;
1145 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1146 sid_string_dbg(&dinfo->sid)));
1148 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1149 if (!samr_array) {
1150 return NT_STATUS_NO_MEMORY;
1153 become_root();
1155 if (dinfo->disp_info->aliases == NULL) {
1156 dinfo->disp_info->aliases = pdb_search_aliases(
1157 dinfo->disp_info, &dinfo->sid);
1158 if (dinfo->disp_info->aliases == NULL) {
1159 unbecome_root();
1160 return NT_STATUS_ACCESS_DENIED;
1164 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1165 *r->in.resume_handle,
1166 MAX_SAM_ENTRIES, &aliases);
1167 unbecome_root();
1169 /* Ensure we cache this enumeration. */
1170 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1172 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1173 num_aliases, aliases);
1175 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1177 samr_array->count = num_aliases;
1178 samr_array->entries = samr_entries;
1180 *r->out.sam = samr_array;
1181 *r->out.num_entries = num_aliases;
1182 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1184 return status;
1187 /*******************************************************************
1188 inits a samr_DispInfoGeneral structure.
1189 ********************************************************************/
1191 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1192 struct samr_DispInfoGeneral *r,
1193 uint32_t num_entries,
1194 uint32_t start_idx,
1195 struct samr_displayentry *entries)
1197 uint32 i;
1199 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1201 if (num_entries == 0) {
1202 return NT_STATUS_OK;
1205 r->count = num_entries;
1207 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1208 if (!r->entries) {
1209 return NT_STATUS_NO_MEMORY;
1212 for (i = 0; i < num_entries ; i++) {
1214 init_lsa_String(&r->entries[i].account_name,
1215 entries[i].account_name);
1217 init_lsa_String(&r->entries[i].description,
1218 entries[i].description);
1220 init_lsa_String(&r->entries[i].full_name,
1221 entries[i].fullname);
1223 r->entries[i].rid = entries[i].rid;
1224 r->entries[i].acct_flags = entries[i].acct_flags;
1225 r->entries[i].idx = start_idx+i+1;
1228 return NT_STATUS_OK;
1231 /*******************************************************************
1232 inits a samr_DispInfoFull structure.
1233 ********************************************************************/
1235 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1236 struct samr_DispInfoFull *r,
1237 uint32_t num_entries,
1238 uint32_t start_idx,
1239 struct samr_displayentry *entries)
1241 uint32_t i;
1243 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1245 if (num_entries == 0) {
1246 return NT_STATUS_OK;
1249 r->count = num_entries;
1251 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1252 if (!r->entries) {
1253 return NT_STATUS_NO_MEMORY;
1256 for (i = 0; i < num_entries ; i++) {
1258 init_lsa_String(&r->entries[i].account_name,
1259 entries[i].account_name);
1261 init_lsa_String(&r->entries[i].description,
1262 entries[i].description);
1264 r->entries[i].rid = entries[i].rid;
1265 r->entries[i].acct_flags = entries[i].acct_flags;
1266 r->entries[i].idx = start_idx+i+1;
1269 return NT_STATUS_OK;
1272 /*******************************************************************
1273 inits a samr_DispInfoFullGroups structure.
1274 ********************************************************************/
1276 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1277 struct samr_DispInfoFullGroups *r,
1278 uint32_t num_entries,
1279 uint32_t start_idx,
1280 struct samr_displayentry *entries)
1282 uint32_t i;
1284 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1286 if (num_entries == 0) {
1287 return NT_STATUS_OK;
1290 r->count = num_entries;
1292 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1293 if (!r->entries) {
1294 return NT_STATUS_NO_MEMORY;
1297 for (i = 0; i < num_entries ; i++) {
1299 init_lsa_String(&r->entries[i].account_name,
1300 entries[i].account_name);
1302 init_lsa_String(&r->entries[i].description,
1303 entries[i].description);
1305 r->entries[i].rid = entries[i].rid;
1306 r->entries[i].acct_flags = entries[i].acct_flags;
1307 r->entries[i].idx = start_idx+i+1;
1310 return NT_STATUS_OK;
1313 /*******************************************************************
1314 inits a samr_DispInfoAscii structure.
1315 ********************************************************************/
1317 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1318 struct samr_DispInfoAscii *r,
1319 uint32_t num_entries,
1320 uint32_t start_idx,
1321 struct samr_displayentry *entries)
1323 uint32_t i;
1325 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1327 if (num_entries == 0) {
1328 return NT_STATUS_OK;
1331 r->count = num_entries;
1333 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1334 if (!r->entries) {
1335 return NT_STATUS_NO_MEMORY;
1338 for (i = 0; i < num_entries ; i++) {
1340 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1341 entries[i].account_name);
1343 r->entries[i].idx = start_idx+i+1;
1346 return NT_STATUS_OK;
1349 /*******************************************************************
1350 inits a samr_DispInfoAscii structure.
1351 ********************************************************************/
1353 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1354 struct samr_DispInfoAscii *r,
1355 uint32_t num_entries,
1356 uint32_t start_idx,
1357 struct samr_displayentry *entries)
1359 uint32_t i;
1361 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1363 if (num_entries == 0) {
1364 return NT_STATUS_OK;
1367 r->count = num_entries;
1369 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1370 if (!r->entries) {
1371 return NT_STATUS_NO_MEMORY;
1374 for (i = 0; i < num_entries ; i++) {
1376 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1377 entries[i].account_name);
1379 r->entries[i].idx = start_idx+i+1;
1382 return NT_STATUS_OK;
1385 /*******************************************************************
1386 _samr_QueryDisplayInfo
1387 ********************************************************************/
1389 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1390 struct samr_QueryDisplayInfo *r)
1392 NTSTATUS status;
1393 struct samr_domain_info *dinfo;
1394 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1396 uint32 max_entries = r->in.max_entries;
1397 uint32 enum_context = r->in.start_idx;
1398 uint32 max_size = r->in.buf_size;
1400 union samr_DispInfo *disp_info = r->out.info;
1402 uint32 temp_size=0, total_data_size=0;
1403 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1404 uint32 num_account = 0;
1405 enum remote_arch_types ra_type = get_remote_arch();
1406 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1407 struct samr_displayentry *entries = NULL;
1409 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1411 dinfo = policy_handle_find(p, r->in.domain_handle,
1412 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1413 struct samr_domain_info, &status);
1414 if (!NT_STATUS_IS_OK(status)) {
1415 return status;
1418 if (sid_check_is_builtin(&dinfo->sid)) {
1419 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1420 return NT_STATUS_OK;
1424 * calculate how many entries we will return.
1425 * based on
1426 * - the number of entries the client asked
1427 * - our limit on that
1428 * - the starting point (enumeration context)
1429 * - the buffer size the client will accept
1433 * We are a lot more like W2K. Instead of reading the SAM
1434 * each time to find the records we need to send back,
1435 * we read it once and link that copy to the sam handle.
1436 * For large user list (over the MAX_SAM_ENTRIES)
1437 * it's a definitive win.
1438 * second point to notice: between enumerations
1439 * our sam is now the same as it's a snapshoot.
1440 * third point: got rid of the static SAM_USER_21 struct
1441 * no more intermediate.
1442 * con: it uses much more memory, as a full copy is stored
1443 * in memory.
1445 * If you want to change it, think twice and think
1446 * of the second point , that's really important.
1448 * JFM, 12/20/2001
1451 if ((r->in.level < 1) || (r->in.level > 5)) {
1452 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1453 (unsigned int)r->in.level ));
1454 return NT_STATUS_INVALID_INFO_CLASS;
1457 /* first limit the number of entries we will return */
1458 if(max_entries > max_sam_entries) {
1459 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1460 "entries, limiting to %d\n", max_entries,
1461 max_sam_entries));
1462 max_entries = max_sam_entries;
1465 /* calculate the size and limit on the number of entries we will
1466 * return */
1468 temp_size=max_entries*struct_size;
1470 if (temp_size>max_size) {
1471 max_entries=MIN((max_size/struct_size),max_entries);;
1472 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1473 "only %d entries\n", max_entries));
1476 become_root();
1478 /* THe following done as ROOT. Don't return without unbecome_root(). */
1480 switch (r->in.level) {
1481 case 1:
1482 case 4:
1483 if (dinfo->disp_info->users == NULL) {
1484 dinfo->disp_info->users = pdb_search_users(
1485 dinfo->disp_info, ACB_NORMAL);
1486 if (dinfo->disp_info->users == NULL) {
1487 unbecome_root();
1488 return NT_STATUS_ACCESS_DENIED;
1490 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1491 (unsigned int)enum_context ));
1492 } else {
1493 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1494 (unsigned int)enum_context ));
1497 num_account = pdb_search_entries(dinfo->disp_info->users,
1498 enum_context, max_entries,
1499 &entries);
1500 break;
1501 case 2:
1502 if (dinfo->disp_info->machines == NULL) {
1503 dinfo->disp_info->machines = pdb_search_users(
1504 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1505 if (dinfo->disp_info->machines == NULL) {
1506 unbecome_root();
1507 return NT_STATUS_ACCESS_DENIED;
1509 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1510 (unsigned int)enum_context ));
1511 } else {
1512 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1513 (unsigned int)enum_context ));
1516 num_account = pdb_search_entries(dinfo->disp_info->machines,
1517 enum_context, max_entries,
1518 &entries);
1519 break;
1520 case 3:
1521 case 5:
1522 if (dinfo->disp_info->groups == NULL) {
1523 dinfo->disp_info->groups = pdb_search_groups(
1524 dinfo->disp_info);
1525 if (dinfo->disp_info->groups == NULL) {
1526 unbecome_root();
1527 return NT_STATUS_ACCESS_DENIED;
1529 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1530 (unsigned int)enum_context ));
1531 } else {
1532 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1533 (unsigned int)enum_context ));
1536 num_account = pdb_search_entries(dinfo->disp_info->groups,
1537 enum_context, max_entries,
1538 &entries);
1539 break;
1540 default:
1541 unbecome_root();
1542 smb_panic("info class changed");
1543 break;
1545 unbecome_root();
1548 /* Now create reply structure */
1549 switch (r->in.level) {
1550 case 1:
1551 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1552 num_account, enum_context,
1553 entries);
1554 break;
1555 case 2:
1556 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1557 num_account, enum_context,
1558 entries);
1559 break;
1560 case 3:
1561 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1562 num_account, enum_context,
1563 entries);
1564 break;
1565 case 4:
1566 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1567 num_account, enum_context,
1568 entries);
1569 break;
1570 case 5:
1571 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1572 num_account, enum_context,
1573 entries);
1574 break;
1575 default:
1576 smb_panic("info class changed");
1577 break;
1580 if (!NT_STATUS_IS_OK(disp_ret))
1581 return disp_ret;
1583 /* calculate the total size */
1584 total_data_size=num_account*struct_size;
1586 if (max_entries <= num_account) {
1587 status = STATUS_MORE_ENTRIES;
1588 } else {
1589 status = NT_STATUS_OK;
1592 /* Ensure we cache this enumeration. */
1593 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1595 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1597 *r->out.total_size = total_data_size;
1598 *r->out.returned_size = temp_size;
1600 return status;
1603 /****************************************************************
1604 _samr_QueryDisplayInfo2
1605 ****************************************************************/
1607 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1608 struct samr_QueryDisplayInfo2 *r)
1610 struct samr_QueryDisplayInfo q;
1612 q.in.domain_handle = r->in.domain_handle;
1613 q.in.level = r->in.level;
1614 q.in.start_idx = r->in.start_idx;
1615 q.in.max_entries = r->in.max_entries;
1616 q.in.buf_size = r->in.buf_size;
1618 q.out.total_size = r->out.total_size;
1619 q.out.returned_size = r->out.returned_size;
1620 q.out.info = r->out.info;
1622 return _samr_QueryDisplayInfo(p, &q);
1625 /****************************************************************
1626 _samr_QueryDisplayInfo3
1627 ****************************************************************/
1629 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1630 struct samr_QueryDisplayInfo3 *r)
1632 struct samr_QueryDisplayInfo q;
1634 q.in.domain_handle = r->in.domain_handle;
1635 q.in.level = r->in.level;
1636 q.in.start_idx = r->in.start_idx;
1637 q.in.max_entries = r->in.max_entries;
1638 q.in.buf_size = r->in.buf_size;
1640 q.out.total_size = r->out.total_size;
1641 q.out.returned_size = r->out.returned_size;
1642 q.out.info = r->out.info;
1644 return _samr_QueryDisplayInfo(p, &q);
1647 /*******************************************************************
1648 _samr_QueryAliasInfo
1649 ********************************************************************/
1651 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1652 struct samr_QueryAliasInfo *r)
1654 struct samr_alias_info *ainfo;
1655 struct acct_info info;
1656 NTSTATUS status;
1657 union samr_AliasInfo *alias_info = NULL;
1658 const char *alias_name = NULL;
1659 const char *alias_description = NULL;
1661 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1663 ainfo = policy_handle_find(p, r->in.alias_handle,
1664 SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1665 struct samr_alias_info, &status);
1666 if (!NT_STATUS_IS_OK(status)) {
1667 return status;
1670 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1671 if (!alias_info) {
1672 return NT_STATUS_NO_MEMORY;
1675 become_root();
1676 status = pdb_get_aliasinfo(&ainfo->sid, &info);
1677 unbecome_root();
1679 if ( !NT_STATUS_IS_OK(status))
1680 return status;
1682 /* FIXME: info contains fstrings */
1683 alias_name = talloc_strdup(r, info.acct_name);
1684 alias_description = talloc_strdup(r, info.acct_desc);
1686 switch (r->in.level) {
1687 case ALIASINFOALL:
1688 alias_info->all.name.string = alias_name;
1689 alias_info->all.num_members = 1; /* ??? */
1690 alias_info->all.description.string = alias_description;
1691 break;
1692 case ALIASINFONAME:
1693 alias_info->name.string = alias_name;
1694 break;
1695 case ALIASINFODESCRIPTION:
1696 alias_info->description.string = alias_description;
1697 break;
1698 default:
1699 return NT_STATUS_INVALID_INFO_CLASS;
1702 *r->out.info = alias_info;
1704 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1706 return NT_STATUS_OK;
1709 /*******************************************************************
1710 _samr_LookupNames
1711 ********************************************************************/
1713 NTSTATUS _samr_LookupNames(pipes_struct *p,
1714 struct samr_LookupNames *r)
1716 struct samr_domain_info *dinfo;
1717 NTSTATUS status;
1718 uint32 *rid;
1719 enum lsa_SidType *type;
1720 int i;
1721 int num_rids = r->in.num_names;
1722 struct samr_Ids rids, types;
1723 uint32_t num_mapped = 0;
1725 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1727 dinfo = policy_handle_find(p, r->in.domain_handle,
1728 0 /* Don't know the acc_bits yet */, NULL,
1729 struct samr_domain_info, &status);
1730 if (!NT_STATUS_IS_OK(status)) {
1731 return status;
1734 if (num_rids > MAX_SAM_ENTRIES) {
1735 num_rids = MAX_SAM_ENTRIES;
1736 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1739 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1740 NT_STATUS_HAVE_NO_MEMORY(rid);
1742 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1743 NT_STATUS_HAVE_NO_MEMORY(type);
1745 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1746 sid_string_dbg(&dinfo->sid)));
1748 for (i = 0; i < num_rids; i++) {
1750 status = NT_STATUS_NONE_MAPPED;
1751 type[i] = SID_NAME_UNKNOWN;
1753 rid[i] = 0xffffffff;
1755 if (sid_check_is_builtin(&dinfo->sid)) {
1756 if (lookup_builtin_name(r->in.names[i].string,
1757 &rid[i]))
1759 type[i] = SID_NAME_ALIAS;
1761 } else {
1762 lookup_global_sam_name(r->in.names[i].string, 0,
1763 &rid[i], &type[i]);
1766 if (type[i] != SID_NAME_UNKNOWN) {
1767 num_mapped++;
1771 if (num_mapped == num_rids) {
1772 status = NT_STATUS_OK;
1773 } else if (num_mapped == 0) {
1774 status = NT_STATUS_NONE_MAPPED;
1775 } else {
1776 status = STATUS_SOME_UNMAPPED;
1779 rids.count = num_rids;
1780 rids.ids = rid;
1782 types.count = num_rids;
1783 types.ids = type;
1785 *r->out.rids = rids;
1786 *r->out.types = types;
1788 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1790 return status;
1793 /****************************************************************
1794 _samr_ChangePasswordUser
1795 ****************************************************************/
1797 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1798 struct samr_ChangePasswordUser *r)
1800 NTSTATUS status;
1801 bool ret = false;
1802 struct samr_user_info *uinfo;
1803 struct samu *pwd;
1804 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1805 struct samr_Password lm_pwd, nt_pwd;
1807 uinfo = policy_handle_find(p, r->in.user_handle,
1808 SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1809 struct samr_user_info, &status);
1810 if (!NT_STATUS_IS_OK(status)) {
1811 return status;
1814 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1815 sid_string_dbg(&uinfo->sid)));
1817 if (!(pwd = samu_new(NULL))) {
1818 return NT_STATUS_NO_MEMORY;
1821 become_root();
1822 ret = pdb_getsampwsid(pwd, &uinfo->sid);
1823 unbecome_root();
1825 if (!ret) {
1826 TALLOC_FREE(pwd);
1827 return NT_STATUS_WRONG_PASSWORD;
1831 const uint8_t *lm_pass, *nt_pass;
1833 lm_pass = pdb_get_lanman_passwd(pwd);
1834 nt_pass = pdb_get_nt_passwd(pwd);
1836 if (!lm_pass || !nt_pass) {
1837 status = NT_STATUS_WRONG_PASSWORD;
1838 goto out;
1841 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1842 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1845 /* basic sanity checking on parameters. Do this before any database ops */
1846 if (!r->in.lm_present || !r->in.nt_present ||
1847 !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1848 !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1849 /* we should really handle a change with lm not
1850 present */
1851 status = NT_STATUS_INVALID_PARAMETER_MIX;
1852 goto out;
1855 /* decrypt and check the new lm hash */
1856 D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1857 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1858 if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1859 status = NT_STATUS_WRONG_PASSWORD;
1860 goto out;
1863 /* decrypt and check the new nt hash */
1864 D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1865 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1866 if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1867 status = NT_STATUS_WRONG_PASSWORD;
1868 goto out;
1871 /* The NT Cross is not required by Win2k3 R2, but if present
1872 check the nt cross hash */
1873 if (r->in.cross1_present && r->in.nt_cross) {
1874 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1875 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1876 status = NT_STATUS_WRONG_PASSWORD;
1877 goto out;
1881 /* The LM Cross is not required by Win2k3 R2, but if present
1882 check the lm cross hash */
1883 if (r->in.cross2_present && r->in.lm_cross) {
1884 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1885 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1886 status = NT_STATUS_WRONG_PASSWORD;
1887 goto out;
1891 if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1892 !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1893 status = NT_STATUS_ACCESS_DENIED;
1894 goto out;
1897 status = pdb_update_sam_account(pwd);
1898 out:
1899 TALLOC_FREE(pwd);
1901 return status;
1904 /*******************************************************************
1905 _samr_ChangePasswordUser2
1906 ********************************************************************/
1908 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1909 struct samr_ChangePasswordUser2 *r)
1911 NTSTATUS status;
1912 fstring user_name;
1913 fstring wks;
1915 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1917 fstrcpy(user_name, r->in.account->string);
1918 fstrcpy(wks, r->in.server->string);
1920 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1923 * Pass the user through the NT -> unix user mapping
1924 * function.
1927 (void)map_username(user_name);
1930 * UNIX username case mangling not required, pass_oem_change
1931 * is case insensitive.
1934 status = pass_oem_change(user_name,
1935 r->in.lm_password->data,
1936 r->in.lm_verifier->hash,
1937 r->in.nt_password->data,
1938 r->in.nt_verifier->hash,
1939 NULL);
1941 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1943 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1944 return NT_STATUS_WRONG_PASSWORD;
1947 return status;
1950 /****************************************************************
1951 _samr_OemChangePasswordUser2
1952 ****************************************************************/
1954 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
1955 struct samr_OemChangePasswordUser2 *r)
1957 NTSTATUS status;
1958 fstring user_name;
1959 const char *wks = NULL;
1961 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1963 fstrcpy(user_name, r->in.account->string);
1964 if (r->in.server && r->in.server->string) {
1965 wks = r->in.server->string;
1968 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1971 * Pass the user through the NT -> unix user mapping
1972 * function.
1975 (void)map_username(user_name);
1978 * UNIX username case mangling not required, pass_oem_change
1979 * is case insensitive.
1982 if (!r->in.hash || !r->in.password) {
1983 return NT_STATUS_INVALID_PARAMETER;
1986 status = pass_oem_change(user_name,
1987 r->in.password->data,
1988 r->in.hash->hash,
1991 NULL);
1993 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1994 return NT_STATUS_WRONG_PASSWORD;
1997 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1999 return status;
2002 /*******************************************************************
2003 _samr_ChangePasswordUser3
2004 ********************************************************************/
2006 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
2007 struct samr_ChangePasswordUser3 *r)
2009 NTSTATUS status;
2010 fstring user_name;
2011 const char *wks = NULL;
2012 uint32 reject_reason;
2013 struct samr_DomInfo1 *dominfo = NULL;
2014 struct samr_ChangeReject *reject = NULL;
2015 uint32_t tmp;
2017 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2019 fstrcpy(user_name, r->in.account->string);
2020 if (r->in.server && r->in.server->string) {
2021 wks = r->in.server->string;
2024 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2027 * Pass the user through the NT -> unix user mapping
2028 * function.
2031 (void)map_username(user_name);
2034 * UNIX username case mangling not required, pass_oem_change
2035 * is case insensitive.
2038 status = pass_oem_change(user_name,
2039 r->in.lm_password->data,
2040 r->in.lm_verifier->hash,
2041 r->in.nt_password->data,
2042 r->in.nt_verifier->hash,
2043 &reject_reason);
2044 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2045 return NT_STATUS_WRONG_PASSWORD;
2048 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2049 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2051 time_t u_expire, u_min_age;
2052 uint32 account_policy_temp;
2054 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2055 if (!dominfo) {
2056 return NT_STATUS_NO_MEMORY;
2059 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2060 if (!reject) {
2061 return NT_STATUS_NO_MEMORY;
2064 become_root();
2066 /* AS ROOT !!! */
2068 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
2069 dominfo->min_password_length = tmp;
2071 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
2072 dominfo->password_history_length = tmp;
2074 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2075 &dominfo->password_properties);
2077 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2078 u_expire = account_policy_temp;
2080 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2081 u_min_age = account_policy_temp;
2083 /* !AS ROOT */
2085 unbecome_root();
2087 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2088 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2090 if (lp_check_password_script() && *lp_check_password_script()) {
2091 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2094 reject->reason = reject_reason;
2096 *r->out.dominfo = dominfo;
2097 *r->out.reject = reject;
2100 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2102 return status;
2105 /*******************************************************************
2106 makes a SAMR_R_LOOKUP_RIDS structure.
2107 ********************************************************************/
2109 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2110 const char **names,
2111 struct lsa_String **lsa_name_array_p)
2113 struct lsa_String *lsa_name_array = NULL;
2114 uint32_t i;
2116 *lsa_name_array_p = NULL;
2118 if (num_names != 0) {
2119 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2120 if (!lsa_name_array) {
2121 return false;
2125 for (i = 0; i < num_names; i++) {
2126 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2127 init_lsa_String(&lsa_name_array[i], names[i]);
2130 *lsa_name_array_p = lsa_name_array;
2132 return true;
2135 /*******************************************************************
2136 _samr_LookupRids
2137 ********************************************************************/
2139 NTSTATUS _samr_LookupRids(pipes_struct *p,
2140 struct samr_LookupRids *r)
2142 struct samr_domain_info *dinfo;
2143 NTSTATUS status;
2144 const char **names;
2145 enum lsa_SidType *attrs = NULL;
2146 uint32 *wire_attrs = NULL;
2147 int num_rids = (int)r->in.num_rids;
2148 int i;
2149 struct lsa_Strings names_array;
2150 struct samr_Ids types_array;
2151 struct lsa_String *lsa_names = NULL;
2153 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2155 dinfo = policy_handle_find(p, r->in.domain_handle,
2156 0 /* Don't know the acc_bits yet */, NULL,
2157 struct samr_domain_info, &status);
2158 if (!NT_STATUS_IS_OK(status)) {
2159 return status;
2162 if (num_rids > 1000) {
2163 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2164 "to samba4 idl this is not possible\n", num_rids));
2165 return NT_STATUS_UNSUCCESSFUL;
2168 if (num_rids) {
2169 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2170 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2171 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2173 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2174 return NT_STATUS_NO_MEMORY;
2175 } else {
2176 names = NULL;
2177 attrs = NULL;
2178 wire_attrs = NULL;
2181 become_root(); /* lookup_sid can require root privs */
2182 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2183 names, attrs);
2184 unbecome_root();
2186 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2187 status = NT_STATUS_OK;
2190 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2191 &lsa_names)) {
2192 return NT_STATUS_NO_MEMORY;
2195 /* Convert from enum lsa_SidType to uint32 for wire format. */
2196 for (i = 0; i < num_rids; i++) {
2197 wire_attrs[i] = (uint32)attrs[i];
2200 names_array.count = num_rids;
2201 names_array.names = lsa_names;
2203 types_array.count = num_rids;
2204 types_array.ids = wire_attrs;
2206 *r->out.names = names_array;
2207 *r->out.types = types_array;
2209 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2211 return status;
2214 /*******************************************************************
2215 _samr_OpenUser
2216 ********************************************************************/
2218 NTSTATUS _samr_OpenUser(pipes_struct *p,
2219 struct samr_OpenUser *r)
2221 struct samu *sampass=NULL;
2222 DOM_SID sid;
2223 struct samr_domain_info *dinfo;
2224 struct samr_user_info *uinfo;
2225 SEC_DESC *psd = NULL;
2226 uint32 acc_granted;
2227 uint32 des_access = r->in.access_mask;
2228 uint32_t extra_access = 0;
2229 size_t sd_size;
2230 bool ret;
2231 NTSTATUS nt_status;
2232 SE_PRIV se_rights;
2233 NTSTATUS status;
2235 dinfo = policy_handle_find(p, r->in.domain_handle,
2236 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2237 struct samr_domain_info, &status);
2238 if (!NT_STATUS_IS_OK(status)) {
2239 return status;
2242 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2243 return NT_STATUS_NO_MEMORY;
2246 /* append the user's RID to it */
2248 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2249 return NT_STATUS_NO_SUCH_USER;
2251 /* check if access can be granted as requested by client. */
2253 map_max_allowed_access(p->server_info->ptok, &des_access);
2255 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2256 se_map_generic(&des_access, &usr_generic_mapping);
2259 * Get the sampass first as we need to check privilages
2260 * based on what kind of user object this is.
2261 * But don't reveal info too early if it didn't exist.
2264 become_root();
2265 ret=pdb_getsampwsid(sampass, &sid);
2266 unbecome_root();
2268 se_priv_copy(&se_rights, &se_priv_none);
2271 * We do the override access checks on *open*, not at
2272 * SetUserInfo time.
2274 if (ret) {
2275 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2277 if ((acb_info & ACB_WSTRUST) &&
2278 user_has_any_privilege(p->server_info->ptok,
2279 &se_machine_account)) {
2281 * SeMachineAccount is needed to add
2282 * GENERIC_RIGHTS_USER_WRITE to a machine
2283 * account.
2285 se_priv_add(&se_rights, &se_machine_account);
2286 DEBUG(10,("_samr_OpenUser: adding machine account "
2287 "rights to handle for user %s\n",
2288 pdb_get_username(sampass) ));
2290 if ((acb_info & ACB_NORMAL) &&
2291 user_has_any_privilege(p->server_info->ptok,
2292 &se_add_users)) {
2294 * SeAddUsers is needed to add
2295 * GENERIC_RIGHTS_USER_WRITE to a normal
2296 * account.
2298 se_priv_add(&se_rights, &se_add_users);
2299 DEBUG(10,("_samr_OpenUser: adding add user "
2300 "rights to handle for user %s\n",
2301 pdb_get_username(sampass) ));
2304 * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
2305 * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not
2306 * what Windows does but is a hack for people who haven't
2307 * set up privilages on groups in Samba.
2309 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2310 if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2311 DOMAIN_GROUP_RID_ADMINS)) {
2312 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2313 extra_access = GENERIC_RIGHTS_USER_WRITE;
2314 DEBUG(4,("_samr_OpenUser: Allowing "
2315 "GENERIC_RIGHTS_USER_WRITE for "
2316 "rid admins\n"));
2321 TALLOC_FREE(sampass);
2323 nt_status = access_check_samr_object(psd, p->server_info->ptok,
2324 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2325 &acc_granted, "_samr_OpenUser");
2327 if ( !NT_STATUS_IS_OK(nt_status) )
2328 return nt_status;
2330 /* check that the SID exists in our domain. */
2331 if (ret == False) {
2332 return NT_STATUS_NO_SUCH_USER;
2335 /* If we did the rid admins hack above, allow access. */
2336 acc_granted |= extra_access;
2338 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2339 struct samr_user_info, &nt_status);
2340 if (!NT_STATUS_IS_OK(nt_status)) {
2341 return nt_status;
2343 uinfo->sid = sid;
2345 return NT_STATUS_OK;
2348 /*************************************************************************
2349 *************************************************************************/
2351 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2352 DATA_BLOB *blob,
2353 struct lsa_BinaryString **_r)
2355 struct lsa_BinaryString *r;
2357 if (!blob || !_r) {
2358 return NT_STATUS_INVALID_PARAMETER;
2361 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2362 if (!r) {
2363 return NT_STATUS_NO_MEMORY;
2366 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2367 if (!r->array) {
2368 return NT_STATUS_NO_MEMORY;
2370 memcpy(r->array, blob->data, blob->length);
2371 r->size = blob->length;
2372 r->length = blob->length;
2374 if (!r->array) {
2375 return NT_STATUS_NO_MEMORY;
2378 *_r = r;
2380 return NT_STATUS_OK;
2383 /*************************************************************************
2384 get_user_info_1.
2385 *************************************************************************/
2387 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2388 struct samr_UserInfo1 *r,
2389 struct samu *pw,
2390 DOM_SID *domain_sid)
2392 const DOM_SID *sid_group;
2393 uint32_t primary_gid;
2395 become_root();
2396 sid_group = pdb_get_group_sid(pw);
2397 unbecome_root();
2399 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2400 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2401 "which conflicts with the domain sid %s. Failing operation.\n",
2402 pdb_get_username(pw), sid_string_dbg(sid_group),
2403 sid_string_dbg(domain_sid)));
2404 return NT_STATUS_UNSUCCESSFUL;
2407 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2408 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2409 r->primary_gid = primary_gid;
2410 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2411 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2413 return NT_STATUS_OK;
2416 /*************************************************************************
2417 get_user_info_2.
2418 *************************************************************************/
2420 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2421 struct samr_UserInfo2 *r,
2422 struct samu *pw)
2424 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2425 r->unknown.string = NULL;
2426 r->country_code = 0;
2427 r->code_page = 0;
2429 return NT_STATUS_OK;
2432 /*************************************************************************
2433 get_user_info_3.
2434 *************************************************************************/
2436 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2437 struct samr_UserInfo3 *r,
2438 struct samu *pw,
2439 DOM_SID *domain_sid)
2441 const DOM_SID *sid_user, *sid_group;
2442 uint32_t rid, primary_gid;
2444 sid_user = pdb_get_user_sid(pw);
2446 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2447 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2448 "the domain sid %s. Failing operation.\n",
2449 pdb_get_username(pw), sid_string_dbg(sid_user),
2450 sid_string_dbg(domain_sid)));
2451 return NT_STATUS_UNSUCCESSFUL;
2454 become_root();
2455 sid_group = pdb_get_group_sid(pw);
2456 unbecome_root();
2458 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2459 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2460 "which conflicts with the domain sid %s. Failing operation.\n",
2461 pdb_get_username(pw), sid_string_dbg(sid_group),
2462 sid_string_dbg(domain_sid)));
2463 return NT_STATUS_UNSUCCESSFUL;
2466 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2467 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2468 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2469 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2470 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2472 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2473 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2474 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2475 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2476 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2477 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2478 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2480 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2481 r->rid = rid;
2482 r->primary_gid = primary_gid;
2483 r->acct_flags = pdb_get_acct_ctrl(pw);
2484 r->bad_password_count = pdb_get_bad_password_count(pw);
2485 r->logon_count = pdb_get_logon_count(pw);
2487 return NT_STATUS_OK;
2490 /*************************************************************************
2491 get_user_info_4.
2492 *************************************************************************/
2494 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2495 struct samr_UserInfo4 *r,
2496 struct samu *pw)
2498 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2500 return NT_STATUS_OK;
2503 /*************************************************************************
2504 get_user_info_5.
2505 *************************************************************************/
2507 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2508 struct samr_UserInfo5 *r,
2509 struct samu *pw,
2510 DOM_SID *domain_sid)
2512 const DOM_SID *sid_user, *sid_group;
2513 uint32_t rid, primary_gid;
2515 sid_user = pdb_get_user_sid(pw);
2517 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2518 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2519 "the domain sid %s. Failing operation.\n",
2520 pdb_get_username(pw), sid_string_dbg(sid_user),
2521 sid_string_dbg(domain_sid)));
2522 return NT_STATUS_UNSUCCESSFUL;
2525 become_root();
2526 sid_group = pdb_get_group_sid(pw);
2527 unbecome_root();
2529 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2530 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2531 "which conflicts with the domain sid %s. Failing operation.\n",
2532 pdb_get_username(pw), sid_string_dbg(sid_group),
2533 sid_string_dbg(domain_sid)));
2534 return NT_STATUS_UNSUCCESSFUL;
2537 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2538 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2539 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2540 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2542 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2543 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2544 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2545 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2546 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2547 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2548 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2549 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2551 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2552 r->rid = rid;
2553 r->primary_gid = primary_gid;
2554 r->acct_flags = pdb_get_acct_ctrl(pw);
2555 r->bad_password_count = pdb_get_bad_password_count(pw);
2556 r->logon_count = pdb_get_logon_count(pw);
2558 return NT_STATUS_OK;
2561 /*************************************************************************
2562 get_user_info_6.
2563 *************************************************************************/
2565 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2566 struct samr_UserInfo6 *r,
2567 struct samu *pw)
2569 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2570 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2572 return NT_STATUS_OK;
2575 /*************************************************************************
2576 get_user_info_7. Safe. Only gives out account_name.
2577 *************************************************************************/
2579 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2580 struct samr_UserInfo7 *r,
2581 struct samu *smbpass)
2583 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2584 if (!r->account_name.string) {
2585 return NT_STATUS_NO_MEMORY;
2588 return NT_STATUS_OK;
2591 /*************************************************************************
2592 get_user_info_8.
2593 *************************************************************************/
2595 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2596 struct samr_UserInfo8 *r,
2597 struct samu *pw)
2599 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2601 return NT_STATUS_OK;
2604 /*************************************************************************
2605 get_user_info_9. Only gives out primary group SID.
2606 *************************************************************************/
2608 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2609 struct samr_UserInfo9 *r,
2610 struct samu *smbpass)
2612 r->primary_gid = pdb_get_group_rid(smbpass);
2614 return NT_STATUS_OK;
2617 /*************************************************************************
2618 get_user_info_10.
2619 *************************************************************************/
2621 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2622 struct samr_UserInfo10 *r,
2623 struct samu *pw)
2625 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2626 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2628 return NT_STATUS_OK;
2631 /*************************************************************************
2632 get_user_info_11.
2633 *************************************************************************/
2635 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2636 struct samr_UserInfo11 *r,
2637 struct samu *pw)
2639 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2641 return NT_STATUS_OK;
2644 /*************************************************************************
2645 get_user_info_12.
2646 *************************************************************************/
2648 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2649 struct samr_UserInfo12 *r,
2650 struct samu *pw)
2652 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2654 return NT_STATUS_OK;
2657 /*************************************************************************
2658 get_user_info_13.
2659 *************************************************************************/
2661 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2662 struct samr_UserInfo13 *r,
2663 struct samu *pw)
2665 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2667 return NT_STATUS_OK;
2670 /*************************************************************************
2671 get_user_info_14.
2672 *************************************************************************/
2674 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2675 struct samr_UserInfo14 *r,
2676 struct samu *pw)
2678 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2680 return NT_STATUS_OK;
2683 /*************************************************************************
2684 get_user_info_16. Safe. Only gives out acb bits.
2685 *************************************************************************/
2687 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2688 struct samr_UserInfo16 *r,
2689 struct samu *smbpass)
2691 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2693 return NT_STATUS_OK;
2696 /*************************************************************************
2697 get_user_info_17.
2698 *************************************************************************/
2700 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2701 struct samr_UserInfo17 *r,
2702 struct samu *pw)
2704 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2706 return NT_STATUS_OK;
2709 /*************************************************************************
2710 get_user_info_18. OK - this is the killer as it gives out password info.
2711 Ensure that this is only allowed on an encrypted connection with a root
2712 user. JRA.
2713 *************************************************************************/
2715 static NTSTATUS get_user_info_18(pipes_struct *p,
2716 TALLOC_CTX *mem_ctx,
2717 struct samr_UserInfo18 *r,
2718 DOM_SID *user_sid)
2720 struct samu *smbpass=NULL;
2721 bool ret;
2723 ZERO_STRUCTP(r);
2725 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2726 return NT_STATUS_ACCESS_DENIED;
2729 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2730 return NT_STATUS_ACCESS_DENIED;
2734 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2737 if ( !(smbpass = samu_new( mem_ctx )) ) {
2738 return NT_STATUS_NO_MEMORY;
2741 ret = pdb_getsampwsid(smbpass, user_sid);
2743 if (ret == False) {
2744 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2745 TALLOC_FREE(smbpass);
2746 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2749 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2751 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2752 TALLOC_FREE(smbpass);
2753 return NT_STATUS_ACCOUNT_DISABLED;
2756 r->lm_pwd_active = true;
2757 r->nt_pwd_active = true;
2758 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2759 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2760 r->password_expired = 0; /* FIXME */
2762 TALLOC_FREE(smbpass);
2764 return NT_STATUS_OK;
2767 /*************************************************************************
2768 get_user_info_20
2769 *************************************************************************/
2771 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2772 struct samr_UserInfo20 *r,
2773 struct samu *sampass)
2775 const char *munged_dial = NULL;
2776 DATA_BLOB blob;
2777 NTSTATUS status;
2778 struct lsa_BinaryString *parameters = NULL;
2780 ZERO_STRUCTP(r);
2782 munged_dial = pdb_get_munged_dial(sampass);
2784 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2785 munged_dial, (int)strlen(munged_dial)));
2787 if (munged_dial) {
2788 blob = base64_decode_data_blob(munged_dial);
2789 } else {
2790 blob = data_blob_string_const_null("");
2793 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2794 data_blob_free(&blob);
2795 if (!NT_STATUS_IS_OK(status)) {
2796 return status;
2799 r->parameters = *parameters;
2801 return NT_STATUS_OK;
2805 /*************************************************************************
2806 get_user_info_21
2807 *************************************************************************/
2809 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2810 struct samr_UserInfo21 *r,
2811 struct samu *pw,
2812 DOM_SID *domain_sid,
2813 uint32_t acc_granted)
2815 NTSTATUS status;
2816 const DOM_SID *sid_user, *sid_group;
2817 uint32_t rid, primary_gid;
2818 NTTIME force_password_change;
2819 time_t must_change_time;
2820 struct lsa_BinaryString *parameters = NULL;
2821 const char *munged_dial = NULL;
2822 DATA_BLOB blob;
2824 ZERO_STRUCTP(r);
2826 sid_user = pdb_get_user_sid(pw);
2828 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2829 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2830 "the domain sid %s. Failing operation.\n",
2831 pdb_get_username(pw), sid_string_dbg(sid_user),
2832 sid_string_dbg(domain_sid)));
2833 return NT_STATUS_UNSUCCESSFUL;
2836 become_root();
2837 sid_group = pdb_get_group_sid(pw);
2838 unbecome_root();
2840 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2841 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2842 "which conflicts with the domain sid %s. Failing operation.\n",
2843 pdb_get_username(pw), sid_string_dbg(sid_group),
2844 sid_string_dbg(domain_sid)));
2845 return NT_STATUS_UNSUCCESSFUL;
2848 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2849 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2850 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2851 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2852 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2854 must_change_time = pdb_get_pass_must_change_time(pw);
2855 if (must_change_time == get_time_t_max()) {
2856 unix_to_nt_time_abs(&force_password_change, must_change_time);
2857 } else {
2858 unix_to_nt_time(&force_password_change, must_change_time);
2861 munged_dial = pdb_get_munged_dial(pw);
2862 if (munged_dial) {
2863 blob = base64_decode_data_blob(munged_dial);
2864 } else {
2865 blob = data_blob_string_const_null("");
2868 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2869 data_blob_free(&blob);
2870 if (!NT_STATUS_IS_OK(status)) {
2871 return status;
2874 r->force_password_change = force_password_change;
2876 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2877 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2878 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2879 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2880 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2881 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2882 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2883 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2884 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2886 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2887 r->parameters = *parameters;
2888 r->rid = rid;
2889 r->primary_gid = primary_gid;
2890 r->acct_flags = pdb_get_acct_ctrl(pw);
2891 r->bad_password_count = pdb_get_bad_password_count(pw);
2892 r->logon_count = pdb_get_logon_count(pw);
2893 r->fields_present = pdb_build_fields_present(pw);
2894 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2895 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2896 r->country_code = 0;
2897 r->code_page = 0;
2898 r->lm_password_set = 0;
2899 r->nt_password_set = 0;
2901 #if 0
2904 Look at a user on a real NT4 PDC with usrmgr, press
2905 'ok'. Then you will see that fields_present is set to
2906 0x08f827fa. Look at the user immediately after that again,
2907 and you will see that 0x00fffff is returned. This solves
2908 the problem that you get access denied after having looked
2909 at the user.
2910 -- Volker
2913 #endif
2916 return NT_STATUS_OK;
2919 /*******************************************************************
2920 _samr_QueryUserInfo
2921 ********************************************************************/
2923 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2924 struct samr_QueryUserInfo *r)
2926 NTSTATUS status;
2927 union samr_UserInfo *user_info = NULL;
2928 struct samr_user_info *uinfo;
2929 DOM_SID domain_sid;
2930 uint32 rid;
2931 bool ret = false;
2932 struct samu *pwd = NULL;
2933 uint32_t acc_required, acc_granted;
2935 switch (r->in.level) {
2936 case 1: /* UserGeneralInformation */
2937 /* USER_READ_GENERAL */
2938 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2939 break;
2940 case 2: /* UserPreferencesInformation */
2941 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2942 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2943 SAMR_USER_ACCESS_GET_NAME_ETC;
2944 break;
2945 case 3: /* UserLogonInformation */
2946 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2947 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2948 SAMR_USER_ACCESS_GET_LOCALE |
2949 SAMR_USER_ACCESS_GET_LOGONINFO |
2950 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2951 break;
2952 case 4: /* UserLogonHoursInformation */
2953 /* USER_READ_LOGON */
2954 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2955 break;
2956 case 5: /* UserAccountInformation */
2957 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2958 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2959 SAMR_USER_ACCESS_GET_LOCALE |
2960 SAMR_USER_ACCESS_GET_LOGONINFO |
2961 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2962 break;
2963 case 6: /* UserNameInformation */
2964 case 7: /* UserAccountNameInformation */
2965 case 8: /* UserFullNameInformation */
2966 case 9: /* UserPrimaryGroupInformation */
2967 case 13: /* UserAdminCommentInformation */
2968 /* USER_READ_GENERAL */
2969 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2970 break;
2971 case 10: /* UserHomeInformation */
2972 case 11: /* UserScriptInformation */
2973 case 12: /* UserProfileInformation */
2974 case 14: /* UserWorkStationsInformation */
2975 /* USER_READ_LOGON */
2976 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2977 break;
2978 case 16: /* UserControlInformation */
2979 case 17: /* UserExpiresInformation */
2980 case 20: /* UserParametersInformation */
2981 /* USER_READ_ACCOUNT */
2982 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2983 break;
2984 case 21: /* UserAllInformation */
2985 /* FIXME! - gd */
2986 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2987 break;
2988 case 18: /* UserInternal1Information */
2989 /* FIXME! - gd */
2990 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2991 break;
2992 case 23: /* UserInternal4Information */
2993 case 24: /* UserInternal4InformationNew */
2994 case 25: /* UserInternal4InformationNew */
2995 case 26: /* UserInternal5InformationNew */
2996 default:
2997 return NT_STATUS_INVALID_INFO_CLASS;
2998 break;
3001 uinfo = policy_handle_find(p, r->in.user_handle,
3002 acc_required, &acc_granted,
3003 struct samr_user_info, &status);
3004 if (!NT_STATUS_IS_OK(status)) {
3005 return status;
3008 domain_sid = uinfo->sid;
3010 sid_split_rid(&domain_sid, &rid);
3012 if (!sid_check_is_in_our_domain(&uinfo->sid))
3013 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3015 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3016 sid_string_dbg(&uinfo->sid)));
3018 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3019 if (!user_info) {
3020 return NT_STATUS_NO_MEMORY;
3023 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3025 if (!(pwd = samu_new(p->mem_ctx))) {
3026 return NT_STATUS_NO_MEMORY;
3029 become_root();
3030 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3031 unbecome_root();
3033 if (ret == false) {
3034 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3035 TALLOC_FREE(pwd);
3036 return NT_STATUS_NO_SUCH_USER;
3039 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3041 samr_clear_sam_passwd(pwd);
3043 switch (r->in.level) {
3044 case 1:
3045 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3046 break;
3047 case 2:
3048 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3049 break;
3050 case 3:
3051 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3052 break;
3053 case 4:
3054 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3055 break;
3056 case 5:
3057 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3058 break;
3059 case 6:
3060 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3061 break;
3062 case 7:
3063 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3064 break;
3065 case 8:
3066 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3067 break;
3068 case 9:
3069 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3070 break;
3071 case 10:
3072 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3073 break;
3074 case 11:
3075 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3076 break;
3077 case 12:
3078 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3079 break;
3080 case 13:
3081 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3082 break;
3083 case 14:
3084 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3085 break;
3086 case 16:
3087 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3088 break;
3089 case 17:
3090 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3091 break;
3092 case 18:
3093 /* level 18 is special */
3094 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3095 &uinfo->sid);
3096 break;
3097 case 20:
3098 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3099 break;
3100 case 21:
3101 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3102 break;
3103 default:
3104 status = NT_STATUS_INVALID_INFO_CLASS;
3105 break;
3108 if (!NT_STATUS_IS_OK(status)) {
3109 goto done;
3112 *r->out.info = user_info;
3114 done:
3115 TALLOC_FREE(pwd);
3117 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3119 return status;
3122 /****************************************************************
3123 ****************************************************************/
3125 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3126 struct samr_QueryUserInfo2 *r)
3128 struct samr_QueryUserInfo u;
3130 u.in.user_handle = r->in.user_handle;
3131 u.in.level = r->in.level;
3132 u.out.info = r->out.info;
3134 return _samr_QueryUserInfo(p, &u);
3137 /*******************************************************************
3138 _samr_GetGroupsForUser
3139 ********************************************************************/
3141 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3142 struct samr_GetGroupsForUser *r)
3144 struct samr_user_info *uinfo;
3145 struct samu *sam_pass=NULL;
3146 DOM_SID *sids;
3147 struct samr_RidWithAttribute dom_gid;
3148 struct samr_RidWithAttribute *gids = NULL;
3149 uint32 primary_group_rid;
3150 size_t num_groups = 0;
3151 gid_t *unix_gids;
3152 size_t i, num_gids;
3153 bool ret;
3154 NTSTATUS result;
3155 bool success = False;
3157 struct samr_RidWithAttributeArray *rids = NULL;
3160 * from the SID in the request:
3161 * we should send back the list of DOMAIN GROUPS
3162 * the user is a member of
3164 * and only the DOMAIN GROUPS
3165 * no ALIASES !!! neither aliases of the domain
3166 * nor aliases of the builtin SID
3168 * JFM, 12/2/2001
3171 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3173 uinfo = policy_handle_find(p, r->in.user_handle,
3174 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3175 struct samr_user_info, &result);
3176 if (!NT_STATUS_IS_OK(result)) {
3177 return result;
3180 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3181 if (!rids) {
3182 return NT_STATUS_NO_MEMORY;
3185 if (!sid_check_is_in_our_domain(&uinfo->sid))
3186 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3188 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3189 return NT_STATUS_NO_MEMORY;
3192 become_root();
3193 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3194 unbecome_root();
3196 if (!ret) {
3197 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3198 sid_string_dbg(&uinfo->sid)));
3199 return NT_STATUS_NO_SUCH_USER;
3202 sids = NULL;
3204 /* make both calls inside the root block */
3205 become_root();
3206 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3207 &sids, &unix_gids, &num_groups);
3208 if ( NT_STATUS_IS_OK(result) ) {
3209 success = sid_peek_check_rid(get_global_sam_sid(),
3210 pdb_get_group_sid(sam_pass),
3211 &primary_group_rid);
3213 unbecome_root();
3215 if (!NT_STATUS_IS_OK(result)) {
3216 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3217 sid_string_dbg(&uinfo->sid)));
3218 return result;
3221 if ( !success ) {
3222 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3223 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3224 pdb_get_username(sam_pass)));
3225 TALLOC_FREE(sam_pass);
3226 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3229 gids = NULL;
3230 num_gids = 0;
3232 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3233 SE_GROUP_ENABLED);
3234 dom_gid.rid = primary_group_rid;
3235 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3237 for (i=0; i<num_groups; i++) {
3239 if (!sid_peek_check_rid(get_global_sam_sid(),
3240 &(sids[i]), &dom_gid.rid)) {
3241 DEBUG(10, ("Found sid %s not in our domain\n",
3242 sid_string_dbg(&sids[i])));
3243 continue;
3246 if (dom_gid.rid == primary_group_rid) {
3247 /* We added the primary group directly from the
3248 * sam_account. The other SIDs are unique from
3249 * enum_group_memberships */
3250 continue;
3253 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3256 rids->count = num_gids;
3257 rids->rids = gids;
3259 *r->out.rids = rids;
3261 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3263 return result;
3266 /*******************************************************************
3267 _samr_QueryDomainInfo
3268 ********************************************************************/
3270 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3271 struct samr_QueryDomainInfo *r)
3273 NTSTATUS status = NT_STATUS_OK;
3274 struct samr_domain_info *dinfo;
3275 union samr_DomainInfo *dom_info;
3276 time_t u_expire, u_min_age;
3278 time_t u_lock_duration, u_reset_time;
3279 uint32_t u_logout;
3281 uint32 account_policy_temp;
3283 time_t seq_num;
3284 uint32 server_role;
3285 uint32_t acc_required;
3287 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3289 switch (r->in.level) {
3290 case 1: /* DomainPasswordInformation */
3291 case 12: /* DomainLockoutInformation */
3292 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3293 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3294 break;
3295 case 11: /* DomainGeneralInformation2 */
3296 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3297 * DOMAIN_READ_OTHER_PARAMETERS */
3298 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3299 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3300 break;
3301 case 2: /* DomainGeneralInformation */
3302 case 3: /* DomainLogoffInformation */
3303 case 4: /* DomainOemInformation */
3304 case 5: /* DomainReplicationInformation */
3305 case 6: /* DomainReplicationInformation */
3306 case 7: /* DomainServerRoleInformation */
3307 case 8: /* DomainModifiedInformation */
3308 case 9: /* DomainStateInformation */
3309 case 10: /* DomainUasInformation */
3310 case 13: /* DomainModifiedInformation2 */
3311 /* DOMAIN_READ_OTHER_PARAMETERS */
3312 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3313 break;
3314 default:
3315 return NT_STATUS_INVALID_INFO_CLASS;
3318 dinfo = policy_handle_find(p, r->in.domain_handle,
3319 acc_required, NULL,
3320 struct samr_domain_info, &status);
3321 if (!NT_STATUS_IS_OK(status)) {
3322 return status;
3325 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3326 if (!dom_info) {
3327 return NT_STATUS_NO_MEMORY;
3330 switch (r->in.level) {
3331 case 1:
3333 become_root();
3335 /* AS ROOT !!! */
3337 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
3338 &account_policy_temp);
3339 dom_info->info1.min_password_length = account_policy_temp;
3341 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
3342 dom_info->info1.password_history_length = account_policy_temp;
3344 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
3345 &dom_info->info1.password_properties);
3347 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
3348 u_expire = account_policy_temp;
3350 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
3351 u_min_age = account_policy_temp;
3353 /* !AS ROOT */
3355 unbecome_root();
3357 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
3358 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
3360 if (lp_check_password_script() && *lp_check_password_script()) {
3361 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
3364 break;
3365 case 2:
3367 become_root();
3369 /* AS ROOT !!! */
3371 dom_info->general.num_users = count_sam_users(
3372 dinfo->disp_info, ACB_NORMAL);
3373 dom_info->general.num_groups = count_sam_groups(
3374 dinfo->disp_info);
3375 dom_info->general.num_aliases = count_sam_aliases(
3376 dinfo->disp_info);
3378 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3380 unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
3382 if (!pdb_get_seq_num(&seq_num))
3383 seq_num = time(NULL);
3385 /* !AS ROOT */
3387 unbecome_root();
3389 server_role = ROLE_DOMAIN_PDC;
3390 if (lp_server_role() == ROLE_DOMAIN_BDC)
3391 server_role = ROLE_DOMAIN_BDC;
3393 dom_info->general.oem_information.string = lp_serverstring();
3394 dom_info->general.domain_name.string = lp_workgroup();
3395 dom_info->general.primary.string = global_myname();
3396 dom_info->general.sequence_num = seq_num;
3397 dom_info->general.domain_server_state = DOMAIN_SERVER_ENABLED;
3398 dom_info->general.role = server_role;
3399 dom_info->general.unknown3 = 1;
3401 break;
3402 case 3:
3404 become_root();
3406 /* AS ROOT !!! */
3409 uint32 ul;
3410 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3411 u_logout = (time_t)ul;
3414 /* !AS ROOT */
3416 unbecome_root();
3418 unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
3420 break;
3421 case 4:
3422 dom_info->oem.oem_information.string = lp_serverstring();
3423 break;
3424 case 5:
3425 dom_info->info5.domain_name.string = get_global_sam_name();
3426 break;
3427 case 6:
3428 /* NT returns its own name when a PDC. win2k and later
3429 * only the name of the PDC if itself is a BDC (samba4
3430 * idl) */
3431 dom_info->info6.primary.string = global_myname();
3432 break;
3433 case 7:
3434 server_role = ROLE_DOMAIN_PDC;
3435 if (lp_server_role() == ROLE_DOMAIN_BDC)
3436 server_role = ROLE_DOMAIN_BDC;
3438 dom_info->info7.role = server_role;
3439 break;
3440 case 8:
3442 become_root();
3444 /* AS ROOT !!! */
3446 if (!pdb_get_seq_num(&seq_num)) {
3447 seq_num = time(NULL);
3450 /* !AS ROOT */
3452 unbecome_root();
3454 dom_info->info8.sequence_num = seq_num;
3455 dom_info->info8.domain_create_time = 0;
3457 break;
3458 case 9:
3460 dom_info->info9.domain_server_state = DOMAIN_SERVER_ENABLED;
3462 break;
3463 case 11:
3465 /* AS ROOT !!! */
3467 become_root();
3469 dom_info->general2.general.num_users = count_sam_users(
3470 dinfo->disp_info, ACB_NORMAL);
3471 dom_info->general2.general.num_groups = count_sam_groups(
3472 dinfo->disp_info);
3473 dom_info->general2.general.num_aliases = count_sam_aliases(
3474 dinfo->disp_info);
3476 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
3478 unix_to_nt_time_abs(&dom_info->general2.general.force_logoff_time, u_logout);
3480 if (!pdb_get_seq_num(&seq_num))
3481 seq_num = time(NULL);
3483 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3484 u_lock_duration = account_policy_temp;
3485 if (u_lock_duration != -1) {
3486 u_lock_duration *= 60;
3489 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3490 u_reset_time = account_policy_temp * 60;
3492 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3493 &account_policy_temp);
3494 dom_info->general2.lockout_threshold = account_policy_temp;
3496 /* !AS ROOT */
3498 unbecome_root();
3500 server_role = ROLE_DOMAIN_PDC;
3501 if (lp_server_role() == ROLE_DOMAIN_BDC)
3502 server_role = ROLE_DOMAIN_BDC;
3504 dom_info->general2.general.oem_information.string = lp_serverstring();
3505 dom_info->general2.general.domain_name.string = lp_workgroup();
3506 dom_info->general2.general.primary.string = global_myname();
3507 dom_info->general2.general.sequence_num = seq_num;
3508 dom_info->general2.general.domain_server_state = DOMAIN_SERVER_ENABLED;
3509 dom_info->general2.general.role = server_role;
3510 dom_info->general2.general.unknown3 = 1;
3512 unix_to_nt_time_abs(&dom_info->general2.lockout_duration,
3513 u_lock_duration);
3514 unix_to_nt_time_abs(&dom_info->general2.lockout_window,
3515 u_reset_time);
3517 break;
3518 case 12:
3520 become_root();
3522 /* AS ROOT !!! */
3524 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3525 u_lock_duration = account_policy_temp;
3526 if (u_lock_duration != -1) {
3527 u_lock_duration *= 60;
3530 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3531 u_reset_time = account_policy_temp * 60;
3533 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
3534 &account_policy_temp);
3535 dom_info->info12.lockout_threshold = account_policy_temp;
3537 /* !AS ROOT */
3539 unbecome_root();
3541 unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
3542 u_lock_duration);
3543 unix_to_nt_time_abs(&dom_info->info12.lockout_window,
3544 u_reset_time);
3546 break;
3547 case 13:
3549 become_root();
3551 /* AS ROOT !!! */
3553 if (!pdb_get_seq_num(&seq_num)) {
3554 seq_num = time(NULL);
3557 /* !AS ROOT */
3559 unbecome_root();
3561 dom_info->info13.sequence_num = seq_num;
3562 dom_info->info13.domain_create_time = 0;
3563 dom_info->info13.modified_count_at_last_promotion = 0;
3565 break;
3566 default:
3567 return NT_STATUS_INVALID_INFO_CLASS;
3570 *r->out.info = dom_info;
3572 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3574 return status;
3577 /* W2k3 seems to use the same check for all 3 objects that can be created via
3578 * SAMR, if you try to create for example "Dialup" as an alias it says
3579 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3580 * database. */
3582 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3584 enum lsa_SidType type;
3585 bool result;
3587 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3589 become_root();
3590 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3591 * whether the name already exists */
3592 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3593 NULL, NULL, NULL, &type);
3594 unbecome_root();
3596 if (!result) {
3597 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3598 return NT_STATUS_OK;
3601 DEBUG(5, ("trying to create %s, exists as %s\n",
3602 new_name, sid_type_lookup(type)));
3604 if (type == SID_NAME_DOM_GRP) {
3605 return NT_STATUS_GROUP_EXISTS;
3607 if (type == SID_NAME_ALIAS) {
3608 return NT_STATUS_ALIAS_EXISTS;
3611 /* Yes, the default is NT_STATUS_USER_EXISTS */
3612 return NT_STATUS_USER_EXISTS;
3615 /*******************************************************************
3616 _samr_CreateUser2
3617 ********************************************************************/
3619 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3620 struct samr_CreateUser2 *r)
3622 const char *account = NULL;
3623 DOM_SID sid;
3624 uint32_t acb_info = r->in.acct_flags;
3625 struct samr_domain_info *dinfo;
3626 struct samr_user_info *uinfo;
3627 NTSTATUS nt_status;
3628 uint32 acc_granted;
3629 SEC_DESC *psd;
3630 size_t sd_size;
3631 /* check this, when giving away 'add computer to domain' privs */
3632 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3633 bool can_add_account = False;
3634 SE_PRIV se_rights;
3636 dinfo = policy_handle_find(p, r->in.domain_handle,
3637 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3638 struct samr_domain_info, &nt_status);
3639 if (!NT_STATUS_IS_OK(nt_status)) {
3640 return nt_status;
3643 if (sid_check_is_builtin(&dinfo->sid)) {
3644 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3645 return NT_STATUS_ACCESS_DENIED;
3648 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3649 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3650 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3651 this parameter is not an account type */
3652 return NT_STATUS_INVALID_PARAMETER;
3655 account = r->in.account_name->string;
3656 if (account == NULL) {
3657 return NT_STATUS_NO_MEMORY;
3660 nt_status = can_create(p->mem_ctx, account);
3661 if (!NT_STATUS_IS_OK(nt_status)) {
3662 return nt_status;
3665 /* determine which user right we need to check based on the acb_info */
3667 if (geteuid() == sec_initial_uid()) {
3668 se_priv_copy(&se_rights, &se_priv_none);
3669 can_add_account = true;
3670 } else if (acb_info & ACB_WSTRUST) {
3671 se_priv_copy(&se_rights, &se_machine_account);
3672 can_add_account = user_has_privileges(
3673 p->server_info->ptok, &se_rights );
3674 } else if (acb_info & ACB_NORMAL &&
3675 (account[strlen(account)-1] != '$')) {
3676 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3677 account for domain trusts and changes the ACB flags later */
3678 se_priv_copy(&se_rights, &se_add_users);
3679 can_add_account = user_has_privileges(
3680 p->server_info->ptok, &se_rights );
3681 } else if (lp_enable_privileges()) {
3682 /* implicit assumption of a BDC or domain trust account here
3683 * (we already check the flags earlier) */
3684 /* only Domain Admins can add a BDC or domain trust */
3685 se_priv_copy(&se_rights, &se_priv_none);
3686 can_add_account = nt_token_check_domain_rid(
3687 p->server_info->ptok,
3688 DOMAIN_GROUP_RID_ADMINS );
3691 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3692 uidtoname(p->server_info->utok.uid),
3693 can_add_account ? "True":"False" ));
3695 if (!can_add_account) {
3696 return NT_STATUS_ACCESS_DENIED;
3699 /********** BEGIN Admin BLOCK **********/
3701 become_root();
3702 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3703 r->out.rid);
3704 unbecome_root();
3706 /********** END Admin BLOCK **********/
3708 /* now check for failure */
3710 if ( !NT_STATUS_IS_OK(nt_status) )
3711 return nt_status;
3713 /* Get the user's SID */
3715 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3717 map_max_allowed_access(p->server_info->ptok, &des_access);
3719 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3720 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3721 se_map_generic(&des_access, &usr_generic_mapping);
3724 * JRA - TESTME. We just created this user so we
3725 * had rights to create them. Do we need to check
3726 * any further access on this object ? Can't we
3727 * just assume we have all the rights we need ?
3730 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3731 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3732 &acc_granted, "_samr_CreateUser2");
3734 if ( !NT_STATUS_IS_OK(nt_status) ) {
3735 return nt_status;
3738 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3739 struct samr_user_info, &nt_status);
3740 if (!NT_STATUS_IS_OK(nt_status)) {
3741 return nt_status;
3743 uinfo->sid = sid;
3745 /* After a "set" ensure we have no cached display info. */
3746 force_flush_samr_cache(&sid);
3748 *r->out.access_granted = acc_granted;
3750 return NT_STATUS_OK;
3753 /****************************************************************
3754 ****************************************************************/
3756 NTSTATUS _samr_CreateUser(pipes_struct *p,
3757 struct samr_CreateUser *r)
3759 struct samr_CreateUser2 c;
3760 uint32_t access_granted;
3762 c.in.domain_handle = r->in.domain_handle;
3763 c.in.account_name = r->in.account_name;
3764 c.in.acct_flags = ACB_NORMAL;
3765 c.in.access_mask = r->in.access_mask;
3766 c.out.user_handle = r->out.user_handle;
3767 c.out.access_granted = &access_granted;
3768 c.out.rid = r->out.rid;
3770 return _samr_CreateUser2(p, &c);
3773 /*******************************************************************
3774 _samr_Connect
3775 ********************************************************************/
3777 NTSTATUS _samr_Connect(pipes_struct *p,
3778 struct samr_Connect *r)
3780 struct samr_connect_info *info;
3781 uint32_t acc_granted;
3782 struct policy_handle hnd;
3783 uint32 des_access = r->in.access_mask;
3784 NTSTATUS status;
3786 /* Access check */
3788 if (!pipe_access_check(p)) {
3789 DEBUG(3, ("access denied to _samr_Connect\n"));
3790 return NT_STATUS_ACCESS_DENIED;
3793 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3794 was observed from a win98 client trying to enumerate users (when configured
3795 user level access control on shares) --jerry */
3797 map_max_allowed_access(p->server_info->ptok, &des_access);
3799 se_map_generic( &des_access, &sam_generic_mapping );
3801 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3802 |SAMR_ACCESS_LOOKUP_DOMAIN);
3804 /* set up the SAMR connect_anon response */
3806 info = policy_handle_create(p, &hnd, acc_granted,
3807 struct samr_connect_info,
3808 &status);
3809 if (!NT_STATUS_IS_OK(status)) {
3810 return status;
3813 *r->out.connect_handle = hnd;
3814 return NT_STATUS_OK;
3817 /*******************************************************************
3818 _samr_Connect2
3819 ********************************************************************/
3821 NTSTATUS _samr_Connect2(pipes_struct *p,
3822 struct samr_Connect2 *r)
3824 struct samr_connect_info *info = NULL;
3825 struct policy_handle hnd;
3826 SEC_DESC *psd = NULL;
3827 uint32 acc_granted;
3828 uint32 des_access = r->in.access_mask;
3829 NTSTATUS nt_status;
3830 size_t sd_size;
3831 const char *fn = "_samr_Connect2";
3833 switch (p->hdr_req.opnum) {
3834 case NDR_SAMR_CONNECT2:
3835 fn = "_samr_Connect2";
3836 break;
3837 case NDR_SAMR_CONNECT3:
3838 fn = "_samr_Connect3";
3839 break;
3840 case NDR_SAMR_CONNECT4:
3841 fn = "_samr_Connect4";
3842 break;
3843 case NDR_SAMR_CONNECT5:
3844 fn = "_samr_Connect5";
3845 break;
3848 DEBUG(5,("%s: %d\n", fn, __LINE__));
3850 /* Access check */
3852 if (!pipe_access_check(p)) {
3853 DEBUG(3, ("access denied to %s\n", fn));
3854 return NT_STATUS_ACCESS_DENIED;
3857 map_max_allowed_access(p->server_info->ptok, &des_access);
3859 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3860 se_map_generic(&des_access, &sam_generic_mapping);
3862 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3863 NULL, 0, des_access, &acc_granted, fn);
3865 if ( !NT_STATUS_IS_OK(nt_status) )
3866 return nt_status;
3868 info = policy_handle_create(p, &hnd, acc_granted,
3869 struct samr_connect_info, &nt_status);
3870 if (!NT_STATUS_IS_OK(nt_status)) {
3871 return nt_status;
3874 DEBUG(5,("%s: %d\n", fn, __LINE__));
3876 *r->out.connect_handle = hnd;
3877 return NT_STATUS_OK;
3880 /****************************************************************
3881 _samr_Connect3
3882 ****************************************************************/
3884 NTSTATUS _samr_Connect3(pipes_struct *p,
3885 struct samr_Connect3 *r)
3887 struct samr_Connect2 c;
3889 c.in.system_name = r->in.system_name;
3890 c.in.access_mask = r->in.access_mask;
3891 c.out.connect_handle = r->out.connect_handle;
3893 return _samr_Connect2(p, &c);
3896 /*******************************************************************
3897 _samr_Connect4
3898 ********************************************************************/
3900 NTSTATUS _samr_Connect4(pipes_struct *p,
3901 struct samr_Connect4 *r)
3903 struct samr_Connect2 c;
3905 c.in.system_name = r->in.system_name;
3906 c.in.access_mask = r->in.access_mask;
3907 c.out.connect_handle = r->out.connect_handle;
3909 return _samr_Connect2(p, &c);
3912 /*******************************************************************
3913 _samr_Connect5
3914 ********************************************************************/
3916 NTSTATUS _samr_Connect5(pipes_struct *p,
3917 struct samr_Connect5 *r)
3919 NTSTATUS status;
3920 struct samr_Connect2 c;
3921 struct samr_ConnectInfo1 info1;
3923 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3924 info1.unknown2 = 0;
3926 c.in.system_name = r->in.system_name;
3927 c.in.access_mask = r->in.access_mask;
3928 c.out.connect_handle = r->out.connect_handle;
3930 *r->out.level_out = 1;
3932 status = _samr_Connect2(p, &c);
3933 if (!NT_STATUS_IS_OK(status)) {
3934 return status;
3937 r->out.info_out->info1 = info1;
3939 return NT_STATUS_OK;
3942 /**********************************************************************
3943 _samr_LookupDomain
3944 **********************************************************************/
3946 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3947 struct samr_LookupDomain *r)
3949 NTSTATUS status;
3950 struct samr_connect_info *info;
3951 const char *domain_name;
3952 DOM_SID *sid = NULL;
3954 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3955 Reverted that change so we will work with RAS servers again */
3957 info = policy_handle_find(p, r->in.connect_handle,
3958 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3959 struct samr_connect_info,
3960 &status);
3961 if (!NT_STATUS_IS_OK(status)) {
3962 return status;
3965 domain_name = r->in.domain_name->string;
3966 if (!domain_name) {
3967 return NT_STATUS_INVALID_PARAMETER;
3970 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3971 if (!sid) {
3972 return NT_STATUS_NO_MEMORY;
3975 if (strequal(domain_name, builtin_domain_name())) {
3976 sid_copy(sid, &global_sid_Builtin);
3977 } else {
3978 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3979 status = NT_STATUS_NO_SUCH_DOMAIN;
3983 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3984 sid_string_dbg(sid)));
3986 *r->out.sid = sid;
3988 return status;
3991 /**********************************************************************
3992 _samr_EnumDomains
3993 **********************************************************************/
3995 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3996 struct samr_EnumDomains *r)
3998 NTSTATUS status;
3999 struct samr_connect_info *info;
4000 uint32_t num_entries = 2;
4001 struct samr_SamEntry *entry_array = NULL;
4002 struct samr_SamArray *sam;
4004 info = policy_handle_find(p, r->in.connect_handle,
4005 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4006 struct samr_connect_info, &status);
4007 if (!NT_STATUS_IS_OK(status)) {
4008 return status;
4011 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4012 if (!sam) {
4013 return NT_STATUS_NO_MEMORY;
4016 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4017 struct samr_SamEntry,
4018 num_entries);
4019 if (!entry_array) {
4020 return NT_STATUS_NO_MEMORY;
4023 entry_array[0].idx = 0;
4024 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4026 entry_array[1].idx = 1;
4027 init_lsa_String(&entry_array[1].name, "Builtin");
4029 sam->count = num_entries;
4030 sam->entries = entry_array;
4032 *r->out.sam = sam;
4033 *r->out.num_entries = num_entries;
4035 return status;
4038 /*******************************************************************
4039 _samr_OpenAlias
4040 ********************************************************************/
4042 NTSTATUS _samr_OpenAlias(pipes_struct *p,
4043 struct samr_OpenAlias *r)
4045 DOM_SID sid;
4046 uint32 alias_rid = r->in.rid;
4047 struct samr_alias_info *ainfo;
4048 struct samr_domain_info *dinfo;
4049 SEC_DESC *psd = NULL;
4050 uint32 acc_granted;
4051 uint32 des_access = r->in.access_mask;
4052 size_t sd_size;
4053 NTSTATUS status;
4054 SE_PRIV se_rights;
4056 dinfo = policy_handle_find(p, r->in.domain_handle,
4057 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4058 struct samr_domain_info, &status);
4059 if (!NT_STATUS_IS_OK(status)) {
4060 return status;
4063 /* append the alias' RID to it */
4065 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4066 return NT_STATUS_NO_SUCH_ALIAS;
4068 /*check if access can be granted as requested by client. */
4070 map_max_allowed_access(p->server_info->ptok, &des_access);
4072 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4073 se_map_generic(&des_access,&ali_generic_mapping);
4075 se_priv_copy( &se_rights, &se_add_users );
4077 status = access_check_samr_object(psd, p->server_info->ptok,
4078 &se_rights, SAMR_ALIAS_ACCESS_ADD_MEMBER,
4079 des_access, &acc_granted, "_samr_OpenAlias");
4081 if ( !NT_STATUS_IS_OK(status) )
4082 return status;
4085 /* Check we actually have the requested alias */
4086 enum lsa_SidType type;
4087 bool result;
4088 gid_t gid;
4090 become_root();
4091 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4092 unbecome_root();
4094 if (!result || (type != SID_NAME_ALIAS)) {
4095 return NT_STATUS_NO_SUCH_ALIAS;
4098 /* make sure there is a mapping */
4100 if ( !sid_to_gid( &sid, &gid ) ) {
4101 return NT_STATUS_NO_SUCH_ALIAS;
4106 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4107 struct samr_alias_info, &status);
4108 if (!NT_STATUS_IS_OK(status)) {
4109 return status;
4111 ainfo->sid = sid;
4113 return NT_STATUS_OK;
4116 /*******************************************************************
4117 set_user_info_2
4118 ********************************************************************/
4120 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4121 struct samr_UserInfo2 *id2,
4122 struct samu *pwd)
4124 if (id2 == NULL) {
4125 DEBUG(5,("set_user_info_2: NULL id2\n"));
4126 return NT_STATUS_ACCESS_DENIED;
4129 copy_id2_to_sam_passwd(pwd, id2);
4131 return pdb_update_sam_account(pwd);
4134 /*******************************************************************
4135 set_user_info_4
4136 ********************************************************************/
4138 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4139 struct samr_UserInfo4 *id4,
4140 struct samu *pwd)
4142 if (id4 == NULL) {
4143 DEBUG(5,("set_user_info_2: NULL id4\n"));
4144 return NT_STATUS_ACCESS_DENIED;
4147 copy_id4_to_sam_passwd(pwd, id4);
4149 return pdb_update_sam_account(pwd);
4152 /*******************************************************************
4153 set_user_info_6
4154 ********************************************************************/
4156 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4157 struct samr_UserInfo6 *id6,
4158 struct samu *pwd)
4160 if (id6 == NULL) {
4161 DEBUG(5,("set_user_info_6: NULL id6\n"));
4162 return NT_STATUS_ACCESS_DENIED;
4165 copy_id6_to_sam_passwd(pwd, id6);
4167 return pdb_update_sam_account(pwd);
4170 /*******************************************************************
4171 set_user_info_7
4172 ********************************************************************/
4174 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4175 struct samr_UserInfo7 *id7,
4176 struct samu *pwd)
4178 NTSTATUS rc;
4180 if (id7 == NULL) {
4181 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4182 return NT_STATUS_ACCESS_DENIED;
4185 if (!id7->account_name.string) {
4186 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4187 return NT_STATUS_ACCESS_DENIED;
4190 /* check to see if the new username already exists. Note: we can't
4191 reliably lock all backends, so there is potentially the
4192 possibility that a user can be created in between this check and
4193 the rename. The rename should fail, but may not get the
4194 exact same failure status code. I think this is small enough
4195 of a window for this type of operation and the results are
4196 simply that the rename fails with a slightly different status
4197 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4199 rc = can_create(mem_ctx, id7->account_name.string);
4201 /* when there is nothing to change, we're done here */
4202 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4203 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4204 return NT_STATUS_OK;
4206 if (!NT_STATUS_IS_OK(rc)) {
4207 return rc;
4210 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4212 return rc;
4215 /*******************************************************************
4216 set_user_info_8
4217 ********************************************************************/
4219 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4220 struct samr_UserInfo8 *id8,
4221 struct samu *pwd)
4223 if (id8 == NULL) {
4224 DEBUG(5,("set_user_info_8: NULL id8\n"));
4225 return NT_STATUS_ACCESS_DENIED;
4228 copy_id8_to_sam_passwd(pwd, id8);
4230 return pdb_update_sam_account(pwd);
4233 /*******************************************************************
4234 set_user_info_10
4235 ********************************************************************/
4237 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4238 struct samr_UserInfo10 *id10,
4239 struct samu *pwd)
4241 if (id10 == NULL) {
4242 DEBUG(5,("set_user_info_8: NULL id10\n"));
4243 return NT_STATUS_ACCESS_DENIED;
4246 copy_id10_to_sam_passwd(pwd, id10);
4248 return pdb_update_sam_account(pwd);
4251 /*******************************************************************
4252 set_user_info_11
4253 ********************************************************************/
4255 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4256 struct samr_UserInfo11 *id11,
4257 struct samu *pwd)
4259 if (id11 == NULL) {
4260 DEBUG(5,("set_user_info_11: NULL id11\n"));
4261 return NT_STATUS_ACCESS_DENIED;
4264 copy_id11_to_sam_passwd(pwd, id11);
4266 return pdb_update_sam_account(pwd);
4269 /*******************************************************************
4270 set_user_info_12
4271 ********************************************************************/
4273 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4274 struct samr_UserInfo12 *id12,
4275 struct samu *pwd)
4277 if (id12 == NULL) {
4278 DEBUG(5,("set_user_info_12: NULL id12\n"));
4279 return NT_STATUS_ACCESS_DENIED;
4282 copy_id12_to_sam_passwd(pwd, id12);
4284 return pdb_update_sam_account(pwd);
4287 /*******************************************************************
4288 set_user_info_13
4289 ********************************************************************/
4291 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4292 struct samr_UserInfo13 *id13,
4293 struct samu *pwd)
4295 if (id13 == NULL) {
4296 DEBUG(5,("set_user_info_13: NULL id13\n"));
4297 return NT_STATUS_ACCESS_DENIED;
4300 copy_id13_to_sam_passwd(pwd, id13);
4302 return pdb_update_sam_account(pwd);
4305 /*******************************************************************
4306 set_user_info_14
4307 ********************************************************************/
4309 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4310 struct samr_UserInfo14 *id14,
4311 struct samu *pwd)
4313 if (id14 == NULL) {
4314 DEBUG(5,("set_user_info_14: NULL id14\n"));
4315 return NT_STATUS_ACCESS_DENIED;
4318 copy_id14_to_sam_passwd(pwd, id14);
4320 return pdb_update_sam_account(pwd);
4323 /*******************************************************************
4324 set_user_info_16
4325 ********************************************************************/
4327 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4328 struct samr_UserInfo16 *id16,
4329 struct samu *pwd)
4331 if (id16 == NULL) {
4332 DEBUG(5,("set_user_info_16: NULL id16\n"));
4333 return NT_STATUS_ACCESS_DENIED;
4336 copy_id16_to_sam_passwd(pwd, id16);
4338 return pdb_update_sam_account(pwd);
4341 /*******************************************************************
4342 set_user_info_17
4343 ********************************************************************/
4345 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4346 struct samr_UserInfo17 *id17,
4347 struct samu *pwd)
4349 if (id17 == NULL) {
4350 DEBUG(5,("set_user_info_17: NULL id17\n"));
4351 return NT_STATUS_ACCESS_DENIED;
4354 copy_id17_to_sam_passwd(pwd, id17);
4356 return pdb_update_sam_account(pwd);
4359 /*******************************************************************
4360 set_user_info_18
4361 ********************************************************************/
4363 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4364 TALLOC_CTX *mem_ctx,
4365 DATA_BLOB *session_key,
4366 struct samu *pwd)
4368 if (id18 == NULL) {
4369 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4370 return NT_STATUS_INVALID_PARAMETER;
4373 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4374 if (!session_key->length) {
4375 return NT_STATUS_NO_USER_SESSION_KEY;
4379 if (id18->nt_pwd_active) {
4381 DATA_BLOB in, out;
4383 in = data_blob_const(id18->nt_pwd.hash, 16);
4384 out = data_blob_talloc_zero(mem_ctx, 16);
4386 sess_crypt_blob(&out, &in, session_key, false);
4388 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4389 return NT_STATUS_ACCESS_DENIED;
4392 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4395 if (id18->lm_pwd_active) {
4397 DATA_BLOB in, out;
4399 in = data_blob_const(id18->lm_pwd.hash, 16);
4400 out = data_blob_talloc_zero(mem_ctx, 16);
4402 sess_crypt_blob(&out, &in, session_key, false);
4404 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4405 return NT_STATUS_ACCESS_DENIED;
4408 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4411 copy_id18_to_sam_passwd(pwd, id18);
4413 return pdb_update_sam_account(pwd);
4416 /*******************************************************************
4417 set_user_info_20
4418 ********************************************************************/
4420 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4421 struct samr_UserInfo20 *id20,
4422 struct samu *pwd)
4424 if (id20 == NULL) {
4425 DEBUG(5,("set_user_info_20: NULL id20\n"));
4426 return NT_STATUS_ACCESS_DENIED;
4429 copy_id20_to_sam_passwd(pwd, id20);
4431 return pdb_update_sam_account(pwd);
4434 /*******************************************************************
4435 set_user_info_21
4436 ********************************************************************/
4438 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4439 TALLOC_CTX *mem_ctx,
4440 DATA_BLOB *session_key,
4441 struct samu *pwd)
4443 NTSTATUS status;
4445 if (id21 == NULL) {
4446 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4447 return NT_STATUS_INVALID_PARAMETER;
4450 if (id21->fields_present == 0) {
4451 return NT_STATUS_INVALID_PARAMETER;
4454 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4455 return NT_STATUS_ACCESS_DENIED;
4458 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4459 if (id21->nt_password_set) {
4460 DATA_BLOB in, out;
4462 if ((id21->nt_owf_password.length != 16) ||
4463 (id21->nt_owf_password.size != 16)) {
4464 return NT_STATUS_INVALID_PARAMETER;
4467 if (!session_key->length) {
4468 return NT_STATUS_NO_USER_SESSION_KEY;
4471 in = data_blob_const(id21->nt_owf_password.array, 16);
4472 out = data_blob_talloc_zero(mem_ctx, 16);
4474 sess_crypt_blob(&out, &in, session_key, false);
4476 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4477 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4481 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4482 if (id21->lm_password_set) {
4483 DATA_BLOB in, out;
4485 if ((id21->lm_owf_password.length != 16) ||
4486 (id21->lm_owf_password.size != 16)) {
4487 return NT_STATUS_INVALID_PARAMETER;
4490 if (!session_key->length) {
4491 return NT_STATUS_NO_USER_SESSION_KEY;
4494 in = data_blob_const(id21->lm_owf_password.array, 16);
4495 out = data_blob_talloc_zero(mem_ctx, 16);
4497 sess_crypt_blob(&out, &in, session_key, false);
4499 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4500 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4504 /* we need to separately check for an account rename first */
4506 if (id21->account_name.string &&
4507 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4510 /* check to see if the new username already exists. Note: we can't
4511 reliably lock all backends, so there is potentially the
4512 possibility that a user can be created in between this check and
4513 the rename. The rename should fail, but may not get the
4514 exact same failure status code. I think this is small enough
4515 of a window for this type of operation and the results are
4516 simply that the rename fails with a slightly different status
4517 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4519 status = can_create(mem_ctx, id21->account_name.string);
4520 if (!NT_STATUS_IS_OK(status)) {
4521 return status;
4524 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4526 if (!NT_STATUS_IS_OK(status)) {
4527 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4528 nt_errstr(status)));
4529 return status;
4532 /* set the new username so that later
4533 functions can work on the new account */
4534 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4537 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4540 * The funny part about the previous two calls is
4541 * that pwd still has the password hashes from the
4542 * passdb entry. These have not been updated from
4543 * id21. I don't know if they need to be set. --jerry
4546 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4547 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4548 if ( !NT_STATUS_IS_OK(status) ) {
4549 return status;
4553 /* Don't worry about writing out the user account since the
4554 primary group SID is generated solely from the user's Unix
4555 primary group. */
4557 /* write the change out */
4558 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4559 return status;
4562 return NT_STATUS_OK;
4565 /*******************************************************************
4566 set_user_info_23
4567 ********************************************************************/
4569 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4570 struct samr_UserInfo23 *id23,
4571 struct samu *pwd)
4573 char *plaintext_buf = NULL;
4574 size_t len = 0;
4575 uint32_t acct_ctrl;
4576 NTSTATUS status;
4578 if (id23 == NULL) {
4579 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4580 return NT_STATUS_INVALID_PARAMETER;
4583 if (id23->info.fields_present == 0) {
4584 return NT_STATUS_INVALID_PARAMETER;
4587 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4588 return NT_STATUS_ACCESS_DENIED;
4591 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4592 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4594 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4595 pdb_get_username(pwd)));
4597 if (!decode_pw_buffer(mem_ctx,
4598 id23->password.data,
4599 &plaintext_buf,
4600 &len,
4601 CH_UTF16)) {
4602 return NT_STATUS_WRONG_PASSWORD;
4605 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4606 return NT_STATUS_ACCESS_DENIED;
4610 copy_id23_to_sam_passwd(pwd, id23);
4612 acct_ctrl = pdb_get_acct_ctrl(pwd);
4614 /* if it's a trust account, don't update /etc/passwd */
4615 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4616 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4617 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4618 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4619 } else if (plaintext_buf) {
4620 /* update the UNIX password */
4621 if (lp_unix_password_sync() ) {
4622 struct passwd *passwd;
4623 if (pdb_get_username(pwd) == NULL) {
4624 DEBUG(1, ("chgpasswd: User without name???\n"));
4625 return NT_STATUS_ACCESS_DENIED;
4628 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4629 if (passwd == NULL) {
4630 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4633 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4634 return NT_STATUS_ACCESS_DENIED;
4636 TALLOC_FREE(passwd);
4640 if (plaintext_buf) {
4641 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4644 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4645 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4646 pwd)))) {
4647 return status;
4650 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4651 return status;
4654 return NT_STATUS_OK;
4657 /*******************************************************************
4658 set_user_info_pw
4659 ********************************************************************/
4661 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4663 size_t len = 0;
4664 char *plaintext_buf = NULL;
4665 uint32 acct_ctrl;
4667 DEBUG(5, ("Attempting administrator password change for user %s\n",
4668 pdb_get_username(pwd)));
4670 acct_ctrl = pdb_get_acct_ctrl(pwd);
4672 if (!decode_pw_buffer(talloc_tos(),
4673 pass,
4674 &plaintext_buf,
4675 &len,
4676 CH_UTF16)) {
4677 return False;
4680 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4681 return False;
4684 /* if it's a trust account, don't update /etc/passwd */
4685 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4686 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4687 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4688 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4689 } else {
4690 /* update the UNIX password */
4691 if (lp_unix_password_sync()) {
4692 struct passwd *passwd;
4694 if (pdb_get_username(pwd) == NULL) {
4695 DEBUG(1, ("chgpasswd: User without name???\n"));
4696 return False;
4699 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4700 if (passwd == NULL) {
4701 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4704 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4705 return False;
4707 TALLOC_FREE(passwd);
4711 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4713 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4715 return True;
4718 /*******************************************************************
4719 set_user_info_24
4720 ********************************************************************/
4722 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4723 struct samr_UserInfo24 *id24,
4724 struct samu *pwd)
4726 NTSTATUS status;
4728 if (id24 == NULL) {
4729 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4730 return NT_STATUS_INVALID_PARAMETER;
4733 if (!set_user_info_pw(id24->password.data, pwd)) {
4734 return NT_STATUS_WRONG_PASSWORD;
4737 copy_id24_to_sam_passwd(pwd, id24);
4739 status = pdb_update_sam_account(pwd);
4740 if (!NT_STATUS_IS_OK(status)) {
4741 return status;
4744 return NT_STATUS_OK;
4747 /*******************************************************************
4748 set_user_info_25
4749 ********************************************************************/
4751 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4752 struct samr_UserInfo25 *id25,
4753 struct samu *pwd)
4755 NTSTATUS status;
4757 if (id25 == NULL) {
4758 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4759 return NT_STATUS_INVALID_PARAMETER;
4762 if (id25->info.fields_present == 0) {
4763 return NT_STATUS_INVALID_PARAMETER;
4766 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4767 return NT_STATUS_ACCESS_DENIED;
4770 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4771 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4773 if (!set_user_info_pw(id25->password.data, pwd)) {
4774 return NT_STATUS_WRONG_PASSWORD;
4778 copy_id25_to_sam_passwd(pwd, id25);
4780 /* write the change out */
4781 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4782 return status;
4786 * We need to "pdb_update_sam_account" before the unix primary group
4787 * is set, because the idealx scripts would also change the
4788 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4789 * the delete explicit / add explicit, which would then fail to find
4790 * the previous primaryGroupSid value.
4793 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4794 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4795 if ( !NT_STATUS_IS_OK(status) ) {
4796 return status;
4800 return NT_STATUS_OK;
4803 /*******************************************************************
4804 set_user_info_26
4805 ********************************************************************/
4807 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4808 struct samr_UserInfo26 *id26,
4809 struct samu *pwd)
4811 NTSTATUS status;
4813 if (id26 == NULL) {
4814 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4815 return NT_STATUS_INVALID_PARAMETER;
4818 if (!set_user_info_pw(id26->password.data, pwd)) {
4819 return NT_STATUS_WRONG_PASSWORD;
4822 copy_id26_to_sam_passwd(pwd, id26);
4824 status = pdb_update_sam_account(pwd);
4825 if (!NT_STATUS_IS_OK(status)) {
4826 return status;
4829 return NT_STATUS_OK;
4832 /*************************************************************
4833 **************************************************************/
4835 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4837 uint32_t acc_required = 0;
4839 /* USER_ALL_USERNAME */
4840 if (fields & SAMR_FIELD_ACCOUNT_NAME)
4841 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4842 /* USER_ALL_FULLNAME */
4843 if (fields & SAMR_FIELD_FULL_NAME)
4844 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4845 /* USER_ALL_PRIMARYGROUPID */
4846 if (fields & SAMR_FIELD_PRIMARY_GID)
4847 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4848 /* USER_ALL_HOMEDIRECTORY */
4849 if (fields & SAMR_FIELD_HOME_DIRECTORY)
4850 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4851 /* USER_ALL_HOMEDIRECTORYDRIVE */
4852 if (fields & SAMR_FIELD_HOME_DRIVE)
4853 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4854 /* USER_ALL_SCRIPTPATH */
4855 if (fields & SAMR_FIELD_LOGON_SCRIPT)
4856 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4857 /* USER_ALL_PROFILEPATH */
4858 if (fields & SAMR_FIELD_PROFILE_PATH)
4859 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4860 /* USER_ALL_ADMINCOMMENT */
4861 if (fields & SAMR_FIELD_COMMENT)
4862 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4863 /* USER_ALL_WORKSTATIONS */
4864 if (fields & SAMR_FIELD_WORKSTATIONS)
4865 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4866 /* USER_ALL_LOGONHOURS */
4867 if (fields & SAMR_FIELD_LOGON_HOURS)
4868 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4869 /* USER_ALL_ACCOUNTEXPIRES */
4870 if (fields & SAMR_FIELD_ACCT_EXPIRY)
4871 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4872 /* USER_ALL_USERACCOUNTCONTROL */
4873 if (fields & SAMR_FIELD_ACCT_FLAGS)
4874 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4875 /* USER_ALL_PARAMETERS */
4876 if (fields & SAMR_FIELD_PARAMETERS)
4877 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4878 /* USER_ALL_USERCOMMENT */
4879 if (fields & SAMR_FIELD_COMMENT)
4880 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4881 /* USER_ALL_COUNTRYCODE */
4882 if (fields & SAMR_FIELD_COUNTRY_CODE)
4883 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4884 /* USER_ALL_CODEPAGE */
4885 if (fields & SAMR_FIELD_CODE_PAGE)
4886 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4887 /* USER_ALL_NTPASSWORDPRESENT */
4888 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
4889 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4890 /* USER_ALL_LMPASSWORDPRESENT */
4891 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
4892 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4893 /* USER_ALL_PASSWORDEXPIRED */
4894 if (fields & SAMR_FIELD_EXPIRED_FLAG)
4895 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4897 return acc_required;
4900 /*******************************************************************
4901 samr_SetUserInfo
4902 ********************************************************************/
4904 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4905 struct samr_SetUserInfo *r)
4907 struct samr_user_info *uinfo;
4908 NTSTATUS status;
4909 struct samu *pwd = NULL;
4910 union samr_UserInfo *info = r->in.info;
4911 uint32_t acc_required = 0;
4912 uint32_t fields = 0;
4913 bool ret;
4915 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4917 /* This is tricky. A WinXP domain join sets
4918 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4919 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4920 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4921 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4922 we'll use the set from the WinXP join as the basis. */
4924 switch (r->in.level) {
4925 case 2: /* UserPreferencesInformation */
4926 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
4927 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
4928 break;
4929 case 4: /* UserLogonHoursInformation */
4930 case 6: /* UserNameInformation */
4931 case 7: /* UserAccountNameInformation */
4932 case 8: /* UserFullNameInformation */
4933 case 9: /* UserPrimaryGroupInformation */
4934 case 10: /* UserHomeInformation */
4935 case 11: /* UserScriptInformation */
4936 case 12: /* UserProfileInformation */
4937 case 13: /* UserAdminCommentInformation */
4938 case 14: /* UserWorkStationsInformation */
4939 case 16: /* UserControlInformation */
4940 case 17: /* UserExpiresInformation */
4941 case 20: /* UserParametersInformation */
4942 /* USER_WRITE_ACCOUNT */
4943 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
4944 break;
4945 case 18: /* UserInternal1Information */
4946 /* FIXME: gd, this is a guess */
4947 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4948 break;
4949 case 21: /* UserAllInformation */
4950 fields = info->info21.fields_present;
4951 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4952 break;
4953 case 23: /* UserInternal4Information */
4954 fields = info->info23.info.fields_present;
4955 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4956 break;
4957 case 25: /* UserInternal4InformationNew */
4958 fields = info->info25.info.fields_present;
4959 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4960 break;
4961 case 24: /* UserInternal5Information */
4962 case 26: /* UserInternal5InformationNew */
4963 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4964 break;
4965 default:
4966 return NT_STATUS_INVALID_INFO_CLASS;
4969 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
4970 struct samr_user_info, &status);
4971 if (!NT_STATUS_IS_OK(status)) {
4972 return status;
4975 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4976 sid_string_dbg(&uinfo->sid), r->in.level));
4978 if (info == NULL) {
4979 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4980 return NT_STATUS_INVALID_INFO_CLASS;
4983 if (!(pwd = samu_new(NULL))) {
4984 return NT_STATUS_NO_MEMORY;
4987 become_root();
4988 ret = pdb_getsampwsid(pwd, &uinfo->sid);
4989 unbecome_root();
4991 if (!ret) {
4992 TALLOC_FREE(pwd);
4993 return NT_STATUS_NO_SUCH_USER;
4996 /* ================ BEGIN Privilege BLOCK ================ */
4998 become_root();
5000 /* ok! user info levels (lots: see MSDEV help), off we go... */
5002 switch (r->in.level) {
5004 case 2:
5005 status = set_user_info_2(p->mem_ctx,
5006 &info->info2, pwd);
5007 break;
5009 case 4:
5010 status = set_user_info_4(p->mem_ctx,
5011 &info->info4, pwd);
5012 break;
5014 case 6:
5015 status = set_user_info_6(p->mem_ctx,
5016 &info->info6, pwd);
5017 break;
5019 case 7:
5020 status = set_user_info_7(p->mem_ctx,
5021 &info->info7, pwd);
5022 break;
5024 case 8:
5025 status = set_user_info_8(p->mem_ctx,
5026 &info->info8, pwd);
5027 break;
5029 case 10:
5030 status = set_user_info_10(p->mem_ctx,
5031 &info->info10, pwd);
5032 break;
5034 case 11:
5035 status = set_user_info_11(p->mem_ctx,
5036 &info->info11, pwd);
5037 break;
5039 case 12:
5040 status = set_user_info_12(p->mem_ctx,
5041 &info->info12, pwd);
5042 break;
5044 case 13:
5045 status = set_user_info_13(p->mem_ctx,
5046 &info->info13, pwd);
5047 break;
5049 case 14:
5050 status = set_user_info_14(p->mem_ctx,
5051 &info->info14, pwd);
5052 break;
5054 case 16:
5055 status = set_user_info_16(p->mem_ctx,
5056 &info->info16, pwd);
5057 break;
5059 case 17:
5060 status = set_user_info_17(p->mem_ctx,
5061 &info->info17, pwd);
5062 break;
5064 case 18:
5065 /* Used by AS/U JRA. */
5066 status = set_user_info_18(&info->info18,
5067 p->mem_ctx,
5068 &p->server_info->user_session_key,
5069 pwd);
5070 break;
5072 case 20:
5073 status = set_user_info_20(p->mem_ctx,
5074 &info->info20, pwd);
5075 break;
5077 case 21:
5078 status = set_user_info_21(&info->info21,
5079 p->mem_ctx,
5080 &p->server_info->user_session_key,
5081 pwd);
5082 break;
5084 case 23:
5085 if (!p->server_info->user_session_key.length) {
5086 status = NT_STATUS_NO_USER_SESSION_KEY;
5088 arcfour_crypt_blob(info->info23.password.data, 516,
5089 &p->server_info->user_session_key);
5091 dump_data(100, info->info23.password.data, 516);
5093 status = set_user_info_23(p->mem_ctx,
5094 &info->info23, pwd);
5095 break;
5097 case 24:
5098 if (!p->server_info->user_session_key.length) {
5099 status = NT_STATUS_NO_USER_SESSION_KEY;
5101 arcfour_crypt_blob(info->info24.password.data,
5102 516,
5103 &p->server_info->user_session_key);
5105 dump_data(100, info->info24.password.data, 516);
5107 status = set_user_info_24(p->mem_ctx,
5108 &info->info24, pwd);
5109 break;
5111 case 25:
5112 if (!p->server_info->user_session_key.length) {
5113 status = NT_STATUS_NO_USER_SESSION_KEY;
5115 encode_or_decode_arc4_passwd_buffer(
5116 info->info25.password.data,
5117 &p->server_info->user_session_key);
5119 dump_data(100, info->info25.password.data, 532);
5121 status = set_user_info_25(p->mem_ctx,
5122 &info->info25, pwd);
5123 break;
5125 case 26:
5126 if (!p->server_info->user_session_key.length) {
5127 status = NT_STATUS_NO_USER_SESSION_KEY;
5129 encode_or_decode_arc4_passwd_buffer(
5130 info->info26.password.data,
5131 &p->server_info->user_session_key);
5133 dump_data(100, info->info26.password.data, 516);
5135 status = set_user_info_26(p->mem_ctx,
5136 &info->info26, pwd);
5137 break;
5139 default:
5140 status = NT_STATUS_INVALID_INFO_CLASS;
5143 TALLOC_FREE(pwd);
5145 unbecome_root();
5147 /* ================ END Privilege BLOCK ================ */
5149 if (NT_STATUS_IS_OK(status)) {
5150 force_flush_samr_cache(&uinfo->sid);
5153 return status;
5156 /*******************************************************************
5157 _samr_SetUserInfo2
5158 ********************************************************************/
5160 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
5161 struct samr_SetUserInfo2 *r)
5163 struct samr_SetUserInfo q;
5165 q.in.user_handle = r->in.user_handle;
5166 q.in.level = r->in.level;
5167 q.in.info = r->in.info;
5169 return _samr_SetUserInfo(p, &q);
5172 /*********************************************************************
5173 _samr_GetAliasMembership
5174 *********************************************************************/
5176 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
5177 struct samr_GetAliasMembership *r)
5179 size_t num_alias_rids;
5180 uint32 *alias_rids;
5181 struct samr_domain_info *dinfo;
5182 size_t i;
5184 NTSTATUS status;
5186 DOM_SID *members;
5188 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5190 dinfo = policy_handle_find(p, r->in.domain_handle,
5191 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5192 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5193 struct samr_domain_info, &status);
5194 if (!NT_STATUS_IS_OK(status)) {
5195 return status;
5198 if (!sid_check_is_domain(&dinfo->sid) &&
5199 !sid_check_is_builtin(&dinfo->sid))
5200 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5202 if (r->in.sids->num_sids) {
5203 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
5205 if (members == NULL)
5206 return NT_STATUS_NO_MEMORY;
5207 } else {
5208 members = NULL;
5211 for (i=0; i<r->in.sids->num_sids; i++)
5212 sid_copy(&members[i], r->in.sids->sids[i].sid);
5214 alias_rids = NULL;
5215 num_alias_rids = 0;
5217 become_root();
5218 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5219 r->in.sids->num_sids,
5220 &alias_rids, &num_alias_rids);
5221 unbecome_root();
5223 if (!NT_STATUS_IS_OK(status)) {
5224 return status;
5227 r->out.rids->count = num_alias_rids;
5228 r->out.rids->ids = alias_rids;
5230 return NT_STATUS_OK;
5233 /*********************************************************************
5234 _samr_GetMembersInAlias
5235 *********************************************************************/
5237 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5238 struct samr_GetMembersInAlias *r)
5240 struct samr_alias_info *ainfo;
5241 NTSTATUS status;
5242 size_t i;
5243 size_t num_sids = 0;
5244 struct lsa_SidPtr *sids = NULL;
5245 DOM_SID *pdb_sids = NULL;
5247 ainfo = policy_handle_find(p, r->in.alias_handle,
5248 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5249 struct samr_alias_info, &status);
5250 if (!NT_STATUS_IS_OK(status)) {
5251 return status;
5254 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5256 become_root();
5257 status = pdb_enum_aliasmem(&ainfo->sid, &pdb_sids, &num_sids);
5258 unbecome_root();
5260 if (!NT_STATUS_IS_OK(status)) {
5261 return status;
5264 if (num_sids) {
5265 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5266 if (sids == NULL) {
5267 TALLOC_FREE(pdb_sids);
5268 return NT_STATUS_NO_MEMORY;
5272 for (i = 0; i < num_sids; i++) {
5273 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5274 if (!sids[i].sid) {
5275 TALLOC_FREE(pdb_sids);
5276 return NT_STATUS_NO_MEMORY;
5280 r->out.sids->num_sids = num_sids;
5281 r->out.sids->sids = sids;
5283 TALLOC_FREE(pdb_sids);
5285 return NT_STATUS_OK;
5288 /*********************************************************************
5289 _samr_QueryGroupMember
5290 *********************************************************************/
5292 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5293 struct samr_QueryGroupMember *r)
5295 struct samr_group_info *ginfo;
5296 size_t i, num_members;
5298 uint32 *rid=NULL;
5299 uint32 *attr=NULL;
5301 NTSTATUS status;
5302 struct samr_RidTypeArray *rids = NULL;
5304 ginfo = policy_handle_find(p, r->in.group_handle,
5305 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5306 struct samr_group_info, &status);
5307 if (!NT_STATUS_IS_OK(status)) {
5308 return status;
5311 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5312 if (!rids) {
5313 return NT_STATUS_NO_MEMORY;
5316 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5318 if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5319 DEBUG(3, ("sid %s is not in our domain\n",
5320 sid_string_dbg(&ginfo->sid)));
5321 return NT_STATUS_NO_SUCH_GROUP;
5324 DEBUG(10, ("lookup on Domain SID\n"));
5326 become_root();
5327 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5328 &rid, &num_members);
5329 unbecome_root();
5331 if (!NT_STATUS_IS_OK(status))
5332 return status;
5334 if (num_members) {
5335 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5336 if (attr == NULL) {
5337 return NT_STATUS_NO_MEMORY;
5339 } else {
5340 attr = NULL;
5343 for (i=0; i<num_members; i++)
5344 attr[i] = SID_NAME_USER;
5346 rids->count = num_members;
5347 rids->types = attr;
5348 rids->rids = rid;
5350 *r->out.rids = rids;
5352 return NT_STATUS_OK;
5355 /*********************************************************************
5356 _samr_AddAliasMember
5357 *********************************************************************/
5359 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5360 struct samr_AddAliasMember *r)
5362 struct samr_alias_info *ainfo;
5363 NTSTATUS status;
5365 ainfo = policy_handle_find(p, r->in.alias_handle,
5366 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5367 struct samr_alias_info, &status);
5368 if (!NT_STATUS_IS_OK(status)) {
5369 return status;
5372 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5374 /******** BEGIN SeAddUsers BLOCK *********/
5376 become_root();
5377 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5378 unbecome_root();
5380 /******** END SeAddUsers BLOCK *********/
5382 if (NT_STATUS_IS_OK(status)) {
5383 force_flush_samr_cache(&ainfo->sid);
5386 return status;
5389 /*********************************************************************
5390 _samr_DeleteAliasMember
5391 *********************************************************************/
5393 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5394 struct samr_DeleteAliasMember *r)
5396 struct samr_alias_info *ainfo;
5397 NTSTATUS status;
5399 ainfo = policy_handle_find(p, r->in.alias_handle,
5400 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5401 struct samr_alias_info, &status);
5402 if (!NT_STATUS_IS_OK(status)) {
5403 return status;
5406 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5407 sid_string_dbg(&ainfo->sid)));
5409 /******** BEGIN SeAddUsers BLOCK *********/
5411 become_root();
5412 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5413 unbecome_root();
5415 /******** END SeAddUsers BLOCK *********/
5417 if (NT_STATUS_IS_OK(status)) {
5418 force_flush_samr_cache(&ainfo->sid);
5421 return status;
5424 /*********************************************************************
5425 _samr_AddGroupMember
5426 *********************************************************************/
5428 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5429 struct samr_AddGroupMember *r)
5431 struct samr_group_info *ginfo;
5432 NTSTATUS status;
5433 uint32 group_rid;
5435 ginfo = policy_handle_find(p, r->in.group_handle,
5436 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5437 struct samr_group_info, &status);
5438 if (!NT_STATUS_IS_OK(status)) {
5439 return status;
5442 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5444 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5445 &group_rid)) {
5446 return NT_STATUS_INVALID_HANDLE;
5449 /******** BEGIN SeAddUsers BLOCK *********/
5451 become_root();
5452 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5453 unbecome_root();
5455 /******** END SeAddUsers BLOCK *********/
5457 force_flush_samr_cache(&ginfo->sid);
5459 return status;
5462 /*********************************************************************
5463 _samr_DeleteGroupMember
5464 *********************************************************************/
5466 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5467 struct samr_DeleteGroupMember *r)
5470 struct samr_group_info *ginfo;
5471 NTSTATUS status;
5472 uint32 group_rid;
5475 * delete the group member named r->in.rid
5476 * who is a member of the sid associated with the handle
5477 * the rid is a user's rid as the group is a domain group.
5480 ginfo = policy_handle_find(p, r->in.group_handle,
5481 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5482 struct samr_group_info, &status);
5483 if (!NT_STATUS_IS_OK(status)) {
5484 return status;
5487 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5488 &group_rid)) {
5489 return NT_STATUS_INVALID_HANDLE;
5492 /******** BEGIN SeAddUsers BLOCK *********/
5494 become_root();
5495 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5496 unbecome_root();
5498 /******** END SeAddUsers BLOCK *********/
5500 force_flush_samr_cache(&ginfo->sid);
5502 return status;
5505 /*********************************************************************
5506 _samr_DeleteUser
5507 *********************************************************************/
5509 NTSTATUS _samr_DeleteUser(pipes_struct *p,
5510 struct samr_DeleteUser *r)
5512 struct samr_user_info *uinfo;
5513 NTSTATUS status;
5514 struct samu *sam_pass=NULL;
5515 bool ret;
5517 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5519 uinfo = policy_handle_find(p, r->in.user_handle,
5520 STD_RIGHT_DELETE_ACCESS, NULL,
5521 struct samr_user_info, &status);
5522 if (!NT_STATUS_IS_OK(status)) {
5523 return status;
5526 if (!sid_check_is_in_our_domain(&uinfo->sid))
5527 return NT_STATUS_CANNOT_DELETE;
5529 /* check if the user exists before trying to delete */
5530 if ( !(sam_pass = samu_new( NULL )) ) {
5531 return NT_STATUS_NO_MEMORY;
5534 become_root();
5535 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5536 unbecome_root();
5538 if(!ret) {
5539 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5540 sid_string_dbg(&uinfo->sid)));
5541 TALLOC_FREE(sam_pass);
5542 return NT_STATUS_NO_SUCH_USER;
5545 /******** BEGIN SeAddUsers BLOCK *********/
5547 become_root();
5548 status = pdb_delete_user(p->mem_ctx, sam_pass);
5549 unbecome_root();
5551 /******** END SeAddUsers BLOCK *********/
5553 if ( !NT_STATUS_IS_OK(status) ) {
5554 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5555 "user %s: %s.\n", pdb_get_username(sam_pass),
5556 nt_errstr(status)));
5557 TALLOC_FREE(sam_pass);
5558 return status;
5562 TALLOC_FREE(sam_pass);
5564 if (!close_policy_hnd(p, r->in.user_handle))
5565 return NT_STATUS_OBJECT_NAME_INVALID;
5567 ZERO_STRUCTP(r->out.user_handle);
5569 force_flush_samr_cache(&uinfo->sid);
5571 return NT_STATUS_OK;
5574 /*********************************************************************
5575 _samr_DeleteDomainGroup
5576 *********************************************************************/
5578 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5579 struct samr_DeleteDomainGroup *r)
5581 struct samr_group_info *ginfo;
5582 NTSTATUS status;
5583 uint32 group_rid;
5585 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5587 ginfo = policy_handle_find(p, r->in.group_handle,
5588 STD_RIGHT_DELETE_ACCESS, NULL,
5589 struct samr_group_info, &status);
5590 if (!NT_STATUS_IS_OK(status)) {
5591 return status;
5594 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5596 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5597 &group_rid)) {
5598 return NT_STATUS_NO_SUCH_GROUP;
5601 /******** BEGIN SeAddUsers BLOCK *********/
5603 become_root();
5604 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5605 unbecome_root();
5607 /******** END SeAddUsers BLOCK *********/
5609 if ( !NT_STATUS_IS_OK(status) ) {
5610 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5611 "entry for group %s: %s\n",
5612 sid_string_dbg(&ginfo->sid),
5613 nt_errstr(status)));
5614 return status;
5617 if (!close_policy_hnd(p, r->in.group_handle))
5618 return NT_STATUS_OBJECT_NAME_INVALID;
5620 force_flush_samr_cache(&ginfo->sid);
5622 return NT_STATUS_OK;
5625 /*********************************************************************
5626 _samr_DeleteDomAlias
5627 *********************************************************************/
5629 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5630 struct samr_DeleteDomAlias *r)
5632 struct samr_alias_info *ainfo;
5633 NTSTATUS status;
5635 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5637 ainfo = policy_handle_find(p, r->in.alias_handle,
5638 STD_RIGHT_DELETE_ACCESS, NULL,
5639 struct samr_alias_info, &status);
5640 if (!NT_STATUS_IS_OK(status)) {
5641 return status;
5644 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5646 /* Don't let Windows delete builtin groups */
5648 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5649 return NT_STATUS_SPECIAL_ACCOUNT;
5652 if (!sid_check_is_in_our_domain(&ainfo->sid))
5653 return NT_STATUS_NO_SUCH_ALIAS;
5655 DEBUG(10, ("lookup on Local SID\n"));
5657 /******** BEGIN SeAddUsers BLOCK *********/
5659 become_root();
5660 /* Have passdb delete the alias */
5661 status = pdb_delete_alias(&ainfo->sid);
5662 unbecome_root();
5664 /******** END SeAddUsers BLOCK *********/
5666 if ( !NT_STATUS_IS_OK(status))
5667 return status;
5669 if (!close_policy_hnd(p, r->in.alias_handle))
5670 return NT_STATUS_OBJECT_NAME_INVALID;
5672 force_flush_samr_cache(&ainfo->sid);
5674 return NT_STATUS_OK;
5677 /*********************************************************************
5678 _samr_CreateDomainGroup
5679 *********************************************************************/
5681 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5682 struct samr_CreateDomainGroup *r)
5685 NTSTATUS status;
5686 const char *name;
5687 struct samr_domain_info *dinfo;
5688 struct samr_group_info *ginfo;
5690 dinfo = policy_handle_find(p, r->in.domain_handle,
5691 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5692 struct samr_domain_info, &status);
5693 if (!NT_STATUS_IS_OK(status)) {
5694 return status;
5697 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5698 return NT_STATUS_ACCESS_DENIED;
5700 name = r->in.name->string;
5701 if (name == NULL) {
5702 return NT_STATUS_NO_MEMORY;
5705 status = can_create(p->mem_ctx, name);
5706 if (!NT_STATUS_IS_OK(status)) {
5707 return status;
5710 /******** BEGIN SeAddUsers BLOCK *********/
5712 become_root();
5713 /* check that we successfully create the UNIX group */
5714 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5715 unbecome_root();
5717 /******** END SeAddUsers BLOCK *********/
5719 /* check if we should bail out here */
5721 if ( !NT_STATUS_IS_OK(status) )
5722 return status;
5724 ginfo = policy_handle_create(p, r->out.group_handle,
5725 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5726 struct samr_group_info, &status);
5727 if (!NT_STATUS_IS_OK(status)) {
5728 return status;
5730 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5732 force_flush_samr_cache(&dinfo->sid);
5734 return NT_STATUS_OK;
5737 /*********************************************************************
5738 _samr_CreateDomAlias
5739 *********************************************************************/
5741 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5742 struct samr_CreateDomAlias *r)
5744 DOM_SID info_sid;
5745 const char *name = NULL;
5746 struct samr_domain_info *dinfo;
5747 struct samr_alias_info *ainfo;
5748 gid_t gid;
5749 NTSTATUS result;
5751 dinfo = policy_handle_find(p, r->in.domain_handle,
5752 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5753 struct samr_domain_info, &result);
5754 if (!NT_STATUS_IS_OK(result)) {
5755 return result;
5758 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5759 return NT_STATUS_ACCESS_DENIED;
5761 name = r->in.alias_name->string;
5763 result = can_create(p->mem_ctx, name);
5764 if (!NT_STATUS_IS_OK(result)) {
5765 return result;
5768 /******** BEGIN SeAddUsers BLOCK *********/
5770 become_root();
5771 /* Have passdb create the alias */
5772 result = pdb_create_alias(name, r->out.rid);
5773 unbecome_root();
5775 /******** END SeAddUsers BLOCK *********/
5777 if (!NT_STATUS_IS_OK(result)) {
5778 DEBUG(10, ("pdb_create_alias failed: %s\n",
5779 nt_errstr(result)));
5780 return result;
5783 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5785 if (!sid_to_gid(&info_sid, &gid)) {
5786 DEBUG(10, ("Could not find alias just created\n"));
5787 return NT_STATUS_ACCESS_DENIED;
5790 /* check if the group has been successfully created */
5791 if ( getgrgid(gid) == NULL ) {
5792 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5793 (unsigned int)gid));
5794 return NT_STATUS_ACCESS_DENIED;
5797 ainfo = policy_handle_create(p, r->out.alias_handle,
5798 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5799 struct samr_alias_info, &result);
5800 if (!NT_STATUS_IS_OK(result)) {
5801 return result;
5803 ainfo->sid = info_sid;
5805 force_flush_samr_cache(&info_sid);
5807 return NT_STATUS_OK;
5810 /*********************************************************************
5811 _samr_QueryGroupInfo
5812 *********************************************************************/
5814 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5815 struct samr_QueryGroupInfo *r)
5817 struct samr_group_info *ginfo;
5818 NTSTATUS status;
5819 GROUP_MAP map;
5820 union samr_GroupInfo *info = NULL;
5821 bool ret;
5822 uint32_t attributes = SE_GROUP_MANDATORY |
5823 SE_GROUP_ENABLED_BY_DEFAULT |
5824 SE_GROUP_ENABLED;
5825 const char *group_name = NULL;
5826 const char *group_description = NULL;
5828 ginfo = policy_handle_find(p, r->in.group_handle,
5829 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5830 struct samr_group_info, &status);
5831 if (!NT_STATUS_IS_OK(status)) {
5832 return status;
5835 become_root();
5836 ret = get_domain_group_from_sid(ginfo->sid, &map);
5837 unbecome_root();
5838 if (!ret)
5839 return NT_STATUS_INVALID_HANDLE;
5841 /* FIXME: map contains fstrings */
5842 group_name = talloc_strdup(r, map.nt_name);
5843 group_description = talloc_strdup(r, map.comment);
5845 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5846 if (!info) {
5847 return NT_STATUS_NO_MEMORY;
5850 switch (r->in.level) {
5851 case 1: {
5852 uint32 *members;
5853 size_t num_members;
5855 become_root();
5856 status = pdb_enum_group_members(
5857 p->mem_ctx, &ginfo->sid, &members,
5858 &num_members);
5859 unbecome_root();
5861 if (!NT_STATUS_IS_OK(status)) {
5862 return status;
5865 info->all.name.string = group_name;
5866 info->all.attributes = attributes;
5867 info->all.num_members = num_members;
5868 info->all.description.string = group_description;
5869 break;
5871 case 2:
5872 info->name.string = group_name;
5873 break;
5874 case 3:
5875 info->attributes.attributes = attributes;
5876 break;
5877 case 4:
5878 info->description.string = group_description;
5879 break;
5880 case 5: {
5882 uint32 *members;
5883 size_t num_members;
5887 become_root();
5888 status = pdb_enum_group_members(
5889 p->mem_ctx, &ginfo->sid, &members,
5890 &num_members);
5891 unbecome_root();
5893 if (!NT_STATUS_IS_OK(status)) {
5894 return status;
5897 info->all2.name.string = group_name;
5898 info->all2.attributes = attributes;
5899 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5900 info->all2.description.string = group_description;
5902 break;
5904 default:
5905 return NT_STATUS_INVALID_INFO_CLASS;
5908 *r->out.info = info;
5910 return NT_STATUS_OK;
5913 /*********************************************************************
5914 _samr_SetGroupInfo
5915 *********************************************************************/
5917 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5918 struct samr_SetGroupInfo *r)
5920 struct samr_group_info *ginfo;
5921 GROUP_MAP map;
5922 NTSTATUS status;
5923 bool ret;
5925 ginfo = policy_handle_find(p, r->in.group_handle,
5926 SAMR_GROUP_ACCESS_SET_INFO, NULL,
5927 struct samr_group_info, &status);
5928 if (!NT_STATUS_IS_OK(status)) {
5929 return status;
5932 become_root();
5933 ret = get_domain_group_from_sid(ginfo->sid, &map);
5934 unbecome_root();
5935 if (!ret)
5936 return NT_STATUS_NO_SUCH_GROUP;
5938 switch (r->in.level) {
5939 case 1:
5940 fstrcpy(map.comment, r->in.info->all.description.string);
5941 break;
5942 case 2:
5943 /* group rename is not supported yet */
5944 return NT_STATUS_NOT_SUPPORTED;
5945 case 4:
5946 fstrcpy(map.comment, r->in.info->description.string);
5947 break;
5948 default:
5949 return NT_STATUS_INVALID_INFO_CLASS;
5952 /******** BEGIN SeAddUsers BLOCK *********/
5954 become_root();
5955 status = pdb_update_group_mapping_entry(&map);
5956 unbecome_root();
5958 /******** End SeAddUsers BLOCK *********/
5960 if (NT_STATUS_IS_OK(status)) {
5961 force_flush_samr_cache(&ginfo->sid);
5964 return status;
5967 /*********************************************************************
5968 _samr_SetAliasInfo
5969 *********************************************************************/
5971 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5972 struct samr_SetAliasInfo *r)
5974 struct samr_alias_info *ainfo;
5975 struct acct_info info;
5976 NTSTATUS status;
5978 ainfo = policy_handle_find(p, r->in.alias_handle,
5979 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
5980 struct samr_alias_info, &status);
5981 if (!NT_STATUS_IS_OK(status)) {
5982 return status;
5985 /* get the current group information */
5987 become_root();
5988 status = pdb_get_aliasinfo( &ainfo->sid, &info );
5989 unbecome_root();
5991 if ( !NT_STATUS_IS_OK(status))
5992 return status;
5994 switch (r->in.level) {
5995 case ALIASINFONAME:
5997 fstring group_name;
5999 /* We currently do not support renaming groups in the
6000 the BUILTIN domain. Refer to util_builtin.c to understand
6001 why. The eventually needs to be fixed to be like Windows
6002 where you can rename builtin groups, just not delete them */
6004 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6005 return NT_STATUS_SPECIAL_ACCOUNT;
6008 /* There has to be a valid name (and it has to be different) */
6010 if ( !r->in.info->name.string )
6011 return NT_STATUS_INVALID_PARAMETER;
6013 /* If the name is the same just reply "ok". Yes this
6014 doesn't allow you to change the case of a group name. */
6016 if ( strequal( r->in.info->name.string, info.acct_name ) )
6017 return NT_STATUS_OK;
6019 fstrcpy( info.acct_name, r->in.info->name.string);
6021 /* make sure the name doesn't already exist as a user
6022 or local group */
6024 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6025 status = can_create( p->mem_ctx, group_name );
6026 if ( !NT_STATUS_IS_OK( status ) )
6027 return status;
6028 break;
6030 case ALIASINFODESCRIPTION:
6031 if (r->in.info->description.string) {
6032 fstrcpy(info.acct_desc,
6033 r->in.info->description.string);
6034 } else {
6035 fstrcpy( info.acct_desc, "" );
6037 break;
6038 default:
6039 return NT_STATUS_INVALID_INFO_CLASS;
6042 /******** BEGIN SeAddUsers BLOCK *********/
6044 become_root();
6045 status = pdb_set_aliasinfo( &ainfo->sid, &info );
6046 unbecome_root();
6048 /******** End SeAddUsers BLOCK *********/
6050 if (NT_STATUS_IS_OK(status))
6051 force_flush_samr_cache(&ainfo->sid);
6053 return status;
6056 /****************************************************************
6057 _samr_GetDomPwInfo
6058 ****************************************************************/
6060 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
6061 struct samr_GetDomPwInfo *r)
6063 uint32_t min_password_length = 0;
6064 uint32_t password_properties = 0;
6066 /* Perform access check. Since this rpc does not require a
6067 policy handle it will not be caught by the access checks on
6068 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6070 if (!pipe_access_check(p)) {
6071 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6072 return NT_STATUS_ACCESS_DENIED;
6075 become_root();
6076 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
6077 &min_password_length);
6078 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
6079 &password_properties);
6080 unbecome_root();
6082 if (lp_check_password_script() && *lp_check_password_script()) {
6083 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6086 r->out.info->min_password_length = min_password_length;
6087 r->out.info->password_properties = password_properties;
6089 return NT_STATUS_OK;
6092 /*********************************************************************
6093 _samr_OpenGroup
6094 *********************************************************************/
6096 NTSTATUS _samr_OpenGroup(pipes_struct *p,
6097 struct samr_OpenGroup *r)
6100 DOM_SID info_sid;
6101 GROUP_MAP map;
6102 struct samr_domain_info *dinfo;
6103 struct samr_group_info *ginfo;
6104 SEC_DESC *psd = NULL;
6105 uint32 acc_granted;
6106 uint32 des_access = r->in.access_mask;
6107 size_t sd_size;
6108 NTSTATUS status;
6109 bool ret;
6110 SE_PRIV se_rights;
6112 dinfo = policy_handle_find(p, r->in.domain_handle,
6113 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6114 struct samr_domain_info, &status);
6115 if (!NT_STATUS_IS_OK(status)) {
6116 return status;
6119 /*check if access can be granted as requested by client. */
6120 map_max_allowed_access(p->server_info->ptok, &des_access);
6122 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6123 se_map_generic(&des_access,&grp_generic_mapping);
6125 se_priv_copy( &se_rights, &se_add_users );
6127 status = access_check_samr_object(psd, p->server_info->ptok,
6128 &se_rights, SAMR_GROUP_ACCESS_ADD_MEMBER,
6129 des_access, &acc_granted, "_samr_OpenGroup");
6131 if ( !NT_STATUS_IS_OK(status) )
6132 return status;
6134 /* this should not be hard-coded like this */
6136 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
6137 return NT_STATUS_ACCESS_DENIED;
6139 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6141 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6142 sid_string_dbg(&info_sid)));
6144 /* check if that group really exists */
6145 become_root();
6146 ret = get_domain_group_from_sid(info_sid, &map);
6147 unbecome_root();
6148 if (!ret)
6149 return NT_STATUS_NO_SUCH_GROUP;
6151 ginfo = policy_handle_create(p, r->out.group_handle,
6152 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6153 struct samr_group_info, &status);
6154 if (!NT_STATUS_IS_OK(status)) {
6155 return status;
6157 ginfo->sid = info_sid;
6159 return NT_STATUS_OK;
6162 /*********************************************************************
6163 _samr_RemoveMemberFromForeignDomain
6164 *********************************************************************/
6166 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6167 struct samr_RemoveMemberFromForeignDomain *r)
6169 struct samr_domain_info *dinfo;
6170 NTSTATUS result;
6172 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6173 sid_string_dbg(r->in.sid)));
6175 /* Find the policy handle. Open a policy on it. */
6177 dinfo = policy_handle_find(p, r->in.domain_handle,
6178 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6179 struct samr_domain_info, &result);
6180 if (!NT_STATUS_IS_OK(result)) {
6181 return result;
6184 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6185 sid_string_dbg(&dinfo->sid)));
6187 /* we can only delete a user from a group since we don't have
6188 nested groups anyways. So in the latter case, just say OK */
6190 /* TODO: The above comment nowadays is bogus. Since we have nested
6191 * groups now, and aliases members are never reported out of the unix
6192 * group membership, the "just say OK" makes this call a no-op. For
6193 * us. This needs fixing however. */
6195 /* I've only ever seen this in the wild when deleting a user from
6196 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6197 * is the user about to be deleted. I very much suspect this is the
6198 * only application of this call. To verify this, let people report
6199 * other cases. */
6201 if (!sid_check_is_builtin(&dinfo->sid)) {
6202 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6203 "global_sam_sid() = %s\n",
6204 sid_string_dbg(&dinfo->sid),
6205 sid_string_dbg(get_global_sam_sid())));
6206 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6207 return NT_STATUS_OK;
6210 force_flush_samr_cache(&dinfo->sid);
6212 result = NT_STATUS_OK;
6214 return result;
6217 /*******************************************************************
6218 _samr_QueryDomainInfo2
6219 ********************************************************************/
6221 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6222 struct samr_QueryDomainInfo2 *r)
6224 struct samr_QueryDomainInfo q;
6226 q.in.domain_handle = r->in.domain_handle;
6227 q.in.level = r->in.level;
6229 q.out.info = r->out.info;
6231 return _samr_QueryDomainInfo(p, &q);
6234 /*******************************************************************
6235 _samr_SetDomainInfo
6236 ********************************************************************/
6238 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6239 struct samr_SetDomainInfo *r)
6241 struct samr_domain_info *dinfo;
6242 time_t u_expire, u_min_age;
6243 time_t u_logout;
6244 time_t u_lock_duration, u_reset_time;
6245 NTSTATUS result;
6246 uint32_t acc_required = 0;
6248 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6250 switch (r->in.level) {
6251 case 1: /* DomainPasswordInformation */
6252 case 12: /* DomainLockoutInformation */
6253 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6254 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6255 break;
6256 case 3: /* DomainLogoffInformation */
6257 case 4: /* DomainOemInformation */
6258 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6259 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6260 break;
6261 case 6: /* DomainReplicationInformation */
6262 case 9: /* DomainStateInformation */
6263 case 7: /* DomainServerRoleInformation */
6264 /* DOMAIN_ADMINISTER_SERVER */
6265 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6266 break;
6267 default:
6268 return NT_STATUS_INVALID_INFO_CLASS;
6271 dinfo = policy_handle_find(p, r->in.domain_handle,
6272 acc_required, NULL,
6273 struct samr_domain_info, &result);
6274 if (!NT_STATUS_IS_OK(result)) {
6275 return result;
6278 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6280 switch (r->in.level) {
6281 case 1:
6282 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
6283 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
6284 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
6285 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
6286 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
6287 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
6288 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
6289 break;
6290 case 3:
6291 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
6292 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
6293 break;
6294 case 4:
6295 break;
6296 case 6:
6297 break;
6298 case 7:
6299 break;
6300 case 9:
6301 break;
6302 case 12:
6303 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
6304 if (u_lock_duration != -1)
6305 u_lock_duration /= 60;
6307 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
6309 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6310 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
6311 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
6312 break;
6313 default:
6314 return NT_STATUS_INVALID_INFO_CLASS;
6317 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6319 return NT_STATUS_OK;
6322 /****************************************************************
6323 _samr_GetDisplayEnumerationIndex
6324 ****************************************************************/
6326 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6327 struct samr_GetDisplayEnumerationIndex *r)
6329 struct samr_domain_info *dinfo;
6330 uint32_t max_entries = (uint32_t) -1;
6331 uint32_t enum_context = 0;
6332 int i;
6333 uint32_t num_account = 0;
6334 struct samr_displayentry *entries = NULL;
6335 NTSTATUS status;
6337 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6339 dinfo = policy_handle_find(p, r->in.domain_handle,
6340 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6341 struct samr_domain_info, &status);
6342 if (!NT_STATUS_IS_OK(status)) {
6343 return status;
6346 if ((r->in.level < 1) || (r->in.level > 3)) {
6347 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6348 "Unknown info level (%u)\n",
6349 r->in.level));
6350 return NT_STATUS_INVALID_INFO_CLASS;
6353 become_root();
6355 /* The following done as ROOT. Don't return without unbecome_root(). */
6357 switch (r->in.level) {
6358 case 1:
6359 if (dinfo->disp_info->users == NULL) {
6360 dinfo->disp_info->users = pdb_search_users(
6361 dinfo->disp_info, ACB_NORMAL);
6362 if (dinfo->disp_info->users == NULL) {
6363 unbecome_root();
6364 return NT_STATUS_ACCESS_DENIED;
6366 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6367 "starting user enumeration at index %u\n",
6368 (unsigned int)enum_context));
6369 } else {
6370 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6371 "using cached user enumeration at index %u\n",
6372 (unsigned int)enum_context));
6374 num_account = pdb_search_entries(dinfo->disp_info->users,
6375 enum_context, max_entries,
6376 &entries);
6377 break;
6378 case 2:
6379 if (dinfo->disp_info->machines == NULL) {
6380 dinfo->disp_info->machines = pdb_search_users(
6381 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6382 if (dinfo->disp_info->machines == NULL) {
6383 unbecome_root();
6384 return NT_STATUS_ACCESS_DENIED;
6386 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6387 "starting machine enumeration at index %u\n",
6388 (unsigned int)enum_context));
6389 } else {
6390 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6391 "using cached machine enumeration at index %u\n",
6392 (unsigned int)enum_context));
6394 num_account = pdb_search_entries(dinfo->disp_info->machines,
6395 enum_context, max_entries,
6396 &entries);
6397 break;
6398 case 3:
6399 if (dinfo->disp_info->groups == NULL) {
6400 dinfo->disp_info->groups = pdb_search_groups(
6401 dinfo->disp_info);
6402 if (dinfo->disp_info->groups == NULL) {
6403 unbecome_root();
6404 return NT_STATUS_ACCESS_DENIED;
6406 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6407 "starting group enumeration at index %u\n",
6408 (unsigned int)enum_context));
6409 } else {
6410 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6411 "using cached group enumeration at index %u\n",
6412 (unsigned int)enum_context));
6414 num_account = pdb_search_entries(dinfo->disp_info->groups,
6415 enum_context, max_entries,
6416 &entries);
6417 break;
6418 default:
6419 unbecome_root();
6420 smb_panic("info class changed");
6421 break;
6424 unbecome_root();
6426 /* Ensure we cache this enumeration. */
6427 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6429 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6430 r->in.name->string));
6432 for (i=0; i<num_account; i++) {
6433 if (strequal(entries[i].account_name, r->in.name->string)) {
6434 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6435 "found %s at idx %d\n",
6436 r->in.name->string, i));
6437 *r->out.idx = i;
6438 return NT_STATUS_OK;
6442 /* assuming account_name lives at the very end */
6443 *r->out.idx = num_account;
6445 return NT_STATUS_NO_MORE_ENTRIES;
6448 /****************************************************************
6449 _samr_GetDisplayEnumerationIndex2
6450 ****************************************************************/
6452 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6453 struct samr_GetDisplayEnumerationIndex2 *r)
6455 struct samr_GetDisplayEnumerationIndex q;
6457 q.in.domain_handle = r->in.domain_handle;
6458 q.in.level = r->in.level;
6459 q.in.name = r->in.name;
6461 q.out.idx = r->out.idx;
6463 return _samr_GetDisplayEnumerationIndex(p, &q);
6466 /****************************************************************
6467 _samr_RidToSid
6468 ****************************************************************/
6470 NTSTATUS _samr_RidToSid(pipes_struct *p,
6471 struct samr_RidToSid *r)
6473 struct samr_domain_info *dinfo;
6474 NTSTATUS status;
6475 struct dom_sid sid;
6477 dinfo = policy_handle_find(p, r->in.domain_handle,
6478 0, NULL,
6479 struct samr_domain_info, &status);
6480 if (!NT_STATUS_IS_OK(status)) {
6481 return status;
6484 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6485 return NT_STATUS_NO_MEMORY;
6488 *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
6489 if (!*r->out.sid) {
6490 return NT_STATUS_NO_MEMORY;
6493 return NT_STATUS_OK;
6496 /****************************************************************
6497 ****************************************************************/
6499 NTSTATUS _samr_Shutdown(pipes_struct *p,
6500 struct samr_Shutdown *r)
6502 p->rng_fault_state = true;
6503 return NT_STATUS_NOT_IMPLEMENTED;
6506 /****************************************************************
6507 ****************************************************************/
6509 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6510 struct samr_SetMemberAttributesOfGroup *r)
6512 p->rng_fault_state = true;
6513 return NT_STATUS_NOT_IMPLEMENTED;
6516 /****************************************************************
6517 ****************************************************************/
6519 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6520 struct samr_TestPrivateFunctionsDomain *r)
6522 return NT_STATUS_NOT_IMPLEMENTED;
6525 /****************************************************************
6526 ****************************************************************/
6528 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6529 struct samr_TestPrivateFunctionsUser *r)
6531 return NT_STATUS_NOT_IMPLEMENTED;
6534 /****************************************************************
6535 ****************************************************************/
6537 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6538 struct samr_AddMultipleMembersToAlias *r)
6540 p->rng_fault_state = true;
6541 return NT_STATUS_NOT_IMPLEMENTED;
6544 /****************************************************************
6545 ****************************************************************/
6547 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6548 struct samr_RemoveMultipleMembersFromAlias *r)
6550 p->rng_fault_state = true;
6551 return NT_STATUS_NOT_IMPLEMENTED;
6554 /****************************************************************
6555 ****************************************************************/
6557 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6558 struct samr_SetBootKeyInformation *r)
6560 p->rng_fault_state = true;
6561 return NT_STATUS_NOT_IMPLEMENTED;
6564 /****************************************************************
6565 ****************************************************************/
6567 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6568 struct samr_GetBootKeyInformation *r)
6570 p->rng_fault_state = true;
6571 return NT_STATUS_NOT_IMPLEMENTED;
6574 /****************************************************************
6575 ****************************************************************/
6577 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6578 struct samr_SetDsrmPassword *r)
6580 p->rng_fault_state = true;
6581 return NT_STATUS_NOT_IMPLEMENTED;
6584 /****************************************************************
6585 ****************************************************************/
6587 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6588 struct samr_ValidatePassword *r)
6590 p->rng_fault_state = true;
6591 return NT_STATUS_NOT_IMPLEMENTED;