2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
35 #include "../libcli/auth/libcli_auth.h"
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 {
56 struct samr_domain_info {
58 struct disp_info *disp_info;
61 struct samr_user_info {
65 struct samr_group_info {
69 struct samr_alias_info {
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 */
81 struct pdb_search *enum_users; /* enumusers with a mask */
83 struct timed_event *cache_timeout_event; /* cache idle timeout
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 */
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 */
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 */
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;
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,
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
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",
199 /* check the security descriptor first */
201 status = se_access_check(psd, token, des_access, acc_granted);
202 if (NT_STATUS_IS_OK(status)) {
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;
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));
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)) {
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;
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;
263 /* Full access for DOMAIN\Domain Admins. */
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;
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.
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
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) {
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) {
341 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
343 return domain_dispinfo;
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. */
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);
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,
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 "
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)) {
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)
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. */
453 if (info->users == NULL) {
454 info->users = pdb_search_users(info, acct_flags);
455 if (info->users == NULL) {
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. */
477 if (info->groups == NULL) {
478 info->groups = pdb_search_groups(info);
479 if (info->groups == NULL) {
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) {
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 /*******************************************************************
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);
526 /*******************************************************************
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;
537 uint32 des_access = r->in.access_mask;
540 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
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)) {
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
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) )
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)) {
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__));
601 /*******************************************************************
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;
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)) {
624 if (!sid_check_is_in_our_domain(&uinfo->sid)) {
625 return NT_STATUS_OBJECT_TYPE_MISMATCH;
629 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
632 return NT_STATUS_NO_SUCH_USER;
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);
644 if (lp_check_password_script() && *lp_check_password_script()) {
645 password_properties |= DOMAIN_PASSWORD_COMPLEX;
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__));
661 /*******************************************************************
663 ********************************************************************/
665 NTSTATUS _samr_SetSecurity(pipes_struct *p,
666 struct samr_SetSecurity *r)
668 struct samr_user_info *uinfo;
672 struct samu *sampass=NULL;
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)) {
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 */
689 ret = pdb_getsampwsid(sampass, &uinfo->sid);
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) ?
711 TALLOC_FREE(sampass);
712 return NT_STATUS_ACCESS_DENIED;
716 status = pdb_update_sam_account(sampass);
719 TALLOC_FREE(sampass);
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;
732 if ( !(sampass = samu_new( mem_ctx )) ) {
733 DEBUG(0,("No memory!\n"));
738 ret = pdb_getsampwsid(sampass, user_sid);
742 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
743 TALLOC_FREE(sampass);
747 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
749 if (pdb_get_pass_can_change(sampass)) {
750 TALLOC_FREE(sampass);
753 TALLOC_FREE(sampass);
758 /*******************************************************************
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;
771 SEC_DESC * psd = NULL;
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);
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
794 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
795 &dom_generic_mapping, NULL, 0);
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);
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);
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);
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);
856 return NT_STATUS_OBJECT_TYPE_MISMATCH;
858 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
859 return NT_STATUS_NO_MEMORY;
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,
872 struct samr_displayentry *entries)
875 struct samr_SamEntry *sam;
879 if (num_entries == 0) {
883 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
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++) {
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,
899 init_unistr2(&uni_temp_name, entries[i].account_name,
903 init_lsa_String(&sam[i].name, entries[i].account_name);
904 sam[i].idx = entries[i].rid;
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)
922 struct samr_domain_info *dinfo;
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)) {
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"));
948 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
950 return NT_STATUS_NO_MEMORY;
952 *r->out.sam = samr_array;
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 !!!! */
972 return NT_STATUS_ACCESS_DENIED;
975 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
976 enum_context, max_entries,
979 /* END AS ROOT !!!! */
983 if (num_account == 0) {
984 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
986 *r->out.resume_handle = *r->in.resume_handle;
990 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
991 num_account, enum_context,
993 if (!NT_STATUS_IS_OK(status)) {
997 if (max_entries <= num_account) {
998 status = STATUS_MORE_ENTRIES;
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__));
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;
1033 if (num_sam_entries == 0) {
1037 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
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;
1053 /*******************************************************************
1054 _samr_EnumDomainGroups
1055 ********************************************************************/
1057 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1058 struct samr_EnumDomainGroups *r)
1061 struct samr_domain_info *dinfo;
1062 struct samr_displayentry *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)) {
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"));
1083 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1085 return NT_STATUS_NO_MEMORY;
1088 /* the domain group array is being allocated in the function below */
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) {
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);
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__));
1124 /*******************************************************************
1125 _samr_EnumDomainAliases
1126 ********************************************************************/
1128 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1129 struct samr_EnumDomainAliases *r)
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)) {
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);
1150 return NT_STATUS_NO_MEMORY;
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) {
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);
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;
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,
1195 struct samr_displayentry *entries)
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);
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,
1239 struct samr_displayentry *entries)
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);
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,
1280 struct samr_displayentry *entries)
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);
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,
1321 struct samr_displayentry *entries)
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);
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,
1357 struct samr_displayentry *entries)
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);
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)
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)) {
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.
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
1445 * If you want to change it, think twice and think
1446 * of the second point , that's really important.
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,
1462 max_entries = max_sam_entries;
1465 /* calculate the size and limit on the number of entries we will
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));
1478 /* THe following done as ROOT. Don't return without unbecome_root(). */
1480 switch (r->in.level) {
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) {
1488 return NT_STATUS_ACCESS_DENIED;
1490 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1491 (unsigned int)enum_context ));
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,
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) {
1507 return NT_STATUS_ACCESS_DENIED;
1509 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1510 (unsigned int)enum_context ));
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,
1522 if (dinfo->disp_info->groups == NULL) {
1523 dinfo->disp_info->groups = pdb_search_groups(
1525 if (dinfo->disp_info->groups == NULL) {
1527 return NT_STATUS_ACCESS_DENIED;
1529 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1530 (unsigned int)enum_context ));
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,
1542 smb_panic("info class changed");
1548 /* Now create reply structure */
1549 switch (r->in.level) {
1551 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1552 num_account, enum_context,
1556 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1557 num_account, enum_context,
1561 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1562 num_account, enum_context,
1566 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1567 num_account, enum_context,
1571 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1572 num_account, enum_context,
1576 smb_panic("info class changed");
1580 if (!NT_STATUS_IS_OK(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;
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;
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;
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)) {
1670 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1672 return NT_STATUS_NO_MEMORY;
1676 status = pdb_get_aliasinfo(&ainfo->sid, &info);
1679 if ( !NT_STATUS_IS_OK(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) {
1688 alias_info->all.name.string = alias_name;
1689 alias_info->all.num_members = 1; /* ??? */
1690 alias_info->all.description.string = alias_description;
1693 alias_info->name.string = alias_name;
1695 case ALIASINFODESCRIPTION:
1696 alias_info->description.string = alias_description;
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 /*******************************************************************
1711 ********************************************************************/
1713 NTSTATUS _samr_LookupNames(pipes_struct *p,
1714 struct samr_LookupNames *r)
1716 struct samr_domain_info *dinfo;
1719 enum lsa_SidType *type;
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)) {
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,
1759 type[i] = SID_NAME_ALIAS;
1762 lookup_global_sam_name(r->in.names[i].string, 0,
1766 if (type[i] != SID_NAME_UNKNOWN) {
1771 if (num_mapped == num_rids) {
1772 status = NT_STATUS_OK;
1773 } else if (num_mapped == 0) {
1774 status = NT_STATUS_NONE_MAPPED;
1776 status = STATUS_SOME_UNMAPPED;
1779 rids.count = num_rids;
1782 types.count = num_rids;
1785 *r->out.rids = rids;
1786 *r->out.types = types;
1788 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1793 /****************************************************************
1794 _samr_ChangePasswordUser
1795 ****************************************************************/
1797 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1798 struct samr_ChangePasswordUser *r)
1802 struct samr_user_info *uinfo;
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)) {
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;
1822 ret = pdb_getsampwsid(pwd, &uinfo->sid);
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;
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
1851 status = NT_STATUS_INVALID_PARAMETER_MIX;
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;
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;
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;
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;
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;
1897 status = pdb_update_sam_account(pwd);
1904 /*******************************************************************
1905 _samr_ChangePasswordUser2
1906 ********************************************************************/
1908 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1909 struct samr_ChangePasswordUser2 *r)
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
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,
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;
1950 /****************************************************************
1951 _samr_OemChangePasswordUser2
1952 ****************************************************************/
1954 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
1955 struct samr_OemChangePasswordUser2 *r)
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
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,
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__));
2002 /*******************************************************************
2003 _samr_ChangePasswordUser3
2004 ********************************************************************/
2006 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
2007 struct samr_ChangePasswordUser3 *r)
2011 const char *wks = NULL;
2012 uint32 reject_reason;
2013 struct samr_DomInfo1 *dominfo = NULL;
2014 struct samr_ChangeReject *reject = NULL;
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
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,
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);
2056 return NT_STATUS_NO_MEMORY;
2059 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2061 return NT_STATUS_NO_MEMORY;
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;
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__));
2105 /*******************************************************************
2106 makes a SAMR_R_LOOKUP_RIDS structure.
2107 ********************************************************************/
2109 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2111 struct lsa_String **lsa_name_array_p)
2113 struct lsa_String *lsa_name_array = NULL;
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) {
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;
2135 /*******************************************************************
2137 ********************************************************************/
2139 NTSTATUS _samr_LookupRids(pipes_struct *p,
2140 struct samr_LookupRids *r)
2142 struct samr_domain_info *dinfo;
2145 enum lsa_SidType *attrs = NULL;
2146 uint32 *wire_attrs = NULL;
2147 int num_rids = (int)r->in.num_rids;
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)) {
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;
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;
2181 become_root(); /* lookup_sid can require root privs */
2182 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
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,
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__));
2214 /*******************************************************************
2216 ********************************************************************/
2218 NTSTATUS _samr_OpenUser(pipes_struct *p,
2219 struct samr_OpenUser *r)
2221 struct samu *sampass=NULL;
2223 struct samr_domain_info *dinfo;
2224 struct samr_user_info *uinfo;
2225 SEC_DESC *psd = NULL;
2227 uint32 des_access = r->in.access_mask;
2228 uint32_t extra_access = 0;
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)) {
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.
2265 ret=pdb_getsampwsid(sampass, &sid);
2268 se_priv_copy(&se_rights, &se_priv_none);
2271 * We do the override access checks on *open*, not at
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
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,
2294 * SeAddUsers is needed to add
2295 * GENERIC_RIGHTS_USER_WRITE to a normal
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 "
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) )
2330 /* check that the SID exists in our domain. */
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)) {
2345 return NT_STATUS_OK;
2348 /*************************************************************************
2349 *************************************************************************/
2351 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2353 struct lsa_BinaryString **_r)
2355 struct lsa_BinaryString *r;
2358 return NT_STATUS_INVALID_PARAMETER;
2361 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2363 return NT_STATUS_NO_MEMORY;
2366 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2368 return NT_STATUS_NO_MEMORY;
2370 memcpy(r->array, blob->data, blob->length);
2371 r->size = blob->length;
2372 r->length = blob->length;
2375 return NT_STATUS_NO_MEMORY;
2380 return NT_STATUS_OK;
2383 /*************************************************************************
2385 *************************************************************************/
2387 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2388 struct samr_UserInfo1 *r,
2390 DOM_SID *domain_sid)
2392 const DOM_SID *sid_group;
2393 uint32_t primary_gid;
2396 sid_group = pdb_get_group_sid(pw);
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 /*************************************************************************
2418 *************************************************************************/
2420 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2421 struct samr_UserInfo2 *r,
2424 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2425 r->unknown.string = NULL;
2426 r->country_code = 0;
2429 return NT_STATUS_OK;
2432 /*************************************************************************
2434 *************************************************************************/
2436 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2437 struct samr_UserInfo3 *r,
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;
2455 sid_group = pdb_get_group_sid(pw);
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);
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 /*************************************************************************
2492 *************************************************************************/
2494 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2495 struct samr_UserInfo4 *r,
2498 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2500 return NT_STATUS_OK;
2503 /*************************************************************************
2505 *************************************************************************/
2507 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2508 struct samr_UserInfo5 *r,
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;
2526 sid_group = pdb_get_group_sid(pw);
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);
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 /*************************************************************************
2563 *************************************************************************/
2565 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2566 struct samr_UserInfo6 *r,
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 /*************************************************************************
2593 *************************************************************************/
2595 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2596 struct samr_UserInfo8 *r,
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 /*************************************************************************
2619 *************************************************************************/
2621 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2622 struct samr_UserInfo10 *r,
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 /*************************************************************************
2633 *************************************************************************/
2635 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2636 struct samr_UserInfo11 *r,
2639 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2641 return NT_STATUS_OK;
2644 /*************************************************************************
2646 *************************************************************************/
2648 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2649 struct samr_UserInfo12 *r,
2652 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2654 return NT_STATUS_OK;
2657 /*************************************************************************
2659 *************************************************************************/
2661 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2662 struct samr_UserInfo13 *r,
2665 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2667 return NT_STATUS_OK;
2670 /*************************************************************************
2672 *************************************************************************/
2674 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2675 struct samr_UserInfo14 *r,
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 /*************************************************************************
2698 *************************************************************************/
2700 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2701 struct samr_UserInfo17 *r,
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
2713 *************************************************************************/
2715 static NTSTATUS get_user_info_18(pipes_struct *p,
2716 TALLOC_CTX *mem_ctx,
2717 struct samr_UserInfo18 *r,
2720 struct samu *smbpass=NULL;
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);
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 /*************************************************************************
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;
2778 struct lsa_BinaryString *parameters = NULL;
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)));
2788 blob = base64_decode_data_blob(munged_dial);
2790 blob = data_blob_string_const_null("");
2793 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2794 data_blob_free(&blob);
2795 if (!NT_STATUS_IS_OK(status)) {
2799 r->parameters = *parameters;
2801 return NT_STATUS_OK;
2805 /*************************************************************************
2807 *************************************************************************/
2809 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2810 struct samr_UserInfo21 *r,
2812 DOM_SID *domain_sid,
2813 uint32_t acc_granted)
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;
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;
2837 sid_group = pdb_get_group_sid(pw);
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);
2858 unix_to_nt_time(&force_password_change, must_change_time);
2861 munged_dial = pdb_get_munged_dial(pw);
2863 blob = base64_decode_data_blob(munged_dial);
2865 blob = data_blob_string_const_null("");
2868 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2869 data_blob_free(&blob);
2870 if (!NT_STATUS_IS_OK(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;
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;
2898 r->lm_password_set = 0;
2899 r->nt_password_set = 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
2916 return NT_STATUS_OK;
2919 /*******************************************************************
2921 ********************************************************************/
2923 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2924 struct samr_QueryUserInfo *r)
2927 union samr_UserInfo *user_info = NULL;
2928 struct samr_user_info *uinfo;
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;
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;
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;
2952 case 4: /* UserLogonHoursInformation */
2953 /* USER_READ_LOGON */
2954 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
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;
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;
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;
2978 case 16: /* UserControlInformation */
2979 case 17: /* UserExpiresInformation */
2980 case 20: /* UserParametersInformation */
2981 /* USER_READ_ACCOUNT */
2982 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2984 case 21: /* UserAllInformation */
2986 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2988 case 18: /* UserInternal1Information */
2990 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2992 case 23: /* UserInternal4Information */
2993 case 24: /* UserInternal4InformationNew */
2994 case 25: /* UserInternal4InformationNew */
2995 case 26: /* UserInternal5InformationNew */
2997 return NT_STATUS_INVALID_INFO_CLASS;
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)) {
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);
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;
3030 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3034 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
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) {
3045 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3048 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3051 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3054 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3057 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3060 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3063 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3066 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3069 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3072 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3075 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3078 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3081 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3084 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3087 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3090 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3093 /* level 18 is special */
3094 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3098 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3101 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3104 status = NT_STATUS_INVALID_INFO_CLASS;
3108 if (!NT_STATUS_IS_OK(status)) {
3112 *r->out.info = user_info;
3117 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
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;
3147 struct samr_RidWithAttribute dom_gid;
3148 struct samr_RidWithAttribute *gids = NULL;
3149 uint32 primary_group_rid;
3150 size_t num_groups = 0;
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
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)) {
3180 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
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;
3193 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3197 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3198 sid_string_dbg(&uinfo->sid)));
3199 return NT_STATUS_NO_SUCH_USER;
3204 /* make both calls inside the root block */
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);
3215 if (!NT_STATUS_IS_OK(result)) {
3216 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",