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 "system/passwd.h"
36 #include "../libcli/auth/libcli_auth.h"
38 #include "librpc/rpc/dcesrv_core.h"
39 #include "../librpc/gen_ndr/ndr_samr.h"
40 #include "../librpc/gen_ndr/ndr_samr_scompat.h"
41 #include "rpc_server/samr/srv_samr_util.h"
43 #include "rpc_client/init_lsa.h"
44 #include "../libcli/security/security.h"
47 #include "rpc_server/srv_access_check.h"
48 #include "../lib/tsocket/tsocket.h"
49 #include "lib/util/base64.h"
50 #include "param/param.h"
51 #include "librpc/rpc/dcerpc_helper.h"
53 #include "lib/crypto/gnutls_helpers.h"
54 #include <gnutls/gnutls.h>
55 #include <gnutls/crypto.h>
56 #include "lib/global_contexts.h"
57 #include "nsswitch/winbind_client.h"
60 #define DBGC_CLASS DBGC_RPC_SRV
62 #define SAMR_USR_RIGHTS_WRITE_PW \
63 ( READ_CONTROL_ACCESS | \
64 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
65 SAMR_USER_ACCESS_SET_LOC_COM)
66 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
67 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
69 #define DISP_INFO_CACHE_TIMEOUT 10
71 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
72 #define MAX_SAM_ENTRIES_W95 50
83 uint32_t access_granted;
85 struct disp_info *disp_info;
88 typedef struct disp_info {
89 struct dom_sid sid; /* identify which domain this is. */
90 struct pdb_search *users; /* querydispinfo 1 and 4 */
91 struct pdb_search *machines; /* querydispinfo 2 */
92 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
93 struct pdb_search *aliases; /* enumaliases */
95 uint32_t enum_acb_mask;
96 struct pdb_search *enum_users; /* enumusers with a mask */
98 struct tevent_timer *cache_timeout_event; /* cache idle timeout
102 static const struct generic_mapping sam_generic_mapping = {
103 GENERIC_RIGHTS_SAM_READ,
104 GENERIC_RIGHTS_SAM_WRITE,
105 GENERIC_RIGHTS_SAM_EXECUTE,
106 GENERIC_RIGHTS_SAM_ALL_ACCESS};
107 static const struct generic_mapping dom_generic_mapping = {
108 GENERIC_RIGHTS_DOMAIN_READ,
109 GENERIC_RIGHTS_DOMAIN_WRITE,
110 GENERIC_RIGHTS_DOMAIN_EXECUTE,
111 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
112 static const struct generic_mapping usr_generic_mapping = {
113 GENERIC_RIGHTS_USER_READ,
114 GENERIC_RIGHTS_USER_WRITE,
115 GENERIC_RIGHTS_USER_EXECUTE,
116 GENERIC_RIGHTS_USER_ALL_ACCESS};
117 static const struct generic_mapping usr_nopwchange_generic_mapping = {
118 GENERIC_RIGHTS_USER_READ,
119 GENERIC_RIGHTS_USER_WRITE,
120 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
121 GENERIC_RIGHTS_USER_ALL_ACCESS};
122 static const struct generic_mapping grp_generic_mapping = {
123 GENERIC_RIGHTS_GROUP_READ,
124 GENERIC_RIGHTS_GROUP_WRITE,
125 GENERIC_RIGHTS_GROUP_EXECUTE,
126 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
127 static const struct generic_mapping ali_generic_mapping = {
128 GENERIC_RIGHTS_ALIAS_READ,
129 GENERIC_RIGHTS_ALIAS_WRITE,
130 GENERIC_RIGHTS_ALIAS_EXECUTE,
131 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
133 /*******************************************************************
134 *******************************************************************/
135 static NTSTATUS create_samr_policy_handle(TALLOC_CTX *mem_ctx,
136 struct pipes_struct *p,
137 enum samr_handle type,
138 uint32_t acc_granted,
140 struct disp_info *disp_info,
141 struct policy_handle *handle)
143 struct samr_info *info = NULL;
146 ZERO_STRUCTP(handle);
148 info = talloc_zero(mem_ctx, struct samr_info);
150 return NT_STATUS_NO_MEMORY;
153 info->access_granted = acc_granted;
156 sid_copy(&info->sid, sid);
159 if (disp_info != NULL) {
160 info->disp_info = disp_info;
163 ok = create_policy_hnd(p, handle, type, info);
166 ZERO_STRUCTP(handle);
167 return NT_STATUS_NO_MEMORY;
173 static NTSTATUS samr_handle_access_check(uint32_t access_granted,
174 uint32_t access_required,
175 uint32_t *paccess_granted)
177 if ((access_required & access_granted) != access_required) {
179 DBG_INFO("ACCESS should be DENIED (granted: "
180 "%#010x; required: %#010x) but overwritten "
181 "by euid == 0\n", access_granted,
185 DBG_NOTICE("ACCESS DENIED (granted: %#010x; required: "
186 "%#010x)\n", access_granted, access_required);
187 return NT_STATUS_ACCESS_DENIED;
191 if (paccess_granted != NULL) {
192 *paccess_granted = access_granted;
197 static void *samr_policy_handle_find(struct pipes_struct *p,
198 const struct policy_handle *handle,
200 uint32_t access_required,
201 uint32_t *access_granted,
204 struct samr_info *info = NULL;
207 info = find_policy_by_hnd(p,
212 if (!NT_STATUS_IS_OK(status)) {
213 *pstatus = NT_STATUS_INVALID_HANDLE;
217 status = samr_handle_access_check(info->access_granted,
220 if (!NT_STATUS_IS_OK(status)) {
225 *pstatus = NT_STATUS_OK;
229 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
230 const struct generic_mapping *map,
231 struct dom_sid *sid, uint32_t sid_access )
233 struct dom_sid domadmin_sid;
234 struct security_ace ace[5]; /* at most 5 entries */
237 struct security_acl *psa = NULL;
239 /* basic access for Everyone */
241 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
242 map->generic_execute | map->generic_read, 0);
244 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
246 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
247 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
248 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
249 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
251 /* Add Full Access for Domain Admins if we are a DC */
254 sid_compose(&domadmin_sid, get_global_sam_sid(),
256 init_sec_ace(&ace[i++], &domadmin_sid,
257 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
260 /* if we have a sid, give it some special access */
263 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
266 /* create the security descriptor */
268 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
269 return NT_STATUS_NO_MEMORY;
271 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
272 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
273 psa, sd_size)) == NULL)
274 return NT_STATUS_NO_MEMORY;
279 /*******************************************************************
280 Fetch or create a dispinfo struct.
281 ********************************************************************/
283 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
286 * We do a static cache for DISP_INFO's here. Explanation can be found
287 * in Jeremy's checkin message to r11793:
289 * Fix the SAMR cache so it works across completely insane
290 * client behaviour (ie.:
291 * open pipe/open SAMR handle/enumerate 0 - 1024
292 * close SAMR handle, close pipe.
293 * open pipe/open SAMR handle/enumerate 1024 - 2048...
294 * close SAMR handle, close pipe.
295 * And on ad-nausium. Amazing.... probably object-oriented
296 * client side programming in action yet again.
297 * This change should *massively* improve performance when
298 * enumerating users from an LDAP database.
301 * "Our" and the builtin domain are the only ones where we ever
302 * enumerate stuff, so just cache 2 entries.
305 static struct disp_info *builtin_dispinfo;
306 static struct disp_info *domain_dispinfo;
308 /* There are two cases to consider here:
309 1) The SID is a domain SID and we look for an equality match, or
310 2) This is an account SID and so we return the DISP_INFO* for our
317 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
319 * Necessary only once, but it does not really hurt.
321 if (builtin_dispinfo == NULL) {
322 builtin_dispinfo = talloc_zero(NULL, struct disp_info);
323 if (builtin_dispinfo == NULL) {
327 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
329 return builtin_dispinfo;
332 if (sid_check_is_our_sam(psid) || sid_check_is_in_our_sam(psid)) {
334 * Necessary only once, but it does not really hurt.
336 if (domain_dispinfo == NULL) {
337 domain_dispinfo = talloc_zero(NULL, struct disp_info);
338 if (domain_dispinfo == NULL) {
342 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
344 return domain_dispinfo;
350 /*******************************************************************
351 Function to free the per SID data.
352 ********************************************************************/
354 static void free_samr_cache(DISP_INFO *disp_info)
356 struct dom_sid_buf buf;
358 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
359 dom_sid_str_buf(&disp_info->sid, &buf)));
361 /* We need to become root here because the paged search might have to
362 * tell the LDAP server we're not interested in the rest anymore. */
366 TALLOC_FREE(disp_info->users);
367 TALLOC_FREE(disp_info->machines);
368 TALLOC_FREE(disp_info->groups);
369 TALLOC_FREE(disp_info->aliases);
370 TALLOC_FREE(disp_info->enum_users);
375 /*******************************************************************
376 Idle event handler. Throw away the disp info cache.
377 ********************************************************************/
379 static void disp_info_cache_idle_timeout_handler(struct tevent_context *ev_ctx,
380 struct tevent_timer *te,
384 DISP_INFO *disp_info = (DISP_INFO *)private_data;
386 TALLOC_FREE(disp_info->cache_timeout_event);
388 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
390 free_samr_cache(disp_info);
393 /*******************************************************************
394 Setup cache removal idle event handler.
395 ********************************************************************/
397 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
399 struct dom_sid_buf buf;
401 /* Remove any pending timeout and update. */
403 TALLOC_FREE(disp_info->cache_timeout_event);
405 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
406 "SID %s for %u seconds\n",
407 dom_sid_str_buf(&disp_info->sid, &buf),
408 (unsigned int)secs_fromnow ));
410 disp_info->cache_timeout_event = tevent_add_timer(
411 global_event_context(), NULL,
412 timeval_current_ofs(secs_fromnow, 0),
413 disp_info_cache_idle_timeout_handler, (void *)disp_info);
416 /*******************************************************************
417 Force flush any cache. We do this on any samr_set_xxx call.
418 We must also remove the timeout handler.
419 ********************************************************************/
421 static void force_flush_samr_cache(const struct dom_sid *sid)
423 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
425 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
429 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
430 TALLOC_FREE(disp_info->cache_timeout_event);
431 free_samr_cache(disp_info);
434 /*******************************************************************
435 Ensure password info is never given out. Paranioa... JRA.
436 ********************************************************************/
438 static void samr_clear_sam_passwd(struct samu *sam_pass)
444 /* These now zero out the old password */
446 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
447 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
450 static uint32_t count_sam_users(struct disp_info *info, uint32_t acct_flags)
452 struct samr_displayentry *entry;
454 if (sid_check_is_builtin(&info->sid)) {
455 /* No users in builtin. */
459 if (info->users == NULL) {
460 info->users = pdb_search_users(info, acct_flags);
461 if (info->users == NULL) {
465 /* Fetch the last possible entry, thus trigger an enumeration */
466 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
468 /* Ensure we cache this enumeration. */
469 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
471 return info->users->num_entries;
474 static uint32_t count_sam_groups(struct disp_info *info)
476 struct samr_displayentry *entry;
478 if (sid_check_is_builtin(&info->sid)) {
479 /* No groups in builtin. */
483 if (info->groups == NULL) {
484 info->groups = pdb_search_groups(info);
485 if (info->groups == NULL) {
489 /* Fetch the last possible entry, thus trigger an enumeration */
490 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
492 /* Ensure we cache this enumeration. */
493 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
495 return info->groups->num_entries;
498 static uint32_t count_sam_aliases(struct disp_info *info)
500 struct samr_displayentry *entry;
502 if (info->aliases == NULL) {
503 info->aliases = pdb_search_aliases(info, &info->sid);
504 if (info->aliases == NULL) {
508 /* Fetch the last possible entry, thus trigger an enumeration */
509 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
511 /* Ensure we cache this enumeration. */
512 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
514 return info->aliases->num_entries;
517 /*******************************************************************
519 ********************************************************************/
521 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
523 if (!close_policy_hnd(p, r->in.handle)) {
524 return NT_STATUS_INVALID_HANDLE;
527 ZERO_STRUCTP(r->out.handle);
532 /*******************************************************************
534 ********************************************************************/
536 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
537 struct samr_OpenDomain *r)
539 struct security_descriptor *psd = NULL;
540 uint32_t acc_granted;
541 uint32_t des_access = r->in.access_mask;
544 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
545 struct disp_info *disp_info = NULL;
547 /* find the connection policy handle. */
548 (void)samr_policy_handle_find(p,
549 r->in.connect_handle,
554 if (!NT_STATUS_IS_OK(status)) {
558 /*check if access can be granted as requested by client. */
559 map_max_allowed_access(p->session_info->security_token,
560 p->session_info->unix_token,
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 SeAddUser get the ability to manipulate groups
570 if (security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS)) {
571 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
572 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
573 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
574 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
575 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
579 * Users with SeMachineAccount or SeAddUser get additional
580 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
583 status = access_check_object( psd, p->session_info->security_token,
584 SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
585 extra_access, des_access,
586 &acc_granted, "_samr_OpenDomain" );
588 if ( !NT_STATUS_IS_OK(status) )
591 if (!sid_check_is_our_sam(r->in.sid) &&
592 !sid_check_is_builtin(r->in.sid)) {
593 return NT_STATUS_NO_SUCH_DOMAIN;
596 disp_info = get_samr_dispinfo_by_sid(r->in.sid);
598 status = create_samr_policy_handle(p->mem_ctx,
604 r->out.domain_handle);
605 if (!NT_STATUS_IS_OK(status)) {
609 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
614 /*******************************************************************
616 ********************************************************************/
618 NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
619 struct samr_GetUserPwInfo *r)
621 const struct loadparm_substitution *lp_sub =
622 loadparm_s3_global_substitution();
623 struct samr_info *uinfo;
624 enum lsa_SidType sid_type;
625 uint32_t min_password_length = 0;
626 uint32_t password_properties = 0;
630 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
632 uinfo = samr_policy_handle_find(p, r->in.user_handle,
634 SAMR_USER_ACCESS_GET_ATTRIBUTES,
637 if (!NT_STATUS_IS_OK(status)) {
641 if (!sid_check_is_in_our_sam(&uinfo->sid)) {
642 return NT_STATUS_OBJECT_TYPE_MISMATCH;
646 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
649 return NT_STATUS_NO_SUCH_USER;
655 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
656 &min_password_length);
657 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
658 &password_properties);
661 if (lp_check_password_script(talloc_tos(), lp_sub)
662 && *lp_check_password_script(talloc_tos(), lp_sub)) {
663 password_properties |= DOMAIN_PASSWORD_COMPLEX;
671 r->out.info->min_password_length = min_password_length;
672 r->out.info->password_properties = password_properties;
674 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
679 /*******************************************************************
681 ********************************************************************/
683 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
684 struct samr_SetSecurity *r)
686 struct samr_info *uinfo;
688 struct security_acl *dacl;
690 struct samu *sampass=NULL;
693 uinfo = samr_policy_handle_find(p,
696 SAMR_USER_ACCESS_SET_ATTRIBUTES,
699 if (!NT_STATUS_IS_OK(status)) {
703 if (!(sampass = samu_new( p->mem_ctx))) {
704 DEBUG(0,("No memory!\n"));
705 return NT_STATUS_NO_MEMORY;
708 /* get the user record */
710 ret = pdb_getsampwsid(sampass, &uinfo->sid);
714 struct dom_sid_buf buf;
715 DEBUG(4, ("User %s not found\n",
716 dom_sid_str_buf(&uinfo->sid, &buf)));
717 TALLOC_FREE(sampass);
718 return NT_STATUS_INVALID_HANDLE;
721 dacl = r->in.sdbuf->sd->dacl;
722 for (i=0; i < dacl->num_aces; i++) {
723 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
724 ret = pdb_set_pass_can_change(sampass,
725 (dacl->aces[i].access_mask &
726 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
733 TALLOC_FREE(sampass);
734 return NT_STATUS_ACCESS_DENIED;
738 status = pdb_update_sam_account(sampass);
741 TALLOC_FREE(sampass);
746 /*******************************************************************
747 build correct perms based on policies and password times for _samr_query_sec_obj
748 *******************************************************************/
749 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
751 struct samu *sampass=NULL;
754 if ( !(sampass = samu_new( mem_ctx )) ) {
755 DEBUG(0,("No memory!\n"));
760 ret = pdb_getsampwsid(sampass, user_sid);
764 struct dom_sid_buf buf;
765 DEBUG(4,("User %s not found\n",
766 dom_sid_str_buf(user_sid, &buf)));
767 TALLOC_FREE(sampass);
771 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
773 if (pdb_get_pass_can_change(sampass)) {
774 TALLOC_FREE(sampass);
777 TALLOC_FREE(sampass);
782 /*******************************************************************
784 ********************************************************************/
786 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
787 struct samr_QuerySecurity *r)
789 struct samr_info *info;
791 struct security_descriptor * psd = NULL;
793 struct dom_sid_buf buf;
795 info = samr_policy_handle_find(p,
798 SEC_STD_READ_CONTROL,
801 if (NT_STATUS_IS_OK(status)) {
802 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
803 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
804 &sam_generic_mapping, NULL, 0);
808 info = samr_policy_handle_find(p,
811 SEC_STD_READ_CONTROL,
814 if (NT_STATUS_IS_OK(status)) {
815 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
817 dom_sid_str_buf(&info->sid, &buf)));
819 * TODO: Builtin probably needs a different SD with restricted
822 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
823 &dom_generic_mapping, NULL, 0);
827 info = samr_policy_handle_find(p,
830 SEC_STD_READ_CONTROL,
833 if (NT_STATUS_IS_OK(status)) {
834 DEBUG(10,("_samr_QuerySecurity: querying security on user "
835 "Object with SID: %s\n",
836 dom_sid_str_buf(&info->sid, &buf)));
837 if (check_change_pw_access(p->mem_ctx, &info->sid)) {
838 status = make_samr_object_sd(
839 p->mem_ctx, &psd, &sd_size,
840 &usr_generic_mapping,
841 &info->sid, SAMR_USR_RIGHTS_WRITE_PW);
843 status = make_samr_object_sd(
844 p->mem_ctx, &psd, &sd_size,
845 &usr_nopwchange_generic_mapping,
846 &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
851 info = samr_policy_handle_find(p,
854 SEC_STD_READ_CONTROL,
857 if (NT_STATUS_IS_OK(status)) {
859 * TODO: different SDs have to be generated for aliases groups
860 * and users. Currently all three get a default user SD
862 DEBUG(10,("_samr_QuerySecurity: querying security on group "
863 "Object with SID: %s\n",
864 dom_sid_str_buf(&info->sid, &buf)));
865 status = make_samr_object_sd(
866 p->mem_ctx, &psd, &sd_size,
867 &usr_nopwchange_generic_mapping,
868 &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
872 info = samr_policy_handle_find(p,
875 SEC_STD_READ_CONTROL,
878 if (NT_STATUS_IS_OK(status)) {
880 * TODO: different SDs have to be generated for aliases groups
881 * and users. Currently all three get a default user SD
883 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
884 "Object with SID: %s\n",
885 dom_sid_str_buf(&info->sid, &buf)));
886 status = make_samr_object_sd(
887 p->mem_ctx, &psd, &sd_size,
888 &usr_nopwchange_generic_mapping,
889 &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
893 return NT_STATUS_OBJECT_TYPE_MISMATCH;
895 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
896 return NT_STATUS_NO_MEMORY;
901 /*******************************************************************
902 makes a SAM_ENTRY / UNISTR2* structure from a user list.
903 ********************************************************************/
905 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
906 struct samr_SamEntry **sam_pp,
907 uint32_t num_entries,
909 struct samr_displayentry *entries)
912 struct samr_SamEntry *sam;
916 if (num_entries == 0) {
920 sam = talloc_zero_array(ctx, struct samr_SamEntry, num_entries);
922 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
923 return NT_STATUS_NO_MEMORY;
926 for (i = 0; i < num_entries; i++) {
929 * usrmgr expects a non-NULL terminated string with
930 * trust relationships
932 if (entries[i].acct_flags & ACB_DOMTRUST) {
933 init_unistr2(&uni_temp_name, entries[i].account_name,
936 init_unistr2(&uni_temp_name, entries[i].account_name,
940 init_lsa_String(&sam[i].name, entries[i].account_name);
941 sam[i].idx = entries[i].rid;
949 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
951 /*******************************************************************
952 _samr_EnumDomainUsers
953 ********************************************************************/
955 NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
956 struct samr_EnumDomainUsers *r)
959 struct samr_info *dinfo;
960 uint32_t num_account;
961 uint32_t enum_context = *r->in.resume_handle;
962 enum remote_arch_types ra_type = get_remote_arch();
963 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
964 uint32_t max_entries = max_sam_entries;
965 struct samr_displayentry *entries = NULL;
966 struct samr_SamArray *samr_array = NULL;
967 struct samr_SamEntry *samr_entries = NULL;
969 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
971 dinfo = samr_policy_handle_find(p,
974 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
977 if (!NT_STATUS_IS_OK(status)) {
981 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
983 return NT_STATUS_NO_MEMORY;
985 *r->out.sam = samr_array;
987 if (sid_check_is_builtin(&dinfo->sid)) {
988 /* No users in builtin. */
989 *r->out.resume_handle = *r->in.resume_handle;
990 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
998 if ((dinfo->disp_info->enum_users != NULL) &&
999 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
1000 TALLOC_FREE(dinfo->disp_info->enum_users);
1003 if (dinfo->disp_info->enum_users == NULL) {
1004 dinfo->disp_info->enum_users = pdb_search_users(
1005 dinfo->disp_info, r->in.acct_flags);
1006 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
1009 if (dinfo->disp_info->enum_users == NULL) {
1010 /* END AS ROOT !!!! */
1012 return NT_STATUS_ACCESS_DENIED;
1015 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
1016 enum_context, max_entries,
1019 /* END AS ROOT !!!! */
1023 if (num_account == 0) {
1024 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1025 "total entries\n"));
1026 *r->out.resume_handle = *r->in.resume_handle;
1027 return NT_STATUS_OK;
1030 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1031 num_account, enum_context,
1033 if (!NT_STATUS_IS_OK(status)) {
1037 if (max_entries <= num_account) {
1038 status = STATUS_MORE_ENTRIES;
1040 status = NT_STATUS_OK;
1043 /* Ensure we cache this enumeration. */
1044 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1046 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1048 samr_array->count = num_account;
1049 samr_array->entries = samr_entries;
1051 *r->out.resume_handle = *r->in.resume_handle + num_account;
1052 *r->out.num_entries = num_account;
1054 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1059 /*******************************************************************
1060 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1061 ********************************************************************/
1063 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1064 struct samr_SamEntry **sam_pp,
1065 uint32_t num_sam_entries,
1066 struct samr_displayentry *entries)
1068 struct samr_SamEntry *sam;
1073 if (num_sam_entries == 0) {
1077 sam = talloc_zero_array(ctx, struct samr_SamEntry, num_sam_entries);
1082 for (i = 0; i < num_sam_entries; i++) {
1084 * JRA. I think this should include the null. TNG does not.
1086 init_lsa_String(&sam[i].name, entries[i].account_name);
1087 sam[i].idx = entries[i].rid;
1093 /*******************************************************************
1094 _samr_EnumDomainGroups
1095 ********************************************************************/
1097 NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
1098 struct samr_EnumDomainGroups *r)
1101 struct samr_info *dinfo;
1102 struct samr_displayentry *groups;
1103 uint32_t num_groups;
1104 struct samr_SamArray *samr_array = NULL;
1105 struct samr_SamEntry *samr_entries = NULL;
1107 dinfo = samr_policy_handle_find(p,
1108 r->in.domain_handle,
1110 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1113 if (!NT_STATUS_IS_OK(status)) {
1117 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1119 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
1121 return NT_STATUS_NO_MEMORY;
1123 *r->out.sam = samr_array;
1125 if (sid_check_is_builtin(&dinfo->sid)) {
1126 /* No groups in builtin. */
1127 *r->out.resume_handle = *r->in.resume_handle;
1128 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1132 /* the domain group array is being allocated in the function below */
1136 if (dinfo->disp_info->groups == NULL) {
1137 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1139 if (dinfo->disp_info->groups == NULL) {
1141 return NT_STATUS_ACCESS_DENIED;
1145 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1146 *r->in.resume_handle,
1147 MAX_SAM_ENTRIES, &groups);
1150 /* Ensure we cache this enumeration. */
1151 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1153 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1154 num_groups, groups);
1156 if (MAX_SAM_ENTRIES <= num_groups) {
1157 status = STATUS_MORE_ENTRIES;
1159 status = NT_STATUS_OK;
1162 samr_array->count = num_groups;
1163 samr_array->entries = samr_entries;
1165 *r->out.num_entries = num_groups;
1166 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1168 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1173 /*******************************************************************
1174 _samr_EnumDomainAliases
1175 ********************************************************************/
1177 NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1178 struct samr_EnumDomainAliases *r)
1181 struct samr_info *dinfo;
1182 struct samr_displayentry *aliases;
1183 uint32_t num_aliases = 0;
1184 struct samr_SamArray *samr_array = NULL;
1185 struct samr_SamEntry *samr_entries = NULL;
1186 struct dom_sid_buf buf;
1188 dinfo = samr_policy_handle_find(p,
1189 r->in.domain_handle,
1191 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1194 if (!NT_STATUS_IS_OK(status)) {
1198 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1199 dom_sid_str_buf(&dinfo->sid, &buf)));
1201 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
1203 return NT_STATUS_NO_MEMORY;
1208 if (dinfo->disp_info->aliases == NULL) {
1209 dinfo->disp_info->aliases = pdb_search_aliases(
1210 dinfo->disp_info, &dinfo->sid);
1211 if (dinfo->disp_info->aliases == NULL) {
1213 return NT_STATUS_ACCESS_DENIED;
1217 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1218 *r->in.resume_handle,
1219 MAX_SAM_ENTRIES, &aliases);
1222 /* Ensure we cache this enumeration. */
1223 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1225 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1226 num_aliases, aliases);
1228 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1230 if (MAX_SAM_ENTRIES <= num_aliases) {
1231 status = STATUS_MORE_ENTRIES;
1233 status = NT_STATUS_OK;
1236 samr_array->count = num_aliases;
1237 samr_array->entries = samr_entries;
1239 *r->out.sam = samr_array;
1240 *r->out.num_entries = num_aliases;
1241 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1246 /*******************************************************************
1247 inits a samr_DispInfoGeneral structure.
1248 ********************************************************************/
1250 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1251 struct samr_DispInfoGeneral *r,
1252 uint32_t num_entries,
1254 struct samr_displayentry *entries)
1258 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1260 if (num_entries == 0) {
1261 return NT_STATUS_OK;
1264 r->count = num_entries;
1266 r->entries = talloc_zero_array(ctx, struct samr_DispEntryGeneral, num_entries);
1268 return NT_STATUS_NO_MEMORY;
1271 for (i = 0; i < num_entries ; i++) {
1273 init_lsa_String(&r->entries[i].account_name,
1274 entries[i].account_name);
1276 init_lsa_String(&r->entries[i].description,
1277 entries[i].description);
1279 init_lsa_String(&r->entries[i].full_name,
1280 entries[i].fullname);
1282 r->entries[i].rid = entries[i].rid;
1283 r->entries[i].acct_flags = entries[i].acct_flags;
1284 r->entries[i].idx = start_idx+i+1;
1287 return NT_STATUS_OK;
1290 /*******************************************************************
1291 inits a samr_DispInfoFull structure.
1292 ********************************************************************/
1294 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1295 struct samr_DispInfoFull *r,
1296 uint32_t num_entries,
1298 struct samr_displayentry *entries)
1302 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1304 if (num_entries == 0) {
1305 return NT_STATUS_OK;
1308 r->count = num_entries;
1310 r->entries = talloc_zero_array(ctx, struct samr_DispEntryFull, num_entries);
1312 return NT_STATUS_NO_MEMORY;
1315 for (i = 0; i < num_entries ; i++) {
1317 init_lsa_String(&r->entries[i].account_name,
1318 entries[i].account_name);
1320 init_lsa_String(&r->entries[i].description,
1321 entries[i].description);
1323 r->entries[i].rid = entries[i].rid;
1324 r->entries[i].acct_flags = entries[i].acct_flags;
1325 r->entries[i].idx = start_idx+i+1;
1328 return NT_STATUS_OK;
1331 /*******************************************************************
1332 inits a samr_DispInfoFullGroups structure.
1333 ********************************************************************/
1335 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1336 struct samr_DispInfoFullGroups *r,
1337 uint32_t num_entries,
1339 struct samr_displayentry *entries)
1343 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1345 if (num_entries == 0) {
1346 return NT_STATUS_OK;
1349 r->count = num_entries;
1351 r->entries = talloc_zero_array(ctx, struct samr_DispEntryFullGroup, num_entries);
1353 return NT_STATUS_NO_MEMORY;
1356 for (i = 0; i < num_entries ; i++) {
1358 init_lsa_String(&r->entries[i].account_name,
1359 entries[i].account_name);
1361 init_lsa_String(&r->entries[i].description,
1362 entries[i].description);
1364 r->entries[i].rid = entries[i].rid;
1365 r->entries[i].acct_flags = entries[i].acct_flags;
1366 r->entries[i].idx = start_idx+i+1;
1369 return NT_STATUS_OK;
1372 /*******************************************************************
1373 inits a samr_DispInfoAscii structure.
1374 ********************************************************************/
1376 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1377 struct samr_DispInfoAscii *r,
1378 uint32_t num_entries,
1380 struct samr_displayentry *entries)
1384 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1386 if (num_entries == 0) {
1387 return NT_STATUS_OK;
1390 r->count = num_entries;
1392 r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1394 return NT_STATUS_NO_MEMORY;
1397 for (i = 0; i < num_entries ; i++) {
1399 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1400 entries[i].account_name);
1402 r->entries[i].idx = start_idx+i+1;
1405 return NT_STATUS_OK;
1408 /*******************************************************************
1409 inits a samr_DispInfoAscii structure.
1410 ********************************************************************/
1412 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1413 struct samr_DispInfoAscii *r,
1414 uint32_t num_entries,
1416 struct samr_displayentry *entries)
1420 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1422 if (num_entries == 0) {
1423 return NT_STATUS_OK;
1426 r->count = num_entries;
1428 r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1430 return NT_STATUS_NO_MEMORY;
1433 for (i = 0; i < num_entries ; i++) {
1435 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1436 entries[i].account_name);
1438 r->entries[i].idx = start_idx+i+1;
1441 return NT_STATUS_OK;
1444 /*******************************************************************
1445 _samr_QueryDisplayInfo
1446 ********************************************************************/
1448 NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1449 struct samr_QueryDisplayInfo *r)
1452 struct samr_info *dinfo;
1453 uint32_t struct_size=0x20; /* W2K always reply that, client doesn't care */
1455 uint32_t max_entries = r->in.max_entries;
1457 union samr_DispInfo *disp_info = r->out.info;
1459 uint32_t temp_size=0;
1460 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1461 uint32_t num_account = 0;
1462 enum remote_arch_types ra_type = get_remote_arch();
1463 uint32_t max_sam_entries = (ra_type == RA_WIN95) ?
1464 MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1465 struct samr_displayentry *entries = NULL;
1467 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1469 dinfo = samr_policy_handle_find(p,
1470 r->in.domain_handle,
1472 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
1475 if (!NT_STATUS_IS_OK(status)) {
1479 if (sid_check_is_builtin(&dinfo->sid)) {
1480 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1481 return NT_STATUS_OK;
1485 * calculate how many entries we will return.
1487 * - the number of entries the client asked
1488 * - our limit on that
1489 * - the starting point (enumeration context)
1490 * - the buffer size the client will accept
1494 * We are a lot more like W2K. Instead of reading the SAM
1495 * each time to find the records we need to send back,
1496 * we read it once and link that copy to the sam handle.
1497 * For large user list (over the MAX_SAM_ENTRIES)
1498 * it's a definitive win.
1499 * second point to notice: between enumerations
1500 * our sam is now the same as it's a snapshoot.
1501 * third point: got rid of the static SAM_USER_21 struct
1502 * no more intermediate.
1503 * con: it uses much more memory, as a full copy is stored
1506 * If you want to change it, think twice and think
1507 * of the second point , that's really important.
1512 if ((r->in.level < 1) || (r->in.level > 5)) {
1513 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1514 (unsigned int)r->in.level ));
1515 return NT_STATUS_INVALID_INFO_CLASS;
1518 /* first limit the number of entries we will return */
1519 if (r->in.max_entries > max_sam_entries) {
1520 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1521 "entries, limiting to %d\n", r->in.max_entries,
1523 max_entries = max_sam_entries;
1526 /* calculate the size and limit on the number of entries we will
1529 temp_size=max_entries*struct_size;
1531 if (temp_size > r->in.buf_size) {
1532 max_entries = MIN((r->in.buf_size / struct_size),max_entries);
1533 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1534 "only %d entries\n", max_entries));
1539 /* THe following done as ROOT. Don't return without unbecome_root(). */
1541 switch (r->in.level) {
1544 if (dinfo->disp_info->users == NULL) {
1545 dinfo->disp_info->users = pdb_search_users(
1546 dinfo->disp_info, ACB_NORMAL);
1547 if (dinfo->disp_info->users == NULL) {
1549 return NT_STATUS_ACCESS_DENIED;
1551 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1552 (unsigned int)r->in.start_idx));
1554 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1555 (unsigned int)r->in.start_idx));
1558 num_account = pdb_search_entries(dinfo->disp_info->users,
1559 r->in.start_idx, max_entries,
1563 if (dinfo->disp_info->machines == NULL) {
1564 dinfo->disp_info->machines = pdb_search_users(
1565 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1566 if (dinfo->disp_info->machines == NULL) {
1568 return NT_STATUS_ACCESS_DENIED;
1570 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1571 (unsigned int)r->in.start_idx));
1573 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1574 (unsigned int)r->in.start_idx));
1577 num_account = pdb_search_entries(dinfo->disp_info->machines,
1578 r->in.start_idx, max_entries,
1583 if (dinfo->disp_info->groups == NULL) {
1584 dinfo->disp_info->groups = pdb_search_groups(
1586 if (dinfo->disp_info->groups == NULL) {
1588 return NT_STATUS_ACCESS_DENIED;
1590 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1591 (unsigned int)r->in.start_idx));
1593 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1594 (unsigned int)r->in.start_idx));
1597 num_account = pdb_search_entries(dinfo->disp_info->groups,
1598 r->in.start_idx, max_entries,
1603 smb_panic("info class changed");
1609 /* Now create reply structure */
1610 switch (r->in.level) {
1612 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1613 num_account, r->in.start_idx,
1617 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1618 num_account, r->in.start_idx,
1622 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1623 num_account, r->in.start_idx,
1627 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1628 num_account, r->in.start_idx,
1632 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1633 num_account, r->in.start_idx,
1637 smb_panic("info class changed");
1641 if (!NT_STATUS_IS_OK(disp_ret))
1644 if (max_entries <= num_account) {
1645 status = STATUS_MORE_ENTRIES;
1647 status = NT_STATUS_OK;
1650 /* Ensure we cache this enumeration. */
1651 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1653 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1655 *r->out.total_size = num_account * struct_size;
1656 *r->out.returned_size = num_account ? temp_size : 0;
1661 /****************************************************************
1662 _samr_QueryDisplayInfo2
1663 ****************************************************************/
1665 NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1666 struct samr_QueryDisplayInfo2 *r)
1668 struct samr_QueryDisplayInfo q;
1670 q.in.domain_handle = r->in.domain_handle;
1671 q.in.level = r->in.level;
1672 q.in.start_idx = r->in.start_idx;
1673 q.in.max_entries = r->in.max_entries;
1674 q.in.buf_size = r->in.buf_size;
1676 q.out.total_size = r->out.total_size;
1677 q.out.returned_size = r->out.returned_size;
1678 q.out.info = r->out.info;
1680 return _samr_QueryDisplayInfo(p, &q);
1683 /****************************************************************
1684 _samr_QueryDisplayInfo3
1685 ****************************************************************/
1687 NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1688 struct samr_QueryDisplayInfo3 *r)
1690 struct samr_QueryDisplayInfo q;
1692 q.in.domain_handle = r->in.domain_handle;
1693 q.in.level = r->in.level;
1694 q.in.start_idx = r->in.start_idx;
1695 q.in.max_entries = r->in.max_entries;
1696 q.in.buf_size = r->in.buf_size;
1698 q.out.total_size = r->out.total_size;
1699 q.out.returned_size = r->out.returned_size;
1700 q.out.info = r->out.info;
1702 return _samr_QueryDisplayInfo(p, &q);
1705 /*******************************************************************
1706 _samr_QueryAliasInfo
1707 ********************************************************************/
1709 NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1710 struct samr_QueryAliasInfo *r)
1712 struct samr_info *ainfo;
1713 struct acct_info *info;
1715 union samr_AliasInfo *alias_info = NULL;
1716 const char *alias_name = NULL;
1717 const char *alias_description = NULL;
1719 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1721 ainfo = samr_policy_handle_find(p,
1724 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1727 if (!NT_STATUS_IS_OK(status)) {
1731 alias_info = talloc_zero(p->mem_ctx, union samr_AliasInfo);
1733 return NT_STATUS_NO_MEMORY;
1736 info = talloc_zero(p->mem_ctx, struct acct_info);
1738 return NT_STATUS_NO_MEMORY;
1742 status = pdb_get_aliasinfo(&ainfo->sid, info);
1745 if (!NT_STATUS_IS_OK(status)) {
1750 alias_name = talloc_steal(r, info->acct_name);
1751 alias_description = talloc_steal(r, info->acct_desc);
1754 switch (r->in.level) {
1756 alias_info->all.name.string = alias_name;
1757 alias_info->all.num_members = 1; /* ??? */
1758 alias_info->all.description.string = alias_description;
1761 alias_info->name.string = alias_name;
1763 case ALIASINFODESCRIPTION:
1764 alias_info->description.string = alias_description;
1767 return NT_STATUS_INVALID_INFO_CLASS;
1770 *r->out.info = alias_info;
1772 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1774 return NT_STATUS_OK;
1777 /*******************************************************************
1779 ********************************************************************/
1781 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1782 struct samr_LookupNames *r)
1784 struct samr_info *dinfo;
1787 enum lsa_SidType *type;
1788 uint32_t i, num_rids = r->in.num_names;
1789 struct samr_Ids rids, types;
1790 uint32_t num_mapped = 0;
1791 struct dom_sid_buf buf;
1793 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1795 dinfo = samr_policy_handle_find(p,
1796 r->in.domain_handle,
1798 0 /* Don't know the acc_bits yet */,
1801 if (!NT_STATUS_IS_OK(status)) {
1805 if (num_rids > MAX_SAM_ENTRIES) {
1806 num_rids = MAX_SAM_ENTRIES;
1807 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1810 rid = talloc_array(p->mem_ctx, uint32_t, num_rids);
1811 NT_STATUS_HAVE_NO_MEMORY(rid);
1813 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1814 NT_STATUS_HAVE_NO_MEMORY(type);
1816 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1817 dom_sid_str_buf(&dinfo->sid, &buf)));
1819 for (i = 0; i < num_rids; i++) {
1821 status = NT_STATUS_NONE_MAPPED;
1822 type[i] = SID_NAME_UNKNOWN;
1824 rid[i] = 0xffffffff;
1826 if (sid_check_is_builtin(&dinfo->sid)) {
1827 if (lookup_builtin_name(r->in.names[i].string,
1830 type[i] = SID_NAME_ALIAS;
1833 lookup_global_sam_name(r->in.names[i].string, 0,
1837 if (type[i] != SID_NAME_UNKNOWN) {
1842 if (num_mapped == num_rids) {
1843 status = NT_STATUS_OK;
1844 } else if (num_mapped == 0) {
1845 status = NT_STATUS_NONE_MAPPED;
1847 status = STATUS_SOME_UNMAPPED;
1850 rids.count = num_rids;
1853 types.count = num_rids;
1854 types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1855 NT_STATUS_HAVE_NO_MEMORY(type);
1856 for (i = 0; i < num_rids; i++) {
1857 types.ids[i] = (type[i] & 0xffffffff);
1860 *r->out.rids = rids;
1861 *r->out.types = types;
1863 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1868 /****************************************************************
1869 _samr_ChangePasswordUser.
1871 So old it is just not worth implementing
1872 because it does not supply a plaintext and so we can't do password
1873 complexity checking and cannot update other services that use a
1874 plaintext password via passwd chat/pam password change/ldap password
1876 ****************************************************************/
1878 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1879 struct samr_ChangePasswordUser *r)
1881 return NT_STATUS_NOT_IMPLEMENTED;
1884 /*******************************************************************
1885 _samr_ChangePasswordUser2
1886 ********************************************************************/
1888 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1889 struct samr_ChangePasswordUser2 *r)
1892 char *user_name = NULL;
1894 const char *wks = NULL;
1897 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1899 if (!r->in.account->string) {
1900 return NT_STATUS_INVALID_PARAMETER;
1902 if (r->in.server && r->in.server->string) {
1903 wks = r->in.server->string;
1906 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1909 * Pass the user through the NT -> unix user mapping
1913 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1915 return NT_STATUS_NO_MEMORY;
1918 rhost = tsocket_address_inet_addr_string(p->remote_address,
1920 if (rhost == NULL) {
1921 return NT_STATUS_NO_MEMORY;
1924 encrypted = dcerpc_is_transport_encrypted(p->session_info);
1925 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
1927 return NT_STATUS_ACCESS_DENIED;
1931 * UNIX username case mangling not required, pass_oem_change
1932 * is case insensitive.
1935 status = pass_oem_change(user_name,
1937 r->in.lm_password->data,
1938 r->in.lm_verifier->hash,
1939 r->in.nt_password->data,
1940 r->in.nt_verifier->hash,
1943 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1945 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1946 return NT_STATUS_WRONG_PASSWORD;
1952 /****************************************************************
1953 _samr_OemChangePasswordUser2
1954 ****************************************************************/
1956 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1957 struct samr_OemChangePasswordUser2 *r)
1960 char *user_name = NULL;
1961 const char *wks = NULL;
1965 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1967 if (!r->in.account->string) {
1968 return NT_STATUS_INVALID_PARAMETER;
1970 if (r->in.server && r->in.server->string) {
1971 wks = r->in.server->string;
1974 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1977 * Pass the user through the NT -> unix user mapping
1981 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1983 return NT_STATUS_NO_MEMORY;
1987 * UNIX username case mangling not required, pass_oem_change
1988 * is case insensitive.
1991 if (!r->in.hash || !r->in.password) {
1992 return NT_STATUS_INVALID_PARAMETER;
1995 rhost = tsocket_address_inet_addr_string(p->remote_address,
1997 if (rhost == NULL) {
1998 return NT_STATUS_NO_MEMORY;
2001 encrypted = dcerpc_is_transport_encrypted(p->session_info);
2002 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
2004 return NT_STATUS_ACCESS_DENIED;
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)
2032 char *user_name = NULL;
2033 const char *wks = NULL;
2034 enum samPwdChangeReason reject_reason;
2035 struct samr_DomInfo1 *dominfo = NULL;
2036 struct userPwdChangeFailureInformation *reject = NULL;
2037 const struct loadparm_substitution *lp_sub =
2038 loadparm_s3_global_substitution();
2042 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2044 if (!r->in.account->string) {
2045 return NT_STATUS_INVALID_PARAMETER;
2047 if (r->in.server && r->in.server->string) {
2048 wks = r->in.server->string;
2051 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2054 * Pass the user through the NT -> unix user mapping
2058 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
2060 return NT_STATUS_NO_MEMORY;
2063 rhost = tsocket_address_inet_addr_string(p->remote_address,
2065 if (rhost == NULL) {
2066 return NT_STATUS_NO_MEMORY;
2070 * UNIX username case mangling not required, pass_oem_change
2071 * is case insensitive.
2074 status = pass_oem_change(user_name,
2076 r->in.lm_password->data,
2077 r->in.lm_verifier->hash,
2078 r->in.nt_password->data,
2079 r->in.nt_verifier->hash,
2081 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2082 return NT_STATUS_WRONG_PASSWORD;
2085 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2086 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2088 time_t u_expire, u_min_age;
2089 uint32_t account_policy_temp;
2091 dominfo = talloc_zero(p->mem_ctx, struct samr_DomInfo1);
2093 return NT_STATUS_NO_MEMORY;
2096 reject = talloc_zero(p->mem_ctx,
2097 struct userPwdChangeFailureInformation);
2099 return NT_STATUS_NO_MEMORY;
2106 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2107 dominfo->min_password_length = tmp;
2109 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2110 dominfo->password_history_length = tmp;
2112 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2113 &dominfo->password_properties);
2115 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2116 u_expire = account_policy_temp;
2118 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2119 u_min_age = account_policy_temp;
2125 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2126 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2128 if (lp_check_password_script(talloc_tos(), lp_sub)
2129 && *lp_check_password_script(talloc_tos(), lp_sub)) {
2130 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2133 reject->extendedFailureReason = reject_reason;
2135 *r->out.dominfo = dominfo;
2136 *r->out.reject = reject;
2139 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2144 /*******************************************************************
2145 makes a SAMR_R_LOOKUP_RIDS structure.
2146 ********************************************************************/
2148 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32_t num_names,
2150 struct lsa_String **lsa_name_array_p)
2152 struct lsa_String *lsa_name_array = NULL;
2155 *lsa_name_array_p = NULL;
2157 if (num_names != 0) {
2158 lsa_name_array = talloc_zero_array(ctx, struct lsa_String, num_names);
2159 if (!lsa_name_array) {
2164 for (i = 0; i < num_names; i++) {
2165 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2166 init_lsa_String(&lsa_name_array[i], names[i]);
2169 *lsa_name_array_p = lsa_name_array;
2174 /*******************************************************************
2176 ********************************************************************/
2178 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2179 struct samr_LookupRids *r)
2181 struct samr_info *dinfo;
2184 enum lsa_SidType *attrs = NULL;
2185 uint32_t *wire_attrs = NULL;
2186 int num_rids = (int)r->in.num_rids;
2188 struct lsa_Strings names_array;
2189 struct samr_Ids types_array;
2190 struct lsa_String *lsa_names = NULL;
2192 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2194 dinfo = samr_policy_handle_find(p,
2195 r->in.domain_handle,
2197 0 /* Don't know the acc_bits yet */,
2200 if (!NT_STATUS_IS_OK(status)) {
2204 if (num_rids > 1000) {
2205 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2206 "to samba4 idl this is not possible\n", num_rids));
2207 return NT_STATUS_UNSUCCESSFUL;
2211 names = talloc_zero_array(p->mem_ctx, const char *, num_rids);
2212 attrs = talloc_zero_array(p->mem_ctx, enum lsa_SidType, num_rids);
2213 wire_attrs = talloc_zero_array(p->mem_ctx, uint32_t, num_rids);
2215 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2216 return NT_STATUS_NO_MEMORY;
2223 become_root(); /* lookup_sid can require root privs */
2224 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2228 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2229 status = NT_STATUS_OK;
2232 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2234 return NT_STATUS_NO_MEMORY;
2237 /* Convert from enum lsa_SidType to uint32_t for wire format. */
2238 for (i = 0; i < num_rids; i++) {
2239 wire_attrs[i] = (uint32_t)attrs[i];
2242 names_array.count = num_rids;
2243 names_array.names = lsa_names;
2245 types_array.count = num_rids;
2246 types_array.ids = wire_attrs;
2248 *r->out.names = names_array;
2249 *r->out.types = types_array;
2251 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2256 /*******************************************************************
2258 ********************************************************************/
2260 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2261 struct samr_OpenUser *r)
2263 struct samu *sampass=NULL;
2265 struct samr_info *dinfo;
2266 struct security_descriptor *psd = NULL;
2267 uint32_t acc_granted;
2268 uint32_t des_access = r->in.access_mask;
2269 uint32_t extra_access = 0;
2274 /* These two privileges, if != SEC_PRIV_INVALID, indicate
2275 * privileges that the user must have to complete this
2276 * operation in defience of the fixed ACL */
2277 enum sec_privilege needed_priv_1, needed_priv_2;
2280 dinfo = samr_policy_handle_find(p,
2281 r->in.domain_handle,
2283 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2286 if (!NT_STATUS_IS_OK(status)) {
2290 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2291 return NT_STATUS_NO_MEMORY;
2294 /* append the user's RID to it */
2296 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2297 return NT_STATUS_NO_SUCH_USER;
2299 /* check if access can be granted as requested by client. */
2300 map_max_allowed_access(p->session_info->security_token,
2301 p->session_info->unix_token,
2304 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2305 se_map_generic(&des_access, &usr_generic_mapping);
2308 * Get the sampass first as we need to check privileges
2309 * based on what kind of user object this is.
2310 * But don't reveal info too early if it didn't exist.
2314 ret=pdb_getsampwsid(sampass, &sid);
2317 needed_priv_1 = SEC_PRIV_INVALID;
2318 needed_priv_2 = SEC_PRIV_INVALID;
2320 * We do the override access checks on *open*, not at
2324 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2326 if (acb_info & ACB_WSTRUST) {
2328 * SeMachineAccount is needed to add
2329 * GENERIC_RIGHTS_USER_WRITE to a machine
2332 needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2334 if (acb_info & ACB_NORMAL) {
2336 * SeAddUsers is needed to add
2337 * GENERIC_RIGHTS_USER_WRITE to a normal
2340 needed_priv_1 = SEC_PRIV_ADD_USERS;
2343 * Cheat - we have not set a specific privilege for
2344 * server (BDC) or domain trust account, so allow
2345 * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2346 * DOMAIN_RID_ADMINS.
2348 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2349 if (lp_enable_privileges() && nt_token_check_domain_rid(p->session_info->security_token,
2350 DOMAIN_RID_ADMINS)) {
2351 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2352 extra_access = GENERIC_RIGHTS_USER_WRITE;
2353 DEBUG(4,("_samr_OpenUser: Allowing "
2354 "GENERIC_RIGHTS_USER_WRITE for "
2360 TALLOC_FREE(sampass);
2362 nt_status = access_check_object(psd, p->session_info->security_token,
2363 needed_priv_1, needed_priv_2,
2364 GENERIC_RIGHTS_USER_WRITE, des_access,
2365 &acc_granted, "_samr_OpenUser");
2367 if ( !NT_STATUS_IS_OK(nt_status) )
2370 /* check that the SID exists in our domain. */
2372 return NT_STATUS_NO_SUCH_USER;
2375 /* If we did the rid admins hack above, allow access. */
2376 acc_granted |= extra_access;
2378 status = create_samr_policy_handle(p->mem_ctx,
2384 r->out.user_handle);
2385 if (!NT_STATUS_IS_OK(status)) {
2389 return NT_STATUS_OK;
2392 /*************************************************************************
2393 *************************************************************************/
2395 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2397 struct lsa_BinaryString **_r)
2399 struct lsa_BinaryString *r;
2402 return NT_STATUS_INVALID_PARAMETER;
2405 r = talloc_zero(mem_ctx, struct lsa_BinaryString);
2407 return NT_STATUS_NO_MEMORY;
2410 r->array = talloc_zero_array(mem_ctx, uint16_t, blob->length/2);
2412 return NT_STATUS_NO_MEMORY;
2414 memcpy(r->array, blob->data, blob->length);
2415 r->size = blob->length;
2416 r->length = blob->length;
2419 return NT_STATUS_NO_MEMORY;
2424 return NT_STATUS_OK;
2427 /*************************************************************************
2428 *************************************************************************/
2430 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2433 struct samr_LogonHours hours;
2434 const int units_per_week = 168;
2437 hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2442 hours.units_per_week = units_per_week;
2443 memset(hours.bits, 0xFF, units_per_week);
2445 if (pdb_get_hours(pw)) {
2446 memcpy(hours.bits, pdb_get_hours(pw),
2447 MIN(pdb_get_hours_len(pw), units_per_week));
2453 /*************************************************************************
2455 *************************************************************************/
2457 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2458 struct samr_UserInfo1 *r,
2460 struct dom_sid *domain_sid)
2462 const struct dom_sid *sid_group;
2463 uint32_t primary_gid;
2466 sid_group = pdb_get_group_sid(pw);
2469 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2470 struct dom_sid_buf buf1, buf2;
2472 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2473 "which conflicts with the domain sid %s. Failing operation.\n",
2474 pdb_get_username(pw),
2475 dom_sid_str_buf(sid_group, &buf1),
2476 dom_sid_str_buf(domain_sid, &buf2)));
2477 return NT_STATUS_UNSUCCESSFUL;
2480 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2481 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2482 r->primary_gid = primary_gid;
2483 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2484 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2486 return NT_STATUS_OK;
2489 /*************************************************************************
2491 *************************************************************************/
2493 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2494 struct samr_UserInfo2 *r,
2497 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2498 r->reserved.string = NULL;
2499 r->country_code = pdb_get_country_code(pw);
2500 r->code_page = pdb_get_code_page(pw);
2502 return NT_STATUS_OK;
2505 /*************************************************************************
2507 *************************************************************************/
2509 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2510 struct samr_UserInfo3 *r,
2512 struct dom_sid *domain_sid)
2514 const struct dom_sid *sid_user, *sid_group;
2515 uint32_t rid, primary_gid;
2516 struct dom_sid_buf buf1, buf2;
2518 sid_user = pdb_get_user_sid(pw);
2520 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2521 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2522 "the domain sid %s. Failing operation.\n",
2523 pdb_get_username(pw),
2524 dom_sid_str_buf(sid_user, &buf1),
2525 dom_sid_str_buf(domain_sid, &buf2)));
2526 return NT_STATUS_UNSUCCESSFUL;
2530 sid_group = pdb_get_group_sid(pw);
2533 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2534 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2535 "which conflicts with the domain sid %s. Failing operation.\n",
2536 pdb_get_username(pw),
2537 dom_sid_str_buf(sid_group, &buf1),
2538 dom_sid_str_buf(domain_sid, &buf2)));
2539 return NT_STATUS_UNSUCCESSFUL;
2542 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2543 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2544 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2545 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2546 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2548 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2549 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2550 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2551 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2552 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2553 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2554 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2556 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2558 r->primary_gid = primary_gid;
2559 r->acct_flags = pdb_get_acct_ctrl(pw);
2560 r->bad_password_count = pdb_get_bad_password_count(pw);
2561 r->logon_count = pdb_get_logon_count(pw);
2563 return NT_STATUS_OK;
2566 /*************************************************************************
2568 *************************************************************************/
2570 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2571 struct samr_UserInfo4 *r,
2574 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2576 return NT_STATUS_OK;
2579 /*************************************************************************
2581 *************************************************************************/
2583 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2584 struct samr_UserInfo5 *r,
2586 struct dom_sid *domain_sid)
2588 const struct dom_sid *sid_user, *sid_group;
2589 uint32_t rid, primary_gid;
2590 struct dom_sid_buf buf1, buf2;
2592 sid_user = pdb_get_user_sid(pw);
2594 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2595 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2596 "the domain sid %s. Failing operation.\n",
2597 pdb_get_username(pw),
2598 dom_sid_str_buf(sid_user, &buf1),
2599 dom_sid_str_buf(domain_sid, &buf2)));
2600 return NT_STATUS_UNSUCCESSFUL;
2604 sid_group = pdb_get_group_sid(pw);
2607 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2608 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2609 "which conflicts with the domain sid %s. Failing operation.\n",
2610 pdb_get_username(pw),
2611 dom_sid_str_buf(sid_group, &buf1),
2612 dom_sid_str_buf(domain_sid, &buf2)));
2613 return NT_STATUS_UNSUCCESSFUL;
2616 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2617 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2618 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2619 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2621 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2622 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2623 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2624 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2625 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2626 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2627 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2628 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2630 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2632 r->primary_gid = primary_gid;
2633 r->acct_flags = pdb_get_acct_ctrl(pw);
2634 r->bad_password_count = pdb_get_bad_password_count(pw);
2635 r->logon_count = pdb_get_logon_count(pw);
2637 return NT_STATUS_OK;
2640 /*************************************************************************
2642 *************************************************************************/
2644 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2645 struct samr_UserInfo6 *r,
2648 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2649 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2651 return NT_STATUS_OK;
2654 /*************************************************************************
2655 get_user_info_7. Safe. Only gives out account_name.
2656 *************************************************************************/
2658 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2659 struct samr_UserInfo7 *r,
2660 struct samu *smbpass)
2662 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2663 if (!r->account_name.string) {
2664 return NT_STATUS_NO_MEMORY;
2667 return NT_STATUS_OK;
2670 /*************************************************************************
2672 *************************************************************************/
2674 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2675 struct samr_UserInfo8 *r,
2678 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2680 return NT_STATUS_OK;
2683 /*************************************************************************
2684 get_user_info_9. Only gives out primary group SID.
2685 *************************************************************************/
2687 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2688 struct samr_UserInfo9 *r,
2689 struct samu *smbpass)
2691 r->primary_gid = pdb_get_group_rid(smbpass);
2693 return NT_STATUS_OK;
2696 /*************************************************************************
2698 *************************************************************************/
2700 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2701 struct samr_UserInfo10 *r,
2704 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2705 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2707 return NT_STATUS_OK;
2710 /*************************************************************************
2712 *************************************************************************/
2714 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2715 struct samr_UserInfo11 *r,
2718 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2720 return NT_STATUS_OK;
2723 /*************************************************************************
2725 *************************************************************************/
2727 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2728 struct samr_UserInfo12 *r,
2731 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2733 return NT_STATUS_OK;
2736 /*************************************************************************
2738 *************************************************************************/
2740 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2741 struct samr_UserInfo13 *r,
2744 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2746 return NT_STATUS_OK;
2749 /*************************************************************************
2751 *************************************************************************/
2753 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2754 struct samr_UserInfo14 *r,
2757 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2759 return NT_STATUS_OK;
2762 /*************************************************************************
2763 get_user_info_16. Safe. Only gives out acb bits.
2764 *************************************************************************/
2766 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2767 struct samr_UserInfo16 *r,
2768 struct samu *smbpass)
2770 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2772 return NT_STATUS_OK;
2775 /*************************************************************************
2777 *************************************************************************/
2779 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2780 struct samr_UserInfo17 *r,
2783 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2785 return NT_STATUS_OK;
2788 /*************************************************************************
2789 get_user_info_18. OK - this is the killer as it gives out password info.
2790 Ensure that this is only allowed on an encrypted connection with a root
2792 *************************************************************************/
2794 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2795 TALLOC_CTX *mem_ctx,
2796 struct samr_UserInfo18 *r,
2797 struct dom_sid *user_sid)
2799 struct samu *smbpass=NULL;
2801 const uint8_t *nt_pass = NULL;
2802 const uint8_t *lm_pass = NULL;
2806 if (p->transport != NCALRPC) {
2807 return NT_STATUS_INVALID_INFO_CLASS;
2810 if (!security_token_is_system(p->session_info->security_token)) {
2811 return NT_STATUS_ACCESS_DENIED;
2815 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2818 if ( !(smbpass = samu_new( mem_ctx )) ) {
2819 return NT_STATUS_NO_MEMORY;
2822 ret = pdb_getsampwsid(smbpass, user_sid);
2825 struct dom_sid_buf buf;
2826 DEBUG(4, ("User %s not found\n",
2827 dom_sid_str_buf(user_sid, &buf)));
2828 TALLOC_FREE(smbpass);
2829 return root_mode() ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2832 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2834 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2835 TALLOC_FREE(smbpass);
2836 return NT_STATUS_ACCOUNT_DISABLED;
2839 lm_pass = pdb_get_lanman_passwd(smbpass);
2840 if (lm_pass != NULL) {
2841 memcpy(r->lm_pwd.hash, lm_pass, 16);
2842 r->lm_pwd_active = true;
2845 nt_pass = pdb_get_nt_passwd(smbpass);
2846 if (nt_pass != NULL) {
2847 memcpy(r->nt_pwd.hash, nt_pass, 16);
2848 r->nt_pwd_active = true;
2850 r->password_expired = 0; /* FIXME */
2852 TALLOC_FREE(smbpass);
2854 return NT_STATUS_OK;
2857 /*************************************************************************
2859 *************************************************************************/
2861 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2862 struct samr_UserInfo20 *r,
2863 struct samu *sampass)
2865 const char *munged_dial = NULL;
2868 struct lsa_BinaryString *parameters = NULL;
2872 munged_dial = pdb_get_munged_dial(sampass);
2874 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2875 munged_dial, (int)strlen(munged_dial)));
2878 blob = base64_decode_data_blob(munged_dial);
2880 blob = data_blob_string_const_null("");
2883 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2884 data_blob_free(&blob);
2885 if (!NT_STATUS_IS_OK(status)) {
2889 r->parameters = *parameters;
2891 return NT_STATUS_OK;
2895 /*************************************************************************
2897 *************************************************************************/
2899 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2900 struct samr_UserInfo21 *r,
2902 struct dom_sid *domain_sid,
2903 uint32_t acc_granted)
2906 const struct dom_sid *sid_user, *sid_group;
2907 uint32_t rid, primary_gid;
2908 NTTIME force_password_change;
2909 time_t must_change_time;
2910 struct lsa_BinaryString *parameters = NULL;
2911 const char *munged_dial = NULL;
2913 struct dom_sid_buf buf1, buf2;
2917 sid_user = pdb_get_user_sid(pw);
2919 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2920 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2921 "the domain sid %s. Failing operation.\n",
2922 pdb_get_username(pw),
2923 dom_sid_str_buf(sid_user, &buf1),
2924 dom_sid_str_buf(domain_sid, &buf2)));
2925 return NT_STATUS_UNSUCCESSFUL;
2929 sid_group = pdb_get_group_sid(pw);
2932 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2933 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2934 "which conflicts with the domain sid %s. Failing operation.\n",
2935 pdb_get_username(pw),
2936 dom_sid_str_buf(sid_group, &buf1),
2937 dom_sid_str_buf(domain_sid, &buf2)));
2938 return NT_STATUS_UNSUCCESSFUL;
2941 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2942 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2943 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2944 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2945 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2947 must_change_time = pdb_get_pass_must_change_time(pw);
2948 if (pdb_is_password_change_time_max(must_change_time)) {
2949 unix_to_nt_time_abs(&force_password_change, must_change_time);
2951 unix_to_nt_time(&force_password_change, must_change_time);
2954 munged_dial = pdb_get_munged_dial(pw);
2956 blob = base64_decode_data_blob(munged_dial);
2958 blob = data_blob_string_const_null("");
2961 status = init_samr_parameters_string(mem_ctx, &blob, ¶meters);
2962 data_blob_free(&blob);
2963 if (!NT_STATUS_IS_OK(status)) {
2967 r->force_password_change = force_password_change;
2969 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2970 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2971 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2972 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2973 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2974 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2975 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2976 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2977 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2979 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2980 r->parameters = *parameters;
2982 r->primary_gid = primary_gid;
2983 r->acct_flags = pdb_get_acct_ctrl(pw);
2984 r->bad_password_count = pdb_get_bad_password_count(pw);
2985 r->logon_count = pdb_get_logon_count(pw);
2986 r->fields_present = pdb_build_fields_present(pw);
2987 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2988 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2989 r->country_code = pdb_get_country_code(pw);
2990 r->code_page = pdb_get_code_page(pw);
2991 r->lm_password_set = 0;
2992 r->nt_password_set = 0;
2997 Look at a user on a real NT4 PDC with usrmgr, press
2998 'ok'. Then you will see that fields_present is set to
2999 0x08f827fa. Look at the user immediately after that again,
3000 and you will see that 0x00fffff is returned. This solves
3001 the problem that you get access denied after having looked
3009 return NT_STATUS_OK;
3012 /*******************************************************************
3014 ********************************************************************/
3016 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
3017 struct samr_QueryUserInfo *r)
3020 union samr_UserInfo *user_info = NULL;
3021 struct samr_info *uinfo;
3022 struct dom_sid domain_sid;
3025 struct samu *pwd = NULL;
3026 uint32_t acc_required, acc_granted;
3027 struct dom_sid_buf buf;
3029 switch (r->in.level) {
3030 case 1: /* UserGeneralInformation */
3031 /* USER_READ_GENERAL */
3032 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3034 case 2: /* UserPreferencesInformation */
3035 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
3036 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
3037 SAMR_USER_ACCESS_GET_NAME_ETC;
3039 case 3: /* UserLogonInformation */
3040 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3041 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3042 SAMR_USER_ACCESS_GET_LOCALE |
3043 SAMR_USER_ACCESS_GET_LOGONINFO |
3044 SAMR_USER_ACCESS_GET_ATTRIBUTES;
3046 case 4: /* UserLogonHoursInformation */
3047 /* USER_READ_LOGON */
3048 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3050 case 5: /* UserAccountInformation */
3051 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
3052 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
3053 SAMR_USER_ACCESS_GET_LOCALE |
3054 SAMR_USER_ACCESS_GET_LOGONINFO |
3055 SAMR_USER_ACCESS_GET_ATTRIBUTES;
3057 case 6: /* UserNameInformation */
3058 case 7: /* UserAccountNameInformation */
3059 case 8: /* UserFullNameInformation */
3060 case 9: /* UserPrimaryGroupInformation */
3061 case 13: /* UserAdminCommentInformation */
3062 /* USER_READ_GENERAL */
3063 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
3065 case 10: /* UserHomeInformation */
3066 case 11: /* UserScriptInformation */
3067 case 12: /* UserProfileInformation */
3068 case 14: /* UserWorkStationsInformation */
3069 /* USER_READ_LOGON */
3070 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3072 case 16: /* UserControlInformation */
3073 case 17: /* UserExpiresInformation */
3074 case 20: /* UserParametersInformation */
3075 /* USER_READ_ACCOUNT */
3076 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3078 case 21: /* UserAllInformation */
3080 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3082 case 18: /* UserInternal1Information */
3084 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3086 case 23: /* UserInternal4Information */
3087 case 24: /* UserInternal4InformationNew */
3088 case 25: /* UserInternal4InformationNew */
3089 case 26: /* UserInternal5InformationNew */
3091 return NT_STATUS_INVALID_INFO_CLASS;
3095 uinfo = samr_policy_handle_find(p,
3101 if (!NT_STATUS_IS_OK(status)) {
3105 domain_sid = uinfo->sid;
3107 sid_split_rid(&domain_sid, &rid);
3109 if (!sid_check_is_in_our_sam(&uinfo->sid))
3110 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3112 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3113 dom_sid_str_buf(&uinfo->sid, &buf)));
3115 user_info = talloc_zero(p->mem_ctx, union samr_UserInfo);
3117 return NT_STATUS_NO_MEMORY;
3120 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3122 if (!(pwd = samu_new(p->mem_ctx))) {
3123 return NT_STATUS_NO_MEMORY;
3127 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3131 DEBUG(4,("User %s not found\n",
3132 dom_sid_str_buf(&uinfo->sid, &buf)));
3134 return NT_STATUS_NO_SUCH_USER;
3137 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3139 samr_clear_sam_passwd(pwd);
3141 switch (r->in.level) {
3143 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3146 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3149 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3152 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3155 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3158 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3161 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3164 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3167 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3170 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3173 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3176 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3179 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3182 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3185 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3188 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3191 /* level 18 is special */
3192 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3196 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3199 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3202 status = NT_STATUS_INVALID_INFO_CLASS;
3206 if (!NT_STATUS_IS_OK(status)) {
3210 *r->out.info = user_info;
3215 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3220 /****************************************************************
3221 ****************************************************************/
3223 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3224 struct samr_QueryUserInfo2 *r)
3226 struct samr_QueryUserInfo u;
3228 u.in.user_handle = r->in.user_handle;
3229 u.in.level = r->in.level;
3230 u.out.info = r->out.info;
3232 return _samr_QueryUserInfo(p, &u);
3235 /*******************************************************************
3236 _samr_GetGroupsForUser
3237 ********************************************************************/
3239 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3240 struct samr_GetGroupsForUser *r)
3242 struct samr_info *uinfo;
3243 struct samu *sam_pass=NULL;
3244 struct dom_sid *sids;
3245 struct samr_RidWithAttribute dom_gid;
3246 struct samr_RidWithAttribute *gids = NULL;
3247 uint32_t primary_group_rid;
3248 uint32_t num_groups = 0;
3250 uint32_t i, num_gids;
3253 bool success = False;
3254 struct dom_sid_buf buf;
3256 struct samr_RidWithAttributeArray *rids = NULL;
3259 * from the SID in the request:
3260 * we should send back the list of DOMAIN GROUPS
3261 * the user is a member of
3263 * and only the DOMAIN GROUPS
3264 * no ALIASES !!! neither aliases of the domain
3265 * nor aliases of the builtin SID
3270 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3272 uinfo = samr_policy_handle_find(p,
3275 SAMR_USER_ACCESS_GET_GROUPS,
3278 if (!NT_STATUS_IS_OK(result)) {
3282 rids = talloc_zero(p->mem_ctx, struct samr_RidWithAttributeArray);
3284 return NT_STATUS_NO_MEMORY;
3287 if (!sid_check_is_in_our_sam(&uinfo->sid))
3288 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3290 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3291 return NT_STATUS_NO_MEMORY;
3295 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3299 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3300 dom_sid_str_buf(&uinfo->sid, &buf)));
3301 return NT_STATUS_NO_SUCH_USER;
3306 /* make both calls inside the root block */
3308 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3309 &sids, &unix_gids, &num_groups);
3310 if ( NT_STATUS_IS_OK(result) ) {
3311 success = sid_peek_check_rid(get_global_sam_sid(),
3312 pdb_get_group_sid(sam_pass),
3313 &primary_group_rid);
3317 if (!NT_STATUS_IS_OK(result)) {
3318 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3319 dom_sid_str_buf(&uinfo->sid, &buf)));
3324 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3325 dom_sid_str_buf(pdb_get_group_sid(sam_pass), &buf),
3326 pdb_get_username(sam_pass)));
3327 TALLOC_FREE(sam_pass);
3328 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3334 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3336 dom_gid.rid = primary_group_rid;
3337 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3339 for (i=0; i<num_groups; i++) {
3341 if (!sid_peek_check_rid(get_global_sam_sid(),
3342 &(sids[i]), &dom_gid.rid)) {
3343 DEBUG(10, ("Found sid %s not in our domain\n",
3344 dom_sid_str_buf(&sids[i], &buf)));
3348 if (dom_gid.rid == primary_group_rid) {
3349 /* We added the primary group directly from the
3350 * sam_account. The other SIDs are unique from
3351 * enum_group_memberships */
3355 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3358 rids->count = num_gids;
3361 *r->out.rids = rids;
3363 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3368 /*******************************************************************
3369 ********************************************************************/
3371 static uint32_t samr_get_server_role(void)
3373 uint32_t role = ROLE_DOMAIN_PDC;
3375 if (lp_server_role() == ROLE_DOMAIN_BDC) {
3376 role = ROLE_DOMAIN_BDC;
3382 /*******************************************************************
3383 ********************************************************************/
3385 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3386 struct samr_DomInfo1 *r)
3388 const struct loadparm_substitution *lp_sub =
3389 loadparm_s3_global_substitution();
3390 uint32_t account_policy_temp;
3391 time_t u_expire, u_min_age;
3397 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3398 r->min_password_length = account_policy_temp;
3400 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3401 r->password_history_length = account_policy_temp;
3403 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3404 &r->password_properties);
3406 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3407 u_expire = account_policy_temp;
3409 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3410 u_min_age = account_policy_temp;
3416 unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3417 unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3419 if (lp_check_password_script(talloc_tos(), lp_sub) && *lp_check_password_script(talloc_tos(), lp_sub)){
3420 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3423 return NT_STATUS_OK;
3426 /*******************************************************************
3427 ********************************************************************/
3429 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3430 struct samr_DomGeneralInformation *r,
3431 struct samr_info *dinfo)
3433 const struct loadparm_substitution *lp_sub =
3434 loadparm_s3_global_substitution();
3442 r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3443 r->num_groups = count_sam_groups(dinfo->disp_info);
3444 r->num_aliases = count_sam_aliases(dinfo->disp_info);
3446 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3448 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3450 if (!pdb_get_seq_num(&seq_num)) {
3451 seq_num = time(NULL);
3458 r->oem_information.string = lp_server_string(r, lp_sub);
3459 r->domain_name.string = lp_workgroup();
3460 r->primary.string = lp_netbios_name();
3461 r->sequence_num = seq_num;
3462 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3463 r->role = (enum samr_Role) samr_get_server_role();
3466 return NT_STATUS_OK;
3469 /*******************************************************************
3470 ********************************************************************/
3472 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3473 struct samr_DomInfo3 *r)
3483 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3484 u_logout = (time_t)ul;
3491 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3493 return NT_STATUS_OK;
3496 /*******************************************************************
3497 ********************************************************************/
3499 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3500 struct samr_DomOEMInformation *r)
3502 const struct loadparm_substitution *lp_sub =
3503 loadparm_s3_global_substitution();
3505 r->oem_information.string = lp_server_string(r, lp_sub);
3507 return NT_STATUS_OK;
3510 /*******************************************************************
3511 ********************************************************************/
3513 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3514 struct samr_DomInfo5 *r)
3516 r->domain_name.string = get_global_sam_name();
3518 return NT_STATUS_OK;
3521 /*******************************************************************
3522 ********************************************************************/
3524 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3525 struct samr_DomInfo6 *r)
3527 /* NT returns its own name when a PDC. win2k and later
3528 * only the name of the PDC if itself is a BDC (samba4
3530 r->primary.string = lp_netbios_name();
3532 return NT_STATUS_OK;
3535 /*******************************************************************
3536 ********************************************************************/
3538 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3539 struct samr_DomInfo7 *r)
3541 r->role = (enum samr_Role) samr_get_server_role();
3543 return NT_STATUS_OK;
3546 /*******************************************************************
3547 ********************************************************************/
3549 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3550 struct samr_DomInfo8 *r)
3558 if (!pdb_get_seq_num(&seq_num)) {
3559 seq_num = time(NULL);
3566 r->sequence_num = seq_num;
3567 r->domain_create_time = 0;
3569 return NT_STATUS_OK;
3572 /*******************************************************************
3573 ********************************************************************/
3575 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3576 struct samr_DomInfo9 *r)
3578 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3580 return NT_STATUS_OK;
3583 /*******************************************************************
3584 ********************************************************************/
3586 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3587 struct samr_DomGeneralInformation2 *r,
3588 struct samr_info *dinfo)
3591 uint32_t account_policy_temp;
3592 time_t u_lock_duration, u_reset_time;
3594 status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3595 if (!NT_STATUS_IS_OK(status)) {
3603 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3604 u_lock_duration = account_policy_temp;
3605 if (u_lock_duration != -1) {
3606 u_lock_duration *= 60;
3609 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3610 u_reset_time = account_policy_temp * 60;
3612 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3613 r->lockout_threshold = account_policy_temp;
3619 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3620 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3622 return NT_STATUS_OK;
3625 /*******************************************************************
3626 ********************************************************************/
3628 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3629 struct samr_DomInfo12 *r)
3631 uint32_t account_policy_temp;
3632 time_t u_lock_duration, u_reset_time;
3638 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3639 u_lock_duration = account_policy_temp;
3640 if (u_lock_duration != -1) {
3641 u_lock_duration *= 60;
3644 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3645 u_reset_time = account_policy_temp * 60;
3647 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3648 r->lockout_threshold = account_policy_temp;
3654 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3655 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3657 return NT_STATUS_OK;
3660 /*******************************************************************
3661 ********************************************************************/
3663 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3664 struct samr_DomInfo13 *r)
3672 if (!pdb_get_seq_num(&seq_num)) {
3673 seq_num = time(NULL);
3680 r->sequence_num = seq_num;
3681 r->domain_create_time = 0;
3682 r->modified_count_at_last_promotion = 0;
3684 return NT_STATUS_OK;
3687 /*******************************************************************
3688 _samr_QueryDomainInfo
3689 ********************************************************************/
3691 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3692 struct samr_QueryDomainInfo *r)
3694 NTSTATUS status = NT_STATUS_OK;
3695 struct samr_info *dinfo;
3696 union samr_DomainInfo *dom_info;
3698 uint32_t acc_required;
3700 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3702 switch (r->in.level) {
3703 case 1: /* DomainPasswordInformation */
3704 case 12: /* DomainLockoutInformation */
3705 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3706 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3708 case 11: /* DomainGeneralInformation2 */
3709 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3710 * DOMAIN_READ_OTHER_PARAMETERS */
3711 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3712 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3714 case 2: /* DomainGeneralInformation */
3715 case 3: /* DomainLogoffInformation */
3716 case 4: /* DomainOemInformation */
3717 case 5: /* DomainReplicationInformation */
3718 case 6: /* DomainReplicationInformation */
3719 case 7: /* DomainServerRoleInformation */
3720 case 8: /* DomainModifiedInformation */
3721 case 9: /* DomainStateInformation */
3722 case 10: /* DomainUasInformation */
3723 case 13: /* DomainModifiedInformation2 */
3724 /* DOMAIN_READ_OTHER_PARAMETERS */
3725 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3728 return NT_STATUS_INVALID_INFO_CLASS;
3731 dinfo = samr_policy_handle_find(p,
3732 r->in.domain_handle,
3737 if (!NT_STATUS_IS_OK(status)) {
3741 dom_info = talloc_zero(p->mem_ctx, union samr_DomainInfo);
3743 return NT_STATUS_NO_MEMORY;
3746 switch (r->in.level) {
3748 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3751 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3754 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3757 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3760 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3763 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3766 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3769 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3772 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3775 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3778 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3781 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3784 return NT_STATUS_INVALID_INFO_CLASS;
3787 if (!NT_STATUS_IS_OK(status)) {
3791 *r->out.info = dom_info;
3793 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3798 /* W2k3 seems to use the same check for all 3 objects that can be created via
3799 * SAMR, if you try to create for example "Dialup" as an alias it says
3800 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3803 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3805 enum lsa_SidType type;
3808 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3811 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3812 * whether the name already exists */
3813 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3814 NULL, NULL, NULL, &type);
3818 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3819 return NT_STATUS_OK;
3822 DEBUG(5, ("trying to create %s, exists as %s\n",
3823 new_name, sid_type_lookup(type)));
3825 if (type == SID_NAME_DOM_GRP) {
3826 return NT_STATUS_GROUP_EXISTS;
3828 if (type == SID_NAME_ALIAS) {
3829 return NT_STATUS_ALIAS_EXISTS;
3832 /* Yes, the default is NT_STATUS_USER_EXISTS */
3833 return NT_STATUS_USER_EXISTS;
3836 /*******************************************************************
3838 ********************************************************************/
3840 NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3841 struct samr_CreateUser2 *r)
3843 const char *account = NULL;
3845 uint32_t acb_info = r->in.acct_flags;
3846 struct samr_info *dinfo;
3848 uint32_t acc_granted;
3849 struct security_descriptor *psd;
3851 /* check this, when giving away 'add computer to domain' privs */
3852 uint32_t des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3853 bool can_add_account = False;
3855 /* Which privilege is needed to override the ACL? */
3856 enum sec_privilege needed_priv = SEC_PRIV_INVALID;
3858 dinfo = samr_policy_handle_find(p,
3859 r->in.domain_handle,
3861 SAMR_DOMAIN_ACCESS_CREATE_USER,
3864 if (!NT_STATUS_IS_OK(nt_status)) {
3868 if (sid_check_is_builtin(&dinfo->sid)) {
3869 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3870 return NT_STATUS_ACCESS_DENIED;
3873 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3874 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3875 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3876 this parameter is not an account type */
3877 return NT_STATUS_INVALID_PARAMETER;
3880 account = r->in.account_name->string;
3881 if (account == NULL) {
3882 return NT_STATUS_NO_MEMORY;
3885 nt_status = can_create(p->mem_ctx, account);
3886 if (!NT_STATUS_IS_OK(nt_status)) {
3890 /* determine which user right we need to check based on the acb_info */
3893 can_add_account = true;
3894 } else if (acb_info & ACB_WSTRUST) {
3895 needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
3896 can_add_account = security_token_has_privilege(
3897 p->session_info->security_token, needed_priv);
3898 } else if (acb_info & ACB_NORMAL &&
3899 (account[strlen(account)-1] != '$')) {
3900 /* usrmgr.exe (and net rpc trustdom add) creates a normal user
3901 account for domain trusts and changes the ACB flags later */
3902 needed_priv = SEC_PRIV_ADD_USERS;
3903 can_add_account = security_token_has_privilege(
3904 p->session_info->security_token, needed_priv);
3905 } else if (lp_enable_privileges()) {
3906 /* implicit assumption of a BDC or domain trust account here
3907 * (we already check the flags earlier) */
3908 /* only Domain Admins can add a BDC or domain trust */
3909 can_add_account = nt_token_check_domain_rid(
3910 p->session_info->security_token,
3911 DOMAIN_RID_ADMINS );
3914 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3915 uidtoname(p->session_info->unix_token->uid),
3916 can_add_account ? "True":"False" ));
3918 if (!can_add_account) {
3919 return NT_STATUS_ACCESS_DENIED;
3922 /********** BEGIN Admin BLOCK **********/
3924 (void)winbind_off();
3926 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3931 /********** END Admin BLOCK **********/
3933 /* now check for failure */
3935 if ( !NT_STATUS_IS_OK(nt_status) )
3938 /* Get the user's SID */
3940 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3942 map_max_allowed_access(p->session_info->security_token,
3943 p->session_info->unix_token,
3946 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3947 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3948 se_map_generic(&des_access, &usr_generic_mapping);
3951 * JRA - TESTME. We just created this user so we
3952 * had rights to create them. Do we need to check
3953 * any further access on this object ? Can't we
3954 * just assume we have all the rights we need ?
3957 nt_status = access_check_object(psd, p->session_info->security_token,
3958 needed_priv, SEC_PRIV_INVALID,
3959 GENERIC_RIGHTS_USER_WRITE, des_access,
3960 &acc_granted, "_samr_CreateUser2");
3962 if ( !NT_STATUS_IS_OK(nt_status) ) {
3966 nt_status = create_samr_policy_handle(p->mem_ctx,
3972 r->out.user_handle);
3973 if (!NT_STATUS_IS_OK(nt_status)) {
3977 /* After a "set" ensure we have no cached display info. */
3978 force_flush_samr_cache(&sid);
3980 *r->out.access_granted = acc_granted;
3982 return NT_STATUS_OK;
3985 /****************************************************************
3986 ****************************************************************/
3988 NTSTATUS _samr_CreateUser(struct pipes_struct *p,
3989 struct samr_CreateUser *r)
3991 struct samr_CreateUser2 c;
3992 uint32_t access_granted;
3994 c.in.domain_handle = r->in.domain_handle;
3995 c.in.account_name = r->in.account_name;
3996 c.in.acct_flags = ACB_NORMAL;
3997 c.in.access_mask = r->in.access_mask;
3998 c.out.user_handle = r->out.user_handle;
3999 c.out.access_granted = &access_granted;
4000 c.out.rid = r->out.rid;
4002 return _samr_CreateUser2(p, &c);
4005 /*******************************************************************
4007 ********************************************************************/
4009 NTSTATUS _samr_Connect(struct pipes_struct *p,
4010 struct samr_Connect *r)
4012 uint32_t acc_granted;
4013 uint32_t des_access = r->in.access_mask;
4018 if (!pipe_access_check(p)) {
4019 DEBUG(3, ("access denied to _samr_Connect\n"));
4020 return NT_STATUS_ACCESS_DENIED;
4023 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
4024 was observed from a win98 client trying to enumerate users (when configured
4025 user level access control on shares) --jerry */
4027 map_max_allowed_access(p->session_info->security_token,
4028 p->session_info->unix_token,
4031 se_map_generic( &des_access, &sam_generic_mapping );
4033 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
4034 |SAMR_ACCESS_LOOKUP_DOMAIN);
4036 /* set up the SAMR connect_anon response */
4037 status = create_samr_policy_handle(p->mem_ctx,
4039 SAMR_HANDLE_CONNECT,
4043 r->out.connect_handle);
4044 if (!NT_STATUS_IS_OK(status)) {
4048 return NT_STATUS_OK;
4051 /*******************************************************************
4053 ********************************************************************/
4055 NTSTATUS _samr_Connect2(struct pipes_struct *p,
4056 struct samr_Connect2 *r)
4058 struct dcesrv_call_state *dce_call = p->dce_call;
4059 struct security_descriptor *psd = NULL;
4060 uint32_t acc_granted;
4061 uint32_t des_access = r->in.access_mask;
4064 const char *fn = "_samr_Connect2";
4066 switch (dce_call->pkt.u.request.opnum) {
4067 case NDR_SAMR_CONNECT2:
4068 fn = "_samr_Connect2";
4070 case NDR_SAMR_CONNECT3:
4071 fn = "_samr_Connect3";
4073 case NDR_SAMR_CONNECT4:
4074 fn = "_samr_Connect4";
4076 case NDR_SAMR_CONNECT5:
4077 fn = "_samr_Connect5";
4081 DEBUG(5,("%s: %d\n", fn, __LINE__));
4085 if (!pipe_access_check(p)) {
4086 DEBUG(3, ("access denied to %s\n", fn));
4087 return NT_STATUS_ACCESS_DENIED;
4090 map_max_allowed_access(p->session_info->security_token,
4091 p->session_info->unix_token,
4094 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
4095 se_map_generic(&des_access, &sam_generic_mapping);
4097 nt_status = access_check_object(psd, p->session_info->security_token,
4098 SEC_PRIV_INVALID, SEC_PRIV_INVALID,
4099 0, des_access, &acc_granted, fn);
4101 if ( !NT_STATUS_IS_OK(nt_status) )
4104 nt_status = create_samr_policy_handle(p->mem_ctx,
4106 SAMR_HANDLE_CONNECT,
4110 r->out.connect_handle);
4111 if (!NT_STATUS_IS_OK(nt_status)) {
4115 DEBUG(5,("%s: %d\n", fn, __LINE__));
4117 return NT_STATUS_OK;
4120 /****************************************************************
4122 ****************************************************************/
4124 NTSTATUS _samr_Connect3(struct pipes_struct *p,
4125 struct samr_Connect3 *r)
4127 struct samr_Connect2 c;
4129 c.in.system_name = r->in.system_name;
4130 c.in.access_mask = r->in.access_mask;
4131 c.out.connect_handle = r->out.connect_handle;
4133 return _samr_Connect2(p, &c);
4136 /*******************************************************************
4138 ********************************************************************/
4140 NTSTATUS _samr_Connect4(struct pipes_struct *p,
4141 struct samr_Connect4 *r)
4143 struct samr_Connect2 c;
4145 c.in.system_name = r->in.system_name;
4146 c.in.access_mask = r->in.access_mask;
4147 c.out.connect_handle = r->out.connect_handle;
4149 return _samr_Connect2(p, &c);
4152 /*******************************************************************
4154 ********************************************************************/
4156 NTSTATUS _samr_Connect5(struct pipes_struct *p,
4157 struct samr_Connect5 *r)
4160 struct samr_Connect2 c;
4161 struct samr_ConnectInfo1 info1;
4163 info1.client_version = SAMR_CONNECT_AFTER_W2K;
4166 c.in.system_name = r->in.system_name;
4167 c.in.access_mask = r->in.access_mask;
4168 c.out.connect_handle = r->out.connect_handle;
4170 *r->out.level_out = 1;
4172 status = _samr_Connect2(p, &c);
4173 if (!NT_STATUS_IS_OK(status)) {
4177 r->out.info_out->info1 = info1;
4179 return NT_STATUS_OK;
4182 /**********************************************************************
4184 **********************************************************************/
4186 NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
4187 struct samr_LookupDomain *r)
4190 const char *domain_name;
4191 struct dom_sid *sid = NULL;
4192 struct dom_sid_buf buf;
4194 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4195 Reverted that change so we will work with RAS servers again */
4197 (void)samr_policy_handle_find(p,
4198 r->in.connect_handle,
4199 SAMR_HANDLE_CONNECT,
4200 SAMR_ACCESS_LOOKUP_DOMAIN,
4203 if (!NT_STATUS_IS_OK(status)) {
4207 domain_name = r->in.domain_name->string;
4209 return NT_STATUS_INVALID_PARAMETER;
4212 sid = talloc_zero(p->mem_ctx, struct dom_sid2);
4214 return NT_STATUS_NO_MEMORY;
4217 if (strequal(domain_name, builtin_domain_name())) {
4218 sid_copy(sid, &global_sid_Builtin);
4220 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4221 status = NT_STATUS_NO_SUCH_DOMAIN;
4225 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4226 dom_sid_str_buf(sid, &buf)));
4233 /**********************************************************************
4235 **********************************************************************/
4237 NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4238 struct samr_EnumDomains *r)
4241 uint32_t num_entries = 2;
4242 struct samr_SamEntry *entry_array = NULL;
4243 struct samr_SamArray *sam;
4245 (void)samr_policy_handle_find(p,
4246 r->in.connect_handle,
4247 SAMR_HANDLE_CONNECT,
4248 SAMR_ACCESS_ENUM_DOMAINS,
4251 if (!NT_STATUS_IS_OK(status)) {
4255 sam = talloc_zero(p->mem_ctx, struct samr_SamArray);
4257 return NT_STATUS_NO_MEMORY;
4260 entry_array = talloc_zero_array(p->mem_ctx,
4261 struct samr_SamEntry,
4264 return NT_STATUS_NO_MEMORY;
4267 entry_array[0].idx = 0;
4268 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4270 entry_array[1].idx = 1;
4271 init_lsa_String(&entry_array[1].name, "Builtin");
4273 sam->count = num_entries;
4274 sam->entries = entry_array;
4277 *r->out.num_entries = num_entries;
4282 /*******************************************************************
4284 ********************************************************************/
4286 NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4287 struct samr_OpenAlias *r)
4290 uint32_t alias_rid = r->in.rid;
4291 struct samr_info *dinfo;
4292 struct security_descriptor *psd = NULL;
4293 uint32_t acc_granted;
4294 uint32_t des_access = r->in.access_mask;
4298 dinfo = samr_policy_handle_find(p,
4299 r->in.domain_handle,
4301 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
4304 if (!NT_STATUS_IS_OK(status)) {
4308 /* append the alias' RID to it */
4310 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4311 return NT_STATUS_NO_SUCH_ALIAS;
4313 /*check if access can be granted as requested by client. */
4315 map_max_allowed_access(p->session_info->security_token,
4316 p->session_info->unix_token,
4319 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4320 se_map_generic(&des_access,&ali_generic_mapping);
4322 status = access_check_object(psd, p->session_info->security_token,
4323 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
4324 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4325 des_access, &acc_granted, "_samr_OpenAlias");
4327 if ( !NT_STATUS_IS_OK(status) )
4331 /* Check we actually have the requested alias */
4332 enum lsa_SidType type;
4337 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4340 if (!result || (type != SID_NAME_ALIAS)) {
4341 return NT_STATUS_NO_SUCH_ALIAS;
4344 /* make sure there is a mapping */
4346 if ( !sid_to_gid( &sid, &gid ) ) {
4347 return NT_STATUS_NO_SUCH_ALIAS;
4352 status = create_samr_policy_handle(p->mem_ctx,
4358 r->out.alias_handle);
4359 if (!NT_STATUS_IS_OK(status)) {
4363 return NT_STATUS_OK;
4366 /*******************************************************************
4368 ********************************************************************/
4370 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4371 struct samr_UserInfo2 *id2,
4375 DEBUG(5,("set_user_info_2: NULL id2\n"));
4376 return NT_STATUS_ACCESS_DENIED;
4379 copy_id2_to_sam_passwd(pwd, id2);
4381 return pdb_update_sam_account(pwd);
4384 /*******************************************************************
4386 ********************************************************************/
4388 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4389 struct samr_UserInfo4 *id4,
4393 DEBUG(5,("set_user_info_2: NULL id4\n"));
4394 return NT_STATUS_ACCESS_DENIED;
4397 copy_id4_to_sam_passwd(pwd, id4);
4399 return pdb_update_sam_account(pwd);
4402 /*******************************************************************
4404 ********************************************************************/
4406 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4407 struct samr_UserInfo6 *id6,
4411 DEBUG(5,("set_user_info_6: NULL id6\n"));
4412 return NT_STATUS_ACCESS_DENIED;
4415 copy_id6_to_sam_passwd(pwd, id6);
4417 return pdb_update_sam_account(pwd);
4420 /*******************************************************************
4422 ********************************************************************/
4424 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4425 struct samr_UserInfo7 *id7,
4431 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4432 return NT_STATUS_ACCESS_DENIED;
4435 if (!id7->account_name.string) {
4436 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4437 return NT_STATUS_ACCESS_DENIED;
4440 /* check to see if the new username already exists. Note: we can't
4441 reliably lock all backends, so there is potentially the
4442 possibility that a user can be created in between this check and
4443 the rename. The rename should fail, but may not get the
4444 exact same failure status code. I think this is small enough
4445 of a window for this type of operation and the results are
4446 simply that the rename fails with a slightly different status
4447 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4449 rc = can_create(mem_ctx, id7->account_name.string);
4451 /* when there is nothing to change, we're done here */
4452 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4453 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4454 return NT_STATUS_OK;
4456 if (!NT_STATUS_IS_OK(rc)) {
4460 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4465 /*******************************************************************
4467 ********************************************************************/
4469 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4470 struct samr_UserInfo8 *id8,
4474 DEBUG(5,("set_user_info_8: NULL id8\n"));
4475 return NT_STATUS_ACCESS_DENIED;
4478 copy_id8_to_sam_passwd(pwd, id8);
4480 return pdb_update_sam_account(pwd);
4483 /*******************************************************************
4485 ********************************************************************/
4487 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4488 struct samr_UserInfo10 *id10,
4492 DEBUG(5,("set_user_info_8: NULL id10\n"));
4493 return NT_STATUS_ACCESS_DENIED;
4496 copy_id10_to_sam_passwd(pwd, id10);
4498 return pdb_update_sam_account(pwd);
4501 /*******************************************************************
4503 ********************************************************************/
4505 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4506 struct samr_UserInfo11 *id11,
4510 DEBUG(5,("set_user_info_11: NULL id11\n"));
4511 return NT_STATUS_ACCESS_DENIED;
4514 copy_id11_to_sam_passwd(pwd, id11);
4516 return pdb_update_sam_account(pwd);
4519 /*******************************************************************
4521 ********************************************************************/
4523 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4524 struct samr_UserInfo12 *id12,
4528 DEBUG(5,("set_user_info_12: NULL id12\n"));
4529 return NT_STATUS_ACCESS_DENIED;
4532 copy_id12_to_sam_passwd(pwd, id12);
4534 return pdb_update_sam_account(pwd);
4537 /*******************************************************************
4539 ********************************************************************/
4541 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4542 struct samr_UserInfo13 *id13,
4546 DEBUG(5,("set_user_info_13: NULL id13\n"));
4547 return NT_STATUS_ACCESS_DENIED;
4550 copy_id13_to_sam_passwd(pwd, id13);
4552 return pdb_update_sam_account(pwd);
4555 /*******************************************************************
4557 ********************************************************************/
4559 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4560 struct samr_UserInfo14 *id14,
4564 DEBUG(5,("set_user_info_14: NULL id14\n"));
4565 return NT_STATUS_ACCESS_DENIED;
4568 copy_id14_to_sam_passwd(pwd, id14);
4570 return pdb_update_sam_account(pwd);
4573 /*******************************************************************
4575 ********************************************************************/
4577 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4578 struct samr_UserInfo16 *id16,
4582 DEBUG(5,("set_user_info_16: NULL id16\n"));
4583 return NT_STATUS_ACCESS_DENIED;
4586 copy_id16_to_sam_passwd(pwd, id16);
4588 return pdb_update_sam_account(pwd);
4591 /*******************************************************************
4593 ********************************************************************/
4595 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4596 struct samr_UserInfo17 *id17,
4600 DEBUG(5,("set_user_info_17: NULL id17\n"));
4601 return NT_STATUS_ACCESS_DENIED;
4604 copy_id17_to_sam_passwd(pwd, id17);
4606 return pdb_update_sam_account(pwd);
4609 /*******************************************************************
4611 ********************************************************************/
4613 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4614 TALLOC_CTX *mem_ctx,
4615 DATA_BLOB *session_key,
4621 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4622 return NT_STATUS_INVALID_PARAMETER;
4625 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4626 if (!session_key->length) {
4627 return NT_STATUS_NO_USER_SESSION_KEY;
4631 if (id18->nt_pwd_active) {
4632 DATA_BLOB in = data_blob_const(id18->nt_pwd.hash, 16);
4633 uint8_t outbuf[16] = { 0, };
4634 DATA_BLOB out = data_blob_const(outbuf, sizeof(outbuf));
4636 rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
4638 return gnutls_error_to_ntstatus(rc,
4639 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
4642 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4643 return NT_STATUS_ACCESS_DENIED;
4646 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4649 if (id18->lm_pwd_active) {
4650 DATA_BLOB in = data_blob_const(id18->lm_pwd.hash, 16);
4651 uint8_t outbuf[16] = { 0, };
4652 DATA_BLOB out = data_blob_const(outbuf, sizeof(outbuf));
4654 rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
4656 return gnutls_error_to_ntstatus(rc,
4657 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
4660 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4661 return NT_STATUS_ACCESS_DENIED;
4664 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4667 copy_id18_to_sam_passwd(pwd, id18);
4669 return pdb_update_sam_account(pwd);
4672 /*******************************************************************
4674 ********************************************************************/
4676 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4677 struct samr_UserInfo20 *id20,
4681 DEBUG(5,("set_user_info_20: NULL id20\n"));
4682 return NT_STATUS_ACCESS_DENIED;
4685 copy_id20_to_sam_passwd(pwd, id20);
4687 return pdb_update_sam_account(pwd);
4690 /*******************************************************************
4692 ********************************************************************/
4694 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4695 TALLOC_CTX *mem_ctx,
4696 DATA_BLOB *session_key,
4703 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4704 return NT_STATUS_INVALID_PARAMETER;
4707 if (id21->fields_present == 0) {
4708 return NT_STATUS_INVALID_PARAMETER;
4711 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4712 return NT_STATUS_ACCESS_DENIED;
4715 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4716 if (id21->nt_password_set) {
4717 DATA_BLOB in = data_blob_const(
4718 id21->nt_owf_password.array, 16);
4719 uint8_t outbuf[16] = { 0, };
4720 DATA_BLOB out = data_blob_const(
4721 outbuf, sizeof(outbuf));
4723 if ((id21->nt_owf_password.length != 16) ||
4724 (id21->nt_owf_password.size != 16)) {
4725 return NT_STATUS_INVALID_PARAMETER;
4728 if (!session_key->length) {
4729 return NT_STATUS_NO_USER_SESSION_KEY;
4732 rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
4734 return gnutls_error_to_ntstatus(rc,
4735 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
4738 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4739 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4743 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4744 if (id21->lm_password_set) {
4745 DATA_BLOB in = data_blob_const(
4746 id21->lm_owf_password.array, 16);
4747 uint8_t outbuf[16] = { 0, };
4748 DATA_BLOB out = data_blob_const(
4749 outbuf, sizeof(outbuf));
4751 if ((id21->lm_owf_password.length != 16) ||
4752 (id21->lm_owf_password.size != 16)) {
4753 return NT_STATUS_INVALID_PARAMETER;
4756 if (!session_key->length) {
4757 return NT_STATUS_NO_USER_SESSION_KEY;
4760 rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
4762 return gnutls_error_to_ntstatus(rc,
4763 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
4766 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4767 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4771 /* we need to separately check for an account rename first */
4773 if (id21->account_name.string &&
4774 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4777 /* check to see if the new username already exists. Note: we can't
4778 reliably lock all backends, so there is potentially the
4779 possibility that a user can be created in between this check and
4780 the rename. The rename should fail, but may not get the
4781 exact same failure status code. I think this is small enough
4782 of a window for this type of operation and the results are
4783 simply that the rename fails with a slightly different status
4784 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4786 status = can_create(mem_ctx, id21->account_name.string);
4787 if (!NT_STATUS_IS_OK(status)) {
4791 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4793 if (!NT_STATUS_IS_OK(status)) {
4794 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4795 nt_errstr(status)));
4799 /* set the new username so that later
4800 functions can work on the new account */
4801 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4804 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4807 * The funny part about the previous two calls is
4808 * that pwd still has the password hashes from the
4809 * passdb entry. These have not been updated from
4810 * id21. I don't know if they need to be set. --jerry
4813 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4814 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4815 if ( !NT_STATUS_IS_OK(status) ) {
4820 /* Don't worry about writing out the user account since the
4821 primary group SID is generated solely from the user's Unix
4824 /* write the change out */
4825 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4829 return NT_STATUS_OK;
4832 /*******************************************************************
4834 ********************************************************************/
4836 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4837 struct samr_UserInfo23 *id23,
4841 char *plaintext_buf = NULL;
4847 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4848 return NT_STATUS_INVALID_PARAMETER;
4851 if (id23->info.fields_present == 0) {
4852 return NT_STATUS_INVALID_PARAMETER;
4855 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4856 return NT_STATUS_ACCESS_DENIED;
4859 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4860 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4862 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4863 pdb_get_username(pwd)));
4865 if (!decode_pw_buffer(mem_ctx,
4866 id23->password.data,
4870 return NT_STATUS_WRONG_PASSWORD;
4873 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4874 return NT_STATUS_ACCESS_DENIED;
4878 copy_id23_to_sam_passwd(pwd, id23);
4880 acct_ctrl = pdb_get_acct_ctrl(pwd);
4882 /* if it's a trust account, don't update /etc/passwd */
4883 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4884 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4885 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4886 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4887 } else if (plaintext_buf) {
4888 /* update the UNIX password */
4889 if (lp_unix_password_sync() ) {
4890 struct passwd *passwd;
4891 if (pdb_get_username(pwd) == NULL) {
4892 DEBUG(1, ("chgpasswd: User without name???\n"));
4893 return NT_STATUS_ACCESS_DENIED;
4896 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4897 if (passwd == NULL) {
4898 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4901 if(!chgpasswd(pdb_get_username(pwd), rhost,
4902 passwd, "", plaintext_buf, True)) {
4903 return NT_STATUS_ACCESS_DENIED;
4905 TALLOC_FREE(passwd);
4909 if (plaintext_buf) {
4910 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4913 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4914 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4919 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4923 return NT_STATUS_OK;
4926 /*******************************************************************
4928 ********************************************************************/
4930 static bool set_user_info_pw(uint8_t *pass, const char *rhost, struct samu *pwd)
4933 char *plaintext_buf = NULL;
4936 DEBUG(5, ("Attempting administrator password change for user %s\n",
4937 pdb_get_username(pwd)));
4939 acct_ctrl = pdb_get_acct_ctrl(pwd);
4941 if (!decode_pw_buffer(talloc_tos(),
4949 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4953 /* if it's a trust account, don't update /etc/passwd */
4954 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4955 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4956 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4957 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4959 /* update the UNIX password */
4960 if (lp_unix_password_sync()) {
4961 struct passwd *passwd;
4963 if (pdb_get_username(pwd) == NULL) {
4964 DEBUG(1, ("chgpasswd: User without name???\n"));
4968 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4969 if (passwd == NULL) {
4970 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4973 if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
4974 "", plaintext_buf, True)) {
4977 TALLOC_FREE(passwd);
4981 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4983 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4988 /*******************************************************************
4990 ********************************************************************/
4992 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4994 struct samr_UserInfo24 *id24,
5000 DEBUG(5, ("set_user_info_24: NULL id24\n"));
5001 return NT_STATUS_INVALID_PARAMETER;
5004 if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
5005 return NT_STATUS_WRONG_PASSWORD;
5008 copy_id24_to_sam_passwd(pwd, id24);
5010 status = pdb_update_sam_account(pwd);
5011 if (!NT_STATUS_IS_OK(status)) {
5015 return NT_STATUS_OK;
5018 /*******************************************************************
5020 ********************************************************************/
5022 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
5024 struct samr_UserInfo25 *id25,
5030 DEBUG(5, ("set_user_info_25: NULL id25\n"));
5031 return NT_STATUS_INVALID_PARAMETER;
5034 if (id25->info.fields_present == 0) {
5035 return NT_STATUS_INVALID_PARAMETER;
5038 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
5039 return NT_STATUS_ACCESS_DENIED;
5042 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
5043 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
5045 if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
5046 return NT_STATUS_WRONG_PASSWORD;
5050 copy_id25_to_sam_passwd(pwd, id25);
5052 /* write the change out */
5053 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
5058 * We need to "pdb_update_sam_account" before the unix primary group
5059 * is set, because the idealx scripts would also change the
5060 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
5061 * the delete explicit / add explicit, which would then fail to find
5062 * the previous primaryGroupSid value.
5065 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
5066 status = pdb_set_unix_primary_group(mem_ctx, pwd);
5067 if ( !NT_STATUS_IS_OK(status) ) {
5072 return NT_STATUS_OK;
5075 /*******************************************************************
5077 ********************************************************************/
5079 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
5081 struct samr_UserInfo26 *id26,
5087 DEBUG(5, ("set_user_info_26: NULL id26\n"));
5088 return NT_STATUS_INVALID_PARAMETER;
5091 if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
5092 return NT_STATUS_WRONG_PASSWORD;
5095 copy_id26_to_sam_passwd(pwd, id26);
5097 status = pdb_update_sam_account(pwd);
5098 if (!NT_STATUS_IS_OK(status)) {
5102 return NT_STATUS_OK;
5105 /*************************************************************
5106 **************************************************************/
5108 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
5110 uint32_t acc_required = 0;
5112 /* USER_ALL_USERNAME */
5113 if (fields & SAMR_FIELD_ACCOUNT_NAME)
5114 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5115 /* USER_ALL_FULLNAME */
5116 if (fields & SAMR_FIELD_FULL_NAME)
5117 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5118 /* USER_ALL_PRIMARYGROUPID */
5119 if (fields & SAMR_FIELD_PRIMARY_GID)
5120 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5121 /* USER_ALL_HOMEDIRECTORY */
5122 if (fields & SAMR_FIELD_HOME_DIRECTORY)
5123 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5124 /* USER_ALL_HOMEDIRECTORYDRIVE */
5125 if (fields & SAMR_FIELD_HOME_DRIVE)
5126 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5127 /* USER_ALL_SCRIPTPATH */
5128 if (fields & SAMR_FIELD_LOGON_SCRIPT)
5129 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5130 /* USER_ALL_PROFILEPATH */
5131 if (fields & SAMR_FIELD_PROFILE_PATH)
5132 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5133 /* USER_ALL_ADMINCOMMENT */
5134 if (fields & SAMR_FIELD_COMMENT)
5135 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5136 /* USER_ALL_WORKSTATIONS */
5137 if (fields & SAMR_FIELD_WORKSTATIONS)
5138 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5139 /* USER_ALL_LOGONHOURS */
5140 if (fields & SAMR_FIELD_LOGON_HOURS)
5141 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5142 /* USER_ALL_ACCOUNTEXPIRES */
5143 if (fields & SAMR_FIELD_ACCT_EXPIRY)
5144 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5145 /* USER_ALL_USERACCOUNTCONTROL */
5146 if (fields & SAMR_FIELD_ACCT_FLAGS)
5147 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5148 /* USER_ALL_PARAMETERS */
5149 if (fields & SAMR_FIELD_PARAMETERS)
5150 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5151 /* USER_ALL_USERCOMMENT */
5152 if (fields & SAMR_FIELD_COMMENT)
5153 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5154 /* USER_ALL_COUNTRYCODE */
5155 if (fields & SAMR_FIELD_COUNTRY_CODE)
5156 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5157 /* USER_ALL_CODEPAGE */
5158 if (fields & SAMR_FIELD_CODE_PAGE)
5159 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5160 /* USER_ALL_NTPASSWORDPRESENT */
5161 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
5162 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5163 /* USER_ALL_LMPASSWORDPRESENT */
5164 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
5165 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5166 /* USER_ALL_PASSWORDEXPIRED */
5167 if (fields & SAMR_FIELD_EXPIRED_FLAG)
5168 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5170 return acc_required;
5173 static NTSTATUS arc4_decrypt_data(DATA_BLOB session_key,
5177 gnutls_cipher_hd_t cipher_hnd = NULL;
5178 gnutls_datum_t my_session_key = {
5179 .data = session_key.data,
5180 .size = session_key.length,
5182 NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
5185 rc = gnutls_cipher_init(&cipher_hnd,
5186 GNUTLS_CIPHER_ARCFOUR_128,
5190 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
5194 rc = gnutls_cipher_decrypt(cipher_hnd,
5197 gnutls_cipher_deinit(cipher_hnd);
5199 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
5203 status = NT_STATUS_OK;
5208 /*******************************************************************
5210 ********************************************************************/
5212 NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
5213 struct samr_SetUserInfo *r)
5215 struct samr_info *uinfo;
5217 struct samu *pwd = NULL;
5218 union samr_UserInfo *info = r->in.info;
5219 uint32_t acc_required = 0;
5220 uint32_t fields = 0;
5223 DATA_BLOB session_key;
5224 struct dom_sid_buf buf;
5225 struct loadparm_context *lp_ctx = NULL;
5228 lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
5229 if (lp_ctx == NULL) {
5230 return NT_STATUS_NO_MEMORY;
5233 /* This is tricky. A WinXP domain join sets
5234 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5235 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
5236 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5237 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
5238 we'll use the set from the WinXP join as the basis. */
5240 switch (r->in.level) {
5241 case 2: /* UserPreferencesInformation */
5242 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5243 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5245 case 4: /* UserLogonHoursInformation */
5246 case 6: /* UserNameInformation */
5247 case 7: /* UserAccountNameInformation */
5248 case 8: /* UserFullNameInformation */
5249 case 9: /* UserPrimaryGroupInformation */
5250 case 10: /* UserHomeInformation */
5251 case 11: /* UserScriptInformation */
5252 case 12: /* UserProfileInformation */
5253 case 13: /* UserAdminCommentInformation */
5254 case 14: /* UserWorkStationsInformation */
5255 case 16: /* UserControlInformation */
5256 case 17: /* UserExpiresInformation */
5257 case 20: /* UserParametersInformation */
5258 /* USER_WRITE_ACCOUNT */
5259 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5261 case 18: /* UserInternal1Information */
5262 /* FIXME: gd, this is a guess */
5263 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5265 case 21: /* UserAllInformation */
5266 fields = info->info21.fields_present;
5267 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5269 case 23: /* UserInternal4Information */
5270 fields = info->info23.info.fields_present;
5271 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5273 case 25: /* UserInternal4InformationNew */
5274 fields = info->info25.info.fields_present;
5275 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5277 case 24: /* UserInternal5Information */
5278 case 26: /* UserInternal5InformationNew */
5279 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5282 return NT_STATUS_INVALID_INFO_CLASS;
5285 uinfo = samr_policy_handle_find(p,
5291 if (!NT_STATUS_IS_OK(status)) {
5295 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5296 dom_sid_str_buf(&uinfo->sid, &buf),
5300 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5301 return NT_STATUS_INVALID_INFO_CLASS;
5304 if (!(pwd = samu_new(NULL))) {
5305 return NT_STATUS_NO_MEMORY;
5309 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5314 return NT_STATUS_NO_SUCH_USER;
5317 rhost = tsocket_address_inet_addr_string(p->remote_address,
5319 if (rhost == NULL) {
5320 return NT_STATUS_NO_MEMORY;
5323 /* ================ BEGIN Privilege BLOCK ================ */
5327 /* ok! user info levels (lots: see MSDEV help), off we go... */
5329 switch (r->in.level) {
5332 status = set_user_info_2(p->mem_ctx,
5337 status = set_user_info_4(p->mem_ctx,
5342 status = set_user_info_6(p->mem_ctx,
5347 status = set_user_info_7(p->mem_ctx,
5352 status = set_user_info_8(p->mem_ctx,
5357 status = set_user_info_10(p->mem_ctx,
5358 &info->info10, pwd);
5362 status = set_user_info_11(p->mem_ctx,
5363 &info->info11, pwd);
5367 status = set_user_info_12(p->mem_ctx,
5368 &info->info12, pwd);
5372 status = set_user_info_13(p->mem_ctx,
5373 &info->info13, pwd);
5377 status = set_user_info_14(p->mem_ctx,
5378 &info->info14, pwd);
5382 status = set_user_info_16(p->mem_ctx,
5383 &info->info16, pwd);
5387 status = set_user_info_17(p->mem_ctx,
5388 &info->info17, pwd);
5392 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5393 if(!NT_STATUS_IS_OK(status)) {
5396 /* Used by AS/U JRA. */
5397 status = set_user_info_18(&info->info18,
5404 status = set_user_info_20(p->mem_ctx,
5405 &info->info20, pwd);
5409 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5410 if(!NT_STATUS_IS_OK(status)) {
5413 status = set_user_info_21(&info->info21,
5421 dcerpc_is_transport_encrypted(p->session_info);
5422 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
5424 status = NT_STATUS_ACCESS_DENIED;
5428 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5429 if(!NT_STATUS_IS_OK(status)) {
5433 * This can be allowed as it requires a session key
5434 * which we only have if we have a SMB session.
5436 GNUTLS_FIPS140_SET_LAX_MODE();
5437 status = arc4_decrypt_data(session_key,
5438 info->info23.password.data,
5440 GNUTLS_FIPS140_SET_STRICT_MODE();
5441 if(!NT_STATUS_IS_OK(status)) {
5445 #ifdef DEBUG_PASSWORD
5446 dump_data(100, info->info23.password.data, 516);
5449 status = set_user_info_23(p->mem_ctx,
5457 dcerpc_is_transport_encrypted(p->session_info);
5458 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
5460 status = NT_STATUS_ACCESS_DENIED;
5464 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5465 if(!NT_STATUS_IS_OK(status)) {
5469 * This can be allowed as it requires a session key
5470 * which we only have if we have a SMB session.
5472 GNUTLS_FIPS140_SET_LAX_MODE();
5473 status = arc4_decrypt_data(session_key,
5474 info->info24.password.data,
5476 GNUTLS_FIPS140_SET_STRICT_MODE();
5477 if(!NT_STATUS_IS_OK(status)) {
5481 #ifdef DEBUG_PASSWORD
5482 dump_data(100, info->info24.password.data, 516);
5485 status = set_user_info_24(p->mem_ctx,
5487 &info->info24, pwd);
5492 dcerpc_is_transport_encrypted(p->session_info);
5493 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
5495 status = NT_STATUS_ACCESS_DENIED;
5499 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5500 if(!NT_STATUS_IS_OK(status)) {
5504 * This can be allowed as it requires a session key
5505 * which we only have if we have a SMB session.
5507 GNUTLS_FIPS140_SET_LAX_MODE();
5508 status = decode_rc4_passwd_buffer(&session_key,
5509 &info->info25.password);
5510 GNUTLS_FIPS140_SET_STRICT_MODE();
5511 if (!NT_STATUS_IS_OK(status)) {
5515 #ifdef DEBUG_PASSWORD
5516 dump_data(100, info->info25.password.data, 532);
5519 status = set_user_info_25(p->mem_ctx,
5521 &info->info25, pwd);
5526 dcerpc_is_transport_encrypted(p->session_info);
5527 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
5529 status = NT_STATUS_ACCESS_DENIED;
5533 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5534 if(!NT_STATUS_IS_OK(status)) {
5538 * This can be allowed as it requires a session key
5539 * which we only have if we have a SMB session.
5541 GNUTLS_FIPS140_SET_LAX_MODE();
5542 status = decode_rc4_passwd_buffer(&session_key,
5543 &info->info26.password);
5544 GNUTLS_FIPS140_SET_STRICT_MODE();
5545 if (!NT_STATUS_IS_OK(status)) {
5549 #ifdef DEBUG_PASSWORD
5550 dump_data(100, info->info26.password.data, 516);
5553 status = set_user_info_26(p->mem_ctx,
5555 &info->info26, pwd);
5559 status = NT_STATUS_INVALID_INFO_CLASS;
5566 /* ================ END Privilege BLOCK ================ */
5568 if (NT_STATUS_IS_OK(status)) {
5569 force_flush_samr_cache(&uinfo->sid);
5575 /*******************************************************************
5577 ********************************************************************/
5579 NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
5580 struct samr_SetUserInfo2 *r)
5582 struct samr_SetUserInfo q;
5584 q.in.user_handle = r->in.user_handle;
5585 q.in.level = r->in.level;
5586 q.in.info = r->in.info;
5588 return _samr_SetUserInfo(p, &q);
5591 /*********************************************************************
5592 _samr_GetAliasMembership
5593 *********************************************************************/
5595 NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
5596 struct samr_GetAliasMembership *r)
5598 size_t num_alias_rids;
5599 uint32_t *alias_rids;
5600 struct samr_info *dinfo;
5605 struct dom_sid *members;
5607 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5609 dinfo = samr_policy_handle_find(p,
5610 r->in.domain_handle,
5612 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5613 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
5616 if (!NT_STATUS_IS_OK(status)) {
5620 if (!sid_check_is_our_sam(&dinfo->sid) &&
5621 !sid_check_is_builtin(&dinfo->sid))
5622 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5624 if (r->in.sids->num_sids) {
5625 members = talloc_array(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
5627 if (members == NULL)
5628 return NT_STATUS_NO_MEMORY;
5633 for (i=0; i<r->in.sids->num_sids; i++)
5634 sid_copy(&members[i], r->in.sids->sids[i].sid);
5640 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5641 r->in.sids->num_sids,
5642 &alias_rids, &num_alias_rids);
5645 if (!NT_STATUS_IS_OK(status)) {
5649 r->out.rids->count = num_alias_rids;
5650 r->out.rids->ids = alias_rids;
5652 if (r->out.rids->ids == NULL) {
5653 /* Windows domain clients don't accept a NULL ptr here */
5654 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5656 if (r->out.rids->ids == NULL) {
5657 return NT_STATUS_NO_MEMORY;
5660 return NT_STATUS_OK;
5663 /*********************************************************************
5664 _samr_GetMembersInAlias
5665 *********************************************************************/
5667 NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
5668 struct samr_GetMembersInAlias *r)
5670 struct samr_info *ainfo;
5673 size_t num_sids = 0;
5674 struct lsa_SidPtr *sids = NULL;
5675 struct dom_sid *pdb_sids = NULL;
5676 struct dom_sid_buf buf;
5678 ainfo = samr_policy_handle_find(p,
5681 SAMR_ALIAS_ACCESS_GET_MEMBERS,
5684 if (!NT_STATUS_IS_OK(status)) {
5688 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
5691 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5695 if (!NT_STATUS_IS_OK(status)) {
5700 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr, num_sids);
5702 TALLOC_FREE(pdb_sids);
5703 return NT_STATUS_NO_MEMORY;
5707 for (i = 0; i < num_sids; i++) {
5708 sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
5710 TALLOC_FREE(pdb_sids);
5711 return NT_STATUS_NO_MEMORY;
5715 r->out.sids->num_sids = num_sids;
5716 r->out.sids->sids = sids;
5718 TALLOC_FREE(pdb_sids);
5720 return NT_STATUS_OK;
5723 /*********************************************************************
5724 _samr_QueryGroupMember
5725 *********************************************************************/
5727 NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
5728 struct samr_QueryGroupMember *r)
5730 struct samr_info *ginfo;
5731 size_t i, num_members;
5734 uint32_t *attr=NULL;
5737 struct samr_RidAttrArray *rids = NULL;
5738 struct dom_sid_buf buf;
5740 ginfo = samr_policy_handle_find(p,
5743 SAMR_GROUP_ACCESS_GET_MEMBERS,
5746 if (!NT_STATUS_IS_OK(status)) {
5750 rids = talloc_zero(p->mem_ctx, struct samr_RidAttrArray);
5752 return NT_STATUS_NO_MEMORY;
5755 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
5757 if (!sid_check_is_in_our_sam(&ginfo->sid)) {
5758 DEBUG(3, ("sid %s is not in our domain\n",
5759 dom_sid_str_buf(&ginfo->sid, &buf)));
5760 return NT_STATUS_NO_SUCH_GROUP;
5763 DEBUG(10, ("lookup on Domain SID\n"));
5766 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5767 &rid, &num_members);
5770 if (!NT_STATUS_IS_OK(status))
5774 attr=talloc_zero_array(p->mem_ctx, uint32_t, num_members);
5776 return NT_STATUS_NO_MEMORY;
5782 for (i=0; i<num_members; i++) {
5783 attr[i] = SE_GROUP_MANDATORY |
5784 SE_GROUP_ENABLED_BY_DEFAULT |
5788 rids->count = num_members;
5789 rids->attributes = attr;
5792 *r->out.rids = rids;
5794 return NT_STATUS_OK;
5797 /*********************************************************************
5798 _samr_AddAliasMember
5799 *********************************************************************/
5801 NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
5802 struct samr_AddAliasMember *r)
5804 struct samr_info *ainfo;
5805 struct dom_sid_buf buf;
5808 ainfo = samr_policy_handle_find(p,
5811 SAMR_ALIAS_ACCESS_ADD_MEMBER,
5814 if (!NT_STATUS_IS_OK(status)) {
5818 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
5820 /******** BEGIN SeAddUsers BLOCK *********/
5823 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5826 /******** END SeAddUsers BLOCK *********/
5828 if (NT_STATUS_IS_OK(status)) {
5829 force_flush_samr_cache(&ainfo->sid);
5835 /*********************************************************************
5836 _samr_DeleteAliasMember
5837 *********************************************************************/
5839 NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
5840 struct samr_DeleteAliasMember *r)
5842 struct samr_info *ainfo;
5843 struct dom_sid_buf buf;
5846 ainfo = samr_policy_handle_find(p,
5849 SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
5852 if (!NT_STATUS_IS_OK(status)) {
5856 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5857 dom_sid_str_buf(&ainfo->sid, &buf)));
5859 /******** BEGIN SeAddUsers BLOCK *********/
5862 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5865 /******** END SeAddUsers BLOCK *********/
5867 if (NT_STATUS_IS_OK(status)) {
5868 force_flush_samr_cache(&ainfo->sid);
5874 /*********************************************************************
5875 _samr_AddGroupMember
5876 *********************************************************************/
5878 NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
5879 struct samr_AddGroupMember *r)
5881 struct samr_info *ginfo;
5882 struct dom_sid_buf buf;
5886 ginfo = samr_policy_handle_find(p,
5889 SAMR_GROUP_ACCESS_ADD_MEMBER,
5892 if (!NT_STATUS_IS_OK(status)) {
5896 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
5898 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5900 return NT_STATUS_INVALID_HANDLE;
5903 /******** BEGIN SeAddUsers BLOCK *********/
5906 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5909 /******** END SeAddUsers BLOCK *********/
5911 force_flush_samr_cache(&ginfo->sid);
5916 /*********************************************************************
5917 _samr_DeleteGroupMember
5918 *********************************************************************/
5920 NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
5921 struct samr_DeleteGroupMember *r)
5924 struct samr_info *ginfo;
5929 * delete the group member named r->in.rid
5930 * who is a member of the sid associated with the handle
5931 * the rid is a user's rid as the group is a domain group.
5934 ginfo = samr_policy_handle_find(p,
5937 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
5940 if (!NT_STATUS_IS_OK(status)) {
5944 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5946 return NT_STATUS_INVALID_HANDLE;
5949 /******** BEGIN SeAddUsers BLOCK *********/
5952 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5955 /******** END SeAddUsers BLOCK *********/
5957 force_flush_samr_cache(&ginfo->sid);
5962 /*********************************************************************
5964 *********************************************************************/
5966 NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
5967 struct samr_DeleteUser *r)
5969 struct samr_info *uinfo;
5971 struct samu *sam_pass=NULL;
5974 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5976 uinfo = samr_policy_handle_find(p,
5982 if (!NT_STATUS_IS_OK(status)) {
5986 if (!sid_check_is_in_our_sam(&uinfo->sid))
5987 return NT_STATUS_CANNOT_DELETE;
5989 /* check if the user exists before trying to delete */
5990 if ( !(sam_pass = samu_new( NULL )) ) {
5991 return NT_STATUS_NO_MEMORY;
5995 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5999 struct dom_sid_buf buf;
6000 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
6001 dom_sid_str_buf(&uinfo->sid, &buf)));
6002 TALLOC_FREE(sam_pass);
6003 return NT_STATUS_NO_SUCH_USER;
6006 /******** BEGIN SeAddUsers BLOCK *********/
6009 status = pdb_delete_user(p->mem_ctx, sam_pass);
6012 /******** END SeAddUsers BLOCK *********/
6014 if ( !NT_STATUS_IS_OK(status) ) {
6015 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
6016 "user %s: %s.\n", pdb_get_username(sam_pass),
6017 nt_errstr(status)));
6018 TALLOC_FREE(sam_pass);
6023 TALLOC_FREE(sam_pass);
6025 force_flush_samr_cache(&uinfo->sid);
6027 if (!close_policy_hnd(p, r->in.user_handle))
6028 return NT_STATUS_OBJECT_NAME_INVALID;
6030 ZERO_STRUCTP(r->out.user_handle);
6032 return NT_STATUS_OK;
6035 /*********************************************************************
6036 _samr_DeleteDomainGroup
6037 *********************************************************************/
6039 NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
6040 struct samr_DeleteDomainGroup *r)
6042 struct samr_info *ginfo;
6043 struct dom_sid_buf buf;
6047 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
6049 ginfo = samr_policy_handle_find(p,
6055 if (!NT_STATUS_IS_OK(status)) {
6059 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
6061 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
6063 return NT_STATUS_NO_SUCH_GROUP;
6066 /******** BEGIN SeAddUsers BLOCK *********/
6069 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
6072 /******** END SeAddUsers BLOCK *********/
6074 if ( !NT_STATUS_IS_OK(status) ) {
6075 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
6076 "entry for group %s: %s\n",
6077 dom_sid_str_buf(&ginfo->sid, &buf),
6078 nt_errstr(status)));
6082 force_flush_samr_cache(&ginfo->sid);
6084 if (!close_policy_hnd(p, r->in.group_handle))
6085 return NT_STATUS_OBJECT_NAME_INVALID;
6087 return NT_STATUS_OK;
6090 /*********************************************************************
6091 _samr_DeleteDomAlias
6092 *********************************************************************/
6094 NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
6095 struct samr_DeleteDomAlias *r)
6097 struct samr_info *ainfo;
6098 struct dom_sid_buf buf;
6101 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
6103 ainfo = samr_policy_handle_find(p,
6109 if (!NT_STATUS_IS_OK(status)) {
6113 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
6115 /* Don't let Windows delete builtin groups */
6117 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6118 return NT_STATUS_SPECIAL_ACCOUNT;
6121 if (!sid_check_is_in_our_sam(&ainfo->sid))
6122 return NT_STATUS_NO_SUCH_ALIAS;
6124 DEBUG(10, ("lookup on Local SID\n"));
6126 /******** BEGIN SeAddUsers BLOCK *********/
6129 /* Have passdb delete the alias */
6130 status = pdb_delete_alias(&ainfo->sid);
6133 /******** END SeAddUsers BLOCK *********/
6135 if ( !NT_STATUS_IS_OK(status))
6138 force_flush_samr_cache(&ainfo->sid);
6140 if (!close_policy_hnd(p, r->in.alias_handle))
6141 return NT_STATUS_OBJECT_NAME_INVALID;
6143 return NT_STATUS_OK;
6146 /*********************************************************************
6147 _samr_CreateDomainGroup
6148 *********************************************************************/
6150 NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
6151 struct samr_CreateDomainGroup *r)
6156 struct samr_info *dinfo;
6159 dinfo = samr_policy_handle_find(p,
6160 r->in.domain_handle,
6162 SAMR_DOMAIN_ACCESS_CREATE_GROUP,
6165 if (!NT_STATUS_IS_OK(status)) {
6169 if (!sid_check_is_our_sam(&dinfo->sid)) {
6170 return NT_STATUS_ACCESS_DENIED;
6173 name = r->in.name->string;
6175 return NT_STATUS_NO_MEMORY;
6178 status = can_create(p->mem_ctx, name);
6179 if (!NT_STATUS_IS_OK(status)) {
6183 /******** BEGIN SeAddUsers BLOCK *********/
6186 /* check that we successfully create the UNIX group */
6187 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
6190 /******** END SeAddUsers BLOCK *********/
6192 /* check if we should bail out here */
6194 if ( !NT_STATUS_IS_OK(status) )
6197 sid_compose(&sid, &dinfo->sid, *r->out.rid);
6199 status = create_samr_policy_handle(p->mem_ctx,
6202 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6205 r->out.group_handle);
6206 if (!NT_STATUS_IS_OK(status)) {
6210 force_flush_samr_cache(&dinfo->sid);
6212 return NT_STATUS_OK;
6215 /*********************************************************************
6216 _samr_CreateDomAlias
6217 *********************************************************************/
6219 NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
6220 struct samr_CreateDomAlias *r)
6222 struct dom_sid info_sid;
6223 const char *name = NULL;
6224 struct samr_info *dinfo;
6228 dinfo = samr_policy_handle_find(p,
6229 r->in.domain_handle,
6231 SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
6234 if (!NT_STATUS_IS_OK(result)) {
6238 if (!sid_check_is_our_sam(&dinfo->sid)) {
6239 return NT_STATUS_ACCESS_DENIED;
6242 name = r->in.alias_name->string;
6244 result = can_create(p->mem_ctx, name);
6245 if (!NT_STATUS_IS_OK(result)) {
6249 /******** BEGIN SeAddUsers BLOCK *********/
6252 /* Have passdb create the alias */
6253 result = pdb_create_alias(name, r->out.rid);
6256 /******** END SeAddUsers BLOCK *********/
6258 if (!NT_STATUS_IS_OK(result)) {
6259 DEBUG(10, ("pdb_create_alias failed: %s\n",
6260 nt_errstr(result)));
6264 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
6266 if (!sid_to_gid(&info_sid, &gid)) {
6267 DEBUG(10, ("Could not find alias just created\n"));
6268 return NT_STATUS_ACCESS_DENIED;
6271 /* check if the group has been successfully created */
6272 if ( getgrgid(gid) == NULL ) {
6273 DEBUG(1, ("getgrgid(%u) of just created alias failed\n",
6274 (unsigned int)gid));
6275 return NT_STATUS_ACCESS_DENIED;
6278 result = create_samr_policy_handle(p->mem_ctx,
6281 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
6284 r->out.alias_handle);
6285 if (!NT_STATUS_IS_OK(result)) {
6289 force_flush_samr_cache(&info_sid);
6291 return NT_STATUS_OK;
6294 /*********************************************************************
6295 _samr_QueryGroupInfo
6296 *********************************************************************/
6298 NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
6299 struct samr_QueryGroupInfo *r)
6301 struct samr_info *ginfo;
6304 union samr_GroupInfo *info = NULL;
6306 uint32_t attributes = SE_GROUP_MANDATORY |
6307 SE_GROUP_ENABLED_BY_DEFAULT |
6309 const char *group_name = NULL;
6310 const char *group_description = NULL;
6312 ginfo = samr_policy_handle_find(p,
6315 SAMR_GROUP_ACCESS_LOOKUP_INFO,
6318 if (!NT_STATUS_IS_OK(status)) {
6322 map = talloc_zero(p->mem_ctx, GROUP_MAP);
6324 return NT_STATUS_NO_MEMORY;
6328 ret = get_domain_group_from_sid(ginfo->sid, map);
6331 return NT_STATUS_INVALID_HANDLE;
6333 group_name = talloc_move(r, &map->nt_name);
6334 group_description = talloc_move(r, &map->comment);
6338 info = talloc_zero(p->mem_ctx, union samr_GroupInfo);
6340 return NT_STATUS_NO_MEMORY;
6343 switch (r->in.level) {
6349 status = pdb_enum_group_members(
6350 p->mem_ctx, &ginfo->sid, &members,
6354 if (!NT_STATUS_IS_OK(status)) {
6358 info->all.name.string = group_name;
6359 info->all.attributes = attributes;
6360 info->all.num_members = num_members;
6361 info->all.description.string = group_description;
6365 info->name.string = group_name;
6368 info->attributes.attributes = attributes;
6371 info->description.string = group_description;
6381 status = pdb_enum_group_members(
6382 p->mem_ctx, &ginfo->sid, &members,
6386 if (!NT_STATUS_IS_OK(status)) {
6390 info->all2.name.string = group_name;
6391 info->all2.attributes = attributes;
6392 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
6393 info->all2.description.string = group_description;
6398 return NT_STATUS_INVALID_INFO_CLASS;
6401 *r->out.info = info;
6403 return NT_STATUS_OK;
6406 /*********************************************************************
6408 *********************************************************************/
6410 NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
6411 struct samr_SetGroupInfo *r)
6413 struct samr_info *ginfo;
6418 ginfo = samr_policy_handle_find(p,
6421 SAMR_GROUP_ACCESS_SET_INFO,
6424 if (!NT_STATUS_IS_OK(status)) {
6428 map = talloc_zero(p->mem_ctx, GROUP_MAP);
6430 return NT_STATUS_NO_MEMORY;
6434 ret = get_domain_group_from_sid(ginfo->sid, map);
6437 return NT_STATUS_NO_SUCH_GROUP;
6439 switch (r->in.level) {
6441 map->nt_name = talloc_strdup(map,
6442 r->in.info->name.string);
6443 if (!map->nt_name) {
6444 return NT_STATUS_NO_MEMORY;
6450 map->comment = talloc_strdup(map,
6451 r->in.info->description.string);
6452 if (!map->comment) {
6453 return NT_STATUS_NO_MEMORY;
6457 return NT_STATUS_INVALID_INFO_CLASS;
6460 /******** BEGIN SeAddUsers BLOCK *********/
6463 status = pdb_update_group_mapping_entry(map);
6466 /******** End SeAddUsers BLOCK *********/
6470 if (NT_STATUS_IS_OK(status)) {
6471 force_flush_samr_cache(&ginfo->sid);
6477 /*********************************************************************
6479 *********************************************************************/
6481 NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
6482 struct samr_SetAliasInfo *r)
6484 struct samr_info *ainfo;
6485 struct acct_info *info;
6488 ainfo = samr_policy_handle_find(p,
6491 SAMR_ALIAS_ACCESS_SET_INFO,
6494 if (!NT_STATUS_IS_OK(status)) {
6498 info = talloc_zero(p->mem_ctx, struct acct_info);
6500 return NT_STATUS_NO_MEMORY;
6503 /* get the current group information */
6506 status = pdb_get_aliasinfo(&ainfo->sid, info);
6509 if ( !NT_STATUS_IS_OK(status))
6512 switch (r->in.level) {
6517 /* We currently do not support renaming groups in the
6518 the BUILTIN domain. Refer to util_builtin.c to understand
6519 why. The eventually needs to be fixed to be like Windows
6520 where you can rename builtin groups, just not delete them */
6522 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6523 return NT_STATUS_SPECIAL_ACCOUNT;
6526 /* There has to be a valid name (and it has to be different) */
6528 if ( !r->in.info->name.string )
6529 return NT_STATUS_INVALID_PARAMETER;
6531 /* If the name is the same just reply "ok". Yes this
6532 doesn't allow you to change the case of a group name. */
6534 if (strequal(r->in.info->name.string, info->acct_name)) {
6535 return NT_STATUS_OK;
6538 talloc_free(info->acct_name);
6539 info->acct_name = talloc_strdup(info, r->in.info->name.string);
6540 if (!info->acct_name) {
6541 return NT_STATUS_NO_MEMORY;
6544 /* make sure the name doesn't already exist as a user
6547 group_name = talloc_asprintf(p->mem_ctx,
6551 if (group_name == NULL) {
6552 return NT_STATUS_NO_MEMORY;
6555 status = can_create( p->mem_ctx, group_name );
6556 talloc_free(group_name);
6557 if ( !NT_STATUS_IS_OK( status ) )
6561 case ALIASINFODESCRIPTION:
6562 TALLOC_FREE(info->acct_desc);
6563 if (r->in.info->description.string) {
6564 info->acct_desc = talloc_strdup(info,
6565 r->in.info->description.string);
6567 info->acct_desc = talloc_strdup(info, "");
6569 if (!info->acct_desc) {
6570 return NT_STATUS_NO_MEMORY;
6574 return NT_STATUS_INVALID_INFO_CLASS;
6577 /******** BEGIN SeAddUsers BLOCK *********/
6580 status = pdb_set_aliasinfo(&ainfo->sid, info);
6583 /******** End SeAddUsers BLOCK *********/
6585 if (NT_STATUS_IS_OK(status))
6586 force_flush_samr_cache(&ainfo->sid);
6591 /****************************************************************
6593 ****************************************************************/
6595 NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
6596 struct samr_GetDomPwInfo *r)
6598 const struct loadparm_substitution *lp_sub =
6599 loadparm_s3_global_substitution();
6600 uint32_t min_password_length = 0;
6601 uint32_t password_properties = 0;
6603 /* Perform access check. Since this rpc does not require a
6604 policy handle it will not be caught by the access checks on
6605 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6607 if (!pipe_access_check(p)) {
6608 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6609 return NT_STATUS_ACCESS_DENIED;
6613 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6614 &min_password_length);
6615 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6616 &password_properties);
6619 if (lp_check_password_script(talloc_tos(), lp_sub) && *lp_check_password_script(talloc_tos(), lp_sub)) {
6620 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6623 r->out.info->min_password_length = min_password_length;
6624 r->out.info->password_properties = password_properties;
6626 return NT_STATUS_OK;
6629 /*********************************************************************
6631 *********************************************************************/
6633 NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
6634 struct samr_OpenGroup *r)
6637 struct dom_sid info_sid;
6638 struct dom_sid_buf buf;
6640 struct samr_info *dinfo;
6641 struct security_descriptor *psd = NULL;
6642 uint32_t acc_granted;
6643 uint32_t des_access = r->in.access_mask;
6648 dinfo = samr_policy_handle_find(p,
6649 r->in.domain_handle,
6651 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
6654 if (!NT_STATUS_IS_OK(status)) {
6658 /*check if access can be granted as requested by client. */
6659 map_max_allowed_access(p->session_info->security_token,
6660 p->session_info->unix_token,
6663 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6664 se_map_generic(&des_access,&grp_generic_mapping);
6666 status = access_check_object(psd, p->session_info->security_token,
6667 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6668 des_access, &acc_granted, "_samr_OpenGroup");
6670 if ( !NT_STATUS_IS_OK(status) )
6673 /* this should not be hard-coded like this */
6675 if (!sid_check_is_our_sam(&dinfo->sid)) {
6676 return NT_STATUS_ACCESS_DENIED;
6679 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6681 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6682 dom_sid_str_buf(&info_sid, &buf)));
6684 map = talloc_zero(p->mem_ctx, GROUP_MAP);
6686 return NT_STATUS_NO_MEMORY;
6689 /* check if that group really exists */
6691 ret = get_domain_group_from_sid(info_sid, map);
6694 return NT_STATUS_NO_SUCH_GROUP;
6698 status = create_samr_policy_handle(p->mem_ctx,
6704 r->out.group_handle);
6705 if (!NT_STATUS_IS_OK(status)) {
6709 return NT_STATUS_OK;
6712 /*********************************************************************
6713 _samr_RemoveMemberFromForeignDomain
6714 *********************************************************************/
6716 NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
6717 struct samr_RemoveMemberFromForeignDomain *r)
6719 struct samr_info *dinfo;
6720 struct dom_sid_buf buf;
6723 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6724 dom_sid_str_buf(r->in.sid, &buf)));
6726 /* Find the policy handle. Open a policy on it. */
6728 dinfo = samr_policy_handle_find(p,
6729 r->in.domain_handle,
6731 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
6734 if (!NT_STATUS_IS_OK(result)) {
6738 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6739 dom_sid_str_buf(&dinfo->sid, &buf)));
6741 /* we can only delete a user from a group since we don't have
6742 nested groups anyways. So in the latter case, just say OK */
6744 /* TODO: The above comment nowadays is bogus. Since we have nested
6745 * groups now, and aliases members are never reported out of the unix
6746 * group membership, the "just say OK" makes this call a no-op. For
6747 * us. This needs fixing however. */
6749 /* I've only ever seen this in the wild when deleting a user from
6750 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6751 * is the user about to be deleted. I very much suspect this is the
6752 * only application of this call. To verify this, let people report
6755 if (!sid_check_is_builtin(&dinfo->sid)) {
6756 struct dom_sid_buf buf2;
6757 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6758 "global_sam_sid() = %s\n",
6759 dom_sid_str_buf(&dinfo->sid, &buf),
6760 dom_sid_str_buf(get_global_sam_sid(), &buf2)));
6761 DEBUGADD(1,("please report to samba-technical@lists.samba.org!\n"));
6762 return NT_STATUS_OK;
6765 force_flush_samr_cache(&dinfo->sid);
6767 result = NT_STATUS_OK;
6772 /*******************************************************************
6773 _samr_QueryDomainInfo2
6774 ********************************************************************/
6776 NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
6777 struct samr_QueryDomainInfo2 *r)
6779 struct samr_QueryDomainInfo q;
6781 q.in.domain_handle = r->in.domain_handle;
6782 q.in.level = r->in.level;
6784 q.out.info = r->out.info;
6786 return _samr_QueryDomainInfo(p, &q);
6789 /*******************************************************************
6790 ********************************************************************/
6792 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6793 struct samr_DomInfo1 *r)
6795 time_t u_expire, u_min_age;
6797 u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6798 u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6800 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6801 (uint32_t)r->min_password_length);
6802 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6803 (uint32_t)r->password_history_length);
6804 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6805 (uint32_t)r->password_properties);
6806 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6807 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6809 return NT_STATUS_OK;
6812 /*******************************************************************
6813 ********************************************************************/
6815 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6816 struct samr_DomInfo3 *r)
6820 u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6822 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6824 return NT_STATUS_OK;
6827 /*******************************************************************
6828 ********************************************************************/
6830 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6831 struct samr_DomInfo12 *r)
6833 time_t u_lock_duration, u_reset_time;
6836 * It is not possible to set lockout_duration < lockout_window.
6837 * (The test is the other way around since the negative numbers
6840 * This constraint is documented here for the samr rpc service:
6841 * MS-SAMR 3.1.1.6 Attribute Constraints for Originating Updates
6842 * http://msdn.microsoft.com/en-us/library/cc245667%28PROT.10%29.aspx
6844 * And here for the ldap backend:
6845 * MS-ADTS 3.1.1.5.3.2 Constraints
6846 * http://msdn.microsoft.com/en-us/library/cc223462(PROT.10).aspx
6848 if (r->lockout_duration > r->lockout_window) {
6849 return NT_STATUS_INVALID_PARAMETER;
6852 u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6853 if (u_lock_duration != -1) {
6854 u_lock_duration /= 60;
6857 u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6859 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6860 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6861 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6862 (uint32_t)r->lockout_threshold);
6864 return NT_STATUS_OK;
6867 /*******************************************************************
6869 ********************************************************************/
6871 NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
6872 struct samr_SetDomainInfo *r)
6875 uint32_t acc_required = 0;
6877 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6879 switch (r->in.level) {
6880 case 1: /* DomainPasswordInformation */
6881 case 12: /* DomainLockoutInformation */
6882 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6883 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6885 case 3: /* DomainLogoffInformation */
6886 case 4: /* DomainOemInformation */
6887 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6888 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6890 case 6: /* DomainReplicationInformation */
6891 case 9: /* DomainStateInformation */
6892 case 7: /* DomainServerRoleInformation */
6893 /* DOMAIN_ADMINISTER_SERVER */
6894 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6897 return NT_STATUS_INVALID_INFO_CLASS;
6900 (void)samr_policy_handle_find(p,
6901 r->in.domain_handle,
6906 if (!NT_STATUS_IS_OK(status)) {
6910 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6912 switch (r->in.level) {
6914 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6917 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6928 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6931 return NT_STATUS_INVALID_INFO_CLASS;
6934 if (!NT_STATUS_IS_OK(status)) {
6938 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6940 return NT_STATUS_OK;
6943 /****************************************************************
6944 _samr_GetDisplayEnumerationIndex
6945 ****************************************************************/
6947 NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
6948 struct samr_GetDisplayEnumerationIndex *r)
6950 struct samr_info *dinfo;
6951 uint32_t max_entries = (uint32_t) -1;
6952 uint32_t enum_context = 0;
6953 uint32_t i, num_account = 0;
6954 struct samr_displayentry *entries = NULL;
6957 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6959 dinfo = samr_policy_handle_find(p,
6960 r->in.domain_handle,
6962 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
6965 if (!NT_STATUS_IS_OK(status)) {
6969 if ((r->in.level < 1) || (r->in.level > 3)) {
6970 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6971 "Unknown info level (%u)\n",
6973 return NT_STATUS_INVALID_INFO_CLASS;
6978 /* The following done as ROOT. Don't return without unbecome_root(). */
6980 switch (r->in.level) {
6982 if (dinfo->disp_info->users == NULL) {
6983 dinfo->disp_info->users = pdb_search_users(
6984 dinfo->disp_info, ACB_NORMAL);
6985 if (dinfo->disp_info->users == NULL) {
6987 return NT_STATUS_ACCESS_DENIED;
6989 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6990 "starting user enumeration at index %u\n",
6991 (unsigned int)enum_context));
6993 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6994 "using cached user enumeration at index %u\n",
6995 (unsigned int)enum_context));
6997 num_account = pdb_search_entries(dinfo->disp_info->users,
6998 enum_context, max_entries,
7002 if (dinfo->disp_info->machines == NULL) {
7003 dinfo->disp_info->machines = pdb_search_users(
7004 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
7005 if (dinfo->disp_info->machines == NULL) {
7007 return NT_STATUS_ACCESS_DENIED;
7009 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
7010 "starting machine enumeration at index %u\n",
7011 (unsigned int)enum_context));
7013 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
7014 "using cached machine enumeration at index %u\n",
7015 (unsigned int)enum_context));
7017 num_account = pdb_search_entries(dinfo->disp_info->machines,
7018 enum_context, max_entries,
7022 if (dinfo->disp_info->groups == NULL) {
7023 dinfo->disp_info->groups = pdb_search_groups(
7025 if (dinfo->disp_info->groups == NULL) {
7027 return NT_STATUS_ACCESS_DENIED;
7029 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
7030 "starting group enumeration at index %u\n",
7031 (unsigned int)enum_context));
7033 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
7034 "using cached group enumeration at index %u\n",
7035 (unsigned int)enum_context));
7037 num_account = pdb_search_entries(dinfo->disp_info->groups,
7038 enum_context, max_entries,
7043 smb_panic("info class changed");
7049 /* Ensure we cache this enumeration. */
7050 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
7052 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
7053 r->in.name->string));
7055 for (i=0; i<num_account; i++) {
7056 if (strequal(entries[i].account_name, r->in.name->string)) {
7057 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
7058 "found %s at idx %d\n",
7059 r->in.name->string, i));
7061 return NT_STATUS_OK;
7065 /* assuming account_name lives at the very end */
7066 *r->out.idx = num_account;
7068 return NT_STATUS_NO_MORE_ENTRIES;
7071 /****************************************************************
7072 _samr_GetDisplayEnumerationIndex2
7073 ****************************************************************/
7075 NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
7076 struct samr_GetDisplayEnumerationIndex2 *r)
7078 struct samr_GetDisplayEnumerationIndex q;
7080 q.in.domain_handle = r->in.domain_handle;
7081 q.in.level = r->in.level;
7082 q.in.name = r->in.name;
7084 q.out.idx = r->out.idx;
7086 return _samr_GetDisplayEnumerationIndex(p, &q);
7089 /****************************************************************
7091 ****************************************************************/
7093 NTSTATUS _samr_RidToSid(struct pipes_struct *p,
7094 struct samr_RidToSid *r)
7096 struct samr_info *dinfo;
7100 dinfo = samr_policy_handle_find(p,
7101 r->in.domain_handle,
7106 if (!NT_STATUS_IS_OK(status)) {
7110 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
7111 return NT_STATUS_NO_MEMORY;
7114 *r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
7116 return NT_STATUS_NO_MEMORY;
7119 return NT_STATUS_OK;
7122 /****************************************************************
7123 ****************************************************************/
7125 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
7126 const struct samr_PwInfo *dom_pw_info,
7127 const struct samr_ValidatePasswordReq2 *req,
7128 struct samr_ValidatePasswordRepCtr *rep)
7132 if (req->password.string == NULL) {
7133 return SAMR_VALIDATION_STATUS_SUCCESS;
7135 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
7136 ZERO_STRUCT(rep->info);
7137 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
7139 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
7140 status = check_password_complexity(req->account.string,
7141 NULL, /* full_name */
7142 req->password.string,
7144 if (!NT_STATUS_IS_OK(status)) {
7145 ZERO_STRUCT(rep->info);
7146 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
7150 return SAMR_VALIDATION_STATUS_SUCCESS;
7153 /****************************************************************
7154 ****************************************************************/
7156 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
7157 const struct samr_PwInfo *dom_pw_info,
7158 const struct samr_ValidatePasswordReq3 *req,
7159 struct samr_ValidatePasswordRepCtr *rep)
7163 if (req->password.string == NULL) {
7164 return SAMR_VALIDATION_STATUS_SUCCESS;
7166 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
7167 ZERO_STRUCT(rep->info);
7168 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
7170 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
7171 status = check_password_complexity(req->account.string,
7172 NULL, /* full_name */
7173 req->password.string,
7175 if (!NT_STATUS_IS_OK(status)) {
7176 ZERO_STRUCT(rep->info);
7177 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
7181 return SAMR_VALIDATION_STATUS_SUCCESS;
7184 /****************************************************************
7185 _samr_ValidatePassword
7186 ****************************************************************/
7188 NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
7189 struct samr_ValidatePassword *r)
7191 union samr_ValidatePasswordRep *rep;
7193 struct samr_GetDomPwInfo pw;
7194 struct samr_PwInfo dom_pw_info;
7196 if (p->transport != NCACN_IP_TCP && p->transport != NCALRPC) {
7197 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
7198 return NT_STATUS_ACCESS_DENIED;
7201 if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
7202 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
7203 return NT_STATUS_ACCESS_DENIED;
7206 if (r->in.level < 1 || r->in.level > 3) {
7207 return NT_STATUS_INVALID_INFO_CLASS;
7210 pw.in.domain_name = NULL;
7211 pw.out.info = &dom_pw_info;
7213 status = _samr_GetDomPwInfo(p, &pw);
7214 if (!NT_STATUS_IS_OK(status)) {
7218 rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
7220 return NT_STATUS_NO_MEMORY;
7223 switch (r->in.level) {
7225 status = NT_STATUS_NOT_SUPPORTED;
7228 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
7234 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
7240 status = NT_STATUS_INVALID_INFO_CLASS;
7244 if (!NT_STATUS_IS_OK(status)) {
7251 return NT_STATUS_OK;
7254 /****************************************************************
7255 ****************************************************************/
7257 NTSTATUS _samr_Shutdown(struct pipes_struct *p,
7258 struct samr_Shutdown *r)
7260 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7261 return NT_STATUS_NOT_IMPLEMENTED;
7264 /****************************************************************
7265 ****************************************************************/
7267 NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
7268 struct samr_SetMemberAttributesOfGroup *r)
7270 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7271 return NT_STATUS_NOT_IMPLEMENTED;
7274 /****************************************************************
7275 ****************************************************************/
7277 NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
7278 struct samr_TestPrivateFunctionsDomain *r)
7280 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7281 return NT_STATUS_NOT_IMPLEMENTED;
7284 /****************************************************************
7285 ****************************************************************/
7287 NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
7288 struct samr_TestPrivateFunctionsUser *r)
7290 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7291 return NT_STATUS_NOT_IMPLEMENTED;
7294 /****************************************************************
7295 ****************************************************************/
7297 NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
7298 struct samr_AddMultipleMembersToAlias *r)
7300 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7301 return NT_STATUS_NOT_IMPLEMENTED;
7304 /****************************************************************
7305 ****************************************************************/
7307 NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
7308 struct samr_RemoveMultipleMembersFromAlias *r)
7310 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7311 return NT_STATUS_NOT_IMPLEMENTED;
7314 /****************************************************************
7315 ****************************************************************/
7317 NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
7318 struct samr_SetBootKeyInformation *r)
7320 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7321 return NT_STATUS_NOT_IMPLEMENTED;
7324 /****************************************************************
7325 ****************************************************************/
7327 NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
7328 struct samr_GetBootKeyInformation *r)
7330 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7331 return NT_STATUS_NOT_IMPLEMENTED;
7334 /****************************************************************
7335 ****************************************************************/
7337 NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
7338 struct samr_SetDsrmPassword *r)
7340 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
7341 return NT_STATUS_NOT_IMPLEMENTED;
7344 /* include the generated boilerplate */
7345 #include "librpc/gen_ndr/ndr_samr_scompat.c"