libcli:smb: Zero sensitive memory after use
[Samba.git] / source3 / rpc_server / samr / srv_samr_nt.c
blob124d6d38cd707ea46716e1eb18a9165fd52150b5
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
34 #include "includes.h"
35 #include "system/passwd.h"
36 #include "../libcli/auth/libcli_auth.h"
37 #include "ntdomain.h"
38 #include "../librpc/gen_ndr/srv_samr.h"
39 #include "rpc_server/samr/srv_samr_util.h"
40 #include "../lib/crypto/arcfour.h"
41 #include "secrets.h"
42 #include "rpc_client/init_lsa.h"
43 #include "../libcli/security/security.h"
44 #include "passdb.h"
45 #include "auth.h"
46 #include "rpc_server/srv_access_check.h"
47 #include "../lib/tsocket/tsocket.h"
48 #include "lib/util/base64.h"
50 #undef DBGC_CLASS
51 #define DBGC_CLASS DBGC_RPC_SRV
53 #define SAMR_USR_RIGHTS_WRITE_PW \
54 ( READ_CONTROL_ACCESS | \
55 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
56 SAMR_USER_ACCESS_SET_LOC_COM)
57 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
58 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
60 #define DISP_INFO_CACHE_TIMEOUT 10
62 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
63 #define MAX_SAM_ENTRIES_W95 50
65 struct samr_connect_info {
66 uint8_t dummy;
69 struct samr_domain_info {
70 struct dom_sid sid;
71 struct disp_info *disp_info;
74 struct samr_user_info {
75 struct dom_sid sid;
78 struct samr_group_info {
79 struct dom_sid sid;
82 struct samr_alias_info {
83 struct dom_sid sid;
86 typedef struct disp_info {
87 struct dom_sid sid; /* identify which domain this is. */
88 struct pdb_search *users; /* querydispinfo 1 and 4 */
89 struct pdb_search *machines; /* querydispinfo 2 */
90 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
91 struct pdb_search *aliases; /* enumaliases */
93 uint32_t enum_acb_mask;
94 struct pdb_search *enum_users; /* enumusers with a mask */
96 struct tevent_timer *cache_timeout_event; /* cache idle timeout
97 * handler. */
98 } DISP_INFO;
100 static const struct generic_mapping sam_generic_mapping = {
101 GENERIC_RIGHTS_SAM_READ,
102 GENERIC_RIGHTS_SAM_WRITE,
103 GENERIC_RIGHTS_SAM_EXECUTE,
104 GENERIC_RIGHTS_SAM_ALL_ACCESS};
105 static const struct generic_mapping dom_generic_mapping = {
106 GENERIC_RIGHTS_DOMAIN_READ,
107 GENERIC_RIGHTS_DOMAIN_WRITE,
108 GENERIC_RIGHTS_DOMAIN_EXECUTE,
109 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
110 static const struct generic_mapping usr_generic_mapping = {
111 GENERIC_RIGHTS_USER_READ,
112 GENERIC_RIGHTS_USER_WRITE,
113 GENERIC_RIGHTS_USER_EXECUTE,
114 GENERIC_RIGHTS_USER_ALL_ACCESS};
115 static const struct generic_mapping usr_nopwchange_generic_mapping = {
116 GENERIC_RIGHTS_USER_READ,
117 GENERIC_RIGHTS_USER_WRITE,
118 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
119 GENERIC_RIGHTS_USER_ALL_ACCESS};
120 static const struct generic_mapping grp_generic_mapping = {
121 GENERIC_RIGHTS_GROUP_READ,
122 GENERIC_RIGHTS_GROUP_WRITE,
123 GENERIC_RIGHTS_GROUP_EXECUTE,
124 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
125 static const struct generic_mapping ali_generic_mapping = {
126 GENERIC_RIGHTS_ALIAS_READ,
127 GENERIC_RIGHTS_ALIAS_WRITE,
128 GENERIC_RIGHTS_ALIAS_EXECUTE,
129 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
131 /*******************************************************************
132 *******************************************************************/
134 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
135 const struct generic_mapping *map,
136 struct dom_sid *sid, uint32_t sid_access )
138 struct dom_sid domadmin_sid;
139 struct security_ace ace[5]; /* at most 5 entries */
140 size_t i = 0;
142 struct security_acl *psa = NULL;
144 /* basic access for Everyone */
146 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
147 map->generic_execute | map->generic_read, 0);
149 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
151 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
152 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
153 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
154 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
156 /* Add Full Access for Domain Admins if we are a DC */
158 if ( IS_DC ) {
159 sid_compose(&domadmin_sid, get_global_sam_sid(),
160 DOMAIN_RID_ADMINS);
161 init_sec_ace(&ace[i++], &domadmin_sid,
162 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
165 /* if we have a sid, give it some special access */
167 if ( sid ) {
168 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
171 /* create the security descriptor */
173 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
174 return NT_STATUS_NO_MEMORY;
176 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
177 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
178 psa, sd_size)) == NULL)
179 return NT_STATUS_NO_MEMORY;
181 return NT_STATUS_OK;
184 /*******************************************************************
185 Fetch or create a dispinfo struct.
186 ********************************************************************/
188 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
191 * We do a static cache for DISP_INFO's here. Explanation can be found
192 * in Jeremy's checkin message to r11793:
194 * Fix the SAMR cache so it works across completely insane
195 * client behaviour (ie.:
196 * open pipe/open SAMR handle/enumerate 0 - 1024
197 * close SAMR handle, close pipe.
198 * open pipe/open SAMR handle/enumerate 1024 - 2048...
199 * close SAMR handle, close pipe.
200 * And on ad-nausium. Amazing.... probably object-oriented
201 * client side programming in action yet again.
202 * This change should *massively* improve performance when
203 * enumerating users from an LDAP database.
204 * Jeremy.
206 * "Our" and the builtin domain are the only ones where we ever
207 * enumerate stuff, so just cache 2 entries.
210 static struct disp_info *builtin_dispinfo;
211 static struct disp_info *domain_dispinfo;
213 /* There are two cases to consider here:
214 1) The SID is a domain SID and we look for an equality match, or
215 2) This is an account SID and so we return the DISP_INFO* for our
216 domain */
218 if (psid == NULL) {
219 return NULL;
222 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
224 * Necessary only once, but it does not really hurt.
226 if (builtin_dispinfo == NULL) {
227 builtin_dispinfo = talloc_zero(NULL, struct disp_info);
228 if (builtin_dispinfo == NULL) {
229 return NULL;
232 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
234 return builtin_dispinfo;
237 if (sid_check_is_our_sam(psid) || sid_check_is_in_our_sam(psid)) {
239 * Necessary only once, but it does not really hurt.
241 if (domain_dispinfo == NULL) {
242 domain_dispinfo = talloc_zero(NULL, struct disp_info);
243 if (domain_dispinfo == NULL) {
244 return NULL;
247 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
249 return domain_dispinfo;
252 return NULL;
255 /*******************************************************************
256 Function to free the per SID data.
257 ********************************************************************/
259 static void free_samr_cache(DISP_INFO *disp_info)
261 struct dom_sid_buf buf;
263 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
264 dom_sid_str_buf(&disp_info->sid, &buf)));
266 /* We need to become root here because the paged search might have to
267 * tell the LDAP server we're not interested in the rest anymore. */
269 become_root();
271 TALLOC_FREE(disp_info->users);
272 TALLOC_FREE(disp_info->machines);
273 TALLOC_FREE(disp_info->groups);
274 TALLOC_FREE(disp_info->aliases);
275 TALLOC_FREE(disp_info->enum_users);
277 unbecome_root();
280 /*******************************************************************
281 Idle event handler. Throw away the disp info cache.
282 ********************************************************************/
284 static void disp_info_cache_idle_timeout_handler(struct tevent_context *ev_ctx,
285 struct tevent_timer *te,
286 struct timeval now,
287 void *private_data)
289 DISP_INFO *disp_info = (DISP_INFO *)private_data;
291 TALLOC_FREE(disp_info->cache_timeout_event);
293 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
294 "out\n"));
295 free_samr_cache(disp_info);
298 /*******************************************************************
299 Setup cache removal idle event handler.
300 ********************************************************************/
302 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
304 struct dom_sid_buf buf;
306 /* Remove any pending timeout and update. */
308 TALLOC_FREE(disp_info->cache_timeout_event);
310 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
311 "SID %s for %u seconds\n",
312 dom_sid_str_buf(&disp_info->sid, &buf),
313 (unsigned int)secs_fromnow ));
315 disp_info->cache_timeout_event = tevent_add_timer(
316 global_event_context(), NULL,
317 timeval_current_ofs(secs_fromnow, 0),
318 disp_info_cache_idle_timeout_handler, (void *)disp_info);
321 /*******************************************************************
322 Force flush any cache. We do this on any samr_set_xxx call.
323 We must also remove the timeout handler.
324 ********************************************************************/
326 static void force_flush_samr_cache(const struct dom_sid *sid)
328 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
330 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
331 return;
334 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
335 TALLOC_FREE(disp_info->cache_timeout_event);
336 free_samr_cache(disp_info);
339 /*******************************************************************
340 Ensure password info is never given out. Paranioa... JRA.
341 ********************************************************************/
343 static void samr_clear_sam_passwd(struct samu *sam_pass)
346 if (!sam_pass)
347 return;
349 /* These now zero out the old password */
351 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
352 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
355 static uint32_t count_sam_users(struct disp_info *info, uint32_t acct_flags)
357 struct samr_displayentry *entry;
359 if (sid_check_is_builtin(&info->sid)) {
360 /* No users in builtin. */
361 return 0;
364 if (info->users == NULL) {
365 info->users = pdb_search_users(info, acct_flags);
366 if (info->users == NULL) {
367 return 0;
370 /* Fetch the last possible entry, thus trigger an enumeration */
371 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
373 /* Ensure we cache this enumeration. */
374 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
376 return info->users->num_entries;
379 static uint32_t count_sam_groups(struct disp_info *info)
381 struct samr_displayentry *entry;
383 if (sid_check_is_builtin(&info->sid)) {
384 /* No groups in builtin. */
385 return 0;
388 if (info->groups == NULL) {
389 info->groups = pdb_search_groups(info);
390 if (info->groups == NULL) {
391 return 0;
394 /* Fetch the last possible entry, thus trigger an enumeration */
395 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
397 /* Ensure we cache this enumeration. */
398 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
400 return info->groups->num_entries;
403 static uint32_t count_sam_aliases(struct disp_info *info)
405 struct samr_displayentry *entry;
407 if (info->aliases == NULL) {
408 info->aliases = pdb_search_aliases(info, &info->sid);
409 if (info->aliases == NULL) {
410 return 0;
413 /* Fetch the last possible entry, thus trigger an enumeration */
414 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
416 /* Ensure we cache this enumeration. */
417 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
419 return info->aliases->num_entries;
422 /*******************************************************************
423 _samr_Close
424 ********************************************************************/
426 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
428 if (!close_policy_hnd(p, r->in.handle)) {
429 return NT_STATUS_INVALID_HANDLE;
432 ZERO_STRUCTP(r->out.handle);
434 return NT_STATUS_OK;
437 /*******************************************************************
438 _samr_OpenDomain
439 ********************************************************************/
441 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
442 struct samr_OpenDomain *r)
444 struct samr_domain_info *dinfo;
445 struct security_descriptor *psd = NULL;
446 uint32_t acc_granted;
447 uint32_t des_access = r->in.access_mask;
448 NTSTATUS status;
449 size_t sd_size;
450 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
452 /* find the connection policy handle. */
454 (void)policy_handle_find(p, r->in.connect_handle, 0, NULL,
455 struct samr_connect_info, &status);
456 if (!NT_STATUS_IS_OK(status)) {
457 return status;
460 /*check if access can be granted as requested by client. */
461 map_max_allowed_access(p->session_info->security_token,
462 p->session_info->unix_token,
463 &des_access);
465 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
466 se_map_generic( &des_access, &dom_generic_mapping );
469 * Users with SeAddUser get the ability to manipulate groups
470 * and aliases.
472 if (security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS)) {
473 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
474 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
475 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
476 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
477 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
481 * Users with SeMachineAccount or SeAddUser get additional
482 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
485 status = access_check_object( psd, p->session_info->security_token,
486 SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
487 extra_access, des_access,
488 &acc_granted, "_samr_OpenDomain" );
490 if ( !NT_STATUS_IS_OK(status) )
491 return status;
493 if (!sid_check_is_our_sam(r->in.sid) &&
494 !sid_check_is_builtin(r->in.sid)) {
495 return NT_STATUS_NO_SUCH_DOMAIN;
498 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
499 struct samr_domain_info, &status);
500 if (!NT_STATUS_IS_OK(status)) {
501 return status;
503 dinfo->sid = *r->in.sid;
504 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
506 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
508 return NT_STATUS_OK;
511 /*******************************************************************
512 _samr_GetUserPwInfo
513 ********************************************************************/
515 NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
516 struct samr_GetUserPwInfo *r)
518 struct samr_user_info *uinfo;
519 enum lsa_SidType sid_type;
520 uint32_t min_password_length = 0;
521 uint32_t password_properties = 0;
522 bool ret = false;
523 NTSTATUS status;
525 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
527 uinfo = policy_handle_find(p, r->in.user_handle,
528 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
529 struct samr_user_info, &status);
530 if (!NT_STATUS_IS_OK(status)) {
531 return status;
534 if (!sid_check_is_in_our_sam(&uinfo->sid)) {
535 return NT_STATUS_OBJECT_TYPE_MISMATCH;
538 become_root();
539 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
540 unbecome_root();
541 if (ret == false) {
542 return NT_STATUS_NO_SUCH_USER;
545 switch (sid_type) {
546 case SID_NAME_USER:
547 become_root();
548 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
549 &min_password_length);
550 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
551 &password_properties);
552 unbecome_root();
554 if (lp_check_password_script(talloc_tos())
555 && *lp_check_password_script(talloc_tos())) {
556 password_properties |= DOMAIN_PASSWORD_COMPLEX;
559 break;
560 default:
561 break;
564 r->out.info->min_password_length = min_password_length;
565 r->out.info->password_properties = password_properties;
567 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
569 return NT_STATUS_OK;
572 /*******************************************************************
573 _samr_SetSecurity
574 ********************************************************************/
576 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
577 struct samr_SetSecurity *r)
579 struct samr_user_info *uinfo;
580 uint32_t i;
581 struct security_acl *dacl;
582 bool ret;
583 struct samu *sampass=NULL;
584 NTSTATUS status;
586 uinfo = policy_handle_find(p, r->in.handle,
587 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
588 struct samr_user_info, &status);
589 if (!NT_STATUS_IS_OK(status)) {
590 return status;
593 if (!(sampass = samu_new( p->mem_ctx))) {
594 DEBUG(0,("No memory!\n"));
595 return NT_STATUS_NO_MEMORY;
598 /* get the user record */
599 become_root();
600 ret = pdb_getsampwsid(sampass, &uinfo->sid);
601 unbecome_root();
603 if (!ret) {
604 struct dom_sid_buf buf;
605 DEBUG(4, ("User %s not found\n",
606 dom_sid_str_buf(&uinfo->sid, &buf)));
607 TALLOC_FREE(sampass);
608 return NT_STATUS_INVALID_HANDLE;
611 dacl = r->in.sdbuf->sd->dacl;
612 for (i=0; i < dacl->num_aces; i++) {
613 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
614 ret = pdb_set_pass_can_change(sampass,
615 (dacl->aces[i].access_mask &
616 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
617 True: False);
618 break;
622 if (!ret) {
623 TALLOC_FREE(sampass);
624 return NT_STATUS_ACCESS_DENIED;
627 become_root();
628 status = pdb_update_sam_account(sampass);
629 unbecome_root();
631 TALLOC_FREE(sampass);
633 return status;
636 /*******************************************************************
637 build correct perms based on policies and password times for _samr_query_sec_obj
638 *******************************************************************/
639 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
641 struct samu *sampass=NULL;
642 bool ret;
644 if ( !(sampass = samu_new( mem_ctx )) ) {
645 DEBUG(0,("No memory!\n"));
646 return False;
649 become_root();
650 ret = pdb_getsampwsid(sampass, user_sid);
651 unbecome_root();
653 if (ret == False) {
654 struct dom_sid_buf buf;
655 DEBUG(4,("User %s not found\n",
656 dom_sid_str_buf(user_sid, &buf)));
657 TALLOC_FREE(sampass);
658 return False;
661 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
663 if (pdb_get_pass_can_change(sampass)) {
664 TALLOC_FREE(sampass);
665 return True;
667 TALLOC_FREE(sampass);
668 return False;
672 /*******************************************************************
673 _samr_QuerySecurity
674 ********************************************************************/
676 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
677 struct samr_QuerySecurity *r)
679 struct samr_domain_info *dinfo;
680 struct samr_user_info *uinfo;
681 struct samr_group_info *ginfo;
682 struct samr_alias_info *ainfo;
683 NTSTATUS status;
684 struct security_descriptor * psd = NULL;
685 size_t sd_size = 0;
686 struct dom_sid_buf buf;
688 (void)policy_handle_find(p, r->in.handle,
689 SEC_STD_READ_CONTROL, NULL,
690 struct samr_connect_info, &status);
691 if (NT_STATUS_IS_OK(status)) {
692 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
693 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
694 &sam_generic_mapping, NULL, 0);
695 goto done;
698 dinfo = policy_handle_find(p, r->in.handle,
699 SEC_STD_READ_CONTROL, NULL,
700 struct samr_domain_info, &status);
701 if (NT_STATUS_IS_OK(status)) {
702 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
703 "with SID: %s\n",
704 dom_sid_str_buf(&dinfo->sid, &buf)));
706 * TODO: Builtin probably needs a different SD with restricted
707 * write access
709 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
710 &dom_generic_mapping, NULL, 0);
711 goto done;
714 uinfo = policy_handle_find(p, r->in.handle,
715 SEC_STD_READ_CONTROL, NULL,
716 struct samr_user_info, &status);
717 if (NT_STATUS_IS_OK(status)) {
718 DEBUG(10,("_samr_QuerySecurity: querying security on user "
719 "Object with SID: %s\n",
720 dom_sid_str_buf(&uinfo->sid, &buf)));
721 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
722 status = make_samr_object_sd(
723 p->mem_ctx, &psd, &sd_size,
724 &usr_generic_mapping,
725 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
726 } else {
727 status = make_samr_object_sd(
728 p->mem_ctx, &psd, &sd_size,
729 &usr_nopwchange_generic_mapping,
730 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
732 goto done;
735 ginfo = policy_handle_find(p, r->in.handle,
736 SEC_STD_READ_CONTROL, NULL,
737 struct samr_group_info, &status);
738 if (NT_STATUS_IS_OK(status)) {
740 * TODO: different SDs have to be generated for aliases groups
741 * and users. Currently all three get a default user SD
743 DEBUG(10,("_samr_QuerySecurity: querying security on group "
744 "Object with SID: %s\n",
745 dom_sid_str_buf(&ginfo->sid, &buf)));
746 status = make_samr_object_sd(
747 p->mem_ctx, &psd, &sd_size,
748 &usr_nopwchange_generic_mapping,
749 &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
750 goto done;
753 ainfo = policy_handle_find(p, r->in.handle,
754 SEC_STD_READ_CONTROL, NULL,
755 struct samr_alias_info, &status);
756 if (NT_STATUS_IS_OK(status)) {
758 * TODO: different SDs have to be generated for aliases groups
759 * and users. Currently all three get a default user SD
761 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
762 "Object with SID: %s\n",
763 dom_sid_str_buf(&ainfo->sid, &buf)));
764 status = make_samr_object_sd(
765 p->mem_ctx, &psd, &sd_size,
766 &usr_nopwchange_generic_mapping,
767 &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
768 goto done;
771 return NT_STATUS_OBJECT_TYPE_MISMATCH;
772 done:
773 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
774 return NT_STATUS_NO_MEMORY;
776 return status;
779 /*******************************************************************
780 makes a SAM_ENTRY / UNISTR2* structure from a user list.
781 ********************************************************************/
783 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
784 struct samr_SamEntry **sam_pp,
785 uint32_t num_entries,
786 uint32_t start_idx,
787 struct samr_displayentry *entries)
789 uint32_t i;
790 struct samr_SamEntry *sam;
792 *sam_pp = NULL;
794 if (num_entries == 0) {
795 return NT_STATUS_OK;
798 sam = talloc_zero_array(ctx, struct samr_SamEntry, num_entries);
799 if (sam == NULL) {
800 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
801 return NT_STATUS_NO_MEMORY;
804 for (i = 0; i < num_entries; i++) {
805 #if 0
807 * usrmgr expects a non-NULL terminated string with
808 * trust relationships
810 if (entries[i].acct_flags & ACB_DOMTRUST) {
811 init_unistr2(&uni_temp_name, entries[i].account_name,
812 UNI_FLAGS_NONE);
813 } else {
814 init_unistr2(&uni_temp_name, entries[i].account_name,
815 UNI_STR_TERMINATE);
817 #endif
818 init_lsa_String(&sam[i].name, entries[i].account_name);
819 sam[i].idx = entries[i].rid;
822 *sam_pp = sam;
824 return NT_STATUS_OK;
827 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
829 /*******************************************************************
830 _samr_EnumDomainUsers
831 ********************************************************************/
833 NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
834 struct samr_EnumDomainUsers *r)
836 NTSTATUS status;
837 struct samr_domain_info *dinfo;
838 int num_account;
839 uint32_t enum_context = *r->in.resume_handle;
840 enum remote_arch_types ra_type = get_remote_arch();
841 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
842 uint32_t max_entries = max_sam_entries;
843 struct samr_displayentry *entries = NULL;
844 struct samr_SamArray *samr_array = NULL;
845 struct samr_SamEntry *samr_entries = NULL;
847 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
849 dinfo = policy_handle_find(p, r->in.domain_handle,
850 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
851 struct samr_domain_info, &status);
852 if (!NT_STATUS_IS_OK(status)) {
853 return status;
856 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
857 if (!samr_array) {
858 return NT_STATUS_NO_MEMORY;
860 *r->out.sam = samr_array;
862 if (sid_check_is_builtin(&dinfo->sid)) {
863 /* No users in builtin. */
864 *r->out.resume_handle = *r->in.resume_handle;
865 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
866 return status;
869 become_root();
871 /* AS ROOT !!!! */
873 if ((dinfo->disp_info->enum_users != NULL) &&
874 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
875 TALLOC_FREE(dinfo->disp_info->enum_users);
878 if (dinfo->disp_info->enum_users == NULL) {
879 dinfo->disp_info->enum_users = pdb_search_users(
880 dinfo->disp_info, r->in.acct_flags);
881 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
884 if (dinfo->disp_info->enum_users == NULL) {
885 /* END AS ROOT !!!! */
886 unbecome_root();
887 return NT_STATUS_ACCESS_DENIED;
890 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
891 enum_context, max_entries,
892 &entries);
894 /* END AS ROOT !!!! */
896 unbecome_root();
898 if (num_account == 0) {
899 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
900 "total entries\n"));
901 *r->out.resume_handle = *r->in.resume_handle;
902 return NT_STATUS_OK;
905 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
906 num_account, enum_context,
907 entries);
908 if (!NT_STATUS_IS_OK(status)) {
909 return status;
912 if (max_entries <= num_account) {
913 status = STATUS_MORE_ENTRIES;
914 } else {
915 status = NT_STATUS_OK;
918 /* Ensure we cache this enumeration. */
919 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
921 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
923 samr_array->count = num_account;
924 samr_array->entries = samr_entries;
926 *r->out.resume_handle = *r->in.resume_handle + num_account;
927 *r->out.num_entries = num_account;
929 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
931 return status;
934 /*******************************************************************
935 makes a SAM_ENTRY / UNISTR2* structure from a group list.
936 ********************************************************************/
938 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
939 struct samr_SamEntry **sam_pp,
940 uint32_t num_sam_entries,
941 struct samr_displayentry *entries)
943 struct samr_SamEntry *sam;
944 uint32_t i;
946 *sam_pp = NULL;
948 if (num_sam_entries == 0) {
949 return;
952 sam = talloc_zero_array(ctx, struct samr_SamEntry, num_sam_entries);
953 if (sam == NULL) {
954 return;
957 for (i = 0; i < num_sam_entries; i++) {
959 * JRA. I think this should include the null. TNG does not.
961 init_lsa_String(&sam[i].name, entries[i].account_name);
962 sam[i].idx = entries[i].rid;
965 *sam_pp = sam;
968 /*******************************************************************
969 _samr_EnumDomainGroups
970 ********************************************************************/
972 NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
973 struct samr_EnumDomainGroups *r)
975 NTSTATUS status;
976 struct samr_domain_info *dinfo;
977 struct samr_displayentry *groups;
978 uint32_t num_groups;
979 struct samr_SamArray *samr_array = NULL;
980 struct samr_SamEntry *samr_entries = NULL;
982 dinfo = policy_handle_find(p, r->in.domain_handle,
983 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
984 struct samr_domain_info, &status);
985 if (!NT_STATUS_IS_OK(status)) {
986 return status;
989 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
991 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
992 if (!samr_array) {
993 return NT_STATUS_NO_MEMORY;
995 *r->out.sam = samr_array;
997 if (sid_check_is_builtin(&dinfo->sid)) {
998 /* No groups in builtin. */
999 *r->out.resume_handle = *r->in.resume_handle;
1000 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1001 return status;
1004 /* the domain group array is being allocated in the function below */
1006 become_root();
1008 if (dinfo->disp_info->groups == NULL) {
1009 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1011 if (dinfo->disp_info->groups == NULL) {
1012 unbecome_root();
1013 return NT_STATUS_ACCESS_DENIED;
1017 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1018 *r->in.resume_handle,
1019 MAX_SAM_ENTRIES, &groups);
1020 unbecome_root();
1022 /* Ensure we cache this enumeration. */
1023 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1025 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1026 num_groups, groups);
1028 if (MAX_SAM_ENTRIES <= num_groups) {
1029 status = STATUS_MORE_ENTRIES;
1030 } else {
1031 status = NT_STATUS_OK;
1034 samr_array->count = num_groups;
1035 samr_array->entries = samr_entries;
1037 *r->out.num_entries = num_groups;
1038 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1040 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1042 return status;
1045 /*******************************************************************
1046 _samr_EnumDomainAliases
1047 ********************************************************************/
1049 NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1050 struct samr_EnumDomainAliases *r)
1052 NTSTATUS status;
1053 struct samr_domain_info *dinfo;
1054 struct samr_displayentry *aliases;
1055 uint32_t num_aliases = 0;
1056 struct samr_SamArray *samr_array = NULL;
1057 struct samr_SamEntry *samr_entries = NULL;
1058 struct dom_sid_buf buf;
1060 dinfo = policy_handle_find(p, r->in.domain_handle,
1061 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1062 struct samr_domain_info, &status);
1063 if (!NT_STATUS_IS_OK(status)) {
1064 return status;
1067 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1068 dom_sid_str_buf(&dinfo->sid, &buf)));
1070 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
1071 if (!samr_array) {
1072 return NT_STATUS_NO_MEMORY;
1075 become_root();
1077 if (dinfo->disp_info->aliases == NULL) {
1078 dinfo->disp_info->aliases = pdb_search_aliases(
1079 dinfo->disp_info, &dinfo->sid);
1080 if (dinfo->disp_info->aliases == NULL) {
1081 unbecome_root();
1082 return NT_STATUS_ACCESS_DENIED;
1086 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1087 *r->in.resume_handle,
1088 MAX_SAM_ENTRIES, &aliases);
1089 unbecome_root();
1091 /* Ensure we cache this enumeration. */
1092 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1094 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1095 num_aliases, aliases);
1097 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1099 if (MAX_SAM_ENTRIES <= num_aliases) {
1100 status = STATUS_MORE_ENTRIES;
1101 } else {
1102 status = NT_STATUS_OK;
1105 samr_array->count = num_aliases;
1106 samr_array->entries = samr_entries;
1108 *r->out.sam = samr_array;
1109 *r->out.num_entries = num_aliases;
1110 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1112 return status;
1115 /*******************************************************************
1116 inits a samr_DispInfoGeneral structure.
1117 ********************************************************************/
1119 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1120 struct samr_DispInfoGeneral *r,
1121 uint32_t num_entries,
1122 uint32_t start_idx,
1123 struct samr_displayentry *entries)
1125 uint32_t i;
1127 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1129 if (num_entries == 0) {
1130 return NT_STATUS_OK;
1133 r->count = num_entries;
1135 r->entries = talloc_zero_array(ctx, struct samr_DispEntryGeneral, num_entries);
1136 if (!r->entries) {
1137 return NT_STATUS_NO_MEMORY;
1140 for (i = 0; i < num_entries ; i++) {
1142 init_lsa_String(&r->entries[i].account_name,
1143 entries[i].account_name);
1145 init_lsa_String(&r->entries[i].description,
1146 entries[i].description);
1148 init_lsa_String(&r->entries[i].full_name,
1149 entries[i].fullname);
1151 r->entries[i].rid = entries[i].rid;
1152 r->entries[i].acct_flags = entries[i].acct_flags;
1153 r->entries[i].idx = start_idx+i+1;
1156 return NT_STATUS_OK;
1159 /*******************************************************************
1160 inits a samr_DispInfoFull structure.
1161 ********************************************************************/
1163 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1164 struct samr_DispInfoFull *r,
1165 uint32_t num_entries,
1166 uint32_t start_idx,
1167 struct samr_displayentry *entries)
1169 uint32_t i;
1171 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1173 if (num_entries == 0) {
1174 return NT_STATUS_OK;
1177 r->count = num_entries;
1179 r->entries = talloc_zero_array(ctx, struct samr_DispEntryFull, num_entries);
1180 if (!r->entries) {
1181 return NT_STATUS_NO_MEMORY;
1184 for (i = 0; i < num_entries ; i++) {
1186 init_lsa_String(&r->entries[i].account_name,
1187 entries[i].account_name);
1189 init_lsa_String(&r->entries[i].description,
1190 entries[i].description);
1192 r->entries[i].rid = entries[i].rid;
1193 r->entries[i].acct_flags = entries[i].acct_flags;
1194 r->entries[i].idx = start_idx+i+1;
1197 return NT_STATUS_OK;
1200 /*******************************************************************
1201 inits a samr_DispInfoFullGroups structure.
1202 ********************************************************************/
1204 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1205 struct samr_DispInfoFullGroups *r,
1206 uint32_t num_entries,
1207 uint32_t start_idx,
1208 struct samr_displayentry *entries)
1210 uint32_t i;
1212 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1214 if (num_entries == 0) {
1215 return NT_STATUS_OK;
1218 r->count = num_entries;
1220 r->entries = talloc_zero_array(ctx, struct samr_DispEntryFullGroup, num_entries);
1221 if (!r->entries) {
1222 return NT_STATUS_NO_MEMORY;
1225 for (i = 0; i < num_entries ; i++) {
1227 init_lsa_String(&r->entries[i].account_name,
1228 entries[i].account_name);
1230 init_lsa_String(&r->entries[i].description,
1231 entries[i].description);
1233 r->entries[i].rid = entries[i].rid;
1234 r->entries[i].acct_flags = entries[i].acct_flags;
1235 r->entries[i].idx = start_idx+i+1;
1238 return NT_STATUS_OK;
1241 /*******************************************************************
1242 inits a samr_DispInfoAscii structure.
1243 ********************************************************************/
1245 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1246 struct samr_DispInfoAscii *r,
1247 uint32_t num_entries,
1248 uint32_t start_idx,
1249 struct samr_displayentry *entries)
1251 uint32_t i;
1253 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1255 if (num_entries == 0) {
1256 return NT_STATUS_OK;
1259 r->count = num_entries;
1261 r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1262 if (!r->entries) {
1263 return NT_STATUS_NO_MEMORY;
1266 for (i = 0; i < num_entries ; i++) {
1268 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1269 entries[i].account_name);
1271 r->entries[i].idx = start_idx+i+1;
1274 return NT_STATUS_OK;
1277 /*******************************************************************
1278 inits a samr_DispInfoAscii structure.
1279 ********************************************************************/
1281 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1282 struct samr_DispInfoAscii *r,
1283 uint32_t num_entries,
1284 uint32_t start_idx,
1285 struct samr_displayentry *entries)
1287 uint32_t i;
1289 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1291 if (num_entries == 0) {
1292 return NT_STATUS_OK;
1295 r->count = num_entries;
1297 r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1298 if (!r->entries) {
1299 return NT_STATUS_NO_MEMORY;
1302 for (i = 0; i < num_entries ; i++) {
1304 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1305 entries[i].account_name);
1307 r->entries[i].idx = start_idx+i+1;
1310 return NT_STATUS_OK;
1313 /*******************************************************************
1314 _samr_QueryDisplayInfo
1315 ********************************************************************/
1317 NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1318 struct samr_QueryDisplayInfo *r)
1320 NTSTATUS status;
1321 struct samr_domain_info *dinfo;
1322 uint32_t struct_size=0x20; /* W2K always reply that, client doesn't care */
1324 uint32_t max_entries = r->in.max_entries;
1326 union samr_DispInfo *disp_info = r->out.info;
1328 uint32_t temp_size=0;
1329 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1330 uint32_t num_account = 0;
1331 enum remote_arch_types ra_type = get_remote_arch();
1332 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1333 struct samr_displayentry *entries = NULL;
1335 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1337 dinfo = policy_handle_find(p, r->in.domain_handle,
1338 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1339 struct samr_domain_info, &status);
1340 if (!NT_STATUS_IS_OK(status)) {
1341 return status;
1344 if (sid_check_is_builtin(&dinfo->sid)) {
1345 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1346 return NT_STATUS_OK;
1350 * calculate how many entries we will return.
1351 * based on
1352 * - the number of entries the client asked
1353 * - our limit on that
1354 * - the starting point (enumeration context)
1355 * - the buffer size the client will accept
1359 * We are a lot more like W2K. Instead of reading the SAM
1360 * each time to find the records we need to send back,
1361 * we read it once and link that copy to the sam handle.
1362 * For large user list (over the MAX_SAM_ENTRIES)
1363 * it's a definitive win.
1364 * second point to notice: between enumerations
1365 * our sam is now the same as it's a snapshoot.
1366 * third point: got rid of the static SAM_USER_21 struct
1367 * no more intermediate.
1368 * con: it uses much more memory, as a full copy is stored
1369 * in memory.
1371 * If you want to change it, think twice and think
1372 * of the second point , that's really important.
1374 * JFM, 12/20/2001
1377 if ((r->in.level < 1) || (r->in.level > 5)) {
1378 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1379 (unsigned int)r->in.level ));
1380 return NT_STATUS_INVALID_INFO_CLASS;
1383 /* first limit the number of entries we will return */
1384 if (r->in.max_entries > max_sam_entries) {
1385 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1386 "entries, limiting to %d\n", r->in.max_entries,
1387 max_sam_entries));
1388 max_entries = max_sam_entries;
1391 /* calculate the size and limit on the number of entries we will
1392 * return */
1394 temp_size=max_entries*struct_size;
1396 if (temp_size > r->in.buf_size) {
1397 max_entries = MIN((r->in.buf_size / struct_size),max_entries);
1398 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1399 "only %d entries\n", max_entries));
1402 become_root();
1404 /* THe following done as ROOT. Don't return without unbecome_root(). */
1406 switch (r->in.level) {
1407 case 1:
1408 case 4:
1409 if (dinfo->disp_info->users == NULL) {
1410 dinfo->disp_info->users = pdb_search_users(
1411 dinfo->disp_info, ACB_NORMAL);
1412 if (dinfo->disp_info->users == NULL) {
1413 unbecome_root();
1414 return NT_STATUS_ACCESS_DENIED;
1416 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1417 (unsigned int)r->in.start_idx));
1418 } else {
1419 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1420 (unsigned int)r->in.start_idx));
1423 num_account = pdb_search_entries(dinfo->disp_info->users,
1424 r->in.start_idx, max_entries,
1425 &entries);
1426 break;
1427 case 2:
1428 if (dinfo->disp_info->machines == NULL) {
1429 dinfo->disp_info->machines = pdb_search_users(
1430 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1431 if (dinfo->disp_info->machines == NULL) {
1432 unbecome_root();
1433 return NT_STATUS_ACCESS_DENIED;
1435 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1436 (unsigned int)r->in.start_idx));
1437 } else {
1438 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1439 (unsigned int)r->in.start_idx));
1442 num_account = pdb_search_entries(dinfo->disp_info->machines,
1443 r->in.start_idx, max_entries,
1444 &entries);
1445 break;
1446 case 3:
1447 case 5:
1448 if (dinfo->disp_info->groups == NULL) {
1449 dinfo->disp_info->groups = pdb_search_groups(
1450 dinfo->disp_info);
1451 if (dinfo->disp_info->groups == NULL) {
1452 unbecome_root();
1453 return NT_STATUS_ACCESS_DENIED;
1455 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1456 (unsigned int)r->in.start_idx));
1457 } else {
1458 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1459 (unsigned int)r->in.start_idx));
1462 num_account = pdb_search_entries(dinfo->disp_info->groups,
1463 r->in.start_idx, max_entries,
1464 &entries);
1465 break;
1466 default:
1467 unbecome_root();
1468 smb_panic("info class changed");
1469 break;
1471 unbecome_root();
1474 /* Now create reply structure */
1475 switch (r->in.level) {
1476 case 1:
1477 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1478 num_account, r->in.start_idx,
1479 entries);
1480 break;
1481 case 2:
1482 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1483 num_account, r->in.start_idx,
1484 entries);
1485 break;
1486 case 3:
1487 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1488 num_account, r->in.start_idx,
1489 entries);
1490 break;
1491 case 4:
1492 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1493 num_account, r->in.start_idx,
1494 entries);
1495 break;
1496 case 5:
1497 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1498 num_account, r->in.start_idx,
1499 entries);
1500 break;
1501 default:
1502 smb_panic("info class changed");
1503 break;
1506 if (!NT_STATUS_IS_OK(disp_ret))
1507 return disp_ret;
1509 if (max_entries <= num_account) {
1510 status = STATUS_MORE_ENTRIES;
1511 } else {
1512 status = NT_STATUS_OK;
1515 /* Ensure we cache this enumeration. */
1516 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1518 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1520 *r->out.total_size = num_account * struct_size;
1521 *r->out.returned_size = num_account ? temp_size : 0;
1523 return status;
1526 /****************************************************************
1527 _samr_QueryDisplayInfo2
1528 ****************************************************************/
1530 NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1531 struct samr_QueryDisplayInfo2 *r)
1533 struct samr_QueryDisplayInfo q;
1535 q.in.domain_handle = r->in.domain_handle;
1536 q.in.level = r->in.level;
1537 q.in.start_idx = r->in.start_idx;
1538 q.in.max_entries = r->in.max_entries;
1539 q.in.buf_size = r->in.buf_size;
1541 q.out.total_size = r->out.total_size;
1542 q.out.returned_size = r->out.returned_size;
1543 q.out.info = r->out.info;
1545 return _samr_QueryDisplayInfo(p, &q);
1548 /****************************************************************
1549 _samr_QueryDisplayInfo3
1550 ****************************************************************/
1552 NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1553 struct samr_QueryDisplayInfo3 *r)
1555 struct samr_QueryDisplayInfo q;
1557 q.in.domain_handle = r->in.domain_handle;
1558 q.in.level = r->in.level;
1559 q.in.start_idx = r->in.start_idx;
1560 q.in.max_entries = r->in.max_entries;
1561 q.in.buf_size = r->in.buf_size;
1563 q.out.total_size = r->out.total_size;
1564 q.out.returned_size = r->out.returned_size;
1565 q.out.info = r->out.info;
1567 return _samr_QueryDisplayInfo(p, &q);
1570 /*******************************************************************
1571 _samr_QueryAliasInfo
1572 ********************************************************************/
1574 NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1575 struct samr_QueryAliasInfo *r)
1577 struct samr_alias_info *ainfo;
1578 struct acct_info *info;
1579 NTSTATUS status;
1580 union samr_AliasInfo *alias_info = NULL;
1581 const char *alias_name = NULL;
1582 const char *alias_description = NULL;
1584 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1586 ainfo = policy_handle_find(p, r->in.alias_handle,
1587 SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1588 struct samr_alias_info, &status);
1589 if (!NT_STATUS_IS_OK(status)) {
1590 return status;
1593 alias_info = talloc_zero(p->mem_ctx, union samr_AliasInfo);
1594 if (!alias_info) {
1595 return NT_STATUS_NO_MEMORY;
1598 info = talloc_zero(p->mem_ctx, struct acct_info);
1599 if (!info) {
1600 return NT_STATUS_NO_MEMORY;
1603 become_root();
1604 status = pdb_get_aliasinfo(&ainfo->sid, info);
1605 unbecome_root();
1607 if (!NT_STATUS_IS_OK(status)) {
1608 TALLOC_FREE(info);
1609 return status;
1612 alias_name = talloc_steal(r, info->acct_name);
1613 alias_description = talloc_steal(r, info->acct_desc);
1614 TALLOC_FREE(info);
1616 switch (r->in.level) {
1617 case ALIASINFOALL:
1618 alias_info->all.name.string = alias_name;
1619 alias_info->all.num_members = 1; /* ??? */
1620 alias_info->all.description.string = alias_description;
1621 break;
1622 case ALIASINFONAME:
1623 alias_info->name.string = alias_name;
1624 break;
1625 case ALIASINFODESCRIPTION:
1626 alias_info->description.string = alias_description;
1627 break;
1628 default:
1629 return NT_STATUS_INVALID_INFO_CLASS;
1632 *r->out.info = alias_info;
1634 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1636 return NT_STATUS_OK;
1639 /*******************************************************************
1640 _samr_LookupNames
1641 ********************************************************************/
1643 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1644 struct samr_LookupNames *r)
1646 struct samr_domain_info *dinfo;
1647 NTSTATUS status;
1648 uint32_t *rid;
1649 enum lsa_SidType *type;
1650 int i;
1651 int num_rids = r->in.num_names;
1652 struct samr_Ids rids, types;
1653 uint32_t num_mapped = 0;
1654 struct dom_sid_buf buf;
1656 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1658 dinfo = policy_handle_find(p, r->in.domain_handle,
1659 0 /* Don't know the acc_bits yet */, NULL,
1660 struct samr_domain_info, &status);
1661 if (!NT_STATUS_IS_OK(status)) {
1662 return status;
1665 if (num_rids > MAX_SAM_ENTRIES) {
1666 num_rids = MAX_SAM_ENTRIES;
1667 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1670 rid = talloc_array(p->mem_ctx, uint32_t, num_rids);
1671 NT_STATUS_HAVE_NO_MEMORY(rid);
1673 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1674 NT_STATUS_HAVE_NO_MEMORY(type);
1676 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1677 dom_sid_str_buf(&dinfo->sid, &buf)));
1679 for (i = 0; i < num_rids; i++) {
1681 status = NT_STATUS_NONE_MAPPED;
1682 type[i] = SID_NAME_UNKNOWN;
1684 rid[i] = 0xffffffff;
1686 if (sid_check_is_builtin(&dinfo->sid)) {
1687 if (lookup_builtin_name(r->in.names[i].string,
1688 &rid[i]))
1690 type[i] = SID_NAME_ALIAS;
1692 } else {
1693 lookup_global_sam_name(r->in.names[i].string, 0,
1694 &rid[i], &type[i]);
1697 if (type[i] != SID_NAME_UNKNOWN) {
1698 num_mapped++;
1702 if (num_mapped == num_rids) {
1703 status = NT_STATUS_OK;
1704 } else if (num_mapped == 0) {
1705 status = NT_STATUS_NONE_MAPPED;
1706 } else {
1707 status = STATUS_SOME_UNMAPPED;
1710 rids.count = num_rids;
1711 rids.ids = rid;
1713 types.count = num_rids;
1714 types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1715 NT_STATUS_HAVE_NO_MEMORY(type);
1716 for (i = 0; i < num_rids; i++) {
1717 types.ids[i] = (type[i] & 0xffffffff);
1720 *r->out.rids = rids;
1721 *r->out.types = types;
1723 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1725 return status;
1728 /****************************************************************
1729 _samr_ChangePasswordUser.
1731 So old it is just not worth implementing
1732 because it does not supply a plaintext and so we can't do password
1733 complexity checking and cannot update other services that use a
1734 plaintext password via passwd chat/pam password change/ldap password
1735 sync.
1736 ****************************************************************/
1738 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1739 struct samr_ChangePasswordUser *r)
1741 return NT_STATUS_NOT_IMPLEMENTED;
1744 /*******************************************************************
1745 _samr_ChangePasswordUser2
1746 ********************************************************************/
1748 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1749 struct samr_ChangePasswordUser2 *r)
1751 NTSTATUS status;
1752 char *user_name = NULL;
1753 char *rhost;
1754 const char *wks = NULL;
1756 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1758 if (!r->in.account->string) {
1759 return NT_STATUS_INVALID_PARAMETER;
1761 if (r->in.server && r->in.server->string) {
1762 wks = r->in.server->string;
1765 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1768 * Pass the user through the NT -> unix user mapping
1769 * function.
1772 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1773 if (!user_name) {
1774 return NT_STATUS_NO_MEMORY;
1777 rhost = tsocket_address_inet_addr_string(p->remote_address,
1778 talloc_tos());
1779 if (rhost == NULL) {
1780 return NT_STATUS_NO_MEMORY;
1784 * UNIX username case mangling not required, pass_oem_change
1785 * is case insensitive.
1788 status = pass_oem_change(user_name,
1789 rhost,
1790 r->in.lm_password->data,
1791 r->in.lm_verifier->hash,
1792 r->in.nt_password->data,
1793 r->in.nt_verifier->hash,
1794 NULL);
1796 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1798 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1799 return NT_STATUS_WRONG_PASSWORD;
1802 return status;
1805 /****************************************************************
1806 _samr_OemChangePasswordUser2
1807 ****************************************************************/
1809 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1810 struct samr_OemChangePasswordUser2 *r)
1812 NTSTATUS status;
1813 char *user_name = NULL;
1814 const char *wks = NULL;
1815 char *rhost;
1817 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1819 if (!r->in.account->string) {
1820 return NT_STATUS_INVALID_PARAMETER;
1822 if (r->in.server && r->in.server->string) {
1823 wks = r->in.server->string;
1826 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1829 * Pass the user through the NT -> unix user mapping
1830 * function.
1833 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1834 if (!user_name) {
1835 return NT_STATUS_NO_MEMORY;
1839 * UNIX username case mangling not required, pass_oem_change
1840 * is case insensitive.
1843 if (!r->in.hash || !r->in.password) {
1844 return NT_STATUS_INVALID_PARAMETER;
1847 rhost = tsocket_address_inet_addr_string(p->remote_address,
1848 talloc_tos());
1849 if (rhost == NULL) {
1850 return NT_STATUS_NO_MEMORY;
1853 status = pass_oem_change(user_name,
1854 rhost,
1855 r->in.password->data,
1856 r->in.hash->hash,
1859 NULL);
1861 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1862 return NT_STATUS_WRONG_PASSWORD;
1865 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1867 return status;
1870 /*******************************************************************
1871 _samr_ChangePasswordUser3
1872 ********************************************************************/
1874 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
1875 struct samr_ChangePasswordUser3 *r)
1877 NTSTATUS status;
1878 char *user_name = NULL;
1879 const char *wks = NULL;
1880 enum samPwdChangeReason reject_reason;
1881 struct samr_DomInfo1 *dominfo = NULL;
1882 struct userPwdChangeFailureInformation *reject = NULL;
1883 uint32_t tmp;
1884 char *rhost;
1886 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1888 if (!r->in.account->string) {
1889 return NT_STATUS_INVALID_PARAMETER;
1891 if (r->in.server && r->in.server->string) {
1892 wks = r->in.server->string;
1895 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1898 * Pass the user through the NT -> unix user mapping
1899 * function.
1902 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1903 if (!user_name) {
1904 return NT_STATUS_NO_MEMORY;
1907 rhost = tsocket_address_inet_addr_string(p->remote_address,
1908 talloc_tos());
1909 if (rhost == NULL) {
1910 return NT_STATUS_NO_MEMORY;
1914 * UNIX username case mangling not required, pass_oem_change
1915 * is case insensitive.
1918 status = pass_oem_change(user_name,
1919 rhost,
1920 r->in.lm_password->data,
1921 r->in.lm_verifier->hash,
1922 r->in.nt_password->data,
1923 r->in.nt_verifier->hash,
1924 &reject_reason);
1925 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1926 return NT_STATUS_WRONG_PASSWORD;
1929 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1930 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1932 time_t u_expire, u_min_age;
1933 uint32_t account_policy_temp;
1935 dominfo = talloc_zero(p->mem_ctx, struct samr_DomInfo1);
1936 if (!dominfo) {
1937 return NT_STATUS_NO_MEMORY;
1940 reject = talloc_zero(p->mem_ctx,
1941 struct userPwdChangeFailureInformation);
1942 if (!reject) {
1943 return NT_STATUS_NO_MEMORY;
1946 become_root();
1948 /* AS ROOT !!! */
1950 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
1951 dominfo->min_password_length = tmp;
1953 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
1954 dominfo->password_history_length = tmp;
1956 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
1957 &dominfo->password_properties);
1959 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
1960 u_expire = account_policy_temp;
1962 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
1963 u_min_age = account_policy_temp;
1965 /* !AS ROOT */
1967 unbecome_root();
1969 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
1970 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
1972 if (lp_check_password_script(talloc_tos())
1973 && *lp_check_password_script(talloc_tos())) {
1974 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
1977 reject->extendedFailureReason = reject_reason;
1979 *r->out.dominfo = dominfo;
1980 *r->out.reject = reject;
1983 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1985 return status;
1988 /*******************************************************************
1989 makes a SAMR_R_LOOKUP_RIDS structure.
1990 ********************************************************************/
1992 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32_t num_names,
1993 const char **names,
1994 struct lsa_String **lsa_name_array_p)
1996 struct lsa_String *lsa_name_array = NULL;
1997 uint32_t i;
1999 *lsa_name_array_p = NULL;
2001 if (num_names != 0) {
2002 lsa_name_array = talloc_zero_array(ctx, struct lsa_String, num_names);
2003 if (!lsa_name_array) {
2004 return false;
2008 for (i = 0; i < num_names; i++) {
2009 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2010 init_lsa_String(&lsa_name_array[i], names[i]);
2013 *lsa_name_array_p = lsa_name_array;
2015 return true;
2018 /*******************************************************************
2019 _samr_LookupRids
2020 ********************************************************************/
2022 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2023 struct samr_LookupRids *r)
2025 struct samr_domain_info *dinfo;
2026 NTSTATUS status;
2027 const char **names;
2028 enum lsa_SidType *attrs = NULL;
2029 uint32_t *wire_attrs = NULL;
2030 int num_rids = (int)r->in.num_rids;
2031 int i;
2032 struct lsa_Strings names_array;
2033 struct samr_Ids types_array;
2034 struct lsa_String *lsa_names = NULL;
2036 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2038 dinfo = policy_handle_find(p, r->in.domain_handle,
2039 0 /* Don't know the acc_bits yet */, NULL,
2040 struct samr_domain_info, &status);
2041 if (!NT_STATUS_IS_OK(status)) {
2042 return status;
2045 if (num_rids > 1000) {
2046 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2047 "to samba4 idl this is not possible\n", num_rids));
2048 return NT_STATUS_UNSUCCESSFUL;
2051 if (num_rids) {
2052 names = talloc_zero_array(p->mem_ctx, const char *, num_rids);
2053 attrs = talloc_zero_array(p->mem_ctx, enum lsa_SidType, num_rids);
2054 wire_attrs = talloc_zero_array(p->mem_ctx, uint32_t, num_rids);
2056 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2057 return NT_STATUS_NO_MEMORY;
2058 } else {
2059 names = NULL;
2060 attrs = NULL;
2061 wire_attrs = NULL;
2064 become_root(); /* lookup_sid can require root privs */
2065 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2066 names, attrs);
2067 unbecome_root();
2069 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2070 status = NT_STATUS_OK;
2073 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2074 &lsa_names)) {
2075 return NT_STATUS_NO_MEMORY;
2078 /* Convert from enum lsa_SidType to uint32_t for wire format. */
2079 for (i = 0; i < num_rids; i++) {
2080 wire_attrs[i] = (uint32_t)attrs[i];
2083 names_array.count = num_rids;
2084 names_array.names = lsa_names;
2086 types_array.count = num_rids;
2087 types_array.ids = wire_attrs;
2089 *r->out.names = names_array;
2090 *r->out.types = types_array;
2092 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2094 return status;
2097 /*******************************************************************
2098 _samr_OpenUser
2099 ********************************************************************/
2101 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2102 struct samr_OpenUser *r)
2104 struct samu *sampass=NULL;
2105 struct dom_sid sid;
2106 struct samr_domain_info *dinfo;
2107 struct samr_user_info *uinfo;
2108 struct security_descriptor *psd = NULL;
2109 uint32_t acc_granted;
2110 uint32_t des_access = r->in.access_mask;
2111 uint32_t extra_access = 0;
2112 size_t sd_size;
2113 bool ret;
2114 NTSTATUS nt_status;
2116 /* These two privileges, if != SEC_PRIV_INVALID, indicate
2117 * privileges that the user must have to complete this
2118 * operation in defience of the fixed ACL */
2119 enum sec_privilege needed_priv_1, needed_priv_2;
2120 NTSTATUS status;
2122 dinfo = policy_handle_find(p, r->in.domain_handle,
2123 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2124 struct samr_domain_info, &status);
2125 if (!NT_STATUS_IS_OK(status)) {
2126 return status;
2129 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2130 return NT_STATUS_NO_MEMORY;
2133 /* append the user's RID to it */
2135 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2136 return NT_STATUS_NO_SUCH_USER;
2138 /* check if access can be granted as requested by client. */
2139 map_max_allowed_access(p->session_info->security_token,
2140 p->session_info->unix_token,
2141 &des_access);
2143 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2144 se_map_generic(&des_access, &usr_generic_mapping);
2147 * Get the sampass first as we need to check privileges
2148 * based on what kind of user object this is.
2149 * But don't reveal info too early if it didn't exist.
2152 become_root();
2153 ret=pdb_getsampwsid(sampass, &sid);
2154 unbecome_root();
2156 needed_priv_1 = SEC_PRIV_INVALID;
2157 needed_priv_2 = SEC_PRIV_INVALID;
2159 * We do the override access checks on *open*, not at
2160 * SetUserInfo time.
2162 if (ret) {
2163 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2165 if (acb_info & ACB_WSTRUST) {
2167 * SeMachineAccount is needed to add
2168 * GENERIC_RIGHTS_USER_WRITE to a machine
2169 * account.
2171 needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2173 if (acb_info & ACB_NORMAL) {
2175 * SeAddUsers is needed to add
2176 * GENERIC_RIGHTS_USER_WRITE to a normal
2177 * account.
2179 needed_priv_1 = SEC_PRIV_ADD_USERS;
2182 * Cheat - we have not set a specific privilege for
2183 * server (BDC) or domain trust account, so allow
2184 * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2185 * DOMAIN_RID_ADMINS.
2187 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2188 if (lp_enable_privileges() && nt_token_check_domain_rid(p->session_info->security_token,
2189 DOMAIN_RID_ADMINS)) {
2190 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2191 extra_access = GENERIC_RIGHTS_USER_WRITE;
2192 DEBUG(4,("_samr_OpenUser: Allowing "
2193 "GENERIC_RIGHTS_USER_WRITE for "
2194 "rid admins\n"));
2199 TALLOC_FREE(sampass);
2201 nt_status = access_check_object(psd, p->session_info->security_token,
2202 needed_priv_1, needed_priv_2,
2203 GENERIC_RIGHTS_USER_WRITE, des_access,
2204 &acc_granted, "_samr_OpenUser");
2206 if ( !NT_STATUS_IS_OK(nt_status) )
2207 return nt_status;
2209 /* check that the SID exists in our domain. */
2210 if (ret == False) {
2211 return NT_STATUS_NO_SUCH_USER;
2214 /* If we did the rid admins hack above, allow access. */
2215 acc_granted |= extra_access;
2217 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2218 struct samr_user_info, &nt_status);
2219 if (!NT_STATUS_IS_OK(nt_status)) {
2220 return nt_status;
2222 uinfo->sid = sid;
2224 return NT_STATUS_OK;
2227 /*************************************************************************
2228 *************************************************************************/
2230 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2231 DATA_BLOB *blob,
2232 struct lsa_BinaryString **_r)
2234 struct lsa_BinaryString *r;
2236 if (!blob || !_r) {
2237 return NT_STATUS_INVALID_PARAMETER;
2240 r = talloc_zero(mem_ctx, struct lsa_BinaryString);
2241 if (!r) {
2242 return NT_STATUS_NO_MEMORY;
2245 r->array = talloc_zero_array(mem_ctx, uint16_t, blob->length/2);
2246 if (!r->array) {
2247 return NT_STATUS_NO_MEMORY;
2249 memcpy(r->array, blob->data, blob->length);
2250 r->size = blob->length;
2251 r->length = blob->length;
2253 if (!r->array) {
2254 return NT_STATUS_NO_MEMORY;
2257 *_r = r;
2259 return NT_STATUS_OK;
2262 /*************************************************************************
2263 *************************************************************************/
2265 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2266 struct samu *pw)
2268 struct samr_LogonHours hours;
2269 const int units_per_week = 168;
2271 ZERO_STRUCT(hours);
2272 hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2273 if (!hours.bits) {
2274 return hours;
2277 hours.units_per_week = units_per_week;
2278 memset(hours.bits, 0xFF, units_per_week);
2280 if (pdb_get_hours(pw)) {
2281 memcpy(hours.bits, pdb_get_hours(pw),
2282 MIN(pdb_get_hours_len(pw), units_per_week));
2285 return hours;
2288 /*************************************************************************
2289 get_user_info_1.
2290 *************************************************************************/
2292 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2293 struct samr_UserInfo1 *r,
2294 struct samu *pw,
2295 struct dom_sid *domain_sid)
2297 const struct dom_sid *sid_group;
2298 uint32_t primary_gid;
2300 become_root();
2301 sid_group = pdb_get_group_sid(pw);
2302 unbecome_root();
2304 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2305 struct dom_sid_buf buf1, buf2;
2307 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2308 "which conflicts with the domain sid %s. Failing operation.\n",
2309 pdb_get_username(pw),
2310 dom_sid_str_buf(sid_group, &buf1),
2311 dom_sid_str_buf(domain_sid, &buf2)));
2312 return NT_STATUS_UNSUCCESSFUL;
2315 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2316 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2317 r->primary_gid = primary_gid;
2318 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2319 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2321 return NT_STATUS_OK;
2324 /*************************************************************************
2325 get_user_info_2.
2326 *************************************************************************/
2328 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2329 struct samr_UserInfo2 *r,
2330 struct samu *pw)
2332 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2333 r->reserved.string = NULL;
2334 r->country_code = pdb_get_country_code(pw);
2335 r->code_page = pdb_get_code_page(pw);
2337 return NT_STATUS_OK;
2340 /*************************************************************************
2341 get_user_info_3.
2342 *************************************************************************/
2344 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2345 struct samr_UserInfo3 *r,
2346 struct samu *pw,
2347 struct dom_sid *domain_sid)
2349 const struct dom_sid *sid_user, *sid_group;
2350 uint32_t rid, primary_gid;
2351 struct dom_sid_buf buf1, buf2;
2353 sid_user = pdb_get_user_sid(pw);
2355 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2356 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2357 "the domain sid %s. Failing operation.\n",
2358 pdb_get_username(pw),
2359 dom_sid_str_buf(sid_user, &buf1),
2360 dom_sid_str_buf(domain_sid, &buf2)));
2361 return NT_STATUS_UNSUCCESSFUL;
2364 become_root();
2365 sid_group = pdb_get_group_sid(pw);
2366 unbecome_root();
2368 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2369 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2370 "which conflicts with the domain sid %s. Failing operation.\n",
2371 pdb_get_username(pw),
2372 dom_sid_str_buf(sid_group, &buf1),
2373 dom_sid_str_buf(domain_sid, &buf2)));
2374 return NT_STATUS_UNSUCCESSFUL;
2377 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2378 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2379 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2380 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2381 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2383 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2384 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2385 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2386 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2387 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2388 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2389 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2391 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2392 r->rid = rid;
2393 r->primary_gid = primary_gid;
2394 r->acct_flags = pdb_get_acct_ctrl(pw);
2395 r->bad_password_count = pdb_get_bad_password_count(pw);
2396 r->logon_count = pdb_get_logon_count(pw);
2398 return NT_STATUS_OK;
2401 /*************************************************************************
2402 get_user_info_4.
2403 *************************************************************************/
2405 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2406 struct samr_UserInfo4 *r,
2407 struct samu *pw)
2409 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2411 return NT_STATUS_OK;
2414 /*************************************************************************
2415 get_user_info_5.
2416 *************************************************************************/
2418 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2419 struct samr_UserInfo5 *r,
2420 struct samu *pw,
2421 struct dom_sid *domain_sid)
2423 const struct dom_sid *sid_user, *sid_group;
2424 uint32_t rid, primary_gid;
2425 struct dom_sid_buf buf1, buf2;
2427 sid_user = pdb_get_user_sid(pw);
2429 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2430 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2431 "the domain sid %s. Failing operation.\n",
2432 pdb_get_username(pw),
2433 dom_sid_str_buf(sid_user, &buf1),
2434 dom_sid_str_buf(domain_sid, &buf2)));
2435 return NT_STATUS_UNSUCCESSFUL;
2438 become_root();
2439 sid_group = pdb_get_group_sid(pw);
2440 unbecome_root();
2442 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2443 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2444 "which conflicts with the domain sid %s. Failing operation.\n",
2445 pdb_get_username(pw),
2446 dom_sid_str_buf(sid_group, &buf1),
2447 dom_sid_str_buf(domain_sid, &buf2)));
2448 return NT_STATUS_UNSUCCESSFUL;
2451 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2452 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2453 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2454 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2456 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2457 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2458 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2459 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2460 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2461 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2462 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2463 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2465 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2466 r->rid = rid;
2467 r->primary_gid = primary_gid;
2468 r->acct_flags = pdb_get_acct_ctrl(pw);
2469 r->bad_password_count = pdb_get_bad_password_count(pw);
2470 r->logon_count = pdb_get_logon_count(pw);
2472 return NT_STATUS_OK;
2475 /*************************************************************************
2476 get_user_info_6.
2477 *************************************************************************/
2479 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2480 struct samr_UserInfo6 *r,
2481 struct samu *pw)
2483 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2484 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2486 return NT_STATUS_OK;
2489 /*************************************************************************
2490 get_user_info_7. Safe. Only gives out account_name.
2491 *************************************************************************/
2493 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2494 struct samr_UserInfo7 *r,
2495 struct samu *smbpass)
2497 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2498 if (!r->account_name.string) {
2499 return NT_STATUS_NO_MEMORY;
2502 return NT_STATUS_OK;
2505 /*************************************************************************
2506 get_user_info_8.
2507 *************************************************************************/
2509 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2510 struct samr_UserInfo8 *r,
2511 struct samu *pw)
2513 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2515 return NT_STATUS_OK;
2518 /*************************************************************************
2519 get_user_info_9. Only gives out primary group SID.
2520 *************************************************************************/
2522 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2523 struct samr_UserInfo9 *r,
2524 struct samu *smbpass)
2526 r->primary_gid = pdb_get_group_rid(smbpass);
2528 return NT_STATUS_OK;
2531 /*************************************************************************
2532 get_user_info_10.
2533 *************************************************************************/
2535 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2536 struct samr_UserInfo10 *r,
2537 struct samu *pw)
2539 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2540 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2542 return NT_STATUS_OK;
2545 /*************************************************************************
2546 get_user_info_11.
2547 *************************************************************************/
2549 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2550 struct samr_UserInfo11 *r,
2551 struct samu *pw)
2553 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2555 return NT_STATUS_OK;
2558 /*************************************************************************
2559 get_user_info_12.
2560 *************************************************************************/
2562 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2563 struct samr_UserInfo12 *r,
2564 struct samu *pw)
2566 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2568 return NT_STATUS_OK;
2571 /*************************************************************************
2572 get_user_info_13.
2573 *************************************************************************/
2575 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2576 struct samr_UserInfo13 *r,
2577 struct samu *pw)
2579 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2581 return NT_STATUS_OK;
2584 /*************************************************************************
2585 get_user_info_14.
2586 *************************************************************************/
2588 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2589 struct samr_UserInfo14 *r,
2590 struct samu *pw)
2592 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2594 return NT_STATUS_OK;
2597 /*************************************************************************
2598 get_user_info_16. Safe. Only gives out acb bits.
2599 *************************************************************************/
2601 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2602 struct samr_UserInfo16 *r,
2603 struct samu *smbpass)
2605 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2607 return NT_STATUS_OK;
2610 /*************************************************************************
2611 get_user_info_17.
2612 *************************************************************************/
2614 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2615 struct samr_UserInfo17 *r,
2616 struct samu *pw)
2618 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2620 return NT_STATUS_OK;
2623 /*************************************************************************
2624 get_user_info_18. OK - this is the killer as it gives out password info.
2625 Ensure that this is only allowed on an encrypted connection with a root
2626 user. JRA.
2627 *************************************************************************/
2629 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2630 TALLOC_CTX *mem_ctx,
2631 struct samr_UserInfo18 *r,
2632 struct dom_sid *user_sid)
2634 struct samu *smbpass=NULL;
2635 bool ret;
2636 const uint8_t *nt_pass = NULL;
2637 const uint8_t *lm_pass = NULL;
2639 ZERO_STRUCTP(r);
2641 if (p->transport != NCALRPC) {
2642 return NT_STATUS_INVALID_INFO_CLASS;
2645 if (!security_token_is_system(p->session_info->security_token)) {
2646 return NT_STATUS_ACCESS_DENIED;
2650 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2653 if ( !(smbpass = samu_new( mem_ctx )) ) {
2654 return NT_STATUS_NO_MEMORY;
2657 ret = pdb_getsampwsid(smbpass, user_sid);
2659 if (ret == False) {
2660 struct dom_sid_buf buf;
2661 DEBUG(4, ("User %s not found\n",
2662 dom_sid_str_buf(user_sid, &buf)));
2663 TALLOC_FREE(smbpass);
2664 return root_mode() ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2667 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2669 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2670 TALLOC_FREE(smbpass);
2671 return NT_STATUS_ACCOUNT_DISABLED;
2674 lm_pass = pdb_get_lanman_passwd(smbpass);
2675 if (lm_pass != NULL) {
2676 memcpy(r->lm_pwd.hash, lm_pass, 16);
2677 r->lm_pwd_active = true;
2680 nt_pass = pdb_get_nt_passwd(smbpass);
2681 if (nt_pass != NULL) {
2682 memcpy(r->nt_pwd.hash, nt_pass, 16);
2683 r->nt_pwd_active = true;
2685 r->password_expired = 0; /* FIXME */
2687 TALLOC_FREE(smbpass);
2689 return NT_STATUS_OK;
2692 /*************************************************************************
2693 get_user_info_20
2694 *************************************************************************/
2696 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2697 struct samr_UserInfo20 *r,
2698 struct samu *sampass)
2700 const char *munged_dial = NULL;
2701 DATA_BLOB blob;
2702 NTSTATUS status;
2703 struct lsa_BinaryString *parameters = NULL;
2705 ZERO_STRUCTP(r);
2707 munged_dial = pdb_get_munged_dial(sampass);
2709 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2710 munged_dial, (int)strlen(munged_dial)));
2712 if (munged_dial) {
2713 blob = base64_decode_data_blob(munged_dial);
2714 } else {
2715 blob = data_blob_string_const_null("");
2718 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2719 data_blob_free(&blob);
2720 if (!NT_STATUS_IS_OK(status)) {
2721 return status;
2724 r->parameters = *parameters;
2726 return NT_STATUS_OK;
2730 /*************************************************************************
2731 get_user_info_21
2732 *************************************************************************/
2734 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2735 struct samr_UserInfo21 *r,
2736 struct samu *pw,
2737 struct dom_sid *domain_sid,
2738 uint32_t acc_granted)
2740 NTSTATUS status;
2741 const struct dom_sid *sid_user, *sid_group;
2742 uint32_t rid, primary_gid;
2743 NTTIME force_password_change;
2744 time_t must_change_time;
2745 struct lsa_BinaryString *parameters = NULL;
2746 const char *munged_dial = NULL;
2747 DATA_BLOB blob;
2748 struct dom_sid_buf buf1, buf2;
2750 ZERO_STRUCTP(r);
2752 sid_user = pdb_get_user_sid(pw);
2754 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2755 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2756 "the domain sid %s. Failing operation.\n",
2757 pdb_get_username(pw),
2758 dom_sid_str_buf(sid_user, &buf1),
2759 dom_sid_str_buf(domain_sid, &buf2)));
2760 return NT_STATUS_UNSUCCESSFUL;
2763 become_root();
2764 sid_group = pdb_get_group_sid(pw);
2765 unbecome_root();
2767 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2768 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2769 "which conflicts with the domain sid %s. Failing operation.\n",
2770 pdb_get_username(pw),
2771 dom_sid_str_buf(sid_group, &buf1),
2772 dom_sid_str_buf(domain_sid, &buf2)));
2773 return NT_STATUS_UNSUCCESSFUL;
2776 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2777 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2778 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2779 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2780 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2782 must_change_time = pdb_get_pass_must_change_time(pw);
2783 if (pdb_is_password_change_time_max(must_change_time)) {
2784 unix_to_nt_time_abs(&force_password_change, must_change_time);
2785 } else {
2786 unix_to_nt_time(&force_password_change, must_change_time);
2789 munged_dial = pdb_get_munged_dial(pw);
2790 if (munged_dial) {
2791 blob = base64_decode_data_blob(munged_dial);
2792 } else {
2793 blob = data_blob_string_const_null("");
2796 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2797 data_blob_free(&blob);
2798 if (!NT_STATUS_IS_OK(status)) {
2799 return status;
2802 r->force_password_change = force_password_change;
2804 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2805 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2806 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2807 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2808 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2809 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2810 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2811 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2812 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2814 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2815 r->parameters = *parameters;
2816 r->rid = rid;
2817 r->primary_gid = primary_gid;
2818 r->acct_flags = pdb_get_acct_ctrl(pw);
2819 r->bad_password_count = pdb_get_bad_password_count(pw);
2820 r->logon_count = pdb_get_logon_count(pw);
2821 r->fields_present = pdb_build_fields_present(pw);
2822 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2823 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2824 r->country_code = pdb_get_country_code(pw);
2825 r->code_page = pdb_get_code_page(pw);
2826 r->lm_password_set = 0;
2827 r->nt_password_set = 0;
2829 #if 0
2832 Look at a user on a real NT4 PDC with usrmgr, press
2833 'ok'. Then you will see that fields_present is set to
2834 0x08f827fa. Look at the user immediately after that again,
2835 and you will see that 0x00fffff is returned. This solves
2836 the problem that you get access denied after having looked
2837 at the user.
2838 -- Volker
2841 #endif
2844 return NT_STATUS_OK;
2847 /*******************************************************************
2848 _samr_QueryUserInfo
2849 ********************************************************************/
2851 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
2852 struct samr_QueryUserInfo *r)
2854 NTSTATUS status;
2855 union samr_UserInfo *user_info = NULL;
2856 struct samr_user_info *uinfo;
2857 struct dom_sid domain_sid;
2858 uint32_t rid;
2859 bool ret = false;
2860 struct samu *pwd = NULL;
2861 uint32_t acc_required, acc_granted;
2862 struct dom_sid_buf buf;
2864 switch (r->in.level) {
2865 case 1: /* UserGeneralInformation */
2866 /* USER_READ_GENERAL */
2867 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2868 break;
2869 case 2: /* UserPreferencesInformation */
2870 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2871 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2872 SAMR_USER_ACCESS_GET_NAME_ETC;
2873 break;
2874 case 3: /* UserLogonInformation */
2875 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2876 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2877 SAMR_USER_ACCESS_GET_LOCALE |
2878 SAMR_USER_ACCESS_GET_LOGONINFO |
2879 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2880 break;
2881 case 4: /* UserLogonHoursInformation */
2882 /* USER_READ_LOGON */
2883 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2884 break;
2885 case 5: /* UserAccountInformation */
2886 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2887 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2888 SAMR_USER_ACCESS_GET_LOCALE |
2889 SAMR_USER_ACCESS_GET_LOGONINFO |
2890 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2891 break;
2892 case 6: /* UserNameInformation */
2893 case 7: /* UserAccountNameInformation */
2894 case 8: /* UserFullNameInformation */
2895 case 9: /* UserPrimaryGroupInformation */
2896 case 13: /* UserAdminCommentInformation */
2897 /* USER_READ_GENERAL */
2898 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2899 break;
2900 case 10: /* UserHomeInformation */
2901 case 11: /* UserScriptInformation */
2902 case 12: /* UserProfileInformation */
2903 case 14: /* UserWorkStationsInformation */
2904 /* USER_READ_LOGON */
2905 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2906 break;
2907 case 16: /* UserControlInformation */
2908 case 17: /* UserExpiresInformation */
2909 case 20: /* UserParametersInformation */
2910 /* USER_READ_ACCOUNT */
2911 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2912 break;
2913 case 21: /* UserAllInformation */
2914 /* FIXME! - gd */
2915 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2916 break;
2917 case 18: /* UserInternal1Information */
2918 /* FIXME! - gd */
2919 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2920 break;
2921 case 23: /* UserInternal4Information */
2922 case 24: /* UserInternal4InformationNew */
2923 case 25: /* UserInternal4InformationNew */
2924 case 26: /* UserInternal5InformationNew */
2925 default:
2926 return NT_STATUS_INVALID_INFO_CLASS;
2927 break;
2930 uinfo = policy_handle_find(p, r->in.user_handle,
2931 acc_required, &acc_granted,
2932 struct samr_user_info, &status);
2933 if (!NT_STATUS_IS_OK(status)) {
2934 return status;
2937 domain_sid = uinfo->sid;
2939 sid_split_rid(&domain_sid, &rid);
2941 if (!sid_check_is_in_our_sam(&uinfo->sid))
2942 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2944 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2945 dom_sid_str_buf(&uinfo->sid, &buf)));
2947 user_info = talloc_zero(p->mem_ctx, union samr_UserInfo);
2948 if (!user_info) {
2949 return NT_STATUS_NO_MEMORY;
2952 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2954 if (!(pwd = samu_new(p->mem_ctx))) {
2955 return NT_STATUS_NO_MEMORY;
2958 become_root();
2959 ret = pdb_getsampwsid(pwd, &uinfo->sid);
2960 unbecome_root();
2962 if (ret == false) {
2963 DEBUG(4,("User %s not found\n",
2964 dom_sid_str_buf(&uinfo->sid, &buf)));
2965 TALLOC_FREE(pwd);
2966 return NT_STATUS_NO_SUCH_USER;
2969 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2971 samr_clear_sam_passwd(pwd);
2973 switch (r->in.level) {
2974 case 1:
2975 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
2976 break;
2977 case 2:
2978 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
2979 break;
2980 case 3:
2981 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
2982 break;
2983 case 4:
2984 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
2985 break;
2986 case 5:
2987 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2988 break;
2989 case 6:
2990 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
2991 break;
2992 case 7:
2993 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2994 break;
2995 case 8:
2996 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
2997 break;
2998 case 9:
2999 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3000 break;
3001 case 10:
3002 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3003 break;
3004 case 11:
3005 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3006 break;
3007 case 12:
3008 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3009 break;
3010 case 13:
3011 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3012 break;
3013 case 14:
3014 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3015 break;
3016 case 16:
3017 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3018 break;
3019 case 17:
3020 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3021 break;
3022 case 18:
3023 /* level 18 is special */
3024 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3025 &uinfo->sid);
3026 break;
3027 case 20:
3028 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3029 break;
3030 case 21:
3031 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3032 break;
3033 default:
3034 status = NT_STATUS_INVALID_INFO_CLASS;
3035 break;
3038 if (!NT_STATUS_IS_OK(status)) {
3039 goto done;
3042 *r->out.info = user_info;
3044 done:
3045 TALLOC_FREE(pwd);
3047 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3049 return status;
3052 /****************************************************************
3053 ****************************************************************/
3055 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3056 struct samr_QueryUserInfo2 *r)
3058 struct samr_QueryUserInfo u;
3060 u.in.user_handle = r->in.user_handle;
3061 u.in.level = r->in.level;
3062 u.out.info = r->out.info;
3064 return _samr_QueryUserInfo(p, &u);
3067 /*******************************************************************
3068 _samr_GetGroupsForUser
3069 ********************************************************************/
3071 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3072 struct samr_GetGroupsForUser *r)
3074 struct samr_user_info *uinfo;
3075 struct samu *sam_pass=NULL;
3076 struct dom_sid *sids;
3077 struct samr_RidWithAttribute dom_gid;
3078 struct samr_RidWithAttribute *gids = NULL;
3079 uint32_t primary_group_rid;
3080 uint32_t num_groups = 0;
3081 gid_t *unix_gids;
3082 uint32_t i, num_gids;
3083 bool ret;
3084 NTSTATUS result;
3085 bool success = False;
3086 struct dom_sid_buf buf;
3088 struct samr_RidWithAttributeArray *rids = NULL;
3091 * from the SID in the request:
3092 * we should send back the list of DOMAIN GROUPS
3093 * the user is a member of
3095 * and only the DOMAIN GROUPS
3096 * no ALIASES !!! neither aliases of the domain
3097 * nor aliases of the builtin SID
3099 * JFM, 12/2/2001
3102 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3104 uinfo = policy_handle_find(p, r->in.user_handle,
3105 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3106 struct samr_user_info, &result);
3107 if (!NT_STATUS_IS_OK(result)) {
3108 return result;
3111 rids = talloc_zero(p->mem_ctx, struct samr_RidWithAttributeArray);
3112 if (!rids) {
3113 return NT_STATUS_NO_MEMORY;
3116 if (!sid_check_is_in_our_sam(&uinfo->sid))
3117 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3119 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3120 return NT_STATUS_NO_MEMORY;
3123 become_root();
3124 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3125 unbecome_root();
3127 if (!ret) {
3128 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3129 dom_sid_str_buf(&uinfo->sid, &buf)));
3130 return NT_STATUS_NO_SUCH_USER;
3133 sids = NULL;
3135 /* make both calls inside the root block */
3136 become_root();
3137 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3138 &sids, &unix_gids, &num_groups);
3139 if ( NT_STATUS_IS_OK(result) ) {
3140 success = sid_peek_check_rid(get_global_sam_sid(),
3141 pdb_get_group_sid(sam_pass),
3142 &primary_group_rid);
3144 unbecome_root();
3146 if (!NT_STATUS_IS_OK(result)) {
3147 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3148 dom_sid_str_buf(&uinfo->sid, &buf)));
3149 return result;
3152 if ( !success ) {
3153 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3154 dom_sid_str_buf(pdb_get_group_sid(sam_pass), &buf),
3155 pdb_get_username(sam_pass)));
3156 TALLOC_FREE(sam_pass);
3157 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3160 gids = NULL;
3161 num_gids = 0;
3163 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3164 SE_GROUP_ENABLED);
3165 dom_gid.rid = primary_group_rid;
3166 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3168 for (i=0; i<num_groups; i++) {
3170 if (!sid_peek_check_rid(get_global_sam_sid(),
3171 &(sids[i]), &dom_gid.rid)) {
3172 DEBUG(10, ("Found sid %s not in our domain\n",
3173 dom_sid_str_buf(&sids[i], &buf)));
3174 continue;
3177 if (dom_gid.rid == primary_group_rid) {
3178 /* We added the primary group directly from the
3179 * sam_account. The other SIDs are unique from
3180 * enum_group_memberships */
3181 continue;
3184 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3187 rids->count = num_gids;
3188 rids->rids = gids;
3190 *r->out.rids = rids;
3192 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3194 return result;
3197 /*******************************************************************
3198 ********************************************************************/
3200 static uint32_t samr_get_server_role(void)
3202 uint32_t role = ROLE_DOMAIN_PDC;
3204 if (lp_server_role() == ROLE_DOMAIN_BDC) {
3205 role = ROLE_DOMAIN_BDC;
3208 return role;
3211 /*******************************************************************
3212 ********************************************************************/
3214 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3215 struct samr_DomInfo1 *r)
3217 uint32_t account_policy_temp;
3218 time_t u_expire, u_min_age;
3220 become_root();
3222 /* AS ROOT !!! */
3224 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3225 r->min_password_length = account_policy_temp;
3227 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3228 r->password_history_length = account_policy_temp;
3230 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3231 &r->password_properties);
3233 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3234 u_expire = account_policy_temp;
3236 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3237 u_min_age = account_policy_temp;
3239 /* !AS ROOT */
3241 unbecome_root();
3243 unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3244 unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3246 if (lp_check_password_script(talloc_tos()) && *lp_check_password_script(talloc_tos())) {
3247 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3250 return NT_STATUS_OK;
3253 /*******************************************************************
3254 ********************************************************************/
3256 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3257 struct samr_DomGeneralInformation *r,
3258 struct samr_domain_info *dinfo)
3260 uint32_t u_logout;
3261 time_t seq_num;
3263 become_root();
3265 /* AS ROOT !!! */
3267 r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3268 r->num_groups = count_sam_groups(dinfo->disp_info);
3269 r->num_aliases = count_sam_aliases(dinfo->disp_info);
3271 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3273 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3275 if (!pdb_get_seq_num(&seq_num)) {
3276 seq_num = time(NULL);
3279 /* !AS ROOT */
3281 unbecome_root();
3283 r->oem_information.string = lp_server_string(r);
3284 r->domain_name.string = lp_workgroup();
3285 r->primary.string = lp_netbios_name();
3286 r->sequence_num = seq_num;
3287 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3288 r->role = (enum samr_Role) samr_get_server_role();
3289 r->unknown3 = 1;
3291 return NT_STATUS_OK;
3294 /*******************************************************************
3295 ********************************************************************/
3297 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3298 struct samr_DomInfo3 *r)
3300 uint32_t u_logout;
3302 become_root();
3304 /* AS ROOT !!! */
3307 uint32_t ul;
3308 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3309 u_logout = (time_t)ul;
3312 /* !AS ROOT */
3314 unbecome_root();
3316 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3318 return NT_STATUS_OK;
3321 /*******************************************************************
3322 ********************************************************************/
3324 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3325 struct samr_DomOEMInformation *r)
3327 r->oem_information.string = lp_server_string(r);
3329 return NT_STATUS_OK;
3332 /*******************************************************************
3333 ********************************************************************/
3335 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3336 struct samr_DomInfo5 *r)
3338 r->domain_name.string = get_global_sam_name();
3340 return NT_STATUS_OK;
3343 /*******************************************************************
3344 ********************************************************************/
3346 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3347 struct samr_DomInfo6 *r)
3349 /* NT returns its own name when a PDC. win2k and later
3350 * only the name of the PDC if itself is a BDC (samba4
3351 * idl) */
3352 r->primary.string = lp_netbios_name();
3354 return NT_STATUS_OK;
3357 /*******************************************************************
3358 ********************************************************************/
3360 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3361 struct samr_DomInfo7 *r)
3363 r->role = (enum samr_Role) samr_get_server_role();
3365 return NT_STATUS_OK;
3368 /*******************************************************************
3369 ********************************************************************/
3371 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3372 struct samr_DomInfo8 *r)
3374 time_t seq_num;
3376 become_root();
3378 /* AS ROOT !!! */
3380 if (!pdb_get_seq_num(&seq_num)) {
3381 seq_num = time(NULL);
3384 /* !AS ROOT */
3386 unbecome_root();
3388 r->sequence_num = seq_num;
3389 r->domain_create_time = 0;
3391 return NT_STATUS_OK;
3394 /*******************************************************************
3395 ********************************************************************/
3397 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3398 struct samr_DomInfo9 *r)
3400 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3402 return NT_STATUS_OK;
3405 /*******************************************************************
3406 ********************************************************************/
3408 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3409 struct samr_DomGeneralInformation2 *r,
3410 struct samr_domain_info *dinfo)
3412 NTSTATUS status;
3413 uint32_t account_policy_temp;
3414 time_t u_lock_duration, u_reset_time;
3416 status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3417 if (!NT_STATUS_IS_OK(status)) {
3418 return status;
3421 /* AS ROOT !!! */
3423 become_root();
3425 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3426 u_lock_duration = account_policy_temp;
3427 if (u_lock_duration != -1) {
3428 u_lock_duration *= 60;
3431 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3432 u_reset_time = account_policy_temp * 60;
3434 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3435 r->lockout_threshold = account_policy_temp;
3437 /* !AS ROOT */
3439 unbecome_root();
3441 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3442 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3444 return NT_STATUS_OK;
3447 /*******************************************************************
3448 ********************************************************************/
3450 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3451 struct samr_DomInfo12 *r)
3453 uint32_t account_policy_temp;
3454 time_t u_lock_duration, u_reset_time;
3456 become_root();
3458 /* AS ROOT !!! */
3460 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3461 u_lock_duration = account_policy_temp;
3462 if (u_lock_duration != -1) {
3463 u_lock_duration *= 60;
3466 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3467 u_reset_time = account_policy_temp * 60;
3469 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3470 r->lockout_threshold = account_policy_temp;
3472 /* !AS ROOT */
3474 unbecome_root();
3476 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3477 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3479 return NT_STATUS_OK;
3482 /*******************************************************************
3483 ********************************************************************/
3485 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3486 struct samr_DomInfo13 *r)
3488 time_t seq_num;
3490 become_root();
3492 /* AS ROOT !!! */
3494 if (!pdb_get_seq_num(&seq_num)) {
3495 seq_num = time(NULL);
3498 /* !AS ROOT */
3500 unbecome_root();
3502 r->sequence_num = seq_num;
3503 r->domain_create_time = 0;
3504 r->modified_count_at_last_promotion = 0;
3506 return NT_STATUS_OK;
3509 /*******************************************************************
3510 _samr_QueryDomainInfo
3511 ********************************************************************/
3513 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3514 struct samr_QueryDomainInfo *r)
3516 NTSTATUS status = NT_STATUS_OK;
3517 struct samr_domain_info *dinfo;
3518 union samr_DomainInfo *dom_info;
3520 uint32_t acc_required;
3522 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3524 switch (r->in.level) {
3525 case 1: /* DomainPasswordInformation */
3526 case 12: /* DomainLockoutInformation */
3527 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3528 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3529 break;
3530 case 11: /* DomainGeneralInformation2 */
3531 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3532 * DOMAIN_READ_OTHER_PARAMETERS */
3533 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3534 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3535 break;
3536 case 2: /* DomainGeneralInformation */
3537 case 3: /* DomainLogoffInformation */
3538 case 4: /* DomainOemInformation */
3539 case 5: /* DomainReplicationInformation */
3540 case 6: /* DomainReplicationInformation */
3541 case 7: /* DomainServerRoleInformation */
3542 case 8: /* DomainModifiedInformation */
3543 case 9: /* DomainStateInformation */
3544 case 10: /* DomainUasInformation */
3545 case 13: /* DomainModifiedInformation2 */
3546 /* DOMAIN_READ_OTHER_PARAMETERS */
3547 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3548 break;
3549 default:
3550 return NT_STATUS_INVALID_INFO_CLASS;
3553 dinfo = policy_handle_find(p, r->in.domain_handle,
3554 acc_required, NULL,
3555 struct samr_domain_info, &status);
3556 if (!NT_STATUS_IS_OK(status)) {
3557 return status;
3560 dom_info = talloc_zero(p->mem_ctx, union samr_DomainInfo);
3561 if (!dom_info) {
3562 return NT_STATUS_NO_MEMORY;
3565 switch (r->in.level) {
3566 case 1:
3567 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3568 break;
3569 case 2:
3570 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3571 break;
3572 case 3:
3573 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3574 break;
3575 case 4:
3576 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3577 break;
3578 case 5:
3579 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3580 break;
3581 case 6:
3582 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3583 break;
3584 case 7:
3585 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3586 break;
3587 case 8:
3588 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3589 break;
3590 case 9:
3591 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3592 break;
3593 case 11:
3594 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3595 break;
3596 case 12:
3597 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3598 break;
3599 case 13:
3600 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3601 break;
3602 default:
3603 return NT_STATUS_INVALID_INFO_CLASS;
3606 if (!NT_STATUS_IS_OK(status)) {
3607 return status;
3610 *r->out.info = dom_info;
3612 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3614 return status;
3617 /* W2k3 seems to use the same check for all 3 objects that can be created via
3618 * SAMR, if you try to create for example "Dialup" as an alias it says
3619 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3620 * database. */
3622 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3624 enum lsa_SidType type;
3625 bool result;
3627 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3629 become_root();
3630 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3631 * whether the name already exists */
3632 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3633 NULL, NULL, NULL, &type);
3634 unbecome_root();
3636 if (!result) {
3637 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3638 return NT_STATUS_OK;
3641 DEBUG(5, ("trying to create %s, exists as %s\n",
3642 new_name, sid_type_lookup(type)));
3644 if (type == SID_NAME_DOM_GRP) {
3645 return NT_STATUS_GROUP_EXISTS;
3647 if (type == SID_NAME_ALIAS) {
3648 return NT_STATUS_ALIAS_EXISTS;
3651 /* Yes, the default is NT_STATUS_USER_EXISTS */
3652 return NT_STATUS_USER_EXISTS;
3655 /*******************************************************************
3656 _samr_CreateUser2
3657 ********************************************************************/
3659 NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3660 struct samr_CreateUser2 *r)
3662 const char *account = NULL;
3663 struct dom_sid sid;
3664 uint32_t acb_info = r->in.acct_flags;
3665 struct samr_domain_info *dinfo;
3666 struct samr_user_info *uinfo;
3667 NTSTATUS nt_status;
3668 uint32_t acc_granted;
3669 struct security_descriptor *psd;
3670 size_t sd_size;
3671 /* check this, when giving away 'add computer to domain' privs */
3672 uint32_t des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3673 bool can_add_account = False;
3675 /* Which privilege is needed to override the ACL? */
3676 enum sec_privilege needed_priv = SEC_PRIV_INVALID;
3678 dinfo = policy_handle_find(p, r->in.domain_handle,
3679 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3680 struct samr_domain_info, &nt_status);
3681 if (!NT_STATUS_IS_OK(nt_status)) {
3682 return nt_status;
3685 if (sid_check_is_builtin(&dinfo->sid)) {
3686 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3687 return NT_STATUS_ACCESS_DENIED;
3690 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3691 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3692 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3693 this parameter is not an account type */
3694 return NT_STATUS_INVALID_PARAMETER;
3697 account = r->in.account_name->string;
3698 if (account == NULL) {
3699 return NT_STATUS_NO_MEMORY;
3702 nt_status = can_create(p->mem_ctx, account);
3703 if (!NT_STATUS_IS_OK(nt_status)) {
3704 return nt_status;
3707 /* determine which user right we need to check based on the acb_info */
3709 if (root_mode()) {
3710 can_add_account = true;
3711 } else if (acb_info & ACB_WSTRUST) {
3712 needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
3713 can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_MACHINE_ACCOUNT);
3714 } else if (acb_info & ACB_NORMAL &&
3715 (account[strlen(account)-1] != '$')) {
3716 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3717 account for domain trusts and changes the ACB flags later */
3718 needed_priv = SEC_PRIV_ADD_USERS;
3719 can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS);
3720 } else if (lp_enable_privileges()) {
3721 /* implicit assumption of a BDC or domain trust account here
3722 * (we already check the flags earlier) */
3723 /* only Domain Admins can add a BDC or domain trust */
3724 can_add_account = nt_token_check_domain_rid(
3725 p->session_info->security_token,
3726 DOMAIN_RID_ADMINS );
3729 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3730 uidtoname(p->session_info->unix_token->uid),
3731 can_add_account ? "True":"False" ));
3733 if (!can_add_account) {
3734 return NT_STATUS_ACCESS_DENIED;
3737 /********** BEGIN Admin BLOCK **********/
3739 become_root();
3740 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3741 r->out.rid);
3742 unbecome_root();
3744 /********** END Admin BLOCK **********/
3746 /* now check for failure */
3748 if ( !NT_STATUS_IS_OK(nt_status) )
3749 return nt_status;
3751 /* Get the user's SID */
3753 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3755 map_max_allowed_access(p->session_info->security_token,
3756 p->session_info->unix_token,
3757 &des_access);
3759 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3760 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3761 se_map_generic(&des_access, &usr_generic_mapping);
3764 * JRA - TESTME. We just created this user so we
3765 * had rights to create them. Do we need to check
3766 * any further access on this object ? Can't we
3767 * just assume we have all the rights we need ?
3770 nt_status = access_check_object(psd, p->session_info->security_token,
3771 needed_priv, SEC_PRIV_INVALID,
3772 GENERIC_RIGHTS_USER_WRITE, des_access,
3773 &acc_granted, "_samr_CreateUser2");
3775 if ( !NT_STATUS_IS_OK(nt_status) ) {
3776 return nt_status;
3779 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3780 struct samr_user_info, &nt_status);
3781 if (!NT_STATUS_IS_OK(nt_status)) {
3782 return nt_status;
3784 uinfo->sid = sid;
3786 /* After a "set" ensure we have no cached display info. */
3787 force_flush_samr_cache(&sid);
3789 *r->out.access_granted = acc_granted;
3791 return NT_STATUS_OK;
3794 /****************************************************************
3795 ****************************************************************/
3797 NTSTATUS _samr_CreateUser(struct pipes_struct *p,
3798 struct samr_CreateUser *r)
3800 struct samr_CreateUser2 c;
3801 uint32_t access_granted;
3803 c.in.domain_handle = r->in.domain_handle;
3804 c.in.account_name = r->in.account_name;
3805 c.in.acct_flags = ACB_NORMAL;
3806 c.in.access_mask = r->in.access_mask;
3807 c.out.user_handle = r->out.user_handle;
3808 c.out.access_granted = &access_granted;
3809 c.out.rid = r->out.rid;
3811 return _samr_CreateUser2(p, &c);
3814 /*******************************************************************
3815 _samr_Connect
3816 ********************************************************************/
3818 NTSTATUS _samr_Connect(struct pipes_struct *p,
3819 struct samr_Connect *r)
3821 uint32_t acc_granted;
3822 struct policy_handle hnd;
3823 uint32_t des_access = r->in.access_mask;
3824 NTSTATUS status;
3826 /* Access check */
3828 if (!pipe_access_check(p)) {
3829 DEBUG(3, ("access denied to _samr_Connect\n"));
3830 return NT_STATUS_ACCESS_DENIED;
3833 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3834 was observed from a win98 client trying to enumerate users (when configured
3835 user level access control on shares) --jerry */
3837 map_max_allowed_access(p->session_info->security_token,
3838 p->session_info->unix_token,
3839 &des_access);
3841 se_map_generic( &des_access, &sam_generic_mapping );
3843 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3844 |SAMR_ACCESS_LOOKUP_DOMAIN);
3846 /* set up the SAMR connect_anon response */
3848 (void)policy_handle_create(p, &hnd, acc_granted,
3849 struct samr_connect_info,
3850 &status);
3851 if (!NT_STATUS_IS_OK(status)) {
3852 return status;
3855 *r->out.connect_handle = hnd;
3856 return NT_STATUS_OK;
3859 /*******************************************************************
3860 _samr_Connect2
3861 ********************************************************************/
3863 NTSTATUS _samr_Connect2(struct pipes_struct *p,
3864 struct samr_Connect2 *r)
3866 struct policy_handle hnd;
3867 struct security_descriptor *psd = NULL;
3868 uint32_t acc_granted;
3869 uint32_t des_access = r->in.access_mask;
3870 NTSTATUS nt_status;
3871 size_t sd_size;
3872 const char *fn = "_samr_Connect2";
3874 switch (p->opnum) {
3875 case NDR_SAMR_CONNECT2:
3876 fn = "_samr_Connect2";
3877 break;
3878 case NDR_SAMR_CONNECT3:
3879 fn = "_samr_Connect3";
3880 break;
3881 case NDR_SAMR_CONNECT4:
3882 fn = "_samr_Connect4";
3883 break;
3884 case NDR_SAMR_CONNECT5:
3885 fn = "_samr_Connect5";
3886 break;
3889 DEBUG(5,("%s: %d\n", fn, __LINE__));
3891 /* Access check */
3893 if (!pipe_access_check(p)) {
3894 DEBUG(3, ("access denied to %s\n", fn));
3895 return NT_STATUS_ACCESS_DENIED;
3898 map_max_allowed_access(p->session_info->security_token,
3899 p->session_info->unix_token,
3900 &des_access);
3902 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3903 se_map_generic(&des_access, &sam_generic_mapping);
3905 nt_status = access_check_object(psd, p->session_info->security_token,
3906 SEC_PRIV_INVALID, SEC_PRIV_INVALID,
3907 0, des_access, &acc_granted, fn);
3909 if ( !NT_STATUS_IS_OK(nt_status) )
3910 return nt_status;
3912 (void)policy_handle_create(p, &hnd, acc_granted,
3913 struct samr_connect_info, &nt_status);
3914 if (!NT_STATUS_IS_OK(nt_status)) {
3915 return nt_status;
3918 DEBUG(5,("%s: %d\n", fn, __LINE__));
3920 *r->out.connect_handle = hnd;
3921 return NT_STATUS_OK;
3924 /****************************************************************
3925 _samr_Connect3
3926 ****************************************************************/
3928 NTSTATUS _samr_Connect3(struct pipes_struct *p,
3929 struct samr_Connect3 *r)
3931 struct samr_Connect2 c;
3933 c.in.system_name = r->in.system_name;
3934 c.in.access_mask = r->in.access_mask;
3935 c.out.connect_handle = r->out.connect_handle;
3937 return _samr_Connect2(p, &c);
3940 /*******************************************************************
3941 _samr_Connect4
3942 ********************************************************************/
3944 NTSTATUS _samr_Connect4(struct pipes_struct *p,
3945 struct samr_Connect4 *r)
3947 struct samr_Connect2 c;
3949 c.in.system_name = r->in.system_name;
3950 c.in.access_mask = r->in.access_mask;
3951 c.out.connect_handle = r->out.connect_handle;
3953 return _samr_Connect2(p, &c);
3956 /*******************************************************************
3957 _samr_Connect5
3958 ********************************************************************/
3960 NTSTATUS _samr_Connect5(struct pipes_struct *p,
3961 struct samr_Connect5 *r)
3963 NTSTATUS status;
3964 struct samr_Connect2 c;
3965 struct samr_ConnectInfo1 info1;
3967 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3968 info1.unknown2 = 0;
3970 c.in.system_name = r->in.system_name;
3971 c.in.access_mask = r->in.access_mask;
3972 c.out.connect_handle = r->out.connect_handle;
3974 *r->out.level_out = 1;
3976 status = _samr_Connect2(p, &c);
3977 if (!NT_STATUS_IS_OK(status)) {
3978 return status;
3981 r->out.info_out->info1 = info1;
3983 return NT_STATUS_OK;
3986 /**********************************************************************
3987 _samr_LookupDomain
3988 **********************************************************************/
3990 NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
3991 struct samr_LookupDomain *r)
3993 NTSTATUS status;
3994 const char *domain_name;
3995 struct dom_sid *sid = NULL;
3996 struct dom_sid_buf buf;
3998 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3999 Reverted that change so we will work with RAS servers again */
4001 (void)policy_handle_find(p, r->in.connect_handle,
4002 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4003 struct samr_connect_info,
4004 &status);
4005 if (!NT_STATUS_IS_OK(status)) {
4006 return status;
4009 domain_name = r->in.domain_name->string;
4010 if (!domain_name) {
4011 return NT_STATUS_INVALID_PARAMETER;
4014 sid = talloc_zero(p->mem_ctx, struct dom_sid2);
4015 if (!sid) {
4016 return NT_STATUS_NO_MEMORY;
4019 if (strequal(domain_name, builtin_domain_name())) {
4020 sid_copy(sid, &global_sid_Builtin);
4021 } else {
4022 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4023 status = NT_STATUS_NO_SUCH_DOMAIN;
4027 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4028 dom_sid_str_buf(sid, &buf)));
4030 *r->out.sid = sid;
4032 return status;
4035 /**********************************************************************
4036 _samr_EnumDomains
4037 **********************************************************************/
4039 NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4040 struct samr_EnumDomains *r)
4042 NTSTATUS status;
4043 uint32_t num_entries = 2;
4044 struct samr_SamEntry *entry_array = NULL;
4045 struct samr_SamArray *sam;
4047 (void)policy_handle_find(p, r->in.connect_handle,
4048 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4049 struct samr_connect_info, &status);
4050 if (!NT_STATUS_IS_OK(status)) {
4051 return status;
4054 sam = talloc_zero(p->mem_ctx, struct samr_SamArray);
4055 if (!sam) {
4056 return NT_STATUS_NO_MEMORY;
4059 entry_array = talloc_zero_array(p->mem_ctx,
4060 struct samr_SamEntry,
4061 num_entries);
4062 if (!entry_array) {
4063 return NT_STATUS_NO_MEMORY;
4066 entry_array[0].idx = 0;
4067 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4069 entry_array[1].idx = 1;
4070 init_lsa_String(&entry_array[1].name, "Builtin");
4072 sam->count = num_entries;
4073 sam->entries = entry_array;
4075 *r->out.sam = sam;
4076 *r->out.num_entries = num_entries;
4078 return status;
4081 /*******************************************************************
4082 _samr_OpenAlias
4083 ********************************************************************/
4085 NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4086 struct samr_OpenAlias *r)
4088 struct dom_sid sid;
4089 uint32_t alias_rid = r->in.rid;
4090 struct samr_alias_info *ainfo;
4091 struct samr_domain_info *dinfo;
4092 struct security_descriptor *psd = NULL;
4093 uint32_t acc_granted;
4094 uint32_t des_access = r->in.access_mask;
4095 size_t sd_size;
4096 NTSTATUS status;
4098 dinfo = policy_handle_find(p, r->in.domain_handle,
4099 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4100 struct samr_domain_info, &status);
4101 if (!NT_STATUS_IS_OK(status)) {
4102 return status;
4105 /* append the alias' RID to it */
4107 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4108 return NT_STATUS_NO_SUCH_ALIAS;
4110 /*check if access can be granted as requested by client. */
4112 map_max_allowed_access(p->session_info->security_token,
4113 p->session_info->unix_token,
4114 &des_access);
4116 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4117 se_map_generic(&des_access,&ali_generic_mapping);
4119 status = access_check_object(psd, p->session_info->security_token,
4120 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
4121 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4122 des_access, &acc_granted, "_samr_OpenAlias");
4124 if ( !NT_STATUS_IS_OK(status) )
4125 return status;
4128 /* Check we actually have the requested alias */
4129 enum lsa_SidType type;
4130 bool result;
4131 gid_t gid;
4133 become_root();
4134 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4135 unbecome_root();
4137 if (!result || (type != SID_NAME_ALIAS)) {
4138 return NT_STATUS_NO_SUCH_ALIAS;
4141 /* make sure there is a mapping */
4143 if ( !sid_to_gid( &sid, &gid ) ) {
4144 return NT_STATUS_NO_SUCH_ALIAS;
4149 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4150 struct samr_alias_info, &status);
4151 if (!NT_STATUS_IS_OK(status)) {
4152 return status;
4154 ainfo->sid = sid;
4156 return NT_STATUS_OK;
4159 /*******************************************************************
4160 set_user_info_2
4161 ********************************************************************/
4163 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4164 struct samr_UserInfo2 *id2,
4165 struct samu *pwd)
4167 if (id2 == NULL) {
4168 DEBUG(5,("set_user_info_2: NULL id2\n"));
4169 return NT_STATUS_ACCESS_DENIED;
4172 copy_id2_to_sam_passwd(pwd, id2);
4174 return pdb_update_sam_account(pwd);
4177 /*******************************************************************
4178 set_user_info_4
4179 ********************************************************************/
4181 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4182 struct samr_UserInfo4 *id4,
4183 struct samu *pwd)
4185 if (id4 == NULL) {
4186 DEBUG(5,("set_user_info_2: NULL id4\n"));
4187 return NT_STATUS_ACCESS_DENIED;
4190 copy_id4_to_sam_passwd(pwd, id4);
4192 return pdb_update_sam_account(pwd);
4195 /*******************************************************************
4196 set_user_info_6
4197 ********************************************************************/
4199 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4200 struct samr_UserInfo6 *id6,
4201 struct samu *pwd)
4203 if (id6 == NULL) {
4204 DEBUG(5,("set_user_info_6: NULL id6\n"));
4205 return NT_STATUS_ACCESS_DENIED;
4208 copy_id6_to_sam_passwd(pwd, id6);
4210 return pdb_update_sam_account(pwd);
4213 /*******************************************************************
4214 set_user_info_7
4215 ********************************************************************/
4217 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4218 struct samr_UserInfo7 *id7,
4219 struct samu *pwd)
4221 NTSTATUS rc;
4223 if (id7 == NULL) {
4224 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4225 return NT_STATUS_ACCESS_DENIED;
4228 if (!id7->account_name.string) {
4229 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4230 return NT_STATUS_ACCESS_DENIED;
4233 /* check to see if the new username already exists. Note: we can't
4234 reliably lock all backends, so there is potentially the
4235 possibility that a user can be created in between this check and
4236 the rename. The rename should fail, but may not get the
4237 exact same failure status code. I think this is small enough
4238 of a window for this type of operation and the results are
4239 simply that the rename fails with a slightly different status
4240 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4242 rc = can_create(mem_ctx, id7->account_name.string);
4244 /* when there is nothing to change, we're done here */
4245 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4246 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4247 return NT_STATUS_OK;
4249 if (!NT_STATUS_IS_OK(rc)) {
4250 return rc;
4253 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4255 return rc;
4258 /*******************************************************************
4259 set_user_info_8
4260 ********************************************************************/
4262 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4263 struct samr_UserInfo8 *id8,
4264 struct samu *pwd)
4266 if (id8 == NULL) {
4267 DEBUG(5,("set_user_info_8: NULL id8\n"));
4268 return NT_STATUS_ACCESS_DENIED;
4271 copy_id8_to_sam_passwd(pwd, id8);
4273 return pdb_update_sam_account(pwd);
4276 /*******************************************************************
4277 set_user_info_10
4278 ********************************************************************/
4280 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4281 struct samr_UserInfo10 *id10,
4282 struct samu *pwd)
4284 if (id10 == NULL) {
4285 DEBUG(5,("set_user_info_8: NULL id10\n"));
4286 return NT_STATUS_ACCESS_DENIED;
4289 copy_id10_to_sam_passwd(pwd, id10);
4291 return pdb_update_sam_account(pwd);
4294 /*******************************************************************
4295 set_user_info_11
4296 ********************************************************************/
4298 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4299 struct samr_UserInfo11 *id11,
4300 struct samu *pwd)
4302 if (id11 == NULL) {
4303 DEBUG(5,("set_user_info_11: NULL id11\n"));
4304 return NT_STATUS_ACCESS_DENIED;
4307 copy_id11_to_sam_passwd(pwd, id11);
4309 return pdb_update_sam_account(pwd);
4312 /*******************************************************************
4313 set_user_info_12
4314 ********************************************************************/
4316 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4317 struct samr_UserInfo12 *id12,
4318 struct samu *pwd)
4320 if (id12 == NULL) {
4321 DEBUG(5,("set_user_info_12: NULL id12\n"));
4322 return NT_STATUS_ACCESS_DENIED;
4325 copy_id12_to_sam_passwd(pwd, id12);
4327 return pdb_update_sam_account(pwd);
4330 /*******************************************************************
4331 set_user_info_13
4332 ********************************************************************/
4334 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4335 struct samr_UserInfo13 *id13,
4336 struct samu *pwd)
4338 if (id13 == NULL) {
4339 DEBUG(5,("set_user_info_13: NULL id13\n"));
4340 return NT_STATUS_ACCESS_DENIED;
4343 copy_id13_to_sam_passwd(pwd, id13);
4345 return pdb_update_sam_account(pwd);
4348 /*******************************************************************
4349 set_user_info_14
4350 ********************************************************************/
4352 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4353 struct samr_UserInfo14 *id14,
4354 struct samu *pwd)
4356 if (id14 == NULL) {
4357 DEBUG(5,("set_user_info_14: NULL id14\n"));
4358 return NT_STATUS_ACCESS_DENIED;
4361 copy_id14_to_sam_passwd(pwd, id14);
4363 return pdb_update_sam_account(pwd);
4366 /*******************************************************************
4367 set_user_info_16
4368 ********************************************************************/
4370 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4371 struct samr_UserInfo16 *id16,
4372 struct samu *pwd)
4374 if (id16 == NULL) {
4375 DEBUG(5,("set_user_info_16: NULL id16\n"));
4376 return NT_STATUS_ACCESS_DENIED;
4379 copy_id16_to_sam_passwd(pwd, id16);
4381 return pdb_update_sam_account(pwd);
4384 /*******************************************************************
4385 set_user_info_17
4386 ********************************************************************/
4388 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4389 struct samr_UserInfo17 *id17,
4390 struct samu *pwd)
4392 if (id17 == NULL) {
4393 DEBUG(5,("set_user_info_17: NULL id17\n"));
4394 return NT_STATUS_ACCESS_DENIED;
4397 copy_id17_to_sam_passwd(pwd, id17);
4399 return pdb_update_sam_account(pwd);
4402 /*******************************************************************
4403 set_user_info_18
4404 ********************************************************************/
4406 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4407 TALLOC_CTX *mem_ctx,
4408 DATA_BLOB *session_key,
4409 struct samu *pwd)
4411 if (id18 == NULL) {
4412 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4413 return NT_STATUS_INVALID_PARAMETER;
4416 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4417 if (!session_key->length) {
4418 return NT_STATUS_NO_USER_SESSION_KEY;
4422 if (id18->nt_pwd_active) {
4424 DATA_BLOB in, out;
4426 in = data_blob_const(id18->nt_pwd.hash, 16);
4427 out = data_blob_talloc_zero(mem_ctx, 16);
4429 sess_crypt_blob(&out, &in, session_key, false);
4431 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4432 return NT_STATUS_ACCESS_DENIED;
4435 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4438 if (id18->lm_pwd_active) {
4440 DATA_BLOB in, out;
4442 in = data_blob_const(id18->lm_pwd.hash, 16);
4443 out = data_blob_talloc_zero(mem_ctx, 16);
4445 sess_crypt_blob(&out, &in, session_key, false);
4447 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4448 return NT_STATUS_ACCESS_DENIED;
4451 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4454 copy_id18_to_sam_passwd(pwd, id18);
4456 return pdb_update_sam_account(pwd);
4459 /*******************************************************************
4460 set_user_info_20
4461 ********************************************************************/
4463 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4464 struct samr_UserInfo20 *id20,
4465 struct samu *pwd)
4467 if (id20 == NULL) {
4468 DEBUG(5,("set_user_info_20: NULL id20\n"));
4469 return NT_STATUS_ACCESS_DENIED;
4472 copy_id20_to_sam_passwd(pwd, id20);
4474 return pdb_update_sam_account(pwd);
4477 /*******************************************************************
4478 set_user_info_21
4479 ********************************************************************/
4481 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4482 TALLOC_CTX *mem_ctx,
4483 DATA_BLOB *session_key,
4484 struct samu *pwd)
4486 NTSTATUS status;
4488 if (id21 == NULL) {
4489 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4490 return NT_STATUS_INVALID_PARAMETER;
4493 if (id21->fields_present == 0) {
4494 return NT_STATUS_INVALID_PARAMETER;
4497 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4498 return NT_STATUS_ACCESS_DENIED;
4501 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4502 if (id21->nt_password_set) {
4503 DATA_BLOB in, out;
4505 if ((id21->nt_owf_password.length != 16) ||
4506 (id21->nt_owf_password.size != 16)) {
4507 return NT_STATUS_INVALID_PARAMETER;
4510 if (!session_key->length) {
4511 return NT_STATUS_NO_USER_SESSION_KEY;
4514 in = data_blob_const(id21->nt_owf_password.array, 16);
4515 out = data_blob_talloc_zero(mem_ctx, 16);
4517 sess_crypt_blob(&out, &in, session_key, false);
4519 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4520 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4524 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4525 if (id21->lm_password_set) {
4526 DATA_BLOB in, out;
4528 if ((id21->lm_owf_password.length != 16) ||
4529 (id21->lm_owf_password.size != 16)) {
4530 return NT_STATUS_INVALID_PARAMETER;
4533 if (!session_key->length) {
4534 return NT_STATUS_NO_USER_SESSION_KEY;
4537 in = data_blob_const(id21->lm_owf_password.array, 16);
4538 out = data_blob_talloc_zero(mem_ctx, 16);
4540 sess_crypt_blob(&out, &in, session_key, false);
4542 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4543 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4547 /* we need to separately check for an account rename first */
4549 if (id21->account_name.string &&
4550 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4553 /* check to see if the new username already exists. Note: we can't
4554 reliably lock all backends, so there is potentially the
4555 possibility that a user can be created in between this check and
4556 the rename. The rename should fail, but may not get the
4557 exact same failure status code. I think this is small enough
4558 of a window for this type of operation and the results are
4559 simply that the rename fails with a slightly different status
4560 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4562 status = can_create(mem_ctx, id21->account_name.string);
4563 if (!NT_STATUS_IS_OK(status)) {
4564 return status;
4567 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4569 if (!NT_STATUS_IS_OK(status)) {
4570 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4571 nt_errstr(status)));
4572 return status;
4575 /* set the new username so that later
4576 functions can work on the new account */
4577 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4580 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4583 * The funny part about the previous two calls is
4584 * that pwd still has the password hashes from the
4585 * passdb entry. These have not been updated from
4586 * id21. I don't know if they need to be set. --jerry
4589 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4590 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4591 if ( !NT_STATUS_IS_OK(status) ) {
4592 return status;
4596 /* Don't worry about writing out the user account since the
4597 primary group SID is generated solely from the user's Unix
4598 primary group. */
4600 /* write the change out */
4601 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4602 return status;
4605 return NT_STATUS_OK;
4608 /*******************************************************************
4609 set_user_info_23
4610 ********************************************************************/
4612 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4613 struct samr_UserInfo23 *id23,
4614 const char *rhost,
4615 struct samu *pwd)
4617 char *plaintext_buf = NULL;
4618 size_t len = 0;
4619 uint32_t acct_ctrl;
4620 NTSTATUS status;
4622 if (id23 == NULL) {
4623 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4624 return NT_STATUS_INVALID_PARAMETER;
4627 if (id23->info.fields_present == 0) {
4628 return NT_STATUS_INVALID_PARAMETER;
4631 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4632 return NT_STATUS_ACCESS_DENIED;
4635 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4636 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4638 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4639 pdb_get_username(pwd)));
4641 if (!decode_pw_buffer(mem_ctx,
4642 id23->password.data,
4643 &plaintext_buf,
4644 &len,
4645 CH_UTF16)) {
4646 return NT_STATUS_WRONG_PASSWORD;
4649 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4650 return NT_STATUS_ACCESS_DENIED;
4654 copy_id23_to_sam_passwd(pwd, id23);
4656 acct_ctrl = pdb_get_acct_ctrl(pwd);
4658 /* if it's a trust account, don't update /etc/passwd */
4659 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4660 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4661 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4662 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4663 } else if (plaintext_buf) {
4664 /* update the UNIX password */
4665 if (lp_unix_password_sync() ) {
4666 struct passwd *passwd;
4667 if (pdb_get_username(pwd) == NULL) {
4668 DEBUG(1, ("chgpasswd: User without name???\n"));
4669 return NT_STATUS_ACCESS_DENIED;
4672 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4673 if (passwd == NULL) {
4674 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4677 if(!chgpasswd(pdb_get_username(pwd), rhost,
4678 passwd, "", plaintext_buf, True)) {
4679 return NT_STATUS_ACCESS_DENIED;
4681 TALLOC_FREE(passwd);
4685 if (plaintext_buf) {
4686 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4689 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4690 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4691 pwd)))) {
4692 return status;
4695 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4696 return status;
4699 return NT_STATUS_OK;
4702 /*******************************************************************
4703 set_user_info_pw
4704 ********************************************************************/
4706 static bool set_user_info_pw(uint8_t *pass, const char *rhost, struct samu *pwd)
4708 size_t len = 0;
4709 char *plaintext_buf = NULL;
4710 uint32_t acct_ctrl;
4712 DEBUG(5, ("Attempting administrator password change for user %s\n",
4713 pdb_get_username(pwd)));
4715 acct_ctrl = pdb_get_acct_ctrl(pwd);
4717 if (!decode_pw_buffer(talloc_tos(),
4718 pass,
4719 &plaintext_buf,
4720 &len,
4721 CH_UTF16)) {
4722 return False;
4725 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4726 return False;
4729 /* if it's a trust account, don't update /etc/passwd */
4730 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4731 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4732 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4733 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4734 } else {
4735 /* update the UNIX password */
4736 if (lp_unix_password_sync()) {
4737 struct passwd *passwd;
4739 if (pdb_get_username(pwd) == NULL) {
4740 DEBUG(1, ("chgpasswd: User without name???\n"));
4741 return False;
4744 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4745 if (passwd == NULL) {
4746 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4749 if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
4750 "", plaintext_buf, True)) {
4751 return False;
4753 TALLOC_FREE(passwd);
4757 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4759 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4761 return True;
4764 /*******************************************************************
4765 set_user_info_24
4766 ********************************************************************/
4768 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4769 const char *rhost,
4770 struct samr_UserInfo24 *id24,
4771 struct samu *pwd)
4773 NTSTATUS status;
4775 if (id24 == NULL) {
4776 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4777 return NT_STATUS_INVALID_PARAMETER;
4780 if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
4781 return NT_STATUS_WRONG_PASSWORD;
4784 copy_id24_to_sam_passwd(pwd, id24);
4786 status = pdb_update_sam_account(pwd);
4787 if (!NT_STATUS_IS_OK(status)) {
4788 return status;
4791 return NT_STATUS_OK;
4794 /*******************************************************************
4795 set_user_info_25
4796 ********************************************************************/
4798 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4799 const char *rhost,
4800 struct samr_UserInfo25 *id25,
4801 struct samu *pwd)
4803 NTSTATUS status;
4805 if (id25 == NULL) {
4806 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4807 return NT_STATUS_INVALID_PARAMETER;
4810 if (id25->info.fields_present == 0) {
4811 return NT_STATUS_INVALID_PARAMETER;
4814 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4815 return NT_STATUS_ACCESS_DENIED;
4818 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4819 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4821 if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
4822 return NT_STATUS_WRONG_PASSWORD;
4826 copy_id25_to_sam_passwd(pwd, id25);
4828 /* write the change out */
4829 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4830 return status;
4834 * We need to "pdb_update_sam_account" before the unix primary group
4835 * is set, because the idealx scripts would also change the
4836 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4837 * the delete explicit / add explicit, which would then fail to find
4838 * the previous primaryGroupSid value.
4841 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4842 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4843 if ( !NT_STATUS_IS_OK(status) ) {
4844 return status;
4848 return NT_STATUS_OK;
4851 /*******************************************************************
4852 set_user_info_26
4853 ********************************************************************/
4855 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4856 const char *rhost,
4857 struct samr_UserInfo26 *id26,
4858 struct samu *pwd)
4860 NTSTATUS status;
4862 if (id26 == NULL) {
4863 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4864 return NT_STATUS_INVALID_PARAMETER;
4867 if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
4868 return NT_STATUS_WRONG_PASSWORD;
4871 copy_id26_to_sam_passwd(pwd, id26);
4873 status = pdb_update_sam_account(pwd);
4874 if (!NT_STATUS_IS_OK(status)) {
4875 return status;
4878 return NT_STATUS_OK;
4881 /*************************************************************
4882 **************************************************************/
4884 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4886 uint32_t acc_required = 0;
4888 /* USER_ALL_USERNAME */
4889 if (fields & SAMR_FIELD_ACCOUNT_NAME)
4890 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4891 /* USER_ALL_FULLNAME */
4892 if (fields & SAMR_FIELD_FULL_NAME)
4893 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4894 /* USER_ALL_PRIMARYGROUPID */
4895 if (fields & SAMR_FIELD_PRIMARY_GID)
4896 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4897 /* USER_ALL_HOMEDIRECTORY */
4898 if (fields & SAMR_FIELD_HOME_DIRECTORY)
4899 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4900 /* USER_ALL_HOMEDIRECTORYDRIVE */
4901 if (fields & SAMR_FIELD_HOME_DRIVE)
4902 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4903 /* USER_ALL_SCRIPTPATH */
4904 if (fields & SAMR_FIELD_LOGON_SCRIPT)
4905 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4906 /* USER_ALL_PROFILEPATH */
4907 if (fields & SAMR_FIELD_PROFILE_PATH)
4908 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4909 /* USER_ALL_ADMINCOMMENT */
4910 if (fields & SAMR_FIELD_COMMENT)
4911 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4912 /* USER_ALL_WORKSTATIONS */
4913 if (fields & SAMR_FIELD_WORKSTATIONS)
4914 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4915 /* USER_ALL_LOGONHOURS */
4916 if (fields & SAMR_FIELD_LOGON_HOURS)
4917 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4918 /* USER_ALL_ACCOUNTEXPIRES */
4919 if (fields & SAMR_FIELD_ACCT_EXPIRY)
4920 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4921 /* USER_ALL_USERACCOUNTCONTROL */
4922 if (fields & SAMR_FIELD_ACCT_FLAGS)
4923 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4924 /* USER_ALL_PARAMETERS */
4925 if (fields & SAMR_FIELD_PARAMETERS)
4926 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4927 /* USER_ALL_USERCOMMENT */
4928 if (fields & SAMR_FIELD_COMMENT)
4929 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4930 /* USER_ALL_COUNTRYCODE */
4931 if (fields & SAMR_FIELD_COUNTRY_CODE)
4932 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4933 /* USER_ALL_CODEPAGE */
4934 if (fields & SAMR_FIELD_CODE_PAGE)
4935 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4936 /* USER_ALL_NTPASSWORDPRESENT */
4937 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
4938 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4939 /* USER_ALL_LMPASSWORDPRESENT */
4940 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
4941 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4942 /* USER_ALL_PASSWORDEXPIRED */
4943 if (fields & SAMR_FIELD_EXPIRED_FLAG)
4944 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4946 return acc_required;
4949 /*******************************************************************
4950 samr_SetUserInfo
4951 ********************************************************************/
4953 NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
4954 struct samr_SetUserInfo *r)
4956 struct samr_user_info *uinfo;
4957 NTSTATUS status;
4958 struct samu *pwd = NULL;
4959 union samr_UserInfo *info = r->in.info;
4960 uint32_t acc_required = 0;
4961 uint32_t fields = 0;
4962 bool ret;
4963 char *rhost;
4964 DATA_BLOB session_key;
4965 struct dom_sid_buf buf;
4967 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4969 /* This is tricky. A WinXP domain join sets
4970 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4971 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4972 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4973 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4974 we'll use the set from the WinXP join as the basis. */
4976 switch (r->in.level) {
4977 case 2: /* UserPreferencesInformation */
4978 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
4979 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
4980 break;
4981 case 4: /* UserLogonHoursInformation */
4982 case 6: /* UserNameInformation */
4983 case 7: /* UserAccountNameInformation */
4984 case 8: /* UserFullNameInformation */
4985 case 9: /* UserPrimaryGroupInformation */
4986 case 10: /* UserHomeInformation */
4987 case 11: /* UserScriptInformation */
4988 case 12: /* UserProfileInformation */
4989 case 13: /* UserAdminCommentInformation */
4990 case 14: /* UserWorkStationsInformation */
4991 case 16: /* UserControlInformation */
4992 case 17: /* UserExpiresInformation */
4993 case 20: /* UserParametersInformation */
4994 /* USER_WRITE_ACCOUNT */
4995 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
4996 break;
4997 case 18: /* UserInternal1Information */
4998 /* FIXME: gd, this is a guess */
4999 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5000 break;
5001 case 21: /* UserAllInformation */
5002 fields = info->info21.fields_present;
5003 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5004 break;
5005 case 23: /* UserInternal4Information */
5006 fields = info->info23.info.fields_present;
5007 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5008 break;
5009 case 25: /* UserInternal4InformationNew */
5010 fields = info->info25.info.fields_present;
5011 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5012 break;
5013 case 24: /* UserInternal5Information */
5014 case 26: /* UserInternal5InformationNew */
5015 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5016 break;
5017 default:
5018 return NT_STATUS_INVALID_INFO_CLASS;
5021 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5022 struct samr_user_info, &status);
5023 if (!NT_STATUS_IS_OK(status)) {
5024 return status;
5027 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5028 dom_sid_str_buf(&uinfo->sid, &buf),
5029 r->in.level));
5031 if (info == NULL) {
5032 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5033 return NT_STATUS_INVALID_INFO_CLASS;
5036 if (!(pwd = samu_new(NULL))) {
5037 return NT_STATUS_NO_MEMORY;
5040 become_root();
5041 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5042 unbecome_root();
5044 if (!ret) {
5045 TALLOC_FREE(pwd);
5046 return NT_STATUS_NO_SUCH_USER;
5049 rhost = tsocket_address_inet_addr_string(p->remote_address,
5050 talloc_tos());
5051 if (rhost == NULL) {
5052 return NT_STATUS_NO_MEMORY;
5055 /* ================ BEGIN Privilege BLOCK ================ */
5057 become_root();
5059 /* ok! user info levels (lots: see MSDEV help), off we go... */
5061 switch (r->in.level) {
5063 case 2:
5064 status = set_user_info_2(p->mem_ctx,
5065 &info->info2, pwd);
5066 break;
5068 case 4:
5069 status = set_user_info_4(p->mem_ctx,
5070 &info->info4, pwd);
5071 break;
5073 case 6:
5074 status = set_user_info_6(p->mem_ctx,
5075 &info->info6, pwd);
5076 break;
5078 case 7:
5079 status = set_user_info_7(p->mem_ctx,
5080 &info->info7, pwd);
5081 break;
5083 case 8:
5084 status = set_user_info_8(p->mem_ctx,
5085 &info->info8, pwd);
5086 break;
5088 case 10:
5089 status = set_user_info_10(p->mem_ctx,
5090 &info->info10, pwd);
5091 break;
5093 case 11:
5094 status = set_user_info_11(p->mem_ctx,
5095 &info->info11, pwd);
5096 break;
5098 case 12:
5099 status = set_user_info_12(p->mem_ctx,
5100 &info->info12, pwd);
5101 break;
5103 case 13:
5104 status = set_user_info_13(p->mem_ctx,
5105 &info->info13, pwd);
5106 break;
5108 case 14:
5109 status = set_user_info_14(p->mem_ctx,
5110 &info->info14, pwd);
5111 break;
5113 case 16:
5114 status = set_user_info_16(p->mem_ctx,
5115 &info->info16, pwd);
5116 break;
5118 case 17:
5119 status = set_user_info_17(p->mem_ctx,
5120 &info->info17, pwd);
5121 break;
5123 case 18:
5124 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5125 if(!NT_STATUS_IS_OK(status)) {
5126 break;
5128 /* Used by AS/U JRA. */
5129 status = set_user_info_18(&info->info18,
5130 p->mem_ctx,
5131 &session_key,
5132 pwd);
5133 break;
5135 case 20:
5136 status = set_user_info_20(p->mem_ctx,
5137 &info->info20, pwd);
5138 break;
5140 case 21:
5141 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5142 if(!NT_STATUS_IS_OK(status)) {
5143 break;
5145 status = set_user_info_21(&info->info21,
5146 p->mem_ctx,
5147 &session_key,
5148 pwd);
5149 break;
5151 case 23:
5152 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5153 if(!NT_STATUS_IS_OK(status)) {
5154 break;
5156 arcfour_crypt_blob(info->info23.password.data, 516,
5157 &session_key);
5159 dump_data(100, info->info23.password.data, 516);
5161 status = set_user_info_23(p->mem_ctx,
5162 &info->info23,
5163 rhost,
5164 pwd);
5165 break;
5167 case 24:
5168 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5169 if(!NT_STATUS_IS_OK(status)) {
5170 break;
5172 arcfour_crypt_blob(info->info24.password.data,
5173 516,
5174 &session_key);
5176 dump_data(100, info->info24.password.data, 516);
5178 status = set_user_info_24(p->mem_ctx,
5179 rhost,
5180 &info->info24, pwd);
5181 break;
5183 case 25:
5184 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5185 if(!NT_STATUS_IS_OK(status)) {
5186 break;
5188 encode_or_decode_arc4_passwd_buffer(
5189 info->info25.password.data,
5190 &session_key);
5192 dump_data(100, info->info25.password.data, 532);
5194 status = set_user_info_25(p->mem_ctx,
5195 rhost,
5196 &info->info25, pwd);
5197 break;
5199 case 26:
5200 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5201 if(!NT_STATUS_IS_OK(status)) {
5202 break;
5204 encode_or_decode_arc4_passwd_buffer(
5205 info->info26.password.data,
5206 &session_key);
5208 dump_data(100, info->info26.password.data, 516);
5210 status = set_user_info_26(p->mem_ctx,
5211 rhost,
5212 &info->info26, pwd);
5213 break;
5215 default:
5216 status = NT_STATUS_INVALID_INFO_CLASS;
5219 TALLOC_FREE(pwd);
5221 unbecome_root();
5223 /* ================ END Privilege BLOCK ================ */
5225 if (NT_STATUS_IS_OK(status)) {
5226 force_flush_samr_cache(&uinfo->sid);
5229 return status;
5232 /*******************************************************************
5233 _samr_SetUserInfo2
5234 ********************************************************************/
5236 NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
5237 struct samr_SetUserInfo2 *r)
5239 struct samr_SetUserInfo q;
5241 q.in.user_handle = r->in.user_handle;
5242 q.in.level = r->in.level;
5243 q.in.info = r->in.info;
5245 return _samr_SetUserInfo(p, &q);
5248 /*********************************************************************
5249 _samr_GetAliasMembership
5250 *********************************************************************/
5252 NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
5253 struct samr_GetAliasMembership *r)
5255 size_t num_alias_rids;
5256 uint32_t *alias_rids;
5257 struct samr_domain_info *dinfo;
5258 size_t i;
5260 NTSTATUS status;
5262 struct dom_sid *members;
5264 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5266 dinfo = policy_handle_find(p, r->in.domain_handle,
5267 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5268 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5269 struct samr_domain_info, &status);
5270 if (!NT_STATUS_IS_OK(status)) {
5271 return status;
5274 if (!sid_check_is_our_sam(&dinfo->sid) &&
5275 !sid_check_is_builtin(&dinfo->sid))
5276 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5278 if (r->in.sids->num_sids) {
5279 members = talloc_array(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
5281 if (members == NULL)
5282 return NT_STATUS_NO_MEMORY;
5283 } else {
5284 members = NULL;
5287 for (i=0; i<r->in.sids->num_sids; i++)
5288 sid_copy(&members[i], r->in.sids->sids[i].sid);
5290 alias_rids = NULL;
5291 num_alias_rids = 0;
5293 become_root();
5294 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5295 r->in.sids->num_sids,
5296 &alias_rids, &num_alias_rids);
5297 unbecome_root();
5299 if (!NT_STATUS_IS_OK(status)) {
5300 return status;
5303 r->out.rids->count = num_alias_rids;
5304 r->out.rids->ids = alias_rids;
5306 if (r->out.rids->ids == NULL) {
5307 /* Windows domain clients don't accept a NULL ptr here */
5308 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5310 if (r->out.rids->ids == NULL) {
5311 return NT_STATUS_NO_MEMORY;
5314 return NT_STATUS_OK;
5317 /*********************************************************************
5318 _samr_GetMembersInAlias
5319 *********************************************************************/
5321 NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
5322 struct samr_GetMembersInAlias *r)
5324 struct samr_alias_info *ainfo;
5325 NTSTATUS status;
5326 size_t i;
5327 size_t num_sids = 0;
5328 struct lsa_SidPtr *sids = NULL;
5329 struct dom_sid *pdb_sids = NULL;
5330 struct dom_sid_buf buf;
5332 ainfo = policy_handle_find(p, r->in.alias_handle,
5333 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5334 struct samr_alias_info, &status);
5335 if (!NT_STATUS_IS_OK(status)) {
5336 return status;
5339 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
5341 become_root();
5342 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5343 &num_sids);
5344 unbecome_root();
5346 if (!NT_STATUS_IS_OK(status)) {
5347 return status;
5350 if (num_sids) {
5351 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr, num_sids);
5352 if (sids == NULL) {
5353 TALLOC_FREE(pdb_sids);
5354 return NT_STATUS_NO_MEMORY;
5358 for (i = 0; i < num_sids; i++) {
5359 sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
5360 if (!sids[i].sid) {
5361 TALLOC_FREE(pdb_sids);
5362 return NT_STATUS_NO_MEMORY;
5366 r->out.sids->num_sids = num_sids;
5367 r->out.sids->sids = sids;
5369 TALLOC_FREE(pdb_sids);
5371 return NT_STATUS_OK;
5374 /*********************************************************************
5375 _samr_QueryGroupMember
5376 *********************************************************************/
5378 NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
5379 struct samr_QueryGroupMember *r)
5381 struct samr_group_info *ginfo;
5382 size_t i, num_members;
5384 uint32_t *rid=NULL;
5385 uint32_t *attr=NULL;
5387 NTSTATUS status;
5388 struct samr_RidAttrArray *rids = NULL;
5389 struct dom_sid_buf buf;
5391 ginfo = policy_handle_find(p, r->in.group_handle,
5392 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5393 struct samr_group_info, &status);
5394 if (!NT_STATUS_IS_OK(status)) {
5395 return status;
5398 rids = talloc_zero(p->mem_ctx, struct samr_RidAttrArray);
5399 if (!rids) {
5400 return NT_STATUS_NO_MEMORY;
5403 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
5405 if (!sid_check_is_in_our_sam(&ginfo->sid)) {
5406 DEBUG(3, ("sid %s is not in our domain\n",
5407 dom_sid_str_buf(&ginfo->sid, &buf)));
5408 return NT_STATUS_NO_SUCH_GROUP;
5411 DEBUG(10, ("lookup on Domain SID\n"));
5413 become_root();
5414 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5415 &rid, &num_members);
5416 unbecome_root();
5418 if (!NT_STATUS_IS_OK(status))
5419 return status;
5421 if (num_members) {
5422 attr=talloc_zero_array(p->mem_ctx, uint32_t, num_members);
5423 if (attr == NULL) {
5424 return NT_STATUS_NO_MEMORY;
5426 } else {
5427 attr = NULL;
5430 for (i=0; i<num_members; i++) {
5431 attr[i] = SE_GROUP_MANDATORY |
5432 SE_GROUP_ENABLED_BY_DEFAULT |
5433 SE_GROUP_ENABLED;
5436 rids->count = num_members;
5437 rids->attributes = attr;
5438 rids->rids = rid;
5440 *r->out.rids = rids;
5442 return NT_STATUS_OK;
5445 /*********************************************************************
5446 _samr_AddAliasMember
5447 *********************************************************************/
5449 NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
5450 struct samr_AddAliasMember *r)
5452 struct samr_alias_info *ainfo;
5453 struct dom_sid_buf buf;
5454 NTSTATUS status;
5456 ainfo = policy_handle_find(p, r->in.alias_handle,
5457 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5458 struct samr_alias_info, &status);
5459 if (!NT_STATUS_IS_OK(status)) {
5460 return status;
5463 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
5465 /******** BEGIN SeAddUsers BLOCK *********/
5467 become_root();
5468 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5469 unbecome_root();
5471 /******** END SeAddUsers BLOCK *********/
5473 if (NT_STATUS_IS_OK(status)) {
5474 force_flush_samr_cache(&ainfo->sid);
5477 return status;
5480 /*********************************************************************
5481 _samr_DeleteAliasMember
5482 *********************************************************************/
5484 NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
5485 struct samr_DeleteAliasMember *r)
5487 struct samr_alias_info *ainfo;
5488 struct dom_sid_buf buf;
5489 NTSTATUS status;
5491 ainfo = policy_handle_find(p, r->in.alias_handle,
5492 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5493 struct samr_alias_info, &status);
5494 if (!NT_STATUS_IS_OK(status)) {
5495 return status;
5498 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5499 dom_sid_str_buf(&ainfo->sid, &buf)));
5501 /******** BEGIN SeAddUsers BLOCK *********/
5503 become_root();
5504 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5505 unbecome_root();
5507 /******** END SeAddUsers BLOCK *********/
5509 if (NT_STATUS_IS_OK(status)) {
5510 force_flush_samr_cache(&ainfo->sid);
5513 return status;
5516 /*********************************************************************
5517 _samr_AddGroupMember
5518 *********************************************************************/
5520 NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
5521 struct samr_AddGroupMember *r)
5523 struct samr_group_info *ginfo;
5524 struct dom_sid_buf buf;
5525 NTSTATUS status;
5526 uint32_t group_rid;
5528 ginfo = policy_handle_find(p, r->in.group_handle,
5529 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5530 struct samr_group_info, &status);
5531 if (!NT_STATUS_IS_OK(status)) {
5532 return status;
5535 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
5537 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5538 &group_rid)) {
5539 return NT_STATUS_INVALID_HANDLE;
5542 /******** BEGIN SeAddUsers BLOCK *********/
5544 become_root();
5545 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5546 unbecome_root();
5548 /******** END SeAddUsers BLOCK *********/
5550 force_flush_samr_cache(&ginfo->sid);
5552 return status;
5555 /*********************************************************************
5556 _samr_DeleteGroupMember
5557 *********************************************************************/
5559 NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
5560 struct samr_DeleteGroupMember *r)
5563 struct samr_group_info *ginfo;
5564 NTSTATUS status;
5565 uint32_t group_rid;
5568 * delete the group member named r->in.rid
5569 * who is a member of the sid associated with the handle
5570 * the rid is a user's rid as the group is a domain group.
5573 ginfo = policy_handle_find(p, r->in.group_handle,
5574 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5575 struct samr_group_info, &status);
5576 if (!NT_STATUS_IS_OK(status)) {
5577 return status;
5580 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5581 &group_rid)) {
5582 return NT_STATUS_INVALID_HANDLE;
5585 /******** BEGIN SeAddUsers BLOCK *********/
5587 become_root();
5588 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5589 unbecome_root();
5591 /******** END SeAddUsers BLOCK *********/
5593 force_flush_samr_cache(&ginfo->sid);
5595 return status;
5598 /*********************************************************************
5599 _samr_DeleteUser
5600 *********************************************************************/
5602 NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
5603 struct samr_DeleteUser *r)
5605 struct samr_user_info *uinfo;
5606 NTSTATUS status;
5607 struct samu *sam_pass=NULL;
5608 bool ret;
5610 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5612 uinfo = policy_handle_find(p, r->in.user_handle,
5613 SEC_STD_DELETE, NULL,
5614 struct samr_user_info, &status);
5615 if (!NT_STATUS_IS_OK(status)) {
5616 return status;
5619 if (!sid_check_is_in_our_sam(&uinfo->sid))
5620 return NT_STATUS_CANNOT_DELETE;
5622 /* check if the user exists before trying to delete */
5623 if ( !(sam_pass = samu_new( NULL )) ) {
5624 return NT_STATUS_NO_MEMORY;
5627 become_root();
5628 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5629 unbecome_root();
5631 if(!ret) {
5632 struct dom_sid_buf buf;
5633 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5634 dom_sid_str_buf(&uinfo->sid, &buf)));
5635 TALLOC_FREE(sam_pass);
5636 return NT_STATUS_NO_SUCH_USER;
5639 /******** BEGIN SeAddUsers BLOCK *********/
5641 become_root();
5642 status = pdb_delete_user(p->mem_ctx, sam_pass);
5643 unbecome_root();
5645 /******** END SeAddUsers BLOCK *********/
5647 if ( !NT_STATUS_IS_OK(status) ) {
5648 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5649 "user %s: %s.\n", pdb_get_username(sam_pass),
5650 nt_errstr(status)));
5651 TALLOC_FREE(sam_pass);
5652 return status;
5656 TALLOC_FREE(sam_pass);
5658 force_flush_samr_cache(&uinfo->sid);
5660 if (!close_policy_hnd(p, r->in.user_handle))
5661 return NT_STATUS_OBJECT_NAME_INVALID;
5663 ZERO_STRUCTP(r->out.user_handle);
5665 return NT_STATUS_OK;
5668 /*********************************************************************
5669 _samr_DeleteDomainGroup
5670 *********************************************************************/
5672 NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
5673 struct samr_DeleteDomainGroup *r)
5675 struct samr_group_info *ginfo;
5676 struct dom_sid_buf buf;
5677 NTSTATUS status;
5678 uint32_t group_rid;
5680 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5682 ginfo = policy_handle_find(p, r->in.group_handle,
5683 SEC_STD_DELETE, NULL,
5684 struct samr_group_info, &status);
5685 if (!NT_STATUS_IS_OK(status)) {
5686 return status;
5689 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
5691 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5692 &group_rid)) {
5693 return NT_STATUS_NO_SUCH_GROUP;
5696 /******** BEGIN SeAddUsers BLOCK *********/
5698 become_root();
5699 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5700 unbecome_root();
5702 /******** END SeAddUsers BLOCK *********/
5704 if ( !NT_STATUS_IS_OK(status) ) {
5705 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5706 "entry for group %s: %s\n",
5707 dom_sid_str_buf(&ginfo->sid, &buf),
5708 nt_errstr(status)));
5709 return status;
5712 force_flush_samr_cache(&ginfo->sid);
5714 if (!close_policy_hnd(p, r->in.group_handle))
5715 return NT_STATUS_OBJECT_NAME_INVALID;
5717 return NT_STATUS_OK;
5720 /*********************************************************************
5721 _samr_DeleteDomAlias
5722 *********************************************************************/
5724 NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
5725 struct samr_DeleteDomAlias *r)
5727 struct samr_alias_info *ainfo;
5728 struct dom_sid_buf buf;
5729 NTSTATUS status;
5731 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5733 ainfo = policy_handle_find(p, r->in.alias_handle,
5734 SEC_STD_DELETE, NULL,
5735 struct samr_alias_info, &status);
5736 if (!NT_STATUS_IS_OK(status)) {
5737 return status;
5740 DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
5742 /* Don't let Windows delete builtin groups */
5744 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5745 return NT_STATUS_SPECIAL_ACCOUNT;
5748 if (!sid_check_is_in_our_sam(&ainfo->sid))
5749 return NT_STATUS_NO_SUCH_ALIAS;
5751 DEBUG(10, ("lookup on Local SID\n"));
5753 /******** BEGIN SeAddUsers BLOCK *********/
5755 become_root();
5756 /* Have passdb delete the alias */
5757 status = pdb_delete_alias(&ainfo->sid);
5758 unbecome_root();
5760 /******** END SeAddUsers BLOCK *********/
5762 if ( !NT_STATUS_IS_OK(status))
5763 return status;
5765 force_flush_samr_cache(&ainfo->sid);
5767 if (!close_policy_hnd(p, r->in.alias_handle))
5768 return NT_STATUS_OBJECT_NAME_INVALID;
5770 return NT_STATUS_OK;
5773 /*********************************************************************
5774 _samr_CreateDomainGroup
5775 *********************************************************************/
5777 NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
5778 struct samr_CreateDomainGroup *r)
5781 NTSTATUS status;
5782 const char *name;
5783 struct samr_domain_info *dinfo;
5784 struct samr_group_info *ginfo;
5786 dinfo = policy_handle_find(p, r->in.domain_handle,
5787 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5788 struct samr_domain_info, &status);
5789 if (!NT_STATUS_IS_OK(status)) {
5790 return status;
5793 if (!sid_check_is_our_sam(&dinfo->sid)) {
5794 return NT_STATUS_ACCESS_DENIED;
5797 name = r->in.name->string;
5798 if (name == NULL) {
5799 return NT_STATUS_NO_MEMORY;
5802 status = can_create(p->mem_ctx, name);
5803 if (!NT_STATUS_IS_OK(status)) {
5804 return status;
5807 /******** BEGIN SeAddUsers BLOCK *********/
5809 become_root();
5810 /* check that we successfully create the UNIX group */
5811 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5812 unbecome_root();
5814 /******** END SeAddUsers BLOCK *********/
5816 /* check if we should bail out here */
5818 if ( !NT_STATUS_IS_OK(status) )
5819 return status;
5821 ginfo = policy_handle_create(p, r->out.group_handle,
5822 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5823 struct samr_group_info, &status);
5824 if (!NT_STATUS_IS_OK(status)) {
5825 return status;
5827 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5829 force_flush_samr_cache(&dinfo->sid);
5831 return NT_STATUS_OK;
5834 /*********************************************************************
5835 _samr_CreateDomAlias
5836 *********************************************************************/
5838 NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
5839 struct samr_CreateDomAlias *r)
5841 struct dom_sid info_sid;
5842 const char *name = NULL;
5843 struct samr_domain_info *dinfo;
5844 struct samr_alias_info *ainfo;
5845 gid_t gid;
5846 NTSTATUS result;
5848 dinfo = policy_handle_find(p, r->in.domain_handle,
5849 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5850 struct samr_domain_info, &result);
5851 if (!NT_STATUS_IS_OK(result)) {
5852 return result;
5855 if (!sid_check_is_our_sam(&dinfo->sid)) {
5856 return NT_STATUS_ACCESS_DENIED;
5859 name = r->in.alias_name->string;
5861 result = can_create(p->mem_ctx, name);
5862 if (!NT_STATUS_IS_OK(result)) {
5863 return result;
5866 /******** BEGIN SeAddUsers BLOCK *********/
5868 become_root();
5869 /* Have passdb create the alias */
5870 result = pdb_create_alias(name, r->out.rid);
5871 unbecome_root();
5873 /******** END SeAddUsers BLOCK *********/
5875 if (!NT_STATUS_IS_OK(result)) {
5876 DEBUG(10, ("pdb_create_alias failed: %s\n",
5877 nt_errstr(result)));
5878 return result;
5881 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5883 if (!sid_to_gid(&info_sid, &gid)) {
5884 DEBUG(10, ("Could not find alias just created\n"));
5885 return NT_STATUS_ACCESS_DENIED;
5888 /* check if the group has been successfully created */
5889 if ( getgrgid(gid) == NULL ) {
5890 DEBUG(1, ("getgrgid(%u) of just created alias failed\n",
5891 (unsigned int)gid));
5892 return NT_STATUS_ACCESS_DENIED;
5895 ainfo = policy_handle_create(p, r->out.alias_handle,
5896 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5897 struct samr_alias_info, &result);
5898 if (!NT_STATUS_IS_OK(result)) {
5899 return result;
5901 ainfo->sid = info_sid;
5903 force_flush_samr_cache(&info_sid);
5905 return NT_STATUS_OK;
5908 /*********************************************************************
5909 _samr_QueryGroupInfo
5910 *********************************************************************/
5912 NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
5913 struct samr_QueryGroupInfo *r)
5915 struct samr_group_info *ginfo;
5916 NTSTATUS status;
5917 GROUP_MAP *map;
5918 union samr_GroupInfo *info = NULL;
5919 bool ret;
5920 uint32_t attributes = SE_GROUP_MANDATORY |
5921 SE_GROUP_ENABLED_BY_DEFAULT |
5922 SE_GROUP_ENABLED;
5923 const char *group_name = NULL;
5924 const char *group_description = NULL;
5926 ginfo = policy_handle_find(p, r->in.group_handle,
5927 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5928 struct samr_group_info, &status);
5929 if (!NT_STATUS_IS_OK(status)) {
5930 return status;
5933 map = talloc_zero(p->mem_ctx, GROUP_MAP);
5934 if (!map) {
5935 return NT_STATUS_NO_MEMORY;
5938 become_root();
5939 ret = get_domain_group_from_sid(ginfo->sid, map);
5940 unbecome_root();
5941 if (!ret)
5942 return NT_STATUS_INVALID_HANDLE;
5944 group_name = talloc_move(r, &map->nt_name);
5945 group_description = talloc_move(r, &map->comment);
5947 TALLOC_FREE(map);
5949 info = talloc_zero(p->mem_ctx, union samr_GroupInfo);
5950 if (!info) {
5951 return NT_STATUS_NO_MEMORY;
5954 switch (r->in.level) {
5955 case 1: {
5956 uint32_t *members;
5957 size_t num_members;
5959 become_root();
5960 status = pdb_enum_group_members(
5961 p->mem_ctx, &ginfo->sid, &members,
5962 &num_members);
5963 unbecome_root();
5965 if (!NT_STATUS_IS_OK(status)) {
5966 return status;
5969 info->all.name.string = group_name;
5970 info->all.attributes = attributes;
5971 info->all.num_members = num_members;
5972 info->all.description.string = group_description;
5973 break;
5975 case 2:
5976 info->name.string = group_name;
5977 break;
5978 case 3:
5979 info->attributes.attributes = attributes;
5980 break;
5981 case 4:
5982 info->description.string = group_description;
5983 break;
5984 case 5: {
5986 uint32_t *members;
5987 size_t num_members;
5991 become_root();
5992 status = pdb_enum_group_members(
5993 p->mem_ctx, &ginfo->sid, &members,
5994 &num_members);
5995 unbecome_root();
5997 if (!NT_STATUS_IS_OK(status)) {
5998 return status;
6001 info->all2.name.string = group_name;
6002 info->all2.attributes = attributes;
6003 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
6004 info->all2.description.string = group_description;
6006 break;
6008 default:
6009 return NT_STATUS_INVALID_INFO_CLASS;
6012 *r->out.info = info;
6014 return NT_STATUS_OK;
6017 /*********************************************************************
6018 _samr_SetGroupInfo
6019 *********************************************************************/
6021 NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
6022 struct samr_SetGroupInfo *r)
6024 struct samr_group_info *ginfo;
6025 GROUP_MAP *map;
6026 NTSTATUS status;
6027 bool ret;
6029 ginfo = policy_handle_find(p, r->in.group_handle,
6030 SAMR_GROUP_ACCESS_SET_INFO, NULL,
6031 struct samr_group_info, &status);
6032 if (!NT_STATUS_IS_OK(status)) {
6033 return status;
6036 map = talloc_zero(p->mem_ctx, GROUP_MAP);
6037 if (!map) {
6038 return NT_STATUS_NO_MEMORY;
6041 become_root();
6042 ret = get_domain_group_from_sid(ginfo->sid, map);
6043 unbecome_root();
6044 if (!ret)
6045 return NT_STATUS_NO_SUCH_GROUP;
6047 switch (r->in.level) {
6048 case 2:
6049 map->nt_name = talloc_strdup(map,
6050 r->in.info->name.string);
6051 if (!map->nt_name) {
6052 return NT_STATUS_NO_MEMORY;
6054 break;
6055 case 3:
6056 break;
6057 case 4:
6058 map->comment = talloc_strdup(map,
6059 r->in.info->description.string);
6060 if (!map->comment) {
6061 return NT_STATUS_NO_MEMORY;
6063 break;
6064 default:
6065 return NT_STATUS_INVALID_INFO_CLASS;
6068 /******** BEGIN SeAddUsers BLOCK *********/
6070 become_root();
6071 status = pdb_update_group_mapping_entry(map);
6072 unbecome_root();
6074 /******** End SeAddUsers BLOCK *********/
6076 TALLOC_FREE(map);
6078 if (NT_STATUS_IS_OK(status)) {
6079 force_flush_samr_cache(&ginfo->sid);
6082 return status;
6085 /*********************************************************************
6086 _samr_SetAliasInfo
6087 *********************************************************************/
6089 NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
6090 struct samr_SetAliasInfo *r)
6092 struct samr_alias_info *ainfo;
6093 struct acct_info *info;
6094 NTSTATUS status;
6096 ainfo = policy_handle_find(p, r->in.alias_handle,
6097 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6098 struct samr_alias_info, &status);
6099 if (!NT_STATUS_IS_OK(status)) {
6100 return status;
6103 info = talloc_zero(p->mem_ctx, struct acct_info);
6104 if (!info) {
6105 return NT_STATUS_NO_MEMORY;
6108 /* get the current group information */
6110 become_root();
6111 status = pdb_get_aliasinfo(&ainfo->sid, info);
6112 unbecome_root();
6114 if ( !NT_STATUS_IS_OK(status))
6115 return status;
6117 switch (r->in.level) {
6118 case ALIASINFONAME:
6120 char *group_name;
6122 /* We currently do not support renaming groups in the
6123 the BUILTIN domain. Refer to util_builtin.c to understand
6124 why. The eventually needs to be fixed to be like Windows
6125 where you can rename builtin groups, just not delete them */
6127 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6128 return NT_STATUS_SPECIAL_ACCOUNT;
6131 /* There has to be a valid name (and it has to be different) */
6133 if ( !r->in.info->name.string )
6134 return NT_STATUS_INVALID_PARAMETER;
6136 /* If the name is the same just reply "ok". Yes this
6137 doesn't allow you to change the case of a group name. */
6139 if (strequal(r->in.info->name.string, info->acct_name)) {
6140 return NT_STATUS_OK;
6143 talloc_free(info->acct_name);
6144 info->acct_name = talloc_strdup(info, r->in.info->name.string);
6145 if (!info->acct_name) {
6146 return NT_STATUS_NO_MEMORY;
6149 /* make sure the name doesn't already exist as a user
6150 or local group */
6152 group_name = talloc_asprintf(p->mem_ctx,
6153 "%s\\%s",
6154 lp_netbios_name(),
6155 info->acct_name);
6156 if (group_name == NULL) {
6157 return NT_STATUS_NO_MEMORY;
6160 status = can_create( p->mem_ctx, group_name );
6161 talloc_free(group_name);
6162 if ( !NT_STATUS_IS_OK( status ) )
6163 return status;
6164 break;
6166 case ALIASINFODESCRIPTION:
6167 TALLOC_FREE(info->acct_desc);
6168 if (r->in.info->description.string) {
6169 info->acct_desc = talloc_strdup(info,
6170 r->in.info->description.string);
6171 } else {
6172 info->acct_desc = talloc_strdup(info, "");
6174 if (!info->acct_desc) {
6175 return NT_STATUS_NO_MEMORY;
6177 break;
6178 default:
6179 return NT_STATUS_INVALID_INFO_CLASS;
6182 /******** BEGIN SeAddUsers BLOCK *********/
6184 become_root();
6185 status = pdb_set_aliasinfo(&ainfo->sid, info);
6186 unbecome_root();
6188 /******** End SeAddUsers BLOCK *********/
6190 if (NT_STATUS_IS_OK(status))
6191 force_flush_samr_cache(&ainfo->sid);
6193 return status;
6196 /****************************************************************
6197 _samr_GetDomPwInfo
6198 ****************************************************************/
6200 NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
6201 struct samr_GetDomPwInfo *r)
6203 uint32_t min_password_length = 0;
6204 uint32_t password_properties = 0;
6206 /* Perform access check. Since this rpc does not require a
6207 policy handle it will not be caught by the access checks on
6208 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6210 if (!pipe_access_check(p)) {
6211 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6212 return NT_STATUS_ACCESS_DENIED;
6215 become_root();
6216 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6217 &min_password_length);
6218 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6219 &password_properties);
6220 unbecome_root();
6222 if (lp_check_password_script(talloc_tos()) && *lp_check_password_script(talloc_tos())) {
6223 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6226 r->out.info->min_password_length = min_password_length;
6227 r->out.info->password_properties = password_properties;
6229 return NT_STATUS_OK;
6232 /*********************************************************************
6233 _samr_OpenGroup
6234 *********************************************************************/
6236 NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
6237 struct samr_OpenGroup *r)
6240 struct dom_sid info_sid;
6241 struct dom_sid_buf buf;
6242 GROUP_MAP *map;
6243 struct samr_domain_info *dinfo;
6244 struct samr_group_info *ginfo;
6245 struct security_descriptor *psd = NULL;
6246 uint32_t acc_granted;
6247 uint32_t des_access = r->in.access_mask;
6248 size_t sd_size;
6249 NTSTATUS status;
6250 bool ret;
6252 dinfo = policy_handle_find(p, r->in.domain_handle,
6253 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6254 struct samr_domain_info, &status);
6255 if (!NT_STATUS_IS_OK(status)) {
6256 return status;
6259 /*check if access can be granted as requested by client. */
6260 map_max_allowed_access(p->session_info->security_token,
6261 p->session_info->unix_token,
6262 &des_access);
6264 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6265 se_map_generic(&des_access,&grp_generic_mapping);
6267 status = access_check_object(psd, p->session_info->security_token,
6268 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6269 des_access, &acc_granted, "_samr_OpenGroup");
6271 if ( !NT_STATUS_IS_OK(status) )
6272 return status;
6274 /* this should not be hard-coded like this */
6276 if (!sid_check_is_our_sam(&dinfo->sid)) {
6277 return NT_STATUS_ACCESS_DENIED;
6280 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6282 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6283 dom_sid_str_buf(&info_sid, &buf)));
6285 map = talloc_zero(p->mem_ctx, GROUP_MAP);
6286 if (!map) {
6287 return NT_STATUS_NO_MEMORY;
6290 /* check if that group really exists */
6291 become_root();
6292 ret = get_domain_group_from_sid(info_sid, map);
6293 unbecome_root();
6294 if (!ret)
6295 return NT_STATUS_NO_SUCH_GROUP;
6297 TALLOC_FREE(map);
6299 ginfo = policy_handle_create(p, r->out.group_handle,
6300 acc_granted,
6301 struct samr_group_info, &status);
6302 if (!NT_STATUS_IS_OK(status)) {
6303 return status;
6305 ginfo->sid = info_sid;
6307 return NT_STATUS_OK;
6310 /*********************************************************************
6311 _samr_RemoveMemberFromForeignDomain
6312 *********************************************************************/
6314 NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
6315 struct samr_RemoveMemberFromForeignDomain *r)
6317 struct samr_domain_info *dinfo;
6318 struct dom_sid_buf buf;
6319 NTSTATUS result;
6321 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6322 dom_sid_str_buf(r->in.sid, &buf)));
6324 /* Find the policy handle. Open a policy on it. */
6326 dinfo = policy_handle_find(p, r->in.domain_handle,
6327 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6328 struct samr_domain_info, &result);
6329 if (!NT_STATUS_IS_OK(result)) {
6330 return result;
6333 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6334 dom_sid_str_buf(&dinfo->sid, &buf)));
6336 /* we can only delete a user from a group since we don't have
6337 nested groups anyways. So in the latter case, just say OK */
6339 /* TODO: The above comment nowadays is bogus. Since we have nested
6340 * groups now, and aliases members are never reported out of the unix
6341 * group membership, the "just say OK" makes this call a no-op. For
6342 * us. This needs fixing however. */
6344 /* I've only ever seen this in the wild when deleting a user from
6345 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6346 * is the user about to be deleted. I very much suspect this is the
6347 * only application of this call. To verify this, let people report
6348 * other cases. */
6350 if (!sid_check_is_builtin(&dinfo->sid)) {
6351 struct dom_sid_buf buf2;
6352 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6353 "global_sam_sid() = %s\n",
6354 dom_sid_str_buf(&dinfo->sid, &buf),
6355 dom_sid_str_buf(get_global_sam_sid(), &buf2)));
6356 DEBUGADD(1,("please report to samba-technical@lists.samba.org!\n"));
6357 return NT_STATUS_OK;
6360 force_flush_samr_cache(&dinfo->sid);
6362 result = NT_STATUS_OK;
6364 return result;
6367 /*******************************************************************
6368 _samr_QueryDomainInfo2
6369 ********************************************************************/
6371 NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
6372 struct samr_QueryDomainInfo2 *r)
6374 struct samr_QueryDomainInfo q;
6376 q.in.domain_handle = r->in.domain_handle;
6377 q.in.level = r->in.level;
6379 q.out.info = r->out.info;
6381 return _samr_QueryDomainInfo(p, &q);
6384 /*******************************************************************
6385 ********************************************************************/
6387 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6388 struct samr_DomInfo1 *r)
6390 time_t u_expire, u_min_age;
6392 u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6393 u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6395 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6396 (uint32_t)r->min_password_length);
6397 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6398 (uint32_t)r->password_history_length);
6399 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6400 (uint32_t)r->password_properties);
6401 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6402 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6404 return NT_STATUS_OK;
6407 /*******************************************************************
6408 ********************************************************************/
6410 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6411 struct samr_DomInfo3 *r)
6413 time_t u_logout;
6415 u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6417 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6419 return NT_STATUS_OK;
6422 /*******************************************************************
6423 ********************************************************************/
6425 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6426 struct samr_DomInfo12 *r)
6428 time_t u_lock_duration, u_reset_time;
6431 * It is not possible to set lockout_duration < lockout_window.
6432 * (The test is the other way around since the negative numbers
6433 * are stored...)
6435 * This constraint is documented here for the samr rpc service:
6436 * MS-SAMR 3.1.1.6 Attribute Constraints for Originating Updates
6437 * http://msdn.microsoft.com/en-us/library/cc245667%28PROT.10%29.aspx
6439 * And here for the ldap backend:
6440 * MS-ADTS 3.1.1.5.3.2 Constraints
6441 * http://msdn.microsoft.com/en-us/library/cc223462(PROT.10).aspx
6443 if (r->lockout_duration > r->lockout_window) {
6444 return NT_STATUS_INVALID_PARAMETER;
6447 u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6448 if (u_lock_duration != -1) {
6449 u_lock_duration /= 60;
6452 u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6454 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6455 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6456 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6457 (uint32_t)r->lockout_threshold);
6459 return NT_STATUS_OK;
6462 /*******************************************************************
6463 _samr_SetDomainInfo
6464 ********************************************************************/
6466 NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
6467 struct samr_SetDomainInfo *r)
6469 NTSTATUS status;
6470 uint32_t acc_required = 0;
6472 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6474 switch (r->in.level) {
6475 case 1: /* DomainPasswordInformation */
6476 case 12: /* DomainLockoutInformation */
6477 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6478 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6479 break;
6480 case 3: /* DomainLogoffInformation */
6481 case 4: /* DomainOemInformation */
6482 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6483 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6484 break;
6485 case 6: /* DomainReplicationInformation */
6486 case 9: /* DomainStateInformation */
6487 case 7: /* DomainServerRoleInformation */
6488 /* DOMAIN_ADMINISTER_SERVER */
6489 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6490 break;
6491 default:
6492 return NT_STATUS_INVALID_INFO_CLASS;
6495 (void)policy_handle_find(p, r->in.domain_handle,
6496 acc_required, NULL,
6497 struct samr_domain_info, &status);
6498 if (!NT_STATUS_IS_OK(status)) {
6499 return status;
6502 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6504 switch (r->in.level) {
6505 case 1:
6506 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6507 break;
6508 case 3:
6509 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6510 break;
6511 case 4:
6512 break;
6513 case 6:
6514 break;
6515 case 7:
6516 break;
6517 case 9:
6518 break;
6519 case 12:
6520 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6521 break;
6522 default:
6523 return NT_STATUS_INVALID_INFO_CLASS;
6526 if (!NT_STATUS_IS_OK(status)) {
6527 return status;
6530 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6532 return NT_STATUS_OK;
6535 /****************************************************************
6536 _samr_GetDisplayEnumerationIndex
6537 ****************************************************************/
6539 NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
6540 struct samr_GetDisplayEnumerationIndex *r)
6542 struct samr_domain_info *dinfo;
6543 uint32_t max_entries = (uint32_t) -1;
6544 uint32_t enum_context = 0;
6545 int i;
6546 uint32_t num_account = 0;
6547 struct samr_displayentry *entries = NULL;
6548 NTSTATUS status;
6550 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6552 dinfo = policy_handle_find(p, r->in.domain_handle,
6553 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6554 struct samr_domain_info, &status);
6555 if (!NT_STATUS_IS_OK(status)) {
6556 return status;
6559 if ((r->in.level < 1) || (r->in.level > 3)) {
6560 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6561 "Unknown info level (%u)\n",
6562 r->in.level));
6563 return NT_STATUS_INVALID_INFO_CLASS;
6566 become_root();
6568 /* The following done as ROOT. Don't return without unbecome_root(). */
6570 switch (r->in.level) {
6571 case 1:
6572 if (dinfo->disp_info->users == NULL) {
6573 dinfo->disp_info->users = pdb_search_users(
6574 dinfo->disp_info, ACB_NORMAL);
6575 if (dinfo->disp_info->users == NULL) {
6576 unbecome_root();
6577 return NT_STATUS_ACCESS_DENIED;
6579 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6580 "starting user enumeration at index %u\n",
6581 (unsigned int)enum_context));
6582 } else {
6583 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6584 "using cached user enumeration at index %u\n",
6585 (unsigned int)enum_context));
6587 num_account = pdb_search_entries(dinfo->disp_info->users,
6588 enum_context, max_entries,
6589 &entries);
6590 break;
6591 case 2:
6592 if (dinfo->disp_info->machines == NULL) {
6593 dinfo->disp_info->machines = pdb_search_users(
6594 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6595 if (dinfo->disp_info->machines == NULL) {
6596 unbecome_root();
6597 return NT_STATUS_ACCESS_DENIED;
6599 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6600 "starting machine enumeration at index %u\n",
6601 (unsigned int)enum_context));
6602 } else {
6603 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6604 "using cached machine enumeration at index %u\n",
6605 (unsigned int)enum_context));
6607 num_account = pdb_search_entries(dinfo->disp_info->machines,
6608 enum_context, max_entries,
6609 &entries);
6610 break;
6611 case 3:
6612 if (dinfo->disp_info->groups == NULL) {
6613 dinfo->disp_info->groups = pdb_search_groups(
6614 dinfo->disp_info);
6615 if (dinfo->disp_info->groups == NULL) {
6616 unbecome_root();
6617 return NT_STATUS_ACCESS_DENIED;
6619 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6620 "starting group enumeration at index %u\n",
6621 (unsigned int)enum_context));
6622 } else {
6623 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6624 "using cached group enumeration at index %u\n",
6625 (unsigned int)enum_context));
6627 num_account = pdb_search_entries(dinfo->disp_info->groups,
6628 enum_context, max_entries,
6629 &entries);
6630 break;
6631 default:
6632 unbecome_root();
6633 smb_panic("info class changed");
6634 break;
6637 unbecome_root();
6639 /* Ensure we cache this enumeration. */
6640 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6642 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6643 r->in.name->string));
6645 for (i=0; i<num_account; i++) {
6646 if (strequal(entries[i].account_name, r->in.name->string)) {
6647 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6648 "found %s at idx %d\n",
6649 r->in.name->string, i));
6650 *r->out.idx = i;
6651 return NT_STATUS_OK;
6655 /* assuming account_name lives at the very end */
6656 *r->out.idx = num_account;
6658 return NT_STATUS_NO_MORE_ENTRIES;
6661 /****************************************************************
6662 _samr_GetDisplayEnumerationIndex2
6663 ****************************************************************/
6665 NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
6666 struct samr_GetDisplayEnumerationIndex2 *r)
6668 struct samr_GetDisplayEnumerationIndex q;
6670 q.in.domain_handle = r->in.domain_handle;
6671 q.in.level = r->in.level;
6672 q.in.name = r->in.name;
6674 q.out.idx = r->out.idx;
6676 return _samr_GetDisplayEnumerationIndex(p, &q);
6679 /****************************************************************
6680 _samr_RidToSid
6681 ****************************************************************/
6683 NTSTATUS _samr_RidToSid(struct pipes_struct *p,
6684 struct samr_RidToSid *r)
6686 struct samr_domain_info *dinfo;
6687 NTSTATUS status;
6688 struct dom_sid sid;
6690 dinfo = policy_handle_find(p, r->in.domain_handle,
6691 0, NULL,
6692 struct samr_domain_info, &status);
6693 if (!NT_STATUS_IS_OK(status)) {
6694 return status;
6697 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6698 return NT_STATUS_NO_MEMORY;
6701 *r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
6702 if (!*r->out.sid) {
6703 return NT_STATUS_NO_MEMORY;
6706 return NT_STATUS_OK;
6709 /****************************************************************
6710 ****************************************************************/
6712 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
6713 const struct samr_PwInfo *dom_pw_info,
6714 const struct samr_ValidatePasswordReq2 *req,
6715 struct samr_ValidatePasswordRepCtr *rep)
6717 NTSTATUS status;
6719 if (req->password.string == NULL) {
6720 return SAMR_VALIDATION_STATUS_SUCCESS;
6722 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6723 ZERO_STRUCT(rep->info);
6724 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6726 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6727 status = check_password_complexity(req->account.string,
6728 NULL, /* full_name */
6729 req->password.string,
6730 NULL);
6731 if (!NT_STATUS_IS_OK(status)) {
6732 ZERO_STRUCT(rep->info);
6733 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6737 return SAMR_VALIDATION_STATUS_SUCCESS;
6740 /****************************************************************
6741 ****************************************************************/
6743 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
6744 const struct samr_PwInfo *dom_pw_info,
6745 const struct samr_ValidatePasswordReq3 *req,
6746 struct samr_ValidatePasswordRepCtr *rep)
6748 NTSTATUS status;
6750 if (req->password.string == NULL) {
6751 return SAMR_VALIDATION_STATUS_SUCCESS;
6753 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6754 ZERO_STRUCT(rep->info);
6755 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6757 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6758 status = check_password_complexity(req->account.string,
6759 NULL, /* full_name */
6760 req->password.string,
6761 NULL);
6762 if (!NT_STATUS_IS_OK(status)) {
6763 ZERO_STRUCT(rep->info);
6764 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6768 return SAMR_VALIDATION_STATUS_SUCCESS;
6771 /****************************************************************
6772 _samr_ValidatePassword
6773 ****************************************************************/
6775 NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
6776 struct samr_ValidatePassword *r)
6778 union samr_ValidatePasswordRep *rep;
6779 NTSTATUS status;
6780 struct samr_GetDomPwInfo pw;
6781 struct samr_PwInfo dom_pw_info;
6783 if (p->transport != NCACN_IP_TCP && p->transport != NCALRPC) {
6784 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
6785 return NT_STATUS_ACCESS_DENIED;
6788 if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
6789 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
6790 return NT_STATUS_ACCESS_DENIED;
6793 if (r->in.level < 1 || r->in.level > 3) {
6794 return NT_STATUS_INVALID_INFO_CLASS;
6797 pw.in.domain_name = NULL;
6798 pw.out.info = &dom_pw_info;
6800 status = _samr_GetDomPwInfo(p, &pw);
6801 if (!NT_STATUS_IS_OK(status)) {
6802 return status;
6805 rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
6806 if (!rep) {
6807 return NT_STATUS_NO_MEMORY;
6810 switch (r->in.level) {
6811 case 1:
6812 status = NT_STATUS_NOT_SUPPORTED;
6813 break;
6814 case 2:
6815 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
6816 &dom_pw_info,
6817 &r->in.req->req2,
6818 &rep->ctr2);
6819 break;
6820 case 3:
6821 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
6822 &dom_pw_info,
6823 &r->in.req->req3,
6824 &rep->ctr3);
6825 break;
6826 default:
6827 status = NT_STATUS_INVALID_INFO_CLASS;
6828 break;
6831 if (!NT_STATUS_IS_OK(status)) {
6832 talloc_free(rep);
6833 return status;
6836 *r->out.rep = rep;
6838 return NT_STATUS_OK;
6841 /****************************************************************
6842 ****************************************************************/
6844 NTSTATUS _samr_Shutdown(struct pipes_struct *p,
6845 struct samr_Shutdown *r)
6847 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6848 return NT_STATUS_NOT_IMPLEMENTED;
6851 /****************************************************************
6852 ****************************************************************/
6854 NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
6855 struct samr_SetMemberAttributesOfGroup *r)
6857 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6858 return NT_STATUS_NOT_IMPLEMENTED;
6861 /****************************************************************
6862 ****************************************************************/
6864 NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
6865 struct samr_TestPrivateFunctionsDomain *r)
6867 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6868 return NT_STATUS_NOT_IMPLEMENTED;
6871 /****************************************************************
6872 ****************************************************************/
6874 NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
6875 struct samr_TestPrivateFunctionsUser *r)
6877 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6878 return NT_STATUS_NOT_IMPLEMENTED;
6881 /****************************************************************
6882 ****************************************************************/
6884 NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
6885 struct samr_AddMultipleMembersToAlias *r)
6887 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6888 return NT_STATUS_NOT_IMPLEMENTED;
6891 /****************************************************************
6892 ****************************************************************/
6894 NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
6895 struct samr_RemoveMultipleMembersFromAlias *r)
6897 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6898 return NT_STATUS_NOT_IMPLEMENTED;
6901 /****************************************************************
6902 ****************************************************************/
6904 NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
6905 struct samr_SetBootKeyInformation *r)
6907 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6908 return NT_STATUS_NOT_IMPLEMENTED;
6911 /****************************************************************
6912 ****************************************************************/
6914 NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
6915 struct samr_GetBootKeyInformation *r)
6917 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6918 return NT_STATUS_NOT_IMPLEMENTED;
6921 /****************************************************************
6922 ****************************************************************/
6924 NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
6925 struct samr_SetDsrmPassword *r)
6927 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6928 return NT_STATUS_NOT_IMPLEMENTED;