s3-talloc Change TALLOC_ZERO_P() to talloc_zero()
[Samba.git] / source3 / rpc_server / samr / srv_samr_nt.c
blob9f96127c0f37d45830b321956c2be0e4e8390b9c
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"
48 #undef DBGC_CLASS
49 #define DBGC_CLASS DBGC_RPC_SRV
51 #define SAMR_USR_RIGHTS_WRITE_PW \
52 ( READ_CONTROL_ACCESS | \
53 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
54 SAMR_USER_ACCESS_SET_LOC_COM)
55 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
56 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
58 #define DISP_INFO_CACHE_TIMEOUT 10
60 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
61 #define MAX_SAM_ENTRIES_W95 50
63 struct samr_connect_info {
64 uint8_t dummy;
67 struct samr_domain_info {
68 struct dom_sid sid;
69 struct disp_info *disp_info;
72 struct samr_user_info {
73 struct dom_sid sid;
76 struct samr_group_info {
77 struct dom_sid sid;
80 struct samr_alias_info {
81 struct dom_sid sid;
84 typedef struct disp_info {
85 struct dom_sid sid; /* identify which domain this is. */
86 struct pdb_search *users; /* querydispinfo 1 and 4 */
87 struct pdb_search *machines; /* querydispinfo 2 */
88 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
89 struct pdb_search *aliases; /* enumaliases */
91 uint32_t enum_acb_mask;
92 struct pdb_search *enum_users; /* enumusers with a mask */
94 struct timed_event *cache_timeout_event; /* cache idle timeout
95 * handler. */
96 } DISP_INFO;
98 static const struct generic_mapping sam_generic_mapping = {
99 GENERIC_RIGHTS_SAM_READ,
100 GENERIC_RIGHTS_SAM_WRITE,
101 GENERIC_RIGHTS_SAM_EXECUTE,
102 GENERIC_RIGHTS_SAM_ALL_ACCESS};
103 static const struct generic_mapping dom_generic_mapping = {
104 GENERIC_RIGHTS_DOMAIN_READ,
105 GENERIC_RIGHTS_DOMAIN_WRITE,
106 GENERIC_RIGHTS_DOMAIN_EXECUTE,
107 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
108 static const struct generic_mapping usr_generic_mapping = {
109 GENERIC_RIGHTS_USER_READ,
110 GENERIC_RIGHTS_USER_WRITE,
111 GENERIC_RIGHTS_USER_EXECUTE,
112 GENERIC_RIGHTS_USER_ALL_ACCESS};
113 static const struct generic_mapping usr_nopwchange_generic_mapping = {
114 GENERIC_RIGHTS_USER_READ,
115 GENERIC_RIGHTS_USER_WRITE,
116 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
117 GENERIC_RIGHTS_USER_ALL_ACCESS};
118 static const struct generic_mapping grp_generic_mapping = {
119 GENERIC_RIGHTS_GROUP_READ,
120 GENERIC_RIGHTS_GROUP_WRITE,
121 GENERIC_RIGHTS_GROUP_EXECUTE,
122 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
123 static const struct generic_mapping ali_generic_mapping = {
124 GENERIC_RIGHTS_ALIAS_READ,
125 GENERIC_RIGHTS_ALIAS_WRITE,
126 GENERIC_RIGHTS_ALIAS_EXECUTE,
127 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
129 /*******************************************************************
130 *******************************************************************/
132 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
133 const struct generic_mapping *map,
134 struct dom_sid *sid, uint32 sid_access )
136 struct dom_sid domadmin_sid;
137 struct security_ace ace[5]; /* at most 5 entries */
138 size_t i = 0;
140 struct security_acl *psa = NULL;
142 /* basic access for Everyone */
144 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
145 map->generic_execute | map->generic_read, 0);
147 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
149 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
150 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
151 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
152 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
154 /* Add Full Access for Domain Admins if we are a DC */
156 if ( IS_DC ) {
157 sid_compose(&domadmin_sid, get_global_sam_sid(),
158 DOMAIN_RID_ADMINS);
159 init_sec_ace(&ace[i++], &domadmin_sid,
160 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
163 /* if we have a sid, give it some special access */
165 if ( sid ) {
166 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
169 /* create the security descriptor */
171 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
172 return NT_STATUS_NO_MEMORY;
174 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
175 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
176 psa, sd_size)) == NULL)
177 return NT_STATUS_NO_MEMORY;
179 return NT_STATUS_OK;
182 /*******************************************************************
183 Fetch or create a dispinfo struct.
184 ********************************************************************/
186 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
189 * We do a static cache for DISP_INFO's here. Explanation can be found
190 * in Jeremy's checkin message to r11793:
192 * Fix the SAMR cache so it works across completely insane
193 * client behaviour (ie.:
194 * open pipe/open SAMR handle/enumerate 0 - 1024
195 * close SAMR handle, close pipe.
196 * open pipe/open SAMR handle/enumerate 1024 - 2048...
197 * close SAMR handle, close pipe.
198 * And on ad-nausium. Amazing.... probably object-oriented
199 * client side programming in action yet again.
200 * This change should *massively* improve performance when
201 * enumerating users from an LDAP database.
202 * Jeremy.
204 * "Our" and the builtin domain are the only ones where we ever
205 * enumerate stuff, so just cache 2 entries.
208 static struct disp_info *builtin_dispinfo;
209 static struct disp_info *domain_dispinfo;
211 /* There are two cases to consider here:
212 1) The SID is a domain SID and we look for an equality match, or
213 2) This is an account SID and so we return the DISP_INFO* for our
214 domain */
216 if (psid == NULL) {
217 return NULL;
220 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
222 * Necessary only once, but it does not really hurt.
224 if (builtin_dispinfo == NULL) {
225 builtin_dispinfo = talloc_zero(NULL, struct disp_info);
226 if (builtin_dispinfo == NULL) {
227 return NULL;
230 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
232 return builtin_dispinfo;
235 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
237 * Necessary only once, but it does not really hurt.
239 if (domain_dispinfo == NULL) {
240 domain_dispinfo = talloc_zero(NULL, struct disp_info);
241 if (domain_dispinfo == NULL) {
242 return NULL;
245 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
247 return domain_dispinfo;
250 return NULL;
253 /*******************************************************************
254 Function to free the per SID data.
255 ********************************************************************/
257 static void free_samr_cache(DISP_INFO *disp_info)
259 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
260 sid_string_dbg(&disp_info->sid)));
262 /* We need to become root here because the paged search might have to
263 * tell the LDAP server we're not interested in the rest anymore. */
265 become_root();
267 TALLOC_FREE(disp_info->users);
268 TALLOC_FREE(disp_info->machines);
269 TALLOC_FREE(disp_info->groups);
270 TALLOC_FREE(disp_info->aliases);
271 TALLOC_FREE(disp_info->enum_users);
273 unbecome_root();
276 /*******************************************************************
277 Idle event handler. Throw away the disp info cache.
278 ********************************************************************/
280 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
281 struct timed_event *te,
282 struct timeval now,
283 void *private_data)
285 DISP_INFO *disp_info = (DISP_INFO *)private_data;
287 TALLOC_FREE(disp_info->cache_timeout_event);
289 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
290 "out\n"));
291 free_samr_cache(disp_info);
294 /*******************************************************************
295 Setup cache removal idle event handler.
296 ********************************************************************/
298 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
300 /* Remove any pending timeout and update. */
302 TALLOC_FREE(disp_info->cache_timeout_event);
304 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
305 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
306 (unsigned int)secs_fromnow ));
308 disp_info->cache_timeout_event = event_add_timed(
309 server_event_context(), NULL,
310 timeval_current_ofs(secs_fromnow, 0),
311 disp_info_cache_idle_timeout_handler, (void *)disp_info);
314 /*******************************************************************
315 Force flush any cache. We do this on any samr_set_xxx call.
316 We must also remove the timeout handler.
317 ********************************************************************/
319 static void force_flush_samr_cache(const struct dom_sid *sid)
321 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
323 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
324 return;
327 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
328 TALLOC_FREE(disp_info->cache_timeout_event);
329 free_samr_cache(disp_info);
332 /*******************************************************************
333 Ensure password info is never given out. Paranioa... JRA.
334 ********************************************************************/
336 static void samr_clear_sam_passwd(struct samu *sam_pass)
339 if (!sam_pass)
340 return;
342 /* These now zero out the old password */
344 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
345 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
348 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
350 struct samr_displayentry *entry;
352 if (sid_check_is_builtin(&info->sid)) {
353 /* No users in builtin. */
354 return 0;
357 if (info->users == NULL) {
358 info->users = pdb_search_users(info, acct_flags);
359 if (info->users == NULL) {
360 return 0;
363 /* Fetch the last possible entry, thus trigger an enumeration */
364 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
366 /* Ensure we cache this enumeration. */
367 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
369 return info->users->num_entries;
372 static uint32 count_sam_groups(struct disp_info *info)
374 struct samr_displayentry *entry;
376 if (sid_check_is_builtin(&info->sid)) {
377 /* No groups in builtin. */
378 return 0;
381 if (info->groups == NULL) {
382 info->groups = pdb_search_groups(info);
383 if (info->groups == NULL) {
384 return 0;
387 /* Fetch the last possible entry, thus trigger an enumeration */
388 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
390 /* Ensure we cache this enumeration. */
391 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
393 return info->groups->num_entries;
396 static uint32 count_sam_aliases(struct disp_info *info)
398 struct samr_displayentry *entry;
400 if (info->aliases == NULL) {
401 info->aliases = pdb_search_aliases(info, &info->sid);
402 if (info->aliases == NULL) {
403 return 0;
406 /* Fetch the last possible entry, thus trigger an enumeration */
407 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
409 /* Ensure we cache this enumeration. */
410 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
412 return info->aliases->num_entries;
415 /*******************************************************************
416 _samr_Close
417 ********************************************************************/
419 NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
421 if (!close_policy_hnd(p, r->in.handle)) {
422 return NT_STATUS_INVALID_HANDLE;
425 ZERO_STRUCTP(r->out.handle);
427 return NT_STATUS_OK;
430 /*******************************************************************
431 _samr_OpenDomain
432 ********************************************************************/
434 NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
435 struct samr_OpenDomain *r)
437 struct samr_connect_info *cinfo;
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 cinfo = 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->utok,
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_domain(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_domain(&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() && *lp_check_password_script()) {
549 password_properties |= DOMAIN_PASSWORD_COMPLEX;
552 break;
553 default:
554 break;
557 r->out.info->min_password_length = min_password_length;
558 r->out.info->password_properties = password_properties;
560 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
562 return NT_STATUS_OK;
565 /*******************************************************************
566 _samr_SetSecurity
567 ********************************************************************/
569 NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
570 struct samr_SetSecurity *r)
572 struct samr_user_info *uinfo;
573 uint32 i;
574 struct security_acl *dacl;
575 bool ret;
576 struct samu *sampass=NULL;
577 NTSTATUS status;
579 uinfo = policy_handle_find(p, r->in.handle,
580 SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
581 struct samr_user_info, &status);
582 if (!NT_STATUS_IS_OK(status)) {
583 return status;
586 if (!(sampass = samu_new( p->mem_ctx))) {
587 DEBUG(0,("No memory!\n"));
588 return NT_STATUS_NO_MEMORY;
591 /* get the user record */
592 become_root();
593 ret = pdb_getsampwsid(sampass, &uinfo->sid);
594 unbecome_root();
596 if (!ret) {
597 DEBUG(4, ("User %s not found\n",
598 sid_string_dbg(&uinfo->sid)));
599 TALLOC_FREE(sampass);
600 return NT_STATUS_INVALID_HANDLE;
603 dacl = r->in.sdbuf->sd->dacl;
604 for (i=0; i < dacl->num_aces; i++) {
605 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
606 ret = pdb_set_pass_can_change(sampass,
607 (dacl->aces[i].access_mask &
608 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
609 True: False);
610 break;
614 if (!ret) {
615 TALLOC_FREE(sampass);
616 return NT_STATUS_ACCESS_DENIED;
619 become_root();
620 status = pdb_update_sam_account(sampass);
621 unbecome_root();
623 TALLOC_FREE(sampass);
625 return status;
628 /*******************************************************************
629 build correct perms based on policies and password times for _samr_query_sec_obj
630 *******************************************************************/
631 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
633 struct samu *sampass=NULL;
634 bool ret;
636 if ( !(sampass = samu_new( mem_ctx )) ) {
637 DEBUG(0,("No memory!\n"));
638 return False;
641 become_root();
642 ret = pdb_getsampwsid(sampass, user_sid);
643 unbecome_root();
645 if (ret == False) {
646 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
647 TALLOC_FREE(sampass);
648 return False;
651 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
653 if (pdb_get_pass_can_change(sampass)) {
654 TALLOC_FREE(sampass);
655 return True;
657 TALLOC_FREE(sampass);
658 return False;
662 /*******************************************************************
663 _samr_QuerySecurity
664 ********************************************************************/
666 NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
667 struct samr_QuerySecurity *r)
669 struct samr_connect_info *cinfo;
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 cinfo = 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 become_root();
1587 status = pdb_get_aliasinfo(&ainfo->sid, &info);
1588 unbecome_root();
1590 if ( !NT_STATUS_IS_OK(status))
1591 return status;
1593 /* FIXME: info contains fstrings */
1594 alias_name = talloc_strdup(r, info.acct_name);
1595 alias_description = talloc_strdup(r, info.acct_desc);
1597 switch (r->in.level) {
1598 case ALIASINFOALL:
1599 alias_info->all.name.string = alias_name;
1600 alias_info->all.num_members = 1; /* ??? */
1601 alias_info->all.description.string = alias_description;
1602 break;
1603 case ALIASINFONAME:
1604 alias_info->name.string = alias_name;
1605 break;
1606 case ALIASINFODESCRIPTION:
1607 alias_info->description.string = alias_description;
1608 break;
1609 default:
1610 return NT_STATUS_INVALID_INFO_CLASS;
1613 *r->out.info = alias_info;
1615 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1617 return NT_STATUS_OK;
1620 /*******************************************************************
1621 _samr_LookupNames
1622 ********************************************************************/
1624 NTSTATUS _samr_LookupNames(struct pipes_struct *p,
1625 struct samr_LookupNames *r)
1627 struct samr_domain_info *dinfo;
1628 NTSTATUS status;
1629 uint32 *rid;
1630 enum lsa_SidType *type;
1631 int i;
1632 int num_rids = r->in.num_names;
1633 struct samr_Ids rids, types;
1634 uint32_t num_mapped = 0;
1636 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1638 dinfo = policy_handle_find(p, r->in.domain_handle,
1639 0 /* Don't know the acc_bits yet */, NULL,
1640 struct samr_domain_info, &status);
1641 if (!NT_STATUS_IS_OK(status)) {
1642 return status;
1645 if (num_rids > MAX_SAM_ENTRIES) {
1646 num_rids = MAX_SAM_ENTRIES;
1647 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1650 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1651 NT_STATUS_HAVE_NO_MEMORY(rid);
1653 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1654 NT_STATUS_HAVE_NO_MEMORY(type);
1656 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1657 sid_string_dbg(&dinfo->sid)));
1659 for (i = 0; i < num_rids; i++) {
1661 status = NT_STATUS_NONE_MAPPED;
1662 type[i] = SID_NAME_UNKNOWN;
1664 rid[i] = 0xffffffff;
1666 if (sid_check_is_builtin(&dinfo->sid)) {
1667 if (lookup_builtin_name(r->in.names[i].string,
1668 &rid[i]))
1670 type[i] = SID_NAME_ALIAS;
1672 } else {
1673 lookup_global_sam_name(r->in.names[i].string, 0,
1674 &rid[i], &type[i]);
1677 if (type[i] != SID_NAME_UNKNOWN) {
1678 num_mapped++;
1682 if (num_mapped == num_rids) {
1683 status = NT_STATUS_OK;
1684 } else if (num_mapped == 0) {
1685 status = NT_STATUS_NONE_MAPPED;
1686 } else {
1687 status = STATUS_SOME_UNMAPPED;
1690 rids.count = num_rids;
1691 rids.ids = rid;
1693 types.count = num_rids;
1694 types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
1695 NT_STATUS_HAVE_NO_MEMORY(type);
1696 for (i = 0; i < num_rids; i++) {
1697 types.ids[i] = (type[i] & 0xffffffff);
1700 *r->out.rids = rids;
1701 *r->out.types = types;
1703 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1705 return status;
1708 /****************************************************************
1709 _samr_ChangePasswordUser
1710 ****************************************************************/
1712 NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
1713 struct samr_ChangePasswordUser *r)
1715 NTSTATUS status;
1716 bool ret = false;
1717 struct samr_user_info *uinfo;
1718 struct samu *pwd;
1719 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1720 struct samr_Password lm_pwd, nt_pwd;
1722 uinfo = policy_handle_find(p, r->in.user_handle,
1723 SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1724 struct samr_user_info, &status);
1725 if (!NT_STATUS_IS_OK(status)) {
1726 return status;
1729 DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1730 sid_string_dbg(&uinfo->sid)));
1732 if (!(pwd = samu_new(NULL))) {
1733 return NT_STATUS_NO_MEMORY;
1736 become_root();
1737 ret = pdb_getsampwsid(pwd, &uinfo->sid);
1738 unbecome_root();
1740 if (!ret) {
1741 TALLOC_FREE(pwd);
1742 return NT_STATUS_WRONG_PASSWORD;
1746 const uint8_t *lm_pass, *nt_pass;
1748 lm_pass = pdb_get_lanman_passwd(pwd);
1749 nt_pass = pdb_get_nt_passwd(pwd);
1751 if (!lm_pass || !nt_pass) {
1752 status = NT_STATUS_WRONG_PASSWORD;
1753 goto out;
1756 memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1757 memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1760 /* basic sanity checking on parameters. Do this before any database ops */
1761 if (!r->in.lm_present || !r->in.nt_present ||
1762 !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1763 !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1764 /* we should really handle a change with lm not
1765 present */
1766 status = NT_STATUS_INVALID_PARAMETER_MIX;
1767 goto out;
1770 /* decrypt and check the new lm hash */
1771 D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1772 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1773 if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1774 status = NT_STATUS_WRONG_PASSWORD;
1775 goto out;
1778 /* decrypt and check the new nt hash */
1779 D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1780 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1781 if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1782 status = NT_STATUS_WRONG_PASSWORD;
1783 goto out;
1786 /* The NT Cross is not required by Win2k3 R2, but if present
1787 check the nt cross hash */
1788 if (r->in.cross1_present && r->in.nt_cross) {
1789 D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1790 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1791 status = NT_STATUS_WRONG_PASSWORD;
1792 goto out;
1796 /* The LM Cross is not required by Win2k3 R2, but if present
1797 check the lm cross hash */
1798 if (r->in.cross2_present && r->in.lm_cross) {
1799 D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1800 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1801 status = NT_STATUS_WRONG_PASSWORD;
1802 goto out;
1806 if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1807 !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1808 status = NT_STATUS_ACCESS_DENIED;
1809 goto out;
1812 status = pdb_update_sam_account(pwd);
1813 out:
1814 TALLOC_FREE(pwd);
1816 return status;
1819 /*******************************************************************
1820 _samr_ChangePasswordUser2
1821 ********************************************************************/
1823 NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
1824 struct samr_ChangePasswordUser2 *r)
1826 NTSTATUS status;
1827 char *user_name = NULL;
1828 fstring wks;
1830 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1832 if (!r->in.account->string) {
1833 return NT_STATUS_INVALID_PARAMETER;
1835 fstrcpy(wks, r->in.server->string);
1837 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1840 * Pass the user through the NT -> unix user mapping
1841 * function.
1844 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1845 if (!user_name) {
1846 return NT_STATUS_NO_MEMORY;
1850 * UNIX username case mangling not required, pass_oem_change
1851 * is case insensitive.
1854 status = pass_oem_change(user_name,
1855 p->client_id->name,
1856 r->in.lm_password->data,
1857 r->in.lm_verifier->hash,
1858 r->in.nt_password->data,
1859 r->in.nt_verifier->hash,
1860 NULL);
1862 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1864 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1865 return NT_STATUS_WRONG_PASSWORD;
1868 return status;
1871 /****************************************************************
1872 _samr_OemChangePasswordUser2
1873 ****************************************************************/
1875 NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
1876 struct samr_OemChangePasswordUser2 *r)
1878 NTSTATUS status;
1879 char *user_name = NULL;
1880 const char *wks = NULL;
1882 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1884 if (!r->in.account->string) {
1885 return NT_STATUS_INVALID_PARAMETER;
1887 if (r->in.server && r->in.server->string) {
1888 wks = r->in.server->string;
1891 DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1894 * Pass the user through the NT -> unix user mapping
1895 * function.
1898 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1899 if (!user_name) {
1900 return NT_STATUS_NO_MEMORY;
1904 * UNIX username case mangling not required, pass_oem_change
1905 * is case insensitive.
1908 if (!r->in.hash || !r->in.password) {
1909 return NT_STATUS_INVALID_PARAMETER;
1912 status = pass_oem_change(user_name,
1913 p->client_id->name,
1914 r->in.password->data,
1915 r->in.hash->hash,
1918 NULL);
1920 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1921 return NT_STATUS_WRONG_PASSWORD;
1924 DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1926 return status;
1929 /*******************************************************************
1930 _samr_ChangePasswordUser3
1931 ********************************************************************/
1933 NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
1934 struct samr_ChangePasswordUser3 *r)
1936 NTSTATUS status;
1937 char *user_name = NULL;
1938 const char *wks = NULL;
1939 enum samPwdChangeReason reject_reason;
1940 struct samr_DomInfo1 *dominfo = NULL;
1941 struct userPwdChangeFailureInformation *reject = NULL;
1942 uint32_t tmp;
1944 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1946 if (!r->in.account->string) {
1947 return NT_STATUS_INVALID_PARAMETER;
1949 if (r->in.server && r->in.server->string) {
1950 wks = r->in.server->string;
1953 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1956 * Pass the user through the NT -> unix user mapping
1957 * function.
1960 (void)map_username(talloc_tos(), r->in.account->string, &user_name);
1961 if (!user_name) {
1962 return NT_STATUS_NO_MEMORY;
1966 * UNIX username case mangling not required, pass_oem_change
1967 * is case insensitive.
1970 status = pass_oem_change(user_name,
1971 p->client_id->name,
1972 r->in.lm_password->data,
1973 r->in.lm_verifier->hash,
1974 r->in.nt_password->data,
1975 r->in.nt_verifier->hash,
1976 &reject_reason);
1977 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1978 return NT_STATUS_WRONG_PASSWORD;
1981 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1982 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1984 time_t u_expire, u_min_age;
1985 uint32 account_policy_temp;
1987 dominfo = talloc_zero(p->mem_ctx, struct samr_DomInfo1);
1988 if (!dominfo) {
1989 return NT_STATUS_NO_MEMORY;
1992 reject = talloc_zero(p->mem_ctx,
1993 struct userPwdChangeFailureInformation);
1994 if (!reject) {
1995 return NT_STATUS_NO_MEMORY;
1998 become_root();
2000 /* AS ROOT !!! */
2002 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2003 dominfo->min_password_length = tmp;
2005 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2006 dominfo->password_history_length = tmp;
2008 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2009 &dominfo->password_properties);
2011 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2012 u_expire = account_policy_temp;
2014 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2015 u_min_age = account_policy_temp;
2017 /* !AS ROOT */
2019 unbecome_root();
2021 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2022 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2024 if (lp_check_password_script() && *lp_check_password_script()) {
2025 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2028 reject->extendedFailureReason = reject_reason;
2030 *r->out.dominfo = dominfo;
2031 *r->out.reject = reject;
2034 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2036 return status;
2039 /*******************************************************************
2040 makes a SAMR_R_LOOKUP_RIDS structure.
2041 ********************************************************************/
2043 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2044 const char **names,
2045 struct lsa_String **lsa_name_array_p)
2047 struct lsa_String *lsa_name_array = NULL;
2048 uint32_t i;
2050 *lsa_name_array_p = NULL;
2052 if (num_names != 0) {
2053 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2054 if (!lsa_name_array) {
2055 return false;
2059 for (i = 0; i < num_names; i++) {
2060 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2061 init_lsa_String(&lsa_name_array[i], names[i]);
2064 *lsa_name_array_p = lsa_name_array;
2066 return true;
2069 /*******************************************************************
2070 _samr_LookupRids
2071 ********************************************************************/
2073 NTSTATUS _samr_LookupRids(struct pipes_struct *p,
2074 struct samr_LookupRids *r)
2076 struct samr_domain_info *dinfo;
2077 NTSTATUS status;
2078 const char **names;
2079 enum lsa_SidType *attrs = NULL;
2080 uint32 *wire_attrs = NULL;
2081 int num_rids = (int)r->in.num_rids;
2082 int i;
2083 struct lsa_Strings names_array;
2084 struct samr_Ids types_array;
2085 struct lsa_String *lsa_names = NULL;
2087 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2089 dinfo = policy_handle_find(p, r->in.domain_handle,
2090 0 /* Don't know the acc_bits yet */, NULL,
2091 struct samr_domain_info, &status);
2092 if (!NT_STATUS_IS_OK(status)) {
2093 return status;
2096 if (num_rids > 1000) {
2097 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2098 "to samba4 idl this is not possible\n", num_rids));
2099 return NT_STATUS_UNSUCCESSFUL;
2102 if (num_rids) {
2103 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2104 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2105 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2107 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2108 return NT_STATUS_NO_MEMORY;
2109 } else {
2110 names = NULL;
2111 attrs = NULL;
2112 wire_attrs = NULL;
2115 become_root(); /* lookup_sid can require root privs */
2116 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2117 names, attrs);
2118 unbecome_root();
2120 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2121 status = NT_STATUS_OK;
2124 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2125 &lsa_names)) {
2126 return NT_STATUS_NO_MEMORY;
2129 /* Convert from enum lsa_SidType to uint32 for wire format. */
2130 for (i = 0; i < num_rids; i++) {
2131 wire_attrs[i] = (uint32)attrs[i];
2134 names_array.count = num_rids;
2135 names_array.names = lsa_names;
2137 types_array.count = num_rids;
2138 types_array.ids = wire_attrs;
2140 *r->out.names = names_array;
2141 *r->out.types = types_array;
2143 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2145 return status;
2148 /*******************************************************************
2149 _samr_OpenUser
2150 ********************************************************************/
2152 NTSTATUS _samr_OpenUser(struct pipes_struct *p,
2153 struct samr_OpenUser *r)
2155 struct samu *sampass=NULL;
2156 struct dom_sid sid;
2157 struct samr_domain_info *dinfo;
2158 struct samr_user_info *uinfo;
2159 struct security_descriptor *psd = NULL;
2160 uint32 acc_granted;
2161 uint32 des_access = r->in.access_mask;
2162 uint32_t extra_access = 0;
2163 size_t sd_size;
2164 bool ret;
2165 NTSTATUS nt_status;
2167 /* These two privileges, if != SEC_PRIV_INVALID, indicate
2168 * privileges that the user must have to complete this
2169 * operation in defience of the fixed ACL */
2170 enum sec_privilege needed_priv_1, needed_priv_2;
2171 NTSTATUS status;
2173 dinfo = policy_handle_find(p, r->in.domain_handle,
2174 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2175 struct samr_domain_info, &status);
2176 if (!NT_STATUS_IS_OK(status)) {
2177 return status;
2180 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2181 return NT_STATUS_NO_MEMORY;
2184 /* append the user's RID to it */
2186 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2187 return NT_STATUS_NO_SUCH_USER;
2189 /* check if access can be granted as requested by client. */
2190 map_max_allowed_access(p->session_info->security_token,
2191 &p->session_info->utok,
2192 &des_access);
2194 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2195 se_map_generic(&des_access, &usr_generic_mapping);
2198 * Get the sampass first as we need to check privileges
2199 * based on what kind of user object this is.
2200 * But don't reveal info too early if it didn't exist.
2203 become_root();
2204 ret=pdb_getsampwsid(sampass, &sid);
2205 unbecome_root();
2207 needed_priv_1 = SEC_PRIV_INVALID;
2208 needed_priv_2 = SEC_PRIV_INVALID;
2210 * We do the override access checks on *open*, not at
2211 * SetUserInfo time.
2213 if (ret) {
2214 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2216 if (acb_info & ACB_WSTRUST) {
2218 * SeMachineAccount is needed to add
2219 * GENERIC_RIGHTS_USER_WRITE to a machine
2220 * account.
2222 needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
2224 if (acb_info & ACB_NORMAL) {
2226 * SeAddUsers is needed to add
2227 * GENERIC_RIGHTS_USER_WRITE to a normal
2228 * account.
2230 needed_priv_1 = SEC_PRIV_ADD_USERS;
2233 * Cheat - we have not set a specific privilege for
2234 * server (BDC) or domain trust account, so allow
2235 * GENERIC_RIGHTS_USER_WRITE if pipe user is in
2236 * DOMAIN_RID_ADMINS.
2238 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2239 if (lp_enable_privileges() && nt_token_check_domain_rid(p->session_info->security_token,
2240 DOMAIN_RID_ADMINS)) {
2241 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2242 extra_access = GENERIC_RIGHTS_USER_WRITE;
2243 DEBUG(4,("_samr_OpenUser: Allowing "
2244 "GENERIC_RIGHTS_USER_WRITE for "
2245 "rid admins\n"));
2250 TALLOC_FREE(sampass);
2252 nt_status = access_check_object(psd, p->session_info->security_token,
2253 needed_priv_1, needed_priv_2,
2254 GENERIC_RIGHTS_USER_WRITE, des_access,
2255 &acc_granted, "_samr_OpenUser");
2257 if ( !NT_STATUS_IS_OK(nt_status) )
2258 return nt_status;
2260 /* check that the SID exists in our domain. */
2261 if (ret == False) {
2262 return NT_STATUS_NO_SUCH_USER;
2265 /* If we did the rid admins hack above, allow access. */
2266 acc_granted |= extra_access;
2268 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2269 struct samr_user_info, &nt_status);
2270 if (!NT_STATUS_IS_OK(nt_status)) {
2271 return nt_status;
2273 uinfo->sid = sid;
2275 return NT_STATUS_OK;
2278 /*************************************************************************
2279 *************************************************************************/
2281 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2282 DATA_BLOB *blob,
2283 struct lsa_BinaryString **_r)
2285 struct lsa_BinaryString *r;
2287 if (!blob || !_r) {
2288 return NT_STATUS_INVALID_PARAMETER;
2291 r = talloc_zero(mem_ctx, struct lsa_BinaryString);
2292 if (!r) {
2293 return NT_STATUS_NO_MEMORY;
2296 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2297 if (!r->array) {
2298 return NT_STATUS_NO_MEMORY;
2300 memcpy(r->array, blob->data, blob->length);
2301 r->size = blob->length;
2302 r->length = blob->length;
2304 if (!r->array) {
2305 return NT_STATUS_NO_MEMORY;
2308 *_r = r;
2310 return NT_STATUS_OK;
2313 /*************************************************************************
2314 *************************************************************************/
2316 static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2317 struct samu *pw)
2319 struct samr_LogonHours hours;
2320 const int units_per_week = 168;
2322 ZERO_STRUCT(hours);
2323 hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2324 if (!hours.bits) {
2325 return hours;
2328 hours.units_per_week = units_per_week;
2329 memset(hours.bits, 0xFF, units_per_week);
2331 if (pdb_get_hours(pw)) {
2332 memcpy(hours.bits, pdb_get_hours(pw),
2333 MIN(pdb_get_hours_len(pw), units_per_week));
2336 return hours;
2339 /*************************************************************************
2340 get_user_info_1.
2341 *************************************************************************/
2343 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2344 struct samr_UserInfo1 *r,
2345 struct samu *pw,
2346 struct dom_sid *domain_sid)
2348 const struct dom_sid *sid_group;
2349 uint32_t primary_gid;
2351 become_root();
2352 sid_group = pdb_get_group_sid(pw);
2353 unbecome_root();
2355 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2356 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2357 "which conflicts with the domain sid %s. Failing operation.\n",
2358 pdb_get_username(pw), sid_string_dbg(sid_group),
2359 sid_string_dbg(domain_sid)));
2360 return NT_STATUS_UNSUCCESSFUL;
2363 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2364 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2365 r->primary_gid = primary_gid;
2366 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2367 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2369 return NT_STATUS_OK;
2372 /*************************************************************************
2373 get_user_info_2.
2374 *************************************************************************/
2376 static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2377 struct samr_UserInfo2 *r,
2378 struct samu *pw)
2380 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2381 r->reserved.string = NULL;
2382 r->country_code = pdb_get_country_code(pw);
2383 r->code_page = pdb_get_code_page(pw);
2385 return NT_STATUS_OK;
2388 /*************************************************************************
2389 get_user_info_3.
2390 *************************************************************************/
2392 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2393 struct samr_UserInfo3 *r,
2394 struct samu *pw,
2395 struct dom_sid *domain_sid)
2397 const struct dom_sid *sid_user, *sid_group;
2398 uint32_t rid, primary_gid;
2400 sid_user = pdb_get_user_sid(pw);
2402 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2403 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2404 "the domain sid %s. Failing operation.\n",
2405 pdb_get_username(pw), sid_string_dbg(sid_user),
2406 sid_string_dbg(domain_sid)));
2407 return NT_STATUS_UNSUCCESSFUL;
2410 become_root();
2411 sid_group = pdb_get_group_sid(pw);
2412 unbecome_root();
2414 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2415 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2416 "which conflicts with the domain sid %s. Failing operation.\n",
2417 pdb_get_username(pw), sid_string_dbg(sid_group),
2418 sid_string_dbg(domain_sid)));
2419 return NT_STATUS_UNSUCCESSFUL;
2422 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2423 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2424 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2425 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2426 unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2428 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2429 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2430 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2431 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2432 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2433 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2434 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2436 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2437 r->rid = rid;
2438 r->primary_gid = primary_gid;
2439 r->acct_flags = pdb_get_acct_ctrl(pw);
2440 r->bad_password_count = pdb_get_bad_password_count(pw);
2441 r->logon_count = pdb_get_logon_count(pw);
2443 return NT_STATUS_OK;
2446 /*************************************************************************
2447 get_user_info_4.
2448 *************************************************************************/
2450 static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2451 struct samr_UserInfo4 *r,
2452 struct samu *pw)
2454 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2456 return NT_STATUS_OK;
2459 /*************************************************************************
2460 get_user_info_5.
2461 *************************************************************************/
2463 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2464 struct samr_UserInfo5 *r,
2465 struct samu *pw,
2466 struct dom_sid *domain_sid)
2468 const struct dom_sid *sid_user, *sid_group;
2469 uint32_t rid, primary_gid;
2471 sid_user = pdb_get_user_sid(pw);
2473 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2474 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2475 "the domain sid %s. Failing operation.\n",
2476 pdb_get_username(pw), sid_string_dbg(sid_user),
2477 sid_string_dbg(domain_sid)));
2478 return NT_STATUS_UNSUCCESSFUL;
2481 become_root();
2482 sid_group = pdb_get_group_sid(pw);
2483 unbecome_root();
2485 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2486 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2487 "which conflicts with the domain sid %s. Failing operation.\n",
2488 pdb_get_username(pw), sid_string_dbg(sid_group),
2489 sid_string_dbg(domain_sid)));
2490 return NT_STATUS_UNSUCCESSFUL;
2493 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2494 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2495 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2496 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2498 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2499 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2500 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2501 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2502 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2503 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2504 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2505 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2507 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2508 r->rid = rid;
2509 r->primary_gid = primary_gid;
2510 r->acct_flags = pdb_get_acct_ctrl(pw);
2511 r->bad_password_count = pdb_get_bad_password_count(pw);
2512 r->logon_count = pdb_get_logon_count(pw);
2514 return NT_STATUS_OK;
2517 /*************************************************************************
2518 get_user_info_6.
2519 *************************************************************************/
2521 static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2522 struct samr_UserInfo6 *r,
2523 struct samu *pw)
2525 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2526 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2528 return NT_STATUS_OK;
2531 /*************************************************************************
2532 get_user_info_7. Safe. Only gives out account_name.
2533 *************************************************************************/
2535 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2536 struct samr_UserInfo7 *r,
2537 struct samu *smbpass)
2539 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2540 if (!r->account_name.string) {
2541 return NT_STATUS_NO_MEMORY;
2544 return NT_STATUS_OK;
2547 /*************************************************************************
2548 get_user_info_8.
2549 *************************************************************************/
2551 static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2552 struct samr_UserInfo8 *r,
2553 struct samu *pw)
2555 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2557 return NT_STATUS_OK;
2560 /*************************************************************************
2561 get_user_info_9. Only gives out primary group SID.
2562 *************************************************************************/
2564 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2565 struct samr_UserInfo9 *r,
2566 struct samu *smbpass)
2568 r->primary_gid = pdb_get_group_rid(smbpass);
2570 return NT_STATUS_OK;
2573 /*************************************************************************
2574 get_user_info_10.
2575 *************************************************************************/
2577 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2578 struct samr_UserInfo10 *r,
2579 struct samu *pw)
2581 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2582 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2584 return NT_STATUS_OK;
2587 /*************************************************************************
2588 get_user_info_11.
2589 *************************************************************************/
2591 static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2592 struct samr_UserInfo11 *r,
2593 struct samu *pw)
2595 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2597 return NT_STATUS_OK;
2600 /*************************************************************************
2601 get_user_info_12.
2602 *************************************************************************/
2604 static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2605 struct samr_UserInfo12 *r,
2606 struct samu *pw)
2608 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2610 return NT_STATUS_OK;
2613 /*************************************************************************
2614 get_user_info_13.
2615 *************************************************************************/
2617 static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2618 struct samr_UserInfo13 *r,
2619 struct samu *pw)
2621 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2623 return NT_STATUS_OK;
2626 /*************************************************************************
2627 get_user_info_14.
2628 *************************************************************************/
2630 static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2631 struct samr_UserInfo14 *r,
2632 struct samu *pw)
2634 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2636 return NT_STATUS_OK;
2639 /*************************************************************************
2640 get_user_info_16. Safe. Only gives out acb bits.
2641 *************************************************************************/
2643 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2644 struct samr_UserInfo16 *r,
2645 struct samu *smbpass)
2647 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2649 return NT_STATUS_OK;
2652 /*************************************************************************
2653 get_user_info_17.
2654 *************************************************************************/
2656 static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2657 struct samr_UserInfo17 *r,
2658 struct samu *pw)
2660 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2662 return NT_STATUS_OK;
2665 /*************************************************************************
2666 get_user_info_18. OK - this is the killer as it gives out password info.
2667 Ensure that this is only allowed on an encrypted connection with a root
2668 user. JRA.
2669 *************************************************************************/
2671 static NTSTATUS get_user_info_18(struct pipes_struct *p,
2672 TALLOC_CTX *mem_ctx,
2673 struct samr_UserInfo18 *r,
2674 struct dom_sid *user_sid)
2676 struct samu *smbpass=NULL;
2677 bool ret;
2678 const uint8_t *nt_pass = NULL;
2679 const uint8_t *lm_pass = NULL;
2681 ZERO_STRUCTP(r);
2683 if (p->session_info->system) {
2684 goto query;
2687 if ((p->auth.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) ||
2688 (p->auth.auth_type != DCERPC_AUTH_TYPE_KRB5) ||
2689 (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO)) {
2690 return NT_STATUS_ACCESS_DENIED;
2693 if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2694 return NT_STATUS_ACCESS_DENIED;
2697 query:
2699 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2702 if ( !(smbpass = samu_new( mem_ctx )) ) {
2703 return NT_STATUS_NO_MEMORY;
2706 ret = pdb_getsampwsid(smbpass, user_sid);
2708 if (ret == False) {
2709 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2710 TALLOC_FREE(smbpass);
2711 return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2714 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2716 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2717 TALLOC_FREE(smbpass);
2718 return NT_STATUS_ACCOUNT_DISABLED;
2721 lm_pass = pdb_get_lanman_passwd(smbpass);
2722 if (lm_pass != NULL) {
2723 memcpy(r->lm_pwd.hash, lm_pass, 16);
2724 r->lm_pwd_active = true;
2727 nt_pass = pdb_get_nt_passwd(smbpass);
2728 if (nt_pass != NULL) {
2729 memcpy(r->nt_pwd.hash, nt_pass, 16);
2730 r->nt_pwd_active = true;
2732 r->password_expired = 0; /* FIXME */
2734 TALLOC_FREE(smbpass);
2736 return NT_STATUS_OK;
2739 /*************************************************************************
2740 get_user_info_20
2741 *************************************************************************/
2743 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2744 struct samr_UserInfo20 *r,
2745 struct samu *sampass)
2747 const char *munged_dial = NULL;
2748 DATA_BLOB blob;
2749 NTSTATUS status;
2750 struct lsa_BinaryString *parameters = NULL;
2752 ZERO_STRUCTP(r);
2754 munged_dial = pdb_get_munged_dial(sampass);
2756 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2757 munged_dial, (int)strlen(munged_dial)));
2759 if (munged_dial) {
2760 blob = base64_decode_data_blob(munged_dial);
2761 } else {
2762 blob = data_blob_string_const_null("");
2765 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2766 data_blob_free(&blob);
2767 if (!NT_STATUS_IS_OK(status)) {
2768 return status;
2771 r->parameters = *parameters;
2773 return NT_STATUS_OK;
2777 /*************************************************************************
2778 get_user_info_21
2779 *************************************************************************/
2781 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2782 struct samr_UserInfo21 *r,
2783 struct samu *pw,
2784 struct dom_sid *domain_sid,
2785 uint32_t acc_granted)
2787 NTSTATUS status;
2788 const struct dom_sid *sid_user, *sid_group;
2789 uint32_t rid, primary_gid;
2790 NTTIME force_password_change;
2791 time_t must_change_time;
2792 struct lsa_BinaryString *parameters = NULL;
2793 const char *munged_dial = NULL;
2794 DATA_BLOB blob;
2796 ZERO_STRUCTP(r);
2798 sid_user = pdb_get_user_sid(pw);
2800 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2801 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2802 "the domain sid %s. Failing operation.\n",
2803 pdb_get_username(pw), sid_string_dbg(sid_user),
2804 sid_string_dbg(domain_sid)));
2805 return NT_STATUS_UNSUCCESSFUL;
2808 become_root();
2809 sid_group = pdb_get_group_sid(pw);
2810 unbecome_root();
2812 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2813 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2814 "which conflicts with the domain sid %s. Failing operation.\n",
2815 pdb_get_username(pw), sid_string_dbg(sid_group),
2816 sid_string_dbg(domain_sid)));
2817 return NT_STATUS_UNSUCCESSFUL;
2820 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2821 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2822 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2823 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2824 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2826 must_change_time = pdb_get_pass_must_change_time(pw);
2827 if (must_change_time == get_time_t_max()) {
2828 unix_to_nt_time_abs(&force_password_change, must_change_time);
2829 } else {
2830 unix_to_nt_time(&force_password_change, must_change_time);
2833 munged_dial = pdb_get_munged_dial(pw);
2834 if (munged_dial) {
2835 blob = base64_decode_data_blob(munged_dial);
2836 } else {
2837 blob = data_blob_string_const_null("");
2840 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2841 data_blob_free(&blob);
2842 if (!NT_STATUS_IS_OK(status)) {
2843 return status;
2846 r->force_password_change = force_password_change;
2848 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2849 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2850 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2851 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2852 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2853 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2854 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2855 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2856 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2858 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2859 r->parameters = *parameters;
2860 r->rid = rid;
2861 r->primary_gid = primary_gid;
2862 r->acct_flags = pdb_get_acct_ctrl(pw);
2863 r->bad_password_count = pdb_get_bad_password_count(pw);
2864 r->logon_count = pdb_get_logon_count(pw);
2865 r->fields_present = pdb_build_fields_present(pw);
2866 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2867 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2868 r->country_code = pdb_get_country_code(pw);
2869 r->code_page = pdb_get_code_page(pw);
2870 r->lm_password_set = 0;
2871 r->nt_password_set = 0;
2873 #if 0
2876 Look at a user on a real NT4 PDC with usrmgr, press
2877 'ok'. Then you will see that fields_present is set to
2878 0x08f827fa. Look at the user immediately after that again,
2879 and you will see that 0x00fffff is returned. This solves
2880 the problem that you get access denied after having looked
2881 at the user.
2882 -- Volker
2885 #endif
2888 return NT_STATUS_OK;
2891 /*******************************************************************
2892 _samr_QueryUserInfo
2893 ********************************************************************/
2895 NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
2896 struct samr_QueryUserInfo *r)
2898 NTSTATUS status;
2899 union samr_UserInfo *user_info = NULL;
2900 struct samr_user_info *uinfo;
2901 struct dom_sid domain_sid;
2902 uint32 rid;
2903 bool ret = false;
2904 struct samu *pwd = NULL;
2905 uint32_t acc_required, acc_granted;
2907 switch (r->in.level) {
2908 case 1: /* UserGeneralInformation */
2909 /* USER_READ_GENERAL */
2910 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2911 break;
2912 case 2: /* UserPreferencesInformation */
2913 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
2914 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2915 SAMR_USER_ACCESS_GET_NAME_ETC;
2916 break;
2917 case 3: /* UserLogonInformation */
2918 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2919 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2920 SAMR_USER_ACCESS_GET_LOCALE |
2921 SAMR_USER_ACCESS_GET_LOGONINFO |
2922 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2923 break;
2924 case 4: /* UserLogonHoursInformation */
2925 /* USER_READ_LOGON */
2926 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2927 break;
2928 case 5: /* UserAccountInformation */
2929 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2930 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2931 SAMR_USER_ACCESS_GET_LOCALE |
2932 SAMR_USER_ACCESS_GET_LOGONINFO |
2933 SAMR_USER_ACCESS_GET_ATTRIBUTES;
2934 break;
2935 case 6: /* UserNameInformation */
2936 case 7: /* UserAccountNameInformation */
2937 case 8: /* UserFullNameInformation */
2938 case 9: /* UserPrimaryGroupInformation */
2939 case 13: /* UserAdminCommentInformation */
2940 /* USER_READ_GENERAL */
2941 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2942 break;
2943 case 10: /* UserHomeInformation */
2944 case 11: /* UserScriptInformation */
2945 case 12: /* UserProfileInformation */
2946 case 14: /* UserWorkStationsInformation */
2947 /* USER_READ_LOGON */
2948 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2949 break;
2950 case 16: /* UserControlInformation */
2951 case 17: /* UserExpiresInformation */
2952 case 20: /* UserParametersInformation */
2953 /* USER_READ_ACCOUNT */
2954 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2955 break;
2956 case 21: /* UserAllInformation */
2957 /* FIXME! - gd */
2958 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2959 break;
2960 case 18: /* UserInternal1Information */
2961 /* FIXME! - gd */
2962 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
2963 break;
2964 case 23: /* UserInternal4Information */
2965 case 24: /* UserInternal4InformationNew */
2966 case 25: /* UserInternal4InformationNew */
2967 case 26: /* UserInternal5InformationNew */
2968 default:
2969 return NT_STATUS_INVALID_INFO_CLASS;
2970 break;
2973 uinfo = policy_handle_find(p, r->in.user_handle,
2974 acc_required, &acc_granted,
2975 struct samr_user_info, &status);
2976 if (!NT_STATUS_IS_OK(status)) {
2977 return status;
2980 domain_sid = uinfo->sid;
2982 sid_split_rid(&domain_sid, &rid);
2984 if (!sid_check_is_in_our_domain(&uinfo->sid))
2985 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2987 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2988 sid_string_dbg(&uinfo->sid)));
2990 user_info = talloc_zero(p->mem_ctx, union samr_UserInfo);
2991 if (!user_info) {
2992 return NT_STATUS_NO_MEMORY;
2995 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2997 if (!(pwd = samu_new(p->mem_ctx))) {
2998 return NT_STATUS_NO_MEMORY;
3001 become_root();
3002 ret = pdb_getsampwsid(pwd, &uinfo->sid);
3003 unbecome_root();
3005 if (ret == false) {
3006 DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3007 TALLOC_FREE(pwd);
3008 return NT_STATUS_NO_SUCH_USER;
3011 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3013 samr_clear_sam_passwd(pwd);
3015 switch (r->in.level) {
3016 case 1:
3017 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3018 break;
3019 case 2:
3020 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3021 break;
3022 case 3:
3023 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3024 break;
3025 case 4:
3026 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3027 break;
3028 case 5:
3029 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3030 break;
3031 case 6:
3032 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3033 break;
3034 case 7:
3035 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3036 break;
3037 case 8:
3038 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3039 break;
3040 case 9:
3041 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3042 break;
3043 case 10:
3044 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3045 break;
3046 case 11:
3047 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3048 break;
3049 case 12:
3050 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3051 break;
3052 case 13:
3053 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3054 break;
3055 case 14:
3056 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3057 break;
3058 case 16:
3059 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3060 break;
3061 case 17:
3062 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3063 break;
3064 case 18:
3065 /* level 18 is special */
3066 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3067 &uinfo->sid);
3068 break;
3069 case 20:
3070 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3071 break;
3072 case 21:
3073 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3074 break;
3075 default:
3076 status = NT_STATUS_INVALID_INFO_CLASS;
3077 break;
3080 if (!NT_STATUS_IS_OK(status)) {
3081 goto done;
3084 *r->out.info = user_info;
3086 done:
3087 TALLOC_FREE(pwd);
3089 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3091 return status;
3094 /****************************************************************
3095 ****************************************************************/
3097 NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
3098 struct samr_QueryUserInfo2 *r)
3100 struct samr_QueryUserInfo u;
3102 u.in.user_handle = r->in.user_handle;
3103 u.in.level = r->in.level;
3104 u.out.info = r->out.info;
3106 return _samr_QueryUserInfo(p, &u);
3109 /*******************************************************************
3110 _samr_GetGroupsForUser
3111 ********************************************************************/
3113 NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
3114 struct samr_GetGroupsForUser *r)
3116 struct samr_user_info *uinfo;
3117 struct samu *sam_pass=NULL;
3118 struct dom_sid *sids;
3119 struct samr_RidWithAttribute dom_gid;
3120 struct samr_RidWithAttribute *gids = NULL;
3121 uint32 primary_group_rid;
3122 uint32_t num_groups = 0;
3123 gid_t *unix_gids;
3124 uint32_t i, num_gids;
3125 bool ret;
3126 NTSTATUS result;
3127 bool success = False;
3129 struct samr_RidWithAttributeArray *rids = NULL;
3132 * from the SID in the request:
3133 * we should send back the list of DOMAIN GROUPS
3134 * the user is a member of
3136 * and only the DOMAIN GROUPS
3137 * no ALIASES !!! neither aliases of the domain
3138 * nor aliases of the builtin SID
3140 * JFM, 12/2/2001
3143 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3145 uinfo = policy_handle_find(p, r->in.user_handle,
3146 SAMR_USER_ACCESS_GET_GROUPS, NULL,
3147 struct samr_user_info, &result);
3148 if (!NT_STATUS_IS_OK(result)) {
3149 return result;
3152 rids = talloc_zero(p->mem_ctx, struct samr_RidWithAttributeArray);
3153 if (!rids) {
3154 return NT_STATUS_NO_MEMORY;
3157 if (!sid_check_is_in_our_domain(&uinfo->sid))
3158 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3160 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3161 return NT_STATUS_NO_MEMORY;
3164 become_root();
3165 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3166 unbecome_root();
3168 if (!ret) {
3169 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3170 sid_string_dbg(&uinfo->sid)));
3171 return NT_STATUS_NO_SUCH_USER;
3174 sids = NULL;
3176 /* make both calls inside the root block */
3177 become_root();
3178 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3179 &sids, &unix_gids, &num_groups);
3180 if ( NT_STATUS_IS_OK(result) ) {
3181 success = sid_peek_check_rid(get_global_sam_sid(),
3182 pdb_get_group_sid(sam_pass),
3183 &primary_group_rid);
3185 unbecome_root();
3187 if (!NT_STATUS_IS_OK(result)) {
3188 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3189 sid_string_dbg(&uinfo->sid)));
3190 return result;
3193 if ( !success ) {
3194 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3195 sid_string_dbg(pdb_get_group_sid(sam_pass)),
3196 pdb_get_username(sam_pass)));
3197 TALLOC_FREE(sam_pass);
3198 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3201 gids = NULL;
3202 num_gids = 0;
3204 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3205 SE_GROUP_ENABLED);
3206 dom_gid.rid = primary_group_rid;
3207 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3209 for (i=0; i<num_groups; i++) {
3211 if (!sid_peek_check_rid(get_global_sam_sid(),
3212 &(sids[i]), &dom_gid.rid)) {
3213 DEBUG(10, ("Found sid %s not in our domain\n",
3214 sid_string_dbg(&sids[i])));
3215 continue;
3218 if (dom_gid.rid == primary_group_rid) {
3219 /* We added the primary group directly from the
3220 * sam_account. The other SIDs are unique from
3221 * enum_group_memberships */
3222 continue;
3225 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3228 rids->count = num_gids;
3229 rids->rids = gids;
3231 *r->out.rids = rids;
3233 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3235 return result;
3238 /*******************************************************************
3239 ********************************************************************/
3241 static uint32_t samr_get_server_role(void)
3243 uint32_t role = ROLE_DOMAIN_PDC;
3245 if (lp_server_role() == ROLE_DOMAIN_BDC) {
3246 role = ROLE_DOMAIN_BDC;
3249 return role;
3252 /*******************************************************************
3253 ********************************************************************/
3255 static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3256 struct samr_DomInfo1 *r)
3258 uint32_t account_policy_temp;
3259 time_t u_expire, u_min_age;
3261 become_root();
3263 /* AS ROOT !!! */
3265 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3266 r->min_password_length = account_policy_temp;
3268 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3269 r->password_history_length = account_policy_temp;
3271 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3272 &r->password_properties);
3274 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3275 u_expire = account_policy_temp;
3277 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3278 u_min_age = account_policy_temp;
3280 /* !AS ROOT */
3282 unbecome_root();
3284 unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3285 unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3287 if (lp_check_password_script() && *lp_check_password_script()) {
3288 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3291 return NT_STATUS_OK;
3294 /*******************************************************************
3295 ********************************************************************/
3297 static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3298 struct samr_DomGeneralInformation *r,
3299 struct samr_domain_info *dinfo)
3301 uint32_t u_logout;
3302 time_t seq_num;
3304 become_root();
3306 /* AS ROOT !!! */
3308 r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
3309 r->num_groups = count_sam_groups(dinfo->disp_info);
3310 r->num_aliases = count_sam_aliases(dinfo->disp_info);
3312 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3314 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3316 if (!pdb_get_seq_num(&seq_num)) {
3317 seq_num = time(NULL);
3320 /* !AS ROOT */
3322 unbecome_root();
3324 r->oem_information.string = lp_serverstring();
3325 r->domain_name.string = lp_workgroup();
3326 r->primary.string = global_myname();
3327 r->sequence_num = seq_num;
3328 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3329 r->role = (enum samr_Role) samr_get_server_role();
3330 r->unknown3 = 1;
3332 return NT_STATUS_OK;
3335 /*******************************************************************
3336 ********************************************************************/
3338 static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3339 struct samr_DomInfo3 *r)
3341 uint32_t u_logout;
3343 become_root();
3345 /* AS ROOT !!! */
3348 uint32_t ul;
3349 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3350 u_logout = (time_t)ul;
3353 /* !AS ROOT */
3355 unbecome_root();
3357 unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3359 return NT_STATUS_OK;
3362 /*******************************************************************
3363 ********************************************************************/
3365 static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3366 struct samr_DomOEMInformation *r)
3368 r->oem_information.string = lp_serverstring();
3370 return NT_STATUS_OK;
3373 /*******************************************************************
3374 ********************************************************************/
3376 static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3377 struct samr_DomInfo5 *r)
3379 r->domain_name.string = get_global_sam_name();
3381 return NT_STATUS_OK;
3384 /*******************************************************************
3385 ********************************************************************/
3387 static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3388 struct samr_DomInfo6 *r)
3390 /* NT returns its own name when a PDC. win2k and later
3391 * only the name of the PDC if itself is a BDC (samba4
3392 * idl) */
3393 r->primary.string = global_myname();
3395 return NT_STATUS_OK;
3398 /*******************************************************************
3399 ********************************************************************/
3401 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3402 struct samr_DomInfo7 *r)
3404 r->role = (enum samr_Role) samr_get_server_role();
3406 return NT_STATUS_OK;
3409 /*******************************************************************
3410 ********************************************************************/
3412 static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3413 struct samr_DomInfo8 *r)
3415 time_t seq_num;
3417 become_root();
3419 /* AS ROOT !!! */
3421 if (!pdb_get_seq_num(&seq_num)) {
3422 seq_num = time(NULL);
3425 /* !AS ROOT */
3427 unbecome_root();
3429 r->sequence_num = seq_num;
3430 r->domain_create_time = 0;
3432 return NT_STATUS_OK;
3435 /*******************************************************************
3436 ********************************************************************/
3438 static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3439 struct samr_DomInfo9 *r)
3441 r->domain_server_state = DOMAIN_SERVER_ENABLED;
3443 return NT_STATUS_OK;
3446 /*******************************************************************
3447 ********************************************************************/
3449 static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3450 struct samr_DomGeneralInformation2 *r,
3451 struct samr_domain_info *dinfo)
3453 NTSTATUS status;
3454 uint32_t account_policy_temp;
3455 time_t u_lock_duration, u_reset_time;
3457 status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3458 if (!NT_STATUS_IS_OK(status)) {
3459 return status;
3462 /* AS ROOT !!! */
3464 become_root();
3466 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3467 u_lock_duration = account_policy_temp;
3468 if (u_lock_duration != -1) {
3469 u_lock_duration *= 60;
3472 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3473 u_reset_time = account_policy_temp * 60;
3475 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3476 r->lockout_threshold = account_policy_temp;
3478 /* !AS ROOT */
3480 unbecome_root();
3482 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3483 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3485 return NT_STATUS_OK;
3488 /*******************************************************************
3489 ********************************************************************/
3491 static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3492 struct samr_DomInfo12 *r)
3494 uint32_t account_policy_temp;
3495 time_t u_lock_duration, u_reset_time;
3497 become_root();
3499 /* AS ROOT !!! */
3501 pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3502 u_lock_duration = account_policy_temp;
3503 if (u_lock_duration != -1) {
3504 u_lock_duration *= 60;
3507 pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3508 u_reset_time = account_policy_temp * 60;
3510 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3511 r->lockout_threshold = account_policy_temp;
3513 /* !AS ROOT */
3515 unbecome_root();
3517 unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3518 unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3520 return NT_STATUS_OK;
3523 /*******************************************************************
3524 ********************************************************************/
3526 static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3527 struct samr_DomInfo13 *r)
3529 time_t seq_num;
3531 become_root();
3533 /* AS ROOT !!! */
3535 if (!pdb_get_seq_num(&seq_num)) {
3536 seq_num = time(NULL);
3539 /* !AS ROOT */
3541 unbecome_root();
3543 r->sequence_num = seq_num;
3544 r->domain_create_time = 0;
3545 r->modified_count_at_last_promotion = 0;
3547 return NT_STATUS_OK;
3550 /*******************************************************************
3551 _samr_QueryDomainInfo
3552 ********************************************************************/
3554 NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
3555 struct samr_QueryDomainInfo *r)
3557 NTSTATUS status = NT_STATUS_OK;
3558 struct samr_domain_info *dinfo;
3559 union samr_DomainInfo *dom_info;
3561 uint32_t acc_required;
3563 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3565 switch (r->in.level) {
3566 case 1: /* DomainPasswordInformation */
3567 case 12: /* DomainLockoutInformation */
3568 /* DOMAIN_READ_PASSWORD_PARAMETERS */
3569 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3570 break;
3571 case 11: /* DomainGeneralInformation2 */
3572 /* DOMAIN_READ_PASSWORD_PARAMETERS |
3573 * DOMAIN_READ_OTHER_PARAMETERS */
3574 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3575 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3576 break;
3577 case 2: /* DomainGeneralInformation */
3578 case 3: /* DomainLogoffInformation */
3579 case 4: /* DomainOemInformation */
3580 case 5: /* DomainReplicationInformation */
3581 case 6: /* DomainReplicationInformation */
3582 case 7: /* DomainServerRoleInformation */
3583 case 8: /* DomainModifiedInformation */
3584 case 9: /* DomainStateInformation */
3585 case 10: /* DomainUasInformation */
3586 case 13: /* DomainModifiedInformation2 */
3587 /* DOMAIN_READ_OTHER_PARAMETERS */
3588 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3589 break;
3590 default:
3591 return NT_STATUS_INVALID_INFO_CLASS;
3594 dinfo = policy_handle_find(p, r->in.domain_handle,
3595 acc_required, NULL,
3596 struct samr_domain_info, &status);
3597 if (!NT_STATUS_IS_OK(status)) {
3598 return status;
3601 dom_info = talloc_zero(p->mem_ctx, union samr_DomainInfo);
3602 if (!dom_info) {
3603 return NT_STATUS_NO_MEMORY;
3606 switch (r->in.level) {
3607 case 1:
3608 status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3609 break;
3610 case 2:
3611 status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3612 break;
3613 case 3:
3614 status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3615 break;
3616 case 4:
3617 status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3618 break;
3619 case 5:
3620 status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3621 break;
3622 case 6:
3623 status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3624 break;
3625 case 7:
3626 status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3627 break;
3628 case 8:
3629 status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3630 break;
3631 case 9:
3632 status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3633 break;
3634 case 11:
3635 status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3636 break;
3637 case 12:
3638 status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3639 break;
3640 case 13:
3641 status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3642 break;
3643 default:
3644 return NT_STATUS_INVALID_INFO_CLASS;
3647 if (!NT_STATUS_IS_OK(status)) {
3648 return status;
3651 *r->out.info = dom_info;
3653 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3655 return status;
3658 /* W2k3 seems to use the same check for all 3 objects that can be created via
3659 * SAMR, if you try to create for example "Dialup" as an alias it says
3660 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3661 * database. */
3663 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3665 enum lsa_SidType type;
3666 bool result;
3668 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3670 become_root();
3671 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3672 * whether the name already exists */
3673 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3674 NULL, NULL, NULL, &type);
3675 unbecome_root();
3677 if (!result) {
3678 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3679 return NT_STATUS_OK;
3682 DEBUG(5, ("trying to create %s, exists as %s\n",
3683 new_name, sid_type_lookup(type)));
3685 if (type == SID_NAME_DOM_GRP) {
3686 return NT_STATUS_GROUP_EXISTS;
3688 if (type == SID_NAME_ALIAS) {
3689 return NT_STATUS_ALIAS_EXISTS;
3692 /* Yes, the default is NT_STATUS_USER_EXISTS */
3693 return NT_STATUS_USER_EXISTS;
3696 /*******************************************************************
3697 _samr_CreateUser2
3698 ********************************************************************/
3700 NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
3701 struct samr_CreateUser2 *r)
3703 const char *account = NULL;
3704 struct dom_sid sid;
3705 uint32_t acb_info = r->in.acct_flags;
3706 struct samr_domain_info *dinfo;
3707 struct samr_user_info *uinfo;
3708 NTSTATUS nt_status;
3709 uint32 acc_granted;
3710 struct security_descriptor *psd;
3711 size_t sd_size;
3712 /* check this, when giving away 'add computer to domain' privs */
3713 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3714 bool can_add_account = False;
3716 /* Which privilege is needed to override the ACL? */
3717 enum sec_privilege needed_priv = SEC_PRIV_INVALID;
3719 dinfo = policy_handle_find(p, r->in.domain_handle,
3720 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3721 struct samr_domain_info, &nt_status);
3722 if (!NT_STATUS_IS_OK(nt_status)) {
3723 return nt_status;
3726 if (sid_check_is_builtin(&dinfo->sid)) {
3727 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3728 return NT_STATUS_ACCESS_DENIED;
3731 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3732 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3733 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3734 this parameter is not an account type */
3735 return NT_STATUS_INVALID_PARAMETER;
3738 account = r->in.account_name->string;
3739 if (account == NULL) {
3740 return NT_STATUS_NO_MEMORY;
3743 nt_status = can_create(p->mem_ctx, account);
3744 if (!NT_STATUS_IS_OK(nt_status)) {
3745 return nt_status;
3748 /* determine which user right we need to check based on the acb_info */
3750 if (geteuid() == sec_initial_uid()) {
3751 can_add_account = true;
3752 } else if (acb_info & ACB_WSTRUST) {
3753 needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
3754 can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_MACHINE_ACCOUNT);
3755 } else if (acb_info & ACB_NORMAL &&
3756 (account[strlen(account)-1] != '$')) {
3757 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3758 account for domain trusts and changes the ACB flags later */
3759 needed_priv = SEC_PRIV_ADD_USERS;
3760 can_add_account = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_ADD_USERS);
3761 } else if (lp_enable_privileges()) {
3762 /* implicit assumption of a BDC or domain trust account here
3763 * (we already check the flags earlier) */
3764 /* only Domain Admins can add a BDC or domain trust */
3765 can_add_account = nt_token_check_domain_rid(
3766 p->session_info->security_token,
3767 DOMAIN_RID_ADMINS );
3770 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3771 uidtoname(p->session_info->utok.uid),
3772 can_add_account ? "True":"False" ));
3774 if (!can_add_account) {
3775 return NT_STATUS_ACCESS_DENIED;
3778 /********** BEGIN Admin BLOCK **********/
3780 become_root();
3781 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3782 r->out.rid);
3783 unbecome_root();
3785 /********** END Admin BLOCK **********/
3787 /* now check for failure */
3789 if ( !NT_STATUS_IS_OK(nt_status) )
3790 return nt_status;
3792 /* Get the user's SID */
3794 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3796 map_max_allowed_access(p->session_info->security_token,
3797 &p->session_info->utok,
3798 &des_access);
3800 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3801 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3802 se_map_generic(&des_access, &usr_generic_mapping);
3805 * JRA - TESTME. We just created this user so we
3806 * had rights to create them. Do we need to check
3807 * any further access on this object ? Can't we
3808 * just assume we have all the rights we need ?
3811 nt_status = access_check_object(psd, p->session_info->security_token,
3812 needed_priv, SEC_PRIV_INVALID,
3813 GENERIC_RIGHTS_USER_WRITE, des_access,
3814 &acc_granted, "_samr_CreateUser2");
3816 if ( !NT_STATUS_IS_OK(nt_status) ) {
3817 return nt_status;
3820 uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3821 struct samr_user_info, &nt_status);
3822 if (!NT_STATUS_IS_OK(nt_status)) {
3823 return nt_status;
3825 uinfo->sid = sid;
3827 /* After a "set" ensure we have no cached display info. */
3828 force_flush_samr_cache(&sid);
3830 *r->out.access_granted = acc_granted;
3832 return NT_STATUS_OK;
3835 /****************************************************************
3836 ****************************************************************/
3838 NTSTATUS _samr_CreateUser(struct pipes_struct *p,
3839 struct samr_CreateUser *r)
3841 struct samr_CreateUser2 c;
3842 uint32_t access_granted;
3844 c.in.domain_handle = r->in.domain_handle;
3845 c.in.account_name = r->in.account_name;
3846 c.in.acct_flags = ACB_NORMAL;
3847 c.in.access_mask = r->in.access_mask;
3848 c.out.user_handle = r->out.user_handle;
3849 c.out.access_granted = &access_granted;
3850 c.out.rid = r->out.rid;
3852 return _samr_CreateUser2(p, &c);
3855 /*******************************************************************
3856 _samr_Connect
3857 ********************************************************************/
3859 NTSTATUS _samr_Connect(struct pipes_struct *p,
3860 struct samr_Connect *r)
3862 struct samr_connect_info *info;
3863 uint32_t acc_granted;
3864 struct policy_handle hnd;
3865 uint32 des_access = r->in.access_mask;
3866 NTSTATUS status;
3868 /* Access check */
3870 if (!pipe_access_check(p)) {
3871 DEBUG(3, ("access denied to _samr_Connect\n"));
3872 return NT_STATUS_ACCESS_DENIED;
3875 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3876 was observed from a win98 client trying to enumerate users (when configured
3877 user level access control on shares) --jerry */
3879 map_max_allowed_access(p->session_info->security_token,
3880 &p->session_info->utok,
3881 &des_access);
3883 se_map_generic( &des_access, &sam_generic_mapping );
3885 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3886 |SAMR_ACCESS_LOOKUP_DOMAIN);
3888 /* set up the SAMR connect_anon response */
3890 info = policy_handle_create(p, &hnd, acc_granted,
3891 struct samr_connect_info,
3892 &status);
3893 if (!NT_STATUS_IS_OK(status)) {
3894 return status;
3897 *r->out.connect_handle = hnd;
3898 return NT_STATUS_OK;
3901 /*******************************************************************
3902 _samr_Connect2
3903 ********************************************************************/
3905 NTSTATUS _samr_Connect2(struct pipes_struct *p,
3906 struct samr_Connect2 *r)
3908 struct samr_connect_info *info = NULL;
3909 struct policy_handle hnd;
3910 struct security_descriptor *psd = NULL;
3911 uint32 acc_granted;
3912 uint32 des_access = r->in.access_mask;
3913 NTSTATUS nt_status;
3914 size_t sd_size;
3915 const char *fn = "_samr_Connect2";
3917 switch (p->opnum) {
3918 case NDR_SAMR_CONNECT2:
3919 fn = "_samr_Connect2";
3920 break;
3921 case NDR_SAMR_CONNECT3:
3922 fn = "_samr_Connect3";
3923 break;
3924 case NDR_SAMR_CONNECT4:
3925 fn = "_samr_Connect4";
3926 break;
3927 case NDR_SAMR_CONNECT5:
3928 fn = "_samr_Connect5";
3929 break;
3932 DEBUG(5,("%s: %d\n", fn, __LINE__));
3934 /* Access check */
3936 if (!pipe_access_check(p)) {
3937 DEBUG(3, ("access denied to %s\n", fn));
3938 return NT_STATUS_ACCESS_DENIED;
3941 map_max_allowed_access(p->session_info->security_token,
3942 &p->session_info->utok,
3943 &des_access);
3945 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3946 se_map_generic(&des_access, &sam_generic_mapping);
3948 nt_status = access_check_object(psd, p->session_info->security_token,
3949 SEC_PRIV_INVALID, SEC_PRIV_INVALID,
3950 0, des_access, &acc_granted, fn);
3952 if ( !NT_STATUS_IS_OK(nt_status) )
3953 return nt_status;
3955 info = policy_handle_create(p, &hnd, acc_granted,
3956 struct samr_connect_info, &nt_status);
3957 if (!NT_STATUS_IS_OK(nt_status)) {
3958 return nt_status;
3961 DEBUG(5,("%s: %d\n", fn, __LINE__));
3963 *r->out.connect_handle = hnd;
3964 return NT_STATUS_OK;
3967 /****************************************************************
3968 _samr_Connect3
3969 ****************************************************************/
3971 NTSTATUS _samr_Connect3(struct pipes_struct *p,
3972 struct samr_Connect3 *r)
3974 struct samr_Connect2 c;
3976 c.in.system_name = r->in.system_name;
3977 c.in.access_mask = r->in.access_mask;
3978 c.out.connect_handle = r->out.connect_handle;
3980 return _samr_Connect2(p, &c);
3983 /*******************************************************************
3984 _samr_Connect4
3985 ********************************************************************/
3987 NTSTATUS _samr_Connect4(struct pipes_struct *p,
3988 struct samr_Connect4 *r)
3990 struct samr_Connect2 c;
3992 c.in.system_name = r->in.system_name;
3993 c.in.access_mask = r->in.access_mask;
3994 c.out.connect_handle = r->out.connect_handle;
3996 return _samr_Connect2(p, &c);
3999 /*******************************************************************
4000 _samr_Connect5
4001 ********************************************************************/
4003 NTSTATUS _samr_Connect5(struct pipes_struct *p,
4004 struct samr_Connect5 *r)
4006 NTSTATUS status;
4007 struct samr_Connect2 c;
4008 struct samr_ConnectInfo1 info1;
4010 info1.client_version = SAMR_CONNECT_AFTER_W2K;
4011 info1.unknown2 = 0;
4013 c.in.system_name = r->in.system_name;
4014 c.in.access_mask = r->in.access_mask;
4015 c.out.connect_handle = r->out.connect_handle;
4017 *r->out.level_out = 1;
4019 status = _samr_Connect2(p, &c);
4020 if (!NT_STATUS_IS_OK(status)) {
4021 return status;
4024 r->out.info_out->info1 = info1;
4026 return NT_STATUS_OK;
4029 /**********************************************************************
4030 _samr_LookupDomain
4031 **********************************************************************/
4033 NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
4034 struct samr_LookupDomain *r)
4036 NTSTATUS status;
4037 struct samr_connect_info *info;
4038 const char *domain_name;
4039 struct dom_sid *sid = NULL;
4041 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4042 Reverted that change so we will work with RAS servers again */
4044 info = policy_handle_find(p, r->in.connect_handle,
4045 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4046 struct samr_connect_info,
4047 &status);
4048 if (!NT_STATUS_IS_OK(status)) {
4049 return status;
4052 domain_name = r->in.domain_name->string;
4053 if (!domain_name) {
4054 return NT_STATUS_INVALID_PARAMETER;
4057 sid = talloc_zero(p->mem_ctx, struct dom_sid2);
4058 if (!sid) {
4059 return NT_STATUS_NO_MEMORY;
4062 if (strequal(domain_name, builtin_domain_name())) {
4063 sid_copy(sid, &global_sid_Builtin);
4064 } else {
4065 if (!secrets_fetch_domain_sid(domain_name, sid)) {
4066 status = NT_STATUS_NO_SUCH_DOMAIN;
4070 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4071 sid_string_dbg(sid)));
4073 *r->out.sid = sid;
4075 return status;
4078 /**********************************************************************
4079 _samr_EnumDomains
4080 **********************************************************************/
4082 NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
4083 struct samr_EnumDomains *r)
4085 NTSTATUS status;
4086 struct samr_connect_info *info;
4087 uint32_t num_entries = 2;
4088 struct samr_SamEntry *entry_array = NULL;
4089 struct samr_SamArray *sam;
4091 info = policy_handle_find(p, r->in.connect_handle,
4092 SAMR_ACCESS_ENUM_DOMAINS, NULL,
4093 struct samr_connect_info, &status);
4094 if (!NT_STATUS_IS_OK(status)) {
4095 return status;
4098 sam = talloc_zero(p->mem_ctx, struct samr_SamArray);
4099 if (!sam) {
4100 return NT_STATUS_NO_MEMORY;
4103 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4104 struct samr_SamEntry,
4105 num_entries);
4106 if (!entry_array) {
4107 return NT_STATUS_NO_MEMORY;
4110 entry_array[0].idx = 0;
4111 init_lsa_String(&entry_array[0].name, get_global_sam_name());
4113 entry_array[1].idx = 1;
4114 init_lsa_String(&entry_array[1].name, "Builtin");
4116 sam->count = num_entries;
4117 sam->entries = entry_array;
4119 *r->out.sam = sam;
4120 *r->out.num_entries = num_entries;
4122 return status;
4125 /*******************************************************************
4126 _samr_OpenAlias
4127 ********************************************************************/
4129 NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
4130 struct samr_OpenAlias *r)
4132 struct dom_sid sid;
4133 uint32 alias_rid = r->in.rid;
4134 struct samr_alias_info *ainfo;
4135 struct samr_domain_info *dinfo;
4136 struct security_descriptor *psd = NULL;
4137 uint32 acc_granted;
4138 uint32 des_access = r->in.access_mask;
4139 size_t sd_size;
4140 NTSTATUS status;
4142 dinfo = policy_handle_find(p, r->in.domain_handle,
4143 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4144 struct samr_domain_info, &status);
4145 if (!NT_STATUS_IS_OK(status)) {
4146 return status;
4149 /* append the alias' RID to it */
4151 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4152 return NT_STATUS_NO_SUCH_ALIAS;
4154 /*check if access can be granted as requested by client. */
4156 map_max_allowed_access(p->session_info->security_token,
4157 &p->session_info->utok,
4158 &des_access);
4160 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4161 se_map_generic(&des_access,&ali_generic_mapping);
4163 status = access_check_object(psd, p->session_info->security_token,
4164 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
4165 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4166 des_access, &acc_granted, "_samr_OpenAlias");
4168 if ( !NT_STATUS_IS_OK(status) )
4169 return status;
4172 /* Check we actually have the requested alias */
4173 enum lsa_SidType type;
4174 bool result;
4175 gid_t gid;
4177 become_root();
4178 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4179 unbecome_root();
4181 if (!result || (type != SID_NAME_ALIAS)) {
4182 return NT_STATUS_NO_SUCH_ALIAS;
4185 /* make sure there is a mapping */
4187 if ( !sid_to_gid( &sid, &gid ) ) {
4188 return NT_STATUS_NO_SUCH_ALIAS;
4193 ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4194 struct samr_alias_info, &status);
4195 if (!NT_STATUS_IS_OK(status)) {
4196 return status;
4198 ainfo->sid = sid;
4200 return NT_STATUS_OK;
4203 /*******************************************************************
4204 set_user_info_2
4205 ********************************************************************/
4207 static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4208 struct samr_UserInfo2 *id2,
4209 struct samu *pwd)
4211 if (id2 == NULL) {
4212 DEBUG(5,("set_user_info_2: NULL id2\n"));
4213 return NT_STATUS_ACCESS_DENIED;
4216 copy_id2_to_sam_passwd(pwd, id2);
4218 return pdb_update_sam_account(pwd);
4221 /*******************************************************************
4222 set_user_info_4
4223 ********************************************************************/
4225 static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4226 struct samr_UserInfo4 *id4,
4227 struct samu *pwd)
4229 if (id4 == NULL) {
4230 DEBUG(5,("set_user_info_2: NULL id4\n"));
4231 return NT_STATUS_ACCESS_DENIED;
4234 copy_id4_to_sam_passwd(pwd, id4);
4236 return pdb_update_sam_account(pwd);
4239 /*******************************************************************
4240 set_user_info_6
4241 ********************************************************************/
4243 static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4244 struct samr_UserInfo6 *id6,
4245 struct samu *pwd)
4247 if (id6 == NULL) {
4248 DEBUG(5,("set_user_info_6: NULL id6\n"));
4249 return NT_STATUS_ACCESS_DENIED;
4252 copy_id6_to_sam_passwd(pwd, id6);
4254 return pdb_update_sam_account(pwd);
4257 /*******************************************************************
4258 set_user_info_7
4259 ********************************************************************/
4261 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4262 struct samr_UserInfo7 *id7,
4263 struct samu *pwd)
4265 NTSTATUS rc;
4267 if (id7 == NULL) {
4268 DEBUG(5, ("set_user_info_7: NULL id7\n"));
4269 return NT_STATUS_ACCESS_DENIED;
4272 if (!id7->account_name.string) {
4273 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4274 return NT_STATUS_ACCESS_DENIED;
4277 /* check to see if the new username already exists. Note: we can't
4278 reliably lock all backends, so there is potentially the
4279 possibility that a user can be created in between this check and
4280 the rename. The rename should fail, but may not get the
4281 exact same failure status code. I think this is small enough
4282 of a window for this type of operation and the results are
4283 simply that the rename fails with a slightly different status
4284 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4286 rc = can_create(mem_ctx, id7->account_name.string);
4288 /* when there is nothing to change, we're done here */
4289 if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4290 strequal(id7->account_name.string, pdb_get_username(pwd))) {
4291 return NT_STATUS_OK;
4293 if (!NT_STATUS_IS_OK(rc)) {
4294 return rc;
4297 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4299 return rc;
4302 /*******************************************************************
4303 set_user_info_8
4304 ********************************************************************/
4306 static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4307 struct samr_UserInfo8 *id8,
4308 struct samu *pwd)
4310 if (id8 == NULL) {
4311 DEBUG(5,("set_user_info_8: NULL id8\n"));
4312 return NT_STATUS_ACCESS_DENIED;
4315 copy_id8_to_sam_passwd(pwd, id8);
4317 return pdb_update_sam_account(pwd);
4320 /*******************************************************************
4321 set_user_info_10
4322 ********************************************************************/
4324 static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4325 struct samr_UserInfo10 *id10,
4326 struct samu *pwd)
4328 if (id10 == NULL) {
4329 DEBUG(5,("set_user_info_8: NULL id10\n"));
4330 return NT_STATUS_ACCESS_DENIED;
4333 copy_id10_to_sam_passwd(pwd, id10);
4335 return pdb_update_sam_account(pwd);
4338 /*******************************************************************
4339 set_user_info_11
4340 ********************************************************************/
4342 static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4343 struct samr_UserInfo11 *id11,
4344 struct samu *pwd)
4346 if (id11 == NULL) {
4347 DEBUG(5,("set_user_info_11: NULL id11\n"));
4348 return NT_STATUS_ACCESS_DENIED;
4351 copy_id11_to_sam_passwd(pwd, id11);
4353 return pdb_update_sam_account(pwd);
4356 /*******************************************************************
4357 set_user_info_12
4358 ********************************************************************/
4360 static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4361 struct samr_UserInfo12 *id12,
4362 struct samu *pwd)
4364 if (id12 == NULL) {
4365 DEBUG(5,("set_user_info_12: NULL id12\n"));
4366 return NT_STATUS_ACCESS_DENIED;
4369 copy_id12_to_sam_passwd(pwd, id12);
4371 return pdb_update_sam_account(pwd);
4374 /*******************************************************************
4375 set_user_info_13
4376 ********************************************************************/
4378 static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4379 struct samr_UserInfo13 *id13,
4380 struct samu *pwd)
4382 if (id13 == NULL) {
4383 DEBUG(5,("set_user_info_13: NULL id13\n"));
4384 return NT_STATUS_ACCESS_DENIED;
4387 copy_id13_to_sam_passwd(pwd, id13);
4389 return pdb_update_sam_account(pwd);
4392 /*******************************************************************
4393 set_user_info_14
4394 ********************************************************************/
4396 static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4397 struct samr_UserInfo14 *id14,
4398 struct samu *pwd)
4400 if (id14 == NULL) {
4401 DEBUG(5,("set_user_info_14: NULL id14\n"));
4402 return NT_STATUS_ACCESS_DENIED;
4405 copy_id14_to_sam_passwd(pwd, id14);
4407 return pdb_update_sam_account(pwd);
4410 /*******************************************************************
4411 set_user_info_16
4412 ********************************************************************/
4414 static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4415 struct samr_UserInfo16 *id16,
4416 struct samu *pwd)
4418 if (id16 == NULL) {
4419 DEBUG(5,("set_user_info_16: NULL id16\n"));
4420 return NT_STATUS_ACCESS_DENIED;
4423 copy_id16_to_sam_passwd(pwd, id16);
4425 return pdb_update_sam_account(pwd);
4428 /*******************************************************************
4429 set_user_info_17
4430 ********************************************************************/
4432 static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4433 struct samr_UserInfo17 *id17,
4434 struct samu *pwd)
4436 if (id17 == NULL) {
4437 DEBUG(5,("set_user_info_17: NULL id17\n"));
4438 return NT_STATUS_ACCESS_DENIED;
4441 copy_id17_to_sam_passwd(pwd, id17);
4443 return pdb_update_sam_account(pwd);
4446 /*******************************************************************
4447 set_user_info_18
4448 ********************************************************************/
4450 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4451 TALLOC_CTX *mem_ctx,
4452 DATA_BLOB *session_key,
4453 struct samu *pwd)
4455 if (id18 == NULL) {
4456 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4457 return NT_STATUS_INVALID_PARAMETER;
4460 if (id18->nt_pwd_active || id18->lm_pwd_active) {
4461 if (!session_key->length) {
4462 return NT_STATUS_NO_USER_SESSION_KEY;
4466 if (id18->nt_pwd_active) {
4468 DATA_BLOB in, out;
4470 in = data_blob_const(id18->nt_pwd.hash, 16);
4471 out = data_blob_talloc_zero(mem_ctx, 16);
4473 sess_crypt_blob(&out, &in, session_key, false);
4475 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4476 return NT_STATUS_ACCESS_DENIED;
4479 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4482 if (id18->lm_pwd_active) {
4484 DATA_BLOB in, out;
4486 in = data_blob_const(id18->lm_pwd.hash, 16);
4487 out = data_blob_talloc_zero(mem_ctx, 16);
4489 sess_crypt_blob(&out, &in, session_key, false);
4491 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4492 return NT_STATUS_ACCESS_DENIED;
4495 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4498 copy_id18_to_sam_passwd(pwd, id18);
4500 return pdb_update_sam_account(pwd);
4503 /*******************************************************************
4504 set_user_info_20
4505 ********************************************************************/
4507 static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4508 struct samr_UserInfo20 *id20,
4509 struct samu *pwd)
4511 if (id20 == NULL) {
4512 DEBUG(5,("set_user_info_20: NULL id20\n"));
4513 return NT_STATUS_ACCESS_DENIED;
4516 copy_id20_to_sam_passwd(pwd, id20);
4518 return pdb_update_sam_account(pwd);
4521 /*******************************************************************
4522 set_user_info_21
4523 ********************************************************************/
4525 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4526 TALLOC_CTX *mem_ctx,
4527 DATA_BLOB *session_key,
4528 struct samu *pwd)
4530 NTSTATUS status;
4532 if (id21 == NULL) {
4533 DEBUG(5, ("set_user_info_21: NULL id21\n"));
4534 return NT_STATUS_INVALID_PARAMETER;
4537 if (id21->fields_present == 0) {
4538 return NT_STATUS_INVALID_PARAMETER;
4541 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4542 return NT_STATUS_ACCESS_DENIED;
4545 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4546 if (id21->nt_password_set) {
4547 DATA_BLOB in, out;
4549 if ((id21->nt_owf_password.length != 16) ||
4550 (id21->nt_owf_password.size != 16)) {
4551 return NT_STATUS_INVALID_PARAMETER;
4554 if (!session_key->length) {
4555 return NT_STATUS_NO_USER_SESSION_KEY;
4558 in = data_blob_const(id21->nt_owf_password.array, 16);
4559 out = data_blob_talloc_zero(mem_ctx, 16);
4561 sess_crypt_blob(&out, &in, session_key, false);
4563 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4564 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4568 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4569 if (id21->lm_password_set) {
4570 DATA_BLOB in, out;
4572 if ((id21->lm_owf_password.length != 16) ||
4573 (id21->lm_owf_password.size != 16)) {
4574 return NT_STATUS_INVALID_PARAMETER;
4577 if (!session_key->length) {
4578 return NT_STATUS_NO_USER_SESSION_KEY;
4581 in = data_blob_const(id21->lm_owf_password.array, 16);
4582 out = data_blob_talloc_zero(mem_ctx, 16);
4584 sess_crypt_blob(&out, &in, session_key, false);
4586 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4587 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4591 /* we need to separately check for an account rename first */
4593 if (id21->account_name.string &&
4594 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4597 /* check to see if the new username already exists. Note: we can't
4598 reliably lock all backends, so there is potentially the
4599 possibility that a user can be created in between this check and
4600 the rename. The rename should fail, but may not get the
4601 exact same failure status code. I think this is small enough
4602 of a window for this type of operation and the results are
4603 simply that the rename fails with a slightly different status
4604 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4606 status = can_create(mem_ctx, id21->account_name.string);
4607 if (!NT_STATUS_IS_OK(status)) {
4608 return status;
4611 status = pdb_rename_sam_account(pwd, id21->account_name.string);
4613 if (!NT_STATUS_IS_OK(status)) {
4614 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4615 nt_errstr(status)));
4616 return status;
4619 /* set the new username so that later
4620 functions can work on the new account */
4621 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4624 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4627 * The funny part about the previous two calls is
4628 * that pwd still has the password hashes from the
4629 * passdb entry. These have not been updated from
4630 * id21. I don't know if they need to be set. --jerry
4633 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4634 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4635 if ( !NT_STATUS_IS_OK(status) ) {
4636 return status;
4640 /* Don't worry about writing out the user account since the
4641 primary group SID is generated solely from the user's Unix
4642 primary group. */
4644 /* write the change out */
4645 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4646 return status;
4649 return NT_STATUS_OK;
4652 /*******************************************************************
4653 set_user_info_23
4654 ********************************************************************/
4656 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4657 struct samr_UserInfo23 *id23,
4658 const char *rhost,
4659 struct samu *pwd)
4661 char *plaintext_buf = NULL;
4662 size_t len = 0;
4663 uint32_t acct_ctrl;
4664 NTSTATUS status;
4666 if (id23 == NULL) {
4667 DEBUG(5, ("set_user_info_23: NULL id23\n"));
4668 return NT_STATUS_INVALID_PARAMETER;
4671 if (id23->info.fields_present == 0) {
4672 return NT_STATUS_INVALID_PARAMETER;
4675 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4676 return NT_STATUS_ACCESS_DENIED;
4679 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4680 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4682 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4683 pdb_get_username(pwd)));
4685 if (!decode_pw_buffer(mem_ctx,
4686 id23->password.data,
4687 &plaintext_buf,
4688 &len,
4689 CH_UTF16)) {
4690 return NT_STATUS_WRONG_PASSWORD;
4693 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4694 return NT_STATUS_ACCESS_DENIED;
4698 copy_id23_to_sam_passwd(pwd, id23);
4700 acct_ctrl = pdb_get_acct_ctrl(pwd);
4702 /* if it's a trust account, don't update /etc/passwd */
4703 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4704 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4705 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4706 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
4707 } else if (plaintext_buf) {
4708 /* update the UNIX password */
4709 if (lp_unix_password_sync() ) {
4710 struct passwd *passwd;
4711 if (pdb_get_username(pwd) == NULL) {
4712 DEBUG(1, ("chgpasswd: User without name???\n"));
4713 return NT_STATUS_ACCESS_DENIED;
4716 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4717 if (passwd == NULL) {
4718 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4721 if(!chgpasswd(pdb_get_username(pwd), rhost,
4722 passwd, "", plaintext_buf, True)) {
4723 return NT_STATUS_ACCESS_DENIED;
4725 TALLOC_FREE(passwd);
4729 if (plaintext_buf) {
4730 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4733 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4734 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
4735 pwd)))) {
4736 return status;
4739 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4740 return status;
4743 return NT_STATUS_OK;
4746 /*******************************************************************
4747 set_user_info_pw
4748 ********************************************************************/
4750 static bool set_user_info_pw(uint8 *pass, const char *rhost, struct samu *pwd)
4752 size_t len = 0;
4753 char *plaintext_buf = NULL;
4754 uint32 acct_ctrl;
4756 DEBUG(5, ("Attempting administrator password change for user %s\n",
4757 pdb_get_username(pwd)));
4759 acct_ctrl = pdb_get_acct_ctrl(pwd);
4761 if (!decode_pw_buffer(talloc_tos(),
4762 pass,
4763 &plaintext_buf,
4764 &len,
4765 CH_UTF16)) {
4766 return False;
4769 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4770 return False;
4773 /* if it's a trust account, don't update /etc/passwd */
4774 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4775 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4776 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4777 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4778 } else {
4779 /* update the UNIX password */
4780 if (lp_unix_password_sync()) {
4781 struct passwd *passwd;
4783 if (pdb_get_username(pwd) == NULL) {
4784 DEBUG(1, ("chgpasswd: User without name???\n"));
4785 return False;
4788 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4789 if (passwd == NULL) {
4790 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4793 if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
4794 "", plaintext_buf, True)) {
4795 return False;
4797 TALLOC_FREE(passwd);
4801 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4803 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4805 return True;
4808 /*******************************************************************
4809 set_user_info_24
4810 ********************************************************************/
4812 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4813 const char *rhost,
4814 struct samr_UserInfo24 *id24,
4815 struct samu *pwd)
4817 NTSTATUS status;
4819 if (id24 == NULL) {
4820 DEBUG(5, ("set_user_info_24: NULL id24\n"));
4821 return NT_STATUS_INVALID_PARAMETER;
4824 if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
4825 return NT_STATUS_WRONG_PASSWORD;
4828 copy_id24_to_sam_passwd(pwd, id24);
4830 status = pdb_update_sam_account(pwd);
4831 if (!NT_STATUS_IS_OK(status)) {
4832 return status;
4835 return NT_STATUS_OK;
4838 /*******************************************************************
4839 set_user_info_25
4840 ********************************************************************/
4842 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4843 const char *rhost,
4844 struct samr_UserInfo25 *id25,
4845 struct samu *pwd)
4847 NTSTATUS status;
4849 if (id25 == NULL) {
4850 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4851 return NT_STATUS_INVALID_PARAMETER;
4854 if (id25->info.fields_present == 0) {
4855 return NT_STATUS_INVALID_PARAMETER;
4858 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4859 return NT_STATUS_ACCESS_DENIED;
4862 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4863 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4865 if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
4866 return NT_STATUS_WRONG_PASSWORD;
4870 copy_id25_to_sam_passwd(pwd, id25);
4872 /* write the change out */
4873 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4874 return status;
4878 * We need to "pdb_update_sam_account" before the unix primary group
4879 * is set, because the idealx scripts would also change the
4880 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4881 * the delete explicit / add explicit, which would then fail to find
4882 * the previous primaryGroupSid value.
4885 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4886 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4887 if ( !NT_STATUS_IS_OK(status) ) {
4888 return status;
4892 return NT_STATUS_OK;
4895 /*******************************************************************
4896 set_user_info_26
4897 ********************************************************************/
4899 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4900 const char *rhost,
4901 struct samr_UserInfo26 *id26,
4902 struct samu *pwd)
4904 NTSTATUS status;
4906 if (id26 == NULL) {
4907 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4908 return NT_STATUS_INVALID_PARAMETER;
4911 if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
4912 return NT_STATUS_WRONG_PASSWORD;
4915 copy_id26_to_sam_passwd(pwd, id26);
4917 status = pdb_update_sam_account(pwd);
4918 if (!NT_STATUS_IS_OK(status)) {
4919 return status;
4922 return NT_STATUS_OK;
4925 /*************************************************************
4926 **************************************************************/
4928 static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4930 uint32_t acc_required = 0;
4932 /* USER_ALL_USERNAME */
4933 if (fields & SAMR_FIELD_ACCOUNT_NAME)
4934 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4935 /* USER_ALL_FULLNAME */
4936 if (fields & SAMR_FIELD_FULL_NAME)
4937 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4938 /* USER_ALL_PRIMARYGROUPID */
4939 if (fields & SAMR_FIELD_PRIMARY_GID)
4940 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4941 /* USER_ALL_HOMEDIRECTORY */
4942 if (fields & SAMR_FIELD_HOME_DIRECTORY)
4943 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4944 /* USER_ALL_HOMEDIRECTORYDRIVE */
4945 if (fields & SAMR_FIELD_HOME_DRIVE)
4946 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4947 /* USER_ALL_SCRIPTPATH */
4948 if (fields & SAMR_FIELD_LOGON_SCRIPT)
4949 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4950 /* USER_ALL_PROFILEPATH */
4951 if (fields & SAMR_FIELD_PROFILE_PATH)
4952 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4953 /* USER_ALL_ADMINCOMMENT */
4954 if (fields & SAMR_FIELD_COMMENT)
4955 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4956 /* USER_ALL_WORKSTATIONS */
4957 if (fields & SAMR_FIELD_WORKSTATIONS)
4958 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4959 /* USER_ALL_LOGONHOURS */
4960 if (fields & SAMR_FIELD_LOGON_HOURS)
4961 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4962 /* USER_ALL_ACCOUNTEXPIRES */
4963 if (fields & SAMR_FIELD_ACCT_EXPIRY)
4964 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4965 /* USER_ALL_USERACCOUNTCONTROL */
4966 if (fields & SAMR_FIELD_ACCT_FLAGS)
4967 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4968 /* USER_ALL_PARAMETERS */
4969 if (fields & SAMR_FIELD_PARAMETERS)
4970 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4971 /* USER_ALL_USERCOMMENT */
4972 if (fields & SAMR_FIELD_COMMENT)
4973 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4974 /* USER_ALL_COUNTRYCODE */
4975 if (fields & SAMR_FIELD_COUNTRY_CODE)
4976 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4977 /* USER_ALL_CODEPAGE */
4978 if (fields & SAMR_FIELD_CODE_PAGE)
4979 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
4980 /* USER_ALL_NTPASSWORDPRESENT */
4981 if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
4982 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4983 /* USER_ALL_LMPASSWORDPRESENT */
4984 if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
4985 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4986 /* USER_ALL_PASSWORDEXPIRED */
4987 if (fields & SAMR_FIELD_EXPIRED_FLAG)
4988 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
4990 return acc_required;
4993 /*******************************************************************
4994 samr_SetUserInfo
4995 ********************************************************************/
4997 NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
4998 struct samr_SetUserInfo *r)
5000 struct samr_user_info *uinfo;
5001 NTSTATUS status;
5002 struct samu *pwd = NULL;
5003 union samr_UserInfo *info = r->in.info;
5004 uint32_t acc_required = 0;
5005 uint32_t fields = 0;
5006 bool ret;
5008 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
5010 /* This is tricky. A WinXP domain join sets
5011 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5012 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
5013 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5014 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
5015 we'll use the set from the WinXP join as the basis. */
5017 switch (r->in.level) {
5018 case 2: /* UserPreferencesInformation */
5019 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5020 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5021 break;
5022 case 4: /* UserLogonHoursInformation */
5023 case 6: /* UserNameInformation */
5024 case 7: /* UserAccountNameInformation */
5025 case 8: /* UserFullNameInformation */
5026 case 9: /* UserPrimaryGroupInformation */
5027 case 10: /* UserHomeInformation */
5028 case 11: /* UserScriptInformation */
5029 case 12: /* UserProfileInformation */
5030 case 13: /* UserAdminCommentInformation */
5031 case 14: /* UserWorkStationsInformation */
5032 case 16: /* UserControlInformation */
5033 case 17: /* UserExpiresInformation */
5034 case 20: /* UserParametersInformation */
5035 /* USER_WRITE_ACCOUNT */
5036 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5037 break;
5038 case 18: /* UserInternal1Information */
5039 /* FIXME: gd, this is a guess */
5040 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5041 break;
5042 case 21: /* UserAllInformation */
5043 fields = info->info21.fields_present;
5044 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5045 break;
5046 case 23: /* UserInternal4Information */
5047 fields = info->info23.info.fields_present;
5048 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5049 break;
5050 case 25: /* UserInternal4InformationNew */
5051 fields = info->info25.info.fields_present;
5052 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5053 break;
5054 case 24: /* UserInternal5Information */
5055 case 26: /* UserInternal5InformationNew */
5056 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5057 break;
5058 default:
5059 return NT_STATUS_INVALID_INFO_CLASS;
5062 uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5063 struct samr_user_info, &status);
5064 if (!NT_STATUS_IS_OK(status)) {
5065 return status;
5068 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5069 sid_string_dbg(&uinfo->sid), r->in.level));
5071 if (info == NULL) {
5072 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5073 return NT_STATUS_INVALID_INFO_CLASS;
5076 if (!(pwd = samu_new(NULL))) {
5077 return NT_STATUS_NO_MEMORY;
5080 become_root();
5081 ret = pdb_getsampwsid(pwd, &uinfo->sid);
5082 unbecome_root();
5084 if (!ret) {
5085 TALLOC_FREE(pwd);
5086 return NT_STATUS_NO_SUCH_USER;
5089 /* ================ BEGIN Privilege BLOCK ================ */
5091 become_root();
5093 /* ok! user info levels (lots: see MSDEV help), off we go... */
5095 switch (r->in.level) {
5097 case 2:
5098 status = set_user_info_2(p->mem_ctx,
5099 &info->info2, pwd);
5100 break;
5102 case 4:
5103 status = set_user_info_4(p->mem_ctx,
5104 &info->info4, pwd);
5105 break;
5107 case 6:
5108 status = set_user_info_6(p->mem_ctx,
5109 &info->info6, pwd);
5110 break;
5112 case 7:
5113 status = set_user_info_7(p->mem_ctx,
5114 &info->info7, pwd);
5115 break;
5117 case 8:
5118 status = set_user_info_8(p->mem_ctx,
5119 &info->info8, pwd);
5120 break;
5122 case 10:
5123 status = set_user_info_10(p->mem_ctx,
5124 &info->info10, pwd);
5125 break;
5127 case 11:
5128 status = set_user_info_11(p->mem_ctx,
5129 &info->info11, pwd);
5130 break;
5132 case 12:
5133 status = set_user_info_12(p->mem_ctx,
5134 &info->info12, pwd);
5135 break;
5137 case 13:
5138 status = set_user_info_13(p->mem_ctx,
5139 &info->info13, pwd);
5140 break;
5142 case 14:
5143 status = set_user_info_14(p->mem_ctx,
5144 &info->info14, pwd);
5145 break;
5147 case 16:
5148 status = set_user_info_16(p->mem_ctx,
5149 &info->info16, pwd);
5150 break;
5152 case 17:
5153 status = set_user_info_17(p->mem_ctx,
5154 &info->info17, pwd);
5155 break;
5157 case 18:
5158 /* Used by AS/U JRA. */
5159 status = set_user_info_18(&info->info18,
5160 p->mem_ctx,
5161 &p->session_info->session_key,
5162 pwd);
5163 break;
5165 case 20:
5166 status = set_user_info_20(p->mem_ctx,
5167 &info->info20, pwd);
5168 break;
5170 case 21:
5171 status = set_user_info_21(&info->info21,
5172 p->mem_ctx,
5173 &p->session_info->session_key,
5174 pwd);
5175 break;
5177 case 23:
5178 if (!p->session_info->session_key.length) {
5179 status = NT_STATUS_NO_USER_SESSION_KEY;
5181 arcfour_crypt_blob(info->info23.password.data, 516,
5182 &p->session_info->session_key);
5184 dump_data(100, info->info23.password.data, 516);
5186 status = set_user_info_23(p->mem_ctx,
5187 &info->info23,
5188 p->client_id->name,
5189 pwd);
5190 break;
5192 case 24:
5193 if (!p->session_info->session_key.length) {
5194 status = NT_STATUS_NO_USER_SESSION_KEY;
5196 arcfour_crypt_blob(info->info24.password.data,
5197 516,
5198 &p->session_info->session_key);
5200 dump_data(100, info->info24.password.data, 516);
5202 status = set_user_info_24(p->mem_ctx,
5203 p->client_id->name,
5204 &info->info24, pwd);
5205 break;
5207 case 25:
5208 if (!p->session_info->session_key.length) {
5209 status = NT_STATUS_NO_USER_SESSION_KEY;
5211 encode_or_decode_arc4_passwd_buffer(
5212 info->info25.password.data,
5213 &p->session_info->session_key);
5215 dump_data(100, info->info25.password.data, 532);
5217 status = set_user_info_25(p->mem_ctx,
5218 p->client_id->name,
5219 &info->info25, pwd);
5220 break;
5222 case 26:
5223 if (!p->session_info->session_key.length) {
5224 status = NT_STATUS_NO_USER_SESSION_KEY;
5226 encode_or_decode_arc4_passwd_buffer(
5227 info->info26.password.data,
5228 &p->session_info->session_key);
5230 dump_data(100, info->info26.password.data, 516);
5232 status = set_user_info_26(p->mem_ctx,
5233 p->client_id->name,
5234 &info->info26, pwd);
5235 break;
5237 default:
5238 status = NT_STATUS_INVALID_INFO_CLASS;
5241 TALLOC_FREE(pwd);
5243 unbecome_root();
5245 /* ================ END Privilege BLOCK ================ */
5247 if (NT_STATUS_IS_OK(status)) {
5248 force_flush_samr_cache(&uinfo->sid);
5251 return status;
5254 /*******************************************************************
5255 _samr_SetUserInfo2
5256 ********************************************************************/
5258 NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
5259 struct samr_SetUserInfo2 *r)
5261 struct samr_SetUserInfo q;
5263 q.in.user_handle = r->in.user_handle;
5264 q.in.level = r->in.level;
5265 q.in.info = r->in.info;
5267 return _samr_SetUserInfo(p, &q);
5270 /*********************************************************************
5271 _samr_GetAliasMembership
5272 *********************************************************************/
5274 NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
5275 struct samr_GetAliasMembership *r)
5277 size_t num_alias_rids;
5278 uint32 *alias_rids;
5279 struct samr_domain_info *dinfo;
5280 size_t i;
5282 NTSTATUS status;
5284 struct dom_sid *members;
5286 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5288 dinfo = policy_handle_find(p, r->in.domain_handle,
5289 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5290 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5291 struct samr_domain_info, &status);
5292 if (!NT_STATUS_IS_OK(status)) {
5293 return status;
5296 if (!sid_check_is_domain(&dinfo->sid) &&
5297 !sid_check_is_builtin(&dinfo->sid))
5298 return NT_STATUS_OBJECT_TYPE_MISMATCH;
5300 if (r->in.sids->num_sids) {
5301 members = talloc_array(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
5303 if (members == NULL)
5304 return NT_STATUS_NO_MEMORY;
5305 } else {
5306 members = NULL;
5309 for (i=0; i<r->in.sids->num_sids; i++)
5310 sid_copy(&members[i], r->in.sids->sids[i].sid);
5312 alias_rids = NULL;
5313 num_alias_rids = 0;
5315 become_root();
5316 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5317 r->in.sids->num_sids,
5318 &alias_rids, &num_alias_rids);
5319 unbecome_root();
5321 if (!NT_STATUS_IS_OK(status)) {
5322 return status;
5325 r->out.rids->count = num_alias_rids;
5326 r->out.rids->ids = alias_rids;
5328 if (r->out.rids->ids == NULL) {
5329 /* Windows domain clients don't accept a NULL ptr here */
5330 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5332 if (r->out.rids->ids == NULL) {
5333 return NT_STATUS_NO_MEMORY;
5336 return NT_STATUS_OK;
5339 /*********************************************************************
5340 _samr_GetMembersInAlias
5341 *********************************************************************/
5343 NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
5344 struct samr_GetMembersInAlias *r)
5346 struct samr_alias_info *ainfo;
5347 NTSTATUS status;
5348 size_t i;
5349 size_t num_sids = 0;
5350 struct lsa_SidPtr *sids = NULL;
5351 struct dom_sid *pdb_sids = NULL;
5353 ainfo = policy_handle_find(p, r->in.alias_handle,
5354 SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5355 struct samr_alias_info, &status);
5356 if (!NT_STATUS_IS_OK(status)) {
5357 return status;
5360 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5362 become_root();
5363 status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5364 &num_sids);
5365 unbecome_root();
5367 if (!NT_STATUS_IS_OK(status)) {
5368 return status;
5371 if (num_sids) {
5372 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5373 if (sids == NULL) {
5374 TALLOC_FREE(pdb_sids);
5375 return NT_STATUS_NO_MEMORY;
5379 for (i = 0; i < num_sids; i++) {
5380 sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
5381 if (!sids[i].sid) {
5382 TALLOC_FREE(pdb_sids);
5383 return NT_STATUS_NO_MEMORY;
5387 r->out.sids->num_sids = num_sids;
5388 r->out.sids->sids = sids;
5390 TALLOC_FREE(pdb_sids);
5392 return NT_STATUS_OK;
5395 /*********************************************************************
5396 _samr_QueryGroupMember
5397 *********************************************************************/
5399 NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
5400 struct samr_QueryGroupMember *r)
5402 struct samr_group_info *ginfo;
5403 size_t i, num_members;
5405 uint32 *rid=NULL;
5406 uint32 *attr=NULL;
5408 NTSTATUS status;
5409 struct samr_RidAttrArray *rids = NULL;
5411 ginfo = policy_handle_find(p, r->in.group_handle,
5412 SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5413 struct samr_group_info, &status);
5414 if (!NT_STATUS_IS_OK(status)) {
5415 return status;
5418 rids = talloc_zero(p->mem_ctx, struct samr_RidAttrArray);
5419 if (!rids) {
5420 return NT_STATUS_NO_MEMORY;
5423 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5425 if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5426 DEBUG(3, ("sid %s is not in our domain\n",
5427 sid_string_dbg(&ginfo->sid)));
5428 return NT_STATUS_NO_SUCH_GROUP;
5431 DEBUG(10, ("lookup on Domain SID\n"));
5433 become_root();
5434 status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5435 &rid, &num_members);
5436 unbecome_root();
5438 if (!NT_STATUS_IS_OK(status))
5439 return status;
5441 if (num_members) {
5442 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5443 if (attr == NULL) {
5444 return NT_STATUS_NO_MEMORY;
5446 } else {
5447 attr = NULL;
5450 for (i=0; i<num_members; i++) {
5451 attr[i] = SE_GROUP_MANDATORY |
5452 SE_GROUP_ENABLED_BY_DEFAULT |
5453 SE_GROUP_ENABLED;
5456 rids->count = num_members;
5457 rids->attributes = attr;
5458 rids->rids = rid;
5460 *r->out.rids = rids;
5462 return NT_STATUS_OK;
5465 /*********************************************************************
5466 _samr_AddAliasMember
5467 *********************************************************************/
5469 NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
5470 struct samr_AddAliasMember *r)
5472 struct samr_alias_info *ainfo;
5473 NTSTATUS status;
5475 ainfo = policy_handle_find(p, r->in.alias_handle,
5476 SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5477 struct samr_alias_info, &status);
5478 if (!NT_STATUS_IS_OK(status)) {
5479 return status;
5482 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5484 /******** BEGIN SeAddUsers BLOCK *********/
5486 become_root();
5487 status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5488 unbecome_root();
5490 /******** END SeAddUsers BLOCK *********/
5492 if (NT_STATUS_IS_OK(status)) {
5493 force_flush_samr_cache(&ainfo->sid);
5496 return status;
5499 /*********************************************************************
5500 _samr_DeleteAliasMember
5501 *********************************************************************/
5503 NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
5504 struct samr_DeleteAliasMember *r)
5506 struct samr_alias_info *ainfo;
5507 NTSTATUS status;
5509 ainfo = policy_handle_find(p, r->in.alias_handle,
5510 SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5511 struct samr_alias_info, &status);
5512 if (!NT_STATUS_IS_OK(status)) {
5513 return status;
5516 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5517 sid_string_dbg(&ainfo->sid)));
5519 /******** BEGIN SeAddUsers BLOCK *********/
5521 become_root();
5522 status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5523 unbecome_root();
5525 /******** END SeAddUsers BLOCK *********/
5527 if (NT_STATUS_IS_OK(status)) {
5528 force_flush_samr_cache(&ainfo->sid);
5531 return status;
5534 /*********************************************************************
5535 _samr_AddGroupMember
5536 *********************************************************************/
5538 NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
5539 struct samr_AddGroupMember *r)
5541 struct samr_group_info *ginfo;
5542 NTSTATUS status;
5543 uint32 group_rid;
5545 ginfo = policy_handle_find(p, r->in.group_handle,
5546 SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5547 struct samr_group_info, &status);
5548 if (!NT_STATUS_IS_OK(status)) {
5549 return status;
5552 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5554 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5555 &group_rid)) {
5556 return NT_STATUS_INVALID_HANDLE;
5559 /******** BEGIN SeAddUsers BLOCK *********/
5561 become_root();
5562 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5563 unbecome_root();
5565 /******** END SeAddUsers BLOCK *********/
5567 force_flush_samr_cache(&ginfo->sid);
5569 return status;
5572 /*********************************************************************
5573 _samr_DeleteGroupMember
5574 *********************************************************************/
5576 NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
5577 struct samr_DeleteGroupMember *r)
5580 struct samr_group_info *ginfo;
5581 NTSTATUS status;
5582 uint32 group_rid;
5585 * delete the group member named r->in.rid
5586 * who is a member of the sid associated with the handle
5587 * the rid is a user's rid as the group is a domain group.
5590 ginfo = policy_handle_find(p, r->in.group_handle,
5591 SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5592 struct samr_group_info, &status);
5593 if (!NT_STATUS_IS_OK(status)) {
5594 return status;
5597 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5598 &group_rid)) {
5599 return NT_STATUS_INVALID_HANDLE;
5602 /******** BEGIN SeAddUsers BLOCK *********/
5604 become_root();
5605 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5606 unbecome_root();
5608 /******** END SeAddUsers BLOCK *********/
5610 force_flush_samr_cache(&ginfo->sid);
5612 return status;
5615 /*********************************************************************
5616 _samr_DeleteUser
5617 *********************************************************************/
5619 NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
5620 struct samr_DeleteUser *r)
5622 struct samr_user_info *uinfo;
5623 NTSTATUS status;
5624 struct samu *sam_pass=NULL;
5625 bool ret;
5627 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5629 uinfo = policy_handle_find(p, r->in.user_handle,
5630 SEC_STD_DELETE, NULL,
5631 struct samr_user_info, &status);
5632 if (!NT_STATUS_IS_OK(status)) {
5633 return status;
5636 if (!sid_check_is_in_our_domain(&uinfo->sid))
5637 return NT_STATUS_CANNOT_DELETE;
5639 /* check if the user exists before trying to delete */
5640 if ( !(sam_pass = samu_new( NULL )) ) {
5641 return NT_STATUS_NO_MEMORY;
5644 become_root();
5645 ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5646 unbecome_root();
5648 if(!ret) {
5649 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5650 sid_string_dbg(&uinfo->sid)));
5651 TALLOC_FREE(sam_pass);
5652 return NT_STATUS_NO_SUCH_USER;
5655 /******** BEGIN SeAddUsers BLOCK *********/
5657 become_root();
5658 status = pdb_delete_user(p->mem_ctx, sam_pass);
5659 unbecome_root();
5661 /******** END SeAddUsers BLOCK *********/
5663 if ( !NT_STATUS_IS_OK(status) ) {
5664 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5665 "user %s: %s.\n", pdb_get_username(sam_pass),
5666 nt_errstr(status)));
5667 TALLOC_FREE(sam_pass);
5668 return status;
5672 TALLOC_FREE(sam_pass);
5674 force_flush_samr_cache(&uinfo->sid);
5676 if (!close_policy_hnd(p, r->in.user_handle))
5677 return NT_STATUS_OBJECT_NAME_INVALID;
5679 ZERO_STRUCTP(r->out.user_handle);
5681 return NT_STATUS_OK;
5684 /*********************************************************************
5685 _samr_DeleteDomainGroup
5686 *********************************************************************/
5688 NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
5689 struct samr_DeleteDomainGroup *r)
5691 struct samr_group_info *ginfo;
5692 NTSTATUS status;
5693 uint32 group_rid;
5695 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5697 ginfo = policy_handle_find(p, r->in.group_handle,
5698 SEC_STD_DELETE, NULL,
5699 struct samr_group_info, &status);
5700 if (!NT_STATUS_IS_OK(status)) {
5701 return status;
5704 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5706 if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5707 &group_rid)) {
5708 return NT_STATUS_NO_SUCH_GROUP;
5711 /******** BEGIN SeAddUsers BLOCK *********/
5713 become_root();
5714 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5715 unbecome_root();
5717 /******** END SeAddUsers BLOCK *********/
5719 if ( !NT_STATUS_IS_OK(status) ) {
5720 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5721 "entry for group %s: %s\n",
5722 sid_string_dbg(&ginfo->sid),
5723 nt_errstr(status)));
5724 return status;
5727 force_flush_samr_cache(&ginfo->sid);
5729 if (!close_policy_hnd(p, r->in.group_handle))
5730 return NT_STATUS_OBJECT_NAME_INVALID;
5732 return NT_STATUS_OK;
5735 /*********************************************************************
5736 _samr_DeleteDomAlias
5737 *********************************************************************/
5739 NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
5740 struct samr_DeleteDomAlias *r)
5742 struct samr_alias_info *ainfo;
5743 NTSTATUS status;
5745 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5747 ainfo = policy_handle_find(p, r->in.alias_handle,
5748 SEC_STD_DELETE, NULL,
5749 struct samr_alias_info, &status);
5750 if (!NT_STATUS_IS_OK(status)) {
5751 return status;
5754 DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5756 /* Don't let Windows delete builtin groups */
5758 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5759 return NT_STATUS_SPECIAL_ACCOUNT;
5762 if (!sid_check_is_in_our_domain(&ainfo->sid))
5763 return NT_STATUS_NO_SUCH_ALIAS;
5765 DEBUG(10, ("lookup on Local SID\n"));
5767 /******** BEGIN SeAddUsers BLOCK *********/
5769 become_root();
5770 /* Have passdb delete the alias */
5771 status = pdb_delete_alias(&ainfo->sid);
5772 unbecome_root();
5774 /******** END SeAddUsers BLOCK *********/
5776 if ( !NT_STATUS_IS_OK(status))
5777 return status;
5779 force_flush_samr_cache(&ainfo->sid);
5781 if (!close_policy_hnd(p, r->in.alias_handle))
5782 return NT_STATUS_OBJECT_NAME_INVALID;
5784 return NT_STATUS_OK;
5787 /*********************************************************************
5788 _samr_CreateDomainGroup
5789 *********************************************************************/
5791 NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
5792 struct samr_CreateDomainGroup *r)
5795 NTSTATUS status;
5796 const char *name;
5797 struct samr_domain_info *dinfo;
5798 struct samr_group_info *ginfo;
5800 dinfo = policy_handle_find(p, r->in.domain_handle,
5801 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5802 struct samr_domain_info, &status);
5803 if (!NT_STATUS_IS_OK(status)) {
5804 return status;
5807 if (!sid_check_is_domain(&dinfo->sid)) {
5808 return NT_STATUS_ACCESS_DENIED;
5811 name = r->in.name->string;
5812 if (name == NULL) {
5813 return NT_STATUS_NO_MEMORY;
5816 status = can_create(p->mem_ctx, name);
5817 if (!NT_STATUS_IS_OK(status)) {
5818 return status;
5821 /******** BEGIN SeAddUsers BLOCK *********/
5823 become_root();
5824 /* check that we successfully create the UNIX group */
5825 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5826 unbecome_root();
5828 /******** END SeAddUsers BLOCK *********/
5830 /* check if we should bail out here */
5832 if ( !NT_STATUS_IS_OK(status) )
5833 return status;
5835 ginfo = policy_handle_create(p, r->out.group_handle,
5836 GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5837 struct samr_group_info, &status);
5838 if (!NT_STATUS_IS_OK(status)) {
5839 return status;
5841 sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5843 force_flush_samr_cache(&dinfo->sid);
5845 return NT_STATUS_OK;
5848 /*********************************************************************
5849 _samr_CreateDomAlias
5850 *********************************************************************/
5852 NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
5853 struct samr_CreateDomAlias *r)
5855 struct dom_sid info_sid;
5856 const char *name = NULL;
5857 struct samr_domain_info *dinfo;
5858 struct samr_alias_info *ainfo;
5859 gid_t gid;
5860 NTSTATUS result;
5862 dinfo = policy_handle_find(p, r->in.domain_handle,
5863 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5864 struct samr_domain_info, &result);
5865 if (!NT_STATUS_IS_OK(result)) {
5866 return result;
5869 if (!sid_check_is_domain(&dinfo->sid)) {
5870 return NT_STATUS_ACCESS_DENIED;
5873 name = r->in.alias_name->string;
5875 result = can_create(p->mem_ctx, name);
5876 if (!NT_STATUS_IS_OK(result)) {
5877 return result;
5880 /******** BEGIN SeAddUsers BLOCK *********/
5882 become_root();
5883 /* Have passdb create the alias */
5884 result = pdb_create_alias(name, r->out.rid);
5885 unbecome_root();
5887 /******** END SeAddUsers BLOCK *********/
5889 if (!NT_STATUS_IS_OK(result)) {
5890 DEBUG(10, ("pdb_create_alias failed: %s\n",
5891 nt_errstr(result)));
5892 return result;
5895 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5897 if (!sid_to_gid(&info_sid, &gid)) {
5898 DEBUG(10, ("Could not find alias just created\n"));
5899 return NT_STATUS_ACCESS_DENIED;
5902 /* check if the group has been successfully created */
5903 if ( getgrgid(gid) == NULL ) {
5904 DEBUG(1, ("getgrgid(%u) of just created alias failed\n",
5905 (unsigned int)gid));
5906 return NT_STATUS_ACCESS_DENIED;
5909 ainfo = policy_handle_create(p, r->out.alias_handle,
5910 GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5911 struct samr_alias_info, &result);
5912 if (!NT_STATUS_IS_OK(result)) {
5913 return result;
5915 ainfo->sid = info_sid;
5917 force_flush_samr_cache(&info_sid);
5919 return NT_STATUS_OK;
5922 /*********************************************************************
5923 _samr_QueryGroupInfo
5924 *********************************************************************/
5926 NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
5927 struct samr_QueryGroupInfo *r)
5929 struct samr_group_info *ginfo;
5930 NTSTATUS status;
5931 GROUP_MAP map;
5932 union samr_GroupInfo *info = NULL;
5933 bool ret;
5934 uint32_t attributes = SE_GROUP_MANDATORY |
5935 SE_GROUP_ENABLED_BY_DEFAULT |
5936 SE_GROUP_ENABLED;
5937 const char *group_name = NULL;
5938 const char *group_description = NULL;
5940 ginfo = policy_handle_find(p, r->in.group_handle,
5941 SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5942 struct samr_group_info, &status);
5943 if (!NT_STATUS_IS_OK(status)) {
5944 return status;
5947 become_root();
5948 ret = get_domain_group_from_sid(ginfo->sid, &map);
5949 unbecome_root();
5950 if (!ret)
5951 return NT_STATUS_INVALID_HANDLE;
5953 /* FIXME: map contains fstrings */
5954 group_name = talloc_strdup(r, map.nt_name);
5955 group_description = talloc_strdup(r, map.comment);
5957 info = talloc_zero(p->mem_ctx, union samr_GroupInfo);
5958 if (!info) {
5959 return NT_STATUS_NO_MEMORY;
5962 switch (r->in.level) {
5963 case 1: {
5964 uint32 *members;
5965 size_t num_members;
5967 become_root();
5968 status = pdb_enum_group_members(
5969 p->mem_ctx, &ginfo->sid, &members,
5970 &num_members);
5971 unbecome_root();
5973 if (!NT_STATUS_IS_OK(status)) {
5974 return status;
5977 info->all.name.string = group_name;
5978 info->all.attributes = attributes;
5979 info->all.num_members = num_members;
5980 info->all.description.string = group_description;
5981 break;
5983 case 2:
5984 info->name.string = group_name;
5985 break;
5986 case 3:
5987 info->attributes.attributes = attributes;
5988 break;
5989 case 4:
5990 info->description.string = group_description;
5991 break;
5992 case 5: {
5994 uint32 *members;
5995 size_t num_members;
5999 become_root();
6000 status = pdb_enum_group_members(
6001 p->mem_ctx, &ginfo->sid, &members,
6002 &num_members);
6003 unbecome_root();
6005 if (!NT_STATUS_IS_OK(status)) {
6006 return status;
6009 info->all2.name.string = group_name;
6010 info->all2.attributes = attributes;
6011 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
6012 info->all2.description.string = group_description;
6014 break;
6016 default:
6017 return NT_STATUS_INVALID_INFO_CLASS;
6020 *r->out.info = info;
6022 return NT_STATUS_OK;
6025 /*********************************************************************
6026 _samr_SetGroupInfo
6027 *********************************************************************/
6029 NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
6030 struct samr_SetGroupInfo *r)
6032 struct samr_group_info *ginfo;
6033 GROUP_MAP map;
6034 NTSTATUS status;
6035 bool ret;
6037 ginfo = policy_handle_find(p, r->in.group_handle,
6038 SAMR_GROUP_ACCESS_SET_INFO, NULL,
6039 struct samr_group_info, &status);
6040 if (!NT_STATUS_IS_OK(status)) {
6041 return status;
6044 become_root();
6045 ret = get_domain_group_from_sid(ginfo->sid, &map);
6046 unbecome_root();
6047 if (!ret)
6048 return NT_STATUS_NO_SUCH_GROUP;
6050 switch (r->in.level) {
6051 case 2:
6052 fstrcpy(map.nt_name, r->in.info->name.string);
6053 break;
6054 case 3:
6055 break;
6056 case 4:
6057 fstrcpy(map.comment, r->in.info->description.string);
6058 break;
6059 default:
6060 return NT_STATUS_INVALID_INFO_CLASS;
6063 /******** BEGIN SeAddUsers BLOCK *********/
6065 become_root();
6066 status = pdb_update_group_mapping_entry(&map);
6067 unbecome_root();
6069 /******** End SeAddUsers BLOCK *********/
6071 if (NT_STATUS_IS_OK(status)) {
6072 force_flush_samr_cache(&ginfo->sid);
6075 return status;
6078 /*********************************************************************
6079 _samr_SetAliasInfo
6080 *********************************************************************/
6082 NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
6083 struct samr_SetAliasInfo *r)
6085 struct samr_alias_info *ainfo;
6086 struct acct_info info;
6087 NTSTATUS status;
6089 ainfo = policy_handle_find(p, r->in.alias_handle,
6090 SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6091 struct samr_alias_info, &status);
6092 if (!NT_STATUS_IS_OK(status)) {
6093 return status;
6096 /* get the current group information */
6098 become_root();
6099 status = pdb_get_aliasinfo( &ainfo->sid, &info );
6100 unbecome_root();
6102 if ( !NT_STATUS_IS_OK(status))
6103 return status;
6105 switch (r->in.level) {
6106 case ALIASINFONAME:
6108 fstring group_name;
6110 /* We currently do not support renaming groups in the
6111 the BUILTIN domain. Refer to util_builtin.c to understand
6112 why. The eventually needs to be fixed to be like Windows
6113 where you can rename builtin groups, just not delete them */
6115 if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6116 return NT_STATUS_SPECIAL_ACCOUNT;
6119 /* There has to be a valid name (and it has to be different) */
6121 if ( !r->in.info->name.string )
6122 return NT_STATUS_INVALID_PARAMETER;
6124 /* If the name is the same just reply "ok". Yes this
6125 doesn't allow you to change the case of a group name. */
6127 if ( strequal( r->in.info->name.string, info.acct_name ) )
6128 return NT_STATUS_OK;
6130 fstrcpy( info.acct_name, r->in.info->name.string);
6132 /* make sure the name doesn't already exist as a user
6133 or local group */
6135 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6136 status = can_create( p->mem_ctx, group_name );
6137 if ( !NT_STATUS_IS_OK( status ) )
6138 return status;
6139 break;
6141 case ALIASINFODESCRIPTION:
6142 if (r->in.info->description.string) {
6143 fstrcpy(info.acct_desc,
6144 r->in.info->description.string);
6145 } else {
6146 fstrcpy( info.acct_desc, "" );
6148 break;
6149 default:
6150 return NT_STATUS_INVALID_INFO_CLASS;
6153 /******** BEGIN SeAddUsers BLOCK *********/
6155 become_root();
6156 status = pdb_set_aliasinfo( &ainfo->sid, &info );
6157 unbecome_root();
6159 /******** End SeAddUsers BLOCK *********/
6161 if (NT_STATUS_IS_OK(status))
6162 force_flush_samr_cache(&ainfo->sid);
6164 return status;
6167 /****************************************************************
6168 _samr_GetDomPwInfo
6169 ****************************************************************/
6171 NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
6172 struct samr_GetDomPwInfo *r)
6174 uint32_t min_password_length = 0;
6175 uint32_t password_properties = 0;
6177 /* Perform access check. Since this rpc does not require a
6178 policy handle it will not be caught by the access checks on
6179 SAMR_CONNECT or SAMR_CONNECT_ANON. */
6181 if (!pipe_access_check(p)) {
6182 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6183 return NT_STATUS_ACCESS_DENIED;
6186 become_root();
6187 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6188 &min_password_length);
6189 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6190 &password_properties);
6191 unbecome_root();
6193 if (lp_check_password_script() && *lp_check_password_script()) {
6194 password_properties |= DOMAIN_PASSWORD_COMPLEX;
6197 r->out.info->min_password_length = min_password_length;
6198 r->out.info->password_properties = password_properties;
6200 return NT_STATUS_OK;
6203 /*********************************************************************
6204 _samr_OpenGroup
6205 *********************************************************************/
6207 NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
6208 struct samr_OpenGroup *r)
6211 struct dom_sid info_sid;
6212 GROUP_MAP map;
6213 struct samr_domain_info *dinfo;
6214 struct samr_group_info *ginfo;
6215 struct security_descriptor *psd = NULL;
6216 uint32 acc_granted;
6217 uint32 des_access = r->in.access_mask;
6218 size_t sd_size;
6219 NTSTATUS status;
6220 bool ret;
6222 dinfo = policy_handle_find(p, r->in.domain_handle,
6223 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6224 struct samr_domain_info, &status);
6225 if (!NT_STATUS_IS_OK(status)) {
6226 return status;
6229 /*check if access can be granted as requested by client. */
6230 map_max_allowed_access(p->session_info->security_token,
6231 &p->session_info->utok,
6232 &des_access);
6234 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6235 se_map_generic(&des_access,&grp_generic_mapping);
6237 status = access_check_object(psd, p->session_info->security_token,
6238 SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6239 des_access, &acc_granted, "_samr_OpenGroup");
6241 if ( !NT_STATUS_IS_OK(status) )
6242 return status;
6244 /* this should not be hard-coded like this */
6246 if (!sid_check_is_domain(&dinfo->sid)) {
6247 return NT_STATUS_ACCESS_DENIED;
6250 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6252 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6253 sid_string_dbg(&info_sid)));
6255 /* check if that group really exists */
6256 become_root();
6257 ret = get_domain_group_from_sid(info_sid, &map);
6258 unbecome_root();
6259 if (!ret)
6260 return NT_STATUS_NO_SUCH_GROUP;
6262 ginfo = policy_handle_create(p, r->out.group_handle,
6263 acc_granted,
6264 struct samr_group_info, &status);
6265 if (!NT_STATUS_IS_OK(status)) {
6266 return status;
6268 ginfo->sid = info_sid;
6270 return NT_STATUS_OK;
6273 /*********************************************************************
6274 _samr_RemoveMemberFromForeignDomain
6275 *********************************************************************/
6277 NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
6278 struct samr_RemoveMemberFromForeignDomain *r)
6280 struct samr_domain_info *dinfo;
6281 NTSTATUS result;
6283 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6284 sid_string_dbg(r->in.sid)));
6286 /* Find the policy handle. Open a policy on it. */
6288 dinfo = policy_handle_find(p, r->in.domain_handle,
6289 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6290 struct samr_domain_info, &result);
6291 if (!NT_STATUS_IS_OK(result)) {
6292 return result;
6295 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6296 sid_string_dbg(&dinfo->sid)));
6298 /* we can only delete a user from a group since we don't have
6299 nested groups anyways. So in the latter case, just say OK */
6301 /* TODO: The above comment nowadays is bogus. Since we have nested
6302 * groups now, and aliases members are never reported out of the unix
6303 * group membership, the "just say OK" makes this call a no-op. For
6304 * us. This needs fixing however. */
6306 /* I've only ever seen this in the wild when deleting a user from
6307 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6308 * is the user about to be deleted. I very much suspect this is the
6309 * only application of this call. To verify this, let people report
6310 * other cases. */
6312 if (!sid_check_is_builtin(&dinfo->sid)) {
6313 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6314 "global_sam_sid() = %s\n",
6315 sid_string_dbg(&dinfo->sid),
6316 sid_string_dbg(get_global_sam_sid())));
6317 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6318 return NT_STATUS_OK;
6321 force_flush_samr_cache(&dinfo->sid);
6323 result = NT_STATUS_OK;
6325 return result;
6328 /*******************************************************************
6329 _samr_QueryDomainInfo2
6330 ********************************************************************/
6332 NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
6333 struct samr_QueryDomainInfo2 *r)
6335 struct samr_QueryDomainInfo q;
6337 q.in.domain_handle = r->in.domain_handle;
6338 q.in.level = r->in.level;
6340 q.out.info = r->out.info;
6342 return _samr_QueryDomainInfo(p, &q);
6345 /*******************************************************************
6346 ********************************************************************/
6348 static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6349 struct samr_DomInfo1 *r)
6351 time_t u_expire, u_min_age;
6353 u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6354 u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6356 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6357 (uint32_t)r->min_password_length);
6358 pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6359 (uint32_t)r->password_history_length);
6360 pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6361 (uint32_t)r->password_properties);
6362 pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6363 pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6365 return NT_STATUS_OK;
6368 /*******************************************************************
6369 ********************************************************************/
6371 static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6372 struct samr_DomInfo3 *r)
6374 time_t u_logout;
6376 u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6378 pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6380 return NT_STATUS_OK;
6383 /*******************************************************************
6384 ********************************************************************/
6386 static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6387 struct samr_DomInfo12 *r)
6389 time_t u_lock_duration, u_reset_time;
6391 u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6392 if (u_lock_duration != -1) {
6393 u_lock_duration /= 60;
6396 u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6398 pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6399 pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6400 pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6401 (uint32_t)r->lockout_threshold);
6403 return NT_STATUS_OK;
6406 /*******************************************************************
6407 _samr_SetDomainInfo
6408 ********************************************************************/
6410 NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
6411 struct samr_SetDomainInfo *r)
6413 struct samr_domain_info *dinfo;
6414 NTSTATUS status;
6415 uint32_t acc_required = 0;
6417 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6419 switch (r->in.level) {
6420 case 1: /* DomainPasswordInformation */
6421 case 12: /* DomainLockoutInformation */
6422 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6423 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6424 break;
6425 case 3: /* DomainLogoffInformation */
6426 case 4: /* DomainOemInformation */
6427 /* DOMAIN_WRITE_OTHER_PARAMETERS */
6428 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6429 break;
6430 case 6: /* DomainReplicationInformation */
6431 case 9: /* DomainStateInformation */
6432 case 7: /* DomainServerRoleInformation */
6433 /* DOMAIN_ADMINISTER_SERVER */
6434 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6435 break;
6436 default:
6437 return NT_STATUS_INVALID_INFO_CLASS;
6440 dinfo = policy_handle_find(p, r->in.domain_handle,
6441 acc_required, NULL,
6442 struct samr_domain_info, &status);
6443 if (!NT_STATUS_IS_OK(status)) {
6444 return status;
6447 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6449 switch (r->in.level) {
6450 case 1:
6451 status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6452 break;
6453 case 3:
6454 status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6455 break;
6456 case 4:
6457 break;
6458 case 6:
6459 break;
6460 case 7:
6461 break;
6462 case 9:
6463 break;
6464 case 12:
6465 status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6466 break;
6467 default:
6468 return NT_STATUS_INVALID_INFO_CLASS;
6471 if (!NT_STATUS_IS_OK(status)) {
6472 return status;
6475 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6477 return NT_STATUS_OK;
6480 /****************************************************************
6481 _samr_GetDisplayEnumerationIndex
6482 ****************************************************************/
6484 NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
6485 struct samr_GetDisplayEnumerationIndex *r)
6487 struct samr_domain_info *dinfo;
6488 uint32_t max_entries = (uint32_t) -1;
6489 uint32_t enum_context = 0;
6490 int i;
6491 uint32_t num_account = 0;
6492 struct samr_displayentry *entries = NULL;
6493 NTSTATUS status;
6495 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6497 dinfo = policy_handle_find(p, r->in.domain_handle,
6498 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6499 struct samr_domain_info, &status);
6500 if (!NT_STATUS_IS_OK(status)) {
6501 return status;
6504 if ((r->in.level < 1) || (r->in.level > 3)) {
6505 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6506 "Unknown info level (%u)\n",
6507 r->in.level));
6508 return NT_STATUS_INVALID_INFO_CLASS;
6511 become_root();
6513 /* The following done as ROOT. Don't return without unbecome_root(). */
6515 switch (r->in.level) {
6516 case 1:
6517 if (dinfo->disp_info->users == NULL) {
6518 dinfo->disp_info->users = pdb_search_users(
6519 dinfo->disp_info, ACB_NORMAL);
6520 if (dinfo->disp_info->users == NULL) {
6521 unbecome_root();
6522 return NT_STATUS_ACCESS_DENIED;
6524 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6525 "starting user enumeration at index %u\n",
6526 (unsigned int)enum_context));
6527 } else {
6528 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6529 "using cached user enumeration at index %u\n",
6530 (unsigned int)enum_context));
6532 num_account = pdb_search_entries(dinfo->disp_info->users,
6533 enum_context, max_entries,
6534 &entries);
6535 break;
6536 case 2:
6537 if (dinfo->disp_info->machines == NULL) {
6538 dinfo->disp_info->machines = pdb_search_users(
6539 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6540 if (dinfo->disp_info->machines == NULL) {
6541 unbecome_root();
6542 return NT_STATUS_ACCESS_DENIED;
6544 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6545 "starting machine enumeration at index %u\n",
6546 (unsigned int)enum_context));
6547 } else {
6548 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6549 "using cached machine enumeration at index %u\n",
6550 (unsigned int)enum_context));
6552 num_account = pdb_search_entries(dinfo->disp_info->machines,
6553 enum_context, max_entries,
6554 &entries);
6555 break;
6556 case 3:
6557 if (dinfo->disp_info->groups == NULL) {
6558 dinfo->disp_info->groups = pdb_search_groups(
6559 dinfo->disp_info);
6560 if (dinfo->disp_info->groups == NULL) {
6561 unbecome_root();
6562 return NT_STATUS_ACCESS_DENIED;
6564 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6565 "starting group enumeration at index %u\n",
6566 (unsigned int)enum_context));
6567 } else {
6568 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6569 "using cached group enumeration at index %u\n",
6570 (unsigned int)enum_context));
6572 num_account = pdb_search_entries(dinfo->disp_info->groups,
6573 enum_context, max_entries,
6574 &entries);
6575 break;
6576 default:
6577 unbecome_root();
6578 smb_panic("info class changed");
6579 break;
6582 unbecome_root();
6584 /* Ensure we cache this enumeration. */
6585 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6587 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6588 r->in.name->string));
6590 for (i=0; i<num_account; i++) {
6591 if (strequal(entries[i].account_name, r->in.name->string)) {
6592 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6593 "found %s at idx %d\n",
6594 r->in.name->string, i));
6595 *r->out.idx = i;
6596 return NT_STATUS_OK;
6600 /* assuming account_name lives at the very end */
6601 *r->out.idx = num_account;
6603 return NT_STATUS_NO_MORE_ENTRIES;
6606 /****************************************************************
6607 _samr_GetDisplayEnumerationIndex2
6608 ****************************************************************/
6610 NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
6611 struct samr_GetDisplayEnumerationIndex2 *r)
6613 struct samr_GetDisplayEnumerationIndex q;
6615 q.in.domain_handle = r->in.domain_handle;
6616 q.in.level = r->in.level;
6617 q.in.name = r->in.name;
6619 q.out.idx = r->out.idx;
6621 return _samr_GetDisplayEnumerationIndex(p, &q);
6624 /****************************************************************
6625 _samr_RidToSid
6626 ****************************************************************/
6628 NTSTATUS _samr_RidToSid(struct pipes_struct *p,
6629 struct samr_RidToSid *r)
6631 struct samr_domain_info *dinfo;
6632 NTSTATUS status;
6633 struct dom_sid sid;
6635 dinfo = policy_handle_find(p, r->in.domain_handle,
6636 0, NULL,
6637 struct samr_domain_info, &status);
6638 if (!NT_STATUS_IS_OK(status)) {
6639 return status;
6642 if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6643 return NT_STATUS_NO_MEMORY;
6646 *r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
6647 if (!*r->out.sid) {
6648 return NT_STATUS_NO_MEMORY;
6651 return NT_STATUS_OK;
6654 /****************************************************************
6655 ****************************************************************/
6657 static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
6658 const struct samr_PwInfo *dom_pw_info,
6659 const struct samr_ValidatePasswordReq2 *req,
6660 struct samr_ValidatePasswordRepCtr *rep)
6662 NTSTATUS status;
6664 if (req->password.string == NULL) {
6665 return SAMR_VALIDATION_STATUS_SUCCESS;
6667 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6668 ZERO_STRUCT(rep->info);
6669 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6671 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6672 status = check_password_complexity(req->account.string,
6673 req->password.string,
6674 NULL);
6675 if (!NT_STATUS_IS_OK(status)) {
6676 ZERO_STRUCT(rep->info);
6677 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6681 return SAMR_VALIDATION_STATUS_SUCCESS;
6684 /****************************************************************
6685 ****************************************************************/
6687 static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
6688 const struct samr_PwInfo *dom_pw_info,
6689 const struct samr_ValidatePasswordReq3 *req,
6690 struct samr_ValidatePasswordRepCtr *rep)
6692 NTSTATUS status;
6694 if (req->password.string == NULL) {
6695 return SAMR_VALIDATION_STATUS_SUCCESS;
6697 if (strlen(req->password.string) < dom_pw_info->min_password_length) {
6698 ZERO_STRUCT(rep->info);
6699 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
6701 if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
6702 status = check_password_complexity(req->account.string,
6703 req->password.string,
6704 NULL);
6705 if (!NT_STATUS_IS_OK(status)) {
6706 ZERO_STRUCT(rep->info);
6707 return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
6711 return SAMR_VALIDATION_STATUS_SUCCESS;
6714 /****************************************************************
6715 _samr_ValidatePassword
6716 ****************************************************************/
6718 NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
6719 struct samr_ValidatePassword *r)
6721 union samr_ValidatePasswordRep *rep;
6722 NTSTATUS status;
6723 struct samr_GetDomPwInfo pw;
6724 struct samr_PwInfo dom_pw_info;
6726 if (r->in.level < 1 || r->in.level > 3) {
6727 return NT_STATUS_INVALID_INFO_CLASS;
6730 pw.in.domain_name = NULL;
6731 pw.out.info = &dom_pw_info;
6733 status = _samr_GetDomPwInfo(p, &pw);
6734 if (!NT_STATUS_IS_OK(status)) {
6735 return status;
6738 rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
6739 if (!rep) {
6740 return NT_STATUS_NO_MEMORY;
6743 switch (r->in.level) {
6744 case 1:
6745 status = NT_STATUS_NOT_SUPPORTED;
6746 break;
6747 case 2:
6748 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
6749 &dom_pw_info,
6750 &r->in.req->req2,
6751 &rep->ctr2);
6752 break;
6753 case 3:
6754 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
6755 &dom_pw_info,
6756 &r->in.req->req3,
6757 &rep->ctr3);
6758 break;
6759 default:
6760 status = NT_STATUS_INVALID_INFO_CLASS;
6761 break;
6764 if (!NT_STATUS_IS_OK(status)) {
6765 talloc_free(rep);
6766 return status;
6769 *r->out.rep = rep;
6771 return NT_STATUS_OK;
6774 /****************************************************************
6775 ****************************************************************/
6777 NTSTATUS _samr_Shutdown(struct pipes_struct *p,
6778 struct samr_Shutdown *r)
6780 p->rng_fault_state = true;
6781 return NT_STATUS_NOT_IMPLEMENTED;
6784 /****************************************************************
6785 ****************************************************************/
6787 NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
6788 struct samr_SetMemberAttributesOfGroup *r)
6790 p->rng_fault_state = true;
6791 return NT_STATUS_NOT_IMPLEMENTED;
6794 /****************************************************************
6795 ****************************************************************/
6797 NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
6798 struct samr_TestPrivateFunctionsDomain *r)
6800 return NT_STATUS_NOT_IMPLEMENTED;
6803 /****************************************************************
6804 ****************************************************************/
6806 NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
6807 struct samr_TestPrivateFunctionsUser *r)
6809 return NT_STATUS_NOT_IMPLEMENTED;
6812 /****************************************************************
6813 ****************************************************************/
6815 NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
6816 struct samr_AddMultipleMembersToAlias *r)
6818 p->rng_fault_state = true;
6819 return NT_STATUS_NOT_IMPLEMENTED;
6822 /****************************************************************
6823 ****************************************************************/
6825 NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
6826 struct samr_RemoveMultipleMembersFromAlias *r)
6828 p->rng_fault_state = true;
6829 return NT_STATUS_NOT_IMPLEMENTED;
6832 /****************************************************************
6833 ****************************************************************/
6835 NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
6836 struct samr_SetBootKeyInformation *r)
6838 p->rng_fault_state = true;
6839 return NT_STATUS_NOT_IMPLEMENTED;
6842 /****************************************************************
6843 ****************************************************************/
6845 NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
6846 struct samr_GetBootKeyInformation *r)
6848 p->rng_fault_state = true;
6849 return NT_STATUS_NOT_IMPLEMENTED;
6852 /****************************************************************
6853 ****************************************************************/
6855 NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
6856 struct samr_SetDsrmPassword *r)
6858 p->rng_fault_state = true;
6859 return NT_STATUS_NOT_IMPLEMENTED;