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 "smbd/globals.h"
36 #include "../libcli/auth/libcli_auth.h"
37 #include "../librpc/gen_ndr/srv_samr.h"
38 #include "rpc_server/srv_samr_util.h"
39 #include "../lib/crypto/arcfour.h"
41 #include "rpc_client/init_lsa.h"
44 #define DBGC_CLASS DBGC_RPC_SRV
46 #define SAMR_USR_RIGHTS_WRITE_PW \
47 ( READ_CONTROL_ACCESS | \
48 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
49 SAMR_USER_ACCESS_SET_LOC_COM)
50 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
51 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
53 #define DISP_INFO_CACHE_TIMEOUT 10
55 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
56 #define MAX_SAM_ENTRIES_W95 50
58 struct samr_connect_info {
62 struct samr_domain_info {
64 struct disp_info *disp_info;
67 struct samr_user_info {
71 struct samr_group_info {
75 struct samr_alias_info {
79 typedef struct disp_info {
80 struct dom_sid sid; /* identify which domain this is. */
81 struct pdb_search *users; /* querydispinfo 1 and 4 */
82 struct pdb_search *machines; /* querydispinfo 2 */
83 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
84 struct pdb_search *aliases; /* enumaliases */
86 uint32_t enum_acb_mask;
87 struct pdb_search *enum_users; /* enumusers with a mask */
89 struct timed_event *cache_timeout_event; /* cache idle timeout
93 static const struct generic_mapping sam_generic_mapping = {
94 GENERIC_RIGHTS_SAM_READ,
95 GENERIC_RIGHTS_SAM_WRITE,
96 GENERIC_RIGHTS_SAM_EXECUTE,
97 GENERIC_RIGHTS_SAM_ALL_ACCESS};
98 static const struct generic_mapping dom_generic_mapping = {
99 GENERIC_RIGHTS_DOMAIN_READ,
100 GENERIC_RIGHTS_DOMAIN_WRITE,
101 GENERIC_RIGHTS_DOMAIN_EXECUTE,
102 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
103 static const struct generic_mapping usr_generic_mapping = {
104 GENERIC_RIGHTS_USER_READ,
105 GENERIC_RIGHTS_USER_WRITE,
106 GENERIC_RIGHTS_USER_EXECUTE,
107 GENERIC_RIGHTS_USER_ALL_ACCESS};
108 static const struct generic_mapping usr_nopwchange_generic_mapping = {
109 GENERIC_RIGHTS_USER_READ,
110 GENERIC_RIGHTS_USER_WRITE,
111 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
112 GENERIC_RIGHTS_USER_ALL_ACCESS};
113 static const struct generic_mapping grp_generic_mapping = {
114 GENERIC_RIGHTS_GROUP_READ,
115 GENERIC_RIGHTS_GROUP_WRITE,
116 GENERIC_RIGHTS_GROUP_EXECUTE,
117 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
118 static const struct generic_mapping ali_generic_mapping = {
119 GENERIC_RIGHTS_ALIAS_READ,
120 GENERIC_RIGHTS_ALIAS_WRITE,
121 GENERIC_RIGHTS_ALIAS_EXECUTE,
122 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
124 /*******************************************************************
125 *******************************************************************/
127 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
128 const struct generic_mapping *map,
129 struct dom_sid *sid, uint32 sid_access )
131 struct dom_sid domadmin_sid;
132 struct security_ace ace[5]; /* at most 5 entries */
135 struct security_acl *psa = NULL;
137 /* basic access for Everyone */
139 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
140 map->generic_execute | map->generic_read, 0);
142 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
144 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
145 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
146 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
147 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
149 /* Add Full Access for Domain Admins if we are a DC */
152 sid_compose(&domadmin_sid, get_global_sam_sid(),
154 init_sec_ace(&ace[i++], &domadmin_sid,
155 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
158 /* if we have a sid, give it some special access */
161 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
164 /* create the security descriptor */
166 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
167 return NT_STATUS_NO_MEMORY;
169 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
170 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
171 psa, sd_size)) == NULL)
172 return NT_STATUS_NO_MEMORY;
177 /*******************************************************************
178 Checks if access to an object should be granted, and returns that
179 level of access for further checks.
180 ********************************************************************/
182 NTSTATUS access_check_object( struct security_descriptor *psd, NT_USER_TOKEN *token,
183 uint64_t *rights, uint32 rights_mask,
184 uint32 des_access, uint32 *acc_granted,
187 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
188 uint32 saved_mask = 0;
190 /* check privileges; certain SAM access bits should be overridden
191 by privileges (mostly having to do with creating/modifying/deleting
194 if (rights && !se_priv_equal(rights, &se_priv_none) &&
195 user_has_any_privilege(token, rights)) {
197 saved_mask = (des_access & rights_mask);
198 des_access &= ~saved_mask;
200 DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
205 /* check the security descriptor first */
207 status = se_access_check(psd, token, des_access, acc_granted);
208 if (NT_STATUS_IS_OK(status)) {
212 /* give root a free pass */
214 if ( geteuid() == sec_initial_uid() ) {
216 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
217 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
219 *acc_granted = des_access;
221 status = NT_STATUS_OK;
227 /* add in any bits saved during the privilege check (only
228 matters is status is ok) */
230 *acc_granted |= rights_mask;
232 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
233 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
234 des_access, *acc_granted));
240 /*******************************************************************
241 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
242 ********************************************************************/
244 void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
245 const struct unix_user_token *unix_token,
246 uint32_t *pacc_requested)
248 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
251 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
253 /* At least try for generic read|execute - Everyone gets that. */
254 *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
256 /* root gets anything. */
257 if (unix_token->uid == sec_initial_uid()) {
258 *pacc_requested |= GENERIC_ALL_ACCESS;
262 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
264 if (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) ||
265 is_sid_in_token(nt_token, &global_sid_Builtin_Account_Operators)) {
266 *pacc_requested |= GENERIC_ALL_ACCESS;
270 /* Full access for DOMAIN\Domain Admins. */
272 struct dom_sid domadmin_sid;
273 sid_compose(&domadmin_sid, get_global_sam_sid(),
275 if (is_sid_in_token(nt_token, &domadmin_sid)) {
276 *pacc_requested |= GENERIC_ALL_ACCESS;
280 /* TODO ! Check privileges. */
283 /*******************************************************************
284 Fetch or create a dispinfo struct.
285 ********************************************************************/
287 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
290 * We do a static cache for DISP_INFO's here. Explanation can be found
291 * in Jeremy's checkin message to r11793:
293 * Fix the SAMR cache so it works across completely insane
294 * client behaviour (ie.:
295 * open pipe/open SAMR handle/enumerate 0 - 1024
296 * close SAMR handle, close pipe.
297 * open pipe/open SAMR handle/enumerate 1024 - 2048...
298 * close SAMR handle, close pipe.
299 * And on ad-nausium. Amazing.... probably object-oriented
300 * client side programming in action yet again.
301 * This change should *massively* improve performance when
302 * enumerating users from an LDAP database.
305 * "Our" and the builtin domain are the only ones where we ever
306 * enumerate stuff, so just cache 2 entries.
309 static struct disp_info *builtin_dispinfo;
310 static struct disp_info *domain_dispinfo;
312 /* There are two cases to consider here:
313 1) The SID is a domain SID and we look for an equality match, or
314 2) This is an account SID and so we return the DISP_INFO* for our
321 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
323 * Necessary only once, but it does not really hurt.
325 if (builtin_dispinfo == NULL) {
326 builtin_dispinfo = talloc_zero(
327 talloc_autofree_context(), struct disp_info);
328 if (builtin_dispinfo == NULL) {
332 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
334 return builtin_dispinfo;
337 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
339 * Necessary only once, but it does not really hurt.
341 if (domain_dispinfo == NULL) {
342 domain_dispinfo = talloc_zero(
343 talloc_autofree_context(), struct disp_info);
344 if (domain_dispinfo == NULL) {
348 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
350 return domain_dispinfo;
356 /*******************************************************************
357 Function to free the per SID data.
358 ********************************************************************/
360 static void free_samr_cache(DISP_INFO *disp_info)
362 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
363 sid_string_dbg(&disp_info->sid)));
365 /* We need to become root here because the paged search might have to
366 * tell the LDAP server we're not interested in the rest anymore. */
370 TALLOC_FREE(disp_info->users);
371 TALLOC_FREE(disp_info->machines);
372 TALLOC_FREE(disp_info->groups);
373 TALLOC_FREE(disp_info->aliases);
374 TALLOC_FREE(disp_info->enum_users);
379 /*******************************************************************
380 Idle event handler. Throw away the disp info cache.
381 ********************************************************************/
383 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
384 struct timed_event *te,
388 DISP_INFO *disp_info = (DISP_INFO *)private_data;
390 TALLOC_FREE(disp_info->cache_timeout_event);
392 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
394 free_samr_cache(disp_info);
397 /*******************************************************************
398 Setup cache removal idle event handler.
399 ********************************************************************/
401 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
403 /* Remove any pending timeout and update. */
405 TALLOC_FREE(disp_info->cache_timeout_event);
407 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
408 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
409 (unsigned int)secs_fromnow ));
411 disp_info->cache_timeout_event = event_add_timed(
412 server_event_context(), NULL,
413 timeval_current_ofs(secs_fromnow, 0),
414 disp_info_cache_idle_timeout_handler, (void *)disp_info);
417 /*******************************************************************
418 Force flush any cache. We do this on any samr_set_xxx call.
419 We must also remove the timeout handler.
420 ********************************************************************/
422 static void force_flush_samr_cache(const struct dom_sid *sid)
424 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
426 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
430 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
431 TALLOC_FREE(disp_info->cache_timeout_event);
432 free_samr_cache(disp_info);
435 /*******************************************************************
436 Ensure password info is never given out. Paranioa... JRA.
437 ********************************************************************/
439 static void samr_clear_sam_passwd(struct samu *sam_pass)
445 /* These now zero out the old password */
447 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
448 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
451 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
453 struct samr_displayentry *entry;
455 if (sid_check_is_builtin(&info->sid)) {
456 /* No users in builtin. */
460 if (info->users == NULL) {
461 info->users = pdb_search_users(info, acct_flags);
462 if (info->users == NULL) {
466 /* Fetch the last possible entry, thus trigger an enumeration */
467 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
469 /* Ensure we cache this enumeration. */
470 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
472 return info->users->num_entries;
475 static uint32 count_sam_groups(struct disp_info *info)
477 struct samr_displayentry *entry;
479 if (sid_check_is_builtin(&info->sid)) {
480 /* No groups in builtin. */
484 if (info->groups == NULL) {
485 info->groups = pdb_search_groups(info);
486 if (info->groups == NULL) {
490 /* Fetch the last possible entry, thus trigger an enumeration */
491 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
493 /* Ensure we cache this enumeration. */
494 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
496 return info->groups->num_entries;
499 static uint32 count_sam_aliases(struct disp_info *info)
501 struct samr_displayentry *entry;
503 if (info->aliases == NULL) {
504 info->aliases = pdb_search_aliases(info, &info->sid);
505 if (info->aliases == NULL) {
509 /* Fetch the last possible entry, thus trigger an enumeration */
510 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
512 /* Ensure we cache this enumeration. */
513 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
515 return info->aliases->num_entries;
518 /*******************************************************************
520 ********************************************************************/
522 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
524 if (!close_policy_hnd(p, r->in.handle)) {
525 return NT_STATUS_INVALID_HANDLE;
528 ZERO_STRUCTP(r->out.handle);
533 /*******************************************************************
535 ********************************************************************/
537 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
538 struct samr_OpenDomain *r)
540 struct samr_connect_info *cinfo;
541 struct samr_domain_info *dinfo;
542 struct security_descriptor *psd = NULL;
544 uint32 des_access = r->in.access_mask;
547 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
550 /* find the connection policy handle. */
552 cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
553 struct samr_connect_info, &status);
554 if (!NT_STATUS_IS_OK(status)) {
558 /*check if access can be granted as requested by client. */
559 map_max_allowed_access(p->server_info->ptok,
560 &p->server_info->utok,
563 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
564 se_map_generic( &des_access, &dom_generic_mapping );
567 * Users with SeMachineAccount or SeAddUser get additional
568 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
570 se_priv_copy( &se_rights, &se_machine_account );
571 se_priv_add( &se_rights, &se_add_users );
574 * Users with SeAddUser get the ability to manipulate groups
577 if (user_has_any_privilege(p->server_info->ptok, &se_add_users)) {
578 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
579 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
580 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
581 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
582 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
585 status = access_check_object( psd, p->server_info->ptok,
586 &se_rights, extra_access, des_access,
587 &acc_granted, "_samr_OpenDomain" );
589 if ( !NT_STATUS_IS_OK(status) )
592 if (!sid_check_is_domain(r->in.sid) &&
593 !sid_check_is_builtin(r->in.sid)) {
594 return NT_STATUS_NO_SUCH_DOMAIN;
597 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
598 struct samr_domain_info, &status);
599 if (!NT_STATUS_IS_OK(status)) {
602 dinfo->sid = *r->in.sid;
603 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
605 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
610 /*******************************************************************
612 ********************************************************************/
614 NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
615 struct samr_GetUserPwInfo *r)
617 struct samr_user_info *uinfo;
618 enum lsa_SidType sid_type;
619 uint32_t min_password_length = 0;
620 uint32_t password_properties = 0;
624 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
626 uinfo = policy_handle_find(p, r->in.user_handle,
627 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
628 struct samr_user_info, &status);
629 if (!NT_STATUS_IS_OK(status)) {
633 if (!sid_check_is_in_our_domain(&uinfo->sid)) {
634 return NT_STATUS_OBJECT_TYPE_MISMATCH;
638 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
641 return NT_STATUS_NO_SUCH_USER;
647 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
648 &min_password_length);
649 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
650 &password_properties);
653 if (lp_check_password_script() && *lp_check_password_script()) {
654 password_properties |= DOMAIN_PASSWORD_COMPLEX;
662 r->out.info->min_password_length = min_password_length;
663 r->out.info->password_properties = password_properties;
665 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
670 /*******************************************************************
672 ********************************************************************/
674 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
675 struct samr_SetSecurity *r)
677 struct samr_user_info *uinfo;
679 struct security_acl *dacl;
681 struct samu *sampass=NULL;
684 uinfo = policy_handle_find(p, r->in.handle,
685 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
686 struct samr_user_info, &status);
687 if (!NT_STATUS_IS_OK(status)) {
691 if (!(sampass = samu_new( p->mem_ctx))) {
692 DEBUG(0,("No memory!\n"));
693 return NT_STATUS_NO_MEMORY;
696 /* get the user record */
698 ret = pdb_getsampwsid(sampass, &uinfo->sid);
702 DEBUG(4, ("User %s not found\n",
703 sid_string_dbg(&uinfo->sid)));
704 TALLOC_FREE(sampass);
705 return NT_STATUS_INVALID_HANDLE;
708 dacl = r->in.sdbuf->sd->dacl;
709 for (i=0; i < dacl->num_aces; i++) {
710 if (sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
711 ret = pdb_set_pass_can_change(sampass,
712 (dacl->aces[i].access_mask &
713 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
720 TALLOC_FREE(sampass);
721 return NT_STATUS_ACCESS_DENIED;
725 status = pdb_update_sam_account(sampass);
728 TALLOC_FREE(sampass);
733 /*******************************************************************
734 build correct perms based on policies and password times for _samr_query_sec_obj
735 *******************************************************************/
736 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
738 struct samu *sampass=NULL;
741 if ( !(sampass = samu_new( mem_ctx )) ) {
742 DEBUG(0,("No memory!\n"));
747 ret = pdb_getsampwsid(sampass, user_sid);
751 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
752 TALLOC_FREE(sampass);
756 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
758 if (pdb_get_pass_can_change(sampass)) {
759 TALLOC_FREE(sampass);
762 TALLOC_FREE(sampass);
767 /*******************************************************************
769 ********************************************************************/
771 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
772 struct samr_QuerySecurity *r)
774 struct samr_connect_info *cinfo;
775 struct samr_domain_info *dinfo;
776 struct samr_user_info *uinfo;
777 struct samr_group_info *ginfo;
778 struct samr_alias_info *ainfo;
780 struct security_descriptor * psd = NULL;
783 cinfo = policy_handle_find(p, r->in.handle,
784 SEC_STD_READ_CONTROL, NULL,
785 struct samr_connect_info, &status);
786 if (NT_STATUS_IS_OK(status)) {
787 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
788 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
789 &sam_generic_mapping, NULL, 0);
793 dinfo = policy_handle_find(p, r->in.handle,
794 SEC_STD_READ_CONTROL, NULL,
795 struct samr_domain_info, &status);
796 if (NT_STATUS_IS_OK(status)) {
797 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
798 "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
800 * TODO: Builtin probably needs a different SD with restricted
803 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
804 &dom_generic_mapping, NULL, 0);
808 uinfo = policy_handle_find(p, r->in.handle,
809 SEC_STD_READ_CONTROL, NULL,
810 struct samr_user_info, &status);
811 if (NT_STATUS_IS_OK(status)) {
812 DEBUG(10,("_samr_QuerySecurity: querying security on user "
813 "Object with SID: %s\n",
814 sid_string_dbg(&uinfo->sid)));
815 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
816 status = make_samr_object_sd(
817 p->mem_ctx, &psd, &sd_size,
818 &usr_generic_mapping,
819 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
821 status = make_samr_object_sd(
822 p->mem_ctx, &psd, &sd_size,
823 &usr_nopwchange_generic_mapping,
824 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
829 ginfo = policy_handle_find(p, r->in.handle,
830 SEC_STD_READ_CONTROL, NULL,
831 struct samr_group_info, &status);
832 if (NT_STATUS_IS_OK(status)) {
834 * TODO: different SDs have to be generated for aliases groups
835 * and users. Currently all three get a default user SD
837 DEBUG(10,("_samr_QuerySecurity: querying security on group "
838 "Object with SID: %s\n",
839 sid_string_dbg(&ginfo->sid)));
840 status = make_samr_object_sd(
841 p->mem_ctx, &psd, &sd_size,
842 &usr_nopwchange_generic_mapping,
843 &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
847 ainfo = policy_handle_find(p, r->in.handle,
848 SEC_STD_READ_CONTROL, NULL,
849 struct samr_alias_info, &status);
850 if (NT_STATUS_IS_OK(status)) {
852 * TODO: different SDs have to be generated for aliases groups
853 * and users. Currently all three get a default user SD
855 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
856 "Object with SID: %s\n",
857 sid_string_dbg(&ainfo->sid)));
858 status = make_samr_object_sd(
859 p->mem_ctx, &psd, &sd_size,
860 &usr_nopwchange_generic_mapping,
861 &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
865 return NT_STATUS_OBJECT_TYPE_MISMATCH;
867 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
868 return NT_STATUS_NO_MEMORY;
873 /*******************************************************************
874 makes a SAM_ENTRY / UNISTR2* structure from a user list.
875 ********************************************************************/
877 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
878 struct samr_SamEntry **sam_pp,
879 uint32_t num_entries,
881 struct samr_displayentry *entries)
884 struct samr_SamEntry *sam;
888 if (num_entries == 0) {
892 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
894 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
895 return NT_STATUS_NO_MEMORY;
898 for (i = 0; i < num_entries; i++) {
901 * usrmgr expects a non-NULL terminated string with
902 * trust relationships
904 if (entries[i].acct_flags & ACB_DOMTRUST) {
905 init_unistr2(&uni_temp_name, entries[i].account_name,
908 init_unistr2(&uni_temp_name, entries[i].account_name,
912 init_lsa_String(&sam[i].name, entries[i].account_name);
913 sam[i].idx = entries[i].rid;
921 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
923 /*******************************************************************
924 _samr_EnumDomainUsers
925 ********************************************************************/
927 NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
928 struct samr_EnumDomainUsers *r)
931 struct samr_domain_info *dinfo;
933 uint32 enum_context = *r->in.resume_handle;
934 enum remote_arch_types ra_type = get_remote_arch();
935 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
936 uint32 max_entries = max_sam_entries;
937 struct samr_displayentry *entries = NULL;
938 struct samr_SamArray *samr_array = NULL;
939 struct samr_SamEntry *samr_entries = NULL;
941 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
943 dinfo = policy_handle_find(p, r->in.domain_handle,
944 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
945 struct samr_domain_info, &status);
946 if (!NT_STATUS_IS_OK(status)) {
950 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
952 return NT_STATUS_NO_MEMORY;
954 *r->out.sam = samr_array;
956 if (sid_check_is_builtin(&dinfo->sid)) {
957 /* No users in builtin. */
958 *r->out.resume_handle = *r->in.resume_handle;
959 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
967 if ((dinfo->disp_info->enum_users != NULL) &&
968 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
969 TALLOC_FREE(dinfo->disp_info->enum_users);
972 if (dinfo->disp_info->enum_users == NULL) {
973 dinfo->disp_info->enum_users = pdb_search_users(
974 dinfo->disp_info, r->in.acct_flags);
975 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
978 if (dinfo->disp_info->enum_users == NULL) {
979 /* END AS ROOT !!!! */
981 return NT_STATUS_ACCESS_DENIED;
984 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
985 enum_context, max_entries,
988 /* END AS ROOT !!!! */
992 if (num_account == 0) {
993 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
995 *r->out.resume_handle = *r->in.resume_handle;
999 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1000 num_account, enum_context,
1002 if (!NT_STATUS_IS_OK(status)) {
1006 if (max_entries <= num_account) {
1007 status = STATUS_MORE_ENTRIES;
1009 status = NT_STATUS_OK;
1012 /* Ensure we cache this enumeration. */
1013 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1015 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1017 samr_array->count = num_account;
1018 samr_array->entries = samr_entries;
1020 *r->out.resume_handle = *r->in.resume_handle + num_account;
1021 *r->out.num_entries = num_account;
1023 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1028 /*******************************************************************
1029 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1030 ********************************************************************/
1032 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1033 struct samr_SamEntry **sam_pp,
1034 uint32_t num_sam_entries,
1035 struct samr_displayentry *entries)
1037 struct samr_SamEntry *sam;
1042 if (num_sam_entries == 0) {
1046 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1051 for (i = 0; i < num_sam_entries; i++) {
1053 * JRA. I think this should include the null. TNG does not.
1055 init_lsa_String(&sam[i].name, entries[i].account_name);
1056 sam[i].idx = entries[i].rid;
1062 /*******************************************************************
1063 _samr_EnumDomainGroups
1064 ********************************************************************/
1066 NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
1067 struct samr_EnumDomainGroups *r)
1070 struct samr_domain_info *dinfo;
1071 struct samr_displayentry *groups;
1073 struct samr_SamArray *samr_array = NULL;
1074 struct samr_SamEntry *samr_entries = NULL;
1076 dinfo = policy_handle_find(p, r->in.domain_handle,
1077 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1078 struct samr_domain_info, &status);
1079 if (!NT_STATUS_IS_OK(status)) {
1083 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1085 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1087 return NT_STATUS_NO_MEMORY;
1089 *r->out.sam = samr_array;
1091 if (sid_check_is_builtin(&dinfo->sid)) {
1092 /* No groups in builtin. */
1093 *r->out.resume_handle = *r->in.resume_handle;
1094 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1098 /* the domain group array is being allocated in the function below */
1102 if (dinfo->disp_info->groups == NULL) {
1103 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1105 if (dinfo->disp_info->groups == NULL) {
1107 return NT_STATUS_ACCESS_DENIED;
1111 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1112 *r->in.resume_handle,
1113 MAX_SAM_ENTRIES, &groups);
1116 /* Ensure we cache this enumeration. */
1117 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1119 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1120 num_groups, groups);
1122 if (MAX_SAM_ENTRIES <= num_groups) {
1123 status = STATUS_MORE_ENTRIES;
1125 status = NT_STATUS_OK;
1128 samr_array->count = num_groups;
1129 samr_array->entries = samr_entries;
1131 *r->out.num_entries = num_groups;
1132 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1134 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1139 /*******************************************************************
1140 _samr_EnumDomainAliases
1141 ********************************************************************/
1143 NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1144 struct samr_EnumDomainAliases *r)
1147 struct samr_domain_info *dinfo;
1148 struct samr_displayentry *aliases;
1149 uint32 num_aliases = 0;
1150 struct samr_SamArray *samr_array = NULL;
1151 struct samr_SamEntry *samr_entries = NULL;
1153 dinfo = policy_handle_find(p, r->in.domain_handle,
1154 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1155 struct samr_domain_info, &status);
1156 if (!NT_STATUS_IS_OK(status)) {
1160 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1161 sid_string_dbg(&dinfo->sid)));
1163 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1165 return NT_STATUS_NO_MEMORY;
1170 if (dinfo->disp_info->aliases == NULL) {
1171 dinfo->disp_info->aliases = pdb_search_aliases(
1172 dinfo->disp_info, &dinfo->sid);
1173 if (dinfo->disp_info->aliases == NULL) {
1175 return NT_STATUS_ACCESS_DENIED;
1179 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1180 *r->in.resume_handle,
1181 MAX_SAM_ENTRIES, &aliases);
1184 /* Ensure we cache this enumeration. */
1185 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1187 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1188 num_aliases, aliases);
1190 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1192 if (MAX_SAM_ENTRIES <= num_aliases) {
1193 status = STATUS_MORE_ENTRIES;
1195 status = NT_STATUS_OK;
1198 samr_array->count = num_aliases;
1199 samr_array->entries = samr_entries;
1201 *r->out.sam = samr_array;
1202 *r->out.num_entries = num_aliases;
1203 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1208 /*******************************************************************
1209 inits a samr_DispInfoGeneral structure.
1210 ********************************************************************/
1212 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1213 struct samr_DispInfoGeneral *r,
1214 uint32_t num_entries,
1216 struct samr_displayentry *entries)
1220 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1222 if (num_entries == 0) {
1223 return NT_STATUS_OK;
1226 r->count = num_entries;
1228 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1230 return NT_STATUS_NO_MEMORY;
1233 for (i = 0; i < num_entries ; i++) {
1235 init_lsa_String(&r->entries[i].account_name,
1236 entries[i].account_name);
1238 init_lsa_String(&r->entries[i].description,
1239 entries[i].description);
1241 init_lsa_String(&r->entries[i].full_name,
1242 entries[i].fullname);
1244 r->entries[i].rid = entries[i].rid;
1245 r->entries[i].acct_flags = entries[i].acct_flags;
1246 r->entries[i].idx = start_idx+i+1;
1249 return NT_STATUS_OK;
1252 /*******************************************************************
1253 inits a samr_DispInfoFull structure.
1254 ********************************************************************/
1256 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1257 struct samr_DispInfoFull *r,
1258 uint32_t num_entries,
1260 struct samr_displayentry *entries)
1264 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1266 if (num_entries == 0) {
1267 return NT_STATUS_OK;
1270 r->count = num_entries;
1272 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1274 return NT_STATUS_NO_MEMORY;
1277 for (i = 0; i < num_entries ; i++) {
1279 init_lsa_String(&r->entries[i].account_name,
1280 entries[i].account_name);
1282 init_lsa_String(&r->entries[i].description,
1283 entries[i].description);
1285 r->entries[i].rid = entries[i].rid;
1286 r->entries[i].acct_flags = entries[i].acct_flags;
1287 r->entries[i].idx = start_idx+i+1;
1290 return NT_STATUS_OK;
1293 /*******************************************************************
1294 inits a samr_DispInfoFullGroups structure.
1295 ********************************************************************/
1297 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1298 struct samr_DispInfoFullGroups *r,
1299 uint32_t num_entries,
1301 struct samr_displayentry *entries)
1305 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1307 if (num_entries == 0) {
1308 return NT_STATUS_OK;
1311 r->count = num_entries;
1313 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1315 return NT_STATUS_NO_MEMORY;
1318 for (i = 0; i < num_entries ; i++) {
1320 init_lsa_String(&r->entries[i].account_name,
1321 entries[i].account_name);
1323 init_lsa_String(&r->entries[i].description,
1324 entries[i].description);
1326 r->entries[i].rid = entries[i].rid;
1327 r->entries[i].acct_flags = entries[i].acct_flags;
1328 r->entries[i].idx = start_idx+i+1;
1331 return NT_STATUS_OK;
1334 /*******************************************************************
1335 inits a samr_DispInfoAscii structure.
1336 ********************************************************************/
1338 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1339 struct samr_DispInfoAscii *r,
1340 uint32_t num_entries,
1342 struct samr_displayentry *entries)
1346 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1348 if (num_entries == 0) {
1349 return NT_STATUS_OK;
1352 r->count = num_entries;
1354 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1356 return NT_STATUS_NO_MEMORY;
1359 for (i = 0; i < num_entries ; i++) {
1361 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1362 entries[i].account_name);
1364 r->entries[i].idx = start_idx+i+1;
1367 return NT_STATUS_OK;
1370 /*******************************************************************
1371 inits a samr_DispInfoAscii structure.
1372 ********************************************************************/
1374 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1375 struct samr_DispInfoAscii *r,
1376 uint32_t num_entries,
1378 struct samr_displayentry *entries)
1382 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1384 if (num_entries == 0) {
1385 return NT_STATUS_OK;
1388 r->count = num_entries;
1390 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1392 return NT_STATUS_NO_MEMORY;
1395 for (i = 0; i < num_entries ; i++) {
1397 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1398 entries[i].account_name);
1400 r->entries[i].idx = start_idx+i+1;
1403 return NT_STATUS_OK;
1406 /*******************************************************************
1407 _samr_QueryDisplayInfo
1408 ********************************************************************/
1410 NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1411 struct samr_QueryDisplayInfo *r)
1414 struct samr_domain_info *dinfo;
1415 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1417 uint32 max_entries = r->in.max_entries;
1419 union samr_DispInfo *disp_info = r->out.info;
1422 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1423 uint32 num_account = 0;
1424 enum remote_arch_types ra_type = get_remote_arch();
1425 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1426 struct samr_displayentry *entries = NULL;
1428 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1430 dinfo = policy_handle_find(p, r->in.domain_handle,
1431 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1432 struct samr_domain_info, &status);
1433 if (!NT_STATUS_IS_OK(status)) {
1437 if (sid_check_is_builtin(&dinfo->sid)) {
1438 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1439 return NT_STATUS_OK;
1443 * calculate how many entries we will return.
1445 * - the number of entries the client asked
1446 * - our limit on that
1447 * - the starting point (enumeration context)
1448 * - the buffer size the client will accept
1452 * We are a lot more like W2K. Instead of reading the SAM
1453 * each time to find the records we need to send back,
1454 * we read it once and link that copy to the sam handle.
1455 * For large user list (over the MAX_SAM_ENTRIES)
1456 * it's a definitive win.
1457 * second point to notice: between enumerations
1458 * our sam is now the same as it's a snapshoot.
1459 * third point: got rid of the static SAM_USER_21 struct
1460 * no more intermediate.
1461 * con: it uses much more memory, as a full copy is stored
1464 * If you want to change it, think twice and think
1465 * of the second point , that's really important.
1470 if ((r->in.level < 1) || (r->in.level > 5)) {
1471 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1472 (unsigned int)r->in.level ));
1473 return NT_STATUS_INVALID_INFO_CLASS;
1476 /* first limit the number of entries we will return */
1477 if (r->in.max_entries > max_sam_entries) {
1478 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1479 "entries, limiting to %d\n", r->in.max_entries,
1481 max_entries = max_sam_entries;
1484 /* calculate the size and limit on the number of entries we will
1487 temp_size=max_entries*struct_size;
1489 if (temp_size > r->in.buf_size) {
1490 max_entries = MIN((r->in.buf_size / struct_size),max_entries);;
1491 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1492 "only %d entries\n", max_entries));
1497 /* THe following done as ROOT. Don't return without unbecome_root(). */
1499 switch (r->in.level) {
1502 if (dinfo->disp_info->users == NULL) {
1503 dinfo->disp_info->users = pdb_search_users(
1504 dinfo->disp_info, ACB_NORMAL);
1505 if (dinfo->disp_info->users == NULL) {
1507 return NT_STATUS_ACCESS_DENIED;
1509 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1510 (unsigned int)r->in.start_idx));
1512 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1513 (unsigned int)r->in.start_idx));
1516 num_account = pdb_search_entries(dinfo->disp_info->users,
1517 r->in.start_idx, max_entries,
1521 if (dinfo->disp_info->machines == NULL) {
1522 dinfo->disp_info->machines = pdb_search_users(
1523 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1524 if (dinfo->disp_info->machines == NULL) {
1526 return NT_STATUS_ACCESS_DENIED;
1528 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1529 (unsigned int)r->in.start_idx));
1531 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1532 (unsigned int)r->in.start_idx));
1535 num_account = pdb_search_entries(dinfo->disp_info->machines,
1536 r->in.start_idx, max_entries,
1541 if (dinfo->disp_info->groups == NULL) {
1542 dinfo->disp_info->groups = pdb_search_groups(
1544 if (dinfo->disp_info->groups == NULL) {
1546 return NT_STATUS_ACCESS_DENIED;
1548 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1549 (unsigned int)r->in.start_idx));
1551 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1552 (unsigned int)r->in.start_idx));
1555 num_account = pdb_search_entries(dinfo->disp_info->groups,
1556 r->in.start_idx, max_entries,
1561 smb_panic("info class changed");
1567 /* Now create reply structure */
1568 switch (r->in.level) {
1570 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1571 num_account, r->in.start_idx,
1575 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1576 num_account, r->in.start_idx,
1580 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1581 num_account, r->in.start_idx,
1585 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1586 num_account, r->in.start_idx,
1590 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1591 num_account, r->in.start_idx,
1595 smb_panic("info class changed");
1599 if (!NT_STATUS_IS_OK(disp_ret))
1602 if (max_entries <= num_account) {
1603 status = STATUS_MORE_ENTRIES;
1605 status = NT_STATUS_OK;
1608 /* Ensure we cache this enumeration. */
1609 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1611 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1613 *r->out.total_size = num_account * struct_size;
1614 *r->out.returned_size = num_account ? temp_size : 0;
1619 /****************************************************************
1620 _samr_QueryDisplayInfo2
1621 ****************************************************************/
1623 NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1624 struct samr_QueryDisplayInfo2 *r)
1626 struct samr_QueryDisplayInfo q;
1628 q.in.domain_handle = r->in.domain_handle;
1629 q.in.level = r->in.level;
1630 q.in.start_idx = r->in.start_idx;
1631 q.in.max_entries = r->in.max_entries;
1632 q.in.buf_size = r->in.buf_size;
1634 q.out.total_size = r->out.total_size;
1635 q.out.returned_size = r->out.returned_size;
1636 q.out.info = r->out.info;
1638 return _samr_QueryDisplayInfo(p, &q);
1641 /****************************************************************
1642 _samr_QueryDisplayInfo3
1643 ****************************************************************/
1645 NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1646 struct samr_QueryDisplayInfo3 *r)
1648 struct samr_QueryDisplayInfo q;
1650 q.in.domain_handle = r->in.domain_handle;
1651 q.in.level = r->in.level;
1652 q.in.start_idx = r->in.start_idx;
1653 q.in.max_entries = r->in.max_entries;
1654 q.in.buf_size = r->in.buf_size;
1656 q.out.total_size = r->out.total_size;
1657 q.out.returned_size = r->out.returned_size;
1658 q.out.info = r->out.info;
1660 return _samr_QueryDisplayInfo(p, &q);
1663 /*******************************************************************
1664 _samr_QueryAliasInfo
1665 ********************************************************************/
1667 NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1668 struct samr_QueryAliasInfo *r)
1670 struct samr_alias_info *ainfo;
1671 struct acct_info info;
1673 union samr_AliasInfo *alias_info = NULL;
1674 const char *alias_name = NULL;
1675 const char *alias_description = NULL;
1677 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1679 ainfo = policy_handle_find(p, r->in.alias_handle,
1680 SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1681 struct samr_alias_info, &status);
1682 if (!NT_STATUS_IS_OK(status)) {
1686 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1688 return NT_STATUS_NO_MEMORY;
1692 status = pdb_get_aliasinfo(&ainfo->sid, &info);
1695 if ( !NT_STATUS_IS_OK(status))
1698 /* FIXME: info contains fstrings */
1699 alias_name = talloc_strdup(r, info.acct_name);
1700 alias_description = talloc_strdup(r, info.acct_desc);
1702 switch (r->in.level) {
1704 alias_info->all.name.string = alias_name;
1705 alias_info->all.num_members = 1; /* ??? */
1706 alias_info->all.description.string = alias_description;
1709 alias_info->name.string = alias_name;
1711 case ALIASINFODESCRIPTION:
1712 alias_info->description.string = alias_description;
1715 return NT_STATUS_INVALID_INFO_CLASS;
1718 *r->out.info = alias_info;
1720 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1722 return NT_STATUS_OK;
1725 /*******************************************************************
1727 ********************************************************************/
1729 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1730 struct samr_LookupNames *r)
1732 struct samr_domain_info *dinfo;
1735 enum lsa_SidType *type;
1737 int num_rids = r->in.num_names;
1738 struct samr_Ids rids, types;
1739 uint32_t num_mapped = 0;
1741 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1743 dinfo = policy_handle_find(p, r->in.domain_handle,
1744 0 /* Don't know the acc_bits yet */, NULL,
1745 struct samr_domain_info, &status);
1746 if (!NT_STATUS_IS_OK(status)) {
1750 if (num_rids > MAX_SAM_ENTRIES) {
1751 num_rids = MAX_SAM_ENTRIES;
1752 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1755 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1756 NT_STATUS_HAVE_NO_MEMORY(rid);
1758 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1759 NT_STATUS_HAVE_NO_MEMORY(type);
1761 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1762 sid_string_dbg(&dinfo->sid)));
1764 for (i = 0; i < num_rids; i++) {
1766 status = NT_STATUS_NONE_MAPPED;
1767 type[i] = SID_NAME_UNKNOWN;
1769 rid[i] = 0xffffffff;
1771 if (sid_check_is_builtin(&dinfo->sid)) {
1772 if (lookup_builtin_name(r->in.names[i].string,
1775 type[i] = SID_NAME_ALIAS;
1778 lookup_global_sam_name(r->in.names[i].string, 0,
1782 if (type[i] != SID_NAME_UNKNOWN) {
1787 if (num_mapped == num_rids) {
1788 status = NT_STATUS_OK;
1789 } else if (num_mapped == 0) {
1790 status = NT_STATUS_NONE_MAPPED;
1792 status = STATUS_SOME_UNMAPPED;
1795 rids.count = num_rids;
1798 types.count = num_rids;
1799 types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1800 NT_STATUS_HAVE_NO_MEMORY(type);
1801 for (i = 0; i < num_rids; i++) {
1802 types.ids[i] = (type[i] & 0xffffffff);
1805 *r->out.rids = rids;
1806 *r->out.types = types;
1808 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1813 /****************************************************************
1814 _samr_ChangePasswordUser
1815 ****************************************************************/
1817 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1818 struct samr_ChangePasswordUser *r)
1822 struct samr_user_info *uinfo;
1824 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1825 struct samr_Password lm_pwd, nt_pwd;
1827 uinfo = policy_handle_find(p, r->in.user_handle,
1828 SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1829 struct samr_user_info, &status);
1830 if (!NT_STATUS_IS_OK(status)) {
1834 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1835 sid_string_dbg(&uinfo->sid)));
1837 if (!(pwd = samu_new(NULL))) {
1838 return NT_STATUS_NO_MEMORY;
1842 ret = pdb_getsampwsid(pwd, &uinfo->sid);
1847 return NT_STATUS_WRONG_PASSWORD;
1851 const uint8_t *lm_pass, *nt_pass;
1853 lm_pass = pdb_get_lanman_passwd(pwd);
1854 nt_pass = pdb_get_nt_passwd(pwd);
1856 if (!lm_pass || !nt_pass) {
1857 status = NT_STATUS_WRONG_PASSWORD;
1861 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1862 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1865 /* basic sanity checking on parameters. Do this before any database ops */
1866 if (!r->in.lm_present || !r->in.nt_present ||
1867 !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1868 !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1869 /* we should really handle a change with lm not
1871 status = NT_STATUS_INVALID_PARAMETER_MIX;
1875 /* decrypt and check the new lm hash */
1876 D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1877 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1878 if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1879 status = NT_STATUS_WRONG_PASSWORD;
1883 /* decrypt and check the new nt hash */
1884 D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1885 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1886 if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1887 status = NT_STATUS_WRONG_PASSWORD;
1891 /* The NT Cross is not required by Win2k3 R2, but if present
1892 check the nt cross hash */
1893 if (r->in.cross1_present && r->in.nt_cross) {
1894 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1895 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1896 status = NT_STATUS_WRONG_PASSWORD;
1901 /* The LM Cross is not required by Win2k3 R2, but if present
1902 check the lm cross hash */
1903 if (r->in.cross2_present && r->in.lm_cross) {
1904 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1905 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1906 status = NT_STATUS_WRONG_PASSWORD;
1911 if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1912 !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1913 status = NT_STATUS_ACCESS_DENIED;
1917 status = pdb_update_sam_account(pwd);
1924 /*******************************************************************
1925 _samr_ChangePasswordUser2
1926 ********************************************************************/
1928 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1929 struct samr_ChangePasswordUser2 *r)
1935 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1937 fstrcpy(user_name, r->in.account->string);
1938 fstrcpy(wks, r->in.server->string);
1940 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1943 * Pass the user through the NT -> unix user mapping
1947 (void)map_username(user_name);
1950 * UNIX username case mangling not required, pass_oem_change
1951 * is case insensitive.
1954 status = pass_oem_change(user_name,
1956 r->in.lm_password->data,
1957 r->in.lm_verifier->hash,
1958 r->in.nt_password->data,
1959 r->in.nt_verifier->hash,
1962 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1964 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1965 return NT_STATUS_WRONG_PASSWORD;
1971 /****************************************************************
1972 _samr_OemChangePasswordUser2
1973 ****************************************************************/
1975 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1976 struct samr_OemChangePasswordUser2 *r)
1980 const char *wks = NULL;
1982 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1984 fstrcpy(user_name, r->in.account->string);
1985 if (r->in.server && r->in.server->string) {
1986 wks = r->in.server->string;
1989 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1992 * Pass the user through the NT -> unix user mapping
1996 (void)map_username(user_name);
1999 * UNIX username case mangling not required, pass_oem_change
2000 * is case insensitive.
2003 if (!r->in.hash || !r->in.password) {
2004 return NT_STATUS_INVALID_PARAMETER;
2007 status = pass_oem_change(user_name,
2009 r->in.password->data,
2015 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2016 return NT_STATUS_WRONG_PASSWORD;
2019 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2024 /*******************************************************************
2025 _samr_ChangePasswordUser3
2026 ********************************************************************/
2028 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
2029 struct samr_ChangePasswordUser3 *r)
2033 const char *wks = NULL;
2034 enum samPwdChangeReason reject_reason;
2035 struct samr_DomInfo1 *dominfo = NULL;
2036 struct userPwdChangeFailureInformation *reject = NULL;
2039 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2041 fstrcpy(user_name, r->in.account->string);
2042 if (r->in.server && r->in.server->string) {
2043 wks = r->in.server->string;
2046 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2049 * Pass the user through the NT -> unix user mapping
2053 (void)map_username(user_name);
2056 * UNIX username case mangling not required, pass_oem_change
2057 * is case insensitive.
2060 status = pass_oem_change(user_name,
2062 r->in.lm_password->data,
2063 r->in.lm_verifier->hash,
2064 r->in.nt_password->data,
2065 r->in.nt_verifier->hash,
2067 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2068 return NT_STATUS_WRONG_PASSWORD;
2071 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2072 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2074 time_t u_expire, u_min_age;
2075 uint32 account_policy_temp;
2077 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2079 return NT_STATUS_NO_MEMORY;
2082 reject = TALLOC_ZERO_P(p->mem_ctx,
2083 struct userPwdChangeFailureInformation);
2085 return NT_STATUS_NO_MEMORY;
2092 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2093 dominfo->min_password_length = tmp;
2095 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2096 dominfo->password_history_length = tmp;
2098 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2099 &dominfo->password_properties);
2101 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2102 u_expire = account_policy_temp;
2104 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2105 u_min_age = account_policy_temp;
2111 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2112 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2114 if (lp_check_password_script() && *lp_check_password_script()) {
2115 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2118 reject->extendedFailureReason = reject_reason;
2120 *r->out.dominfo = dominfo;
2121 *r->out.reject = reject;
2124 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2129 /*******************************************************************
2130 makes a SAMR_R_LOOKUP_RIDS structure.
2131 ********************************************************************/
2133 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2135 struct lsa_String **lsa_name_array_p)
2137 struct lsa_String *lsa_name_array = NULL;
2140 *lsa_name_array_p = NULL;
2142 if (num_names != 0) {
2143 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2144 if (!lsa_name_array) {
2149 for (i = 0; i < num_names; i++) {
2150 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2151 init_lsa_String(&lsa_name_array[i], names[i]);
2154 *lsa_name_array_p = lsa_name_array;
2159 /*******************************************************************
2161 ********************************************************************/
2163 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2164 struct samr_LookupRids *r)
2166 struct samr_domain_info *dinfo;
2169 enum lsa_SidType *attrs = NULL;
2170 uint32 *wire_attrs = NULL;
2171 int num_rids = (int)r->in.num_rids;
2173 struct lsa_Strings names_array;
2174 struct samr_Ids types_array;
2175 struct lsa_String *lsa_names = NULL;
2177 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2179 dinfo = policy_handle_find(p, r->in.domain_handle,
2180 0 /* Don't know the acc_bits yet */, NULL,
2181 struct samr_domain_info, &status);
2182 if (!NT_STATUS_IS_OK(status)) {
2186 if (num_rids > 1000) {
2187 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2188 "to samba4 idl this is not possible\n", num_rids));
2189 return NT_STATUS_UNSUCCESSFUL;
2193 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2194 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2195 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2197 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2198 return NT_STATUS_NO_MEMORY;
2205 become_root(); /* lookup_sid can require root privs */
2206 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2210 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2211 status = NT_STATUS_OK;
2214 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2216 return NT_STATUS_NO_MEMORY;
2219 /* Convert from enum lsa_SidType to uint32 for wire format. */
2220 for (i = 0; i < num_rids; i++) {
2221 wire_attrs[i] = (uint32)attrs[i];
2224 names_array.count = num_rids;
2225 names_array.names = lsa_names;
2227 types_array.count = num_rids;
2228 types_array.ids = wire_attrs;
2230 *r->out.names = names_array;
2231 *r->out.types = types_array;
2233 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2238 /*******************************************************************
2240 ********************************************************************/
2242 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2243 struct samr_OpenUser *r)
2245 struct samu *sampass=NULL;
2247 struct samr_domain_info *dinfo;
2248 struct samr_user_info *uinfo;
2249 struct security_descriptor *psd = NULL;
2251 uint32 des_access = r->in.access_mask;
2252 uint32_t extra_access = 0;
2259 dinfo = policy_handle_find(p, r->in.domain_handle,
2260 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2261 struct samr_domain_info, &status);
2262 if (!NT_STATUS_IS_OK(status)) {
2266 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2267 return NT_STATUS_NO_MEMORY;
2270 /* append the user's RID to it */
2272 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2273 return NT_STATUS_NO_SUCH_USER;
2275 /* check if access can be granted as requested by client. */
2276 map_max_allowed_access(p->server_info->ptok,
2277 &p->server_info->utok,
2280 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2281 se_map_generic(&des_access, &usr_generic_mapping);
2284 * Get the sampass first as we need to check privileges
2285 * based on what kind of user object this is.
2286 * But don't reveal info too early if it didn't exist.
2290 ret=pdb_getsampwsid(sampass, &sid);
2293 se_priv_copy(&se_rights, &se_priv_none);
2296 * We do the override access checks on *open*, not at
2300 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2302 if ((acb_info & ACB_WSTRUST) &&
2303 user_has_any_privilege(p->server_info->ptok,
2304 &se_machine_account)) {
2306 * SeMachineAccount is needed to add
2307 * GENERIC_RIGHTS_USER_WRITE to a machine
2310 se_priv_add(&se_rights, &se_machine_account);
2311 DEBUG(10,("_samr_OpenUser: adding machine account "
2312 "rights to handle for user %s\n",
2313 pdb_get_username(sampass) ));
2315 if ((acb_info & ACB_NORMAL) &&
2316 user_has_any_privilege(p->server_info->ptok,
2319 * SeAddUsers is needed to add
2320 * GENERIC_RIGHTS_USER_WRITE to a normal
2323 se_priv_add(&se_rights, &se_add_users);
2324 DEBUG(10,("_samr_OpenUser: adding add user "
2325 "rights to handle for user %s\n",
2326 pdb_get_username(sampass) ));
2329 * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
2330 * in DOMAIN_RID_ADMINS. This is almost certainly not
2331 * what Windows does but is a hack for people who haven't
2332 * set up privileges on groups in Samba.
2334 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2335 if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2336 DOMAIN_RID_ADMINS)) {
2337 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2338 extra_access = GENERIC_RIGHTS_USER_WRITE;
2339 DEBUG(4,("_samr_OpenUser: Allowing "
2340 "GENERIC_RIGHTS_USER_WRITE for "
2346 TALLOC_FREE(sampass);
2348 nt_status = access_check_object(psd, p->server_info->ptok,
2349 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2350 &acc_granted, "_samr_OpenUser");
2352 if ( !NT_STATUS_IS_OK(nt_status) )
2355 /* check that the SID exists in our domain. */
2357 return NT_STATUS_NO_SUCH_USER;
2360 /* If we did the rid admins hack above, allow access. */
2361 acc_granted |= extra_access;
2363 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2364 struct samr_user_info, &nt_status);
2365 if (!NT_STATUS_IS_OK(nt_status)) {
2370 return NT_STATUS_OK;
2373 /*************************************************************************
2374 *************************************************************************/
2376 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2378 struct lsa_BinaryString **_r)
2380 struct lsa_BinaryString *r;
2383 return NT_STATUS_INVALID_PARAMETER;
2386 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2388 return NT_STATUS_NO_MEMORY;
2391 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2393 return NT_STATUS_NO_MEMORY;
2395 memcpy(r->array, blob->data, blob->length);
2396 r->size = blob->length;
2397 r->length = blob->length;
2400 return NT_STATUS_NO_MEMORY;
2405 return NT_STATUS_OK;
2408 /*************************************************************************
2409 *************************************************************************/
2411 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2414 struct samr_LogonHours hours;
2415 const int units_per_week = 168;
2418 hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2423 hours.units_per_week = units_per_week;
2424 memset(hours.bits, 0xFF, units_per_week);
2426 if (pdb_get_hours(pw)) {
2427 memcpy(hours.bits, pdb_get_hours(pw),
2428 MIN(pdb_get_hours_len(pw), units_per_week));
2434 /*************************************************************************
2436 *************************************************************************/
2438 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2439 struct samr_UserInfo1 *r,
2441 struct dom_sid *domain_sid)
2443 const struct dom_sid *sid_group;
2444 uint32_t primary_gid;
2447 sid_group = pdb_get_group_sid(pw);
2450 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2451 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2452 "which conflicts with the domain sid %s. Failing operation.\n",
2453 pdb_get_username(pw), sid_string_dbg(sid_group),
2454 sid_string_dbg(domain_sid)));
2455 return NT_STATUS_UNSUCCESSFUL;
2458 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2459 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2460 r->primary_gid = primary_gid;
2461 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2462 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2464 return NT_STATUS_OK;
2467 /*************************************************************************
2469 *************************************************************************/
2471 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2472 struct samr_UserInfo2 *r,
2475 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2476 r->reserved.string = NULL;
2477 r->country_code = 0;
2480 return NT_STATUS_OK;
2483 /*************************************************************************
2485 *************************************************************************/
2487 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2488 struct samr_UserInfo3 *r,
2490 struct dom_sid *domain_sid)
2492 const struct dom_sid *sid_user, *sid_group;
2493 uint32_t rid, primary_gid;
2495 sid_user = pdb_get_user_sid(pw);
2497 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2498 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2499 "the domain sid %s. Failing operation.\n",
2500 pdb_get_username(pw), sid_string_dbg(sid_user),
2501 sid_string_dbg(domain_sid)));
2502 return NT_STATUS_UNSUCCESSFUL;
2506 sid_group = pdb_get_group_sid(pw);
2509 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2510 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2511 "which conflicts with the domain sid %s. Failing operation.\n",
2512 pdb_get_username(pw), sid_string_dbg(sid_group),
2513 sid_string_dbg(domain_sid)));
2514 return NT_STATUS_UNSUCCESSFUL;
2517 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2518 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2519 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2520 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2521 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2523 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2524 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2525 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2526 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2527 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2528 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2529 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2531 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2533 r->primary_gid = primary_gid;
2534 r->acct_flags = pdb_get_acct_ctrl(pw);
2535 r->bad_password_count = pdb_get_bad_password_count(pw);
2536 r->logon_count = pdb_get_logon_count(pw);
2538 return NT_STATUS_OK;
2541 /*************************************************************************
2543 *************************************************************************/
2545 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2546 struct samr_UserInfo4 *r,
2549 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2551 return NT_STATUS_OK;
2554 /*************************************************************************
2556 *************************************************************************/
2558 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2559 struct samr_UserInfo5 *r,
2561 struct dom_sid *domain_sid)
2563 const struct dom_sid *sid_user, *sid_group;
2564 uint32_t rid, primary_gid;
2566 sid_user = pdb_get_user_sid(pw);
2568 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2569 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2570 "the domain sid %s. Failing operation.\n",
2571 pdb_get_username(pw), sid_string_dbg(sid_user),
2572 sid_string_dbg(domain_sid)));
2573 return NT_STATUS_UNSUCCESSFUL;
2577 sid_group = pdb_get_group_sid(pw);
2580 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2581 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2582 "which conflicts with the domain sid %s. Failing operation.\n",
2583 pdb_get_username(pw), sid_string_dbg(sid_group),
2584 sid_string_dbg(domain_sid)));
2585 return NT_STATUS_UNSUCCESSFUL;
2588 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2589 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2590 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2591 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2593 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2594 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2595 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2596 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2597 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2598 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2599 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2600 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2602 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2604 r->primary_gid = primary_gid;
2605 r->acct_flags = pdb_get_acct_ctrl(pw);
2606 r->bad_password_count = pdb_get_bad_password_count(pw);
2607 r->logon_count = pdb_get_logon_count(pw);
2609 return NT_STATUS_OK;
2612 /*************************************************************************
2614 *************************************************************************/
2616 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2617 struct samr_UserInfo6 *r,
2620 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2621 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2623 return NT_STATUS_OK;
2626 /*************************************************************************
2627 get_user_info_7. Safe. Only gives out account_name.
2628 *************************************************************************/
2630 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2631 struct samr_UserInfo7 *r,
2632 struct samu *smbpass)
2634 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2635 if (!r->account_name.string) {
2636 return NT_STATUS_NO_MEMORY;
2639 return NT_STATUS_OK;
2642 /*************************************************************************
2644 *************************************************************************/
2646 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2647 struct samr_UserInfo8 *r,
2650 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2652 return NT_STATUS_OK;
2655 /*************************************************************************
2656 get_user_info_9. Only gives out primary group SID.
2657 *************************************************************************/
2659 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2660 struct samr_UserInfo9 *r,
2661 struct samu *smbpass)
2663 r->primary_gid = pdb_get_group_rid(smbpass);
2665 return NT_STATUS_OK;
2668 /*************************************************************************
2670 *************************************************************************/
2672 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2673 struct samr_UserInfo10 *r,
2676 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2677 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2679 return NT_STATUS_OK;
2682 /*************************************************************************
2684 *************************************************************************/
2686 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2687 struct samr_UserInfo11 *r,
2690 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2692 return NT_STATUS_OK;
2695 /*************************************************************************
2697 *************************************************************************/
2699 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2700 struct samr_UserInfo12 *r,
2703 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2705 return NT_STATUS_OK;
2708 /*************************************************************************
2710 *************************************************************************/
2712 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2713 struct samr_UserInfo13 *r,
2716 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2718 return NT_STATUS_OK;
2721 /*************************************************************************
2723 *************************************************************************/
2725 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2726 struct samr_UserInfo14 *r,
2729 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2731 return NT_STATUS_OK;
2734 /*************************************************************************
2735 get_user_info_16. Safe. Only gives out acb bits.
2736 *************************************************************************/
2738 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2739 struct samr_UserInfo16 *r,
2740 struct samu *smbpass)
2742 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2744 return NT_STATUS_OK;
2747 /*************************************************************************
2749 *************************************************************************/
2751 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2752 struct samr_UserInfo17 *r,
2755 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2757 return NT_STATUS_OK;
2760 /*************************************************************************
2761 get_user_info_18. OK - this is the killer as it gives out password info.
2762 Ensure that this is only allowed on an encrypted connection with a root
2764 *************************************************************************/
2766 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2767 TALLOC_CTX *mem_ctx,
2768 struct samr_UserInfo18 *r,
2769 struct dom_sid *user_sid)
2771 struct samu *smbpass=NULL;
2773 const uint8_t *nt_pass = NULL;
2774 const uint8_t *lm_pass = NULL;
2778 if (p->server_info->system) {
2782 if ((p->auth.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) ||
2783 ((p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO) &&
2784 (p->auth.spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
2785 return NT_STATUS_ACCESS_DENIED;
2788 if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2789 return NT_STATUS_ACCESS_DENIED;
2794 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2797 if ( !(smbpass = samu_new( mem_ctx )) ) {
2798 return NT_STATUS_NO_MEMORY;
2801 ret = pdb_getsampwsid(smbpass, user_sid);
2804 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2805 TALLOC_FREE(smbpass);
2806 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2809 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2811 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2812 TALLOC_FREE(smbpass);
2813 return NT_STATUS_ACCOUNT_DISABLED;
2816 lm_pass = pdb_get_lanman_passwd(smbpass);
2817 if (lm_pass != NULL) {
2818 memcpy(r->lm_pwd.hash, lm_pass, 16);
2819 r->lm_pwd_active = true;
2822 nt_pass = pdb_get_nt_passwd(smbpass);
2823 if (nt_pass != NULL) {
2824 memcpy(r->nt_pwd.hash, nt_pass, 16);
2825 r->nt_pwd_active = true;
2827 r->password_expired = 0; /* FIXME */
2829 TALLOC_FREE(smbpass);
2831 return NT_STATUS_OK;
2834 /*************************************************************************
2836 *************************************************************************/
2838 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2839 struct samr_UserInfo20 *r,
2840 struct samu *sampass)
2842 const char *munged_dial = NULL;
2845 struct lsa_BinaryString *parameters = NULL;
2849 munged_dial = pdb_get_munged_dial(sampass);
2851 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2852 munged_dial, (int)strlen(munged_dial)));
2855 blob = base64_decode_data_blob(munged_dial);
2857 blob = data_blob_string_const_null("");
2860 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2861 data_blob_free(&blob);
2862 if (!NT_STATUS_IS_OK(status)) {
2866 r->parameters = *parameters;
2868 return NT_STATUS_OK;
2872 /*************************************************************************
2874 *************************************************************************/
2876 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2877 struct samr_UserInfo21 *r,
2879 struct dom_sid *domain_sid,
2880 uint32_t acc_granted)
2883 const struct dom_sid *sid_user, *sid_group;
2884 uint32_t rid, primary_gid;
2885 NTTIME force_password_change;
2886 time_t must_change_time;
2887 struct lsa_BinaryString *parameters = NULL;
2888 const char *munged_dial = NULL;
2893 sid_user = pdb_get_user_sid(pw);
2895 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2896 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2897 "the domain sid %s. Failing operation.\n",
2898 pdb_get_username(pw), sid_string_dbg(sid_user),
2899 sid_string_dbg(domain_sid)));
2900 return NT_STATUS_UNSUCCESSFUL;
2904 sid_group = pdb_get_group_sid(pw);
2907 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2908 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2909 "which conflicts with the domain sid %s. Failing operation.\n",
2910 pdb_get_username(pw), sid_string_dbg(sid_group),
2911 sid_string_dbg(domain_sid)));
2912 return NT_STATUS_UNSUCCESSFUL;
2915 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2916 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2917 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2918 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2919 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2921 must_change_time = pdb_get_pass_must_change_time(pw);
2922 if (must_change_time == get_time_t_max()) {
2923 unix_to_nt_time_abs(&force_password_change, must_change_time);
2925 unix_to_nt_time(&force_password_change, must_change_time);
2928 munged_dial = pdb_get_munged_dial(pw);
2930 blob = base64_decode_data_blob(munged_dial);
2932 blob = data_blob_string_const_null("");
2935 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2936 data_blob_free(&blob);
2937 if (!NT_STATUS_IS_OK(status)) {
2941 r->force_password_change = force_password_change;
2943 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2944 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2945 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2946 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2947 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2948 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2949 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2950 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2951 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2953 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2954 r->parameters = *parameters;
2956 r->primary_gid = primary_gid;
2957 r->acct_flags = pdb_get_acct_ctrl(pw);
2958 r->bad_password_count = pdb_get_bad_password_count(pw);
2959 r->logon_count = pdb_get_logon_count(pw);
2960 r->fields_present = pdb_build_fields_present(pw);
2961 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2962 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2963 r->country_code = 0;
2965 r->lm_password_set = 0;
2966 r->nt_password_set = 0;
2971 Look at a user on a real NT4 PDC with usrmgr, press
2972 'ok'. Then you will see that fields_present is set to
2973 0x08f827fa. Look at the user immediately after that again,
2974 and you will see that 0x00fffff is returned. This solves
2975 the problem that you get access denied after having looked
2983 return NT_STATUS_OK;
2986 /*******************************************************************
2988 ********************************************************************/
2990 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
2991 struct samr_QueryUserInfo *r)
2994 union samr_UserInfo *user_info = NULL;
2995 struct samr_user_info *uinfo;
2996 struct dom_sid domain_sid;
2999 struct samu *pwd = NULL;
3000 uint32_t acc_required, acc_granted;
3002 switch (r->in.level) {
3003 case 1: /* UserGeneralInformation */
3004 /* USER_READ_GENERAL */
3005 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3007 case 2: /* UserPreferencesInformation */
3008 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
3009 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
3010 SAMR_USER_ACCESS_GET_NAME_ETC;
3012 case 3: /* UserLogonInformation */
3013 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3014 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3015 SAMR_USER_ACCESS_GET_LOCALE |
3016 SAMR_USER_ACCESS_GET_LOGONINFO |
3017 SAMR_USER_ACCESS_GET_ATTRIBUTES;
3019 case 4: /* UserLogonHoursInformation */
3020 /* USER_READ_LOGON */
3021 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3023 case 5: /* UserAccountInformation */
3024 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3025 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3026 SAMR_USER_ACCESS_GET_LOCALE |
3027 SAMR_USER_ACCESS_GET_LOGONINFO |
3028 SAMR_USER_ACCESS_GET_ATTRIBUTES;
3030 case 6: /* UserNameInformation */
3031 case 7: /* UserAccountNameInformation */
3032 case 8: /* UserFullNameInformation */
3033 case 9: /* UserPrimaryGroupInformation */
3034 case 13: /* UserAdminCommentInformation */
3035 /* USER_READ_GENERAL */
3036 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3038 case 10: /* UserHomeInformation */
3039 case 11: /* UserScriptInformation */
3040 case 12: /* UserProfileInformation */
3041 case 14: /* UserWorkStationsInformation */
3042 /* USER_READ_LOGON */
3043 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3045 case 16: /* UserControlInformation */
3046 case 17: /* UserExpiresInformation */
3047 case 20: /* UserParametersInformation */
3048 /* USER_READ_ACCOUNT */
3049 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3051 case 21: /* UserAllInformation */
3053 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3055 case 18: /* UserInternal1Information */
3057 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3059 case 23: /* UserInternal4Information */
3060 case 24: /* UserInternal4InformationNew */
3061 case 25: /* UserInternal4InformationNew */
3062 case 26: /* UserInternal5InformationNew */
3064 return NT_STATUS_INVALID_INFO_CLASS;
3068 uinfo = policy_handle_find(p, r->in.user_handle,
3069 acc_required, &acc_granted,
3070 struct samr_user_info, &status);
3071 if (!NT_STATUS_IS_OK(status)) {
3075 domain_sid = uinfo->sid;
3077 sid_split_rid(&domain_sid, &rid);
3079 if (!sid_check_is_in_our_domain(&uinfo->sid))
3080 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3082 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3083 sid_string_dbg(&uinfo->sid)));
3085 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3087 return NT_STATUS_NO_MEMORY;
3090 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3092 if (!(pwd = samu_new(p->mem_ctx))) {
3093 return NT_STATUS_NO_MEMORY;
3097 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3101 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3103 return NT_STATUS_NO_SUCH_USER;
3106 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3108 samr_clear_sam_passwd(pwd);
3110 switch (r->in.level) {
3112 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3115 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3118 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3121 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3124 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3127 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3130 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3133 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3136 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3139 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3142 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3145 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3148 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3151 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3154 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3157 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3160 /* level 18 is special */
3161 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3165 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3168 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3171 status = NT_STATUS_INVALID_INFO_CLASS;
3175 if (!NT_STATUS_IS_OK(status)) {
3179 *r->out.info = user_info;
3184 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3189 /****************************************************************
3190 ****************************************************************/
3192 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3193 struct samr_QueryUserInfo2 *r)
3195 struct samr_QueryUserInfo u;
3197 u.in.user_handle = r->in.user_handle;
3198 u.in.level = r->in.level;
3199 u.out.info = r->out.info;
3201 return _samr_QueryUserInfo(p, &u);
3204 /*******************************************************************
3205 _samr_GetGroupsForUser
3206 ********************************************************************/
3208 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3209 struct samr_GetGroupsForUser *r)
3211 struct samr_user_info *uinfo;
3212 struct samu *sam_pass=NULL;
3213 struct dom_sid *sids;
3214 struct samr_RidWithAttribute dom_gid;
3215 struct samr_RidWithAttribute *gids = NULL;
3216 uint32 primary_group_rid;
3217 size_t num_groups = 0;
3222 bool success = False;
3224 struct samr_RidWithAttributeArray *rids = NULL;
3227 * from the SID in the request:
3228 * we should send back the list of DOMAIN GROUPS
3229 * the user is a member of
3231 * and only the DOMAIN GROUPS
3232 * no ALIASES !!! neither aliases of the domain
3233 * nor aliases of the builtin SID
3238 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3240 uinfo = policy_handle_find(p, r->in.user_handle,
3241 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3242 struct samr_user_info, &result);
3243 if (!NT_STATUS_IS_OK(result)) {
3247 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3249 return NT_STATUS_NO_MEMORY;
3252 if (!sid_check_is_in_our_domain(&uinfo->sid))
3253 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3255 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3256 return NT_STATUS_NO_MEMORY;
3260 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3264 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3265 sid_string_dbg(&uinfo->sid)));
3266 return NT_STATUS_NO_SUCH_USER;
3271 /* make both calls inside the root block */
3273 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3274 &sids, &unix_gids, &num_groups);
3275 if ( NT_STATUS_IS_OK(result) ) {
3276 success = sid_peek_check_rid(get_global_sam_sid(),
3277 pdb_get_group_sid(sam_pass),
3278 &primary_group_rid);
3282 if (!NT_STATUS_IS_OK(result)) {
3283 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3284 sid_string_dbg(&uinfo->sid)));
3289 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3290 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3291 pdb_get_username(sam_pass)));
3292 TALLOC_FREE(sam_pass);
3293 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3299 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3301 dom_gid.rid = primary_group_rid;
3302 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3304 for (i=0; i<num_groups; i++) {
3306 if (!sid_peek_check_rid(get_global_sam_sid(),
3307 &(sids[i]), &dom_gid.rid)) {
3308 DEBUG(10, ("Found sid %s not in our domain\n",
3309 sid_string_dbg(&sids[i])));
3313 if (dom_gid.rid == primary_group_rid) {
3314 /* We added the primary group directly from the
3315 * sam_account. The other SIDs are unique from
3316 * enum_group_memberships */
3320 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3323 rids->count = num_gids;
3326 *r->out.rids = rids;
3328 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3333 /*******************************************************************
3334 ********************************************************************/
3336 static uint32_t samr_get_server_role(void)
3338 uint32_t role = ROLE_DOMAIN_PDC;
3340 if (lp_server_role() == ROLE_DOMAIN_BDC) {
3341 role = ROLE_DOMAIN_BDC;
3347 /*******************************************************************
3348 ********************************************************************/
3350 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3351 struct samr_DomInfo1 *r)
3353 uint32_t account_policy_temp;
3354 time_t u_expire, u_min_age;
3360 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3361 r->min_password_length = account_policy_temp;
3363 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3364 r->password_history_length = account_policy_temp;
3366 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3367 &r->password_properties);
3369 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3370 u_expire = account_policy_temp;
3372 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3373 u_min_age = account_policy_temp;
3379 unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3380 unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3382 if (lp_check_password_script() && *lp_check_password_script()) {
3383 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3386 return NT_STATUS_OK;
3389 /*******************************************************************
3390 ********************************************************************/
3392 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3393 struct samr_DomGeneralInformation *r,
3394 struct samr_domain_info *dinfo)
3403 r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3404 r->num_groups = count_sam_groups(dinfo->disp_info);
3405 r->num_aliases = count_sam_aliases(dinfo->disp_info);
3407 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3409 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3411 if (!pdb_get_seq_num(&seq_num)) {
3412 seq_num = time(NULL);
3419 r->oem_information.string = lp_serverstring();
3420 r->domain_name.string = lp_workgroup();
3421 r->primary.string = global_myname();
3422 r->sequence_num = seq_num;
3423 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3424 r->role = (enum samr_Role) samr_get_server_role();
3427 return NT_STATUS_OK;
3430 /*******************************************************************
3431 ********************************************************************/
3433 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3434 struct samr_DomInfo3 *r)
3444 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3445 u_logout = (time_t)ul;
3452 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3454 return NT_STATUS_OK;
3457 /*******************************************************************
3458 ********************************************************************/
3460 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3461 struct samr_DomOEMInformation *r)
3463 r->oem_information.string = lp_serverstring();
3465 return NT_STATUS_OK;
3468 /*******************************************************************
3469 ********************************************************************/
3471 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3472 struct samr_DomInfo5 *r)
3474 r->domain_name.string = get_global_sam_name();
3476 return NT_STATUS_OK;
3479 /*******************************************************************
3480 ********************************************************************/
3482 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3483 struct samr_DomInfo6 *r)
3485 /* NT returns its own name when a PDC. win2k and later
3486 * only the name of the PDC if itself is a BDC (samba4
3488 r->primary.string = global_myname();
3490 return NT_STATUS_OK;
3493 /*******************************************************************
3494 ********************************************************************/
3496 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3497 struct samr_DomInfo7 *r)
3499 r->role = (enum samr_Role) samr_get_server_role();
3501 return NT_STATUS_OK;
3504 /*******************************************************************
3505 ********************************************************************/
3507 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3508 struct samr_DomInfo8 *r)
3516 if (!pdb_get_seq_num(&seq_num)) {
3517 seq_num = time(NULL);
3524 r->sequence_num = seq_num;
3525 r->domain_create_time = 0;
3527 return NT_STATUS_OK;
3530 /*******************************************************************
3531 ********************************************************************/
3533 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3534 struct samr_DomInfo9 *r)
3536 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3538 return NT_STATUS_OK;
3541 /*******************************************************************
3542 ********************************************************************/
3544 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3545 struct samr_DomGeneralInformation2 *r,
3546 struct samr_domain_info *dinfo)
3549 uint32_t account_policy_temp;
3550 time_t u_lock_duration, u_reset_time;
3552 status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3553 if (!NT_STATUS_IS_OK(status)) {
3561 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3562 u_lock_duration = account_policy_temp;
3563 if (u_lock_duration != -1) {
3564 u_lock_duration *= 60;
3567 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3568 u_reset_time = account_policy_temp * 60;
3570 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3571 r->lockout_threshold = account_policy_temp;
3577 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3578 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3580 return NT_STATUS_OK;
3583 /*******************************************************************
3584 ********************************************************************/
3586 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3587 struct samr_DomInfo12 *r)
3589 uint32_t account_policy_temp;
3590 time_t u_lock_duration, u_reset_time;
3596 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3597 u_lock_duration = account_policy_temp;
3598 if (u_lock_duration != -1) {
3599 u_lock_duration *= 60;
3602 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3603 u_reset_time = account_policy_temp * 60;
3605 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3606 r->lockout_threshold = account_policy_temp;
3612 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3613 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3615 return NT_STATUS_OK;
3618 /*******************************************************************
3619 ********************************************************************/
3621 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3622 struct samr_DomInfo13 *r)
3630 if (!pdb_get_seq_num(&seq_num)) {
3631 seq_num = time(NULL);
3638 r->sequence_num = seq_num;
3639 r->domain_create_time = 0;
3640 r->modified_count_at_last_promotion = 0;
3642 return NT_STATUS_OK;
3645 /*******************************************************************
3646 _samr_QueryDomainInfo
3647 ********************************************************************/
3649 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3650 struct samr_QueryDomainInfo *r)
3652 NTSTATUS status = NT_STATUS_OK;
3653 struct samr_domain_info *dinfo;
3654 union samr_DomainInfo *dom_info;
3656 uint32_t acc_required;
3658 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3660 switch (r->in.level) {
3661 case 1: /* DomainPasswordInformation */
3662 case 12: /* DomainLockoutInformation */
3663 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3664 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3666 case 11: /* DomainGeneralInformation2 */
3667 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3668 * DOMAIN_READ_OTHER_PARAMETERS */
3669 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3670 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3672 case 2: /* DomainGeneralInformation */
3673 case 3: /* DomainLogoffInformation */
3674 case 4: /* DomainOemInformation */
3675 case 5: /* DomainReplicationInformation */
3676 case 6: /* DomainReplicationInformation */
3677 case 7: /* DomainServerRoleInformation */
3678 case 8: /* DomainModifiedInformation */
3679 case 9: /* DomainStateInformation */
3680 case 10: /* DomainUasInformation */
3681 case 13: /* DomainModifiedInformation2 */
3682 /* DOMAIN_READ_OTHER_PARAMETERS */
3683 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3686 return NT_STATUS_INVALID_INFO_CLASS;
3689 dinfo = policy_handle_find(p, r->in.domain_handle,
3691 struct samr_domain_info, &status);
3692 if (!NT_STATUS_IS_OK(status)) {
3696 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3698 return NT_STATUS_NO_MEMORY;
3701 switch (r->in.level) {
3703 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3706 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3709 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3712 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3715 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3718 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3721 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3724 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3727 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3730 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3733 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3736 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3739 return NT_STATUS_INVALID_INFO_CLASS;
3742 if (!NT_STATUS_IS_OK(status)) {
3746 *r->out.info = dom_info;
3748 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3753 /* W2k3 seems to use the same check for all 3 objects that can be created via
3754 * SAMR, if you try to create for example "Dialup" as an alias it says
3755 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3758 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3760 enum lsa_SidType type;
3763 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3766 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3767 * whether the name already exists */
3768 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3769 NULL, NULL, NULL, &type);
3773 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3774 return NT_STATUS_OK;
3777 DEBUG(5, ("trying to create %s, exists as %s\n",
3778 new_name, sid_type_lookup(type)));
3780 if (type == SID_NAME_DOM_GRP) {
3781 return NT_STATUS_GROUP_EXISTS;
3783 if (type == SID_NAME_ALIAS) {
3784 return NT_STATUS_ALIAS_EXISTS;
3787 /* Yes, the default is NT_STATUS_USER_EXISTS */
3788 return NT_STATUS_USER_EXISTS;
3791 /*******************************************************************
3793 ********************************************************************/
3795 NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3796 struct samr_CreateUser2 *r)
3798 const char *account = NULL;
3800 uint32_t acb_info = r->in.acct_flags;
3801 struct samr_domain_info *dinfo;
3802 struct samr_user_info *uinfo;
3805 struct security_descriptor *psd;
3807 /* check this, when giving away 'add computer to domain' privs */
3808 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3809 bool can_add_account = False;
3812 dinfo = policy_handle_find(p, r->in.domain_handle,
3813 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3814 struct samr_domain_info, &nt_status);
3815 if (!NT_STATUS_IS_OK(nt_status)) {
3819 if (sid_check_is_builtin(&dinfo->sid)) {
3820 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3821 return NT_STATUS_ACCESS_DENIED;
3824 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3825 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3826 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3827 this parameter is not an account type */
3828 return NT_STATUS_INVALID_PARAMETER;
3831 account = r->in.account_name->string;
3832 if (account == NULL) {
3833 return NT_STATUS_NO_MEMORY;
3836 nt_status = can_create(p->mem_ctx, account);
3837 if (!NT_STATUS_IS_OK(nt_status)) {
3841 /* determine which user right we need to check based on the acb_info */
3843 if (geteuid() == sec_initial_uid()) {
3844 se_priv_copy(&se_rights, &se_priv_none);
3845 can_add_account = true;
3846 } else if (acb_info & ACB_WSTRUST) {
3847 se_priv_copy(&se_rights, &se_machine_account);
3848 can_add_account = user_has_privileges(
3849 p->server_info->ptok, &se_rights );
3850 } else if (acb_info & ACB_NORMAL &&
3851 (account[strlen(account)-1] != '$')) {
3852 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3853 account for domain trusts and changes the ACB flags later */
3854 se_priv_copy(&se_rights, &se_add_users);
3855 can_add_account = user_has_privileges(
3856 p->server_info->ptok, &se_rights );
3857 } else if (lp_enable_privileges()) {
3858 /* implicit assumption of a BDC or domain trust account here
3859 * (we already check the flags earlier) */
3860 /* only Domain Admins can add a BDC or domain trust */
3861 se_priv_copy(&se_rights, &se_priv_none);
3862 can_add_account = nt_token_check_domain_rid(
3863 p->server_info->ptok,
3864 DOMAIN_RID_ADMINS );
3867 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3868 uidtoname(p->server_info->utok.uid),
3869 can_add_account ? "True":"False" ));
3871 if (!can_add_account) {
3872 return NT_STATUS_ACCESS_DENIED;
3875 /********** BEGIN Admin BLOCK **********/
3878 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3882 /********** END Admin BLOCK **********/
3884 /* now check for failure */
3886 if ( !NT_STATUS_IS_OK(nt_status) )
3889 /* Get the user's SID */
3891 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3893 map_max_allowed_access(p->server_info->ptok,
3894 &p->server_info->utok,
3897 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3898 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3899 se_map_generic(&des_access, &usr_generic_mapping);
3902 * JRA - TESTME. We just created this user so we
3903 * had rights to create them. Do we need to check
3904 * any further access on this object ? Can't we
3905 * just assume we have all the rights we need ?
3908 nt_status = access_check_object(psd, p->server_info->ptok,
3909 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3910 &acc_granted, "_samr_CreateUser2");
3912 if ( !NT_STATUS_IS_OK(nt_status) ) {
3916 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3917 struct samr_user_info, &nt_status);
3918 if (!NT_STATUS_IS_OK(nt_status)) {
3923 /* After a "set" ensure we have no cached display info. */
3924 force_flush_samr_cache(&sid);
3926 *r->out.access_granted = acc_granted;
3928 return NT_STATUS_OK;
3931 /****************************************************************
3932 ****************************************************************/
3934 NTSTATUS _samr_CreateUser(struct pipes_struct *p,
3935 struct samr_CreateUser *r)
3937 struct samr_CreateUser2 c;
3938 uint32_t access_granted;
3940 c.in.domain_handle = r->in.domain_handle;
3941 c.in.account_name = r->in.account_name;
3942 c.in.acct_flags = ACB_NORMAL;
3943 c.in.access_mask = r->in.access_mask;
3944 c.out.user_handle = r->out.user_handle;
3945 c.out.access_granted = &access_granted;
3946 c.out.rid = r->out.rid;
3948 return _samr_CreateUser2(p, &c);
3951 /*******************************************************************
3953 ********************************************************************/
3955 NTSTATUS _samr_Connect(struct pipes_struct *p,
3956 struct samr_Connect *r)
3958 struct samr_connect_info *info;
3959 uint32_t acc_granted;
3960 struct policy_handle hnd;
3961 uint32 des_access = r->in.access_mask;
3966 if (!pipe_access_check(p)) {
3967 DEBUG(3, ("access denied to _samr_Connect\n"));
3968 return NT_STATUS_ACCESS_DENIED;
3971 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3972 was observed from a win98 client trying to enumerate users (when configured
3973 user level access control on shares) --jerry */
3975 map_max_allowed_access(p->server_info->ptok,
3976 &p->server_info->utok,
3979 se_map_generic( &des_access, &sam_generic_mapping );
3981 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3982 |SAMR_ACCESS_LOOKUP_DOMAIN);
3984 /* set up the SAMR connect_anon response */
3986 info = policy_handle_create(p, &hnd, acc_granted,
3987 struct samr_connect_info,
3989 if (!NT_STATUS_IS_OK(status)) {
3993 *r->out.connect_handle = hnd;
3994 return NT_STATUS_OK;
3997 /*******************************************************************
3999 ********************************************************************/
4001 NTSTATUS _samr_Connect2(struct pipes_struct *p,
4002 struct samr_Connect2 *r)
4004 struct samr_connect_info *info = NULL;
4005 struct policy_handle hnd;
4006 struct security_descriptor *psd = NULL;
4008 uint32 des_access = r->in.access_mask;
4011 const char *fn = "_samr_Connect2";
4014 case NDR_SAMR_CONNECT2:
4015 fn = "_samr_Connect2";
4017 case NDR_SAMR_CONNECT3:
4018 fn = "_samr_Connect3";
4020 case NDR_SAMR_CONNECT4:
4021 fn = "_samr_Connect4";
4023 case NDR_SAMR_CONNECT5:
4024 fn = "_samr_Connect5";
4028 DEBUG(5,("%s: %d\n", fn, __LINE__));
4032 if (!pipe_access_check(p)) {
4033 DEBUG(3, ("access denied to %s\n", fn));
4034 return NT_STATUS_ACCESS_DENIED;
4037 map_max_allowed_access(p->server_info->ptok,
4038 &p->server_info->utok,
4041 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
4042 se_map_generic(&des_access, &sam_generic_mapping);
4044 nt_status = access_check_object(psd, p->server_info->ptok,
4045 NULL, 0, des_access, &acc_granted, fn);
4047 if ( !NT_STATUS_IS_OK(nt_status) )
4050 info = policy_handle_create(p, &hnd, acc_granted,
4051 struct samr_connect_info, &nt_status);
4052 if (!NT_STATUS_IS_OK(nt_status)) {
4056 DEBUG(5,("%s: %d\n", fn, __LINE__));
4058 *r->out.connect_handle = hnd;
4059 return NT_STATUS_OK;
4062 /****************************************************************
4064 ****************************************************************/
4066 NTSTATUS _samr_Connect3(struct pipes_struct *p,
4067 struct samr_Connect3 *r)
4069 struct samr_Connect2 c;
4071 c.in.system_name = r->in.system_name;
4072 c.in.access_mask = r->in.access_mask;
4073 c.out.connect_handle = r->out.connect_handle;
4075 return _samr_Connect2(p, &c);
4078 /*******************************************************************
4080 ********************************************************************/
4082 NTSTATUS _samr_Connect4(struct pipes_struct *p,
4083 struct samr_Connect4 *r)
4085 struct samr_Connect2 c;
4087 c.in.system_name = r->in.system_name;
4088 c.in.access_mask = r->in.access_mask;
4089 c.out.connect_handle = r->out.connect_handle;
4091 return _samr_Connect2(p, &c);
4094 /*******************************************************************
4096 ********************************************************************/
4098 NTSTATUS _samr_Connect5(struct pipes_struct *p,
4099 struct samr_Connect5 *r)
4102 struct samr_Connect2 c;
4103 struct samr_ConnectInfo1 info1;
4105 info1.client_version = SAMR_CONNECT_AFTER_W2K;
4108 c.in.system_name = r->in.system_name;
4109 c.in.access_mask = r->in.access_mask;
4110 c.out.connect_handle = r->out.connect_handle;
4112 *r->out.level_out = 1;
4114 status = _samr_Connect2(p, &c);
4115 if (!NT_STATUS_IS_OK(status)) {
4119 r->out.info_out->info1 = info1;
4121 return NT_STATUS_OK;
4124 /**********************************************************************
4126 **********************************************************************/
4128 NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
4129 struct samr_LookupDomain *r)
4132 struct samr_connect_info *info;
4133 const char *domain_name;
4134 struct dom_sid *sid = NULL;
4136 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4137 Reverted that change so we will work with RAS servers again */
4139 info = policy_handle_find(p, r->in.connect_handle,
4140 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4141 struct samr_connect_info,
4143 if (!NT_STATUS_IS_OK(status)) {
4147 domain_name = r->in.domain_name->string;
4149 return NT_STATUS_INVALID_PARAMETER;
4152 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
4154 return NT_STATUS_NO_MEMORY;
4157 if (strequal(domain_name, builtin_domain_name())) {
4158 sid_copy(sid, &global_sid_Builtin);
4160 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4161 status = NT_STATUS_NO_SUCH_DOMAIN;
4165 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4166 sid_string_dbg(sid)));
4173 /**********************************************************************
4175 **********************************************************************/
4177 NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4178 struct samr_EnumDomains *r)
4181 struct samr_connect_info *info;
4182 uint32_t num_entries = 2;
4183 struct samr_SamEntry *entry_array = NULL;
4184 struct samr_SamArray *sam;
4186 info = policy_handle_find(p, r->in.connect_handle,
4187 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4188 struct samr_connect_info, &status);
4189 if (!NT_STATUS_IS_OK(status)) {
4193 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4195 return NT_STATUS_NO_MEMORY;
4198 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4199 struct samr_SamEntry,
4202 return NT_STATUS_NO_MEMORY;
4205 entry_array[0].idx = 0;
4206 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4208 entry_array[1].idx = 1;
4209 init_lsa_String(&entry_array[1].name, "Builtin");
4211 sam->count = num_entries;
4212 sam->entries = entry_array;
4215 *r->out.num_entries = num_entries;
4220 /*******************************************************************
4222 ********************************************************************/
4224 NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4225 struct samr_OpenAlias *r)
4228 uint32 alias_rid = r->in.rid;
4229 struct samr_alias_info *ainfo;
4230 struct samr_domain_info *dinfo;
4231 struct security_descriptor *psd = NULL;
4233 uint32 des_access = r->in.access_mask;
4238 dinfo = policy_handle_find(p, r->in.domain_handle,
4239 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4240 struct samr_domain_info, &status);
4241 if (!NT_STATUS_IS_OK(status)) {
4245 /* append the alias' RID to it */
4247 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4248 return NT_STATUS_NO_SUCH_ALIAS;
4250 /*check if access can be granted as requested by client. */
4252 map_max_allowed_access(p->server_info->ptok,
4253 &p->server_info->utok,
4256 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4257 se_map_generic(&des_access,&ali_generic_mapping);
4259 se_priv_copy( &se_rights, &se_add_users );
4261 status = access_check_object(psd, p->server_info->ptok,
4262 &se_rights, GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4263 des_access, &acc_granted, "_samr_OpenAlias");
4265 if ( !NT_STATUS_IS_OK(status) )
4269 /* Check we actually have the requested alias */
4270 enum lsa_SidType type;
4275 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4278 if (!result || (type != SID_NAME_ALIAS)) {
4279 return NT_STATUS_NO_SUCH_ALIAS;
4282 /* make sure there is a mapping */
4284 if ( !sid_to_gid( &sid, &gid ) ) {
4285 return NT_STATUS_NO_SUCH_ALIAS;
4290 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4291 struct samr_alias_info, &status);
4292 if (!NT_STATUS_IS_OK(status)) {
4297 return NT_STATUS_OK;
4300 /*******************************************************************
4302 ********************************************************************/
4304 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4305 struct samr_UserInfo2 *id2,
4309 DEBUG(5,("set_user_info_2: NULL id2\n"));
4310 return NT_STATUS_ACCESS_DENIED;
4313 copy_id2_to_sam_passwd(pwd, id2);
4315 return pdb_update_sam_account(pwd);
4318 /*******************************************************************
4320 ********************************************************************/
4322 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4323 struct samr_UserInfo4 *id4,
4327 DEBUG(5,("set_user_info_2: NULL id4\n"));
4328 return NT_STATUS_ACCESS_DENIED;
4331 copy_id4_to_sam_passwd(pwd, id4);
4333 return pdb_update_sam_account(pwd);
4336 /*******************************************************************
4338 ********************************************************************/
4340 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4341 struct samr_UserInfo6 *id6,
4345 DEBUG(5,("set_user_info_6: NULL id6\n"));
4346 return NT_STATUS_ACCESS_DENIED;
4349 copy_id6_to_sam_passwd(pwd, id6);
4351 return pdb_update_sam_account(pwd);
4354 /*******************************************************************
4356 ********************************************************************/
4358 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4359 struct samr_UserInfo7 *id7,
4365 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4366 return NT_STATUS_ACCESS_DENIED;
4369 if (!id7->account_name.string) {
4370 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4371 return NT_STATUS_ACCESS_DENIED;
4374 /* check to see if the new username already exists. Note: we can't
4375 reliably lock all backends, so there is potentially the
4376 possibility that a user can be created in between this check and
4377 the rename. The rename should fail, but may not get the
4378 exact same failure status code. I think this is small enough
4379 of a window for this type of operation and the results are
4380 simply that the rename fails with a slightly different status
4381 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4383 rc = can_create(mem_ctx, id7->account_name.string);
4385 /* when there is nothing to change, we're done here */
4386 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4387 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4388 return NT_STATUS_OK;
4390 if (!NT_STATUS_IS_OK(rc)) {
4394 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4399 /*******************************************************************
4401 ********************************************************************/
4403 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4404 struct samr_UserInfo8 *id8,
4408 DEBUG(5,("set_user_info_8: NULL id8\n"));
4409 return NT_STATUS_ACCESS_DENIED;
4412 copy_id8_to_sam_passwd(pwd, id8);
4414 return pdb_update_sam_account(pwd);
4417 /*******************************************************************
4419 ********************************************************************/
4421 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4422 struct samr_UserInfo10 *id10,
4426 DEBUG(5,("set_user_info_8: NULL id10\n"));
4427 return NT_STATUS_ACCESS_DENIED;
4430 copy_id10_to_sam_passwd(pwd, id10);
4432 return pdb_update_sam_account(pwd);
4435 /*******************************************************************
4437 ********************************************************************/
4439 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4440 struct samr_UserInfo11 *id11,
4444 DEBUG(5,("set_user_info_11: NULL id11\n"));
4445 return NT_STATUS_ACCESS_DENIED;
4448 copy_id11_to_sam_passwd(pwd, id11);
4450 return pdb_update_sam_account(pwd);
4453 /*******************************************************************
4455 ********************************************************************/
4457 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4458 struct samr_UserInfo12 *id12,
4462 DEBUG(5,("set_user_info_12: NULL id12\n"));
4463 return NT_STATUS_ACCESS_DENIED;
4466 copy_id12_to_sam_passwd(pwd, id12);
4468 return pdb_update_sam_account(pwd);
4471 /*******************************************************************
4473 ********************************************************************/
4475 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4476 struct samr_UserInfo13 *id13,
4480 DEBUG(5,("set_user_info_13: NULL id13\n"));
4481 return NT_STATUS_ACCESS_DENIED;
4484 copy_id13_to_sam_passwd(pwd, id13);
4486 return pdb_update_sam_account(pwd);
4489 /*******************************************************************
4491 ********************************************************************/
4493 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4494 struct samr_UserInfo14 *id14,
4498 DEBUG(5,("set_user_info_14: NULL id14\n"));
4499 return NT_STATUS_ACCESS_DENIED;
4502 copy_id14_to_sam_passwd(pwd, id14);
4504 return pdb_update_sam_account(pwd);
4507 /*******************************************************************
4509 ********************************************************************/
4511 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4512 struct samr_UserInfo16 *id16,
4516 DEBUG(5,("set_user_info_16: NULL id16\n"));
4517 return NT_STATUS_ACCESS_DENIED;
4520 copy_id16_to_sam_passwd(pwd, id16);
4522 return pdb_update_sam_account(pwd);
4525 /*******************************************************************
4527 ********************************************************************/
4529 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4530 struct samr_UserInfo17 *id17,
4534 DEBUG(5,("set_user_info_17: NULL id17\n"));
4535 return NT_STATUS_ACCESS_DENIED;
4538 copy_id17_to_sam_passwd(pwd, id17);
4540 return pdb_update_sam_account(pwd);
4543 /*******************************************************************
4545 ********************************************************************/
4547 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4548 TALLOC_CTX *mem_ctx,
4549 DATA_BLOB *session_key,
4553 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4554 return NT_STATUS_INVALID_PARAMETER;
4557 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4558 if (!session_key->length) {
4559 return NT_STATUS_NO_USER_SESSION_KEY;
4563 if (id18->nt_pwd_active) {
4567 in = data_blob_const(id18->nt_pwd.hash, 16);
4568 out = data_blob_talloc_zero(mem_ctx, 16);
4570 sess_crypt_blob(&out, &in, session_key, false);
4572 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4573 return NT_STATUS_ACCESS_DENIED;
4576 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4579 if (id18->lm_pwd_active) {
4583 in = data_blob_const(id18->lm_pwd.hash, 16);
4584 out = data_blob_talloc_zero(mem_ctx, 16);
4586 sess_crypt_blob(&out, &in, session_key, false);
4588 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4589 return NT_STATUS_ACCESS_DENIED;
4592 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4595 copy_id18_to_sam_passwd(pwd, id18);
4597 return pdb_update_sam_account(pwd);
4600 /*******************************************************************
4602 ********************************************************************/
4604 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4605 struct samr_UserInfo20 *id20,
4609 DEBUG(5,("set_user_info_20: NULL id20\n"));
4610 return NT_STATUS_ACCESS_DENIED;
4613 copy_id20_to_sam_passwd(pwd, id20);
4615 return pdb_update_sam_account(pwd);
4618 /*******************************************************************
4620 ********************************************************************/
4622 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4623 TALLOC_CTX *mem_ctx,
4624 DATA_BLOB *session_key,
4630 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4631 return NT_STATUS_INVALID_PARAMETER;
4634 if (id21->fields_present == 0) {
4635 return NT_STATUS_INVALID_PARAMETER;
4638 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4639 return NT_STATUS_ACCESS_DENIED;
4642 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4643 if (id21->nt_password_set) {
4646 if ((id21->nt_owf_password.length != 16) ||
4647 (id21->nt_owf_password.size != 16)) {
4648 return NT_STATUS_INVALID_PARAMETER;
4651 if (!session_key->length) {
4652 return NT_STATUS_NO_USER_SESSION_KEY;
4655 in = data_blob_const(id21->nt_owf_password.array, 16);
4656 out = data_blob_talloc_zero(mem_ctx, 16);
4658 sess_crypt_blob(&out, &in, session_key, false);
4660 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4661 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4665 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4666 if (id21->lm_password_set) {
4669 if ((id21->lm_owf_password.length != 16) ||
4670 (id21->lm_owf_password.size != 16)) {
4671 return NT_STATUS_INVALID_PARAMETER;
4674 if (!session_key->length) {
4675 return NT_STATUS_NO_USER_SESSION_KEY;
4678 in = data_blob_const(id21->lm_owf_password.array, 16);
4679 out = data_blob_talloc_zero(mem_ctx, 16);
4681 sess_crypt_blob(&out, &in, session_key, false);
4683 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4684 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4688 /* we need to separately check for an account rename first */
4690 if (id21->account_name.string &&
4691 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4694 /* check to see if the new username already exists. Note: we can't
4695 reliably lock all backends, so there is potentially the
4696 possibility that a user can be created in between this check and
4697 the rename. The rename should fail, but may not get the
4698 exact same failure status code. I think this is small enough
4699 of a window for this type of operation and the results are
4700 simply that the rename fails with a slightly different status
4701 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4703 status = can_create(mem_ctx, id21->account_name.string);
4704 if (!NT_STATUS_IS_OK(status)) {
4708 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4710 if (!NT_STATUS_IS_OK(status)) {
4711 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4712 nt_errstr(status)));
4716 /* set the new username so that later
4717 functions can work on the new account */
4718 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4721 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4724 * The funny part about the previous two calls is
4725 * that pwd still has the password hashes from the
4726 * passdb entry. These have not been updated from
4727 * id21. I don't know if they need to be set. --jerry
4730 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4731 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4732 if ( !NT_STATUS_IS_OK(status) ) {
4737 /* Don't worry about writing out the user account since the
4738 primary group SID is generated solely from the user's Unix
4741 /* write the change out */
4742 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4746 return NT_STATUS_OK;
4749 /*******************************************************************
4751 ********************************************************************/
4753 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4754 struct samr_UserInfo23 *id23,
4758 char *plaintext_buf = NULL;
4764 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4765 return NT_STATUS_INVALID_PARAMETER;
4768 if (id23->info.fields_present == 0) {
4769 return NT_STATUS_INVALID_PARAMETER;
4772 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4773 return NT_STATUS_ACCESS_DENIED;
4776 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4777 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4779 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4780 pdb_get_username(pwd)));
4782 if (!decode_pw_buffer(mem_ctx,
4783 id23->password.data,
4787 return NT_STATUS_WRONG_PASSWORD;
4790 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4791 return NT_STATUS_ACCESS_DENIED;
4795 copy_id23_to_sam_passwd(pwd, id23);
4797 acct_ctrl = pdb_get_acct_ctrl(pwd);
4799 /* if it's a trust account, don't update /etc/passwd */
4800 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4801 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4802 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4803 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4804 } else if (plaintext_buf) {
4805 /* update the UNIX password */
4806 if (lp_unix_password_sync() ) {
4807 struct passwd *passwd;
4808 if (pdb_get_username(pwd) == NULL) {
4809 DEBUG(1, ("chgpasswd: User without name???\n"));
4810 return NT_STATUS_ACCESS_DENIED;
4813 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4814 if (passwd == NULL) {
4815 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4818 if(!chgpasswd(pdb_get_username(pwd), rhost,
4819 passwd, "", plaintext_buf, True)) {
4820 return NT_STATUS_ACCESS_DENIED;
4822 TALLOC_FREE(passwd);
4826 if (plaintext_buf) {
4827 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4830 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4831 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4836 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4840 return NT_STATUS_OK;
4843 /*******************************************************************
4845 ********************************************************************/
4847 static bool set_user_info_pw(uint8 *pass, const char *rhost, struct samu *pwd)
4850 char *plaintext_buf = NULL;
4853 DEBUG(5, ("Attempting administrator password change for user %s\n",
4854 pdb_get_username(pwd)));
4856 acct_ctrl = pdb_get_acct_ctrl(pwd);
4858 if (!decode_pw_buffer(talloc_tos(),
4866 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4870 /* if it's a trust account, don't update /etc/passwd */
4871 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4872 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4873 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4874 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4876 /* update the UNIX password */
4877 if (lp_unix_password_sync()) {
4878 struct passwd *passwd;
4880 if (pdb_get_username(pwd) == NULL) {
4881 DEBUG(1, ("chgpasswd: User without name???\n"));
4885 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4886 if (passwd == NULL) {
4887 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4890 if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
4891 "", plaintext_buf, True)) {
4894 TALLOC_FREE(passwd);
4898 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4900 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4905 /*******************************************************************
4907 ********************************************************************/
4909 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4911 struct samr_UserInfo24 *id24,
4917 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4918 return NT_STATUS_INVALID_PARAMETER;
4921 if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
4922 return NT_STATUS_WRONG_PASSWORD;
4925 copy_id24_to_sam_passwd(pwd, id24);
4927 status = pdb_update_sam_account(pwd);
4928 if (!NT_STATUS_IS_OK(status)) {
4932 return NT_STATUS_OK;
4935 /*******************************************************************
4937 ********************************************************************/
4939 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4941 struct samr_UserInfo25 *id25,
4947 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4948 return NT_STATUS_INVALID_PARAMETER;
4951 if (id25->info.fields_present == 0) {
4952 return NT_STATUS_INVALID_PARAMETER;
4955 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4956 return NT_STATUS_ACCESS_DENIED;
4959 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4960 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4962 if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
4963 return NT_STATUS_WRONG_PASSWORD;
4967 copy_id25_to_sam_passwd(pwd, id25);
4969 /* write the change out */
4970 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4975 * We need to "pdb_update_sam_account" before the unix primary group
4976 * is set, because the idealx scripts would also change the
4977 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4978 * the delete explicit / add explicit, which would then fail to find
4979 * the previous primaryGroupSid value.
4982 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4983 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4984 if ( !NT_STATUS_IS_OK(status) ) {
4989 return NT_STATUS_OK;
4992 /*******************************************************************
4994 ********************************************************************/
4996 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4998 struct samr_UserInfo26 *id26,
5004 DEBUG(5, ("set_user_info_26: NULL id26\n"));
5005 return NT_STATUS_INVALID_PARAMETER;
5008 if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
5009 return NT_STATUS_WRONG_PASSWORD;
5012 copy_id26_to_sam_passwd(pwd, id26);
5014 status = pdb_update_sam_account(pwd);
5015 if (!NT_STATUS_IS_OK(status)) {
5019 return NT_STATUS_OK;
5022 /*************************************************************
5023 **************************************************************/
5025 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
5027 uint32_t acc_required = 0;
5029 /* USER_ALL_USERNAME */
5030 if (fields & SAMR_FIELD_ACCOUNT_NAME)
5031 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5032 /* USER_ALL_FULLNAME */
5033 if (fields & SAMR_FIELD_FULL_NAME)
5034 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5035 /* USER_ALL_PRIMARYGROUPID */
5036 if (fields & SAMR_FIELD_PRIMARY_GID)
5037 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5038 /* USER_ALL_HOMEDIRECTORY */
5039 if (fields & SAMR_FIELD_HOME_DIRECTORY)
5040 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5041 /* USER_ALL_HOMEDIRECTORYDRIVE */
5042 if (fields & SAMR_FIELD_HOME_DRIVE)
5043 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5044 /* USER_ALL_SCRIPTPATH */
5045 if (fields & SAMR_FIELD_LOGON_SCRIPT)
5046 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5047 /* USER_ALL_PROFILEPATH */
5048 if (fields & SAMR_FIELD_PROFILE_PATH)
5049 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5050 /* USER_ALL_ADMINCOMMENT */
5051 if (fields & SAMR_FIELD_COMMENT)
5052 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5053 /* USER_ALL_WORKSTATIONS */
5054 if (fields & SAMR_FIELD_WORKSTATIONS)
5055 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5056 /* USER_ALL_LOGONHOURS */
5057 if (fields & SAMR_FIELD_LOGON_HOURS)
5058 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5059 /* USER_ALL_ACCOUNTEXPIRES */
5060 if (fields & SAMR_FIELD_ACCT_EXPIRY)
5061 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5062 /* USER_ALL_USERACCOUNTCONTROL */
5063 if (fields & SAMR_FIELD_ACCT_FLAGS)
5064 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5065 /* USER_ALL_PARAMETERS */
5066 if (fields & SAMR_FIELD_PARAMETERS)
5067 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5068 /* USER_ALL_USERCOMMENT */
5069 if (fields & SAMR_FIELD_COMMENT)
5070 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5071 /* USER_ALL_COUNTRYCODE */
5072 if (fields & SAMR_FIELD_COUNTRY_CODE)
5073 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5074 /* USER_ALL_CODEPAGE */
5075 if (fields & SAMR_FIELD_CODE_PAGE)
5076 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5077 /* USER_ALL_NTPASSWORDPRESENT */
5078 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
5079 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5080 /* USER_ALL_LMPASSWORDPRESENT */
5081 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
5082 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5083 /* USER_ALL_PASSWORDEXPIRED */
5084 if (fields & SAMR_FIELD_EXPIRED_FLAG)
5085 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5087 return acc_required;
5090 /*******************************************************************
5092 ********************************************************************/
5094 NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
5095 struct samr_SetUserInfo *r)
5097 struct samr_user_info *uinfo;
5099 struct samu *pwd = NULL;
5100 union samr_UserInfo *info = r->in.info;
5101 uint32_t acc_required = 0;
5102 uint32_t fields = 0;
5105 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
5107 /* This is tricky. A WinXP domain join sets
5108 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5109 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
5110 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5111 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
5112 we'll use the set from the WinXP join as the basis. */
5114 switch (r->in.level) {
5115 case 2: /* UserPreferencesInformation */
5116 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5117 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5119 case 4: /* UserLogonHoursInformation */
5120 case 6: /* UserNameInformation */
5121 case 7: /* UserAccountNameInformation */
5122 case 8: /* UserFullNameInformation */
5123 case 9: /* UserPrimaryGroupInformation */
5124 case 10: /* UserHomeInformation */
5125 case 11: /* UserScriptInformation */
5126 case 12: /* UserProfileInformation */
5127 case 13: /* UserAdminCommentInformation */
5128 case 14: /* UserWorkStationsInformation */
5129 case 16: /* UserControlInformation */
5130 case 17: /* UserExpiresInformation */
5131 case 20: /* UserParametersInformation */
5132 /* USER_WRITE_ACCOUNT */
5133 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5135 case 18: /* UserInternal1Information */
5136 /* FIXME: gd, this is a guess */
5137 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5139 case 21: /* UserAllInformation */
5140 fields = info->info21.fields_present;
5141 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5143 case 23: /* UserInternal4Information */
5144 fields = info->info23.info.fields_present;
5145 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5147 case 25: /* UserInternal4InformationNew */
5148 fields = info->info25.info.fields_present;
5149 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5151 case 24: /* UserInternal5Information */
5152 case 26: /* UserInternal5InformationNew */
5153 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5156 return NT_STATUS_INVALID_INFO_CLASS;
5159 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5160 struct samr_user_info, &status);
5161 if (!NT_STATUS_IS_OK(status)) {
5165 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5166 sid_string_dbg(&uinfo->sid), r->in.level));
5169 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5170 return NT_STATUS_INVALID_INFO_CLASS;
5173 if (!(pwd = samu_new(NULL))) {
5174 return NT_STATUS_NO_MEMORY;
5178 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5183 return NT_STATUS_NO_SUCH_USER;
5186 /* ================ BEGIN Privilege BLOCK ================ */
5190 /* ok! user info levels (lots: see MSDEV help), off we go... */
5192 switch (r->in.level) {
5195 status = set_user_info_2(p->mem_ctx,
5200 status = set_user_info_4(p->mem_ctx,
5205 status = set_user_info_6(p->mem_ctx,
5210 status = set_user_info_7(p->mem_ctx,
5215 status = set_user_info_8(p->mem_ctx,
5220 status = set_user_info_10(p->mem_ctx,
5221 &info->info10, pwd);
5225 status = set_user_info_11(p->mem_ctx,
5226 &info->info11, pwd);
5230 status = set_user_info_12(p->mem_ctx,
5231 &info->info12, pwd);
5235 status = set_user_info_13(p->mem_ctx,
5236 &info->info13, pwd);
5240 status = set_user_info_14(p->mem_ctx,
5241 &info->info14, pwd);
5245 status = set_user_info_16(p->mem_ctx,
5246 &info->info16, pwd);
5250 status = set_user_info_17(p->mem_ctx,
5251 &info->info17, pwd);
5255 /* Used by AS/U JRA. */
5256 status = set_user_info_18(&info->info18,
5258 &p->server_info->user_session_key,
5263 status = set_user_info_20(p->mem_ctx,
5264 &info->info20, pwd);
5268 status = set_user_info_21(&info->info21,
5270 &p->server_info->user_session_key,
5275 if (!p->server_info->user_session_key.length) {
5276 status = NT_STATUS_NO_USER_SESSION_KEY;
5278 arcfour_crypt_blob(info->info23.password.data, 516,
5279 &p->server_info->user_session_key);
5281 dump_data(100, info->info23.password.data, 516);
5283 status = set_user_info_23(p->mem_ctx,
5290 if (!p->server_info->user_session_key.length) {
5291 status = NT_STATUS_NO_USER_SESSION_KEY;
5293 arcfour_crypt_blob(info->info24.password.data,
5295 &p->server_info->user_session_key);
5297 dump_data(100, info->info24.password.data, 516);
5299 status = set_user_info_24(p->mem_ctx,
5301 &info->info24, pwd);
5305 if (!p->server_info->user_session_key.length) {
5306 status = NT_STATUS_NO_USER_SESSION_KEY;
5308 encode_or_decode_arc4_passwd_buffer(
5309 info->info25.password.data,
5310 &p->server_info->user_session_key);
5312 dump_data(100, info->info25.password.data, 532);
5314 status = set_user_info_25(p->mem_ctx,
5316 &info->info25, pwd);
5320 if (!p->server_info->user_session_key.length) {
5321 status = NT_STATUS_NO_USER_SESSION_KEY;
5323 encode_or_decode_arc4_passwd_buffer(
5324 info->info26.password.data,
5325 &p->server_info->user_session_key);
5327 dump_data(100, info->info26.password.data, 516);
5329 status = set_user_info_26(p->mem_ctx,
5331 &info->info26, pwd);
5335 status = NT_STATUS_INVALID_INFO_CLASS;
5342 /* ================ END Privilege BLOCK ================ */
5344 if (NT_STATUS_IS_OK(status)) {
5345 force_flush_samr_cache(&uinfo->sid);
5351 /*******************************************************************
5353 ********************************************************************/
5355 NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
5356 struct samr_SetUserInfo2 *r)
5358 struct samr_SetUserInfo q;
5360 q.in.user_handle = r->in.user_handle;
5361 q.in.level = r->in.level;
5362 q.in.info = r->in.info;
5364 return _samr_SetUserInfo(p, &q);
5367 /*********************************************************************
5368 _samr_GetAliasMembership
5369 *********************************************************************/
5371 NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
5372 struct samr_GetAliasMembership *r)
5374 size_t num_alias_rids;
5376 struct samr_domain_info *dinfo;
5381 struct dom_sid *members;
5383 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5385 dinfo = policy_handle_find(p, r->in.domain_handle,
5386 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5387 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5388 struct samr_domain_info, &status);
5389 if (!NT_STATUS_IS_OK(status)) {
5393 if (!sid_check_is_domain(&dinfo->sid) &&
5394 !sid_check_is_builtin(&dinfo->sid))
5395 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5397 if (r->in.sids->num_sids) {
5398 members = TALLOC_ARRAY(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
5400 if (members == NULL)
5401 return NT_STATUS_NO_MEMORY;
5406 for (i=0; i<r->in.sids->num_sids; i++)
5407 sid_copy(&members[i], r->in.sids->sids[i].sid);
5413 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5414 r->in.sids->num_sids,
5415 &alias_rids, &num_alias_rids);
5418 if (!NT_STATUS_IS_OK(status)) {
5422 r->out.rids->count = num_alias_rids;
5423 r->out.rids->ids = alias_rids;
5425 if (r->out.rids->ids == NULL) {
5426 /* Windows domain clients don't accept a NULL ptr here */
5427 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5429 if (r->out.rids->ids == NULL) {
5430 return NT_STATUS_NO_MEMORY;
5433 return NT_STATUS_OK;
5436 /*********************************************************************
5437 _samr_GetMembersInAlias
5438 *********************************************************************/
5440 NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
5441 struct samr_GetMembersInAlias *r)
5443 struct samr_alias_info *ainfo;
5446 size_t num_sids = 0;
5447 struct lsa_SidPtr *sids = NULL;
5448 struct dom_sid *pdb_sids = NULL;
5450 ainfo = policy_handle_find(p, r->in.alias_handle,
5451 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5452 struct samr_alias_info, &status);
5453 if (!NT_STATUS_IS_OK(status)) {
5457 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5460 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5464 if (!NT_STATUS_IS_OK(status)) {
5469 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5471 TALLOC_FREE(pdb_sids);
5472 return NT_STATUS_NO_MEMORY;
5476 for (i = 0; i < num_sids; i++) {
5477 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5479 TALLOC_FREE(pdb_sids);
5480 return NT_STATUS_NO_MEMORY;
5484 r->out.sids->num_sids = num_sids;
5485 r->out.sids->sids = sids;
5487 TALLOC_FREE(pdb_sids);
5489 return NT_STATUS_OK;
5492 /*********************************************************************
5493 _samr_QueryGroupMember
5494 *********************************************************************/
5496 NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
5497 struct samr_QueryGroupMember *r)
5499 struct samr_group_info *ginfo;
5500 size_t i, num_members;
5506 struct samr_RidTypeArray *rids = NULL;
5508 ginfo = policy_handle_find(p, r->in.group_handle,
5509 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5510 struct samr_group_info, &status);
5511 if (!NT_STATUS_IS_OK(status)) {
5515 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5517 return NT_STATUS_NO_MEMORY;
5520 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5522 if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5523 DEBUG(3, ("sid %s is not in our domain\n",
5524 sid_string_dbg(&ginfo->sid)));
5525 return NT_STATUS_NO_SUCH_GROUP;
5528 DEBUG(10, ("lookup on Domain SID\n"));
5531 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5532 &rid, &num_members);
5535 if (!NT_STATUS_IS_OK(status))
5539 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5541 return NT_STATUS_NO_MEMORY;
5547 for (i=0; i<num_members; i++)
5548 attr[i] = SID_NAME_USER;
5550 rids->count = num_members;
5554 *r->out.rids = rids;
5556 return NT_STATUS_OK;
5559 /*********************************************************************
5560 _samr_AddAliasMember
5561 *********************************************************************/
5563 NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
5564 struct samr_AddAliasMember *r)
5566 struct samr_alias_info *ainfo;
5569 ainfo = policy_handle_find(p, r->in.alias_handle,
5570 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5571 struct samr_alias_info, &status);
5572 if (!NT_STATUS_IS_OK(status)) {
5576 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5578 /******** BEGIN SeAddUsers BLOCK *********/
5581 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5584 /******** END SeAddUsers BLOCK *********/
5586 if (NT_STATUS_IS_OK(status)) {
5587 force_flush_samr_cache(&ainfo->sid);
5593 /*********************************************************************
5594 _samr_DeleteAliasMember
5595 *********************************************************************/
5597 NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
5598 struct samr_DeleteAliasMember *r)
5600 struct samr_alias_info *ainfo;
5603 ainfo = policy_handle_find(p, r->in.alias_handle,
5604 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5605 struct samr_alias_info, &status);
5606 if (!NT_STATUS_IS_OK(status)) {
5610 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5611 sid_string_dbg(&ainfo->sid)));
5613 /******** BEGIN SeAddUsers BLOCK *********/
5616 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5619 /******** END SeAddUsers BLOCK *********/
5621 if (NT_STATUS_IS_OK(status)) {
5622 force_flush_samr_cache(&ainfo->sid);
5628 /*********************************************************************
5629 _samr_AddGroupMember
5630 *********************************************************************/
5632 NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
5633 struct samr_AddGroupMember *r)
5635 struct samr_group_info *ginfo;
5639 ginfo = policy_handle_find(p, r->in.group_handle,
5640 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5641 struct samr_group_info, &status);
5642 if (!NT_STATUS_IS_OK(status)) {
5646 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5648 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5650 return NT_STATUS_INVALID_HANDLE;
5653 /******** BEGIN SeAddUsers BLOCK *********/
5656 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5659 /******** END SeAddUsers BLOCK *********/
5661 force_flush_samr_cache(&ginfo->sid);
5666 /*********************************************************************
5667 _samr_DeleteGroupMember
5668 *********************************************************************/
5670 NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
5671 struct samr_DeleteGroupMember *r)
5674 struct samr_group_info *ginfo;
5679 * delete the group member named r->in.rid
5680 * who is a member of the sid associated with the handle
5681 * the rid is a user's rid as the group is a domain group.
5684 ginfo = policy_handle_find(p, r->in.group_handle,
5685 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5686 struct samr_group_info, &status);
5687 if (!NT_STATUS_IS_OK(status)) {
5691 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5693 return NT_STATUS_INVALID_HANDLE;
5696 /******** BEGIN SeAddUsers BLOCK *********/
5699 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5702 /******** END SeAddUsers BLOCK *********/
5704 force_flush_samr_cache(&ginfo->sid);
5709 /*********************************************************************
5711 *********************************************************************/
5713 NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
5714 struct samr_DeleteUser *r)
5716 struct samr_user_info *uinfo;
5718 struct samu *sam_pass=NULL;
5721 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5723 uinfo = policy_handle_find(p, r->in.user_handle,
5724 SEC_STD_DELETE, NULL,
5725 struct samr_user_info, &status);
5726 if (!NT_STATUS_IS_OK(status)) {
5730 if (!sid_check_is_in_our_domain(&uinfo->sid))
5731 return NT_STATUS_CANNOT_DELETE;
5733 /* check if the user exists before trying to delete */
5734 if ( !(sam_pass = samu_new( NULL )) ) {
5735 return NT_STATUS_NO_MEMORY;
5739 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5743 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5744 sid_string_dbg(&uinfo->sid)));
5745 TALLOC_FREE(sam_pass);
5746 return NT_STATUS_NO_SUCH_USER;
5749 /******** BEGIN SeAddUsers BLOCK *********/
5752 status = pdb_delete_user(p->mem_ctx, sam_pass);
5755 /******** END SeAddUsers BLOCK *********/
5757 if ( !NT_STATUS_IS_OK(status) ) {
5758 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5759 "user %s: %s.\n", pdb_get_username(sam_pass),
5760 nt_errstr(status)));
5761 TALLOC_FREE(sam_pass);
5766 TALLOC_FREE(sam_pass);
5768 force_flush_samr_cache(&uinfo->sid);
5770 if (!close_policy_hnd(p, r->in.user_handle))
5771 return NT_STATUS_OBJECT_NAME_INVALID;
5773 ZERO_STRUCTP(r->out.user_handle);
5775 return NT_STATUS_OK;
5778 /*********************************************************************
5779 _samr_DeleteDomainGroup
5780 *********************************************************************/
5782 NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
5783 struct samr_DeleteDomainGroup *r)
5785 struct samr_group_info *ginfo;
5789 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5791 ginfo = policy_handle_find(p, r->in.group_handle,
5792 SEC_STD_DELETE, NULL,
5793 struct samr_group_info, &status);
5794 if (!NT_STATUS_IS_OK(status)) {
5798 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5800 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5802 return NT_STATUS_NO_SUCH_GROUP;
5805 /******** BEGIN SeAddUsers BLOCK *********/
5808 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5811 /******** END SeAddUsers BLOCK *********/
5813 if ( !NT_STATUS_IS_OK(status) ) {
5814 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5815 "entry for group %s: %s\n",
5816 sid_string_dbg(&ginfo->sid),
5817 nt_errstr(status)));
5821 force_flush_samr_cache(&ginfo->sid);
5823 if (!close_policy_hnd(p, r->in.group_handle))
5824 return NT_STATUS_OBJECT_NAME_INVALID;
5826 return NT_STATUS_OK;
5829 /*********************************************************************
5830 _samr_DeleteDomAlias
5831 *********************************************************************/
5833 NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
5834 struct samr_DeleteDomAlias *r)
5836 struct samr_alias_info *ainfo;
5839 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5841 ainfo = policy_handle_find(p, r->in.alias_handle,
5842 SEC_STD_DELETE, NULL,
5843 struct samr_alias_info, &status);
5844 if (!NT_STATUS_IS_OK(status)) {
5848 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5850 /* Don't let Windows delete builtin groups */
5852 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5853 return NT_STATUS_SPECIAL_ACCOUNT;
5856 if (!sid_check_is_in_our_domain(&ainfo->sid))
5857 return NT_STATUS_NO_SUCH_ALIAS;
5859 DEBUG(10, ("lookup on Local SID\n"));
5861 /******** BEGIN SeAddUsers BLOCK *********/
5864 /* Have passdb delete the alias */
5865 status = pdb_delete_alias(&ainfo->sid);
5868 /******** END SeAddUsers BLOCK *********/
5870 if ( !NT_STATUS_IS_OK(status))
5873 force_flush_samr_cache(&ainfo->sid);
5875 if (!close_policy_hnd(p, r->in.alias_handle))
5876 return NT_STATUS_OBJECT_NAME_INVALID;
5878 return NT_STATUS_OK;
5881 /*********************************************************************
5882 _samr_CreateDomainGroup
5883 *********************************************************************/
5885 NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
5886 struct samr_CreateDomainGroup *r)
5891 struct samr_domain_info *dinfo;
5892 struct samr_group_info *ginfo;
5894 dinfo = policy_handle_find(p, r->in.domain_handle,
5895 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5896 struct samr_domain_info, &status);
5897 if (!NT_STATUS_IS_OK(status)) {
5901 if (!sid_check_is_domain(&dinfo->sid)) {
5902 return NT_STATUS_ACCESS_DENIED;
5905 name = r->in.name->string;
5907 return NT_STATUS_NO_MEMORY;
5910 status = can_create(p->mem_ctx, name);
5911 if (!NT_STATUS_IS_OK(status)) {
5915 /******** BEGIN SeAddUsers BLOCK *********/
5918 /* check that we successfully create the UNIX group */
5919 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5922 /******** END SeAddUsers BLOCK *********/
5924 /* check if we should bail out here */
5926 if ( !NT_STATUS_IS_OK(status) )
5929 ginfo = policy_handle_create(p, r->out.group_handle,
5930 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5931 struct samr_group_info, &status);
5932 if (!NT_STATUS_IS_OK(status)) {
5935 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5937 force_flush_samr_cache(&dinfo->sid);
5939 return NT_STATUS_OK;
5942 /*********************************************************************
5943 _samr_CreateDomAlias
5944 *********************************************************************/
5946 NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
5947 struct samr_CreateDomAlias *r)
5949 struct dom_sid info_sid;
5950 const char *name = NULL;
5951 struct samr_domain_info *dinfo;
5952 struct samr_alias_info *ainfo;
5956 dinfo = policy_handle_find(p, r->in.domain_handle,
5957 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5958 struct samr_domain_info, &result);
5959 if (!NT_STATUS_IS_OK(result)) {
5963 if (!sid_check_is_domain(&dinfo->sid)) {
5964 return NT_STATUS_ACCESS_DENIED;
5967 name = r->in.alias_name->string;
5969 result = can_create(p->mem_ctx, name);
5970 if (!NT_STATUS_IS_OK(result)) {
5974 /******** BEGIN SeAddUsers BLOCK *********/
5977 /* Have passdb create the alias */
5978 result = pdb_create_alias(name, r->out.rid);
5981 /******** END SeAddUsers BLOCK *********/
5983 if (!NT_STATUS_IS_OK(result)) {
5984 DEBUG(10, ("pdb_create_alias failed: %s\n",
5985 nt_errstr(result)));
5989 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5991 if (!sid_to_gid(&info_sid, &gid)) {
5992 DEBUG(10, ("Could not find alias just created\n"));
5993 return NT_STATUS_ACCESS_DENIED;
5996 /* check if the group has been successfully created */
5997 if ( getgrgid(gid) == NULL ) {
5998 DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5999 (unsigned int)gid));
6000 return NT_STATUS_ACCESS_DENIED;
6003 ainfo = policy_handle_create(p, r->out.alias_handle,
6004 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
6005 struct samr_alias_info, &result);
6006 if (!NT_STATUS_IS_OK(result)) {
6009 ainfo->sid = info_sid;
6011 force_flush_samr_cache(&info_sid);
6013 return NT_STATUS_OK;
6016 /*********************************************************************
6017 _samr_QueryGroupInfo
6018 *********************************************************************/
6020 NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
6021 struct samr_QueryGroupInfo *r)
6023 struct samr_group_info *ginfo;
6026 union samr_GroupInfo *info = NULL;
6028 uint32_t attributes = SE_GROUP_MANDATORY |
6029 SE_GROUP_ENABLED_BY_DEFAULT |
6031 const char *group_name = NULL;
6032 const char *group_description = NULL;
6034 ginfo = policy_handle_find(p, r->in.group_handle,
6035 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
6036 struct samr_group_info, &status);
6037 if (!NT_STATUS_IS_OK(status)) {
6042 ret = get_domain_group_from_sid(ginfo->sid, &map);
6045 return NT_STATUS_INVALID_HANDLE;
6047 /* FIXME: map contains fstrings */
6048 group_name = talloc_strdup(r, map.nt_name);
6049 group_description = talloc_strdup(r, map.comment);
6051 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
6053 return NT_STATUS_NO_MEMORY;
6056 switch (r->in.level) {
6062 status = pdb_enum_group_members(
6063 p->mem_ctx, &ginfo->sid, &members,
6067 if (!NT_STATUS_IS_OK(status)) {
6071 info->all.name.string = group_name;
6072 info->all.attributes = attributes;
6073 info->all.num_members = num_members;
6074 info->all.description.string = group_description;
6078 info->name.string = group_name;
6081 info->attributes.attributes = attributes;
6084 info->description.string = group_description;
6094 status = pdb_enum_group_members(
6095 p->mem_ctx, &ginfo->sid, &members,
6099 if (!NT_STATUS_IS_OK(status)) {
6103 info->all2.name.string = group_name;
6104 info->all2.attributes = attributes;
6105 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
6106 info->all2.description.string = group_description;
6111 return NT_STATUS_INVALID_INFO_CLASS;
6114 *r->out.info = info;
6116 return NT_STATUS_OK;
6119 /*********************************************************************
6121 *********************************************************************/
6123 NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
6124 struct samr_SetGroupInfo *r)
6126 struct samr_group_info *ginfo;
6131 ginfo = policy_handle_find(p, r->in.group_handle,
6132 SAMR_GROUP_ACCESS_SET_INFO, NULL,
6133 struct samr_group_info, &status);
6134 if (!NT_STATUS_IS_OK(status)) {
6139 ret = get_domain_group_from_sid(ginfo->sid, &map);
6142 return NT_STATUS_NO_SUCH_GROUP;
6144 switch (r->in.level) {
6146 fstrcpy(map.nt_name, r->in.info->name.string);
6151 fstrcpy(map.comment, r->in.info->description.string);
6154 return NT_STATUS_INVALID_INFO_CLASS;
6157 /******** BEGIN SeAddUsers BLOCK *********/
6160 status = pdb_update_group_mapping_entry(&map);
6163 /******** End SeAddUsers BLOCK *********/
6165 if (NT_STATUS_IS_OK(status)) {
6166 force_flush_samr_cache(&ginfo->sid);
6172 /*********************************************************************
6174 *********************************************************************/
6176 NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
6177 struct samr_SetAliasInfo *r)
6179 struct samr_alias_info *ainfo;
6180 struct acct_info info;
6183 ainfo = policy_handle_find(p, r->in.alias_handle,
6184 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6185 struct samr_alias_info, &status);
6186 if (!NT_STATUS_IS_OK(status)) {
6190 /* get the current group information */
6193 status = pdb_get_aliasinfo( &ainfo->sid, &info );
6196 if ( !NT_STATUS_IS_OK(status))
6199 switch (r->in.level) {
6204 /* We currently do not support renaming groups in the
6205 the BUILTIN domain. Refer to util_builtin.c to understand
6206 why. The eventually needs to be fixed to be like Windows
6207 where you can rename builtin groups, just not delete them */
6209 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6210 return NT_STATUS_SPECIAL_ACCOUNT;
6213 /* There has to be a valid name (and it has to be different) */
6215 if ( !r->in.info->name.string )
6216 return NT_STATUS_INVALID_PARAMETER;
6218 /* If the name is the same just reply "ok". Yes this
6219 doesn't allow you to change the case of a group name. */
6221 if ( strequal( r->in.info->name.string, info.acct_name ) )
6222 return NT_STATUS_OK;
6224 fstrcpy( info.acct_name, r->in.info->name.string);
6226 /* make sure the name doesn't already exist as a user
6229 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6230 status = can_create( p->mem_ctx, group_name );
6231 if ( !NT_STATUS_IS_OK( status ) )
6235 case ALIASINFODESCRIPTION:
6236 if (r->in.info->description.string) {
6237 fstrcpy(info.acct_desc,
6238 r->in.info->description.string);
6240 fstrcpy( info.acct_desc, "" );
6244 return NT_STATUS_INVALID_INFO_CLASS;
6247 /******** BEGIN SeAddUsers BLOCK *********/
6250 status = pdb_set_aliasinfo( &ainfo->sid, &info );
6253 /******** End SeAddUsers BLOCK *********/
6255 if (NT_STATUS_IS_OK(status))
6256 force_flush_samr_cache(&ainfo->sid);
6261 /****************************************************************
6263 ****************************************************************/
6265 NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
6266 struct samr_GetDomPwInfo *r)
6268 uint32_t min_password_length = 0;
6269 uint32_t password_properties = 0;
6271 /* Perform access check. Since this rpc does not require a
6272 policy handle it will not be caught by the access checks on
6273 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6275 if (!pipe_access_check(p)) {
6276 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6277 return NT_STATUS_ACCESS_DENIED;
6281 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6282 &min_password_length);
6283 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6284 &password_properties);
6287 if (lp_check_password_script() && *lp_check_password_script()) {
6288 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6291 r->out.info->min_password_length = min_password_length;
6292 r->out.info->password_properties = password_properties;
6294 return NT_STATUS_OK;
6297 /*********************************************************************
6299 *********************************************************************/
6301 NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
6302 struct samr_OpenGroup *r)
6305 struct dom_sid info_sid;
6307 struct samr_domain_info *dinfo;
6308 struct samr_group_info *ginfo;
6309 struct security_descriptor *psd = NULL;
6311 uint32 des_access = r->in.access_mask;
6317 dinfo = policy_handle_find(p, r->in.domain_handle,
6318 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6319 struct samr_domain_info, &status);
6320 if (!NT_STATUS_IS_OK(status)) {
6324 /*check if access can be granted as requested by client. */
6325 map_max_allowed_access(p->server_info->ptok,
6326 &p->server_info->utok,
6329 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6330 se_map_generic(&des_access,&grp_generic_mapping);
6332 se_priv_copy( &se_rights, &se_add_users );
6334 status = access_check_object(psd, p->server_info->ptok,
6335 &se_rights, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6336 des_access, &acc_granted, "_samr_OpenGroup");
6338 if ( !NT_STATUS_IS_OK(status) )
6341 /* this should not be hard-coded like this */
6343 if (!sid_check_is_domain(&dinfo->sid)) {
6344 return NT_STATUS_ACCESS_DENIED;
6347 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6349 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6350 sid_string_dbg(&info_sid)));
6352 /* check if that group really exists */
6354 ret = get_domain_group_from_sid(info_sid, &map);
6357 return NT_STATUS_NO_SUCH_GROUP;
6359 ginfo = policy_handle_create(p, r->out.group_handle,
6361 struct samr_group_info, &status);
6362 if (!NT_STATUS_IS_OK(status)) {
6365 ginfo->sid = info_sid;
6367 return NT_STATUS_OK;
6370 /*********************************************************************
6371 _samr_RemoveMemberFromForeignDomain
6372 *********************************************************************/
6374 NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
6375 struct samr_RemoveMemberFromForeignDomain *r)
6377 struct samr_domain_info *dinfo;
6380 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6381 sid_string_dbg(r->in.sid)));
6383 /* Find the policy handle. Open a policy on it. */
6385 dinfo = policy_handle_find(p, r->in.domain_handle,
6386 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6387 struct samr_domain_info, &result);
6388 if (!NT_STATUS_IS_OK(result)) {
6392 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6393 sid_string_dbg(&dinfo->sid)));
6395 /* we can only delete a user from a group since we don't have
6396 nested groups anyways. So in the latter case, just say OK */
6398 /* TODO: The above comment nowadays is bogus. Since we have nested
6399 * groups now, and aliases members are never reported out of the unix
6400 * group membership, the "just say OK" makes this call a no-op. For
6401 * us. This needs fixing however. */
6403 /* I've only ever seen this in the wild when deleting a user from
6404 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6405 * is the user about to be deleted. I very much suspect this is the
6406 * only application of this call. To verify this, let people report
6409 if (!sid_check_is_builtin(&dinfo->sid)) {
6410 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6411 "global_sam_sid() = %s\n",
6412 sid_string_dbg(&dinfo->sid),
6413 sid_string_dbg(get_global_sam_sid())));
6414 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6415 return NT_STATUS_OK;
6418 force_flush_samr_cache(&dinfo->sid);
6420 result = NT_STATUS_OK;
6425 /*******************************************************************
6426 _samr_QueryDomainInfo2
6427 ********************************************************************/
6429 NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
6430 struct samr_QueryDomainInfo2 *r)
6432 struct samr_QueryDomainInfo q;
6434 q.in.domain_handle = r->in.domain_handle;
6435 q.in.level = r->in.level;
6437 q.out.info = r->out.info;
6439 return _samr_QueryDomainInfo(p, &q);
6442 /*******************************************************************
6443 ********************************************************************/
6445 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6446 struct samr_DomInfo1 *r)
6448 time_t u_expire, u_min_age;
6450 u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6451 u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6453 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6454 (uint32_t)r->min_password_length);
6455 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6456 (uint32_t)r->password_history_length);
6457 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6458 (uint32_t)r->password_properties);
6459 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6460 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6462 return NT_STATUS_OK;
6465 /*******************************************************************
6466 ********************************************************************/
6468 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6469 struct samr_DomInfo3 *r)
6473 u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6475 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6477 return NT_STATUS_OK;
6480 /*******************************************************************
6481 ********************************************************************/
6483 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6484 struct samr_DomInfo12 *r)
6486 time_t u_lock_duration, u_reset_time;
6488 u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6489 if (u_lock_duration != -1) {
6490 u_lock_duration /= 60;
6493 u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6495 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6496 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6497 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6498 (uint32_t)r->lockout_threshold);
6500 return NT_STATUS_OK;
6503 /*******************************************************************
6505 ********************************************************************/
6507 NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
6508 struct samr_SetDomainInfo *r)
6510 struct samr_domain_info *dinfo;
6512 uint32_t acc_required = 0;
6514 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6516 switch (r->in.level) {
6517 case 1: /* DomainPasswordInformation */
6518 case 12: /* DomainLockoutInformation */
6519 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6520 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6522 case 3: /* DomainLogoffInformation */
6523 case 4: /* DomainOemInformation */
6524 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6525 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6527 case 6: /* DomainReplicationInformation */
6528 case 9: /* DomainStateInformation */
6529 case 7: /* DomainServerRoleInformation */
6530 /* DOMAIN_ADMINISTER_SERVER */
6531 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6534 return NT_STATUS_INVALID_INFO_CLASS;
6537 dinfo = policy_handle_find(p, r->in.domain_handle,
6539 struct samr_domain_info, &status);
6540 if (!NT_STATUS_IS_OK(status)) {
6544 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6546 switch (r->in.level) {
6548 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6551 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6562 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6565 return NT_STATUS_INVALID_INFO_CLASS;
6568 if (!NT_STATUS_IS_OK(status)) {
6572 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6574 return NT_STATUS_OK;
6577 /****************************************************************
6578 _samr_GetDisplayEnumerationIndex
6579 ****************************************************************/
6581 NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
6582 struct samr_GetDisplayEnumerationIndex *r)
6584 struct samr_domain_info *dinfo;
6585 uint32_t max_entries = (uint32_t) -1;
6586 uint32_t enum_context = 0;
6588 uint32_t num_account = 0;
6589 struct samr_displayentry *entries = NULL;
6592 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6594 dinfo = policy_handle_find(p, r->in.domain_handle,
6595 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6596 struct samr_domain_info, &status);
6597 if (!NT_STATUS_IS_OK(status)) {
6601 if ((r->in.level < 1) || (r->in.level > 3)) {
6602 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6603 "Unknown info level (%u)\n",
6605 return NT_STATUS_INVALID_INFO_CLASS;
6610 /* The following done as ROOT. Don't return without unbecome_root(). */
6612 switch (r->in.level) {
6614 if (dinfo->disp_info->users == NULL) {
6615 dinfo->disp_info->users = pdb_search_users(
6616 dinfo->disp_info, ACB_NORMAL);
6617 if (dinfo->disp_info->users == NULL) {
6619 return NT_STATUS_ACCESS_DENIED;
6621 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6622 "starting user enumeration at index %u\n",
6623 (unsigned int)enum_context));
6625 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6626 "using cached user enumeration at index %u\n",
6627 (unsigned int)enum_context));
6629 num_account = pdb_search_entries(dinfo->disp_info->users,
6630 enum_context, max_entries,
6634 if (dinfo->disp_info->machines == NULL) {
6635 dinfo->disp_info->machines = pdb_search_users(
6636 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6637 if (dinfo->disp_info->machines == NULL) {
6639 return NT_STATUS_ACCESS_DENIED;
6641 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6642 "starting machine enumeration at index %u\n",
6643 (unsigned int)enum_context));
6645 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6646 "using cached machine enumeration at index %u\n",
6647 (unsigned int)enum_context));
6649 num_account = pdb_search_entries(dinfo->disp_info->machines,
6650 enum_context, max_entries,
6654 if (dinfo->disp_info->groups == NULL) {
6655 dinfo->disp_info->groups = pdb_search_groups(
6657 if (dinfo->disp_info->groups == NULL) {
6659 return NT_STATUS_ACCESS_DENIED;
6661 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6662 "starting group enumeration at index %u\n",
6663 (unsigned int)enum_context));
6665 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6666 "using cached group enumeration at index %u\n",
6667 (unsigned int)enum_context));
6669 num_account = pdb_search_entries(dinfo->disp_info->groups,
6670 enum_context, max_entries,
6675 smb_panic("info class changed");
6681 /* Ensure we cache this enumeration. */
6682 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6684 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6685 r->in.name->string));
6687 for (i=0; i<num_account; i++) {
6688 if (strequal(entries[i].account_name, r->in.name->string)) {
6689 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6690 "found %s at idx %d\n",
6691 r->in.name->string, i));
6693 return NT_STATUS_OK;
6697 /* assuming account_name lives at the very end */
6698 *r->out.idx = num_account;
6700 return NT_STATUS_NO_MORE_ENTRIES;
6703 /****************************************************************
6704 _samr_GetDisplayEnumerationIndex2
6705 ****************************************************************/
6707 NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
6708 struct samr_GetDisplayEnumerationIndex2 *r)
6710 struct samr_GetDisplayEnumerationIndex q;
6712 q.in.domain_handle = r->in.domain_handle;
6713 q.in.level = r->in.level;
6714 q.in.name = r->in.name;
6716 q.out.idx = r->out.idx;
6718 return _samr_GetDisplayEnumerationIndex(p, &q);
6721 /****************************************************************
6723 ****************************************************************/
6725 NTSTATUS _samr_RidToSid(struct pipes_struct *p,
6726 struct samr_RidToSid *r)
6728 struct samr_domain_info *dinfo;
6732 dinfo = policy_handle_find(p, r->in.domain_handle,
6734 struct samr_domain_info, &status);
6735 if (!NT_STATUS_IS_OK(status)) {
6739 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6740 return NT_STATUS_NO_MEMORY;
6743 *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
6745 return NT_STATUS_NO_MEMORY;
6748 return NT_STATUS_OK;
6751 /****************************************************************
6752 ****************************************************************/
6754 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
6755 const struct samr_PwInfo *dom_pw_info,
6756 const struct samr_ValidatePasswordReq2 *req,
6757 struct samr_ValidatePasswordRepCtr *rep)
6761 if (req->password.string == NULL) {
6762 return SAMR_VALIDATION_STATUS_SUCCESS;
6764 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6765 ZERO_STRUCT(rep->info);
6766 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6768 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6769 status = check_password_complexity(req->account.string,
6770 req->password.string,
6772 if (!NT_STATUS_IS_OK(status)) {
6773 ZERO_STRUCT(rep->info);
6774 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6778 return SAMR_VALIDATION_STATUS_SUCCESS;
6781 /****************************************************************
6782 ****************************************************************/
6784 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
6785 const struct samr_PwInfo *dom_pw_info,
6786 const struct samr_ValidatePasswordReq3 *req,
6787 struct samr_ValidatePasswordRepCtr *rep)
6791 if (req->password.string == NULL) {
6792 return SAMR_VALIDATION_STATUS_SUCCESS;
6794 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6795 ZERO_STRUCT(rep->info);
6796 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6798 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6799 status = check_password_complexity(req->account.string,
6800 req->password.string,
6802 if (!NT_STATUS_IS_OK(status)) {
6803 ZERO_STRUCT(rep->info);
6804 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6808 return SAMR_VALIDATION_STATUS_SUCCESS;
6811 /****************************************************************
6812 _samr_ValidatePassword
6813 ****************************************************************/
6815 NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
6816 struct samr_ValidatePassword *r)
6818 union samr_ValidatePasswordRep *rep;
6820 struct samr_GetDomPwInfo pw;
6821 struct samr_PwInfo dom_pw_info;
6823 if (r->in.level < 1 || r->in.level > 3) {
6824 return NT_STATUS_INVALID_INFO_CLASS;
6827 pw.in.domain_name = NULL;
6828 pw.out.info = &dom_pw_info;
6830 status = _samr_GetDomPwInfo(p, &pw);
6831 if (!NT_STATUS_IS_OK(status)) {
6835 rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
6837 return NT_STATUS_NO_MEMORY;
6840 switch (r->in.level) {
6842 status = NT_STATUS_NOT_SUPPORTED;
6845 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
6851 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
6857 status = NT_STATUS_INVALID_INFO_CLASS;
6861 if (!NT_STATUS_IS_OK(status)) {
6868 return NT_STATUS_OK;
6871 /****************************************************************
6872 ****************************************************************/
6874 NTSTATUS _samr_Shutdown(struct pipes_struct *p,
6875 struct samr_Shutdown *r)
6877 p->rng_fault_state = true;
6878 return NT_STATUS_NOT_IMPLEMENTED;
6881 /****************************************************************
6882 ****************************************************************/
6884 NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
6885 struct samr_SetMemberAttributesOfGroup *r)
6887 p->rng_fault_state = true;
6888 return NT_STATUS_NOT_IMPLEMENTED;
6891 /****************************************************************
6892 ****************************************************************/
6894 NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
6895 struct samr_TestPrivateFunctionsDomain *r)
6897 return NT_STATUS_NOT_IMPLEMENTED;
6900 /****************************************************************
6901 ****************************************************************/
6903 NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
6904 struct samr_TestPrivateFunctionsUser *r)
6906 return NT_STATUS_NOT_IMPLEMENTED;
6909 /****************************************************************
6910 ****************************************************************/
6912 NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
6913 struct samr_AddMultipleMembersToAlias *r)
6915 p->rng_fault_state = true;
6916 return NT_STATUS_NOT_IMPLEMENTED;
6919 /****************************************************************
6920 ****************************************************************/
6922 NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
6923 struct samr_RemoveMultipleMembersFromAlias *r)
6925 p->rng_fault_state = true;
6926 return NT_STATUS_NOT_IMPLEMENTED;
6929 /****************************************************************
6930 ****************************************************************/
6932 NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
6933 struct samr_SetBootKeyInformation *r)
6935 p->rng_fault_state = true;
6936 return NT_STATUS_NOT_IMPLEMENTED;
6939 /****************************************************************
6940 ****************************************************************/
6942 NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
6943 struct samr_GetBootKeyInformation *r)
6945 p->rng_fault_state = true;
6946 return NT_STATUS_NOT_IMPLEMENTED;
6949 /****************************************************************
6950 ****************************************************************/
6952 NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
6953 struct samr_SetDsrmPassword *r)
6955 p->rng_fault_state = true;
6956 return NT_STATUS_NOT_IMPLEMENTED;