Update mailing list references to point at lists.samba.org
[Samba.git] / source3 / rpc_server / samr / srv_samr_nt.c
blob0a7a915a1c90ebd6c0fb54372dac0af21f9e5138
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"
49 #undef DBGC_CLASS
50 #define DBGC_CLASS DBGC_RPC_SRV
52 #define SAMR_USR_RIGHTS_WRITE_PW \
53 ( READ_CONTROL_ACCESS | \
54 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
55 SAMR_USER_ACCESS_SET_LOC_COM)
56 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
57 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
59 #define DISP_INFO_CACHE_TIMEOUT 10
61 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
62 #define MAX_SAM_ENTRIES_W95 50
64 struct samr_connect_info {
65 uint8_t dummy;
68 struct samr_domain_info {
69 struct dom_sid sid;
70 struct disp_info *disp_info;
73 struct samr_user_info {
74 struct dom_sid sid;
77 struct samr_group_info {
78 struct dom_sid sid;
81 struct samr_alias_info {
82 struct dom_sid sid;
85 typedef struct disp_info {
86 struct dom_sid sid; /* identify which domain this is. */
87 struct pdb_search *users; /* querydispinfo 1 and 4 */
88 struct pdb_search *machines; /* querydispinfo 2 */
89 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
90 struct pdb_search *aliases; /* enumaliases */
92 uint32_t enum_acb_mask;
93 struct pdb_search *enum_users; /* enumusers with a mask */
95 struct tevent_timer *cache_timeout_event; /* cache idle timeout
96 * handler. */
97 } DISP_INFO;
99 static const struct generic_mapping sam_generic_mapping = {
100 GENERIC_RIGHTS_SAM_READ,
101 GENERIC_RIGHTS_SAM_WRITE,
102 GENERIC_RIGHTS_SAM_EXECUTE,
103 GENERIC_RIGHTS_SAM_ALL_ACCESS};
104 static const struct generic_mapping dom_generic_mapping = {
105 GENERIC_RIGHTS_DOMAIN_READ,
106 GENERIC_RIGHTS_DOMAIN_WRITE,
107 GENERIC_RIGHTS_DOMAIN_EXECUTE,
108 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
109 static const struct generic_mapping usr_generic_mapping = {
110 GENERIC_RIGHTS_USER_READ,
111 GENERIC_RIGHTS_USER_WRITE,
112 GENERIC_RIGHTS_USER_EXECUTE,
113 GENERIC_RIGHTS_USER_ALL_ACCESS};
114 static const struct generic_mapping usr_nopwchange_generic_mapping = {
115 GENERIC_RIGHTS_USER_READ,
116 GENERIC_RIGHTS_USER_WRITE,
117 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
118 GENERIC_RIGHTS_USER_ALL_ACCESS};
119 static const struct generic_mapping grp_generic_mapping = {
120 GENERIC_RIGHTS_GROUP_READ,
121 GENERIC_RIGHTS_GROUP_WRITE,
122 GENERIC_RIGHTS_GROUP_EXECUTE,
123 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
124 static const struct generic_mapping ali_generic_mapping = {
125 GENERIC_RIGHTS_ALIAS_READ,
126 GENERIC_RIGHTS_ALIAS_WRITE,
127 GENERIC_RIGHTS_ALIAS_EXECUTE,
128 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
130 /*******************************************************************
131 *******************************************************************/
133 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
134 const struct generic_mapping *map,
135 struct dom_sid *sid, uint32 sid_access )
137 struct dom_sid domadmin_sid;
138 struct security_ace ace[5]; /* at most 5 entries */
139 size_t i = 0;
141 struct security_acl *psa = NULL;
143 /* basic access for Everyone */
145 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
146 map->generic_execute | map->generic_read, 0);
148 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
150 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
151 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
152 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
153 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
155 /* Add Full Access for Domain Admins if we are a DC */
157 if ( IS_DC ) {
158 sid_compose(&domadmin_sid, get_global_sam_sid(),
159 DOMAIN_RID_ADMINS);
160 init_sec_ace(&ace[i++], &domadmin_sid,
161 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
164 /* if we have a sid, give it some special access */
166 if ( sid ) {
167 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
170 /* create the security descriptor */
172 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
173 return NT_STATUS_NO_MEMORY;
175 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
176 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
177 psa, sd_size)) == NULL)
178 return NT_STATUS_NO_MEMORY;
180 return NT_STATUS_OK;
183 /*******************************************************************
184 Fetch or create a dispinfo struct.
185 ********************************************************************/
187 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
190 * We do a static cache for DISP_INFO's here. Explanation can be found
191 * in Jeremy's checkin message to r11793:
193 * Fix the SAMR cache so it works across completely insane
194 * client behaviour (ie.:
195 * open pipe/open SAMR handle/enumerate 0 - 1024
196 * close SAMR handle, close pipe.
197 * open pipe/open SAMR handle/enumerate 1024 - 2048...
198 * close SAMR handle, close pipe.
199 * And on ad-nausium. Amazing.... probably object-oriented
200 * client side programming in action yet again.
201 * This change should *massively* improve performance when
202 * enumerating users from an LDAP database.
203 * Jeremy.
205 * "Our" and the builtin domain are the only ones where we ever
206 * enumerate stuff, so just cache 2 entries.
209 static struct disp_info *builtin_dispinfo;
210 static struct disp_info *domain_dispinfo;
212 /* There are two cases to consider here:
213 1) The SID is a domain SID and we look for an equality match, or
214 2) This is an account SID and so we return the DISP_INFO* for our
215 domain */
217 if (psid == NULL) {
218 return NULL;
221 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
223 * Necessary only once, but it does not really hurt.
225 if (builtin_dispinfo == NULL) {
226 builtin_dispinfo = talloc_zero(NULL, struct disp_info);
227 if (builtin_dispinfo == NULL) {
228 return NULL;
231 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
233 return builtin_dispinfo;
236 if (sid_check_is_our_sam(psid) || sid_check_is_in_our_sam(psid)) {
238 * Necessary only once, but it does not really hurt.
240 if (domain_dispinfo == NULL) {
241 domain_dispinfo = talloc_zero(NULL, struct disp_info);
242 if (domain_dispinfo == NULL) {
243 return NULL;
246 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
248 return domain_dispinfo;
251 return NULL;
254 /*******************************************************************
255 Function to free the per SID data.
256 ********************************************************************/
258 static void free_samr_cache(DISP_INFO *disp_info)
260 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
261 sid_string_dbg(&disp_info->sid)));
263 /* We need to become root here because the paged search might have to
264 * tell the LDAP server we're not interested in the rest anymore. */
266 become_root();
268 TALLOC_FREE(disp_info->users);
269 TALLOC_FREE(disp_info->machines);
270 TALLOC_FREE(disp_info->groups);
271 TALLOC_FREE(disp_info->aliases);
272 TALLOC_FREE(disp_info->enum_users);
274 unbecome_root();
277 /*******************************************************************
278 Idle event handler. Throw away the disp info cache.
279 ********************************************************************/
281 static void disp_info_cache_idle_timeout_handler(struct tevent_context *ev_ctx,
282 struct tevent_timer *te,
283 struct timeval now,
284 void *private_data)
286 DISP_INFO *disp_info = (DISP_INFO *)private_data;
288 TALLOC_FREE(disp_info->cache_timeout_event);
290 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
291 "out\n"));
292 free_samr_cache(disp_info);
295 /*******************************************************************
296 Setup cache removal idle event handler.
297 ********************************************************************/
299 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
301 /* Remove any pending timeout and update. */
303 TALLOC_FREE(disp_info->cache_timeout_event);
305 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
306 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
307 (unsigned int)secs_fromnow ));
309 disp_info->cache_timeout_event = tevent_add_timer(
310 server_event_context(), NULL,
311 timeval_current_ofs(secs_fromnow, 0),
312 disp_info_cache_idle_timeout_handler, (void *)disp_info);
315 /*******************************************************************
316 Force flush any cache. We do this on any samr_set_xxx call.
317 We must also remove the timeout handler.
318 ********************************************************************/
320 static void force_flush_samr_cache(const struct dom_sid *sid)
322 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
324 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
325 return;
328 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
329 TALLOC_FREE(disp_info->cache_timeout_event);
330 free_samr_cache(disp_info);
333 /*******************************************************************
334 Ensure password info is never given out. Paranioa... JRA.
335 ********************************************************************/
337 static void samr_clear_sam_passwd(struct samu *sam_pass)
340 if (!sam_pass)
341 return;
343 /* These now zero out the old password */
345 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
346 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
349 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
351 struct samr_displayentry *entry;
353 if (sid_check_is_builtin(&info->sid)) {
354 /* No users in builtin. */
355 return 0;
358 if (info->users == NULL) {
359 info->users = pdb_search_users(info, acct_flags);
360 if (info->users == NULL) {
361 return 0;
364 /* Fetch the last possible entry, thus trigger an enumeration */
365 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
367 /* Ensure we cache this enumeration. */
368 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
370 return info->users->num_entries;
373 static uint32 count_sam_groups(struct disp_info *info)
375 struct samr_displayentry *entry;
377 if (sid_check_is_builtin(&info->sid)) {
378 /* No groups in builtin. */
379 return 0;
382 if (info->groups == NULL) {
383 info->groups = pdb_search_groups(info);
384 if (info->groups == NULL) {
385 return 0;
388 /* Fetch the last possible entry, thus trigger an enumeration */
389 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
391 /* Ensure we cache this enumeration. */
392 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
394 return info->groups->num_entries;
397 static uint32 count_sam_aliases(struct disp_info *info)
399 struct samr_displayentry *entry;
401 if (info->aliases == NULL) {
402 info->aliases = pdb_search_aliases(info, &info->sid);
403 if (info->aliases == NULL) {
404 return 0;
407 /* Fetch the last possible entry, thus trigger an enumeration */
408 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
410 /* Ensure we cache this enumeration. */
411 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
413 return info->aliases->num_entries;
416 /*******************************************************************
417 _samr_Close
418 ********************************************************************/
420 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
422 if (!close_policy_hnd(p, r->in.handle)) {
423 return NT_STATUS_INVALID_HANDLE;
426 ZERO_STRUCTP(r->out.handle);
428 return NT_STATUS_OK;
431 /*******************************************************************
432 _samr_OpenDomain
433 ********************************************************************/
435 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
436 struct samr_OpenDomain *r)
438 struct samr_domain_info *dinfo;
439 struct security_descriptor *psd = NULL;
440 uint32 acc_granted;
441 uint32 des_access = r->in.access_mask;
442 NTSTATUS status;
443 size_t sd_size;
444 uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
446 /* find the connection policy handle. */
448 (void)policy_handle_find(p, r->in.connect_handle, 0, NULL,
449 struct samr_connect_info, &status);
450 if (!NT_STATUS_IS_OK(status)) {
451 return status;
454 /*check if access can be granted as requested by client. */
455 map_max_allowed_access(p->session_info->security_token,
456 p->session_info->unix_token,
457 &des_access);
459 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
460 se_map_generic( &des_access, &dom_generic_mapping );
463 * Users with SeAddUser get the ability to manipulate groups
464 * and aliases.
466 if (security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS)) {
467 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
468 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
469 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
470 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
471 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
475 * Users with SeMachineAccount or SeAddUser get additional
476 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
479 status = access_check_object( psd, p->session_info->security_token,
480 SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
481 extra_access, des_access,
482 &acc_granted, "_samr_OpenDomain" );
484 if ( !NT_STATUS_IS_OK(status) )
485 return status;
487 if (!sid_check_is_our_sam(r->in.sid) &&
488 !sid_check_is_builtin(r->in.sid)) {
489 return NT_STATUS_NO_SUCH_DOMAIN;
492 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
493 struct samr_domain_info, &status);
494 if (!NT_STATUS_IS_OK(status)) {
495 return status;
497 dinfo->sid = *r->in.sid;
498 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
500 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
502 return NT_STATUS_OK;
505 /*******************************************************************
506 _samr_GetUserPwInfo
507 ********************************************************************/
509 NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
510 struct samr_GetUserPwInfo *r)
512 struct samr_user_info *uinfo;
513 enum lsa_SidType sid_type;
514 uint32_t min_password_length = 0;
515 uint32_t password_properties = 0;
516 bool ret = false;
517 NTSTATUS status;
519 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
521 uinfo = policy_handle_find(p, r->in.user_handle,
522 SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
523 struct samr_user_info, &status);
524 if (!NT_STATUS_IS_OK(status)) {
525 return status;
528 if (!sid_check_is_in_our_sam(&uinfo->sid)) {
529 return NT_STATUS_OBJECT_TYPE_MISMATCH;
532 become_root();
533 ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
534 unbecome_root();
535 if (ret == false) {
536 return NT_STATUS_NO_SUCH_USER;
539 switch (sid_type) {
540 case SID_NAME_USER:
541 become_root();
542 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
543 &min_password_length);
544 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
545 &password_properties);
546 unbecome_root();
548 if (lp_check_password_script(talloc_tos())
549 && *lp_check_password_script(talloc_tos())) {
550 password_properties |= DOMAIN_PASSWORD_COMPLEX;
553 break;
554 default:
555 break;
558 r->out.info->min_password_length = min_password_length;
559 r->out.info->password_properties = password_properties;
561 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
563 return NT_STATUS_OK;
566 /*******************************************************************
567 _samr_SetSecurity
568 ********************************************************************/
570 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
571 struct samr_SetSecurity *r)
573 struct samr_user_info *uinfo;
574 uint32 i;
575 struct security_acl *dacl;
576 bool ret;
577 struct samu *sampass=NULL;
578 NTSTATUS status;
580 uinfo = policy_handle_find(p, r->in.handle,
581 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
582 struct samr_user_info, &status);
583 if (!NT_STATUS_IS_OK(status)) {
584 return status;
587 if (!(sampass = samu_new( p->mem_ctx))) {
588 DEBUG(0,("No memory!\n"));
589 return NT_STATUS_NO_MEMORY;
592 /* get the user record */
593 become_root();
594 ret = pdb_getsampwsid(sampass, &uinfo->sid);
595 unbecome_root();
597 if (!ret) {
598 DEBUG(4, ("User %s not found\n",
599 sid_string_dbg(&uinfo->sid)));
600 TALLOC_FREE(sampass);
601 return NT_STATUS_INVALID_HANDLE;
604 dacl = r->in.sdbuf->sd->dacl;
605 for (i=0; i < dacl->num_aces; i++) {
606 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
607 ret = pdb_set_pass_can_change(sampass,
608 (dacl->aces[i].access_mask &
609 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
610 True: False);
611 break;
615 if (!ret) {
616 TALLOC_FREE(sampass);
617 return NT_STATUS_ACCESS_DENIED;
620 become_root();
621 status = pdb_update_sam_account(sampass);
622 unbecome_root();
624 TALLOC_FREE(sampass);
626 return status;
629 /*******************************************************************
630 build correct perms based on policies and password times for _samr_query_sec_obj
631 *******************************************************************/
632 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
634 struct samu *sampass=NULL;
635 bool ret;
637 if ( !(sampass = samu_new( mem_ctx )) ) {
638 DEBUG(0,("No memory!\n"));
639 return False;
642 become_root();
643 ret = pdb_getsampwsid(sampass, user_sid);
644 unbecome_root();
646 if (ret == False) {
647 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
648 TALLOC_FREE(sampass);
649 return False;
652 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
654 if (pdb_get_pass_can_change(sampass)) {
655 TALLOC_FREE(sampass);
656 return True;
658 TALLOC_FREE(sampass);
659 return False;
663 /*******************************************************************
664 _samr_QuerySecurity
665 ********************************************************************/
667 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
668 struct samr_QuerySecurity *r)
670 struct samr_domain_info *dinfo;
671 struct samr_user_info *uinfo;
672 struct samr_group_info *ginfo;
673 struct samr_alias_info *ainfo;
674 NTSTATUS status;
675 struct security_descriptor * psd = NULL;
676 size_t sd_size = 0;
678 (void)policy_handle_find(p, r->in.handle,
679 SEC_STD_READ_CONTROL, NULL,
680 struct samr_connect_info, &status);
681 if (NT_STATUS_IS_OK(status)) {
682 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
683 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
684 &sam_generic_mapping, NULL, 0);
685 goto done;
688 dinfo = policy_handle_find(p, r->in.handle,
689 SEC_STD_READ_CONTROL, NULL,
690 struct samr_domain_info, &status);
691 if (NT_STATUS_IS_OK(status)) {
692 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
693 "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
695 * TODO: Builtin probably needs a different SD with restricted
696 * write access
698 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
699 &dom_generic_mapping, NULL, 0);
700 goto done;
703 uinfo = policy_handle_find(p, r->in.handle,
704 SEC_STD_READ_CONTROL, NULL,
705 struct samr_user_info, &status);
706 if (NT_STATUS_IS_OK(status)) {
707 DEBUG(10,("_samr_QuerySecurity: querying security on user "
708 "Object with SID: %s\n",
709 sid_string_dbg(&uinfo->sid)));
710 if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
711 status = make_samr_object_sd(
712 p->mem_ctx, &psd, &sd_size,
713 &usr_generic_mapping,
714 &uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
715 } else {
716 status = make_samr_object_sd(
717 p->mem_ctx, &psd, &sd_size,
718 &usr_nopwchange_generic_mapping,
719 &uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
721 goto done;
724 ginfo = policy_handle_find(p, r->in.handle,
725 SEC_STD_READ_CONTROL, NULL,
726 struct samr_group_info, &status);
727 if (NT_STATUS_IS_OK(status)) {
729 * TODO: different SDs have to be generated for aliases groups
730 * and users. Currently all three get a default user SD
732 DEBUG(10,("_samr_QuerySecurity: querying security on group "
733 "Object with SID: %s\n",
734 sid_string_dbg(&ginfo->sid)));
735 status = make_samr_object_sd(
736 p->mem_ctx, &psd, &sd_size,
737 &usr_nopwchange_generic_mapping,
738 &ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
739 goto done;
742 ainfo = policy_handle_find(p, r->in.handle,
743 SEC_STD_READ_CONTROL, NULL,
744 struct samr_alias_info, &status);
745 if (NT_STATUS_IS_OK(status)) {
747 * TODO: different SDs have to be generated for aliases groups
748 * and users. Currently all three get a default user SD
750 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
751 "Object with SID: %s\n",
752 sid_string_dbg(&ainfo->sid)));
753 status = make_samr_object_sd(
754 p->mem_ctx, &psd, &sd_size,
755 &usr_nopwchange_generic_mapping,
756 &ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
757 goto done;
760 return NT_STATUS_OBJECT_TYPE_MISMATCH;
761 done:
762 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
763 return NT_STATUS_NO_MEMORY;
765 return status;
768 /*******************************************************************
769 makes a SAM_ENTRY / UNISTR2* structure from a user list.
770 ********************************************************************/
772 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
773 struct samr_SamEntry **sam_pp,
774 uint32_t num_entries,
775 uint32_t start_idx,
776 struct samr_displayentry *entries)
778 uint32_t i;
779 struct samr_SamEntry *sam;
781 *sam_pp = NULL;
783 if (num_entries == 0) {
784 return NT_STATUS_OK;
787 sam = talloc_zero_array(ctx, struct samr_SamEntry, num_entries);
788 if (sam == NULL) {
789 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
790 return NT_STATUS_NO_MEMORY;
793 for (i = 0; i < num_entries; i++) {
794 #if 0
796 * usrmgr expects a non-NULL terminated string with
797 * trust relationships
799 if (entries[i].acct_flags & ACB_DOMTRUST) {
800 init_unistr2(&uni_temp_name, entries[i].account_name,
801 UNI_FLAGS_NONE);
802 } else {
803 init_unistr2(&uni_temp_name, entries[i].account_name,
804 UNI_STR_TERMINATE);
806 #endif
807 init_lsa_String(&sam[i].name, entries[i].account_name);
808 sam[i].idx = entries[i].rid;
811 *sam_pp = sam;
813 return NT_STATUS_OK;
816 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
818 /*******************************************************************
819 _samr_EnumDomainUsers
820 ********************************************************************/
822 NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
823 struct samr_EnumDomainUsers *r)
825 NTSTATUS status;
826 struct samr_domain_info *dinfo;
827 int num_account;
828 uint32 enum_context = *r->in.resume_handle;
829 enum remote_arch_types ra_type = get_remote_arch();
830 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
831 uint32 max_entries = max_sam_entries;
832 struct samr_displayentry *entries = NULL;
833 struct samr_SamArray *samr_array = NULL;
834 struct samr_SamEntry *samr_entries = NULL;
836 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
838 dinfo = policy_handle_find(p, r->in.domain_handle,
839 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
840 struct samr_domain_info, &status);
841 if (!NT_STATUS_IS_OK(status)) {
842 return status;
845 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
846 if (!samr_array) {
847 return NT_STATUS_NO_MEMORY;
849 *r->out.sam = samr_array;
851 if (sid_check_is_builtin(&dinfo->sid)) {
852 /* No users in builtin. */
853 *r->out.resume_handle = *r->in.resume_handle;
854 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
855 return status;
858 become_root();
860 /* AS ROOT !!!! */
862 if ((dinfo->disp_info->enum_users != NULL) &&
863 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
864 TALLOC_FREE(dinfo->disp_info->enum_users);
867 if (dinfo->disp_info->enum_users == NULL) {
868 dinfo->disp_info->enum_users = pdb_search_users(
869 dinfo->disp_info, r->in.acct_flags);
870 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
873 if (dinfo->disp_info->enum_users == NULL) {
874 /* END AS ROOT !!!! */
875 unbecome_root();
876 return NT_STATUS_ACCESS_DENIED;
879 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
880 enum_context, max_entries,
881 &entries);
883 /* END AS ROOT !!!! */
885 unbecome_root();
887 if (num_account == 0) {
888 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
889 "total entries\n"));
890 *r->out.resume_handle = *r->in.resume_handle;
891 return NT_STATUS_OK;
894 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
895 num_account, enum_context,
896 entries);
897 if (!NT_STATUS_IS_OK(status)) {
898 return status;
901 if (max_entries <= num_account) {
902 status = STATUS_MORE_ENTRIES;
903 } else {
904 status = NT_STATUS_OK;
907 /* Ensure we cache this enumeration. */
908 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
910 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
912 samr_array->count = num_account;
913 samr_array->entries = samr_entries;
915 *r->out.resume_handle = *r->in.resume_handle + num_account;
916 *r->out.num_entries = num_account;
918 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
920 return status;
923 /*******************************************************************
924 makes a SAM_ENTRY / UNISTR2* structure from a group list.
925 ********************************************************************/
927 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
928 struct samr_SamEntry **sam_pp,
929 uint32_t num_sam_entries,
930 struct samr_displayentry *entries)
932 struct samr_SamEntry *sam;
933 uint32_t i;
935 *sam_pp = NULL;
937 if (num_sam_entries == 0) {
938 return;
941 sam = talloc_zero_array(ctx, struct samr_SamEntry, num_sam_entries);
942 if (sam == NULL) {
943 return;
946 for (i = 0; i < num_sam_entries; i++) {
948 * JRA. I think this should include the null. TNG does not.
950 init_lsa_String(&sam[i].name, entries[i].account_name);
951 sam[i].idx = entries[i].rid;
954 *sam_pp = sam;
957 /*******************************************************************
958 _samr_EnumDomainGroups
959 ********************************************************************/
961 NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
962 struct samr_EnumDomainGroups *r)
964 NTSTATUS status;
965 struct samr_domain_info *dinfo;
966 struct samr_displayentry *groups;
967 uint32 num_groups;
968 struct samr_SamArray *samr_array = NULL;
969 struct samr_SamEntry *samr_entries = NULL;
971 dinfo = policy_handle_find(p, r->in.domain_handle,
972 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
973 struct samr_domain_info, &status);
974 if (!NT_STATUS_IS_OK(status)) {
975 return status;
978 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
980 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
981 if (!samr_array) {
982 return NT_STATUS_NO_MEMORY;
984 *r->out.sam = samr_array;
986 if (sid_check_is_builtin(&dinfo->sid)) {
987 /* No groups in builtin. */
988 *r->out.resume_handle = *r->in.resume_handle;
989 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
990 return status;
993 /* the domain group array is being allocated in the function below */
995 become_root();
997 if (dinfo->disp_info->groups == NULL) {
998 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1000 if (dinfo->disp_info->groups == NULL) {
1001 unbecome_root();
1002 return NT_STATUS_ACCESS_DENIED;
1006 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1007 *r->in.resume_handle,
1008 MAX_SAM_ENTRIES, &groups);
1009 unbecome_root();
1011 /* Ensure we cache this enumeration. */
1012 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1014 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1015 num_groups, groups);
1017 if (MAX_SAM_ENTRIES <= num_groups) {
1018 status = STATUS_MORE_ENTRIES;
1019 } else {
1020 status = NT_STATUS_OK;
1023 samr_array->count = num_groups;
1024 samr_array->entries = samr_entries;
1026 *r->out.num_entries = num_groups;
1027 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1029 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1031 return status;
1034 /*******************************************************************
1035 _samr_EnumDomainAliases
1036 ********************************************************************/
1038 NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
1039 struct samr_EnumDomainAliases *r)
1041 NTSTATUS status;
1042 struct samr_domain_info *dinfo;
1043 struct samr_displayentry *aliases;
1044 uint32 num_aliases = 0;
1045 struct samr_SamArray *samr_array = NULL;
1046 struct samr_SamEntry *samr_entries = NULL;
1048 dinfo = policy_handle_find(p, r->in.domain_handle,
1049 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1050 struct samr_domain_info, &status);
1051 if (!NT_STATUS_IS_OK(status)) {
1052 return status;
1055 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1056 sid_string_dbg(&dinfo->sid)));
1058 samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
1059 if (!samr_array) {
1060 return NT_STATUS_NO_MEMORY;
1063 become_root();
1065 if (dinfo->disp_info->aliases == NULL) {
1066 dinfo->disp_info->aliases = pdb_search_aliases(
1067 dinfo->disp_info, &dinfo->sid);
1068 if (dinfo->disp_info->aliases == NULL) {
1069 unbecome_root();
1070 return NT_STATUS_ACCESS_DENIED;
1074 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1075 *r->in.resume_handle,
1076 MAX_SAM_ENTRIES, &aliases);
1077 unbecome_root();
1079 /* Ensure we cache this enumeration. */
1080 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1082 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1083 num_aliases, aliases);
1085 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1087 if (MAX_SAM_ENTRIES <= num_aliases) {
1088 status = STATUS_MORE_ENTRIES;
1089 } else {
1090 status = NT_STATUS_OK;
1093 samr_array->count = num_aliases;
1094 samr_array->entries = samr_entries;
1096 *r->out.sam = samr_array;
1097 *r->out.num_entries = num_aliases;
1098 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1100 return status;
1103 /*******************************************************************
1104 inits a samr_DispInfoGeneral structure.
1105 ********************************************************************/
1107 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1108 struct samr_DispInfoGeneral *r,
1109 uint32_t num_entries,
1110 uint32_t start_idx,
1111 struct samr_displayentry *entries)
1113 uint32 i;
1115 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1117 if (num_entries == 0) {
1118 return NT_STATUS_OK;
1121 r->count = num_entries;
1123 r->entries = talloc_zero_array(ctx, struct samr_DispEntryGeneral, num_entries);
1124 if (!r->entries) {
1125 return NT_STATUS_NO_MEMORY;
1128 for (i = 0; i < num_entries ; i++) {
1130 init_lsa_String(&r->entries[i].account_name,
1131 entries[i].account_name);
1133 init_lsa_String(&r->entries[i].description,
1134 entries[i].description);
1136 init_lsa_String(&r->entries[i].full_name,
1137 entries[i].fullname);
1139 r->entries[i].rid = entries[i].rid;
1140 r->entries[i].acct_flags = entries[i].acct_flags;
1141 r->entries[i].idx = start_idx+i+1;
1144 return NT_STATUS_OK;
1147 /*******************************************************************
1148 inits a samr_DispInfoFull structure.
1149 ********************************************************************/
1151 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1152 struct samr_DispInfoFull *r,
1153 uint32_t num_entries,
1154 uint32_t start_idx,
1155 struct samr_displayentry *entries)
1157 uint32_t i;
1159 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1161 if (num_entries == 0) {
1162 return NT_STATUS_OK;
1165 r->count = num_entries;
1167 r->entries = talloc_zero_array(ctx, struct samr_DispEntryFull, num_entries);
1168 if (!r->entries) {
1169 return NT_STATUS_NO_MEMORY;
1172 for (i = 0; i < num_entries ; i++) {
1174 init_lsa_String(&r->entries[i].account_name,
1175 entries[i].account_name);
1177 init_lsa_String(&r->entries[i].description,
1178 entries[i].description);
1180 r->entries[i].rid = entries[i].rid;
1181 r->entries[i].acct_flags = entries[i].acct_flags;
1182 r->entries[i].idx = start_idx+i+1;
1185 return NT_STATUS_OK;
1188 /*******************************************************************
1189 inits a samr_DispInfoFullGroups structure.
1190 ********************************************************************/
1192 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1193 struct samr_DispInfoFullGroups *r,
1194 uint32_t num_entries,
1195 uint32_t start_idx,
1196 struct samr_displayentry *entries)
1198 uint32_t i;
1200 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1202 if (num_entries == 0) {
1203 return NT_STATUS_OK;
1206 r->count = num_entries;
1208 r->entries = talloc_zero_array(ctx, struct samr_DispEntryFullGroup, num_entries);
1209 if (!r->entries) {
1210 return NT_STATUS_NO_MEMORY;
1213 for (i = 0; i < num_entries ; i++) {
1215 init_lsa_String(&r->entries[i].account_name,
1216 entries[i].account_name);
1218 init_lsa_String(&r->entries[i].description,
1219 entries[i].description);
1221 r->entries[i].rid = entries[i].rid;
1222 r->entries[i].acct_flags = entries[i].acct_flags;
1223 r->entries[i].idx = start_idx+i+1;
1226 return NT_STATUS_OK;
1229 /*******************************************************************
1230 inits a samr_DispInfoAscii structure.
1231 ********************************************************************/
1233 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1234 struct samr_DispInfoAscii *r,
1235 uint32_t num_entries,
1236 uint32_t start_idx,
1237 struct samr_displayentry *entries)
1239 uint32_t i;
1241 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1243 if (num_entries == 0) {
1244 return NT_STATUS_OK;
1247 r->count = num_entries;
1249 r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1250 if (!r->entries) {
1251 return NT_STATUS_NO_MEMORY;
1254 for (i = 0; i < num_entries ; i++) {
1256 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1257 entries[i].account_name);
1259 r->entries[i].idx = start_idx+i+1;
1262 return NT_STATUS_OK;
1265 /*******************************************************************
1266 inits a samr_DispInfoAscii structure.
1267 ********************************************************************/
1269 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1270 struct samr_DispInfoAscii *r,
1271 uint32_t num_entries,
1272 uint32_t start_idx,
1273 struct samr_displayentry *entries)
1275 uint32_t i;
1277 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1279 if (num_entries == 0) {
1280 return NT_STATUS_OK;
1283 r->count = num_entries;
1285 r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
1286 if (!r->entries) {
1287 return NT_STATUS_NO_MEMORY;
1290 for (i = 0; i < num_entries ; i++) {
1292 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1293 entries[i].account_name);
1295 r->entries[i].idx = start_idx+i+1;
1298 return NT_STATUS_OK;
1301 /*******************************************************************
1302 _samr_QueryDisplayInfo
1303 ********************************************************************/
1305 NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
1306 struct samr_QueryDisplayInfo *r)
1308 NTSTATUS status;
1309 struct samr_domain_info *dinfo;
1310 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1312 uint32 max_entries = r->in.max_entries;
1314 union samr_DispInfo *disp_info = r->out.info;
1316 uint32 temp_size=0;
1317 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1318 uint32 num_account = 0;
1319 enum remote_arch_types ra_type = get_remote_arch();
1320 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1321 struct samr_displayentry *entries = NULL;
1323 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1325 dinfo = policy_handle_find(p, r->in.domain_handle,
1326 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1327 struct samr_domain_info, &status);
1328 if (!NT_STATUS_IS_OK(status)) {
1329 return status;
1332 if (sid_check_is_builtin(&dinfo->sid)) {
1333 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1334 return NT_STATUS_OK;
1338 * calculate how many entries we will return.
1339 * based on
1340 * - the number of entries the client asked
1341 * - our limit on that
1342 * - the starting point (enumeration context)
1343 * - the buffer size the client will accept
1347 * We are a lot more like W2K. Instead of reading the SAM
1348 * each time to find the records we need to send back,
1349 * we read it once and link that copy to the sam handle.
1350 * For large user list (over the MAX_SAM_ENTRIES)
1351 * it's a definitive win.
1352 * second point to notice: between enumerations
1353 * our sam is now the same as it's a snapshoot.
1354 * third point: got rid of the static SAM_USER_21 struct
1355 * no more intermediate.
1356 * con: it uses much more memory, as a full copy is stored
1357 * in memory.
1359 * If you want to change it, think twice and think
1360 * of the second point , that's really important.
1362 * JFM, 12/20/2001
1365 if ((r->in.level < 1) || (r->in.level > 5)) {
1366 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1367 (unsigned int)r->in.level ));
1368 return NT_STATUS_INVALID_INFO_CLASS;
1371 /* first limit the number of entries we will return */
1372 if (r->in.max_entries > max_sam_entries) {
1373 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1374 "entries, limiting to %d\n", r->in.max_entries,
1375 max_sam_entries));
1376 max_entries = max_sam_entries;
1379 /* calculate the size and limit on the number of entries we will
1380 * return */
1382 temp_size=max_entries*struct_size;
1384 if (temp_size > r->in.buf_size) {
1385 max_entries = MIN((r->in.buf_size / struct_size),max_entries);
1386 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1387 "only %d entries\n", max_entries));
1390 become_root();
1392 /* THe following done as ROOT. Don't return without unbecome_root(). */
1394 switch (r->in.level) {
1395 case 1:
1396 case 4:
1397 if (dinfo->disp_info->users == NULL) {
1398 dinfo->disp_info->users = pdb_search_users(
1399 dinfo->disp_info, ACB_NORMAL);
1400 if (dinfo->disp_info->users == NULL) {
1401 unbecome_root();
1402 return NT_STATUS_ACCESS_DENIED;
1404 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1405 (unsigned int)r->in.start_idx));
1406 } else {
1407 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1408 (unsigned int)r->in.start_idx));
1411 num_account = pdb_search_entries(dinfo->disp_info->users,
1412 r->in.start_idx, max_entries,
1413 &entries);
1414 break;
1415 case 2:
1416 if (dinfo->disp_info->machines == NULL) {
1417 dinfo->disp_info->machines = pdb_search_users(
1418 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1419 if (dinfo->disp_info->machines == NULL) {
1420 unbecome_root();
1421 return NT_STATUS_ACCESS_DENIED;
1423 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1424 (unsigned int)r->in.start_idx));
1425 } else {
1426 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1427 (unsigned int)r->in.start_idx));
1430 num_account = pdb_search_entries(dinfo->disp_info->machines,
1431 r->in.start_idx, max_entries,
1432 &entries);
1433 break;
1434 case 3:
1435 case 5:
1436 if (dinfo->disp_info->groups == NULL) {
1437 dinfo->disp_info->groups = pdb_search_groups(
1438 dinfo->disp_info);
1439 if (dinfo->disp_info->groups == NULL) {
1440 unbecome_root();
1441 return NT_STATUS_ACCESS_DENIED;
1443 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1444 (unsigned int)r->in.start_idx));
1445 } else {
1446 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1447 (unsigned int)r->in.start_idx));
1450 num_account = pdb_search_entries(dinfo->disp_info->groups,
1451 r->in.start_idx, max_entries,
1452 &entries);
1453 break;
1454 default:
1455 unbecome_root();
1456 smb_panic("info class changed");
1457 break;
1459 unbecome_root();
1462 /* Now create reply structure */
1463 switch (r->in.level) {
1464 case 1:
1465 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1466 num_account, r->in.start_idx,
1467 entries);
1468 break;
1469 case 2:
1470 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1471 num_account, r->in.start_idx,
1472 entries);
1473 break;
1474 case 3:
1475 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1476 num_account, r->in.start_idx,
1477 entries);
1478 break;
1479 case 4:
1480 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1481 num_account, r->in.start_idx,
1482 entries);
1483 break;
1484 case 5:
1485 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1486 num_account, r->in.start_idx,
1487 entries);
1488 break;
1489 default:
1490 smb_panic("info class changed");
1491 break;
1494 if (!NT_STATUS_IS_OK(disp_ret))
1495 return disp_ret;
1497 if (max_entries <= num_account) {
1498 status = STATUS_MORE_ENTRIES;
1499 } else {
1500 status = NT_STATUS_OK;
1503 /* Ensure we cache this enumeration. */
1504 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1506 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1508 *r->out.total_size = num_account * struct_size;
1509 *r->out.returned_size = num_account ? temp_size : 0;
1511 return status;
1514 /****************************************************************
1515 _samr_QueryDisplayInfo2
1516 ****************************************************************/
1518 NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
1519 struct samr_QueryDisplayInfo2 *r)
1521 struct samr_QueryDisplayInfo q;
1523 q.in.domain_handle = r->in.domain_handle;
1524 q.in.level = r->in.level;
1525 q.in.start_idx = r->in.start_idx;
1526 q.in.max_entries = r->in.max_entries;
1527 q.in.buf_size = r->in.buf_size;
1529 q.out.total_size = r->out.total_size;
1530 q.out.returned_size = r->out.returned_size;
1531 q.out.info = r->out.info;
1533 return _samr_QueryDisplayInfo(p, &q);
1536 /****************************************************************
1537 _samr_QueryDisplayInfo3
1538 ****************************************************************/
1540 NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
1541 struct samr_QueryDisplayInfo3 *r)
1543 struct samr_QueryDisplayInfo q;
1545 q.in.domain_handle = r->in.domain_handle;
1546 q.in.level = r->in.level;
1547 q.in.start_idx = r->in.start_idx;
1548 q.in.max_entries = r->in.max_entries;
1549 q.in.buf_size = r->in.buf_size;
1551 q.out.total_size = r->out.total_size;
1552 q.out.returned_size = r->out.returned_size;
1553 q.out.info = r->out.info;
1555 return _samr_QueryDisplayInfo(p, &q);
1558 /*******************************************************************
1559 _samr_QueryAliasInfo
1560 ********************************************************************/
1562 NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
1563 struct samr_QueryAliasInfo *r)
1565 struct samr_alias_info *ainfo;
1566 struct acct_info *info;
1567 NTSTATUS status;
1568 union samr_AliasInfo *alias_info = NULL;
1569 const char *alias_name = NULL;
1570 const char *alias_description = NULL;
1572 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1574 ainfo = policy_handle_find(p, r->in.alias_handle,
1575 SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1576 struct samr_alias_info, &status);
1577 if (!NT_STATUS_IS_OK(status)) {
1578 return status;
1581 alias_info = talloc_zero(p->mem_ctx, union samr_AliasInfo);
1582 if (!alias_info) {
1583 return NT_STATUS_NO_MEMORY;
1586 info = talloc_zero(p->mem_ctx, struct acct_info);
1587 if (!info) {
1588 return NT_STATUS_NO_MEMORY;
1591 become_root();
1592 status = pdb_get_aliasinfo(&ainfo->sid, info);
1593 unbecome_root();
1595 if (!NT_STATUS_IS_OK(status)) {
1596 TALLOC_FREE(info);
1597 return status;
1600 alias_name = talloc_steal(r, info->acct_name);
1601 alias_description = talloc_steal(r, info->acct_desc);
1602 TALLOC_FREE(info);
1604 switch (r->in.level) {
1605 case ALIASINFOALL:
1606 alias_info->all.name.string = alias_name;
1607 alias_info->all.num_members = 1; /* ??? */
1608 alias_info->all.description.string = alias_description;
1609 break;
1610 case ALIASINFONAME:
1611 alias_info->name.string = alias_name;
1612 break;
1613 case ALIASINFODESCRIPTION:
1614 alias_info->description.string = alias_description;
1615 break;
1616 default:
1617 return NT_STATUS_INVALID_INFO_CLASS;
1620 *r->out.info = alias_info;
1622 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1624 return NT_STATUS_OK;
1627 /*******************************************************************
1628 _samr_LookupNames
1629 ********************************************************************/
1631 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1632 struct samr_LookupNames *r)
1634 struct samr_domain_info *dinfo;
1635 NTSTATUS status;
1636 uint32 *rid;
1637 enum lsa_SidType *type;
1638 int i;
1639 int num_rids = r->in.num_names;
1640 struct samr_Ids rids, types;
1641 uint32_t num_mapped = 0;
1643 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1645 dinfo = policy_handle_find(p, r->in.domain_handle,
1646 0 /* Don't know the acc_bits yet */, NULL,
1647 struct samr_domain_info, &status);
1648 if (!NT_STATUS_IS_OK(status)) {
1649 return status;
1652 if (num_rids > MAX_SAM_ENTRIES) {
1653 num_rids = MAX_SAM_ENTRIES;
1654 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1657 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1658 NT_STATUS_HAVE_NO_MEMORY(rid);
1660 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1661 NT_STATUS_HAVE_NO_MEMORY(type);
1663 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1664 sid_string_dbg(&dinfo->sid)));
1666 for (i = 0; i < num_rids; i++) {
1668 status = NT_STATUS_NONE_MAPPED;
1669 type[i] = SID_NAME_UNKNOWN;
1671 rid[i] = 0xffffffff;
1673 if (sid_check_is_builtin(&dinfo->sid)) {
1674 if (lookup_builtin_name(r->in.names[i].string,
1675 &rid[i]))
1677 type[i] = SID_NAME_ALIAS;
1679 } else {
1680 lookup_global_sam_name(r->in.names[i].string, 0,
1681 &rid[i], &type[i]);
1684 if (type[i] != SID_NAME_UNKNOWN) {
1685 num_mapped++;
1689 if (num_mapped == num_rids) {
1690 status = NT_STATUS_OK;
1691 } else if (num_mapped == 0) {
1692 status = NT_STATUS_NONE_MAPPED;
1693 } else {
1694 status = STATUS_SOME_UNMAPPED;
1697 rids.count = num_rids;
1698 rids.ids = rid;
1700 types.count = num_rids;
1701 types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1702 NT_STATUS_HAVE_NO_MEMORY(type);
1703 for (i = 0; i < num_rids; i++) {
1704 types.ids[i] = (type[i] & 0xffffffff);
1707 *r->out.rids = rids;
1708 *r->out.types = types;
1710 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1712 return status;
1715 /****************************************************************
1716 _samr_ChangePasswordUser.
1718 So old it is just not worth implementing
1719 because it does not supply a plaintext and so we can't do password
1720 complexity checking and cannot update other services that use a
1721 plaintext password via passwd chat/pam password change/ldap password
1722 sync.
1723 ****************************************************************/
1725 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1726 struct samr_ChangePasswordUser *r)
1728 return NT_STATUS_NOT_IMPLEMENTED;
1731 /*******************************************************************
1732 _samr_ChangePasswordUser2
1733 ********************************************************************/
1735 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1736 struct samr_ChangePasswordUser2 *r)
1738 NTSTATUS status;
1739 char *user_name = NULL;
1740 char *rhost;
1741 const char *wks = NULL;
1743 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1745 if (!r->in.account->string) {
1746 return NT_STATUS_INVALID_PARAMETER;
1748 if (r->in.server && r->in.server->string) {
1749 wks = r->in.server->string;
1752 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1755 * Pass the user through the NT -> unix user mapping
1756 * function.
1759 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1760 if (!user_name) {
1761 return NT_STATUS_NO_MEMORY;
1764 rhost = tsocket_address_inet_addr_string(p->remote_address,
1765 talloc_tos());
1766 if (rhost == NULL) {
1767 return NT_STATUS_NO_MEMORY;
1771 * UNIX username case mangling not required, pass_oem_change
1772 * is case insensitive.
1775 status = pass_oem_change(user_name,
1776 rhost,
1777 r->in.lm_password->data,
1778 r->in.lm_verifier->hash,
1779 r->in.nt_password->data,
1780 r->in.nt_verifier->hash,
1781 NULL);
1783 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1785 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1786 return NT_STATUS_WRONG_PASSWORD;
1789 return status;
1792 /****************************************************************
1793 _samr_OemChangePasswordUser2
1794 ****************************************************************/
1796 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1797 struct samr_OemChangePasswordUser2 *r)
1799 NTSTATUS status;
1800 char *user_name = NULL;
1801 const char *wks = NULL;
1802 char *rhost;
1804 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1806 if (!r->in.account->string) {
1807 return NT_STATUS_INVALID_PARAMETER;
1809 if (r->in.server && r->in.server->string) {
1810 wks = r->in.server->string;
1813 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1816 * Pass the user through the NT -> unix user mapping
1817 * function.
1820 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1821 if (!user_name) {
1822 return NT_STATUS_NO_MEMORY;
1826 * UNIX username case mangling not required, pass_oem_change
1827 * is case insensitive.
1830 if (!r->in.hash || !r->in.password) {
1831 return NT_STATUS_INVALID_PARAMETER;
1834 rhost = tsocket_address_inet_addr_string(p->remote_address,
1835 talloc_tos());
1836 if (rhost == NULL) {
1837 return NT_STATUS_NO_MEMORY;
1840 status = pass_oem_change(user_name,
1841 rhost,
1842 r->in.password->data,
1843 r->in.hash->hash,
1846 NULL);
1848 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1849 return NT_STATUS_WRONG_PASSWORD;
1852 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1854 return status;
1857 /*******************************************************************
1858 _samr_ChangePasswordUser3
1859 ********************************************************************/
1861 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
1862 struct samr_ChangePasswordUser3 *r)
1864 NTSTATUS status;
1865 char *user_name = NULL;
1866 const char *wks = NULL;
1867 enum samPwdChangeReason reject_reason;
1868 struct samr_DomInfo1 *dominfo = NULL;
1869 struct userPwdChangeFailureInformation *reject = NULL;
1870 uint32_t tmp;
1871 char *rhost;
1873 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1875 if (!r->in.account->string) {
1876 return NT_STATUS_INVALID_PARAMETER;
1878 if (r->in.server && r->in.server->string) {
1879 wks = r->in.server->string;
1882 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1885 * Pass the user through the NT -> unix user mapping
1886 * function.
1889 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1890 if (!user_name) {
1891 return NT_STATUS_NO_MEMORY;
1894 rhost = tsocket_address_inet_addr_string(p->remote_address,
1895 talloc_tos());
1896 if (rhost == NULL) {
1897 return NT_STATUS_NO_MEMORY;
1901 * UNIX username case mangling not required, pass_oem_change
1902 * is case insensitive.
1905 status = pass_oem_change(user_name,
1906 rhost,
1907 r->in.lm_password->data,
1908 r->in.lm_verifier->hash,
1909 r->in.nt_password->data,
1910 r->in.nt_verifier->hash,
1911 &reject_reason);
1912 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1913 return NT_STATUS_WRONG_PASSWORD;
1916 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1917 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1919 time_t u_expire, u_min_age;
1920 uint32 account_policy_temp;
1922 dominfo = talloc_zero(p->mem_ctx, struct samr_DomInfo1);
1923 if (!dominfo) {
1924 return NT_STATUS_NO_MEMORY;
1927 reject = talloc_zero(p->mem_ctx,
1928 struct userPwdChangeFailureInformation);
1929 if (!reject) {
1930 return NT_STATUS_NO_MEMORY;
1933 become_root();
1935 /* AS ROOT !!! */
1937 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
1938 dominfo->min_password_length = tmp;
1940 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
1941 dominfo->password_history_length = tmp;
1943 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
1944 &dominfo->password_properties);
1946 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
1947 u_expire = account_policy_temp;
1949 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
1950 u_min_age = account_policy_temp;
1952 /* !AS ROOT */
1954 unbecome_root();
1956 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
1957 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
1959 if (lp_check_password_script(talloc_tos())
1960 && *lp_check_password_script(talloc_tos())) {
1961 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
1964 reject->extendedFailureReason = reject_reason;
1966 *r->out.dominfo = dominfo;
1967 *r->out.reject = reject;
1970 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1972 return status;
1975 /*******************************************************************
1976 makes a SAMR_R_LOOKUP_RIDS structure.
1977 ********************************************************************/
1979 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1980 const char **names,
1981 struct lsa_String **lsa_name_array_p)
1983 struct lsa_String *lsa_name_array = NULL;
1984 uint32_t i;
1986 *lsa_name_array_p = NULL;
1988 if (num_names != 0) {
1989 lsa_name_array = talloc_zero_array(ctx, struct lsa_String, num_names);
1990 if (!lsa_name_array) {
1991 return false;
1995 for (i = 0; i < num_names; i++) {
1996 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
1997 init_lsa_String(&lsa_name_array[i], names[i]);
2000 *lsa_name_array_p = lsa_name_array;
2002 return true;
2005 /*******************************************************************
2006 _samr_LookupRids
2007 ********************************************************************/
2009 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2010 struct samr_LookupRids *r)
2012 struct samr_domain_info *dinfo;
2013 NTSTATUS status;
2014 const char **names;
2015 enum lsa_SidType *attrs = NULL;
2016 uint32 *wire_attrs = NULL;
2017 int num_rids = (int)r->in.num_rids;
2018 int i;
2019 struct lsa_Strings names_array;
2020 struct samr_Ids types_array;
2021 struct lsa_String *lsa_names = NULL;
2023 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2025 dinfo = policy_handle_find(p, r->in.domain_handle,
2026 0 /* Don't know the acc_bits yet */, NULL,
2027 struct samr_domain_info, &status);
2028 if (!NT_STATUS_IS_OK(status)) {
2029 return status;
2032 if (num_rids > 1000) {
2033 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2034 "to samba4 idl this is not possible\n", num_rids));
2035 return NT_STATUS_UNSUCCESSFUL;
2038 if (num_rids) {
2039 names = talloc_zero_array(p->mem_ctx, const char *, num_rids);
2040 attrs = talloc_zero_array(p->mem_ctx, enum lsa_SidType, num_rids);
2041 wire_attrs = talloc_zero_array(p->mem_ctx, uint32, num_rids);
2043 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2044 return NT_STATUS_NO_MEMORY;
2045 } else {
2046 names = NULL;
2047 attrs = NULL;
2048 wire_attrs = NULL;
2051 become_root(); /* lookup_sid can require root privs */
2052 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2053 names, attrs);
2054 unbecome_root();
2056 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2057 status = NT_STATUS_OK;
2060 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2061 &lsa_names)) {
2062 return NT_STATUS_NO_MEMORY;
2065 /* Convert from enum lsa_SidType to uint32 for wire format. */
2066 for (i = 0; i < num_rids; i++) {
2067 wire_attrs[i] = (uint32)attrs[i];
2070 names_array.count = num_rids;
2071 names_array.names = lsa_names;
2073 types_array.count = num_rids;
2074 types_array.ids = wire_attrs;
2076 *r->out.names = names_array;
2077 *r->out.types = types_array;
2079 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2081 return status;
2084 /*******************************************************************
2085 _samr_OpenUser
2086 ********************************************************************/
2088 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2089 struct samr_OpenUser *r)
2091 struct samu *sampass=NULL;
2092 struct dom_sid sid;
2093 struct samr_domain_info *dinfo;
2094 struct samr_user_info *uinfo;
2095 struct security_descriptor *psd = NULL;
2096 uint32 acc_granted;
2097 uint32 des_access = r->in.access_mask;
2098 uint32_t extra_access = 0;
2099 size_t sd_size;
2100 bool ret;
2101 NTSTATUS nt_status;
2103 /* These two privileges, if != SEC_PRIV_INVALID, indicate
2104 * privileges that the user must have to complete this
2105 * operation in defience of the fixed ACL */
2106 enum sec_privilege needed_priv_1, needed_priv_2;
2107 NTSTATUS status;
2109 dinfo = policy_handle_find(p, r->in.domain_handle,
2110 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2111 struct samr_domain_info, &status);
2112 if (!NT_STATUS_IS_OK(status)) {
2113 return status;
2116 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2117 return NT_STATUS_NO_MEMORY;
2120 /* append the user's RID to it */
2122 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2123 return NT_STATUS_NO_SUCH_USER;
2125 /* check if access can be granted as requested by client. */
2126 map_max_allowed_access(p->session_info->security_token,
2127 p->session_info->unix_token,
2128 &des_access);
2130 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2131 se_map_generic(&des_access, &usr_generic_mapping);
2134 * Get the sampass first as we need to check privileges
2135 * based on what kind of user object this is.
2136 * But don't reveal info too early if it didn't exist.
2139 become_root();
2140 ret=pdb_getsampwsid(sampass, &sid);
2141 unbecome_root();
2143 needed_priv_1 = SEC_PRIV_INVALID;
2144 needed_priv_2 = SEC_PRIV_INVALID;
2146 * We do the override access checks on *open*, not at
2147 * SetUserInfo time.
2149 if (ret) {
2150 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2152 if (acb_info & ACB_WSTRUST) {
2154 * SeMachineAccount is needed to add
2155 * GENERIC_RIGHTS_USER_WRITE to a machine
2156 * account.
2158 needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2160 if (acb_info & ACB_NORMAL) {
2162 * SeAddUsers is needed to add
2163 * GENERIC_RIGHTS_USER_WRITE to a normal
2164 * account.
2166 needed_priv_1 = SEC_PRIV_ADD_USERS;
2169 * Cheat - we have not set a specific privilege for
2170 * server (BDC) or domain trust account, so allow
2171 * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2172 * DOMAIN_RID_ADMINS.
2174 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2175 if (lp_enable_privileges() && nt_token_check_domain_rid(p->session_info->security_token,
2176 DOMAIN_RID_ADMINS)) {
2177 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2178 extra_access = GENERIC_RIGHTS_USER_WRITE;
2179 DEBUG(4,("_samr_OpenUser: Allowing "
2180 "GENERIC_RIGHTS_USER_WRITE for "
2181 "rid admins\n"));
2186 TALLOC_FREE(sampass);
2188 nt_status = access_check_object(psd, p->session_info->security_token,
2189 needed_priv_1, needed_priv_2,
2190 GENERIC_RIGHTS_USER_WRITE, des_access,
2191 &acc_granted, "_samr_OpenUser");
2193 if ( !NT_STATUS_IS_OK(nt_status) )
2194 return nt_status;
2196 /* check that the SID exists in our domain. */
2197 if (ret == False) {
2198 return NT_STATUS_NO_SUCH_USER;
2201 /* If we did the rid admins hack above, allow access. */
2202 acc_granted |= extra_access;
2204 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2205 struct samr_user_info, &nt_status);
2206 if (!NT_STATUS_IS_OK(nt_status)) {
2207 return nt_status;
2209 uinfo->sid = sid;
2211 return NT_STATUS_OK;
2214 /*************************************************************************
2215 *************************************************************************/
2217 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2218 DATA_BLOB *blob,
2219 struct lsa_BinaryString **_r)
2221 struct lsa_BinaryString *r;
2223 if (!blob || !_r) {
2224 return NT_STATUS_INVALID_PARAMETER;
2227 r = talloc_zero(mem_ctx, struct lsa_BinaryString);
2228 if (!r) {
2229 return NT_STATUS_NO_MEMORY;
2232 r->array = talloc_zero_array(mem_ctx, uint16_t, blob->length/2);
2233 if (!r->array) {
2234 return NT_STATUS_NO_MEMORY;
2236 memcpy(r->array, blob->data, blob->length);
2237 r->size = blob->length;
2238 r->length = blob->length;
2240 if (!r->array) {
2241 return NT_STATUS_NO_MEMORY;
2244 *_r = r;
2246 return NT_STATUS_OK;
2249 /*************************************************************************
2250 *************************************************************************/
2252 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2253 struct samu *pw)
2255 struct samr_LogonHours hours;
2256 const int units_per_week = 168;
2258 ZERO_STRUCT(hours);
2259 hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2260 if (!hours.bits) {
2261 return hours;
2264 hours.units_per_week = units_per_week;
2265 memset(hours.bits, 0xFF, units_per_week);
2267 if (pdb_get_hours(pw)) {
2268 memcpy(hours.bits, pdb_get_hours(pw),
2269 MIN(pdb_get_hours_len(pw), units_per_week));
2272 return hours;
2275 /*************************************************************************
2276 get_user_info_1.
2277 *************************************************************************/
2279 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2280 struct samr_UserInfo1 *r,
2281 struct samu *pw,
2282 struct dom_sid *domain_sid)
2284 const struct dom_sid *sid_group;
2285 uint32_t primary_gid;
2287 become_root();
2288 sid_group = pdb_get_group_sid(pw);
2289 unbecome_root();
2291 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2292 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2293 "which conflicts with the domain sid %s. Failing operation.\n",
2294 pdb_get_username(pw), sid_string_dbg(sid_group),
2295 sid_string_dbg(domain_sid)));
2296 return NT_STATUS_UNSUCCESSFUL;
2299 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2300 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2301 r->primary_gid = primary_gid;
2302 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2303 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2305 return NT_STATUS_OK;
2308 /*************************************************************************
2309 get_user_info_2.
2310 *************************************************************************/
2312 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2313 struct samr_UserInfo2 *r,
2314 struct samu *pw)
2316 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2317 r->reserved.string = NULL;
2318 r->country_code = pdb_get_country_code(pw);
2319 r->code_page = pdb_get_code_page(pw);
2321 return NT_STATUS_OK;
2324 /*************************************************************************
2325 get_user_info_3.
2326 *************************************************************************/
2328 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2329 struct samr_UserInfo3 *r,
2330 struct samu *pw,
2331 struct dom_sid *domain_sid)
2333 const struct dom_sid *sid_user, *sid_group;
2334 uint32_t rid, primary_gid;
2336 sid_user = pdb_get_user_sid(pw);
2338 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2339 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2340 "the domain sid %s. Failing operation.\n",
2341 pdb_get_username(pw), sid_string_dbg(sid_user),
2342 sid_string_dbg(domain_sid)));
2343 return NT_STATUS_UNSUCCESSFUL;
2346 become_root();
2347 sid_group = pdb_get_group_sid(pw);
2348 unbecome_root();
2350 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2351 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2352 "which conflicts with the domain sid %s. Failing operation.\n",
2353 pdb_get_username(pw), sid_string_dbg(sid_group),
2354 sid_string_dbg(domain_sid)));
2355 return NT_STATUS_UNSUCCESSFUL;
2358 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2359 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2360 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2361 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2362 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2364 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2365 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2366 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2367 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2368 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2369 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2370 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2372 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2373 r->rid = rid;
2374 r->primary_gid = primary_gid;
2375 r->acct_flags = pdb_get_acct_ctrl(pw);
2376 r->bad_password_count = pdb_get_bad_password_count(pw);
2377 r->logon_count = pdb_get_logon_count(pw);
2379 return NT_STATUS_OK;
2382 /*************************************************************************
2383 get_user_info_4.
2384 *************************************************************************/
2386 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2387 struct samr_UserInfo4 *r,
2388 struct samu *pw)
2390 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2392 return NT_STATUS_OK;
2395 /*************************************************************************
2396 get_user_info_5.
2397 *************************************************************************/
2399 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2400 struct samr_UserInfo5 *r,
2401 struct samu *pw,
2402 struct dom_sid *domain_sid)
2404 const struct dom_sid *sid_user, *sid_group;
2405 uint32_t rid, primary_gid;
2407 sid_user = pdb_get_user_sid(pw);
2409 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2410 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2411 "the domain sid %s. Failing operation.\n",
2412 pdb_get_username(pw), sid_string_dbg(sid_user),
2413 sid_string_dbg(domain_sid)));
2414 return NT_STATUS_UNSUCCESSFUL;
2417 become_root();
2418 sid_group = pdb_get_group_sid(pw);
2419 unbecome_root();
2421 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2422 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2423 "which conflicts with the domain sid %s. Failing operation.\n",
2424 pdb_get_username(pw), sid_string_dbg(sid_group),
2425 sid_string_dbg(domain_sid)));
2426 return NT_STATUS_UNSUCCESSFUL;
2429 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2430 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2431 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2432 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2434 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2435 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2436 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2437 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2438 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2439 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2440 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2441 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2443 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2444 r->rid = rid;
2445 r->primary_gid = primary_gid;
2446 r->acct_flags = pdb_get_acct_ctrl(pw);
2447 r->bad_password_count = pdb_get_bad_password_count(pw);
2448 r->logon_count = pdb_get_logon_count(pw);
2450 return NT_STATUS_OK;
2453 /*************************************************************************
2454 get_user_info_6.
2455 *************************************************************************/
2457 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2458 struct samr_UserInfo6 *r,
2459 struct samu *pw)
2461 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2462 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2464 return NT_STATUS_OK;
2467 /*************************************************************************
2468 get_user_info_7. Safe. Only gives out account_name.
2469 *************************************************************************/
2471 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2472 struct samr_UserInfo7 *r,
2473 struct samu *smbpass)
2475 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2476 if (!r->account_name.string) {
2477 return NT_STATUS_NO_MEMORY;
2480 return NT_STATUS_OK;
2483 /*************************************************************************
2484 get_user_info_8.
2485 *************************************************************************/
2487 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2488 struct samr_UserInfo8 *r,
2489 struct samu *pw)
2491 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2493 return NT_STATUS_OK;
2496 /*************************************************************************
2497 get_user_info_9. Only gives out primary group SID.
2498 *************************************************************************/
2500 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2501 struct samr_UserInfo9 *r,
2502 struct samu *smbpass)
2504 r->primary_gid = pdb_get_group_rid(smbpass);
2506 return NT_STATUS_OK;
2509 /*************************************************************************
2510 get_user_info_10.
2511 *************************************************************************/
2513 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2514 struct samr_UserInfo10 *r,
2515 struct samu *pw)
2517 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2518 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2520 return NT_STATUS_OK;
2523 /*************************************************************************
2524 get_user_info_11.
2525 *************************************************************************/
2527 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2528 struct samr_UserInfo11 *r,
2529 struct samu *pw)
2531 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2533 return NT_STATUS_OK;
2536 /*************************************************************************
2537 get_user_info_12.
2538 *************************************************************************/
2540 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2541 struct samr_UserInfo12 *r,
2542 struct samu *pw)
2544 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2546 return NT_STATUS_OK;
2549 /*************************************************************************
2550 get_user_info_13.
2551 *************************************************************************/
2553 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2554 struct samr_UserInfo13 *r,
2555 struct samu *pw)
2557 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2559 return NT_STATUS_OK;
2562 /*************************************************************************
2563 get_user_info_14.
2564 *************************************************************************/
2566 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2567 struct samr_UserInfo14 *r,
2568 struct samu *pw)
2570 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2572 return NT_STATUS_OK;
2575 /*************************************************************************
2576 get_user_info_16. Safe. Only gives out acb bits.
2577 *************************************************************************/
2579 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2580 struct samr_UserInfo16 *r,
2581 struct samu *smbpass)
2583 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2585 return NT_STATUS_OK;
2588 /*************************************************************************
2589 get_user_info_17.
2590 *************************************************************************/
2592 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2593 struct samr_UserInfo17 *r,
2594 struct samu *pw)
2596 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2598 return NT_STATUS_OK;
2601 /*************************************************************************
2602 get_user_info_18. OK - this is the killer as it gives out password info.
2603 Ensure that this is only allowed on an encrypted connection with a root
2604 user. JRA.
2605 *************************************************************************/
2607 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2608 TALLOC_CTX *mem_ctx,
2609 struct samr_UserInfo18 *r,
2610 struct dom_sid *user_sid)
2612 struct samu *smbpass=NULL;
2613 bool ret;
2614 const uint8_t *nt_pass = NULL;
2615 const uint8_t *lm_pass = NULL;
2617 ZERO_STRUCTP(r);
2619 if (security_token_is_system(p->session_info->security_token)) {
2620 goto query;
2623 if ((p->auth.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) ||
2624 (p->auth.auth_type != DCERPC_AUTH_TYPE_KRB5) ||
2625 (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO)) {
2626 return NT_STATUS_ACCESS_DENIED;
2629 if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2630 return NT_STATUS_ACCESS_DENIED;
2633 query:
2635 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2638 if ( !(smbpass = samu_new( mem_ctx )) ) {
2639 return NT_STATUS_NO_MEMORY;
2642 ret = pdb_getsampwsid(smbpass, user_sid);
2644 if (ret == False) {
2645 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2646 TALLOC_FREE(smbpass);
2647 return root_mode() ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2650 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2652 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2653 TALLOC_FREE(smbpass);
2654 return NT_STATUS_ACCOUNT_DISABLED;
2657 lm_pass = pdb_get_lanman_passwd(smbpass);
2658 if (lm_pass != NULL) {
2659 memcpy(r->lm_pwd.hash, lm_pass, 16);
2660 r->lm_pwd_active = true;
2663 nt_pass = pdb_get_nt_passwd(smbpass);
2664 if (nt_pass != NULL) {
2665 memcpy(r->nt_pwd.hash, nt_pass, 16);
2666 r->nt_pwd_active = true;
2668 r->password_expired = 0; /* FIXME */
2670 TALLOC_FREE(smbpass);
2672 return NT_STATUS_OK;
2675 /*************************************************************************
2676 get_user_info_20
2677 *************************************************************************/
2679 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2680 struct samr_UserInfo20 *r,
2681 struct samu *sampass)
2683 const char *munged_dial = NULL;
2684 DATA_BLOB blob;
2685 NTSTATUS status;
2686 struct lsa_BinaryString *parameters = NULL;
2688 ZERO_STRUCTP(r);
2690 munged_dial = pdb_get_munged_dial(sampass);
2692 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2693 munged_dial, (int)strlen(munged_dial)));
2695 if (munged_dial) {
2696 blob = base64_decode_data_blob(munged_dial);
2697 } else {
2698 blob = data_blob_string_const_null("");
2701 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2702 data_blob_free(&blob);
2703 if (!NT_STATUS_IS_OK(status)) {
2704 return status;
2707 r->parameters = *parameters;
2709 return NT_STATUS_OK;
2713 /*************************************************************************
2714 get_user_info_21
2715 *************************************************************************/
2717 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2718 struct samr_UserInfo21 *r,
2719 struct samu *pw,
2720 struct dom_sid *domain_sid,
2721 uint32_t acc_granted)
2723 NTSTATUS status;
2724 const struct dom_sid *sid_user, *sid_group;
2725 uint32_t rid, primary_gid;
2726 NTTIME force_password_change;
2727 time_t must_change_time;
2728 struct lsa_BinaryString *parameters = NULL;
2729 const char *munged_dial = NULL;
2730 DATA_BLOB blob;
2732 ZERO_STRUCTP(r);
2734 sid_user = pdb_get_user_sid(pw);
2736 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2737 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2738 "the domain sid %s. Failing operation.\n",
2739 pdb_get_username(pw), sid_string_dbg(sid_user),
2740 sid_string_dbg(domain_sid)));
2741 return NT_STATUS_UNSUCCESSFUL;
2744 become_root();
2745 sid_group = pdb_get_group_sid(pw);
2746 unbecome_root();
2748 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2749 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2750 "which conflicts with the domain sid %s. Failing operation.\n",
2751 pdb_get_username(pw), sid_string_dbg(sid_group),
2752 sid_string_dbg(domain_sid)));
2753 return NT_STATUS_UNSUCCESSFUL;
2756 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2757 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2758 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2759 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2760 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2762 must_change_time = pdb_get_pass_must_change_time(pw);
2763 if (pdb_is_password_change_time_max(must_change_time)) {
2764 unix_to_nt_time_abs(&force_password_change, must_change_time);
2765 } else {
2766 unix_to_nt_time(&force_password_change, must_change_time);
2769 munged_dial = pdb_get_munged_dial(pw);
2770 if (munged_dial) {
2771 blob = base64_decode_data_blob(munged_dial);
2772 } else {
2773 blob = data_blob_string_const_null("");
2776 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2777 data_blob_free(&blob);
2778 if (!NT_STATUS_IS_OK(status)) {
2779 return status;
2782 r->force_password_change = force_password_change;
2784 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2785 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2786 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2787 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2788 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2789 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2790 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2791 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2792 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2794 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2795 r->parameters = *parameters;
2796 r->rid = rid;
2797 r->primary_gid = primary_gid;
2798 r->acct_flags = pdb_get_acct_ctrl(pw);
2799 r->bad_password_count = pdb_get_bad_password_count(pw);
2800 r->logon_count = pdb_get_logon_count(pw);
2801 r->fields_present = pdb_build_fields_present(pw);
2802 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2803 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2804 r->country_code = pdb_get_country_code(pw);
2805 r->code_page = pdb_get_code_page(pw);
2806 r->lm_password_set = 0;
2807 r->nt_password_set = 0;
2809 #if 0
2812 Look at a user on a real NT4 PDC with usrmgr, press
2813 'ok'. Then you will see that fields_present is set to
2814 0x08f827fa. Look at the user immediately after that again,
2815 and you will see that 0x00fffff is returned. This solves
2816 the problem that you get access denied after having looked
2817 at the user.
2818 -- Volker
2821 #endif
2824 return NT_STATUS_OK;
2827 /*******************************************************************
2828 _samr_QueryUserInfo
2829 ********************************************************************/
2831 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
2832 struct samr_QueryUserInfo *r)
2834 NTSTATUS status;
2835 union samr_UserInfo *user_info = NULL;
2836 struct samr_user_info *uinfo;
2837 struct dom_sid domain_sid;
2838 uint32 rid;
2839 bool ret = false;
2840 struct samu *pwd = NULL;
2841 uint32_t acc_required, acc_granted;
2843 switch (r->in.level) {
2844 case 1: /* UserGeneralInformation */
2845 /* USER_READ_GENERAL */
2846 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2847 break;
2848 case 2: /* UserPreferencesInformation */
2849 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2850 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2851 SAMR_USER_ACCESS_GET_NAME_ETC;
2852 break;
2853 case 3: /* UserLogonInformation */
2854 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2855 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2856 SAMR_USER_ACCESS_GET_LOCALE |
2857 SAMR_USER_ACCESS_GET_LOGONINFO |
2858 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2859 break;
2860 case 4: /* UserLogonHoursInformation */
2861 /* USER_READ_LOGON */
2862 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2863 break;
2864 case 5: /* UserAccountInformation */
2865 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2866 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2867 SAMR_USER_ACCESS_GET_LOCALE |
2868 SAMR_USER_ACCESS_GET_LOGONINFO |
2869 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2870 break;
2871 case 6: /* UserNameInformation */
2872 case 7: /* UserAccountNameInformation */
2873 case 8: /* UserFullNameInformation */
2874 case 9: /* UserPrimaryGroupInformation */
2875 case 13: /* UserAdminCommentInformation */
2876 /* USER_READ_GENERAL */
2877 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2878 break;
2879 case 10: /* UserHomeInformation */
2880 case 11: /* UserScriptInformation */
2881 case 12: /* UserProfileInformation */
2882 case 14: /* UserWorkStationsInformation */
2883 /* USER_READ_LOGON */
2884 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2885 break;
2886 case 16: /* UserControlInformation */
2887 case 17: /* UserExpiresInformation */
2888 case 20: /* UserParametersInformation */
2889 /* USER_READ_ACCOUNT */
2890 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2891 break;
2892 case 21: /* UserAllInformation */
2893 /* FIXME! - gd */
2894 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2895 break;
2896 case 18: /* UserInternal1Information */
2897 /* FIXME! - gd */
2898 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2899 break;
2900 case 23: /* UserInternal4Information */
2901 case 24: /* UserInternal4InformationNew */
2902 case 25: /* UserInternal4InformationNew */
2903 case 26: /* UserInternal5InformationNew */
2904 default:
2905 return NT_STATUS_INVALID_INFO_CLASS;
2906 break;
2909 uinfo = policy_handle_find(p, r->in.user_handle,
2910 acc_required, &acc_granted,
2911 struct samr_user_info, &status);
2912 if (!NT_STATUS_IS_OK(status)) {
2913 return status;
2916 domain_sid = uinfo->sid;
2918 sid_split_rid(&domain_sid, &rid);
2920 if (!sid_check_is_in_our_sam(&uinfo->sid))
2921 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2923 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2924 sid_string_dbg(&uinfo->sid)));
2926 user_info = talloc_zero(p->mem_ctx, union samr_UserInfo);
2927 if (!user_info) {
2928 return NT_STATUS_NO_MEMORY;
2931 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2933 if (!(pwd = samu_new(p->mem_ctx))) {
2934 return NT_STATUS_NO_MEMORY;
2937 become_root();
2938 ret = pdb_getsampwsid(pwd, &uinfo->sid);
2939 unbecome_root();
2941 if (ret == false) {
2942 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
2943 TALLOC_FREE(pwd);
2944 return NT_STATUS_NO_SUCH_USER;
2947 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2949 samr_clear_sam_passwd(pwd);
2951 switch (r->in.level) {
2952 case 1:
2953 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
2954 break;
2955 case 2:
2956 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
2957 break;
2958 case 3:
2959 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
2960 break;
2961 case 4:
2962 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
2963 break;
2964 case 5:
2965 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2966 break;
2967 case 6:
2968 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
2969 break;
2970 case 7:
2971 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2972 break;
2973 case 8:
2974 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
2975 break;
2976 case 9:
2977 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2978 break;
2979 case 10:
2980 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
2981 break;
2982 case 11:
2983 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
2984 break;
2985 case 12:
2986 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
2987 break;
2988 case 13:
2989 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
2990 break;
2991 case 14:
2992 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
2993 break;
2994 case 16:
2995 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2996 break;
2997 case 17:
2998 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
2999 break;
3000 case 18:
3001 /* level 18 is special */
3002 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3003 &uinfo->sid);
3004 break;
3005 case 20:
3006 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3007 break;
3008 case 21:
3009 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3010 break;
3011 default:
3012 status = NT_STATUS_INVALID_INFO_CLASS;
3013 break;
3016 if (!NT_STATUS_IS_OK(status)) {
3017 goto done;
3020 *r->out.info = user_info;
3022 done:
3023 TALLOC_FREE(pwd);
3025 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3027 return status;
3030 /****************************************************************
3031 ****************************************************************/
3033 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3034 struct samr_QueryUserInfo2 *r)
3036 struct samr_QueryUserInfo u;
3038 u.in.user_handle = r->in.user_handle;
3039 u.in.level = r->in.level;
3040 u.out.info = r->out.info;
3042 return _samr_QueryUserInfo(p, &u);
3045 /*******************************************************************
3046 _samr_GetGroupsForUser
3047 ********************************************************************/
3049 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3050 struct samr_GetGroupsForUser *r)
3052 struct samr_user_info *uinfo;
3053 struct samu *sam_pass=NULL;
3054 struct dom_sid *sids;
3055 struct samr_RidWithAttribute dom_gid;
3056 struct samr_RidWithAttribute *gids = NULL;
3057 uint32 primary_group_rid;
3058 uint32_t num_groups = 0;
3059 gid_t *unix_gids;
3060 uint32_t i, num_gids;
3061 bool ret;
3062 NTSTATUS result;
3063 bool success = False;
3065 struct samr_RidWithAttributeArray *rids = NULL;
3068 * from the SID in the request:
3069 * we should send back the list of DOMAIN GROUPS
3070 * the user is a member of
3072 * and only the DOMAIN GROUPS
3073 * no ALIASES !!! neither aliases of the domain
3074 * nor aliases of the builtin SID
3076 * JFM, 12/2/2001
3079 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3081 uinfo = policy_handle_find(p, r->in.user_handle,
3082 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3083 struct samr_user_info, &result);
3084 if (!NT_STATUS_IS_OK(result)) {
3085 return result;
3088 rids = talloc_zero(p->mem_ctx, struct samr_RidWithAttributeArray);
3089 if (!rids) {
3090 return NT_STATUS_NO_MEMORY;
3093 if (!sid_check_is_in_our_sam(&uinfo->sid))
3094 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3096 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3097 return NT_STATUS_NO_MEMORY;
3100 become_root();
3101 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3102 unbecome_root();
3104 if (!ret) {
3105 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3106 sid_string_dbg(&uinfo->sid)));
3107 return NT_STATUS_NO_SUCH_USER;
3110 sids = NULL;
3112 /* make both calls inside the root block */
3113 become_root();
3114 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3115 &sids, &unix_gids, &num_groups);
3116 if ( NT_STATUS_IS_OK(result) ) {
3117 success = sid_peek_check_rid(get_global_sam_sid(),
3118 pdb_get_group_sid(sam_pass),
3119 &primary_group_rid);
3121 unbecome_root();
3123 if (!NT_STATUS_IS_OK(result)) {
3124 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3125 sid_string_dbg(&uinfo->sid)));
3126 return result;
3129 if ( !success ) {
3130 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3131 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3132 pdb_get_username(sam_pass)));
3133 TALLOC_FREE(sam_pass);
3134 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3137 gids = NULL;
3138 num_gids = 0;
3140 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3141 SE_GROUP_ENABLED);
3142 dom_gid.rid = primary_group_rid;
3143 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3145 for (i=0; i<num_groups; i++) {
3147 if (!sid_peek_check_rid(get_global_sam_sid(),
3148 &(sids[i]), &dom_gid.rid)) {
3149 DEBUG(10, ("Found sid %s not in our domain\n",
3150 sid_string_dbg(&sids[i])));
3151 continue;
3154 if (dom_gid.rid == primary_group_rid) {
3155 /* We added the primary group directly from the
3156 * sam_account. The other SIDs are unique from
3157 * enum_group_memberships */
3158 continue;
3161 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3164 rids->count = num_gids;
3165 rids->rids = gids;
3167 *r->out.rids = rids;
3169 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3171 return result;
3174 /*******************************************************************
3175 ********************************************************************/
3177 static uint32_t samr_get_server_role(void)
3179 uint32_t role = ROLE_DOMAIN_PDC;
3181 if (lp_server_role() == ROLE_DOMAIN_BDC) {
3182 role = ROLE_DOMAIN_BDC;
3185 return role;
3188 /*******************************************************************
3189 ********************************************************************/
3191 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3192 struct samr_DomInfo1 *r)
3194 uint32_t account_policy_temp;
3195 time_t u_expire, u_min_age;
3197 become_root();
3199 /* AS ROOT !!! */
3201 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3202 r->min_password_length = account_policy_temp;
3204 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3205 r->password_history_length = account_policy_temp;
3207 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3208 &r->password_properties);
3210 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3211 u_expire = account_policy_temp;
3213 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3214 u_min_age = account_policy_temp;
3216 /* !AS ROOT */
3218 unbecome_root();
3220 unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3221 unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3223 if (lp_check_password_script(talloc_tos()) && *lp_check_password_script(talloc_tos())) {
3224 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3227 return NT_STATUS_OK;
3230 /*******************************************************************
3231 ********************************************************************/
3233 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3234 struct samr_DomGeneralInformation *r,
3235 struct samr_domain_info *dinfo)
3237 uint32_t u_logout;
3238 time_t seq_num;
3240 become_root();
3242 /* AS ROOT !!! */
3244 r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3245 r->num_groups = count_sam_groups(dinfo->disp_info);
3246 r->num_aliases = count_sam_aliases(dinfo->disp_info);
3248 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3250 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3252 if (!pdb_get_seq_num(&seq_num)) {
3253 seq_num = time(NULL);
3256 /* !AS ROOT */
3258 unbecome_root();
3260 r->oem_information.string = lp_server_string(r);
3261 r->domain_name.string = lp_workgroup();
3262 r->primary.string = lp_netbios_name();
3263 r->sequence_num = seq_num;
3264 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3265 r->role = (enum samr_Role) samr_get_server_role();
3266 r->unknown3 = 1;
3268 return NT_STATUS_OK;
3271 /*******************************************************************
3272 ********************************************************************/
3274 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3275 struct samr_DomInfo3 *r)
3277 uint32_t u_logout;
3279 become_root();
3281 /* AS ROOT !!! */
3284 uint32_t ul;
3285 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3286 u_logout = (time_t)ul;
3289 /* !AS ROOT */
3291 unbecome_root();
3293 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3295 return NT_STATUS_OK;
3298 /*******************************************************************
3299 ********************************************************************/
3301 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3302 struct samr_DomOEMInformation *r)
3304 r->oem_information.string = lp_server_string(r);
3306 return NT_STATUS_OK;
3309 /*******************************************************************
3310 ********************************************************************/
3312 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3313 struct samr_DomInfo5 *r)
3315 r->domain_name.string = get_global_sam_name();
3317 return NT_STATUS_OK;
3320 /*******************************************************************
3321 ********************************************************************/
3323 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3324 struct samr_DomInfo6 *r)
3326 /* NT returns its own name when a PDC. win2k and later
3327 * only the name of the PDC if itself is a BDC (samba4
3328 * idl) */
3329 r->primary.string = lp_netbios_name();
3331 return NT_STATUS_OK;
3334 /*******************************************************************
3335 ********************************************************************/
3337 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3338 struct samr_DomInfo7 *r)
3340 r->role = (enum samr_Role) samr_get_server_role();
3342 return NT_STATUS_OK;
3345 /*******************************************************************
3346 ********************************************************************/
3348 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3349 struct samr_DomInfo8 *r)
3351 time_t seq_num;
3353 become_root();
3355 /* AS ROOT !!! */
3357 if (!pdb_get_seq_num(&seq_num)) {
3358 seq_num = time(NULL);
3361 /* !AS ROOT */
3363 unbecome_root();
3365 r->sequence_num = seq_num;
3366 r->domain_create_time = 0;
3368 return NT_STATUS_OK;
3371 /*******************************************************************
3372 ********************************************************************/
3374 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3375 struct samr_DomInfo9 *r)
3377 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3379 return NT_STATUS_OK;
3382 /*******************************************************************
3383 ********************************************************************/
3385 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3386 struct samr_DomGeneralInformation2 *r,
3387 struct samr_domain_info *dinfo)
3389 NTSTATUS status;
3390 uint32_t account_policy_temp;
3391 time_t u_lock_duration, u_reset_time;
3393 status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3394 if (!NT_STATUS_IS_OK(status)) {
3395 return status;
3398 /* AS ROOT !!! */
3400 become_root();
3402 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3403 u_lock_duration = account_policy_temp;
3404 if (u_lock_duration != -1) {
3405 u_lock_duration *= 60;
3408 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3409 u_reset_time = account_policy_temp * 60;
3411 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3412 r->lockout_threshold = account_policy_temp;
3414 /* !AS ROOT */
3416 unbecome_root();
3418 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3419 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3421 return NT_STATUS_OK;
3424 /*******************************************************************
3425 ********************************************************************/
3427 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3428 struct samr_DomInfo12 *r)
3430 uint32_t account_policy_temp;
3431 time_t u_lock_duration, u_reset_time;
3433 become_root();
3435 /* AS ROOT !!! */
3437 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3438 u_lock_duration = account_policy_temp;
3439 if (u_lock_duration != -1) {
3440 u_lock_duration *= 60;
3443 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3444 u_reset_time = account_policy_temp * 60;
3446 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3447 r->lockout_threshold = account_policy_temp;
3449 /* !AS ROOT */
3451 unbecome_root();
3453 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3454 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3456 return NT_STATUS_OK;
3459 /*******************************************************************
3460 ********************************************************************/
3462 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3463 struct samr_DomInfo13 *r)
3465 time_t seq_num;
3467 become_root();
3469 /* AS ROOT !!! */
3471 if (!pdb_get_seq_num(&seq_num)) {
3472 seq_num = time(NULL);
3475 /* !AS ROOT */
3477 unbecome_root();
3479 r->sequence_num = seq_num;
3480 r->domain_create_time = 0;
3481 r->modified_count_at_last_promotion = 0;
3483 return NT_STATUS_OK;
3486 /*******************************************************************
3487 _samr_QueryDomainInfo
3488 ********************************************************************/
3490 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3491 struct samr_QueryDomainInfo *r)
3493 NTSTATUS status = NT_STATUS_OK;
3494 struct samr_domain_info *dinfo;
3495 union samr_DomainInfo *dom_info;
3497 uint32_t acc_required;
3499 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3501 switch (r->in.level) {
3502 case 1: /* DomainPasswordInformation */
3503 case 12: /* DomainLockoutInformation */
3504 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3505 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3506 break;
3507 case 11: /* DomainGeneralInformation2 */
3508 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3509 * DOMAIN_READ_OTHER_PARAMETERS */
3510 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3511 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3512 break;
3513 case 2: /* DomainGeneralInformation */
3514 case 3: /* DomainLogoffInformation */
3515 case 4: /* DomainOemInformation */
3516 case 5: /* DomainReplicationInformation */
3517 case 6: /* DomainReplicationInformation */
3518 case 7: /* DomainServerRoleInformation */
3519 case 8: /* DomainModifiedInformation */
3520 case 9: /* DomainStateInformation */
3521 case 10: /* DomainUasInformation */
3522 case 13: /* DomainModifiedInformation2 */
3523 /* DOMAIN_READ_OTHER_PARAMETERS */
3524 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3525 break;
3526 default:
3527 return NT_STATUS_INVALID_INFO_CLASS;
3530 dinfo = policy_handle_find(p, r->in.domain_handle,
3531 acc_required, NULL,
3532 struct samr_domain_info, &status);
3533 if (!NT_STATUS_IS_OK(status)) {
3534 return status;
3537 dom_info = talloc_zero(p->mem_ctx, union samr_DomainInfo);
3538 if (!dom_info) {
3539 return NT_STATUS_NO_MEMORY;
3542 switch (r->in.level) {
3543 case 1:
3544 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3545 break;
3546 case 2:
3547 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3548 break;
3549 case 3:
3550 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3551 break;
3552 case 4:
3553 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3554 break;
3555 case 5:
3556 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3557 break;
3558 case 6:
3559 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3560 break;
3561 case 7:
3562 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3563 break;
3564 case 8:
3565 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3566 break;
3567 case 9:
3568 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3569 break;
3570 case 11:
3571 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3572 break;
3573 case 12:
3574 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3575 break;
3576 case 13:
3577 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3578 break;
3579 default:
3580 return NT_STATUS_INVALID_INFO_CLASS;
3583 if (!NT_STATUS_IS_OK(status)) {
3584 return status;
3587 *r->out.info = dom_info;
3589 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3591 return status;
3594 /* W2k3 seems to use the same check for all 3 objects that can be created via
3595 * SAMR, if you try to create for example "Dialup" as an alias it says
3596 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3597 * database. */
3599 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3601 enum lsa_SidType type;
3602 bool result;
3604 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3606 become_root();
3607 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3608 * whether the name already exists */
3609 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3610 NULL, NULL, NULL, &type);
3611 unbecome_root();
3613 if (!result) {
3614 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3615 return NT_STATUS_OK;
3618 DEBUG(5, ("trying to create %s, exists as %s\n",
3619 new_name, sid_type_lookup(type)));
3621 if (type == SID_NAME_DOM_GRP) {
3622 return NT_STATUS_GROUP_EXISTS;
3624 if (type == SID_NAME_ALIAS) {
3625 return NT_STATUS_ALIAS_EXISTS;
3628 /* Yes, the default is NT_STATUS_USER_EXISTS */
3629 return NT_STATUS_USER_EXISTS;
3632 /*******************************************************************
3633 _samr_CreateUser2
3634 ********************************************************************/
3636 NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3637 struct samr_CreateUser2 *r)
3639 const char *account = NULL;
3640 struct dom_sid sid;
3641 uint32_t acb_info = r->in.acct_flags;
3642 struct samr_domain_info *dinfo;
3643 struct samr_user_info *uinfo;
3644 NTSTATUS nt_status;
3645 uint32 acc_granted;
3646 struct security_descriptor *psd;
3647 size_t sd_size;
3648 /* check this, when giving away 'add computer to domain' privs */
3649 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3650 bool can_add_account = False;
3652 /* Which privilege is needed to override the ACL? */
3653 enum sec_privilege needed_priv = SEC_PRIV_INVALID;
3655 dinfo = policy_handle_find(p, r->in.domain_handle,
3656 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3657 struct samr_domain_info, &nt_status);
3658 if (!NT_STATUS_IS_OK(nt_status)) {
3659 return nt_status;
3662 if (sid_check_is_builtin(&dinfo->sid)) {
3663 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3664 return NT_STATUS_ACCESS_DENIED;
3667 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3668 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3669 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3670 this parameter is not an account type */
3671 return NT_STATUS_INVALID_PARAMETER;
3674 account = r->in.account_name->string;
3675 if (account == NULL) {
3676 return NT_STATUS_NO_MEMORY;
3679 nt_status = can_create(p->mem_ctx, account);
3680 if (!NT_STATUS_IS_OK(nt_status)) {
3681 return nt_status;
3684 /* determine which user right we need to check based on the acb_info */
3686 if (root_mode()) {
3687 can_add_account = true;
3688 } else if (acb_info & ACB_WSTRUST) {
3689 needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
3690 can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_MACHINE_ACCOUNT);
3691 } else if (acb_info & ACB_NORMAL &&
3692 (account[strlen(account)-1] != '$')) {
3693 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3694 account for domain trusts and changes the ACB flags later */
3695 needed_priv = SEC_PRIV_ADD_USERS;
3696 can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS);
3697 } else if (lp_enable_privileges()) {
3698 /* implicit assumption of a BDC or domain trust account here
3699 * (we already check the flags earlier) */
3700 /* only Domain Admins can add a BDC or domain trust */
3701 can_add_account = nt_token_check_domain_rid(
3702 p->session_info->security_token,
3703 DOMAIN_RID_ADMINS );
3706 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3707 uidtoname(p->session_info->unix_token->uid),
3708 can_add_account ? "True":"False" ));
3710 if (!can_add_account) {
3711 return NT_STATUS_ACCESS_DENIED;
3714 /********** BEGIN Admin BLOCK **********/
3716 become_root();
3717 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3718 r->out.rid);
3719 unbecome_root();
3721 /********** END Admin BLOCK **********/
3723 /* now check for failure */
3725 if ( !NT_STATUS_IS_OK(nt_status) )
3726 return nt_status;
3728 /* Get the user's SID */
3730 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3732 map_max_allowed_access(p->session_info->security_token,
3733 p->session_info->unix_token,
3734 &des_access);
3736 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3737 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3738 se_map_generic(&des_access, &usr_generic_mapping);
3741 * JRA - TESTME. We just created this user so we
3742 * had rights to create them. Do we need to check
3743 * any further access on this object ? Can't we
3744 * just assume we have all the rights we need ?
3747 nt_status = access_check_object(psd, p->session_info->security_token,
3748 needed_priv, SEC_PRIV_INVALID,
3749 GENERIC_RIGHTS_USER_WRITE, des_access,
3750 &acc_granted, "_samr_CreateUser2");
3752 if ( !NT_STATUS_IS_OK(nt_status) ) {
3753 return nt_status;
3756 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3757 struct samr_user_info, &nt_status);
3758 if (!NT_STATUS_IS_OK(nt_status)) {
3759 return nt_status;
3761 uinfo->sid = sid;
3763 /* After a "set" ensure we have no cached display info. */
3764 force_flush_samr_cache(&sid);
3766 *r->out.access_granted = acc_granted;
3768 return NT_STATUS_OK;
3771 /****************************************************************
3772 ****************************************************************/
3774 NTSTATUS _samr_CreateUser(struct pipes_struct *p,
3775 struct samr_CreateUser *r)
3777 struct samr_CreateUser2 c;
3778 uint32_t access_granted;
3780 c.in.domain_handle = r->in.domain_handle;
3781 c.in.account_name = r->in.account_name;
3782 c.in.acct_flags = ACB_NORMAL;
3783 c.in.access_mask = r->in.access_mask;
3784 c.out.user_handle = r->out.user_handle;
3785 c.out.access_granted = &access_granted;
3786 c.out.rid = r->out.rid;
3788 return _samr_CreateUser2(p, &c);
3791 /*******************************************************************
3792 _samr_Connect
3793 ********************************************************************/
3795 NTSTATUS _samr_Connect(struct pipes_struct *p,
3796 struct samr_Connect *r)
3798 uint32_t acc_granted;
3799 struct policy_handle hnd;
3800 uint32 des_access = r->in.access_mask;
3801 NTSTATUS status;
3803 /* Access check */
3805 if (!pipe_access_check(p)) {
3806 DEBUG(3, ("access denied to _samr_Connect\n"));
3807 return NT_STATUS_ACCESS_DENIED;
3810 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3811 was observed from a win98 client trying to enumerate users (when configured
3812 user level access control on shares) --jerry */
3814 map_max_allowed_access(p->session_info->security_token,
3815 p->session_info->unix_token,
3816 &des_access);
3818 se_map_generic( &des_access, &sam_generic_mapping );
3820 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3821 |SAMR_ACCESS_LOOKUP_DOMAIN);
3823 /* set up the SAMR connect_anon response */
3825 (void)policy_handle_create(p, &hnd, acc_granted,
3826 struct samr_connect_info,
3827 &status);
3828 if (!NT_STATUS_IS_OK(status)) {
3829 return status;
3832 *r->out.connect_handle = hnd;
3833 return NT_STATUS_OK;
3836 /*******************************************************************
3837 _samr_Connect2
3838 ********************************************************************/
3840 NTSTATUS _samr_Connect2(struct pipes_struct *p,
3841 struct samr_Connect2 *r)
3843 struct policy_handle hnd;
3844 struct security_descriptor *psd = NULL;
3845 uint32 acc_granted;
3846 uint32 des_access = r->in.access_mask;
3847 NTSTATUS nt_status;
3848 size_t sd_size;
3849 const char *fn = "_samr_Connect2";
3851 switch (p->opnum) {
3852 case NDR_SAMR_CONNECT2:
3853 fn = "_samr_Connect2";
3854 break;
3855 case NDR_SAMR_CONNECT3:
3856 fn = "_samr_Connect3";
3857 break;
3858 case NDR_SAMR_CONNECT4:
3859 fn = "_samr_Connect4";
3860 break;
3861 case NDR_SAMR_CONNECT5:
3862 fn = "_samr_Connect5";
3863 break;
3866 DEBUG(5,("%s: %d\n", fn, __LINE__));
3868 /* Access check */
3870 if (!pipe_access_check(p)) {
3871 DEBUG(3, ("access denied to %s\n", fn));
3872 return NT_STATUS_ACCESS_DENIED;
3875 map_max_allowed_access(p->session_info->security_token,
3876 p->session_info->unix_token,
3877 &des_access);
3879 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3880 se_map_generic(&des_access, &sam_generic_mapping);
3882 nt_status = access_check_object(psd, p->session_info->security_token,
3883 SEC_PRIV_INVALID, SEC_PRIV_INVALID,
3884 0, des_access, &acc_granted, fn);
3886 if ( !NT_STATUS_IS_OK(nt_status) )
3887 return nt_status;
3889 (void)policy_handle_create(p, &hnd, acc_granted,
3890 struct samr_connect_info, &nt_status);
3891 if (!NT_STATUS_IS_OK(nt_status)) {
3892 return nt_status;
3895 DEBUG(5,("%s: %d\n", fn, __LINE__));
3897 *r->out.connect_handle = hnd;
3898 return NT_STATUS_OK;
3901 /****************************************************************
3902 _samr_Connect3
3903 ****************************************************************/
3905 NTSTATUS _samr_Connect3(struct pipes_struct *p,
3906 struct samr_Connect3 *r)
3908 struct samr_Connect2 c;
3910 c.in.system_name = r->in.system_name;
3911 c.in.access_mask = r->in.access_mask;
3912 c.out.connect_handle = r->out.connect_handle;
3914 return _samr_Connect2(p, &c);
3917 /*******************************************************************
3918 _samr_Connect4
3919 ********************************************************************/
3921 NTSTATUS _samr_Connect4(struct pipes_struct *p,
3922 struct samr_Connect4 *r)
3924 struct samr_Connect2 c;
3926 c.in.system_name = r->in.system_name;
3927 c.in.access_mask = r->in.access_mask;
3928 c.out.connect_handle = r->out.connect_handle;
3930 return _samr_Connect2(p, &c);
3933 /*******************************************************************
3934 _samr_Connect5
3935 ********************************************************************/
3937 NTSTATUS _samr_Connect5(struct pipes_struct *p,
3938 struct samr_Connect5 *r)
3940 NTSTATUS status;
3941 struct samr_Connect2 c;
3942 struct samr_ConnectInfo1 info1;
3944 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3945 info1.unknown2 = 0;
3947 c.in.system_name = r->in.system_name;
3948 c.in.access_mask = r->in.access_mask;
3949 c.out.connect_handle = r->out.connect_handle;
3951 *r->out.level_out = 1;
3953 status = _samr_Connect2(p, &c);
3954 if (!NT_STATUS_IS_OK(status)) {
3955 return status;
3958 r->out.info_out->info1 = info1;
3960 return NT_STATUS_OK;
3963 /**********************************************************************
3964 _samr_LookupDomain
3965 **********************************************************************/
3967 NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
3968 struct samr_LookupDomain *r)
3970 NTSTATUS status;
3971 const char *domain_name;
3972 struct dom_sid *sid = NULL;
3974 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3975 Reverted that change so we will work with RAS servers again */
3977 (void)policy_handle_find(p, r->in.connect_handle,
3978 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3979 struct samr_connect_info,
3980 &status);
3981 if (!NT_STATUS_IS_OK(status)) {
3982 return status;
3985 domain_name = r->in.domain_name->string;
3986 if (!domain_name) {
3987 return NT_STATUS_INVALID_PARAMETER;
3990 sid = talloc_zero(p->mem_ctx, struct dom_sid2);
3991 if (!sid) {
3992 return NT_STATUS_NO_MEMORY;
3995 if (strequal(domain_name, builtin_domain_name())) {
3996 sid_copy(sid, &global_sid_Builtin);
3997 } else {
3998 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3999 status = NT_STATUS_NO_SUCH_DOMAIN;
4003 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4004 sid_string_dbg(sid)));
4006 *r->out.sid = sid;
4008 return status;
4011 /**********************************************************************
4012 _samr_EnumDomains
4013 **********************************************************************/
4015 NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4016 struct samr_EnumDomains *r)
4018 NTSTATUS status;
4019 uint32_t num_entries = 2;
4020 struct samr_SamEntry *entry_array = NULL;
4021 struct samr_SamArray *sam;
4023 (void)policy_handle_find(p, r->in.connect_handle,
4024 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4025 struct samr_connect_info, &status);
4026 if (!NT_STATUS_IS_OK(status)) {
4027 return status;
4030 sam = talloc_zero(p->mem_ctx, struct samr_SamArray);
4031 if (!sam) {
4032 return NT_STATUS_NO_MEMORY;
4035 entry_array = talloc_zero_array(p->mem_ctx,
4036 struct samr_SamEntry,
4037 num_entries);
4038 if (!entry_array) {
4039 return NT_STATUS_NO_MEMORY;
4042 entry_array[0].idx = 0;
4043 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4045 entry_array[1].idx = 1;
4046 init_lsa_String(&entry_array[1].name, "Builtin");
4048 sam->count = num_entries;
4049 sam->entries = entry_array;
4051 *r->out.sam = sam;
4052 *r->out.num_entries = num_entries;
4054 return status;
4057 /*******************************************************************
4058 _samr_OpenAlias
4059 ********************************************************************/
4061 NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4062 struct samr_OpenAlias *r)
4064 struct dom_sid sid;
4065 uint32 alias_rid = r->in.rid;
4066 struct samr_alias_info *ainfo;
4067 struct samr_domain_info *dinfo;
4068 struct security_descriptor *psd = NULL;
4069 uint32 acc_granted;
4070 uint32 des_access = r->in.access_mask;
4071 size_t sd_size;
4072 NTSTATUS status;
4074 dinfo = policy_handle_find(p, r->in.domain_handle,
4075 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4076 struct samr_domain_info, &status);
4077 if (!NT_STATUS_IS_OK(status)) {
4078 return status;
4081 /* append the alias' RID to it */
4083 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4084 return NT_STATUS_NO_SUCH_ALIAS;
4086 /*check if access can be granted as requested by client. */
4088 map_max_allowed_access(p->session_info->security_token,
4089 p->session_info->unix_token,
4090 &des_access);
4092 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4093 se_map_generic(&des_access,&ali_generic_mapping);
4095 status = access_check_object(psd, p->session_info->security_token,
4096 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
4097 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4098 des_access, &acc_granted, "_samr_OpenAlias");
4100 if ( !NT_STATUS_IS_OK(status) )
4101 return status;
4104 /* Check we actually have the requested alias */
4105 enum lsa_SidType type;
4106 bool result;
4107 gid_t gid;
4109 become_root();
4110 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4111 unbecome_root();
4113 if (!result || (type != SID_NAME_ALIAS)) {
4114 return NT_STATUS_NO_SUCH_ALIAS;
4117 /* make sure there is a mapping */
4119 if ( !sid_to_gid( &sid, &gid ) ) {
4120 return NT_STATUS_NO_SUCH_ALIAS;
4125 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4126 struct samr_alias_info, &status);
4127 if (!NT_STATUS_IS_OK(status)) {
4128 return status;
4130 ainfo->sid = sid;
4132 return NT_STATUS_OK;
4135 /*******************************************************************
4136 set_user_info_2
4137 ********************************************************************/
4139 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4140 struct samr_UserInfo2 *id2,
4141 struct samu *pwd)
4143 if (id2 == NULL) {
4144 DEBUG(5,("set_user_info_2: NULL id2\n"));
4145 return NT_STATUS_ACCESS_DENIED;
4148 copy_id2_to_sam_passwd(pwd, id2);
4150 return pdb_update_sam_account(pwd);
4153 /*******************************************************************
4154 set_user_info_4
4155 ********************************************************************/
4157 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4158 struct samr_UserInfo4 *id4,
4159 struct samu *pwd)
4161 if (id4 == NULL) {
4162 DEBUG(5,("set_user_info_2: NULL id4\n"));
4163 return NT_STATUS_ACCESS_DENIED;
4166 copy_id4_to_sam_passwd(pwd, id4);
4168 return pdb_update_sam_account(pwd);
4171 /*******************************************************************
4172 set_user_info_6
4173 ********************************************************************/
4175 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4176 struct samr_UserInfo6 *id6,
4177 struct samu *pwd)
4179 if (id6 == NULL) {
4180 DEBUG(5,("set_user_info_6: NULL id6\n"));
4181 return NT_STATUS_ACCESS_DENIED;
4184 copy_id6_to_sam_passwd(pwd, id6);
4186 return pdb_update_sam_account(pwd);
4189 /*******************************************************************
4190 set_user_info_7
4191 ********************************************************************/
4193 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4194 struct samr_UserInfo7 *id7,
4195 struct samu *pwd)
4197 NTSTATUS rc;
4199 if (id7 == NULL) {
4200 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4201 return NT_STATUS_ACCESS_DENIED;
4204 if (!id7->account_name.string) {
4205 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4206 return NT_STATUS_ACCESS_DENIED;
4209 /* check to see if the new username already exists. Note: we can't
4210 reliably lock all backends, so there is potentially the
4211 possibility that a user can be created in between this check and
4212 the rename. The rename should fail, but may not get the
4213 exact same failure status code. I think this is small enough
4214 of a window for this type of operation and the results are
4215 simply that the rename fails with a slightly different status
4216 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4218 rc = can_create(mem_ctx, id7->account_name.string);
4220 /* when there is nothing to change, we're done here */
4221 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4222 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4223 return NT_STATUS_OK;
4225 if (!NT_STATUS_IS_OK(rc)) {
4226 return rc;
4229 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4231 return rc;
4234 /*******************************************************************
4235 set_user_info_8
4236 ********************************************************************/
4238 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4239 struct samr_UserInfo8 *id8,
4240 struct samu *pwd)
4242 if (id8 == NULL) {
4243 DEBUG(5,("set_user_info_8: NULL id8\n"));
4244 return NT_STATUS_ACCESS_DENIED;
4247 copy_id8_to_sam_passwd(pwd, id8);
4249 return pdb_update_sam_account(pwd);
4252 /*******************************************************************
4253 set_user_info_10
4254 ********************************************************************/
4256 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4257 struct samr_UserInfo10 *id10,
4258 struct samu *pwd)
4260 if (id10 == NULL) {
4261 DEBUG(5,("set_user_info_8: NULL id10\n"));
4262 return NT_STATUS_ACCESS_DENIED;
4265 copy_id10_to_sam_passwd(pwd, id10);
4267 return pdb_update_sam_account(pwd);
4270 /*******************************************************************
4271 set_user_info_11
4272 ********************************************************************/
4274 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4275 struct samr_UserInfo11 *id11,
4276 struct samu *pwd)
4278 if (id11 == NULL) {
4279 DEBUG(5,("set_user_info_11: NULL id11\n"));
4280 return NT_STATUS_ACCESS_DENIED;
4283 copy_id11_to_sam_passwd(pwd, id11);
4285 return pdb_update_sam_account(pwd);
4288 /*******************************************************************
4289 set_user_info_12
4290 ********************************************************************/
4292 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4293 struct samr_UserInfo12 *id12,
4294 struct samu *pwd)
4296 if (id12 == NULL) {
4297 DEBUG(5,("set_user_info_12: NULL id12\n"));
4298 return NT_STATUS_ACCESS_DENIED;
4301 copy_id12_to_sam_passwd(pwd, id12);
4303 return pdb_update_sam_account(pwd);
4306 /*******************************************************************
4307 set_user_info_13
4308 ********************************************************************/
4310 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4311 struct samr_UserInfo13 *id13,
4312 struct samu *pwd)
4314 if (id13 == NULL) {
4315 DEBUG(5,("set_user_info_13: NULL id13\n"));
4316 return NT_STATUS_ACCESS_DENIED;
4319 copy_id13_to_sam_passwd(pwd, id13);
4321 return pdb_update_sam_account(pwd);
4324 /*******************************************************************
4325 set_user_info_14
4326 ********************************************************************/
4328 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4329 struct samr_UserInfo14 *id14,
4330 struct samu *pwd)
4332 if (id14 == NULL) {
4333 DEBUG(5,("set_user_info_14: NULL id14\n"));
4334 return NT_STATUS_ACCESS_DENIED;
4337 copy_id14_to_sam_passwd(pwd, id14);
4339 return pdb_update_sam_account(pwd);
4342 /*******************************************************************
4343 set_user_info_16
4344 ********************************************************************/
4346 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4347 struct samr_UserInfo16 *id16,
4348 struct samu *pwd)
4350 if (id16 == NULL) {
4351 DEBUG(5,("set_user_info_16: NULL id16\n"));
4352 return NT_STATUS_ACCESS_DENIED;
4355 copy_id16_to_sam_passwd(pwd, id16);
4357 return pdb_update_sam_account(pwd);
4360 /*******************************************************************
4361 set_user_info_17
4362 ********************************************************************/
4364 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4365 struct samr_UserInfo17 *id17,
4366 struct samu *pwd)
4368 if (id17 == NULL) {
4369 DEBUG(5,("set_user_info_17: NULL id17\n"));
4370 return NT_STATUS_ACCESS_DENIED;
4373 copy_id17_to_sam_passwd(pwd, id17);
4375 return pdb_update_sam_account(pwd);
4378 /*******************************************************************
4379 set_user_info_18
4380 ********************************************************************/
4382 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4383 TALLOC_CTX *mem_ctx,
4384 DATA_BLOB *session_key,
4385 struct samu *pwd)
4387 if (id18 == NULL) {
4388 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4389 return NT_STATUS_INVALID_PARAMETER;
4392 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4393 if (!session_key->length) {
4394 return NT_STATUS_NO_USER_SESSION_KEY;
4398 if (id18->nt_pwd_active) {
4400 DATA_BLOB in, out;
4402 in = data_blob_const(id18->nt_pwd.hash, 16);
4403 out = data_blob_talloc_zero(mem_ctx, 16);
4405 sess_crypt_blob(&out, &in, session_key, false);
4407 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4408 return NT_STATUS_ACCESS_DENIED;
4411 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4414 if (id18->lm_pwd_active) {
4416 DATA_BLOB in, out;
4418 in = data_blob_const(id18->lm_pwd.hash, 16);
4419 out = data_blob_talloc_zero(mem_ctx, 16);
4421 sess_crypt_blob(&out, &in, session_key, false);
4423 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4424 return NT_STATUS_ACCESS_DENIED;
4427 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4430 copy_id18_to_sam_passwd(pwd, id18);
4432 return pdb_update_sam_account(pwd);
4435 /*******************************************************************
4436 set_user_info_20
4437 ********************************************************************/
4439 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4440 struct samr_UserInfo20 *id20,
4441 struct samu *pwd)
4443 if (id20 == NULL) {
4444 DEBUG(5,("set_user_info_20: NULL id20\n"));
4445 return NT_STATUS_ACCESS_DENIED;
4448 copy_id20_to_sam_passwd(pwd, id20);
4450 return pdb_update_sam_account(pwd);
4453 /*******************************************************************
4454 set_user_info_21
4455 ********************************************************************/
4457 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4458 TALLOC_CTX *mem_ctx,
4459 DATA_BLOB *session_key,
4460 struct samu *pwd)
4462 NTSTATUS status;
4464 if (id21 == NULL) {
4465 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4466 return NT_STATUS_INVALID_PARAMETER;
4469 if (id21->fields_present == 0) {
4470 return NT_STATUS_INVALID_PARAMETER;
4473 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4474 return NT_STATUS_ACCESS_DENIED;
4477 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4478 if (id21->nt_password_set) {
4479 DATA_BLOB in, out;
4481 if ((id21->nt_owf_password.length != 16) ||
4482 (id21->nt_owf_password.size != 16)) {
4483 return NT_STATUS_INVALID_PARAMETER;
4486 if (!session_key->length) {
4487 return NT_STATUS_NO_USER_SESSION_KEY;
4490 in = data_blob_const(id21->nt_owf_password.array, 16);
4491 out = data_blob_talloc_zero(mem_ctx, 16);
4493 sess_crypt_blob(&out, &in, session_key, false);
4495 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4496 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4500 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4501 if (id21->lm_password_set) {
4502 DATA_BLOB in, out;
4504 if ((id21->lm_owf_password.length != 16) ||
4505 (id21->lm_owf_password.size != 16)) {
4506 return NT_STATUS_INVALID_PARAMETER;
4509 if (!session_key->length) {
4510 return NT_STATUS_NO_USER_SESSION_KEY;
4513 in = data_blob_const(id21->lm_owf_password.array, 16);
4514 out = data_blob_talloc_zero(mem_ctx, 16);
4516 sess_crypt_blob(&out, &in, session_key, false);
4518 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4519 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4523 /* we need to separately check for an account rename first */
4525 if (id21->account_name.string &&
4526 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4529 /* check to see if the new username already exists. Note: we can't
4530 reliably lock all backends, so there is potentially the
4531 possibility that a user can be created in between this check and
4532 the rename. The rename should fail, but may not get the
4533 exact same failure status code. I think this is small enough
4534 of a window for this type of operation and the results are
4535 simply that the rename fails with a slightly different status
4536 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4538 status = can_create(mem_ctx, id21->account_name.string);
4539 if (!NT_STATUS_IS_OK(status)) {
4540 return status;
4543 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4545 if (!NT_STATUS_IS_OK(status)) {
4546 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4547 nt_errstr(status)));
4548 return status;
4551 /* set the new username so that later
4552 functions can work on the new account */
4553 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4556 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4559 * The funny part about the previous two calls is
4560 * that pwd still has the password hashes from the
4561 * passdb entry. These have not been updated from
4562 * id21. I don't know if they need to be set. --jerry
4565 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4566 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4567 if ( !NT_STATUS_IS_OK(status) ) {
4568 return status;
4572 /* Don't worry about writing out the user account since the
4573 primary group SID is generated solely from the user's Unix
4574 primary group. */
4576 /* write the change out */
4577 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4578 return status;
4581 return NT_STATUS_OK;
4584 /*******************************************************************
4585 set_user_info_23
4586 ********************************************************************/
4588 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4589 struct samr_UserInfo23 *id23,
4590 const char *rhost,
4591 struct samu *pwd)
4593 char *plaintext_buf = NULL;
4594 size_t len = 0;
4595 uint32_t acct_ctrl;
4596 NTSTATUS status;
4598 if (id23 == NULL) {
4599 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4600 return NT_STATUS_INVALID_PARAMETER;
4603 if (id23->info.fields_present == 0) {
4604 return NT_STATUS_INVALID_PARAMETER;
4607 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4608 return NT_STATUS_ACCESS_DENIED;
4611 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4612 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4614 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4615 pdb_get_username(pwd)));
4617 if (!decode_pw_buffer(mem_ctx,
4618 id23->password.data,
4619 &plaintext_buf,
4620 &len,
4621 CH_UTF16)) {
4622 return NT_STATUS_WRONG_PASSWORD;
4625 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4626 return NT_STATUS_ACCESS_DENIED;
4630 copy_id23_to_sam_passwd(pwd, id23);
4632 acct_ctrl = pdb_get_acct_ctrl(pwd);
4634 /* if it's a trust account, don't update /etc/passwd */
4635 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4636 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4637 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4638 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4639 } else if (plaintext_buf) {
4640 /* update the UNIX password */
4641 if (lp_unix_password_sync() ) {
4642 struct passwd *passwd;
4643 if (pdb_get_username(pwd) == NULL) {
4644 DEBUG(1, ("chgpasswd: User without name???\n"));
4645 return NT_STATUS_ACCESS_DENIED;
4648 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4649 if (passwd == NULL) {
4650 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4653 if(!chgpasswd(pdb_get_username(pwd), rhost,
4654 passwd, "", plaintext_buf, True)) {
4655 return NT_STATUS_ACCESS_DENIED;
4657 TALLOC_FREE(passwd);
4661 if (plaintext_buf) {
4662 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4665 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4666 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4667 pwd)))) {
4668 return status;
4671 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4672 return status;
4675 return NT_STATUS_OK;
4678 /*******************************************************************
4679 set_user_info_pw
4680 ********************************************************************/
4682 static bool set_user_info_pw(uint8 *pass, const char *rhost, struct samu *pwd)
4684 size_t len = 0;
4685 char *plaintext_buf = NULL;
4686 uint32 acct_ctrl;
4688 DEBUG(5, ("Attempting administrator password change for user %s\n",
4689 pdb_get_username(pwd)));
4691 acct_ctrl = pdb_get_acct_ctrl(pwd);
4693 if (!decode_pw_buffer(talloc_tos(),
4694 pass,
4695 &plaintext_buf,
4696 &len,
4697 CH_UTF16)) {
4698 return False;
4701 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4702 return False;
4705 /* if it's a trust account, don't update /etc/passwd */
4706 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4707 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4708 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4709 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4710 } else {
4711 /* update the UNIX password */
4712 if (lp_unix_password_sync()) {
4713 struct passwd *passwd;
4715 if (pdb_get_username(pwd) == NULL) {
4716 DEBUG(1, ("chgpasswd: User without name???\n"));
4717 return False;
4720 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4721 if (passwd == NULL) {
4722 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4725 if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
4726 "", plaintext_buf, True)) {
4727 return False;
4729 TALLOC_FREE(passwd);
4733 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4735 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4737 return True;
4740 /*******************************************************************
4741 set_user_info_24
4742 ********************************************************************/
4744 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4745 const char *rhost,
4746 struct samr_UserInfo24 *id24,
4747 struct samu *pwd)
4749 NTSTATUS status;
4751 if (id24 == NULL) {
4752 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4753 return NT_STATUS_INVALID_PARAMETER;
4756 if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
4757 return NT_STATUS_WRONG_PASSWORD;
4760 copy_id24_to_sam_passwd(pwd, id24);
4762 status = pdb_update_sam_account(pwd);
4763 if (!NT_STATUS_IS_OK(status)) {
4764 return status;
4767 return NT_STATUS_OK;
4770 /*******************************************************************
4771 set_user_info_25
4772 ********************************************************************/
4774 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4775 const char *rhost,
4776 struct samr_UserInfo25 *id25,
4777 struct samu *pwd)
4779 NTSTATUS status;
4781 if (id25 == NULL) {
4782 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4783 return NT_STATUS_INVALID_PARAMETER;
4786 if (id25->info.fields_present == 0) {
4787 return NT_STATUS_INVALID_PARAMETER;
4790 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4791 return NT_STATUS_ACCESS_DENIED;
4794 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4795 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4797 if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
4798 return NT_STATUS_WRONG_PASSWORD;
4802 copy_id25_to_sam_passwd(pwd, id25);
4804 /* write the change out */
4805 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4806 return status;
4810 * We need to "pdb_update_sam_account" before the unix primary group
4811 * is set, because the idealx scripts would also change the
4812 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4813 * the delete explicit / add explicit, which would then fail to find
4814 * the previous primaryGroupSid value.
4817 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4818 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4819 if ( !NT_STATUS_IS_OK(status) ) {
4820 return status;
4824 return NT_STATUS_OK;
4827 /*******************************************************************
4828 set_user_info_26
4829 ********************************************************************/
4831 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4832 const char *rhost,
4833 struct samr_UserInfo26 *id26,
4834 struct samu *pwd)
4836 NTSTATUS status;
4838 if (id26 == NULL) {
4839 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4840 return NT_STATUS_INVALID_PARAMETER;
4843 if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
4844 return NT_STATUS_WRONG_PASSWORD;
4847 copy_id26_to_sam_passwd(pwd, id26);
4849 status = pdb_update_sam_account(pwd);
4850 if (!NT_STATUS_IS_OK(status)) {
4851 return status;
4854 return NT_STATUS_OK;
4857 /*************************************************************
4858 **************************************************************/
4860 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4862 uint32_t acc_required = 0;
4864 /* USER_ALL_USERNAME */
4865 if (fields & SAMR_FIELD_ACCOUNT_NAME)
4866 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4867 /* USER_ALL_FULLNAME */
4868 if (fields & SAMR_FIELD_FULL_NAME)
4869 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4870 /* USER_ALL_PRIMARYGROUPID */
4871 if (fields & SAMR_FIELD_PRIMARY_GID)
4872 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4873 /* USER_ALL_HOMEDIRECTORY */
4874 if (fields & SAMR_FIELD_HOME_DIRECTORY)
4875 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4876 /* USER_ALL_HOMEDIRECTORYDRIVE */
4877 if (fields & SAMR_FIELD_HOME_DRIVE)
4878 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4879 /* USER_ALL_SCRIPTPATH */
4880 if (fields & SAMR_FIELD_LOGON_SCRIPT)
4881 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4882 /* USER_ALL_PROFILEPATH */
4883 if (fields & SAMR_FIELD_PROFILE_PATH)
4884 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4885 /* USER_ALL_ADMINCOMMENT */
4886 if (fields & SAMR_FIELD_COMMENT)
4887 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4888 /* USER_ALL_WORKSTATIONS */
4889 if (fields & SAMR_FIELD_WORKSTATIONS)
4890 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4891 /* USER_ALL_LOGONHOURS */
4892 if (fields & SAMR_FIELD_LOGON_HOURS)
4893 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4894 /* USER_ALL_ACCOUNTEXPIRES */
4895 if (fields & SAMR_FIELD_ACCT_EXPIRY)
4896 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4897 /* USER_ALL_USERACCOUNTCONTROL */
4898 if (fields & SAMR_FIELD_ACCT_FLAGS)
4899 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4900 /* USER_ALL_PARAMETERS */
4901 if (fields & SAMR_FIELD_PARAMETERS)
4902 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4903 /* USER_ALL_USERCOMMENT */
4904 if (fields & SAMR_FIELD_COMMENT)
4905 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4906 /* USER_ALL_COUNTRYCODE */
4907 if (fields & SAMR_FIELD_COUNTRY_CODE)
4908 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4909 /* USER_ALL_CODEPAGE */
4910 if (fields & SAMR_FIELD_CODE_PAGE)
4911 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4912 /* USER_ALL_NTPASSWORDPRESENT */
4913 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
4914 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4915 /* USER_ALL_LMPASSWORDPRESENT */
4916 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
4917 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4918 /* USER_ALL_PASSWORDEXPIRED */
4919 if (fields & SAMR_FIELD_EXPIRED_FLAG)
4920 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4922 return acc_required;
4925 /*******************************************************************
4926 samr_SetUserInfo
4927 ********************************************************************/
4929 NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
4930 struct samr_SetUserInfo *r)
4932 struct samr_user_info *uinfo;
4933 NTSTATUS status;
4934 struct samu *pwd = NULL;
4935 union samr_UserInfo *info = r->in.info;
4936 uint32_t acc_required = 0;
4937 uint32_t fields = 0;
4938 bool ret;
4939 char *rhost;
4940 DATA_BLOB session_key;
4942 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4944 /* This is tricky. A WinXP domain join sets
4945 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4946 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4947 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4948 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4949 we'll use the set from the WinXP join as the basis. */
4951 switch (r->in.level) {
4952 case 2: /* UserPreferencesInformation */
4953 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
4954 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
4955 break;
4956 case 4: /* UserLogonHoursInformation */
4957 case 6: /* UserNameInformation */
4958 case 7: /* UserAccountNameInformation */
4959 case 8: /* UserFullNameInformation */
4960 case 9: /* UserPrimaryGroupInformation */
4961 case 10: /* UserHomeInformation */
4962 case 11: /* UserScriptInformation */
4963 case 12: /* UserProfileInformation */
4964 case 13: /* UserAdminCommentInformation */
4965 case 14: /* UserWorkStationsInformation */
4966 case 16: /* UserControlInformation */
4967 case 17: /* UserExpiresInformation */
4968 case 20: /* UserParametersInformation */
4969 /* USER_WRITE_ACCOUNT */
4970 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
4971 break;
4972 case 18: /* UserInternal1Information */
4973 /* FIXME: gd, this is a guess */
4974 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4975 break;
4976 case 21: /* UserAllInformation */
4977 fields = info->info21.fields_present;
4978 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4979 break;
4980 case 23: /* UserInternal4Information */
4981 fields = info->info23.info.fields_present;
4982 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4983 break;
4984 case 25: /* UserInternal4InformationNew */
4985 fields = info->info25.info.fields_present;
4986 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
4987 break;
4988 case 24: /* UserInternal5Information */
4989 case 26: /* UserInternal5InformationNew */
4990 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4991 break;
4992 default:
4993 return NT_STATUS_INVALID_INFO_CLASS;
4996 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
4997 struct samr_user_info, &status);
4998 if (!NT_STATUS_IS_OK(status)) {
4999 return status;
5002 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5003 sid_string_dbg(&uinfo->sid), r->in.level));
5005 if (info == NULL) {
5006 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5007 return NT_STATUS_INVALID_INFO_CLASS;
5010 if (!(pwd = samu_new(NULL))) {
5011 return NT_STATUS_NO_MEMORY;
5014 become_root();
5015 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5016 unbecome_root();
5018 if (!ret) {
5019 TALLOC_FREE(pwd);
5020 return NT_STATUS_NO_SUCH_USER;
5023 rhost = tsocket_address_inet_addr_string(p->remote_address,
5024 talloc_tos());
5025 if (rhost == NULL) {
5026 return NT_STATUS_NO_MEMORY;
5029 /* ================ BEGIN Privilege BLOCK ================ */
5031 become_root();
5033 /* ok! user info levels (lots: see MSDEV help), off we go... */
5035 switch (r->in.level) {
5037 case 2:
5038 status = set_user_info_2(p->mem_ctx,
5039 &info->info2, pwd);
5040 break;
5042 case 4:
5043 status = set_user_info_4(p->mem_ctx,
5044 &info->info4, pwd);
5045 break;
5047 case 6:
5048 status = set_user_info_6(p->mem_ctx,
5049 &info->info6, pwd);
5050 break;
5052 case 7:
5053 status = set_user_info_7(p->mem_ctx,
5054 &info->info7, pwd);
5055 break;
5057 case 8:
5058 status = set_user_info_8(p->mem_ctx,
5059 &info->info8, pwd);
5060 break;
5062 case 10:
5063 status = set_user_info_10(p->mem_ctx,
5064 &info->info10, pwd);
5065 break;
5067 case 11:
5068 status = set_user_info_11(p->mem_ctx,
5069 &info->info11, pwd);
5070 break;
5072 case 12:
5073 status = set_user_info_12(p->mem_ctx,
5074 &info->info12, pwd);
5075 break;
5077 case 13:
5078 status = set_user_info_13(p->mem_ctx,
5079 &info->info13, pwd);
5080 break;
5082 case 14:
5083 status = set_user_info_14(p->mem_ctx,
5084 &info->info14, pwd);
5085 break;
5087 case 16:
5088 status = set_user_info_16(p->mem_ctx,
5089 &info->info16, pwd);
5090 break;
5092 case 17:
5093 status = set_user_info_17(p->mem_ctx,
5094 &info->info17, pwd);
5095 break;
5097 case 18:
5098 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5099 if(!NT_STATUS_IS_OK(status)) {
5100 return status;
5102 /* Used by AS/U JRA. */
5103 status = set_user_info_18(&info->info18,
5104 p->mem_ctx,
5105 &session_key,
5106 pwd);
5107 break;
5109 case 20:
5110 status = set_user_info_20(p->mem_ctx,
5111 &info->info20, pwd);
5112 break;
5114 case 21:
5115 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5116 if(!NT_STATUS_IS_OK(status)) {
5117 return status;
5119 status = set_user_info_21(&info->info21,
5120 p->mem_ctx,
5121 &session_key,
5122 pwd);
5123 break;
5125 case 23:
5126 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5127 arcfour_crypt_blob(info->info23.password.data, 516,
5128 &session_key);
5130 dump_data(100, info->info23.password.data, 516);
5132 status = set_user_info_23(p->mem_ctx,
5133 &info->info23,
5134 rhost,
5135 pwd);
5136 break;
5138 case 24:
5139 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5140 arcfour_crypt_blob(info->info24.password.data,
5141 516,
5142 &session_key);
5144 dump_data(100, info->info24.password.data, 516);
5146 status = set_user_info_24(p->mem_ctx,
5147 rhost,
5148 &info->info24, pwd);
5149 break;
5151 case 25:
5152 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5153 encode_or_decode_arc4_passwd_buffer(
5154 info->info25.password.data,
5155 &session_key);
5157 dump_data(100, info->info25.password.data, 532);
5159 status = set_user_info_25(p->mem_ctx,
5160 rhost,
5161 &info->info25, pwd);
5162 break;
5164 case 26:
5165 status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
5166 encode_or_decode_arc4_passwd_buffer(
5167 info->info26.password.data,
5168 &session_key);
5170 dump_data(100, info->info26.password.data, 516);
5172 status = set_user_info_26(p->mem_ctx,
5173 rhost,
5174 &info->info26, pwd);
5175 break;
5177 default:
5178 status = NT_STATUS_INVALID_INFO_CLASS;
5181 TALLOC_FREE(pwd);
5183 unbecome_root();
5185 /* ================ END Privilege BLOCK ================ */
5187 if (NT_STATUS_IS_OK(status)) {
5188 force_flush_samr_cache(&uinfo->sid);
5191 return status;
5194 /*******************************************************************
5195 _samr_SetUserInfo2
5196 ********************************************************************/
5198 NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
5199 struct samr_SetUserInfo2 *r)
5201 struct samr_SetUserInfo q;
5203 q.in.user_handle = r->in.user_handle;
5204 q.in.level = r->in.level;
5205 q.in.info = r->in.info;
5207 return _samr_SetUserInfo(p, &q);
5210 /*********************************************************************
5211 _samr_GetAliasMembership
5212 *********************************************************************/
5214 NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
5215 struct samr_GetAliasMembership *r)
5217 size_t num_alias_rids;
5218 uint32 *alias_rids;
5219 struct samr_domain_info *dinfo;
5220 size_t i;
5222 NTSTATUS status;
5224 struct dom_sid *members;
5226 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5228 dinfo = policy_handle_find(p, r->in.domain_handle,
5229 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5230 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5231 struct samr_domain_info, &status);
5232 if (!NT_STATUS_IS_OK(status)) {
5233 return status;
5236 if (!sid_check_is_our_sam(&dinfo->sid) &&
5237 !sid_check_is_builtin(&dinfo->sid))
5238 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5240 if (r->in.sids->num_sids) {
5241 members = talloc_array(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
5243 if (members == NULL)
5244 return NT_STATUS_NO_MEMORY;
5245 } else {
5246 members = NULL;
5249 for (i=0; i<r->in.sids->num_sids; i++)
5250 sid_copy(&members[i], r->in.sids->sids[i].sid);
5252 alias_rids = NULL;
5253 num_alias_rids = 0;
5255 become_root();
5256 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5257 r->in.sids->num_sids,
5258 &alias_rids, &num_alias_rids);
5259 unbecome_root();
5261 if (!NT_STATUS_IS_OK(status)) {
5262 return status;
5265 r->out.rids->count = num_alias_rids;
5266 r->out.rids->ids = alias_rids;
5268 if (r->out.rids->ids == NULL) {
5269 /* Windows domain clients don't accept a NULL ptr here */
5270 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5272 if (r->out.rids->ids == NULL) {
5273 return NT_STATUS_NO_MEMORY;
5276 return NT_STATUS_OK;
5279 /*********************************************************************
5280 _samr_GetMembersInAlias
5281 *********************************************************************/
5283 NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
5284 struct samr_GetMembersInAlias *r)
5286 struct samr_alias_info *ainfo;
5287 NTSTATUS status;
5288 size_t i;
5289 size_t num_sids = 0;
5290 struct lsa_SidPtr *sids = NULL;
5291 struct dom_sid *pdb_sids = NULL;
5293 ainfo = policy_handle_find(p, r->in.alias_handle,
5294 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5295 struct samr_alias_info, &status);
5296 if (!NT_STATUS_IS_OK(status)) {
5297 return status;
5300 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5302 become_root();
5303 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5304 &num_sids);
5305 unbecome_root();
5307 if (!NT_STATUS_IS_OK(status)) {
5308 return status;
5311 if (num_sids) {
5312 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr, num_sids);
5313 if (sids == NULL) {
5314 TALLOC_FREE(pdb_sids);
5315 return NT_STATUS_NO_MEMORY;
5319 for (i = 0; i < num_sids; i++) {
5320 sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
5321 if (!sids[i].sid) {
5322 TALLOC_FREE(pdb_sids);
5323 return NT_STATUS_NO_MEMORY;
5327 r->out.sids->num_sids = num_sids;
5328 r->out.sids->sids = sids;
5330 TALLOC_FREE(pdb_sids);
5332 return NT_STATUS_OK;
5335 /*********************************************************************
5336 _samr_QueryGroupMember
5337 *********************************************************************/
5339 NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
5340 struct samr_QueryGroupMember *r)
5342 struct samr_group_info *ginfo;
5343 size_t i, num_members;
5345 uint32 *rid=NULL;
5346 uint32 *attr=NULL;
5348 NTSTATUS status;
5349 struct samr_RidAttrArray *rids = NULL;
5351 ginfo = policy_handle_find(p, r->in.group_handle,
5352 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5353 struct samr_group_info, &status);
5354 if (!NT_STATUS_IS_OK(status)) {
5355 return status;
5358 rids = talloc_zero(p->mem_ctx, struct samr_RidAttrArray);
5359 if (!rids) {
5360 return NT_STATUS_NO_MEMORY;
5363 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5365 if (!sid_check_is_in_our_sam(&ginfo->sid)) {
5366 DEBUG(3, ("sid %s is not in our domain\n",
5367 sid_string_dbg(&ginfo->sid)));
5368 return NT_STATUS_NO_SUCH_GROUP;
5371 DEBUG(10, ("lookup on Domain SID\n"));
5373 become_root();
5374 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5375 &rid, &num_members);
5376 unbecome_root();
5378 if (!NT_STATUS_IS_OK(status))
5379 return status;
5381 if (num_members) {
5382 attr=talloc_zero_array(p->mem_ctx, uint32, num_members);
5383 if (attr == NULL) {
5384 return NT_STATUS_NO_MEMORY;
5386 } else {
5387 attr = NULL;
5390 for (i=0; i<num_members; i++) {
5391 attr[i] = SE_GROUP_MANDATORY |
5392 SE_GROUP_ENABLED_BY_DEFAULT |
5393 SE_GROUP_ENABLED;
5396 rids->count = num_members;
5397 rids->attributes = attr;
5398 rids->rids = rid;
5400 *r->out.rids = rids;
5402 return NT_STATUS_OK;
5405 /*********************************************************************
5406 _samr_AddAliasMember
5407 *********************************************************************/
5409 NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
5410 struct samr_AddAliasMember *r)
5412 struct samr_alias_info *ainfo;
5413 NTSTATUS status;
5415 ainfo = policy_handle_find(p, r->in.alias_handle,
5416 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5417 struct samr_alias_info, &status);
5418 if (!NT_STATUS_IS_OK(status)) {
5419 return status;
5422 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5424 /******** BEGIN SeAddUsers BLOCK *********/
5426 become_root();
5427 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5428 unbecome_root();
5430 /******** END SeAddUsers BLOCK *********/
5432 if (NT_STATUS_IS_OK(status)) {
5433 force_flush_samr_cache(&ainfo->sid);
5436 return status;
5439 /*********************************************************************
5440 _samr_DeleteAliasMember
5441 *********************************************************************/
5443 NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
5444 struct samr_DeleteAliasMember *r)
5446 struct samr_alias_info *ainfo;
5447 NTSTATUS status;
5449 ainfo = policy_handle_find(p, r->in.alias_handle,
5450 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5451 struct samr_alias_info, &status);
5452 if (!NT_STATUS_IS_OK(status)) {
5453 return status;
5456 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5457 sid_string_dbg(&ainfo->sid)));
5459 /******** BEGIN SeAddUsers BLOCK *********/
5461 become_root();
5462 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5463 unbecome_root();
5465 /******** END SeAddUsers BLOCK *********/
5467 if (NT_STATUS_IS_OK(status)) {
5468 force_flush_samr_cache(&ainfo->sid);
5471 return status;
5474 /*********************************************************************
5475 _samr_AddGroupMember
5476 *********************************************************************/
5478 NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
5479 struct samr_AddGroupMember *r)
5481 struct samr_group_info *ginfo;
5482 NTSTATUS status;
5483 uint32 group_rid;
5485 ginfo = policy_handle_find(p, r->in.group_handle,
5486 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5487 struct samr_group_info, &status);
5488 if (!NT_STATUS_IS_OK(status)) {
5489 return status;
5492 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5494 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5495 &group_rid)) {
5496 return NT_STATUS_INVALID_HANDLE;
5499 /******** BEGIN SeAddUsers BLOCK *********/
5501 become_root();
5502 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5503 unbecome_root();
5505 /******** END SeAddUsers BLOCK *********/
5507 force_flush_samr_cache(&ginfo->sid);
5509 return status;
5512 /*********************************************************************
5513 _samr_DeleteGroupMember
5514 *********************************************************************/
5516 NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
5517 struct samr_DeleteGroupMember *r)
5520 struct samr_group_info *ginfo;
5521 NTSTATUS status;
5522 uint32 group_rid;
5525 * delete the group member named r->in.rid
5526 * who is a member of the sid associated with the handle
5527 * the rid is a user's rid as the group is a domain group.
5530 ginfo = policy_handle_find(p, r->in.group_handle,
5531 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5532 struct samr_group_info, &status);
5533 if (!NT_STATUS_IS_OK(status)) {
5534 return status;
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_del_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_DeleteUser
5557 *********************************************************************/
5559 NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
5560 struct samr_DeleteUser *r)
5562 struct samr_user_info *uinfo;
5563 NTSTATUS status;
5564 struct samu *sam_pass=NULL;
5565 bool ret;
5567 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5569 uinfo = policy_handle_find(p, r->in.user_handle,
5570 SEC_STD_DELETE, NULL,
5571 struct samr_user_info, &status);
5572 if (!NT_STATUS_IS_OK(status)) {
5573 return status;
5576 if (!sid_check_is_in_our_sam(&uinfo->sid))
5577 return NT_STATUS_CANNOT_DELETE;
5579 /* check if the user exists before trying to delete */
5580 if ( !(sam_pass = samu_new( NULL )) ) {
5581 return NT_STATUS_NO_MEMORY;
5584 become_root();
5585 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5586 unbecome_root();
5588 if(!ret) {
5589 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5590 sid_string_dbg(&uinfo->sid)));
5591 TALLOC_FREE(sam_pass);
5592 return NT_STATUS_NO_SUCH_USER;
5595 /******** BEGIN SeAddUsers BLOCK *********/
5597 become_root();
5598 status = pdb_delete_user(p->mem_ctx, sam_pass);
5599 unbecome_root();
5601 /******** END SeAddUsers BLOCK *********/
5603 if ( !NT_STATUS_IS_OK(status) ) {
5604 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5605 "user %s: %s.\n", pdb_get_username(sam_pass),
5606 nt_errstr(status)));
5607 TALLOC_FREE(sam_pass);
5608 return status;
5612 TALLOC_FREE(sam_pass);
5614 force_flush_samr_cache(&uinfo->sid);
5616 if (!close_policy_hnd(p, r->in.user_handle))
5617 return NT_STATUS_OBJECT_NAME_INVALID;
5619 ZERO_STRUCTP(r->out.user_handle);
5621 return NT_STATUS_OK;
5624 /*********************************************************************
5625 _samr_DeleteDomainGroup
5626 *********************************************************************/
5628 NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
5629 struct samr_DeleteDomainGroup *r)
5631 struct samr_group_info *ginfo;
5632 NTSTATUS status;
5633 uint32 group_rid;
5635 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5637 ginfo = policy_handle_find(p, r->in.group_handle,
5638 SEC_STD_DELETE, NULL,
5639 struct samr_group_info, &status);
5640 if (!NT_STATUS_IS_OK(status)) {
5641 return status;
5644 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5646 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5647 &group_rid)) {
5648 return NT_STATUS_NO_SUCH_GROUP;
5651 /******** BEGIN SeAddUsers BLOCK *********/
5653 become_root();
5654 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5655 unbecome_root();
5657 /******** END SeAddUsers BLOCK *********/
5659 if ( !NT_STATUS_IS_OK(status) ) {
5660 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5661 "entry for group %s: %s\n",
5662 sid_string_dbg(&ginfo->sid),
5663 nt_errstr(status)));
5664 return status;
5667 force_flush_samr_cache(&ginfo->sid);
5669 if (!close_policy_hnd(p, r->in.group_handle))
5670 return NT_STATUS_OBJECT_NAME_INVALID;
5672 return NT_STATUS_OK;
5675 /*********************************************************************
5676 _samr_DeleteDomAlias
5677 *********************************************************************/
5679 NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
5680 struct samr_DeleteDomAlias *r)
5682 struct samr_alias_info *ainfo;
5683 NTSTATUS status;
5685 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5687 ainfo = policy_handle_find(p, r->in.alias_handle,
5688 SEC_STD_DELETE, NULL,
5689 struct samr_alias_info, &status);
5690 if (!NT_STATUS_IS_OK(status)) {
5691 return status;
5694 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5696 /* Don't let Windows delete builtin groups */
5698 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5699 return NT_STATUS_SPECIAL_ACCOUNT;
5702 if (!sid_check_is_in_our_sam(&ainfo->sid))
5703 return NT_STATUS_NO_SUCH_ALIAS;
5705 DEBUG(10, ("lookup on Local SID\n"));
5707 /******** BEGIN SeAddUsers BLOCK *********/
5709 become_root();
5710 /* Have passdb delete the alias */
5711 status = pdb_delete_alias(&ainfo->sid);
5712 unbecome_root();
5714 /******** END SeAddUsers BLOCK *********/
5716 if ( !NT_STATUS_IS_OK(status))
5717 return status;
5719 force_flush_samr_cache(&ainfo->sid);
5721 if (!close_policy_hnd(p, r->in.alias_handle))
5722 return NT_STATUS_OBJECT_NAME_INVALID;
5724 return NT_STATUS_OK;
5727 /*********************************************************************
5728 _samr_CreateDomainGroup
5729 *********************************************************************/
5731 NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
5732 struct samr_CreateDomainGroup *r)
5735 NTSTATUS status;
5736 const char *name;
5737 struct samr_domain_info *dinfo;
5738 struct samr_group_info *ginfo;
5740 dinfo = policy_handle_find(p, r->in.domain_handle,
5741 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5742 struct samr_domain_info, &status);
5743 if (!NT_STATUS_IS_OK(status)) {
5744 return status;
5747 if (!sid_check_is_our_sam(&dinfo->sid)) {
5748 return NT_STATUS_ACCESS_DENIED;
5751 name = r->in.name->string;
5752 if (name == NULL) {
5753 return NT_STATUS_NO_MEMORY;
5756 status = can_create(p->mem_ctx, name);
5757 if (!NT_STATUS_IS_OK(status)) {
5758 return status;
5761 /******** BEGIN SeAddUsers BLOCK *********/
5763 become_root();
5764 /* check that we successfully create the UNIX group */
5765 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5766 unbecome_root();
5768 /******** END SeAddUsers BLOCK *********/
5770 /* check if we should bail out here */
5772 if ( !NT_STATUS_IS_OK(status) )
5773 return status;
5775 ginfo = policy_handle_create(p, r->out.group_handle,
5776 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5777 struct samr_group_info, &status);
5778 if (!NT_STATUS_IS_OK(status)) {
5779 return status;
5781 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5783 force_flush_samr_cache(&dinfo->sid);
5785 return NT_STATUS_OK;
5788 /*********************************************************************
5789 _samr_CreateDomAlias
5790 *********************************************************************/
5792 NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
5793 struct samr_CreateDomAlias *r)
5795 struct dom_sid info_sid;
5796 const char *name = NULL;
5797 struct samr_domain_info *dinfo;
5798 struct samr_alias_info *ainfo;
5799 gid_t gid;
5800 NTSTATUS result;
5802 dinfo = policy_handle_find(p, r->in.domain_handle,
5803 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5804 struct samr_domain_info, &result);
5805 if (!NT_STATUS_IS_OK(result)) {
5806 return result;
5809 if (!sid_check_is_our_sam(&dinfo->sid)) {
5810 return NT_STATUS_ACCESS_DENIED;
5813 name = r->in.alias_name->string;
5815 result = can_create(p->mem_ctx, name);
5816 if (!NT_STATUS_IS_OK(result)) {
5817 return result;
5820 /******** BEGIN SeAddUsers BLOCK *********/
5822 become_root();
5823 /* Have passdb create the alias */
5824 result = pdb_create_alias(name, r->out.rid);
5825 unbecome_root();
5827 /******** END SeAddUsers BLOCK *********/
5829 if (!NT_STATUS_IS_OK(result)) {
5830 DEBUG(10, ("pdb_create_alias failed: %s\n",
5831 nt_errstr(result)));
5832 return result;
5835 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5837 if (!sid_to_gid(&info_sid, &gid)) {
5838 DEBUG(10, ("Could not find alias just created\n"));
5839 return NT_STATUS_ACCESS_DENIED;
5842 /* check if the group has been successfully created */
5843 if ( getgrgid(gid) == NULL ) {
5844 DEBUG(1, ("getgrgid(%u) of just created alias failed\n",
5845 (unsigned int)gid));
5846 return NT_STATUS_ACCESS_DENIED;
5849 ainfo = policy_handle_create(p, r->out.alias_handle,
5850 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5851 struct samr_alias_info, &result);
5852 if (!NT_STATUS_IS_OK(result)) {
5853 return result;
5855 ainfo->sid = info_sid;
5857 force_flush_samr_cache(&info_sid);
5859 return NT_STATUS_OK;
5862 /*********************************************************************
5863 _samr_QueryGroupInfo
5864 *********************************************************************/
5866 NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
5867 struct samr_QueryGroupInfo *r)
5869 struct samr_group_info *ginfo;
5870 NTSTATUS status;
5871 GROUP_MAP *map;
5872 union samr_GroupInfo *info = NULL;
5873 bool ret;
5874 uint32_t attributes = SE_GROUP_MANDATORY |
5875 SE_GROUP_ENABLED_BY_DEFAULT |
5876 SE_GROUP_ENABLED;
5877 const char *group_name = NULL;
5878 const char *group_description = NULL;
5880 ginfo = policy_handle_find(p, r->in.group_handle,
5881 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5882 struct samr_group_info, &status);
5883 if (!NT_STATUS_IS_OK(status)) {
5884 return status;
5887 map = talloc_zero(p->mem_ctx, GROUP_MAP);
5888 if (!map) {
5889 return NT_STATUS_NO_MEMORY;
5892 become_root();
5893 ret = get_domain_group_from_sid(ginfo->sid, map);
5894 unbecome_root();
5895 if (!ret)
5896 return NT_STATUS_INVALID_HANDLE;
5898 group_name = talloc_move(r, &map->nt_name);
5899 group_description = talloc_move(r, &map->comment);
5901 TALLOC_FREE(map);
5903 info = talloc_zero(p->mem_ctx, union samr_GroupInfo);
5904 if (!info) {
5905 return NT_STATUS_NO_MEMORY;
5908 switch (r->in.level) {
5909 case 1: {
5910 uint32 *members;
5911 size_t num_members;
5913 become_root();
5914 status = pdb_enum_group_members(
5915 p->mem_ctx, &ginfo->sid, &members,
5916 &num_members);
5917 unbecome_root();
5919 if (!NT_STATUS_IS_OK(status)) {
5920 return status;
5923 info->all.name.string = group_name;
5924 info->all.attributes = attributes;
5925 info->all.num_members = num_members;
5926 info->all.description.string = group_description;
5927 break;
5929 case 2:
5930 info->name.string = group_name;
5931 break;
5932 case 3:
5933 info->attributes.attributes = attributes;
5934 break;
5935 case 4:
5936 info->description.string = group_description;
5937 break;
5938 case 5: {
5940 uint32 *members;
5941 size_t num_members;
5945 become_root();
5946 status = pdb_enum_group_members(
5947 p->mem_ctx, &ginfo->sid, &members,
5948 &num_members);
5949 unbecome_root();
5951 if (!NT_STATUS_IS_OK(status)) {
5952 return status;
5955 info->all2.name.string = group_name;
5956 info->all2.attributes = attributes;
5957 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5958 info->all2.description.string = group_description;
5960 break;
5962 default:
5963 return NT_STATUS_INVALID_INFO_CLASS;
5966 *r->out.info = info;
5968 return NT_STATUS_OK;
5971 /*********************************************************************
5972 _samr_SetGroupInfo
5973 *********************************************************************/
5975 NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
5976 struct samr_SetGroupInfo *r)
5978 struct samr_group_info *ginfo;
5979 GROUP_MAP *map;
5980 NTSTATUS status;
5981 bool ret;
5983 ginfo = policy_handle_find(p, r->in.group_handle,
5984 SAMR_GROUP_ACCESS_SET_INFO, NULL,
5985 struct samr_group_info, &status);
5986 if (!NT_STATUS_IS_OK(status)) {
5987 return status;
5990 map = talloc_zero(p->mem_ctx, GROUP_MAP);
5991 if (!map) {
5992 return NT_STATUS_NO_MEMORY;
5995 become_root();
5996 ret = get_domain_group_from_sid(ginfo->sid, map);
5997 unbecome_root();
5998 if (!ret)
5999 return NT_STATUS_NO_SUCH_GROUP;
6001 switch (r->in.level) {
6002 case 2:
6003 map->nt_name = talloc_strdup(map,
6004 r->in.info->name.string);
6005 if (!map->nt_name) {
6006 return NT_STATUS_NO_MEMORY;
6008 break;
6009 case 3:
6010 break;
6011 case 4:
6012 map->comment = talloc_strdup(map,
6013 r->in.info->description.string);
6014 if (!map->comment) {
6015 return NT_STATUS_NO_MEMORY;
6017 break;
6018 default:
6019 return NT_STATUS_INVALID_INFO_CLASS;
6022 /******** BEGIN SeAddUsers BLOCK *********/
6024 become_root();
6025 status = pdb_update_group_mapping_entry(map);
6026 unbecome_root();
6028 /******** End SeAddUsers BLOCK *********/
6030 TALLOC_FREE(map);
6032 if (NT_STATUS_IS_OK(status)) {
6033 force_flush_samr_cache(&ginfo->sid);
6036 return status;
6039 /*********************************************************************
6040 _samr_SetAliasInfo
6041 *********************************************************************/
6043 NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
6044 struct samr_SetAliasInfo *r)
6046 struct samr_alias_info *ainfo;
6047 struct acct_info *info;
6048 NTSTATUS status;
6050 ainfo = policy_handle_find(p, r->in.alias_handle,
6051 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6052 struct samr_alias_info, &status);
6053 if (!NT_STATUS_IS_OK(status)) {
6054 return status;
6057 info = talloc_zero(p->mem_ctx, struct acct_info);
6058 if (!info) {
6059 return NT_STATUS_NO_MEMORY;
6062 /* get the current group information */
6064 become_root();
6065 status = pdb_get_aliasinfo(&ainfo->sid, info);
6066 unbecome_root();
6068 if ( !NT_STATUS_IS_OK(status))
6069 return status;
6071 switch (r->in.level) {
6072 case ALIASINFONAME:
6074 char *group_name;
6076 /* We currently do not support renaming groups in the
6077 the BUILTIN domain. Refer to util_builtin.c to understand
6078 why. The eventually needs to be fixed to be like Windows
6079 where you can rename builtin groups, just not delete them */
6081 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6082 return NT_STATUS_SPECIAL_ACCOUNT;
6085 /* There has to be a valid name (and it has to be different) */
6087 if ( !r->in.info->name.string )
6088 return NT_STATUS_INVALID_PARAMETER;
6090 /* If the name is the same just reply "ok". Yes this
6091 doesn't allow you to change the case of a group name. */
6093 if (strequal(r->in.info->name.string, info->acct_name)) {
6094 return NT_STATUS_OK;
6097 talloc_free(info->acct_name);
6098 info->acct_name = talloc_strdup(info, r->in.info->name.string);
6099 if (!info->acct_name) {
6100 return NT_STATUS_NO_MEMORY;
6103 /* make sure the name doesn't already exist as a user
6104 or local group */
6106 group_name = talloc_asprintf(p->mem_ctx,
6107 "%s\\%s",
6108 lp_netbios_name(),
6109 info->acct_name);
6110 if (group_name == NULL) {
6111 return NT_STATUS_NO_MEMORY;
6114 status = can_create( p->mem_ctx, group_name );
6115 talloc_free(group_name);
6116 if ( !NT_STATUS_IS_OK( status ) )
6117 return status;
6118 break;
6120 case ALIASINFODESCRIPTION:
6121 TALLOC_FREE(info->acct_desc);
6122 if (r->in.info->description.string) {
6123 info->acct_desc = talloc_strdup(info,
6124 r->in.info->description.string);
6125 } else {
6126 info->acct_desc = talloc_strdup(info, "");
6128 if (!info->acct_desc) {
6129 return NT_STATUS_NO_MEMORY;
6131 break;
6132 default:
6133 return NT_STATUS_INVALID_INFO_CLASS;
6136 /******** BEGIN SeAddUsers BLOCK *********/
6138 become_root();
6139 status = pdb_set_aliasinfo(&ainfo->sid, info);
6140 unbecome_root();
6142 /******** End SeAddUsers BLOCK *********/
6144 if (NT_STATUS_IS_OK(status))
6145 force_flush_samr_cache(&ainfo->sid);
6147 return status;
6150 /****************************************************************
6151 _samr_GetDomPwInfo
6152 ****************************************************************/
6154 NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
6155 struct samr_GetDomPwInfo *r)
6157 uint32_t min_password_length = 0;
6158 uint32_t password_properties = 0;
6160 /* Perform access check. Since this rpc does not require a
6161 policy handle it will not be caught by the access checks on
6162 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6164 if (!pipe_access_check(p)) {
6165 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6166 return NT_STATUS_ACCESS_DENIED;
6169 become_root();
6170 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6171 &min_password_length);
6172 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6173 &password_properties);
6174 unbecome_root();
6176 if (lp_check_password_script(talloc_tos()) && *lp_check_password_script(talloc_tos())) {
6177 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6180 r->out.info->min_password_length = min_password_length;
6181 r->out.info->password_properties = password_properties;
6183 return NT_STATUS_OK;
6186 /*********************************************************************
6187 _samr_OpenGroup
6188 *********************************************************************/
6190 NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
6191 struct samr_OpenGroup *r)
6194 struct dom_sid info_sid;
6195 GROUP_MAP *map;
6196 struct samr_domain_info *dinfo;
6197 struct samr_group_info *ginfo;
6198 struct security_descriptor *psd = NULL;
6199 uint32 acc_granted;
6200 uint32 des_access = r->in.access_mask;
6201 size_t sd_size;
6202 NTSTATUS status;
6203 bool ret;
6205 dinfo = policy_handle_find(p, r->in.domain_handle,
6206 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6207 struct samr_domain_info, &status);
6208 if (!NT_STATUS_IS_OK(status)) {
6209 return status;
6212 /*check if access can be granted as requested by client. */
6213 map_max_allowed_access(p->session_info->security_token,
6214 p->session_info->unix_token,
6215 &des_access);
6217 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6218 se_map_generic(&des_access,&grp_generic_mapping);
6220 status = access_check_object(psd, p->session_info->security_token,
6221 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6222 des_access, &acc_granted, "_samr_OpenGroup");
6224 if ( !NT_STATUS_IS_OK(status) )
6225 return status;
6227 /* this should not be hard-coded like this */
6229 if (!sid_check_is_our_sam(&dinfo->sid)) {
6230 return NT_STATUS_ACCESS_DENIED;
6233 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6235 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6236 sid_string_dbg(&info_sid)));
6238 map = talloc_zero(p->mem_ctx, GROUP_MAP);
6239 if (!map) {
6240 return NT_STATUS_NO_MEMORY;
6243 /* check if that group really exists */
6244 become_root();
6245 ret = get_domain_group_from_sid(info_sid, map);
6246 unbecome_root();
6247 if (!ret)
6248 return NT_STATUS_NO_SUCH_GROUP;
6250 TALLOC_FREE(map);
6252 ginfo = policy_handle_create(p, r->out.group_handle,
6253 acc_granted,
6254 struct samr_group_info, &status);
6255 if (!NT_STATUS_IS_OK(status)) {
6256 return status;
6258 ginfo->sid = info_sid;
6260 return NT_STATUS_OK;
6263 /*********************************************************************
6264 _samr_RemoveMemberFromForeignDomain
6265 *********************************************************************/
6267 NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
6268 struct samr_RemoveMemberFromForeignDomain *r)
6270 struct samr_domain_info *dinfo;
6271 NTSTATUS result;
6273 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6274 sid_string_dbg(r->in.sid)));
6276 /* Find the policy handle. Open a policy on it. */
6278 dinfo = policy_handle_find(p, r->in.domain_handle,
6279 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6280 struct samr_domain_info, &result);
6281 if (!NT_STATUS_IS_OK(result)) {
6282 return result;
6285 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6286 sid_string_dbg(&dinfo->sid)));
6288 /* we can only delete a user from a group since we don't have
6289 nested groups anyways. So in the latter case, just say OK */
6291 /* TODO: The above comment nowadays is bogus. Since we have nested
6292 * groups now, and aliases members are never reported out of the unix
6293 * group membership, the "just say OK" makes this call a no-op. For
6294 * us. This needs fixing however. */
6296 /* I've only ever seen this in the wild when deleting a user from
6297 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6298 * is the user about to be deleted. I very much suspect this is the
6299 * only application of this call. To verify this, let people report
6300 * other cases. */
6302 if (!sid_check_is_builtin(&dinfo->sid)) {
6303 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6304 "global_sam_sid() = %s\n",
6305 sid_string_dbg(&dinfo->sid),
6306 sid_string_dbg(get_global_sam_sid())));
6307 DEBUGADD(1,("please report to samba-technical@lists.samba.org!\n"));
6308 return NT_STATUS_OK;
6311 force_flush_samr_cache(&dinfo->sid);
6313 result = NT_STATUS_OK;
6315 return result;
6318 /*******************************************************************
6319 _samr_QueryDomainInfo2
6320 ********************************************************************/
6322 NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
6323 struct samr_QueryDomainInfo2 *r)
6325 struct samr_QueryDomainInfo q;
6327 q.in.domain_handle = r->in.domain_handle;
6328 q.in.level = r->in.level;
6330 q.out.info = r->out.info;
6332 return _samr_QueryDomainInfo(p, &q);
6335 /*******************************************************************
6336 ********************************************************************/
6338 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6339 struct samr_DomInfo1 *r)
6341 time_t u_expire, u_min_age;
6343 u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6344 u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6346 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6347 (uint32_t)r->min_password_length);
6348 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6349 (uint32_t)r->password_history_length);
6350 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6351 (uint32_t)r->password_properties);
6352 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6353 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6355 return NT_STATUS_OK;
6358 /*******************************************************************
6359 ********************************************************************/
6361 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6362 struct samr_DomInfo3 *r)
6364 time_t u_logout;
6366 u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6368 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6370 return NT_STATUS_OK;
6373 /*******************************************************************
6374 ********************************************************************/
6376 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6377 struct samr_DomInfo12 *r)
6379 time_t u_lock_duration, u_reset_time;
6382 * It is not possible to set lockout_duration < lockout_window.
6383 * (The test is the other way around since the negative numbers
6384 * are stored...)
6386 * This constraint is documented here for the samr rpc service:
6387 * MS-SAMR 3.1.1.6 Attribute Constraints for Originating Updates
6388 * http://msdn.microsoft.com/en-us/library/cc245667%28PROT.10%29.aspx
6390 * And here for the ldap backend:
6391 * MS-ADTS 3.1.1.5.3.2 Constraints
6392 * http://msdn.microsoft.com/en-us/library/cc223462(PROT.10).aspx
6394 if (r->lockout_duration > r->lockout_window) {
6395 return NT_STATUS_INVALID_PARAMETER;
6398 u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6399 if (u_lock_duration != -1) {
6400 u_lock_duration /= 60;
6403 u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6405 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6406 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6407 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6408 (uint32_t)r->lockout_threshold);
6410 return NT_STATUS_OK;
6413 /*******************************************************************
6414 _samr_SetDomainInfo
6415 ********************************************************************/
6417 NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
6418 struct samr_SetDomainInfo *r)
6420 NTSTATUS status;
6421 uint32_t acc_required = 0;
6423 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6425 switch (r->in.level) {
6426 case 1: /* DomainPasswordInformation */
6427 case 12: /* DomainLockoutInformation */
6428 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6429 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6430 break;
6431 case 3: /* DomainLogoffInformation */
6432 case 4: /* DomainOemInformation */
6433 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6434 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6435 break;
6436 case 6: /* DomainReplicationInformation */
6437 case 9: /* DomainStateInformation */
6438 case 7: /* DomainServerRoleInformation */
6439 /* DOMAIN_ADMINISTER_SERVER */
6440 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6441 break;
6442 default:
6443 return NT_STATUS_INVALID_INFO_CLASS;
6446 (void)policy_handle_find(p, r->in.domain_handle,
6447 acc_required, NULL,
6448 struct samr_domain_info, &status);
6449 if (!NT_STATUS_IS_OK(status)) {
6450 return status;
6453 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6455 switch (r->in.level) {
6456 case 1:
6457 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6458 break;
6459 case 3:
6460 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6461 break;
6462 case 4:
6463 break;
6464 case 6:
6465 break;
6466 case 7:
6467 break;
6468 case 9:
6469 break;
6470 case 12:
6471 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6472 break;
6473 default:
6474 return NT_STATUS_INVALID_INFO_CLASS;
6477 if (!NT_STATUS_IS_OK(status)) {
6478 return status;
6481 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6483 return NT_STATUS_OK;
6486 /****************************************************************
6487 _samr_GetDisplayEnumerationIndex
6488 ****************************************************************/
6490 NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
6491 struct samr_GetDisplayEnumerationIndex *r)
6493 struct samr_domain_info *dinfo;
6494 uint32_t max_entries = (uint32_t) -1;
6495 uint32_t enum_context = 0;
6496 int i;
6497 uint32_t num_account = 0;
6498 struct samr_displayentry *entries = NULL;
6499 NTSTATUS status;
6501 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6503 dinfo = policy_handle_find(p, r->in.domain_handle,
6504 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6505 struct samr_domain_info, &status);
6506 if (!NT_STATUS_IS_OK(status)) {
6507 return status;
6510 if ((r->in.level < 1) || (r->in.level > 3)) {
6511 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6512 "Unknown info level (%u)\n",
6513 r->in.level));
6514 return NT_STATUS_INVALID_INFO_CLASS;
6517 become_root();
6519 /* The following done as ROOT. Don't return without unbecome_root(). */
6521 switch (r->in.level) {
6522 case 1:
6523 if (dinfo->disp_info->users == NULL) {
6524 dinfo->disp_info->users = pdb_search_users(
6525 dinfo->disp_info, ACB_NORMAL);
6526 if (dinfo->disp_info->users == NULL) {
6527 unbecome_root();
6528 return NT_STATUS_ACCESS_DENIED;
6530 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6531 "starting user enumeration at index %u\n",
6532 (unsigned int)enum_context));
6533 } else {
6534 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6535 "using cached user enumeration at index %u\n",
6536 (unsigned int)enum_context));
6538 num_account = pdb_search_entries(dinfo->disp_info->users,
6539 enum_context, max_entries,
6540 &entries);
6541 break;
6542 case 2:
6543 if (dinfo->disp_info->machines == NULL) {
6544 dinfo->disp_info->machines = pdb_search_users(
6545 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6546 if (dinfo->disp_info->machines == NULL) {
6547 unbecome_root();
6548 return NT_STATUS_ACCESS_DENIED;
6550 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6551 "starting machine enumeration at index %u\n",
6552 (unsigned int)enum_context));
6553 } else {
6554 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6555 "using cached machine enumeration at index %u\n",
6556 (unsigned int)enum_context));
6558 num_account = pdb_search_entries(dinfo->disp_info->machines,
6559 enum_context, max_entries,
6560 &entries);
6561 break;
6562 case 3:
6563 if (dinfo->disp_info->groups == NULL) {
6564 dinfo->disp_info->groups = pdb_search_groups(
6565 dinfo->disp_info);
6566 if (dinfo->disp_info->groups == NULL) {
6567 unbecome_root();
6568 return NT_STATUS_ACCESS_DENIED;
6570 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6571 "starting group enumeration at index %u\n",
6572 (unsigned int)enum_context));
6573 } else {
6574 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6575 "using cached group enumeration at index %u\n",
6576 (unsigned int)enum_context));
6578 num_account = pdb_search_entries(dinfo->disp_info->groups,
6579 enum_context, max_entries,
6580 &entries);
6581 break;
6582 default:
6583 unbecome_root();
6584 smb_panic("info class changed");
6585 break;
6588 unbecome_root();
6590 /* Ensure we cache this enumeration. */
6591 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6593 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6594 r->in.name->string));
6596 for (i=0; i<num_account; i++) {
6597 if (strequal(entries[i].account_name, r->in.name->string)) {
6598 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6599 "found %s at idx %d\n",
6600 r->in.name->string, i));
6601 *r->out.idx = i;
6602 return NT_STATUS_OK;
6606 /* assuming account_name lives at the very end */
6607 *r->out.idx = num_account;
6609 return NT_STATUS_NO_MORE_ENTRIES;
6612 /****************************************************************
6613 _samr_GetDisplayEnumerationIndex2
6614 ****************************************************************/
6616 NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
6617 struct samr_GetDisplayEnumerationIndex2 *r)
6619 struct samr_GetDisplayEnumerationIndex q;
6621 q.in.domain_handle = r->in.domain_handle;
6622 q.in.level = r->in.level;
6623 q.in.name = r->in.name;
6625 q.out.idx = r->out.idx;
6627 return _samr_GetDisplayEnumerationIndex(p, &q);
6630 /****************************************************************
6631 _samr_RidToSid
6632 ****************************************************************/
6634 NTSTATUS _samr_RidToSid(struct pipes_struct *p,
6635 struct samr_RidToSid *r)
6637 struct samr_domain_info *dinfo;
6638 NTSTATUS status;
6639 struct dom_sid sid;
6641 dinfo = policy_handle_find(p, r->in.domain_handle,
6642 0, NULL,
6643 struct samr_domain_info, &status);
6644 if (!NT_STATUS_IS_OK(status)) {
6645 return status;
6648 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6649 return NT_STATUS_NO_MEMORY;
6652 *r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
6653 if (!*r->out.sid) {
6654 return NT_STATUS_NO_MEMORY;
6657 return NT_STATUS_OK;
6660 /****************************************************************
6661 ****************************************************************/
6663 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
6664 const struct samr_PwInfo *dom_pw_info,
6665 const struct samr_ValidatePasswordReq2 *req,
6666 struct samr_ValidatePasswordRepCtr *rep)
6668 NTSTATUS status;
6670 if (req->password.string == NULL) {
6671 return SAMR_VALIDATION_STATUS_SUCCESS;
6673 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6674 ZERO_STRUCT(rep->info);
6675 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6677 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6678 status = check_password_complexity(req->account.string,
6679 req->password.string,
6680 NULL);
6681 if (!NT_STATUS_IS_OK(status)) {
6682 ZERO_STRUCT(rep->info);
6683 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6687 return SAMR_VALIDATION_STATUS_SUCCESS;
6690 /****************************************************************
6691 ****************************************************************/
6693 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
6694 const struct samr_PwInfo *dom_pw_info,
6695 const struct samr_ValidatePasswordReq3 *req,
6696 struct samr_ValidatePasswordRepCtr *rep)
6698 NTSTATUS status;
6700 if (req->password.string == NULL) {
6701 return SAMR_VALIDATION_STATUS_SUCCESS;
6703 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6704 ZERO_STRUCT(rep->info);
6705 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6707 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6708 status = check_password_complexity(req->account.string,
6709 req->password.string,
6710 NULL);
6711 if (!NT_STATUS_IS_OK(status)) {
6712 ZERO_STRUCT(rep->info);
6713 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6717 return SAMR_VALIDATION_STATUS_SUCCESS;
6720 /****************************************************************
6721 _samr_ValidatePassword
6722 ****************************************************************/
6724 NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
6725 struct samr_ValidatePassword *r)
6727 union samr_ValidatePasswordRep *rep;
6728 NTSTATUS status;
6729 struct samr_GetDomPwInfo pw;
6730 struct samr_PwInfo dom_pw_info;
6732 if (p->transport != NCACN_IP_TCP && p->transport != NCALRPC) {
6733 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
6734 return NT_STATUS_ACCESS_DENIED;
6737 if (r->in.level < 1 || r->in.level > 3) {
6738 return NT_STATUS_INVALID_INFO_CLASS;
6741 pw.in.domain_name = NULL;
6742 pw.out.info = &dom_pw_info;
6744 status = _samr_GetDomPwInfo(p, &pw);
6745 if (!NT_STATUS_IS_OK(status)) {
6746 return status;
6749 rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
6750 if (!rep) {
6751 return NT_STATUS_NO_MEMORY;
6754 switch (r->in.level) {
6755 case 1:
6756 status = NT_STATUS_NOT_SUPPORTED;
6757 break;
6758 case 2:
6759 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
6760 &dom_pw_info,
6761 &r->in.req->req2,
6762 &rep->ctr2);
6763 break;
6764 case 3:
6765 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
6766 &dom_pw_info,
6767 &r->in.req->req3,
6768 &rep->ctr3);
6769 break;
6770 default:
6771 status = NT_STATUS_INVALID_INFO_CLASS;
6772 break;
6775 if (!NT_STATUS_IS_OK(status)) {
6776 talloc_free(rep);
6777 return status;
6780 *r->out.rep = rep;
6782 return NT_STATUS_OK;
6785 /****************************************************************
6786 ****************************************************************/
6788 NTSTATUS _samr_Shutdown(struct pipes_struct *p,
6789 struct samr_Shutdown *r)
6791 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6792 return NT_STATUS_NOT_IMPLEMENTED;
6795 /****************************************************************
6796 ****************************************************************/
6798 NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
6799 struct samr_SetMemberAttributesOfGroup *r)
6801 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6802 return NT_STATUS_NOT_IMPLEMENTED;
6805 /****************************************************************
6806 ****************************************************************/
6808 NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
6809 struct samr_TestPrivateFunctionsDomain *r)
6811 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6812 return NT_STATUS_NOT_IMPLEMENTED;
6815 /****************************************************************
6816 ****************************************************************/
6818 NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
6819 struct samr_TestPrivateFunctionsUser *r)
6821 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6822 return NT_STATUS_NOT_IMPLEMENTED;
6825 /****************************************************************
6826 ****************************************************************/
6828 NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
6829 struct samr_AddMultipleMembersToAlias *r)
6831 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6832 return NT_STATUS_NOT_IMPLEMENTED;
6835 /****************************************************************
6836 ****************************************************************/
6838 NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
6839 struct samr_RemoveMultipleMembersFromAlias *r)
6841 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6842 return NT_STATUS_NOT_IMPLEMENTED;
6845 /****************************************************************
6846 ****************************************************************/
6848 NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
6849 struct samr_SetBootKeyInformation *r)
6851 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6852 return NT_STATUS_NOT_IMPLEMENTED;
6855 /****************************************************************
6856 ****************************************************************/
6858 NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
6859 struct samr_GetBootKeyInformation *r)
6861 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6862 return NT_STATUS_NOT_IMPLEMENTED;
6865 /****************************************************************
6866 ****************************************************************/
6868 NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
6869 struct samr_SetDsrmPassword *r)
6871 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
6872 return NT_STATUS_NOT_IMPLEMENTED;