Remove the requirement for ldap call made as root. Add in security
[Samba/bb.git] / source3 / rpc_server / srv_samr_nt.c
blob261d77ca65dfda6e64bdeb82598619017de21817
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-2005,
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"
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SA_RIGHT_USER_CHANGE_PASSWORD | \
42 SA_RIGHT_USER_SET_LOC_COM )
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 typedef struct disp_info {
49 DOM_SID sid; /* identify which domain this is. */
50 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
51 struct pdb_search *users; /* querydispinfo 1 and 4 */
52 struct pdb_search *machines; /* querydispinfo 2 */
53 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
54 struct pdb_search *aliases; /* enumaliases */
56 uint16 enum_acb_mask;
57 struct pdb_search *enum_users; /* enumusers with a mask */
59 struct timed_event *cache_timeout_event; /* cache idle timeout
60 * handler. */
61 } DISP_INFO;
63 /* We keep a static list of these by SID as modern clients close down
64 all resources between each request in a complete enumeration. */
66 struct samr_info {
67 /* for use by the \PIPE\samr policy */
68 DOM_SID sid;
69 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
70 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
71 uint32 acc_granted;
72 DISP_INFO *disp_info;
73 TALLOC_CTX *mem_ctx;
76 static const struct generic_mapping sam_generic_mapping = {
77 GENERIC_RIGHTS_SAM_READ,
78 GENERIC_RIGHTS_SAM_WRITE,
79 GENERIC_RIGHTS_SAM_EXECUTE,
80 GENERIC_RIGHTS_SAM_ALL_ACCESS};
81 static const struct generic_mapping dom_generic_mapping = {
82 GENERIC_RIGHTS_DOMAIN_READ,
83 GENERIC_RIGHTS_DOMAIN_WRITE,
84 GENERIC_RIGHTS_DOMAIN_EXECUTE,
85 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
86 static const struct generic_mapping usr_generic_mapping = {
87 GENERIC_RIGHTS_USER_READ,
88 GENERIC_RIGHTS_USER_WRITE,
89 GENERIC_RIGHTS_USER_EXECUTE,
90 GENERIC_RIGHTS_USER_ALL_ACCESS};
91 static const struct generic_mapping usr_nopwchange_generic_mapping = {
92 GENERIC_RIGHTS_USER_READ,
93 GENERIC_RIGHTS_USER_WRITE,
94 GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
95 GENERIC_RIGHTS_USER_ALL_ACCESS};
96 static const struct generic_mapping grp_generic_mapping = {
97 GENERIC_RIGHTS_GROUP_READ,
98 GENERIC_RIGHTS_GROUP_WRITE,
99 GENERIC_RIGHTS_GROUP_EXECUTE,
100 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
101 static const struct generic_mapping ali_generic_mapping = {
102 GENERIC_RIGHTS_ALIAS_READ,
103 GENERIC_RIGHTS_ALIAS_WRITE,
104 GENERIC_RIGHTS_ALIAS_EXECUTE,
105 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
107 /*******************************************************************
108 *******************************************************************/
110 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
111 const struct generic_mapping *map,
112 DOM_SID *sid, uint32 sid_access )
114 DOM_SID domadmin_sid;
115 SEC_ACE ace[5]; /* at most 5 entries */
116 size_t i = 0;
118 SEC_ACL *psa = NULL;
120 /* basic access for Everyone */
122 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
123 map->generic_execute | map->generic_read, 0);
125 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
127 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
128 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
129 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
130 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
132 /* Add Full Access for Domain Admins if we are a DC */
134 if ( IS_DC ) {
135 sid_copy( &domadmin_sid, get_global_sam_sid() );
136 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
137 init_sec_ace(&ace[i++], &domadmin_sid,
138 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
141 /* if we have a sid, give it some special access */
143 if ( sid ) {
144 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
147 /* create the security descriptor */
149 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
150 return NT_STATUS_NO_MEMORY;
152 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
153 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
154 psa, sd_size)) == NULL)
155 return NT_STATUS_NO_MEMORY;
157 return NT_STATUS_OK;
160 /*******************************************************************
161 Checks if access to an object should be granted, and returns that
162 level of access for further checks.
163 ********************************************************************/
165 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
166 SE_PRIV *rights, uint32 rights_mask,
167 uint32 des_access, uint32 *acc_granted,
168 const char *debug )
170 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
171 uint32 saved_mask = 0;
173 /* check privileges; certain SAM access bits should be overridden
174 by privileges (mostly having to do with creating/modifying/deleting
175 users and groups) */
177 if ( rights && user_has_any_privilege( token, rights ) ) {
179 saved_mask = (des_access & rights_mask);
180 des_access &= ~saved_mask;
182 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
183 rights_mask));
187 /* check the security descriptor first */
189 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
190 goto done;
192 /* give root a free pass */
194 if ( geteuid() == sec_initial_uid() ) {
196 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
197 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
199 *acc_granted = des_access;
201 status = NT_STATUS_OK;
202 goto done;
206 done:
207 /* add in any bits saved during the privilege check (only
208 matters is status is ok) */
210 *acc_granted |= rights_mask;
212 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
213 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
214 des_access, *acc_granted));
216 return status;
219 /*******************************************************************
220 Checks if access to a function can be granted
221 ********************************************************************/
223 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
225 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
226 debug, acc_granted, acc_required));
228 /* check the security descriptor first */
230 if ( (acc_granted&acc_required) == acc_required )
231 return NT_STATUS_OK;
233 /* give root a free pass */
235 if (geteuid() == sec_initial_uid()) {
237 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
238 debug, acc_granted, acc_required));
239 DEBUGADD(4,("but overwritten by euid == 0\n"));
241 return NT_STATUS_OK;
244 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
245 debug, acc_granted, acc_required));
247 return NT_STATUS_ACCESS_DENIED;
250 /*******************************************************************
251 Fetch or create a dispinfo struct.
252 ********************************************************************/
254 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
257 * We do a static cache for DISP_INFO's here. Explanation can be found
258 * in Jeremy's checkin message to r11793:
260 * Fix the SAMR cache so it works across completely insane
261 * client behaviour (ie.:
262 * open pipe/open SAMR handle/enumerate 0 - 1024
263 * close SAMR handle, close pipe.
264 * open pipe/open SAMR handle/enumerate 1024 - 2048...
265 * close SAMR handle, close pipe.
266 * And on ad-nausium. Amazing.... probably object-oriented
267 * client side programming in action yet again.
268 * This change should *massively* improve performance when
269 * enumerating users from an LDAP database.
270 * Jeremy.
272 * "Our" and the builtin domain are the only ones where we ever
273 * enumerate stuff, so just cache 2 entries.
276 static struct disp_info builtin_dispinfo;
277 static struct disp_info domain_dispinfo;
279 /* There are two cases to consider here:
280 1) The SID is a domain SID and we look for an equality match, or
281 2) This is an account SID and so we return the DISP_INFO* for our
282 domain */
284 if (psid == NULL) {
285 return NULL;
288 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
290 * Necessary only once, but it does not really hurt.
292 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
294 return &builtin_dispinfo;
297 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
299 * Necessary only once, but it does not really hurt.
301 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
303 return &domain_dispinfo;
306 return NULL;
309 /*******************************************************************
310 Create a samr_info struct.
311 ********************************************************************/
313 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
315 struct samr_info *info;
316 fstring sid_str;
317 TALLOC_CTX *mem_ctx;
319 if (psid) {
320 sid_to_fstring(sid_str, psid);
321 } else {
322 fstrcpy(sid_str,"(NULL)");
325 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
327 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
328 return NULL;
330 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
331 if (psid) {
332 sid_copy( &info->sid, psid);
333 info->builtin_domain = sid_check_is_builtin(psid);
334 } else {
335 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
336 info->builtin_domain = False;
338 info->mem_ctx = mem_ctx;
340 info->disp_info = get_samr_dispinfo_by_sid(psid);
342 return info;
345 /*******************************************************************
346 Function to free the per SID data.
347 ********************************************************************/
349 static void free_samr_cache(DISP_INFO *disp_info)
351 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
352 sid_string_dbg(&disp_info->sid)));
354 /* We need to become root here because the paged search might have to
355 * tell the LDAP server we're not interested in the rest anymore. */
357 become_root();
359 if (disp_info->users) {
360 DEBUG(10,("free_samr_cache: deleting users cache\n"));
361 pdb_search_destroy(disp_info->users);
362 disp_info->users = NULL;
364 if (disp_info->machines) {
365 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
366 pdb_search_destroy(disp_info->machines);
367 disp_info->machines = NULL;
369 if (disp_info->groups) {
370 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
371 pdb_search_destroy(disp_info->groups);
372 disp_info->groups = NULL;
374 if (disp_info->aliases) {
375 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
376 pdb_search_destroy(disp_info->aliases);
377 disp_info->aliases = NULL;
379 if (disp_info->enum_users) {
380 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
381 pdb_search_destroy(disp_info->enum_users);
382 disp_info->enum_users = NULL;
384 disp_info->enum_acb_mask = 0;
386 unbecome_root();
389 /*******************************************************************
390 Function to free the per handle data.
391 ********************************************************************/
393 static void free_samr_info(void *ptr)
395 struct samr_info *info=(struct samr_info *) ptr;
397 /* Only free the dispinfo cache if no one bothered to set up
398 a timeout. */
400 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
401 free_samr_cache(info->disp_info);
404 talloc_destroy(info->mem_ctx);
407 /*******************************************************************
408 Idle event handler. Throw away the disp info cache.
409 ********************************************************************/
411 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
412 struct timed_event *te,
413 const struct timeval *now,
414 void *private_data)
416 DISP_INFO *disp_info = (DISP_INFO *)private_data;
418 TALLOC_FREE(disp_info->cache_timeout_event);
420 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
421 "out\n"));
422 free_samr_cache(disp_info);
425 /*******************************************************************
426 Setup cache removal idle event handler.
427 ********************************************************************/
429 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
431 /* Remove any pending timeout and update. */
433 TALLOC_FREE(disp_info->cache_timeout_event);
435 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
436 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
437 (unsigned int)secs_fromnow ));
439 disp_info->cache_timeout_event = event_add_timed(
440 smbd_event_context(), NULL,
441 timeval_current_ofs(secs_fromnow, 0),
442 "disp_info_cache_idle_timeout_handler",
443 disp_info_cache_idle_timeout_handler, (void *)disp_info);
446 /*******************************************************************
447 Force flush any cache. We do this on any samr_set_xxx call.
448 We must also remove the timeout handler.
449 ********************************************************************/
451 static void force_flush_samr_cache(DISP_INFO *disp_info)
453 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
454 return;
457 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
458 TALLOC_FREE(disp_info->cache_timeout_event);
459 free_samr_cache(disp_info);
462 /*******************************************************************
463 Ensure password info is never given out. Paranioa... JRA.
464 ********************************************************************/
466 static void samr_clear_sam_passwd(struct samu *sam_pass)
469 if (!sam_pass)
470 return;
472 /* These now zero out the old password */
474 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
475 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
478 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
480 struct samr_displayentry *entry;
482 if (info->builtin_domain) {
483 /* No users in builtin. */
484 return 0;
487 if (info->users == NULL) {
488 info->users = pdb_search_users(acct_flags);
489 if (info->users == NULL) {
490 return 0;
493 /* Fetch the last possible entry, thus trigger an enumeration */
494 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
496 /* Ensure we cache this enumeration. */
497 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
499 return info->users->num_entries;
502 static uint32 count_sam_groups(struct disp_info *info)
504 struct samr_displayentry *entry;
506 if (info->builtin_domain) {
507 /* No groups in builtin. */
508 return 0;
511 if (info->groups == NULL) {
512 info->groups = pdb_search_groups();
513 if (info->groups == NULL) {
514 return 0;
517 /* Fetch the last possible entry, thus trigger an enumeration */
518 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
520 /* Ensure we cache this enumeration. */
521 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
523 return info->groups->num_entries;
526 static uint32 count_sam_aliases(struct disp_info *info)
528 struct samr_displayentry *entry;
530 if (info->aliases == NULL) {
531 info->aliases = pdb_search_aliases(&info->sid);
532 if (info->aliases == NULL) {
533 return 0;
536 /* Fetch the last possible entry, thus trigger an enumeration */
537 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
539 /* Ensure we cache this enumeration. */
540 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
542 return info->aliases->num_entries;
545 /*******************************************************************
546 _samr_Close
547 ********************************************************************/
549 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
551 if (!close_policy_hnd(p, r->in.handle)) {
552 return NT_STATUS_INVALID_HANDLE;
555 ZERO_STRUCTP(r->out.handle);
557 return NT_STATUS_OK;
560 /*******************************************************************
561 _samr_OpenDomain
562 ********************************************************************/
564 NTSTATUS _samr_OpenDomain(pipes_struct *p,
565 struct samr_OpenDomain *r)
567 struct samr_info *info;
568 SEC_DESC *psd = NULL;
569 uint32 acc_granted;
570 uint32 des_access = r->in.access_mask;
571 NTSTATUS status;
572 size_t sd_size;
573 SE_PRIV se_rights;
575 /* find the connection policy handle. */
577 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
578 return NT_STATUS_INVALID_HANDLE;
580 status = access_check_samr_function(info->acc_granted,
581 SA_RIGHT_SAM_OPEN_DOMAIN,
582 "_samr_OpenDomain" );
584 if ( !NT_STATUS_IS_OK(status) )
585 return status;
587 /*check if access can be granted as requested by client. */
589 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
590 se_map_generic( &des_access, &dom_generic_mapping );
592 se_priv_copy( &se_rights, &se_machine_account );
593 se_priv_add( &se_rights, &se_add_users );
595 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
596 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
597 &acc_granted, "_samr_OpenDomain" );
599 if ( !NT_STATUS_IS_OK(status) )
600 return status;
602 if (!sid_check_is_domain(r->in.sid) &&
603 !sid_check_is_builtin(r->in.sid)) {
604 return NT_STATUS_NO_SUCH_DOMAIN;
607 /* associate the domain SID with the (unique) handle. */
608 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
609 return NT_STATUS_NO_MEMORY;
610 info->acc_granted = acc_granted;
612 /* get a (unique) handle. open a policy on it. */
613 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
614 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
616 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
618 return NT_STATUS_OK;
621 /*******************************************************************
622 _samr_GetUserPwInfo
623 ********************************************************************/
625 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
626 struct samr_GetUserPwInfo *r)
628 struct samr_info *info = NULL;
629 enum lsa_SidType sid_type;
630 uint32_t min_password_length = 0;
631 uint32_t password_properties = 0;
632 bool ret = false;
633 NTSTATUS status;
635 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
637 /* find the policy handle. open a policy on it. */
638 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
639 return NT_STATUS_INVALID_HANDLE;
642 status = access_check_samr_function(info->acc_granted,
643 SAMR_USER_ACCESS_GET_ATTRIBUTES,
644 "_samr_GetUserPwInfo" );
645 if (!NT_STATUS_IS_OK(status)) {
646 return status;
649 if (!sid_check_is_in_our_domain(&info->sid)) {
650 return NT_STATUS_OBJECT_TYPE_MISMATCH;
653 become_root();
654 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
655 unbecome_root();
656 if (ret == false) {
657 return NT_STATUS_NO_SUCH_USER;
660 switch (sid_type) {
661 case SID_NAME_USER:
662 become_root();
663 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
664 &min_password_length);
665 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
666 &password_properties);
667 unbecome_root();
669 if (lp_check_password_script() && *lp_check_password_script()) {
670 password_properties |= DOMAIN_PASSWORD_COMPLEX;
673 break;
674 default:
675 break;
678 r->out.info->min_password_length = min_password_length;
679 r->out.info->password_properties = password_properties;
681 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
683 return NT_STATUS_OK;
686 /*******************************************************************
687 ********************************************************************/
689 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
690 DOM_SID *sid, uint32 *acc_granted,
691 DISP_INFO **ppdisp_info)
693 struct samr_info *info = NULL;
695 /* find the policy handle. open a policy on it. */
696 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
697 return False;
699 if (!info)
700 return False;
702 *sid = info->sid;
703 *acc_granted = info->acc_granted;
704 if (ppdisp_info) {
705 *ppdisp_info = info->disp_info;
708 return True;
711 /*******************************************************************
712 _samr_SetSecurity
713 ********************************************************************/
715 NTSTATUS _samr_SetSecurity(pipes_struct *p,
716 struct samr_SetSecurity *r)
718 DOM_SID pol_sid;
719 uint32 acc_granted, i;
720 SEC_ACL *dacl;
721 bool ret;
722 struct samu *sampass=NULL;
723 NTSTATUS status;
725 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
726 return NT_STATUS_INVALID_HANDLE;
728 if (!(sampass = samu_new( p->mem_ctx))) {
729 DEBUG(0,("No memory!\n"));
730 return NT_STATUS_NO_MEMORY;
733 /* get the user record */
734 become_root();
735 ret = pdb_getsampwsid(sampass, &pol_sid);
736 unbecome_root();
738 if (!ret) {
739 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
740 TALLOC_FREE(sampass);
741 return NT_STATUS_INVALID_HANDLE;
744 dacl = r->in.sdbuf->sd->dacl;
745 for (i=0; i < dacl->num_aces; i++) {
746 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
747 ret = pdb_set_pass_can_change(sampass,
748 (dacl->aces[i].access_mask &
749 SA_RIGHT_USER_CHANGE_PASSWORD) ?
750 True: False);
751 break;
755 if (!ret) {
756 TALLOC_FREE(sampass);
757 return NT_STATUS_ACCESS_DENIED;
760 status = access_check_samr_function(acc_granted,
761 SA_RIGHT_USER_SET_ATTRIBUTES,
762 "_samr_SetSecurity");
763 if (NT_STATUS_IS_OK(status)) {
764 become_root();
765 status = pdb_update_sam_account(sampass);
766 unbecome_root();
769 TALLOC_FREE(sampass);
771 return status;
774 /*******************************************************************
775 build correct perms based on policies and password times for _samr_query_sec_obj
776 *******************************************************************/
777 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
779 struct samu *sampass=NULL;
780 bool ret;
782 if ( !(sampass = samu_new( mem_ctx )) ) {
783 DEBUG(0,("No memory!\n"));
784 return False;
787 become_root();
788 ret = pdb_getsampwsid(sampass, user_sid);
789 unbecome_root();
791 if (ret == False) {
792 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
793 TALLOC_FREE(sampass);
794 return False;
797 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
799 if (pdb_get_pass_can_change(sampass)) {
800 TALLOC_FREE(sampass);
801 return True;
803 TALLOC_FREE(sampass);
804 return False;
808 /*******************************************************************
809 _samr_QuerySecurity
810 ********************************************************************/
812 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
813 struct samr_QuerySecurity *r)
815 NTSTATUS status;
816 DOM_SID pol_sid;
817 SEC_DESC * psd = NULL;
818 uint32 acc_granted;
819 size_t sd_size;
821 /* Get the SID. */
822 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
823 return NT_STATUS_INVALID_HANDLE;
825 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
826 sid_string_dbg(&pol_sid)));
828 status = access_check_samr_function(acc_granted,
829 STD_RIGHT_READ_CONTROL_ACCESS,
830 "_samr_QuerySecurity");
831 if (NT_STATUS_IS_OK(status)) {
832 return status;
835 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
837 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
838 if (pol_sid.sid_rev_num == 0) {
839 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
840 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
841 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
842 /* check if it is our domain SID */
843 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
844 "with SID: %s\n", sid_string_dbg(&pol_sid)));
845 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
846 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
847 /* check if it is the Builtin Domain */
848 /* TODO: Builtin probably needs a different SD with restricted write access*/
849 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
850 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
851 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
852 } else if (sid_check_is_in_our_domain(&pol_sid) ||
853 sid_check_is_in_builtin(&pol_sid)) {
854 /* TODO: different SDs have to be generated for aliases groups and users.
855 Currently all three get a default user SD */
856 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
857 "with SID: %s\n", sid_string_dbg(&pol_sid)));
858 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
859 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
860 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
861 } else {
862 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
863 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
865 } else {
866 return NT_STATUS_OBJECT_TYPE_MISMATCH;
869 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
870 return NT_STATUS_NO_MEMORY;
872 return status;
875 /*******************************************************************
876 makes a SAM_ENTRY / UNISTR2* structure from a user list.
877 ********************************************************************/
879 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
880 struct samr_SamEntry **sam_pp,
881 uint32_t num_entries,
882 uint32_t start_idx,
883 struct samr_displayentry *entries)
885 uint32_t i;
886 struct samr_SamEntry *sam;
888 *sam_pp = NULL;
890 if (num_entries == 0) {
891 return NT_STATUS_OK;
894 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
895 if (sam == NULL) {
896 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
897 return NT_STATUS_NO_MEMORY;
900 for (i = 0; i < num_entries; i++) {
901 #if 0
903 * usrmgr expects a non-NULL terminated string with
904 * trust relationships
906 if (entries[i].acct_flags & ACB_DOMTRUST) {
907 init_unistr2(&uni_temp_name, entries[i].account_name,
908 UNI_FLAGS_NONE);
909 } else {
910 init_unistr2(&uni_temp_name, entries[i].account_name,
911 UNI_STR_TERMINATE);
913 #endif
914 init_lsa_String(&sam[i].name, entries[i].account_name);
915 sam[i].idx = entries[i].rid;
918 *sam_pp = sam;
920 return NT_STATUS_OK;
923 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
925 /*******************************************************************
926 _samr_EnumDomainUsers
927 ********************************************************************/
929 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
930 struct samr_EnumDomainUsers *r)
932 NTSTATUS status;
933 struct samr_info *info = NULL;
934 int num_account;
935 uint32 enum_context = *r->in.resume_handle;
936 enum remote_arch_types ra_type = get_remote_arch();
937 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
938 uint32 max_entries = max_sam_entries;
939 struct samr_displayentry *entries = NULL;
940 struct samr_SamArray *samr_array = NULL;
941 struct samr_SamEntry *samr_entries = NULL;
943 /* find the policy handle. open a policy on it. */
944 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
945 return NT_STATUS_INVALID_HANDLE;
947 status = access_check_samr_function(info->acc_granted,
948 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
949 "_samr_EnumDomainUsers");
950 if (!NT_STATUS_IS_OK(status)) {
951 return status;
954 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
956 if (info->builtin_domain) {
957 /* No users in builtin. */
958 *r->out.resume_handle = *r->in.resume_handle;
959 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
960 return status;
963 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
964 if (!samr_array) {
965 return NT_STATUS_NO_MEMORY;
968 become_root();
970 /* AS ROOT !!!! */
972 if ((info->disp_info->enum_users != NULL) &&
973 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
974 pdb_search_destroy(info->disp_info->enum_users);
975 info->disp_info->enum_users = NULL;
978 if (info->disp_info->enum_users == NULL) {
979 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
980 info->disp_info->enum_acb_mask = r->in.acct_flags;
983 if (info->disp_info->enum_users == NULL) {
984 /* END AS ROOT !!!! */
985 unbecome_root();
986 return NT_STATUS_ACCESS_DENIED;
989 num_account = pdb_search_entries(info->disp_info->enum_users,
990 enum_context, max_entries,
991 &entries);
993 /* END AS ROOT !!!! */
995 unbecome_root();
997 if (num_account == 0) {
998 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
999 "total entries\n"));
1000 *r->out.resume_handle = *r->in.resume_handle;
1001 return NT_STATUS_OK;
1004 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1005 num_account, enum_context,
1006 entries);
1007 if (!NT_STATUS_IS_OK(status)) {
1008 return status;
1011 if (max_entries <= num_account) {
1012 status = STATUS_MORE_ENTRIES;
1013 } else {
1014 status = NT_STATUS_OK;
1017 /* Ensure we cache this enumeration. */
1018 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1020 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1022 samr_array->count = num_account;
1023 samr_array->entries = samr_entries;
1025 *r->out.resume_handle = *r->in.resume_handle + num_account;
1026 *r->out.sam = samr_array;
1027 *r->out.num_entries = num_account;
1029 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1031 return status;
1034 /*******************************************************************
1035 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1036 ********************************************************************/
1038 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1039 struct samr_SamEntry **sam_pp,
1040 uint32_t num_sam_entries,
1041 struct samr_displayentry *entries)
1043 struct samr_SamEntry *sam;
1044 uint32_t i;
1046 *sam_pp = NULL;
1048 if (num_sam_entries == 0) {
1049 return;
1052 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1053 if (sam == NULL) {
1054 return;
1057 for (i = 0; i < num_sam_entries; i++) {
1059 * JRA. I think this should include the null. TNG does not.
1061 init_lsa_String(&sam[i].name, entries[i].account_name);
1062 sam[i].idx = entries[i].rid;
1065 *sam_pp = sam;
1068 /*******************************************************************
1069 _samr_EnumDomainGroups
1070 ********************************************************************/
1072 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1073 struct samr_EnumDomainGroups *r)
1075 NTSTATUS status;
1076 struct samr_info *info = NULL;
1077 struct samr_displayentry *groups;
1078 uint32 num_groups;
1079 struct samr_SamArray *samr_array = NULL;
1080 struct samr_SamEntry *samr_entries = NULL;
1082 /* find the policy handle. open a policy on it. */
1083 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1084 return NT_STATUS_INVALID_HANDLE;
1086 status = access_check_samr_function(info->acc_granted,
1087 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1088 "_samr_EnumDomainGroups");
1089 if (!NT_STATUS_IS_OK(status)) {
1090 return status;
1093 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1095 if (info->builtin_domain) {
1096 /* No groups in builtin. */
1097 *r->out.resume_handle = *r->in.resume_handle;
1098 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1099 return status;
1102 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1103 if (!samr_array) {
1104 return NT_STATUS_NO_MEMORY;
1107 /* the domain group array is being allocated in the function below */
1109 become_root();
1111 if (info->disp_info->groups == NULL) {
1112 info->disp_info->groups = pdb_search_groups();
1114 if (info->disp_info->groups == NULL) {
1115 unbecome_root();
1116 return NT_STATUS_ACCESS_DENIED;
1120 num_groups = pdb_search_entries(info->disp_info->groups,
1121 *r->in.resume_handle,
1122 MAX_SAM_ENTRIES, &groups);
1123 unbecome_root();
1125 /* Ensure we cache this enumeration. */
1126 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1128 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1129 num_groups, groups);
1131 samr_array->count = num_groups;
1132 samr_array->entries = samr_entries;
1134 *r->out.sam = samr_array;
1135 *r->out.num_entries = num_groups;
1136 /* this was missing, IMHO:
1137 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1140 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1142 return status;
1145 /*******************************************************************
1146 _samr_EnumDomainAliases
1147 ********************************************************************/
1149 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1150 struct samr_EnumDomainAliases *r)
1152 NTSTATUS status;
1153 struct samr_info *info;
1154 struct samr_displayentry *aliases;
1155 uint32 num_aliases = 0;
1156 struct samr_SamArray *samr_array = NULL;
1157 struct samr_SamEntry *samr_entries = NULL;
1159 /* find the policy handle. open a policy on it. */
1160 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1161 return NT_STATUS_INVALID_HANDLE;
1163 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1164 sid_string_dbg(&info->sid)));
1166 status = access_check_samr_function(info->acc_granted,
1167 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1168 "_samr_EnumDomainAliases");
1169 if (!NT_STATUS_IS_OK(status)) {
1170 return status;
1173 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1174 if (!samr_array) {
1175 return NT_STATUS_NO_MEMORY;
1178 become_root();
1180 if (info->disp_info->aliases == NULL) {
1181 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1182 if (info->disp_info->aliases == NULL) {
1183 unbecome_root();
1184 return NT_STATUS_ACCESS_DENIED;
1188 num_aliases = pdb_search_entries(info->disp_info->aliases,
1189 *r->in.resume_handle,
1190 MAX_SAM_ENTRIES, &aliases);
1191 unbecome_root();
1193 /* Ensure we cache this enumeration. */
1194 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1196 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1197 num_aliases, aliases);
1199 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1201 samr_array->count = num_aliases;
1202 samr_array->entries = samr_entries;
1204 *r->out.sam = samr_array;
1205 *r->out.num_entries = num_aliases;
1206 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1208 return status;
1211 /*******************************************************************
1212 inits a samr_DispInfoGeneral structure.
1213 ********************************************************************/
1215 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1216 struct samr_DispInfoGeneral *r,
1217 uint32_t num_entries,
1218 uint32_t start_idx,
1219 struct samr_displayentry *entries)
1221 uint32 i;
1223 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1225 if (num_entries == 0) {
1226 return NT_STATUS_OK;
1229 r->count = num_entries;
1231 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1232 if (!r->entries) {
1233 return NT_STATUS_NO_MEMORY;
1236 for (i = 0; i < num_entries ; i++) {
1238 init_lsa_String(&r->entries[i].account_name,
1239 entries[i].account_name);
1241 init_lsa_String(&r->entries[i].description,
1242 entries[i].description);
1244 init_lsa_String(&r->entries[i].full_name,
1245 entries[i].fullname);
1247 r->entries[i].rid = entries[i].rid;
1248 r->entries[i].acct_flags = entries[i].acct_flags;
1249 r->entries[i].idx = start_idx+i+1;
1252 return NT_STATUS_OK;
1255 /*******************************************************************
1256 inits a samr_DispInfoFull structure.
1257 ********************************************************************/
1259 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1260 struct samr_DispInfoFull *r,
1261 uint32_t num_entries,
1262 uint32_t start_idx,
1263 struct samr_displayentry *entries)
1265 uint32_t i;
1267 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1269 if (num_entries == 0) {
1270 return NT_STATUS_OK;
1273 r->count = num_entries;
1275 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1276 if (!r->entries) {
1277 return NT_STATUS_NO_MEMORY;
1280 for (i = 0; i < num_entries ; i++) {
1282 init_lsa_String(&r->entries[i].account_name,
1283 entries[i].account_name);
1285 init_lsa_String(&r->entries[i].description,
1286 entries[i].description);
1288 r->entries[i].rid = entries[i].rid;
1289 r->entries[i].acct_flags = entries[i].acct_flags;
1290 r->entries[i].idx = start_idx+i+1;
1293 return NT_STATUS_OK;
1296 /*******************************************************************
1297 inits a samr_DispInfoFullGroups structure.
1298 ********************************************************************/
1300 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1301 struct samr_DispInfoFullGroups *r,
1302 uint32_t num_entries,
1303 uint32_t start_idx,
1304 struct samr_displayentry *entries)
1306 uint32_t i;
1308 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1310 if (num_entries == 0) {
1311 return NT_STATUS_OK;
1314 r->count = num_entries;
1316 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1317 if (!r->entries) {
1318 return NT_STATUS_NO_MEMORY;
1321 for (i = 0; i < num_entries ; i++) {
1323 init_lsa_String(&r->entries[i].account_name,
1324 entries[i].account_name);
1326 init_lsa_String(&r->entries[i].description,
1327 entries[i].description);
1329 r->entries[i].rid = entries[i].rid;
1330 r->entries[i].acct_flags = entries[i].acct_flags;
1331 r->entries[i].idx = start_idx+i+1;
1334 return NT_STATUS_OK;
1337 /*******************************************************************
1338 inits a samr_DispInfoAscii structure.
1339 ********************************************************************/
1341 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1342 struct samr_DispInfoAscii *r,
1343 uint32_t num_entries,
1344 uint32_t start_idx,
1345 struct samr_displayentry *entries)
1347 uint32_t i;
1349 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1351 if (num_entries == 0) {
1352 return NT_STATUS_OK;
1355 r->count = num_entries;
1357 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1358 if (!r->entries) {
1359 return NT_STATUS_NO_MEMORY;
1362 for (i = 0; i < num_entries ; i++) {
1364 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1365 entries[i].account_name);
1367 r->entries[i].idx = start_idx+i+1;
1370 return NT_STATUS_OK;
1373 /*******************************************************************
1374 inits a samr_DispInfoAscii structure.
1375 ********************************************************************/
1377 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1378 struct samr_DispInfoAscii *r,
1379 uint32_t num_entries,
1380 uint32_t start_idx,
1381 struct samr_displayentry *entries)
1383 uint32_t i;
1385 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1387 if (num_entries == 0) {
1388 return NT_STATUS_OK;
1391 r->count = num_entries;
1393 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1394 if (!r->entries) {
1395 return NT_STATUS_NO_MEMORY;
1398 for (i = 0; i < num_entries ; i++) {
1400 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1401 entries[i].account_name);
1403 r->entries[i].idx = start_idx+i+1;
1406 return NT_STATUS_OK;
1409 /*******************************************************************
1410 _samr_QueryDisplayInfo
1411 ********************************************************************/
1413 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1414 struct samr_QueryDisplayInfo *r)
1416 NTSTATUS status;
1417 struct samr_info *info = NULL;
1418 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1420 uint32 max_entries = r->in.max_entries;
1421 uint32 enum_context = r->in.start_idx;
1422 uint32 max_size = r->in.buf_size;
1424 union samr_DispInfo *disp_info = r->out.info;
1426 uint32 temp_size=0, total_data_size=0;
1427 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1428 uint32 num_account = 0;
1429 enum remote_arch_types ra_type = get_remote_arch();
1430 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1431 struct samr_displayentry *entries = NULL;
1433 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1435 /* find the policy handle. open a policy on it. */
1436 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1437 return NT_STATUS_INVALID_HANDLE;
1439 status = access_check_samr_function(info->acc_granted,
1440 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1441 "_samr_QueryDisplayInfo");
1442 if (!NT_STATUS_IS_OK(status)) {
1443 return status;
1447 * calculate how many entries we will return.
1448 * based on
1449 * - the number of entries the client asked
1450 * - our limit on that
1451 * - the starting point (enumeration context)
1452 * - the buffer size the client will accept
1456 * We are a lot more like W2K. Instead of reading the SAM
1457 * each time to find the records we need to send back,
1458 * we read it once and link that copy to the sam handle.
1459 * For large user list (over the MAX_SAM_ENTRIES)
1460 * it's a definitive win.
1461 * second point to notice: between enumerations
1462 * our sam is now the same as it's a snapshoot.
1463 * third point: got rid of the static SAM_USER_21 struct
1464 * no more intermediate.
1465 * con: it uses much more memory, as a full copy is stored
1466 * in memory.
1468 * If you want to change it, think twice and think
1469 * of the second point , that's really important.
1471 * JFM, 12/20/2001
1474 if ((r->in.level < 1) || (r->in.level > 5)) {
1475 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1476 (unsigned int)r->in.level ));
1477 return NT_STATUS_INVALID_INFO_CLASS;
1480 /* first limit the number of entries we will return */
1481 if(max_entries > max_sam_entries) {
1482 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1483 "entries, limiting to %d\n", max_entries,
1484 max_sam_entries));
1485 max_entries = max_sam_entries;
1488 /* calculate the size and limit on the number of entries we will
1489 * return */
1491 temp_size=max_entries*struct_size;
1493 if (temp_size>max_size) {
1494 max_entries=MIN((max_size/struct_size),max_entries);;
1495 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1496 "only %d entries\n", max_entries));
1499 become_root();
1501 /* THe following done as ROOT. Don't return without unbecome_root(). */
1503 switch (r->in.level) {
1504 case 0x1:
1505 case 0x4:
1506 if (info->disp_info->users == NULL) {
1507 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1508 if (info->disp_info->users == NULL) {
1509 unbecome_root();
1510 return NT_STATUS_ACCESS_DENIED;
1512 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1513 (unsigned int)enum_context ));
1514 } else {
1515 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1516 (unsigned int)enum_context ));
1519 num_account = pdb_search_entries(info->disp_info->users,
1520 enum_context, max_entries,
1521 &entries);
1522 break;
1523 case 0x2:
1524 if (info->disp_info->machines == NULL) {
1525 info->disp_info->machines =
1526 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1527 if (info->disp_info->machines == NULL) {
1528 unbecome_root();
1529 return NT_STATUS_ACCESS_DENIED;
1531 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1532 (unsigned int)enum_context ));
1533 } else {
1534 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1535 (unsigned int)enum_context ));
1538 num_account = pdb_search_entries(info->disp_info->machines,
1539 enum_context, max_entries,
1540 &entries);
1541 break;
1542 case 0x3:
1543 case 0x5:
1544 if (info->disp_info->groups == NULL) {
1545 info->disp_info->groups = pdb_search_groups();
1546 if (info->disp_info->groups == NULL) {
1547 unbecome_root();
1548 return NT_STATUS_ACCESS_DENIED;
1550 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1551 (unsigned int)enum_context ));
1552 } else {
1553 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1554 (unsigned int)enum_context ));
1557 num_account = pdb_search_entries(info->disp_info->groups,
1558 enum_context, max_entries,
1559 &entries);
1560 break;
1561 default:
1562 unbecome_root();
1563 smb_panic("info class changed");
1564 break;
1566 unbecome_root();
1569 /* Now create reply structure */
1570 switch (r->in.level) {
1571 case 0x1:
1572 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1573 num_account, enum_context,
1574 entries);
1575 break;
1576 case 0x2:
1577 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1578 num_account, enum_context,
1579 entries);
1580 break;
1581 case 0x3:
1582 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1583 num_account, enum_context,
1584 entries);
1585 break;
1586 case 0x4:
1587 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1588 num_account, enum_context,
1589 entries);
1590 break;
1591 case 0x5:
1592 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1593 num_account, enum_context,
1594 entries);
1595 break;
1596 default:
1597 smb_panic("info class changed");
1598 break;
1601 if (!NT_STATUS_IS_OK(disp_ret))
1602 return disp_ret;
1604 /* calculate the total size */
1605 total_data_size=num_account*struct_size;
1607 if (num_account) {
1608 status = STATUS_MORE_ENTRIES;
1609 } else {
1610 status = NT_STATUS_OK;
1613 /* Ensure we cache this enumeration. */
1614 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1616 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1618 *r->out.total_size = total_data_size;
1619 *r->out.returned_size = temp_size;
1621 return status;
1624 /****************************************************************
1625 _samr_QueryDisplayInfo2
1626 ****************************************************************/
1628 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1629 struct samr_QueryDisplayInfo2 *r)
1631 struct samr_QueryDisplayInfo q;
1633 q.in.domain_handle = r->in.domain_handle;
1634 q.in.level = r->in.level;
1635 q.in.start_idx = r->in.start_idx;
1636 q.in.max_entries = r->in.max_entries;
1637 q.in.buf_size = r->in.buf_size;
1639 q.out.total_size = r->out.total_size;
1640 q.out.returned_size = r->out.returned_size;
1641 q.out.info = r->out.info;
1643 return _samr_QueryDisplayInfo(p, &q);
1646 /****************************************************************
1647 _samr_QueryDisplayInfo3
1648 ****************************************************************/
1650 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1651 struct samr_QueryDisplayInfo3 *r)
1653 struct samr_QueryDisplayInfo q;
1655 q.in.domain_handle = r->in.domain_handle;
1656 q.in.level = r->in.level;
1657 q.in.start_idx = r->in.start_idx;
1658 q.in.max_entries = r->in.max_entries;
1659 q.in.buf_size = r->in.buf_size;
1661 q.out.total_size = r->out.total_size;
1662 q.out.returned_size = r->out.returned_size;
1663 q.out.info = r->out.info;
1665 return _samr_QueryDisplayInfo(p, &q);
1668 /*******************************************************************
1669 _samr_QueryAliasInfo
1670 ********************************************************************/
1672 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1673 struct samr_QueryAliasInfo *r)
1675 DOM_SID sid;
1676 struct acct_info info;
1677 uint32 acc_granted;
1678 NTSTATUS status;
1679 union samr_AliasInfo *alias_info = NULL;
1680 const char *alias_name = NULL;
1681 const char *alias_description = NULL;
1683 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1685 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1686 if (!alias_info) {
1687 return NT_STATUS_NO_MEMORY;
1690 /* find the policy handle. open a policy on it. */
1691 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1692 return NT_STATUS_INVALID_HANDLE;
1694 status = access_check_samr_function(acc_granted,
1695 SA_RIGHT_ALIAS_LOOKUP_INFO,
1696 "_samr_QueryAliasInfo");
1697 if (!NT_STATUS_IS_OK(status)) {
1698 return status;
1701 become_root();
1702 status = pdb_get_aliasinfo(&sid, &info);
1703 unbecome_root();
1705 if ( !NT_STATUS_IS_OK(status))
1706 return status;
1708 /* FIXME: info contains fstrings */
1709 alias_name = talloc_strdup(r, info.acct_name);
1710 alias_description = talloc_strdup(r, info.acct_desc);
1712 switch (r->in.level) {
1713 case ALIASINFOALL:
1714 init_samr_alias_info1(&alias_info->all,
1715 alias_name,
1717 alias_description);
1718 break;
1719 case ALIASINFODESCRIPTION:
1720 init_samr_alias_info3(&alias_info->description,
1721 alias_description);
1722 break;
1723 default:
1724 return NT_STATUS_INVALID_INFO_CLASS;
1727 *r->out.info = alias_info;
1729 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1731 return NT_STATUS_OK;
1734 #if 0
1735 /*******************************************************************
1736 samr_reply_lookup_ids
1737 ********************************************************************/
1739 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1741 uint32 rid[MAX_SAM_ENTRIES];
1742 int num_rids = q_u->num_sids1;
1744 r_u->status = NT_STATUS_OK;
1746 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1748 if (num_rids > MAX_SAM_ENTRIES) {
1749 num_rids = MAX_SAM_ENTRIES;
1750 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1753 #if 0
1754 int i;
1755 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1757 for (i = 0; i < num_rids && status == 0; i++)
1759 struct sam_passwd *sam_pass;
1760 fstring user_name;
1763 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1764 q_u->uni_user_name[i].uni_str_len));
1766 /* find the user account */
1767 become_root();
1768 sam_pass = get_smb21pwd_entry(user_name, 0);
1769 unbecome_root();
1771 if (sam_pass == NULL)
1773 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1774 rid[i] = 0;
1776 else
1778 rid[i] = sam_pass->user_rid;
1781 #endif
1783 num_rids = 1;
1784 rid[0] = BUILTIN_ALIAS_RID_USERS;
1786 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1788 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1790 return r_u->status;
1792 #endif
1794 /*******************************************************************
1795 _samr_LookupNames
1796 ********************************************************************/
1798 NTSTATUS _samr_LookupNames(pipes_struct *p,
1799 struct samr_LookupNames *r)
1801 NTSTATUS status;
1802 uint32 *rid;
1803 enum lsa_SidType *type;
1804 int i;
1805 int num_rids = r->in.num_names;
1806 DOM_SID pol_sid;
1807 uint32 acc_granted;
1808 struct samr_Ids rids, types;
1810 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1812 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1813 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1816 status = access_check_samr_function(acc_granted,
1817 0, /* Don't know the acc_bits yet */
1818 "_samr_LookupNames");
1819 if (!NT_STATUS_IS_OK(status)) {
1820 return status;
1823 if (num_rids > MAX_SAM_ENTRIES) {
1824 num_rids = MAX_SAM_ENTRIES;
1825 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1828 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1829 NT_STATUS_HAVE_NO_MEMORY(rid);
1831 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1832 NT_STATUS_HAVE_NO_MEMORY(type);
1834 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1835 sid_string_dbg(&pol_sid)));
1837 for (i = 0; i < num_rids; i++) {
1839 status = NT_STATUS_NONE_MAPPED;
1840 type[i] = SID_NAME_UNKNOWN;
1842 rid[i] = 0xffffffff;
1844 if (sid_check_is_builtin(&pol_sid)) {
1845 if (lookup_builtin_name(r->in.names[i].string,
1846 &rid[i]))
1848 type[i] = SID_NAME_ALIAS;
1850 } else {
1851 lookup_global_sam_name(r->in.names[i].string, 0,
1852 &rid[i], &type[i]);
1855 if (type[i] != SID_NAME_UNKNOWN) {
1856 status = NT_STATUS_OK;
1860 rids.count = num_rids;
1861 rids.ids = rid;
1863 types.count = num_rids;
1864 types.ids = type;
1866 *r->out.rids = rids;
1867 *r->out.types = types;
1869 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1871 return status;
1874 /*******************************************************************
1875 _samr_ChangePasswordUser2
1876 ********************************************************************/
1878 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1879 struct samr_ChangePasswordUser2 *r)
1881 NTSTATUS status;
1882 fstring user_name;
1883 fstring wks;
1885 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1887 fstrcpy(user_name, r->in.account->string);
1888 fstrcpy(wks, r->in.server->string);
1890 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1893 * Pass the user through the NT -> unix user mapping
1894 * function.
1897 (void)map_username(user_name);
1900 * UNIX username case mangling not required, pass_oem_change
1901 * is case insensitive.
1904 status = pass_oem_change(user_name,
1905 r->in.lm_password->data,
1906 r->in.lm_verifier->hash,
1907 r->in.nt_password->data,
1908 r->in.nt_verifier->hash,
1909 NULL);
1911 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1913 return status;
1916 /*******************************************************************
1917 _samr_ChangePasswordUser3
1918 ********************************************************************/
1920 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1921 struct samr_ChangePasswordUser3 *r)
1923 NTSTATUS status;
1924 fstring user_name;
1925 const char *wks = NULL;
1926 uint32 reject_reason;
1927 struct samr_DomInfo1 *dominfo = NULL;
1928 struct samr_ChangeReject *reject = NULL;
1930 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1932 fstrcpy(user_name, r->in.account->string);
1933 if (r->in.server && r->in.server->string) {
1934 wks = r->in.server->string;
1937 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1940 * Pass the user through the NT -> unix user mapping
1941 * function.
1944 (void)map_username(user_name);
1947 * UNIX username case mangling not required, pass_oem_change
1948 * is case insensitive.
1951 status = pass_oem_change(user_name,
1952 r->in.lm_password->data,
1953 r->in.lm_verifier->hash,
1954 r->in.nt_password->data,
1955 r->in.nt_verifier->hash,
1956 &reject_reason);
1958 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1959 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1961 uint32 min_pass_len,pass_hist,password_properties;
1962 time_t u_expire, u_min_age;
1963 NTTIME nt_expire, nt_min_age;
1964 uint32 account_policy_temp;
1966 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1967 if (!dominfo) {
1968 return NT_STATUS_NO_MEMORY;
1971 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1972 if (!reject) {
1973 return NT_STATUS_NO_MEMORY;
1976 become_root();
1978 /* AS ROOT !!! */
1980 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1981 min_pass_len = account_policy_temp;
1983 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1984 pass_hist = account_policy_temp;
1986 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1987 password_properties = account_policy_temp;
1989 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1990 u_expire = account_policy_temp;
1992 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1993 u_min_age = account_policy_temp;
1995 /* !AS ROOT */
1997 unbecome_root();
1999 unix_to_nt_time_abs(&nt_expire, u_expire);
2000 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2002 if (lp_check_password_script() && *lp_check_password_script()) {
2003 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2006 init_samr_DomInfo1(dominfo,
2007 min_pass_len,
2008 pass_hist,
2009 password_properties,
2010 u_expire,
2011 u_min_age);
2013 reject->reason = reject_reason;
2015 *r->out.dominfo = dominfo;
2016 *r->out.reject = reject;
2019 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2021 return status;
2024 /*******************************************************************
2025 makes a SAMR_R_LOOKUP_RIDS structure.
2026 ********************************************************************/
2028 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2029 const char **names,
2030 struct lsa_String **lsa_name_array_p)
2032 struct lsa_String *lsa_name_array = NULL;
2033 uint32_t i;
2035 *lsa_name_array_p = NULL;
2037 if (num_names != 0) {
2038 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2039 if (!lsa_name_array) {
2040 return false;
2044 for (i = 0; i < num_names; i++) {
2045 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2046 init_lsa_String(&lsa_name_array[i], names[i]);
2049 *lsa_name_array_p = lsa_name_array;
2051 return true;
2054 /*******************************************************************
2055 _samr_LookupRids
2056 ********************************************************************/
2058 NTSTATUS _samr_LookupRids(pipes_struct *p,
2059 struct samr_LookupRids *r)
2061 NTSTATUS status;
2062 const char **names;
2063 enum lsa_SidType *attrs = NULL;
2064 uint32 *wire_attrs = NULL;
2065 DOM_SID pol_sid;
2066 int num_rids = (int)r->in.num_rids;
2067 uint32 acc_granted;
2068 int i;
2069 struct lsa_Strings names_array;
2070 struct samr_Ids types_array;
2071 struct lsa_String *lsa_names = NULL;
2073 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2075 /* find the policy handle. open a policy on it. */
2076 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2077 return NT_STATUS_INVALID_HANDLE;
2079 status = access_check_samr_function(acc_granted,
2080 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
2081 "_samr__LookupRids");
2082 if (!NT_STATUS_IS_OK(status)) {
2083 return status;
2086 if (num_rids > 1000) {
2087 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2088 "to samba4 idl this is not possible\n", num_rids));
2089 return NT_STATUS_UNSUCCESSFUL;
2092 if (num_rids) {
2093 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2094 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2095 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2097 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2098 return NT_STATUS_NO_MEMORY;
2099 } else {
2100 names = NULL;
2101 attrs = NULL;
2102 wire_attrs = NULL;
2105 become_root(); /* lookup_sid can require root privs */
2106 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2107 names, attrs);
2108 unbecome_root();
2110 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2111 status = NT_STATUS_OK;
2114 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2115 &lsa_names)) {
2116 return NT_STATUS_NO_MEMORY;
2119 /* Convert from enum lsa_SidType to uint32 for wire format. */
2120 for (i = 0; i < num_rids; i++) {
2121 wire_attrs[i] = (uint32)attrs[i];
2124 names_array.count = num_rids;
2125 names_array.names = lsa_names;
2127 types_array.count = num_rids;
2128 types_array.ids = wire_attrs;
2130 *r->out.names = names_array;
2131 *r->out.types = types_array;
2133 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2135 return status;
2138 /*******************************************************************
2139 _samr_OpenUser
2140 ********************************************************************/
2142 NTSTATUS _samr_OpenUser(pipes_struct *p,
2143 struct samr_OpenUser *r)
2145 struct samu *sampass=NULL;
2146 DOM_SID sid;
2147 POLICY_HND domain_pol = *r->in.domain_handle;
2148 POLICY_HND *user_pol = r->out.user_handle;
2149 struct samr_info *info = NULL;
2150 SEC_DESC *psd = NULL;
2151 uint32 acc_granted;
2152 uint32 des_access = r->in.access_mask;
2153 size_t sd_size;
2154 bool ret;
2155 NTSTATUS nt_status;
2156 SE_PRIV se_rights;
2158 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2160 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2161 return NT_STATUS_INVALID_HANDLE;
2163 nt_status = access_check_samr_function(acc_granted,
2164 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2165 "_samr_OpenUser" );
2167 if ( !NT_STATUS_IS_OK(nt_status) )
2168 return nt_status;
2170 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2171 return NT_STATUS_NO_MEMORY;
2174 /* append the user's RID to it */
2176 if (!sid_append_rid(&sid, r->in.rid))
2177 return NT_STATUS_NO_SUCH_USER;
2179 /* check if access can be granted as requested by client. */
2181 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2182 se_map_generic(&des_access, &usr_generic_mapping);
2184 se_priv_copy( &se_rights, &se_machine_account );
2185 se_priv_add( &se_rights, &se_add_users );
2187 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2188 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2189 &acc_granted, "_samr_OpenUser");
2191 if ( !NT_STATUS_IS_OK(nt_status) )
2192 return nt_status;
2194 become_root();
2195 ret=pdb_getsampwsid(sampass, &sid);
2196 unbecome_root();
2198 /* check that the SID exists in our domain. */
2199 if (ret == False) {
2200 return NT_STATUS_NO_SUCH_USER;
2203 TALLOC_FREE(sampass);
2205 /* associate the user's SID and access bits with the new handle. */
2206 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2207 return NT_STATUS_NO_MEMORY;
2208 info->acc_granted = acc_granted;
2210 /* get a (unique) handle. open a policy on it. */
2211 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2212 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2214 return NT_STATUS_OK;
2217 /*************************************************************************
2218 *************************************************************************/
2220 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2221 DATA_BLOB *blob,
2222 struct lsa_BinaryString **_r)
2224 struct lsa_BinaryString *r;
2226 if (!blob || !_r) {
2227 return NT_STATUS_INVALID_PARAMETER;
2230 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2231 if (!r) {
2232 return NT_STATUS_NO_MEMORY;
2235 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2236 if (!r->array) {
2237 return NT_STATUS_NO_MEMORY;
2239 memcpy(r->array, blob->data, blob->length);
2240 r->size = blob->length;
2241 r->length = blob->length;
2243 if (!r->array) {
2244 return NT_STATUS_NO_MEMORY;
2247 *_r = r;
2249 return NT_STATUS_OK;
2252 /*************************************************************************
2253 get_user_info_7. Safe. Only gives out account_name.
2254 *************************************************************************/
2256 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2257 struct samr_UserInfo7 *r,
2258 DOM_SID *user_sid)
2260 struct samu *smbpass=NULL;
2261 bool ret;
2262 const char *account_name = NULL;
2264 ZERO_STRUCTP(r);
2266 if ( !(smbpass = samu_new( mem_ctx )) ) {
2267 return NT_STATUS_NO_MEMORY;
2270 become_root();
2271 ret = pdb_getsampwsid(smbpass, user_sid);
2272 unbecome_root();
2274 if ( !ret ) {
2275 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2276 return NT_STATUS_NO_SUCH_USER;
2279 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2280 if (!account_name) {
2281 TALLOC_FREE(smbpass);
2282 return NT_STATUS_NO_MEMORY;
2284 TALLOC_FREE(smbpass);
2286 DEBUG(3,("User:[%s]\n", account_name));
2288 init_samr_user_info7(r, account_name);
2290 return NT_STATUS_OK;
2293 /*************************************************************************
2294 get_user_info_9. Only gives out primary group SID.
2295 *************************************************************************/
2297 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2298 struct samr_UserInfo9 *r,
2299 DOM_SID *user_sid)
2301 struct samu *smbpass=NULL;
2302 bool ret;
2304 ZERO_STRUCTP(r);
2306 if ( !(smbpass = samu_new( mem_ctx )) ) {
2307 return NT_STATUS_NO_MEMORY;
2310 become_root();
2311 ret = pdb_getsampwsid(smbpass, user_sid);
2312 unbecome_root();
2314 if (ret==False) {
2315 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2316 TALLOC_FREE(smbpass);
2317 return NT_STATUS_NO_SUCH_USER;
2320 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2322 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2324 TALLOC_FREE(smbpass);
2326 return NT_STATUS_OK;
2329 /*************************************************************************
2330 get_user_info_16. Safe. Only gives out acb bits.
2331 *************************************************************************/
2333 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2334 struct samr_UserInfo16 *r,
2335 DOM_SID *user_sid)
2337 struct samu *smbpass=NULL;
2338 bool ret;
2340 ZERO_STRUCTP(r);
2342 if ( !(smbpass = samu_new( mem_ctx )) ) {
2343 return NT_STATUS_NO_MEMORY;
2346 become_root();
2347 ret = pdb_getsampwsid(smbpass, user_sid);
2348 unbecome_root();
2350 if (ret==False) {
2351 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2352 TALLOC_FREE(smbpass);
2353 return NT_STATUS_NO_SUCH_USER;
2356 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2358 init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2360 TALLOC_FREE(smbpass);
2362 return NT_STATUS_OK;
2365 /*************************************************************************
2366 get_user_info_18. OK - this is the killer as it gives out password info.
2367 Ensure that this is only allowed on an encrypted connection with a root
2368 user. JRA.
2369 *************************************************************************/
2371 static NTSTATUS get_user_info_18(pipes_struct *p,
2372 TALLOC_CTX *mem_ctx,
2373 struct samr_UserInfo18 *r,
2374 DOM_SID *user_sid)
2376 struct samu *smbpass=NULL;
2377 bool ret;
2379 ZERO_STRUCTP(r);
2381 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2382 return NT_STATUS_ACCESS_DENIED;
2385 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2386 return NT_STATUS_ACCESS_DENIED;
2390 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2393 if ( !(smbpass = samu_new( mem_ctx )) ) {
2394 return NT_STATUS_NO_MEMORY;
2397 ret = pdb_getsampwsid(smbpass, user_sid);
2399 if (ret == False) {
2400 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2401 TALLOC_FREE(smbpass);
2402 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2405 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2407 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2408 TALLOC_FREE(smbpass);
2409 return NT_STATUS_ACCOUNT_DISABLED;
2412 init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2413 pdb_get_nt_passwd(smbpass));
2415 TALLOC_FREE(smbpass);
2417 return NT_STATUS_OK;
2420 /*************************************************************************
2421 get_user_info_20
2422 *************************************************************************/
2424 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2425 struct samr_UserInfo20 *r,
2426 DOM_SID *user_sid)
2428 struct samu *sampass=NULL;
2429 bool ret;
2430 const char *munged_dial = NULL;
2431 DATA_BLOB blob;
2432 NTSTATUS status;
2433 struct lsa_BinaryString *parameters = NULL;
2435 ZERO_STRUCTP(r);
2437 if ( !(sampass = samu_new( mem_ctx )) ) {
2438 return NT_STATUS_NO_MEMORY;
2441 become_root();
2442 ret = pdb_getsampwsid(sampass, user_sid);
2443 unbecome_root();
2445 if (ret == False) {
2446 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2447 TALLOC_FREE(sampass);
2448 return NT_STATUS_NO_SUCH_USER;
2451 munged_dial = pdb_get_munged_dial(sampass);
2453 samr_clear_sam_passwd(sampass);
2455 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2456 munged_dial, (int)strlen(munged_dial)));
2458 if (munged_dial) {
2459 blob = base64_decode_data_blob(munged_dial);
2460 } else {
2461 blob = data_blob_string_const_null("");
2464 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2465 data_blob_free(&blob);
2466 TALLOC_FREE(sampass);
2467 if (!NT_STATUS_IS_OK(status)) {
2468 return status;
2471 init_samr_user_info20(r, parameters);
2473 return NT_STATUS_OK;
2477 /*************************************************************************
2478 get_user_info_21
2479 *************************************************************************/
2481 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2482 struct samr_UserInfo21 *r,
2483 DOM_SID *user_sid,
2484 DOM_SID *domain_sid)
2486 NTSTATUS status;
2487 struct samu *pw = NULL;
2488 bool ret;
2489 const DOM_SID *sid_user, *sid_group;
2490 uint32_t rid, primary_gid;
2491 NTTIME last_logon, last_logoff, last_password_change,
2492 acct_expiry, allow_password_change, force_password_change;
2493 time_t must_change_time;
2494 uint8_t password_expired;
2495 const char *account_name, *full_name, *home_directory, *home_drive,
2496 *logon_script, *profile_path, *description,
2497 *workstations, *comment;
2498 struct samr_LogonHours logon_hours;
2499 struct lsa_BinaryString *parameters = NULL;
2500 const char *munged_dial = NULL;
2501 DATA_BLOB blob;
2503 ZERO_STRUCTP(r);
2505 if (!(pw = samu_new(mem_ctx))) {
2506 return NT_STATUS_NO_MEMORY;
2509 become_root();
2510 ret = pdb_getsampwsid(pw, user_sid);
2511 unbecome_root();
2513 if (ret == False) {
2514 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2515 TALLOC_FREE(pw);
2516 return NT_STATUS_NO_SUCH_USER;
2519 samr_clear_sam_passwd(pw);
2521 DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2523 sid_user = pdb_get_user_sid(pw);
2525 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2526 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2527 "the domain sid %s. Failing operation.\n",
2528 pdb_get_username(pw), sid_string_dbg(sid_user),
2529 sid_string_dbg(domain_sid)));
2530 TALLOC_FREE(pw);
2531 return NT_STATUS_UNSUCCESSFUL;
2534 become_root();
2535 sid_group = pdb_get_group_sid(pw);
2536 unbecome_root();
2538 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2539 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2540 "which conflicts with the domain sid %s. Failing operation.\n",
2541 pdb_get_username(pw), sid_string_dbg(sid_group),
2542 sid_string_dbg(domain_sid)));
2543 TALLOC_FREE(pw);
2544 return NT_STATUS_UNSUCCESSFUL;
2547 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2548 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2549 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2550 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2551 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2553 must_change_time = pdb_get_pass_must_change_time(pw);
2554 if (must_change_time == get_time_t_max()) {
2555 unix_to_nt_time_abs(&force_password_change, must_change_time);
2556 } else {
2557 unix_to_nt_time(&force_password_change, must_change_time);
2560 if (pdb_get_pass_must_change_time(pw) == 0) {
2561 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2562 } else {
2563 password_expired = 0;
2566 munged_dial = pdb_get_munged_dial(pw);
2567 if (munged_dial) {
2568 blob = base64_decode_data_blob(munged_dial);
2569 } else {
2570 blob = data_blob_string_const_null("");
2573 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2574 data_blob_free(&blob);
2575 if (!NT_STATUS_IS_OK(status)) {
2576 TALLOC_FREE(pw);
2577 return status;
2580 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2581 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2582 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2583 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2584 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2585 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2586 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2587 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2588 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2590 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2591 #if 0
2594 Look at a user on a real NT4 PDC with usrmgr, press
2595 'ok'. Then you will see that fields_present is set to
2596 0x08f827fa. Look at the user immediately after that again,
2597 and you will see that 0x00fffff is returned. This solves
2598 the problem that you get access denied after having looked
2599 at the user.
2600 -- Volker
2603 #endif
2605 init_samr_user_info21(r,
2606 last_logon,
2607 last_logoff,
2608 last_password_change,
2609 acct_expiry,
2610 allow_password_change,
2611 force_password_change,
2612 account_name,
2613 full_name,
2614 home_directory,
2615 home_drive,
2616 logon_script,
2617 profile_path,
2618 description,
2619 workstations,
2620 comment,
2621 parameters,
2622 rid,
2623 primary_gid,
2624 pdb_get_acct_ctrl(pw),
2625 pdb_build_fields_present(pw),
2626 logon_hours,
2627 pdb_get_bad_password_count(pw),
2628 pdb_get_logon_count(pw),
2629 0, /* country_code */
2630 0, /* code_page */
2631 0, /* nt_password_set */
2632 0, /* lm_password_set */
2633 password_expired);
2634 TALLOC_FREE(pw);
2636 return NT_STATUS_OK;
2639 /*******************************************************************
2640 _samr_QueryUserInfo
2641 ********************************************************************/
2643 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2644 struct samr_QueryUserInfo *r)
2646 NTSTATUS status;
2647 union samr_UserInfo *user_info = NULL;
2648 struct samr_info *info = NULL;
2649 DOM_SID domain_sid;
2650 uint32 rid;
2652 /* search for the handle */
2653 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2654 return NT_STATUS_INVALID_HANDLE;
2656 status = access_check_samr_function(info->acc_granted,
2657 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2658 "_samr_QueryUserInfo");
2659 if (!NT_STATUS_IS_OK(status)) {
2660 return status;
2663 domain_sid = info->sid;
2665 sid_split_rid(&domain_sid, &rid);
2667 if (!sid_check_is_in_our_domain(&info->sid))
2668 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2670 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2671 sid_string_dbg(&info->sid)));
2673 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2674 if (!user_info) {
2675 return NT_STATUS_NO_MEMORY;
2678 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2680 switch (r->in.level) {
2681 case 7:
2682 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2683 if (!NT_STATUS_IS_OK(status)) {
2684 return status;
2686 break;
2687 case 9:
2688 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2689 if (!NT_STATUS_IS_OK(status)) {
2690 return status;
2692 break;
2693 case 16:
2694 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2695 if (!NT_STATUS_IS_OK(status)) {
2696 return status;
2698 break;
2700 case 18:
2701 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2702 if (!NT_STATUS_IS_OK(status)) {
2703 return status;
2705 break;
2707 case 20:
2708 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2709 if (!NT_STATUS_IS_OK(status)) {
2710 return status;
2712 break;
2714 case 21:
2715 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2716 &info->sid, &domain_sid);
2717 if (!NT_STATUS_IS_OK(status)) {
2718 return status;
2720 break;
2722 default:
2723 return NT_STATUS_INVALID_INFO_CLASS;
2726 *r->out.info = user_info;
2728 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2730 return status;
2733 /*******************************************************************
2734 _samr_GetGroupsForUser
2735 ********************************************************************/
2737 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2738 struct samr_GetGroupsForUser *r)
2740 struct samu *sam_pass=NULL;
2741 DOM_SID sid;
2742 DOM_SID *sids;
2743 struct samr_RidWithAttribute dom_gid;
2744 struct samr_RidWithAttribute *gids = NULL;
2745 uint32 primary_group_rid;
2746 size_t num_groups = 0;
2747 gid_t *unix_gids;
2748 size_t i, num_gids;
2749 uint32 acc_granted;
2750 bool ret;
2751 NTSTATUS result;
2752 bool success = False;
2754 struct samr_RidWithAttributeArray *rids = NULL;
2757 * from the SID in the request:
2758 * we should send back the list of DOMAIN GROUPS
2759 * the user is a member of
2761 * and only the DOMAIN GROUPS
2762 * no ALIASES !!! neither aliases of the domain
2763 * nor aliases of the builtin SID
2765 * JFM, 12/2/2001
2768 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2770 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2771 if (!rids) {
2772 return NT_STATUS_NO_MEMORY;
2775 /* find the policy handle. open a policy on it. */
2776 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2777 return NT_STATUS_INVALID_HANDLE;
2779 result = access_check_samr_function(acc_granted,
2780 SA_RIGHT_USER_GET_GROUPS,
2781 "_samr_GetGroupsForUser");
2782 if (!NT_STATUS_IS_OK(result)) {
2783 return result;
2786 if (!sid_check_is_in_our_domain(&sid))
2787 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2789 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2790 return NT_STATUS_NO_MEMORY;
2793 become_root();
2794 ret = pdb_getsampwsid(sam_pass, &sid);
2795 unbecome_root();
2797 if (!ret) {
2798 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2799 sid_string_dbg(&sid)));
2800 return NT_STATUS_NO_SUCH_USER;
2803 sids = NULL;
2805 /* make both calls inside the root block */
2806 become_root();
2807 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2808 &sids, &unix_gids, &num_groups);
2809 if ( NT_STATUS_IS_OK(result) ) {
2810 success = sid_peek_check_rid(get_global_sam_sid(),
2811 pdb_get_group_sid(sam_pass),
2812 &primary_group_rid);
2814 unbecome_root();
2816 if (!NT_STATUS_IS_OK(result)) {
2817 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2818 sid_string_dbg(&sid)));
2819 return result;
2822 if ( !success ) {
2823 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2824 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2825 pdb_get_username(sam_pass)));
2826 TALLOC_FREE(sam_pass);
2827 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2830 gids = NULL;
2831 num_gids = 0;
2833 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2834 SE_GROUP_ENABLED);
2835 dom_gid.rid = primary_group_rid;
2836 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2838 for (i=0; i<num_groups; i++) {
2840 if (!sid_peek_check_rid(get_global_sam_sid(),
2841 &(sids[i]), &dom_gid.rid)) {
2842 DEBUG(10, ("Found sid %s not in our domain\n",
2843 sid_string_dbg(&sids[i])));
2844 continue;
2847 if (dom_gid.rid == primary_group_rid) {
2848 /* We added the primary group directly from the
2849 * sam_account. The other SIDs are unique from
2850 * enum_group_memberships */
2851 continue;
2854 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2857 rids->count = num_gids;
2858 rids->rids = gids;
2860 *r->out.rids = rids;
2862 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2864 return result;
2867 /*******************************************************************
2868 samr_QueryDomainInfo_internal
2869 ********************************************************************/
2871 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2872 pipes_struct *p,
2873 struct policy_handle *handle,
2874 uint32_t level,
2875 union samr_DomainInfo **dom_info_ptr)
2877 NTSTATUS status = NT_STATUS_OK;
2878 struct samr_info *info = NULL;
2879 union samr_DomainInfo *dom_info;
2880 uint32 min_pass_len,pass_hist,password_properties;
2881 time_t u_expire, u_min_age;
2882 NTTIME nt_expire, nt_min_age;
2884 time_t u_lock_duration, u_reset_time;
2885 NTTIME nt_lock_duration, nt_reset_time;
2886 uint32 lockout;
2887 time_t u_logout;
2888 NTTIME nt_logout;
2890 uint32 account_policy_temp;
2892 time_t seq_num;
2893 uint32 server_role;
2895 uint32 num_users=0, num_groups=0, num_aliases=0;
2897 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2899 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2900 if (!dom_info) {
2901 return NT_STATUS_NO_MEMORY;
2904 *dom_info_ptr = dom_info;
2906 /* find the policy handle. open a policy on it. */
2907 if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2908 return NT_STATUS_INVALID_HANDLE;
2911 status = access_check_samr_function(info->acc_granted,
2912 SA_RIGHT_SAM_OPEN_DOMAIN,
2913 "_samr_QueryDomainInfo_internal" );
2915 if ( !NT_STATUS_IS_OK(status) )
2916 return status;
2918 switch (level) {
2919 case 0x01:
2921 become_root();
2923 /* AS ROOT !!! */
2925 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2926 min_pass_len = account_policy_temp;
2928 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2929 pass_hist = account_policy_temp;
2931 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2932 password_properties = account_policy_temp;
2934 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2935 u_expire = account_policy_temp;
2937 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2938 u_min_age = account_policy_temp;
2940 /* !AS ROOT */
2942 unbecome_root();
2944 unix_to_nt_time_abs(&nt_expire, u_expire);
2945 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2947 if (lp_check_password_script() && *lp_check_password_script()) {
2948 password_properties |= DOMAIN_PASSWORD_COMPLEX;
2951 init_samr_DomInfo1(&dom_info->info1,
2952 (uint16)min_pass_len,
2953 (uint16)pass_hist,
2954 password_properties,
2955 nt_expire,
2956 nt_min_age);
2957 break;
2958 case 0x02:
2960 become_root();
2962 /* AS ROOT !!! */
2964 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2965 num_groups = count_sam_groups(info->disp_info);
2966 num_aliases = count_sam_aliases(info->disp_info);
2968 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2969 u_logout = account_policy_temp;
2971 unix_to_nt_time_abs(&nt_logout, u_logout);
2973 if (!pdb_get_seq_num(&seq_num))
2974 seq_num = time(NULL);
2976 /* !AS ROOT */
2978 unbecome_root();
2980 server_role = ROLE_DOMAIN_PDC;
2981 if (lp_server_role() == ROLE_DOMAIN_BDC)
2982 server_role = ROLE_DOMAIN_BDC;
2984 init_samr_DomGeneralInformation(&dom_info->general,
2985 nt_logout,
2986 lp_serverstring(),
2987 lp_workgroup(),
2988 global_myname(),
2989 seq_num,
2991 server_role,
2993 num_users,
2994 num_groups,
2995 num_aliases);
2996 break;
2997 case 0x03:
2999 become_root();
3001 /* AS ROOT !!! */
3004 uint32 ul;
3005 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
3006 u_logout = (time_t)ul;
3009 /* !AS ROOT */
3011 unbecome_root();
3013 unix_to_nt_time_abs(&nt_logout, u_logout);
3015 init_samr_DomInfo3(&dom_info->info3,
3016 nt_logout);
3018 break;
3019 case 0x04:
3020 init_samr_DomOEMInformation(&dom_info->oem,
3021 lp_serverstring());
3022 break;
3023 case 0x05:
3024 init_samr_DomInfo5(&dom_info->info5,
3025 get_global_sam_name());
3026 break;
3027 case 0x06:
3028 /* NT returns its own name when a PDC. win2k and later
3029 * only the name of the PDC if itself is a BDC (samba4
3030 * idl) */
3031 init_samr_DomInfo6(&dom_info->info6,
3032 global_myname());
3033 break;
3034 case 0x07:
3035 server_role = ROLE_DOMAIN_PDC;
3036 if (lp_server_role() == ROLE_DOMAIN_BDC)
3037 server_role = ROLE_DOMAIN_BDC;
3039 init_samr_DomInfo7(&dom_info->info7,
3040 server_role);
3041 break;
3042 case 0x08:
3044 become_root();
3046 /* AS ROOT !!! */
3048 if (!pdb_get_seq_num(&seq_num)) {
3049 seq_num = time(NULL);
3052 /* !AS ROOT */
3054 unbecome_root();
3056 init_samr_DomInfo8(&dom_info->info8,
3057 seq_num,
3059 break;
3060 case 0x0c:
3062 become_root();
3064 /* AS ROOT !!! */
3066 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3067 u_lock_duration = account_policy_temp;
3068 if (u_lock_duration != -1) {
3069 u_lock_duration *= 60;
3072 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3073 u_reset_time = account_policy_temp * 60;
3075 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3076 lockout = account_policy_temp;
3078 /* !AS ROOT */
3080 unbecome_root();
3082 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3083 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3085 init_samr_DomInfo12(&dom_info->info12,
3086 nt_lock_duration,
3087 nt_reset_time,
3088 (uint16)lockout);
3089 break;
3090 default:
3091 return NT_STATUS_INVALID_INFO_CLASS;
3094 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
3096 return status;
3099 /*******************************************************************
3100 _samr_QueryDomainInfo
3101 ********************************************************************/
3103 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3104 struct samr_QueryDomainInfo *r)
3106 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
3108 r->in.domain_handle,
3109 r->in.level,
3110 r->out.info);
3113 /* W2k3 seems to use the same check for all 3 objects that can be created via
3114 * SAMR, if you try to create for example "Dialup" as an alias it says
3115 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3116 * database. */
3118 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3120 enum lsa_SidType type;
3121 bool result;
3123 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3125 become_root();
3126 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3127 * whether the name already exists */
3128 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3129 NULL, NULL, NULL, &type);
3130 unbecome_root();
3132 if (!result) {
3133 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3134 return NT_STATUS_OK;
3137 DEBUG(5, ("trying to create %s, exists as %s\n",
3138 new_name, sid_type_lookup(type)));
3140 if (type == SID_NAME_DOM_GRP) {
3141 return NT_STATUS_GROUP_EXISTS;
3143 if (type == SID_NAME_ALIAS) {
3144 return NT_STATUS_ALIAS_EXISTS;
3147 /* Yes, the default is NT_STATUS_USER_EXISTS */
3148 return NT_STATUS_USER_EXISTS;
3151 /*******************************************************************
3152 _samr_CreateUser2
3153 ********************************************************************/
3155 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3156 struct samr_CreateUser2 *r)
3158 const char *account = NULL;
3159 DOM_SID sid;
3160 POLICY_HND dom_pol = *r->in.domain_handle;
3161 uint32_t acb_info = r->in.acct_flags;
3162 POLICY_HND *user_pol = r->out.user_handle;
3163 struct samr_info *info = NULL;
3164 NTSTATUS nt_status;
3165 uint32 acc_granted;
3166 SEC_DESC *psd;
3167 size_t sd_size;
3168 /* check this, when giving away 'add computer to domain' privs */
3169 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3170 bool can_add_account = False;
3171 SE_PRIV se_rights;
3172 DISP_INFO *disp_info = NULL;
3174 /* Get the domain SID stored in the domain policy */
3175 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3176 &disp_info))
3177 return NT_STATUS_INVALID_HANDLE;
3179 nt_status = access_check_samr_function(acc_granted,
3180 SA_RIGHT_DOMAIN_CREATE_USER,
3181 "_samr_CreateUser2");
3182 if (!NT_STATUS_IS_OK(nt_status)) {
3183 return nt_status;
3186 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3187 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3188 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3189 this parameter is not an account type */
3190 return NT_STATUS_INVALID_PARAMETER;
3193 account = r->in.account_name->string;
3194 if (account == NULL) {
3195 return NT_STATUS_NO_MEMORY;
3198 nt_status = can_create(p->mem_ctx, account);
3199 if (!NT_STATUS_IS_OK(nt_status)) {
3200 return nt_status;
3203 /* determine which user right we need to check based on the acb_info */
3205 if ( acb_info & ACB_WSTRUST )
3207 se_priv_copy( &se_rights, &se_machine_account );
3208 can_add_account = user_has_privileges(
3209 p->pipe_user.nt_user_token, &se_rights );
3211 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3212 account for domain trusts and changes the ACB flags later */
3213 else if ( acb_info & ACB_NORMAL &&
3214 (account[strlen(account)-1] != '$') )
3216 se_priv_copy( &se_rights, &se_add_users );
3217 can_add_account = user_has_privileges(
3218 p->pipe_user.nt_user_token, &se_rights );
3220 else /* implicit assumption of a BDC or domain trust account here
3221 * (we already check the flags earlier) */
3223 if ( lp_enable_privileges() ) {
3224 /* only Domain Admins can add a BDC or domain trust */
3225 se_priv_copy( &se_rights, &se_priv_none );
3226 can_add_account = nt_token_check_domain_rid(
3227 p->pipe_user.nt_user_token,
3228 DOMAIN_GROUP_RID_ADMINS );
3232 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3233 uidtoname(p->pipe_user.ut.uid),
3234 can_add_account ? "True":"False" ));
3236 /********** BEGIN Admin BLOCK **********/
3238 if ( can_add_account )
3239 become_root();
3241 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3242 r->out.rid);
3244 if ( can_add_account )
3245 unbecome_root();
3247 /********** END Admin BLOCK **********/
3249 /* now check for failure */
3251 if ( !NT_STATUS_IS_OK(nt_status) )
3252 return nt_status;
3254 /* Get the user's SID */
3256 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3258 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3259 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3260 se_map_generic(&des_access, &usr_generic_mapping);
3262 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3263 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3264 &acc_granted, "_samr_CreateUser2");
3266 if ( !NT_STATUS_IS_OK(nt_status) ) {
3267 return nt_status;
3270 /* associate the user's SID with the new handle. */
3271 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3272 return NT_STATUS_NO_MEMORY;
3275 ZERO_STRUCTP(info);
3276 info->sid = sid;
3277 info->acc_granted = acc_granted;
3279 /* get a (unique) handle. open a policy on it. */
3280 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3281 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3284 /* After a "set" ensure we have no cached display info. */
3285 force_flush_samr_cache(info->disp_info);
3287 *r->out.access_granted = acc_granted;
3289 return NT_STATUS_OK;
3292 /*******************************************************************
3293 _samr_Connect
3294 ********************************************************************/
3296 NTSTATUS _samr_Connect(pipes_struct *p,
3297 struct samr_Connect *r)
3299 struct samr_info *info = NULL;
3300 uint32 des_access = r->in.access_mask;
3302 /* Access check */
3304 if (!pipe_access_check(p)) {
3305 DEBUG(3, ("access denied to _samr_Connect\n"));
3306 return NT_STATUS_ACCESS_DENIED;
3309 /* set up the SAMR connect_anon response */
3311 /* associate the user's SID with the new handle. */
3312 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3313 return NT_STATUS_NO_MEMORY;
3315 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3316 was observed from a win98 client trying to enumerate users (when configured
3317 user level access control on shares) --jerry */
3319 if (des_access == MAXIMUM_ALLOWED_ACCESS) {
3320 /* Map to max possible knowing we're filtered below. */
3321 des_access = GENERIC_ALL_ACCESS;
3324 se_map_generic( &des_access, &sam_generic_mapping );
3325 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3327 /* get a (unique) handle. open a policy on it. */
3328 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3329 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3331 return NT_STATUS_OK;
3334 /*******************************************************************
3335 _samr_Connect2
3336 ********************************************************************/
3338 NTSTATUS _samr_Connect2(pipes_struct *p,
3339 struct samr_Connect2 *r)
3341 struct samr_info *info = NULL;
3342 SEC_DESC *psd = NULL;
3343 uint32 acc_granted;
3344 uint32 des_access = r->in.access_mask;
3345 NTSTATUS nt_status;
3346 size_t sd_size;
3349 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3351 /* Access check */
3353 if (!pipe_access_check(p)) {
3354 DEBUG(3, ("access denied to _samr_Connect2\n"));
3355 return NT_STATUS_ACCESS_DENIED;
3358 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3359 se_map_generic(&des_access, &sam_generic_mapping);
3361 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3362 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3364 if ( !NT_STATUS_IS_OK(nt_status) )
3365 return nt_status;
3367 /* associate the user's SID and access granted with the new handle. */
3368 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3369 return NT_STATUS_NO_MEMORY;
3371 info->acc_granted = acc_granted;
3372 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3374 /* get a (unique) handle. open a policy on it. */
3375 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3376 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3378 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3380 return nt_status;
3383 /*******************************************************************
3384 _samr_Connect4
3385 ********************************************************************/
3387 NTSTATUS _samr_Connect4(pipes_struct *p,
3388 struct samr_Connect4 *r)
3390 struct samr_info *info = NULL;
3391 SEC_DESC *psd = NULL;
3392 uint32 acc_granted;
3393 uint32 des_access = r->in.access_mask;
3394 NTSTATUS nt_status;
3395 size_t sd_size;
3398 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3400 /* Access check */
3402 if (!pipe_access_check(p)) {
3403 DEBUG(3, ("access denied to samr_Connect4\n"));
3404 return NT_STATUS_ACCESS_DENIED;
3407 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3408 se_map_generic(&des_access, &sam_generic_mapping);
3410 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3411 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3413 if ( !NT_STATUS_IS_OK(nt_status) )
3414 return nt_status;
3416 /* associate the user's SID and access granted with the new handle. */
3417 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3418 return NT_STATUS_NO_MEMORY;
3420 info->acc_granted = acc_granted;
3421 info->status = r->in.access_mask; /* ??? */
3423 /* get a (unique) handle. open a policy on it. */
3424 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3425 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3427 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3429 return NT_STATUS_OK;
3432 /*******************************************************************
3433 _samr_Connect5
3434 ********************************************************************/
3436 NTSTATUS _samr_Connect5(pipes_struct *p,
3437 struct samr_Connect5 *r)
3439 struct samr_info *info = NULL;
3440 SEC_DESC *psd = NULL;
3441 uint32 acc_granted;
3442 uint32 des_access = r->in.access_mask;
3443 NTSTATUS nt_status;
3444 size_t sd_size;
3445 struct samr_ConnectInfo1 info1;
3447 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3449 /* Access check */
3451 if (!pipe_access_check(p)) {
3452 DEBUG(3, ("access denied to samr_Connect5\n"));
3453 return NT_STATUS_ACCESS_DENIED;
3456 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3457 se_map_generic(&des_access, &sam_generic_mapping);
3459 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3460 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3462 if ( !NT_STATUS_IS_OK(nt_status) )
3463 return nt_status;
3465 /* associate the user's SID and access granted with the new handle. */
3466 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3467 return NT_STATUS_NO_MEMORY;
3469 info->acc_granted = acc_granted;
3470 info->status = r->in.access_mask; /* ??? */
3472 /* get a (unique) handle. open a policy on it. */
3473 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3474 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3476 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3478 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3479 info1.unknown2 = 0;
3481 *r->out.level_out = 1;
3482 r->out.info_out->info1 = info1;
3484 return NT_STATUS_OK;
3487 /**********************************************************************
3488 _samr_LookupDomain
3489 **********************************************************************/
3491 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3492 struct samr_LookupDomain *r)
3494 NTSTATUS status = NT_STATUS_OK;
3495 struct samr_info *info;
3496 const char *domain_name;
3497 DOM_SID *sid = NULL;
3499 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3500 return NT_STATUS_INVALID_HANDLE;
3502 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3503 Reverted that change so we will work with RAS servers again */
3505 status = access_check_samr_function(info->acc_granted,
3506 SA_RIGHT_SAM_OPEN_DOMAIN,
3507 "_samr_LookupDomain");
3508 if (!NT_STATUS_IS_OK(status)) {
3509 return status;
3512 domain_name = r->in.domain_name->string;
3514 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3515 if (!sid) {
3516 return NT_STATUS_NO_MEMORY;
3519 if (strequal(domain_name, builtin_domain_name())) {
3520 sid_copy(sid, &global_sid_Builtin);
3521 } else {
3522 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3523 status = NT_STATUS_NO_SUCH_DOMAIN;
3527 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3528 sid_string_dbg(sid)));
3530 *r->out.sid = sid;
3532 return status;
3535 /**********************************************************************
3536 _samr_EnumDomains
3537 **********************************************************************/
3539 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3540 struct samr_EnumDomains *r)
3542 NTSTATUS status;
3543 struct samr_info *info;
3544 uint32_t num_entries = 2;
3545 struct samr_SamEntry *entry_array = NULL;
3546 struct samr_SamArray *sam;
3548 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3549 return NT_STATUS_INVALID_HANDLE;
3551 status = access_check_samr_function(info->acc_granted,
3552 SA_RIGHT_SAM_ENUM_DOMAINS,
3553 "_samr_EnumDomains");
3554 if (!NT_STATUS_IS_OK(status)) {
3555 return status;
3558 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3559 if (!sam) {
3560 return NT_STATUS_NO_MEMORY;
3563 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3564 struct samr_SamEntry,
3565 num_entries);
3566 if (!entry_array) {
3567 return NT_STATUS_NO_MEMORY;
3570 entry_array[0].idx = 0;
3571 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3573 entry_array[1].idx = 1;
3574 init_lsa_String(&entry_array[1].name, "Builtin");
3576 sam->count = num_entries;
3577 sam->entries = entry_array;
3579 *r->out.sam = sam;
3580 *r->out.num_entries = num_entries;
3582 return status;
3585 /*******************************************************************
3586 _samr_OpenAlias
3587 ********************************************************************/
3589 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3590 struct samr_OpenAlias *r)
3592 DOM_SID sid;
3593 POLICY_HND domain_pol = *r->in.domain_handle;
3594 uint32 alias_rid = r->in.rid;
3595 POLICY_HND *alias_pol = r->out.alias_handle;
3596 struct samr_info *info = NULL;
3597 SEC_DESC *psd = NULL;
3598 uint32 acc_granted;
3599 uint32 des_access = r->in.access_mask;
3600 size_t sd_size;
3601 NTSTATUS status;
3602 SE_PRIV se_rights;
3604 /* find the domain policy and get the SID / access bits stored in the domain policy */
3606 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3607 return NT_STATUS_INVALID_HANDLE;
3609 status = access_check_samr_function(acc_granted,
3610 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3611 "_samr_OpenAlias");
3613 if ( !NT_STATUS_IS_OK(status) )
3614 return status;
3616 /* append the alias' RID to it */
3618 if (!sid_append_rid(&sid, alias_rid))
3619 return NT_STATUS_NO_SUCH_ALIAS;
3621 /*check if access can be granted as requested by client. */
3623 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3624 se_map_generic(&des_access,&ali_generic_mapping);
3626 se_priv_copy( &se_rights, &se_add_users );
3629 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3630 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3631 &acc_granted, "_samr_OpenAlias");
3633 if ( !NT_STATUS_IS_OK(status) )
3634 return status;
3637 /* Check we actually have the requested alias */
3638 enum lsa_SidType type;
3639 bool result;
3640 gid_t gid;
3642 become_root();
3643 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3644 unbecome_root();
3646 if (!result || (type != SID_NAME_ALIAS)) {
3647 return NT_STATUS_NO_SUCH_ALIAS;
3650 /* make sure there is a mapping */
3652 if ( !sid_to_gid( &sid, &gid ) ) {
3653 return NT_STATUS_NO_SUCH_ALIAS;
3658 /* associate the alias SID with the new handle. */
3659 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3660 return NT_STATUS_NO_MEMORY;
3662 info->acc_granted = acc_granted;
3664 /* get a (unique) handle. open a policy on it. */
3665 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3666 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3668 return NT_STATUS_OK;
3671 /*******************************************************************
3672 set_user_info_7
3673 ********************************************************************/
3675 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3676 struct samr_UserInfo7 *id7,
3677 struct samu *pwd)
3679 NTSTATUS rc;
3681 if (id7 == NULL) {
3682 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3683 TALLOC_FREE(pwd);
3684 return NT_STATUS_ACCESS_DENIED;
3687 if (!id7->account_name.string) {
3688 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3689 TALLOC_FREE(pwd);
3690 return NT_STATUS_ACCESS_DENIED;
3693 /* check to see if the new username already exists. Note: we can't
3694 reliably lock all backends, so there is potentially the
3695 possibility that a user can be created in between this check and
3696 the rename. The rename should fail, but may not get the
3697 exact same failure status code. I think this is small enough
3698 of a window for this type of operation and the results are
3699 simply that the rename fails with a slightly different status
3700 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3702 rc = can_create(mem_ctx, id7->account_name.string);
3703 if (!NT_STATUS_IS_OK(rc)) {
3704 return rc;
3707 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3709 TALLOC_FREE(pwd);
3710 return rc;
3713 /*******************************************************************
3714 set_user_info_16
3715 ********************************************************************/
3717 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3718 struct samu *pwd)
3720 if (id16 == NULL) {
3721 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3722 TALLOC_FREE(pwd);
3723 return False;
3726 /* FIX ME: check if the value is really changed --metze */
3727 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3728 TALLOC_FREE(pwd);
3729 return False;
3732 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3733 TALLOC_FREE(pwd);
3734 return False;
3737 TALLOC_FREE(pwd);
3739 return True;
3742 /*******************************************************************
3743 set_user_info_18
3744 ********************************************************************/
3746 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3747 struct samu *pwd)
3749 if (id18 == NULL) {
3750 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3751 TALLOC_FREE(pwd);
3752 return False;
3755 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3756 TALLOC_FREE(pwd);
3757 return False;
3759 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3760 TALLOC_FREE(pwd);
3761 return False;
3763 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3764 TALLOC_FREE(pwd);
3765 return False;
3768 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3769 TALLOC_FREE(pwd);
3770 return False;
3773 TALLOC_FREE(pwd);
3774 return True;
3777 /*******************************************************************
3778 set_user_info_20
3779 ********************************************************************/
3781 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3782 struct samu *pwd)
3784 if (id20 == NULL) {
3785 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3786 return False;
3789 copy_id20_to_sam_passwd(pwd, id20);
3791 /* write the change out */
3792 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3793 TALLOC_FREE(pwd);
3794 return False;
3797 TALLOC_FREE(pwd);
3799 return True;
3802 /*******************************************************************
3803 set_user_info_21
3804 ********************************************************************/
3806 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3807 struct samr_UserInfo21 *id21,
3808 struct samu *pwd)
3810 NTSTATUS status;
3812 if (id21 == NULL) {
3813 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3814 return NT_STATUS_INVALID_PARAMETER;
3817 /* we need to separately check for an account rename first */
3819 if (id21->account_name.string &&
3820 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3823 /* check to see if the new username already exists. Note: we can't
3824 reliably lock all backends, so there is potentially the
3825 possibility that a user can be created in between this check and
3826 the rename. The rename should fail, but may not get the
3827 exact same failure status code. I think this is small enough
3828 of a window for this type of operation and the results are
3829 simply that the rename fails with a slightly different status
3830 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3832 status = can_create(mem_ctx, id21->account_name.string);
3833 if (!NT_STATUS_IS_OK(status)) {
3834 return status;
3837 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3839 if (!NT_STATUS_IS_OK(status)) {
3840 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3841 nt_errstr(status)));
3842 TALLOC_FREE(pwd);
3843 return status;
3846 /* set the new username so that later
3847 functions can work on the new account */
3848 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3851 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3854 * The funny part about the previous two calls is
3855 * that pwd still has the password hashes from the
3856 * passdb entry. These have not been updated from
3857 * id21. I don't know if they need to be set. --jerry
3860 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3861 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3862 if ( !NT_STATUS_IS_OK(status) ) {
3863 return status;
3867 /* Don't worry about writing out the user account since the
3868 primary group SID is generated solely from the user's Unix
3869 primary group. */
3871 /* write the change out */
3872 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3873 TALLOC_FREE(pwd);
3874 return status;
3877 TALLOC_FREE(pwd);
3879 return NT_STATUS_OK;
3882 /*******************************************************************
3883 set_user_info_23
3884 ********************************************************************/
3886 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3887 struct samr_UserInfo23 *id23,
3888 struct samu *pwd)
3890 char *plaintext_buf = NULL;
3891 uint32 len = 0;
3892 uint16 acct_ctrl;
3893 NTSTATUS status;
3895 if (id23 == NULL) {
3896 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3897 return NT_STATUS_INVALID_PARAMETER;
3900 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3901 pdb_get_username(pwd)));
3903 acct_ctrl = pdb_get_acct_ctrl(pwd);
3905 if (!decode_pw_buffer(mem_ctx,
3906 id23->password.data,
3907 &plaintext_buf,
3908 &len,
3909 STR_UNICODE)) {
3910 TALLOC_FREE(pwd);
3911 return NT_STATUS_INVALID_PARAMETER;
3914 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3915 TALLOC_FREE(pwd);
3916 return NT_STATUS_ACCESS_DENIED;
3919 copy_id23_to_sam_passwd(pwd, id23);
3921 /* if it's a trust account, don't update /etc/passwd */
3922 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3923 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3924 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3925 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3926 } else {
3927 /* update the UNIX password */
3928 if (lp_unix_password_sync() ) {
3929 struct passwd *passwd;
3930 if (pdb_get_username(pwd) == NULL) {
3931 DEBUG(1, ("chgpasswd: User without name???\n"));
3932 TALLOC_FREE(pwd);
3933 return NT_STATUS_ACCESS_DENIED;
3936 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3937 if (passwd == NULL) {
3938 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3941 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3942 TALLOC_FREE(pwd);
3943 return NT_STATUS_ACCESS_DENIED;
3945 TALLOC_FREE(passwd);
3949 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3951 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3952 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3953 pwd)))) {
3954 TALLOC_FREE(pwd);
3955 return status;
3958 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3959 TALLOC_FREE(pwd);
3960 return status;
3963 TALLOC_FREE(pwd);
3965 return NT_STATUS_OK;
3968 /*******************************************************************
3969 set_user_info_pw
3970 ********************************************************************/
3972 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
3973 int level)
3975 uint32 len = 0;
3976 char *plaintext_buf = NULL;
3977 uint32 acct_ctrl;
3978 time_t last_set_time;
3979 enum pdb_value_state last_set_state;
3981 DEBUG(5, ("Attempting administrator password change for user %s\n",
3982 pdb_get_username(pwd)));
3984 acct_ctrl = pdb_get_acct_ctrl(pwd);
3985 /* we need to know if it's expired, because this is an admin change, not a
3986 user change, so it's still expired when we're done */
3987 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3988 last_set_time = pdb_get_pass_last_set_time(pwd);
3990 if (!decode_pw_buffer(talloc_tos(),
3991 pass,
3992 &plaintext_buf,
3993 &len,
3994 STR_UNICODE)) {
3995 TALLOC_FREE(pwd);
3996 return False;
3999 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4000 TALLOC_FREE(pwd);
4001 return False;
4004 /* if it's a trust account, don't update /etc/passwd */
4005 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4006 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
4007 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
4008 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4009 } else {
4010 /* update the UNIX password */
4011 if (lp_unix_password_sync()) {
4012 struct passwd *passwd;
4014 if (pdb_get_username(pwd) == NULL) {
4015 DEBUG(1, ("chgpasswd: User without name???\n"));
4016 TALLOC_FREE(pwd);
4017 return False;
4020 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4021 if (passwd == NULL) {
4022 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4025 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4026 TALLOC_FREE(pwd);
4027 return False;
4029 TALLOC_FREE(passwd);
4033 memset(plaintext_buf, '\0', strlen(plaintext_buf));
4036 * A level 25 change does reset the pwdlastset field, a level 24
4037 * change does not. I know this is probably not the full story, but
4038 * it is needed to make XP join LDAP correctly, without it the later
4039 * auth2 check can fail with PWD_MUST_CHANGE.
4041 if (level != 25) {
4043 * restore last set time as this is an admin change, not a
4044 * user pw change
4046 pdb_set_pass_last_set_time (pwd, last_set_time,
4047 last_set_state);
4050 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4052 /* update the SAMBA password */
4053 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4054 TALLOC_FREE(pwd);
4055 return False;
4058 TALLOC_FREE(pwd);
4060 return True;
4063 /*******************************************************************
4064 set_user_info_25
4065 ********************************************************************/
4067 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4068 struct samr_UserInfo25 *id25,
4069 struct samu *pwd)
4071 NTSTATUS status;
4073 if (id25 == NULL) {
4074 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4075 return NT_STATUS_INVALID_PARAMETER;
4078 copy_id25_to_sam_passwd(pwd, id25);
4080 /* write the change out */
4081 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4082 TALLOC_FREE(pwd);
4083 return status;
4087 * We need to "pdb_update_sam_account" before the unix primary group
4088 * is set, because the idealx scripts would also change the
4089 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4090 * the delete explicit / add explicit, which would then fail to find
4091 * the previous primaryGroupSid value.
4094 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4095 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4096 if ( !NT_STATUS_IS_OK(status) ) {
4097 return status;
4101 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
4102 * hereafter! */
4104 return NT_STATUS_OK;
4107 /*******************************************************************
4108 samr_SetUserInfo_internal
4109 ********************************************************************/
4111 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
4112 pipes_struct *p,
4113 struct policy_handle *user_handle,
4114 uint16_t level,
4115 union samr_UserInfo *info)
4117 NTSTATUS status;
4118 struct samu *pwd = NULL;
4119 DOM_SID sid;
4120 POLICY_HND *pol = user_handle;
4121 uint16_t switch_value = level;
4122 uint32_t acc_granted;
4123 uint32_t acc_required;
4124 bool ret;
4125 bool has_enough_rights = False;
4126 uint32_t acb_info;
4127 DISP_INFO *disp_info = NULL;
4129 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4131 /* find the policy handle. open a policy on it. */
4132 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4133 return NT_STATUS_INVALID_HANDLE;
4136 /* This is tricky. A WinXP domain join sets
4137 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4138 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4139 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4140 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4141 we'll use the set from the WinXP join as the basis. */
4143 switch (switch_value) {
4144 case 18:
4145 case 24:
4146 case 25:
4147 case 26:
4148 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4149 break;
4150 default:
4151 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4152 SA_RIGHT_USER_SET_ATTRIBUTES |
4153 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4154 break;
4157 status = access_check_samr_function(acc_granted,
4158 acc_required,
4159 fn_name);
4160 if (!NT_STATUS_IS_OK(status)) {
4161 return status;
4164 DEBUG(5, ("%s: sid:%s, level:%d\n",
4165 fn_name, sid_string_dbg(&sid), switch_value));
4167 if (info == NULL) {
4168 DEBUG(5, ("%s: NULL info level\n", fn_name));
4169 return NT_STATUS_INVALID_INFO_CLASS;
4172 if (!(pwd = samu_new(NULL))) {
4173 return NT_STATUS_NO_MEMORY;
4176 become_root();
4177 ret = pdb_getsampwsid(pwd, &sid);
4178 unbecome_root();
4180 if (!ret) {
4181 TALLOC_FREE(pwd);
4182 return NT_STATUS_NO_SUCH_USER;
4185 /* deal with machine password changes differently from userinfo changes */
4186 /* check to see if we have the sufficient rights */
4188 acb_info = pdb_get_acct_ctrl(pwd);
4189 if (acb_info & ACB_WSTRUST)
4190 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4191 &se_machine_account);
4192 else if (acb_info & ACB_NORMAL)
4193 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4194 &se_add_users);
4195 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4196 if (lp_enable_privileges()) {
4197 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4198 DOMAIN_GROUP_RID_ADMINS);
4202 DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4203 fn_name,
4204 uidtoname(p->pipe_user.ut.uid),
4205 has_enough_rights ? "" : " not"));
4207 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4209 if (has_enough_rights) {
4210 become_root();
4213 /* ok! user info levels (lots: see MSDEV help), off we go... */
4215 switch (switch_value) {
4217 case 7:
4218 status = set_user_info_7(p->mem_ctx,
4219 &info->info7, pwd);
4220 break;
4222 case 16:
4223 if (!set_user_info_16(&info->info16, pwd)) {
4224 status = NT_STATUS_ACCESS_DENIED;
4226 break;
4228 case 18:
4229 /* Used by AS/U JRA. */
4230 if (!set_user_info_18(&info->info18, pwd)) {
4231 status = NT_STATUS_ACCESS_DENIED;
4233 break;
4235 case 20:
4236 if (!set_user_info_20(&info->info20, pwd)) {
4237 status = NT_STATUS_ACCESS_DENIED;
4239 break;
4241 case 21:
4242 status = set_user_info_21(p->mem_ctx,
4243 &info->info21, pwd);
4244 break;
4246 case 23:
4247 if (!p->server_info->user_session_key.length) {
4248 status = NT_STATUS_NO_USER_SESSION_KEY;
4250 SamOEMhashBlob(info->info23.password.data, 516,
4251 &p->server_info->user_session_key);
4253 dump_data(100, info->info23.password.data, 516);
4255 status = set_user_info_23(p->mem_ctx,
4256 &info->info23, pwd);
4257 break;
4259 case 24:
4260 if (!p->server_info->user_session_key.length) {
4261 status = NT_STATUS_NO_USER_SESSION_KEY;
4263 SamOEMhashBlob(info->info24.password.data,
4264 516,
4265 &p->server_info->user_session_key);
4267 dump_data(100, info->info24.password.data, 516);
4269 if (!set_user_info_pw(info->info24.password.data, pwd,
4270 switch_value)) {
4271 status = NT_STATUS_ACCESS_DENIED;
4273 break;
4275 case 25:
4276 if (!p->server_info->user_session_key.length) {
4277 status = NT_STATUS_NO_USER_SESSION_KEY;
4279 encode_or_decode_arc4_passwd_buffer(
4280 info->info25.password.data,
4281 &p->server_info->user_session_key);
4283 dump_data(100, info->info25.password.data, 532);
4285 status = set_user_info_25(p->mem_ctx,
4286 &info->info25, pwd);
4287 if (!NT_STATUS_IS_OK(status)) {
4288 goto done;
4290 if (!set_user_info_pw(info->info25.password.data, pwd,
4291 switch_value)) {
4292 status = NT_STATUS_ACCESS_DENIED;
4294 break;
4296 case 26:
4297 if (!p->server_info->user_session_key.length) {
4298 status = NT_STATUS_NO_USER_SESSION_KEY;
4300 encode_or_decode_arc4_passwd_buffer(
4301 info->info26.password.data,
4302 &p->server_info->user_session_key);
4304 dump_data(100, info->info26.password.data, 516);
4306 if (!set_user_info_pw(info->info26.password.data, pwd,
4307 switch_value)) {
4308 status = NT_STATUS_ACCESS_DENIED;
4310 break;
4312 default:
4313 status = NT_STATUS_INVALID_INFO_CLASS;
4316 done:
4318 if (has_enough_rights) {
4319 unbecome_root();
4322 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4324 if (NT_STATUS_IS_OK(status)) {
4325 force_flush_samr_cache(disp_info);
4328 return status;
4331 /*******************************************************************
4332 _samr_SetUserInfo
4333 ********************************************************************/
4335 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4336 struct samr_SetUserInfo *r)
4338 return samr_SetUserInfo_internal("_samr_SetUserInfo",
4340 r->in.user_handle,
4341 r->in.level,
4342 r->in.info);
4345 /*******************************************************************
4346 _samr_SetUserInfo2
4347 ********************************************************************/
4349 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4350 struct samr_SetUserInfo2 *r)
4352 return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4354 r->in.user_handle,
4355 r->in.level,
4356 r->in.info);
4359 /*********************************************************************
4360 _samr_GetAliasMembership
4361 *********************************************************************/
4363 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4364 struct samr_GetAliasMembership *r)
4366 size_t num_alias_rids;
4367 uint32 *alias_rids;
4368 struct samr_info *info = NULL;
4369 size_t i;
4371 NTSTATUS ntstatus1;
4372 NTSTATUS ntstatus2;
4374 DOM_SID *members;
4376 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4378 /* find the policy handle. open a policy on it. */
4379 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4380 return NT_STATUS_INVALID_HANDLE;
4382 ntstatus1 = access_check_samr_function(info->acc_granted,
4383 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4384 "_samr_GetAliasMembership");
4385 ntstatus2 = access_check_samr_function(info->acc_granted,
4386 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4387 "_samr_GetAliasMembership");
4389 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4390 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4391 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4392 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4396 if (!sid_check_is_domain(&info->sid) &&
4397 !sid_check_is_builtin(&info->sid))
4398 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4400 if (r->in.sids->num_sids) {
4401 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4403 if (members == NULL)
4404 return NT_STATUS_NO_MEMORY;
4405 } else {
4406 members = NULL;
4409 for (i=0; i<r->in.sids->num_sids; i++)
4410 sid_copy(&members[i], r->in.sids->sids[i].sid);
4412 alias_rids = NULL;
4413 num_alias_rids = 0;
4415 become_root();
4416 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4417 r->in.sids->num_sids,
4418 &alias_rids, &num_alias_rids);
4419 unbecome_root();
4421 if (!NT_STATUS_IS_OK(ntstatus1)) {
4422 return ntstatus1;
4425 r->out.rids->count = num_alias_rids;
4426 r->out.rids->ids = alias_rids;
4428 return NT_STATUS_OK;
4431 /*********************************************************************
4432 _samr_GetMembersInAlias
4433 *********************************************************************/
4435 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4436 struct samr_GetMembersInAlias *r)
4438 NTSTATUS status;
4439 size_t i;
4440 size_t num_sids = 0;
4441 struct lsa_SidPtr *sids = NULL;
4442 DOM_SID *pdb_sids = NULL;
4444 DOM_SID alias_sid;
4446 uint32 acc_granted;
4448 /* find the policy handle. open a policy on it. */
4449 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4450 return NT_STATUS_INVALID_HANDLE;
4452 status = access_check_samr_function(acc_granted,
4453 SA_RIGHT_ALIAS_GET_MEMBERS,
4454 "_samr_GetMembersInAlias");
4455 if (!NT_STATUS_IS_OK(status)) {
4456 return status;
4459 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4461 become_root();
4462 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4463 unbecome_root();
4465 if (!NT_STATUS_IS_OK(status)) {
4466 return status;
4469 if (num_sids) {
4470 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4471 if (sids == NULL) {
4472 TALLOC_FREE(pdb_sids);
4473 return NT_STATUS_NO_MEMORY;
4477 for (i = 0; i < num_sids; i++) {
4478 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4479 if (!sids[i].sid) {
4480 TALLOC_FREE(pdb_sids);
4481 return NT_STATUS_NO_MEMORY;
4485 r->out.sids->num_sids = num_sids;
4486 r->out.sids->sids = sids;
4488 TALLOC_FREE(pdb_sids);
4490 return NT_STATUS_OK;
4493 /*********************************************************************
4494 _samr_QueryGroupMember
4495 *********************************************************************/
4497 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4498 struct samr_QueryGroupMember *r)
4500 DOM_SID group_sid;
4501 size_t i, num_members;
4503 uint32 *rid=NULL;
4504 uint32 *attr=NULL;
4506 uint32 acc_granted;
4508 NTSTATUS status;
4509 struct samr_RidTypeArray *rids = NULL;
4511 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4512 if (!rids) {
4513 return NT_STATUS_NO_MEMORY;
4516 /* find the policy handle. open a policy on it. */
4517 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4518 return NT_STATUS_INVALID_HANDLE;
4520 status = access_check_samr_function(acc_granted,
4521 SA_RIGHT_GROUP_GET_MEMBERS,
4522 "_samr_QueryGroupMember");
4523 if (!NT_STATUS_IS_OK(status)) {
4524 return status;
4527 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4529 if (!sid_check_is_in_our_domain(&group_sid)) {
4530 DEBUG(3, ("sid %s is not in our domain\n",
4531 sid_string_dbg(&group_sid)));
4532 return NT_STATUS_NO_SUCH_GROUP;
4535 DEBUG(10, ("lookup on Domain SID\n"));
4537 become_root();
4538 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4539 &rid, &num_members);
4540 unbecome_root();
4542 if (!NT_STATUS_IS_OK(status))
4543 return status;
4545 if (num_members) {
4546 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4547 if (attr == NULL) {
4548 return NT_STATUS_NO_MEMORY;
4550 } else {
4551 attr = NULL;
4554 for (i=0; i<num_members; i++)
4555 attr[i] = SID_NAME_USER;
4557 rids->count = num_members;
4558 rids->types = attr;
4559 rids->rids = rid;
4561 *r->out.rids = rids;
4563 return NT_STATUS_OK;
4566 /*********************************************************************
4567 _samr_AddAliasMember
4568 *********************************************************************/
4570 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4571 struct samr_AddAliasMember *r)
4573 DOM_SID alias_sid;
4574 uint32 acc_granted;
4575 SE_PRIV se_rights;
4576 bool can_add_accounts;
4577 NTSTATUS status;
4578 DISP_INFO *disp_info = NULL;
4580 /* Find the policy handle. Open a policy on it. */
4581 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4582 return NT_STATUS_INVALID_HANDLE;
4584 status = access_check_samr_function(acc_granted,
4585 SA_RIGHT_ALIAS_ADD_MEMBER,
4586 "_samr_AddAliasMember");
4587 if (!NT_STATUS_IS_OK(status)) {
4588 return status;
4591 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4593 se_priv_copy( &se_rights, &se_add_users );
4594 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4596 /******** BEGIN SeAddUsers BLOCK *********/
4598 if ( can_add_accounts )
4599 become_root();
4601 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4603 if ( can_add_accounts )
4604 unbecome_root();
4606 /******** END SeAddUsers BLOCK *********/
4608 if (NT_STATUS_IS_OK(status)) {
4609 force_flush_samr_cache(disp_info);
4612 return status;
4615 /*********************************************************************
4616 _samr_DeleteAliasMember
4617 *********************************************************************/
4619 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4620 struct samr_DeleteAliasMember *r)
4622 DOM_SID alias_sid;
4623 uint32 acc_granted;
4624 SE_PRIV se_rights;
4625 bool can_add_accounts;
4626 NTSTATUS status;
4627 DISP_INFO *disp_info = NULL;
4629 /* Find the policy handle. Open a policy on it. */
4630 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4631 return NT_STATUS_INVALID_HANDLE;
4633 status = access_check_samr_function(acc_granted,
4634 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4635 "_samr_DeleteAliasMember");
4636 if (!NT_STATUS_IS_OK(status)) {
4637 return status;
4640 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4641 sid_string_dbg(&alias_sid)));
4643 se_priv_copy( &se_rights, &se_add_users );
4644 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4646 /******** BEGIN SeAddUsers BLOCK *********/
4648 if ( can_add_accounts )
4649 become_root();
4651 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4653 if ( can_add_accounts )
4654 unbecome_root();
4656 /******** END SeAddUsers BLOCK *********/
4658 if (NT_STATUS_IS_OK(status)) {
4659 force_flush_samr_cache(disp_info);
4662 return status;
4665 /*********************************************************************
4666 _samr_AddGroupMember
4667 *********************************************************************/
4669 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4670 struct samr_AddGroupMember *r)
4672 NTSTATUS status;
4673 DOM_SID group_sid;
4674 uint32 group_rid;
4675 uint32 acc_granted;
4676 SE_PRIV se_rights;
4677 bool can_add_accounts;
4678 DISP_INFO *disp_info = NULL;
4680 /* Find the policy handle. Open a policy on it. */
4681 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4682 return NT_STATUS_INVALID_HANDLE;
4684 status = access_check_samr_function(acc_granted,
4685 SA_RIGHT_GROUP_ADD_MEMBER,
4686 "_samr_AddGroupMember");
4687 if (!NT_STATUS_IS_OK(status)) {
4688 return status;
4691 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4693 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4694 &group_rid)) {
4695 return NT_STATUS_INVALID_HANDLE;
4698 se_priv_copy( &se_rights, &se_add_users );
4699 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4701 /******** BEGIN SeAddUsers BLOCK *********/
4703 if ( can_add_accounts )
4704 become_root();
4706 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4708 if ( can_add_accounts )
4709 unbecome_root();
4711 /******** END SeAddUsers BLOCK *********/
4713 force_flush_samr_cache(disp_info);
4715 return status;
4718 /*********************************************************************
4719 _samr_DeleteGroupMember
4720 *********************************************************************/
4722 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4723 struct samr_DeleteGroupMember *r)
4726 NTSTATUS status;
4727 DOM_SID group_sid;
4728 uint32 group_rid;
4729 uint32 acc_granted;
4730 SE_PRIV se_rights;
4731 bool can_add_accounts;
4732 DISP_INFO *disp_info = NULL;
4735 * delete the group member named r->in.rid
4736 * who is a member of the sid associated with the handle
4737 * the rid is a user's rid as the group is a domain group.
4740 /* Find the policy handle. Open a policy on it. */
4741 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4742 return NT_STATUS_INVALID_HANDLE;
4744 status = access_check_samr_function(acc_granted,
4745 SA_RIGHT_GROUP_REMOVE_MEMBER,
4746 "_samr_DeleteGroupMember");
4747 if (!NT_STATUS_IS_OK(status)) {
4748 return status;
4751 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4752 &group_rid)) {
4753 return NT_STATUS_INVALID_HANDLE;
4756 se_priv_copy( &se_rights, &se_add_users );
4757 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4759 /******** BEGIN SeAddUsers BLOCK *********/
4761 if ( can_add_accounts )
4762 become_root();
4764 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4766 if ( can_add_accounts )
4767 unbecome_root();
4769 /******** END SeAddUsers BLOCK *********/
4771 force_flush_samr_cache(disp_info);
4773 return status;
4776 /*********************************************************************
4777 _samr_DeleteUser
4778 *********************************************************************/
4780 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4781 struct samr_DeleteUser *r)
4783 NTSTATUS status;
4784 DOM_SID user_sid;
4785 struct samu *sam_pass=NULL;
4786 uint32 acc_granted;
4787 bool can_add_accounts;
4788 uint32 acb_info;
4789 DISP_INFO *disp_info = NULL;
4790 bool ret;
4792 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4794 /* Find the policy handle. Open a policy on it. */
4795 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4796 return NT_STATUS_INVALID_HANDLE;
4798 status = access_check_samr_function(acc_granted,
4799 STD_RIGHT_DELETE_ACCESS,
4800 "_samr_DeleteUser");
4801 if (!NT_STATUS_IS_OK(status)) {
4802 return status;
4805 if (!sid_check_is_in_our_domain(&user_sid))
4806 return NT_STATUS_CANNOT_DELETE;
4808 /* check if the user exists before trying to delete */
4809 if ( !(sam_pass = samu_new( NULL )) ) {
4810 return NT_STATUS_NO_MEMORY;
4813 become_root();
4814 ret = pdb_getsampwsid(sam_pass, &user_sid);
4815 unbecome_root();
4817 if( !ret ) {
4818 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4819 sid_string_dbg(&user_sid)));
4820 TALLOC_FREE(sam_pass);
4821 return NT_STATUS_NO_SUCH_USER;
4824 acb_info = pdb_get_acct_ctrl(sam_pass);
4826 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4827 if ( acb_info & ACB_WSTRUST ) {
4828 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4829 } else {
4830 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4833 /******** BEGIN SeAddUsers BLOCK *********/
4835 if ( can_add_accounts )
4836 become_root();
4838 status = pdb_delete_user(p->mem_ctx, sam_pass);
4840 if ( can_add_accounts )
4841 unbecome_root();
4843 /******** END SeAddUsers BLOCK *********/
4845 if ( !NT_STATUS_IS_OK(status) ) {
4846 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4847 "user %s: %s.\n", pdb_get_username(sam_pass),
4848 nt_errstr(status)));
4849 TALLOC_FREE(sam_pass);
4850 return status;
4854 TALLOC_FREE(sam_pass);
4856 if (!close_policy_hnd(p, r->in.user_handle))
4857 return NT_STATUS_OBJECT_NAME_INVALID;
4859 force_flush_samr_cache(disp_info);
4861 return NT_STATUS_OK;
4864 /*********************************************************************
4865 _samr_DeleteDomainGroup
4866 *********************************************************************/
4868 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4869 struct samr_DeleteDomainGroup *r)
4871 NTSTATUS status;
4872 DOM_SID group_sid;
4873 uint32 group_rid;
4874 uint32 acc_granted;
4875 SE_PRIV se_rights;
4876 bool can_add_accounts;
4877 DISP_INFO *disp_info = NULL;
4879 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4881 /* Find the policy handle. Open a policy on it. */
4882 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4883 return NT_STATUS_INVALID_HANDLE;
4885 status = access_check_samr_function(acc_granted,
4886 STD_RIGHT_DELETE_ACCESS,
4887 "_samr_DeleteDomainGroup");
4888 if (!NT_STATUS_IS_OK(status)) {
4889 return status;
4892 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4894 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4895 &group_rid)) {
4896 return NT_STATUS_NO_SUCH_GROUP;
4899 se_priv_copy( &se_rights, &se_add_users );
4900 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4902 /******** BEGIN SeAddUsers BLOCK *********/
4904 if ( can_add_accounts )
4905 become_root();
4907 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4909 if ( can_add_accounts )
4910 unbecome_root();
4912 /******** END SeAddUsers BLOCK *********/
4914 if ( !NT_STATUS_IS_OK(status) ) {
4915 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4916 "entry for group %s: %s\n",
4917 sid_string_dbg(&group_sid),
4918 nt_errstr(status)));
4919 return status;
4922 if (!close_policy_hnd(p, r->in.group_handle))
4923 return NT_STATUS_OBJECT_NAME_INVALID;
4925 force_flush_samr_cache(disp_info);
4927 return NT_STATUS_OK;
4930 /*********************************************************************
4931 _samr_DeleteDomAlias
4932 *********************************************************************/
4934 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4935 struct samr_DeleteDomAlias *r)
4937 DOM_SID alias_sid;
4938 uint32 acc_granted;
4939 SE_PRIV se_rights;
4940 bool can_add_accounts;
4941 NTSTATUS status;
4942 DISP_INFO *disp_info = NULL;
4944 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4946 /* Find the policy handle. Open a policy on it. */
4947 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4948 return NT_STATUS_INVALID_HANDLE;
4950 /* copy the handle to the outgoing reply */
4952 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4954 status = access_check_samr_function(acc_granted,
4955 STD_RIGHT_DELETE_ACCESS,
4956 "_samr_DeleteDomAlias");
4957 if (!NT_STATUS_IS_OK(status)) {
4958 return status;
4961 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4963 /* Don't let Windows delete builtin groups */
4965 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4966 return NT_STATUS_SPECIAL_ACCOUNT;
4969 if (!sid_check_is_in_our_domain(&alias_sid))
4970 return NT_STATUS_NO_SUCH_ALIAS;
4972 DEBUG(10, ("lookup on Local SID\n"));
4974 se_priv_copy( &se_rights, &se_add_users );
4975 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4977 /******** BEGIN SeAddUsers BLOCK *********/
4979 if ( can_add_accounts )
4980 become_root();
4982 /* Have passdb delete the alias */
4983 status = pdb_delete_alias(&alias_sid);
4985 if ( can_add_accounts )
4986 unbecome_root();
4988 /******** END SeAddUsers BLOCK *********/
4990 if ( !NT_STATUS_IS_OK(status))
4991 return status;
4993 if (!close_policy_hnd(p, r->in.alias_handle))
4994 return NT_STATUS_OBJECT_NAME_INVALID;
4996 force_flush_samr_cache(disp_info);
4998 return NT_STATUS_OK;
5001 /*********************************************************************
5002 _samr_CreateDomainGroup
5003 *********************************************************************/
5005 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5006 struct samr_CreateDomainGroup *r)
5009 NTSTATUS status;
5010 DOM_SID dom_sid;
5011 DOM_SID info_sid;
5012 const char *name;
5013 struct samr_info *info;
5014 uint32 acc_granted;
5015 SE_PRIV se_rights;
5016 bool can_add_accounts;
5017 DISP_INFO *disp_info = NULL;
5019 /* Find the policy handle. Open a policy on it. */
5020 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5021 return NT_STATUS_INVALID_HANDLE;
5023 status = access_check_samr_function(acc_granted,
5024 SA_RIGHT_DOMAIN_CREATE_GROUP,
5025 "_samr_CreateDomainGroup");
5026 if (!NT_STATUS_IS_OK(status)) {
5027 return status;
5030 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5031 return NT_STATUS_ACCESS_DENIED;
5033 name = r->in.name->string;
5034 if (name == NULL) {
5035 return NT_STATUS_NO_MEMORY;
5038 status = can_create(p->mem_ctx, name);
5039 if (!NT_STATUS_IS_OK(status)) {
5040 return status;
5043 se_priv_copy( &se_rights, &se_add_users );
5044 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5046 /******** BEGIN SeAddUsers BLOCK *********/
5048 if ( can_add_accounts )
5049 become_root();
5051 /* check that we successfully create the UNIX group */
5053 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5055 if ( can_add_accounts )
5056 unbecome_root();
5058 /******** END SeAddUsers BLOCK *********/
5060 /* check if we should bail out here */
5062 if ( !NT_STATUS_IS_OK(status) )
5063 return status;
5065 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5067 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5068 return NT_STATUS_NO_MEMORY;
5070 /* they created it; let the user do what he wants with it */
5072 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5074 /* get a (unique) handle. open a policy on it. */
5075 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5076 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5078 force_flush_samr_cache(disp_info);
5080 return NT_STATUS_OK;
5083 /*********************************************************************
5084 _samr_CreateDomAlias
5085 *********************************************************************/
5087 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5088 struct samr_CreateDomAlias *r)
5090 DOM_SID dom_sid;
5091 DOM_SID info_sid;
5092 const char *name = NULL;
5093 struct samr_info *info;
5094 uint32 acc_granted;
5095 gid_t gid;
5096 NTSTATUS result;
5097 SE_PRIV se_rights;
5098 bool can_add_accounts;
5099 DISP_INFO *disp_info = NULL;
5101 /* Find the policy handle. Open a policy on it. */
5102 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5103 return NT_STATUS_INVALID_HANDLE;
5105 result = access_check_samr_function(acc_granted,
5106 SA_RIGHT_DOMAIN_CREATE_ALIAS,
5107 "_samr_CreateDomAlias");
5108 if (!NT_STATUS_IS_OK(result)) {
5109 return result;
5112 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5113 return NT_STATUS_ACCESS_DENIED;
5115 name = r->in.alias_name->string;
5117 se_priv_copy( &se_rights, &se_add_users );
5118 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5120 result = can_create(p->mem_ctx, name);
5121 if (!NT_STATUS_IS_OK(result)) {
5122 return result;
5125 /******** BEGIN SeAddUsers BLOCK *********/
5127 if ( can_add_accounts )
5128 become_root();
5130 /* Have passdb create the alias */
5131 result = pdb_create_alias(name, r->out.rid);
5133 if ( can_add_accounts )
5134 unbecome_root();
5136 /******** END SeAddUsers BLOCK *********/
5138 if (!NT_STATUS_IS_OK(result)) {
5139 DEBUG(10, ("pdb_create_alias failed: %s\n",
5140 nt_errstr(result)));
5141 return result;
5144 sid_copy(&info_sid, get_global_sam_sid());
5145 sid_append_rid(&info_sid, *r->out.rid);
5147 if (!sid_to_gid(&info_sid, &gid)) {
5148 DEBUG(10, ("Could not find alias just created\n"));
5149 return NT_STATUS_ACCESS_DENIED;
5152 /* check if the group has been successfully created */
5153 if ( getgrgid(gid) == NULL ) {
5154 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5155 gid));
5156 return NT_STATUS_ACCESS_DENIED;
5159 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5160 return NT_STATUS_NO_MEMORY;
5162 /* they created it; let the user do what he wants with it */
5164 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5166 /* get a (unique) handle. open a policy on it. */
5167 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5168 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5170 force_flush_samr_cache(disp_info);
5172 return NT_STATUS_OK;
5175 /*********************************************************************
5176 _samr_QueryGroupInfo
5177 *********************************************************************/
5179 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5180 struct samr_QueryGroupInfo *r)
5182 NTSTATUS status;
5183 DOM_SID group_sid;
5184 GROUP_MAP map;
5185 union samr_GroupInfo *info = NULL;
5186 uint32 acc_granted;
5187 bool ret;
5188 uint32_t attributes = SE_GROUP_MANDATORY |
5189 SE_GROUP_ENABLED_BY_DEFAULT |
5190 SE_GROUP_ENABLED;
5191 const char *group_name = NULL;
5192 const char *group_description = NULL;
5194 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5195 return NT_STATUS_INVALID_HANDLE;
5197 status = access_check_samr_function(acc_granted,
5198 SA_RIGHT_GROUP_LOOKUP_INFO,
5199 "_samr_QueryGroupInfo");
5200 if (!NT_STATUS_IS_OK(status)) {
5201 return status;
5204 become_root();
5205 ret = get_domain_group_from_sid(group_sid, &map);
5206 unbecome_root();
5207 if (!ret)
5208 return NT_STATUS_INVALID_HANDLE;
5210 /* FIXME: map contains fstrings */
5211 group_name = talloc_strdup(r, map.nt_name);
5212 group_description = talloc_strdup(r, map.comment);
5214 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5215 if (!info) {
5216 return NT_STATUS_NO_MEMORY;
5219 switch (r->in.level) {
5220 case 1: {
5221 uint32 *members;
5222 size_t num_members;
5224 become_root();
5225 status = pdb_enum_group_members(
5226 p->mem_ctx, &group_sid, &members, &num_members);
5227 unbecome_root();
5229 if (!NT_STATUS_IS_OK(status)) {
5230 return status;
5233 init_samr_group_info1(&info->all,
5234 group_name,
5235 attributes,
5236 num_members,
5237 group_description);
5238 break;
5240 case 2:
5241 init_samr_group_info2(&info->name,
5242 group_name);
5243 break;
5244 case 3:
5245 init_samr_group_info3(&info->attributes,
5246 attributes);
5247 break;
5248 case 4:
5249 init_samr_group_info4(&info->description,
5250 group_description);
5251 break;
5252 case 5: {
5254 uint32 *members;
5255 size_t num_members;
5259 become_root();
5260 status = pdb_enum_group_members(
5261 p->mem_ctx, &group_sid, &members, &num_members);
5262 unbecome_root();
5264 if (!NT_STATUS_IS_OK(status)) {
5265 return status;
5268 init_samr_group_info5(&info->all2,
5269 group_name,
5270 attributes,
5271 0, /* num_members - in w2k3 this is always 0 */
5272 group_description);
5274 break;
5276 default:
5277 return NT_STATUS_INVALID_INFO_CLASS;
5280 *r->out.info = info;
5282 return NT_STATUS_OK;
5285 /*********************************************************************
5286 _samr_SetGroupInfo
5287 *********************************************************************/
5289 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5290 struct samr_SetGroupInfo *r)
5292 DOM_SID group_sid;
5293 GROUP_MAP map;
5294 uint32 acc_granted;
5295 NTSTATUS status;
5296 bool ret;
5297 bool can_mod_accounts;
5298 DISP_INFO *disp_info = NULL;
5300 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5301 return NT_STATUS_INVALID_HANDLE;
5303 status = access_check_samr_function(acc_granted,
5304 SA_RIGHT_GROUP_SET_INFO,
5305 "_samr_SetGroupInfo");
5306 if (!NT_STATUS_IS_OK(status)) {
5307 return status;
5310 become_root();
5311 ret = get_domain_group_from_sid(group_sid, &map);
5312 unbecome_root();
5313 if (!ret)
5314 return NT_STATUS_NO_SUCH_GROUP;
5316 switch (r->in.level) {
5317 case 1:
5318 fstrcpy(map.comment, r->in.info->all.description.string);
5319 break;
5320 case 4:
5321 fstrcpy(map.comment, r->in.info->description.string);
5322 break;
5323 default:
5324 return NT_STATUS_INVALID_INFO_CLASS;
5327 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5329 /******** BEGIN SeAddUsers BLOCK *********/
5331 if ( can_mod_accounts )
5332 become_root();
5334 status = pdb_update_group_mapping_entry(&map);
5336 if ( can_mod_accounts )
5337 unbecome_root();
5339 /******** End SeAddUsers BLOCK *********/
5341 if (NT_STATUS_IS_OK(status)) {
5342 force_flush_samr_cache(disp_info);
5345 return status;
5348 /*********************************************************************
5349 _samr_SetAliasInfo
5350 *********************************************************************/
5352 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5353 struct samr_SetAliasInfo *r)
5355 DOM_SID group_sid;
5356 struct acct_info info;
5357 uint32 acc_granted;
5358 bool can_mod_accounts;
5359 NTSTATUS status;
5360 DISP_INFO *disp_info = NULL;
5362 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5363 return NT_STATUS_INVALID_HANDLE;
5365 status = access_check_samr_function(acc_granted,
5366 SA_RIGHT_ALIAS_SET_INFO,
5367 "_samr_SetAliasInfo");
5368 if (!NT_STATUS_IS_OK(status)) {
5369 return status;
5372 /* get the current group information */
5374 become_root();
5375 status = pdb_get_aliasinfo( &group_sid, &info );
5376 unbecome_root();
5378 if ( !NT_STATUS_IS_OK(status))
5379 return status;
5381 switch (r->in.level) {
5382 case ALIASINFONAME:
5384 fstring group_name;
5386 /* We currently do not support renaming groups in the
5387 the BUILTIN domain. Refer to util_builtin.c to understand
5388 why. The eventually needs to be fixed to be like Windows
5389 where you can rename builtin groups, just not delete them */
5391 if ( sid_check_is_in_builtin( &group_sid ) ) {
5392 return NT_STATUS_SPECIAL_ACCOUNT;
5395 /* There has to be a valid name (and it has to be different) */
5397 if ( !r->in.info->name.string )
5398 return NT_STATUS_INVALID_PARAMETER;
5400 /* If the name is the same just reply "ok". Yes this
5401 doesn't allow you to change the case of a group name. */
5403 if ( strequal( r->in.info->name.string, info.acct_name ) )
5404 return NT_STATUS_OK;
5406 fstrcpy( info.acct_name, r->in.info->name.string);
5408 /* make sure the name doesn't already exist as a user
5409 or local group */
5411 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5412 status = can_create( p->mem_ctx, group_name );
5413 if ( !NT_STATUS_IS_OK( status ) )
5414 return status;
5415 break;
5417 case ALIASINFODESCRIPTION:
5418 if (r->in.info->description.string) {
5419 fstrcpy(info.acct_desc,
5420 r->in.info->description.string);
5421 } else {
5422 fstrcpy( info.acct_desc, "" );
5424 break;
5425 default:
5426 return NT_STATUS_INVALID_INFO_CLASS;
5429 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5431 /******** BEGIN SeAddUsers BLOCK *********/
5433 if ( can_mod_accounts )
5434 become_root();
5436 status = pdb_set_aliasinfo( &group_sid, &info );
5438 if ( can_mod_accounts )
5439 unbecome_root();
5441 /******** End SeAddUsers BLOCK *********/
5443 if (NT_STATUS_IS_OK(status))
5444 force_flush_samr_cache(disp_info);
5446 return status;
5449 /****************************************************************
5450 _samr_GetDomPwInfo
5451 ****************************************************************/
5453 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5454 struct samr_GetDomPwInfo *r)
5456 uint32_t min_password_length = 0;
5457 uint32_t password_properties = 0;
5459 /* Perform access check. Since this rpc does not require a
5460 policy handle it will not be caught by the access checks on
5461 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5463 if (!pipe_access_check(p)) {
5464 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5465 return NT_STATUS_ACCESS_DENIED;
5468 become_root();
5469 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5470 &min_password_length);
5471 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5472 &password_properties);
5473 unbecome_root();
5475 if (lp_check_password_script() && *lp_check_password_script()) {
5476 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5479 r->out.info->min_password_length = min_password_length;
5480 r->out.info->password_properties = password_properties;
5482 return NT_STATUS_OK;
5485 /*********************************************************************
5486 _samr_OpenGroup
5487 *********************************************************************/
5489 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5490 struct samr_OpenGroup *r)
5493 DOM_SID sid;
5494 DOM_SID info_sid;
5495 GROUP_MAP map;
5496 struct samr_info *info;
5497 SEC_DESC *psd = NULL;
5498 uint32 acc_granted;
5499 uint32 des_access = r->in.access_mask;
5500 size_t sd_size;
5501 NTSTATUS status;
5502 fstring sid_string;
5503 bool ret;
5504 SE_PRIV se_rights;
5506 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5507 return NT_STATUS_INVALID_HANDLE;
5509 status = access_check_samr_function(acc_granted,
5510 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5511 "_samr_OpenGroup");
5513 if ( !NT_STATUS_IS_OK(status) )
5514 return status;
5516 /*check if access can be granted as requested by client. */
5517 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5518 se_map_generic(&des_access,&grp_generic_mapping);
5520 se_priv_copy( &se_rights, &se_add_users );
5522 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5523 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5524 &acc_granted, "_samr_OpenGroup");
5526 if ( !NT_STATUS_IS_OK(status) )
5527 return status;
5529 /* this should not be hard-coded like this */
5531 if (!sid_equal(&sid, get_global_sam_sid()))
5532 return NT_STATUS_ACCESS_DENIED;
5534 sid_copy(&info_sid, get_global_sam_sid());
5535 sid_append_rid(&info_sid, r->in.rid);
5536 sid_to_fstring(sid_string, &info_sid);
5538 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5539 return NT_STATUS_NO_MEMORY;
5541 info->acc_granted = acc_granted;
5543 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5545 /* check if that group really exists */
5546 become_root();
5547 ret = get_domain_group_from_sid(info->sid, &map);
5548 unbecome_root();
5549 if (!ret)
5550 return NT_STATUS_NO_SUCH_GROUP;
5552 /* get a (unique) handle. open a policy on it. */
5553 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5554 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5556 return NT_STATUS_OK;
5559 /*********************************************************************
5560 _samr_RemoveMemberFromForeignDomain
5561 *********************************************************************/
5563 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5564 struct samr_RemoveMemberFromForeignDomain *r)
5566 DOM_SID delete_sid, domain_sid;
5567 uint32 acc_granted;
5568 NTSTATUS result;
5569 DISP_INFO *disp_info = NULL;
5571 sid_copy( &delete_sid, r->in.sid );
5573 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5574 sid_string_dbg(&delete_sid)));
5576 /* Find the policy handle. Open a policy on it. */
5578 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5579 &acc_granted, &disp_info))
5580 return NT_STATUS_INVALID_HANDLE;
5582 result = access_check_samr_function(acc_granted,
5583 STD_RIGHT_DELETE_ACCESS,
5584 "_samr_RemoveMemberFromForeignDomain");
5586 if (!NT_STATUS_IS_OK(result))
5587 return result;
5589 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5590 sid_string_dbg(&domain_sid)));
5592 /* we can only delete a user from a group since we don't have
5593 nested groups anyways. So in the latter case, just say OK */
5595 /* TODO: The above comment nowadays is bogus. Since we have nested
5596 * groups now, and aliases members are never reported out of the unix
5597 * group membership, the "just say OK" makes this call a no-op. For
5598 * us. This needs fixing however. */
5600 /* I've only ever seen this in the wild when deleting a user from
5601 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5602 * is the user about to be deleted. I very much suspect this is the
5603 * only application of this call. To verify this, let people report
5604 * other cases. */
5606 if (!sid_check_is_builtin(&domain_sid)) {
5607 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5608 "global_sam_sid() = %s\n",
5609 sid_string_dbg(&domain_sid),
5610 sid_string_dbg(get_global_sam_sid())));
5611 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5612 return NT_STATUS_OK;
5615 force_flush_samr_cache(disp_info);
5617 result = NT_STATUS_OK;
5619 return result;
5622 /*******************************************************************
5623 _samr_QueryDomainInfo2
5624 ********************************************************************/
5626 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5627 struct samr_QueryDomainInfo2 *r)
5629 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5631 r->in.domain_handle,
5632 r->in.level,
5633 r->out.info);
5636 /*******************************************************************
5637 _samr_SetDomainInfo
5638 ********************************************************************/
5640 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5641 struct samr_SetDomainInfo *r)
5643 struct samr_info *info = NULL;
5644 time_t u_expire, u_min_age;
5645 time_t u_logout;
5646 time_t u_lock_duration, u_reset_time;
5647 NTSTATUS result;
5649 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5651 /* find the policy handle. open a policy on it. */
5652 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
5653 return NT_STATUS_INVALID_HANDLE;
5655 /* We do have different access bits for info
5656 * levels here, but we're really just looking for
5657 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5658 * this maps to different specific bits. So
5659 * assume if we have SA_RIGHT_DOMAIN_SET_INFO_1
5660 * set we are ok. */
5662 result = access_check_samr_function(info->acc_granted,
5663 SA_RIGHT_DOMAIN_SET_INFO_1,
5664 "_samr_SetDomainInfo");
5666 if (!NT_STATUS_IS_OK(result))
5667 return result;
5669 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5671 switch (r->in.level) {
5672 case 0x01:
5673 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5674 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5675 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5676 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5677 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5678 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5679 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5680 break;
5681 case 0x02:
5682 break;
5683 case 0x03:
5684 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5685 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5686 break;
5687 case 0x05:
5688 break;
5689 case 0x06:
5690 break;
5691 case 0x07:
5692 break;
5693 case 0x0c:
5694 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5695 if (u_lock_duration != -1)
5696 u_lock_duration /= 60;
5698 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5700 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5701 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5702 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5703 break;
5704 default:
5705 return NT_STATUS_INVALID_INFO_CLASS;
5708 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5710 return NT_STATUS_OK;
5713 /****************************************************************
5714 _samr_GetDisplayEnumerationIndex
5715 ****************************************************************/
5717 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5718 struct samr_GetDisplayEnumerationIndex *r)
5720 struct samr_info *info = NULL;
5721 uint32_t max_entries = (uint32_t) -1;
5722 uint32_t enum_context = 0;
5723 int i;
5724 uint32_t num_account = 0;
5725 struct samr_displayentry *entries = NULL;
5726 NTSTATUS status;
5728 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5730 /* find the policy handle. open a policy on it. */
5731 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5732 return NT_STATUS_INVALID_HANDLE;
5735 status = access_check_samr_function(info->acc_granted,
5736 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
5737 "_samr_GetDisplayEnumerationIndex");
5738 if (!NT_STATUS_IS_OK(status)) {
5739 return status;
5742 if ((r->in.level < 1) || (r->in.level > 3)) {
5743 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5744 "Unknown info level (%u)\n",
5745 r->in.level));
5746 return NT_STATUS_INVALID_INFO_CLASS;
5749 become_root();
5751 /* The following done as ROOT. Don't return without unbecome_root(). */
5753 switch (r->in.level) {
5754 case 1:
5755 if (info->disp_info->users == NULL) {
5756 info->disp_info->users = pdb_search_users(ACB_NORMAL);
5757 if (info->disp_info->users == NULL) {
5758 unbecome_root();
5759 return NT_STATUS_ACCESS_DENIED;
5761 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5762 "starting user enumeration at index %u\n",
5763 (unsigned int)enum_context));
5764 } else {
5765 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5766 "using cached user enumeration at index %u\n",
5767 (unsigned int)enum_context));
5769 num_account = pdb_search_entries(info->disp_info->users,
5770 enum_context, max_entries,
5771 &entries);
5772 break;
5773 case 2:
5774 if (info->disp_info->machines == NULL) {
5775 info->disp_info->machines =
5776 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5777 if (info->disp_info->machines == NULL) {
5778 unbecome_root();
5779 return NT_STATUS_ACCESS_DENIED;
5781 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5782 "starting machine enumeration at index %u\n",
5783 (unsigned int)enum_context));
5784 } else {
5785 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5786 "using cached machine enumeration at index %u\n",
5787 (unsigned int)enum_context));
5789 num_account = pdb_search_entries(info->disp_info->machines,
5790 enum_context, max_entries,
5791 &entries);
5792 break;
5793 case 3:
5794 if (info->disp_info->groups == NULL) {
5795 info->disp_info->groups = pdb_search_groups();
5796 if (info->disp_info->groups == NULL) {
5797 unbecome_root();
5798 return NT_STATUS_ACCESS_DENIED;
5800 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5801 "starting group enumeration at index %u\n",
5802 (unsigned int)enum_context));
5803 } else {
5804 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5805 "using cached group enumeration at index %u\n",
5806 (unsigned int)enum_context));
5808 num_account = pdb_search_entries(info->disp_info->groups,
5809 enum_context, max_entries,
5810 &entries);
5811 break;
5812 default:
5813 unbecome_root();
5814 smb_panic("info class changed");
5815 break;
5818 unbecome_root();
5820 /* Ensure we cache this enumeration. */
5821 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5823 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5824 r->in.name->string));
5826 for (i=0; i<num_account; i++) {
5827 if (strequal(entries[i].account_name, r->in.name->string)) {
5828 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5829 "found %s at idx %d\n",
5830 r->in.name->string, i));
5831 *r->out.idx = i;
5832 return NT_STATUS_OK;
5836 /* assuming account_name lives at the very end */
5837 *r->out.idx = num_account;
5839 return NT_STATUS_NO_MORE_ENTRIES;
5842 /****************************************************************
5843 _samr_GetDisplayEnumerationIndex2
5844 ****************************************************************/
5846 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5847 struct samr_GetDisplayEnumerationIndex2 *r)
5849 struct samr_GetDisplayEnumerationIndex q;
5851 q.in.domain_handle = r->in.domain_handle;
5852 q.in.level = r->in.level;
5853 q.in.name = r->in.name;
5855 q.out.idx = r->out.idx;
5857 return _samr_GetDisplayEnumerationIndex(p, &q);
5860 /****************************************************************
5861 ****************************************************************/
5863 NTSTATUS _samr_Shutdown(pipes_struct *p,
5864 struct samr_Shutdown *r)
5866 p->rng_fault_state = true;
5867 return NT_STATUS_NOT_IMPLEMENTED;
5870 /****************************************************************
5871 ****************************************************************/
5873 NTSTATUS _samr_CreateUser(pipes_struct *p,
5874 struct samr_CreateUser *r)
5876 p->rng_fault_state = true;
5877 return NT_STATUS_NOT_IMPLEMENTED;
5880 /****************************************************************
5881 ****************************************************************/
5883 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5884 struct samr_SetMemberAttributesOfGroup *r)
5886 p->rng_fault_state = true;
5887 return NT_STATUS_NOT_IMPLEMENTED;
5890 /****************************************************************
5891 ****************************************************************/
5893 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5894 struct samr_ChangePasswordUser *r)
5896 p->rng_fault_state = true;
5897 return NT_STATUS_NOT_IMPLEMENTED;
5900 /****************************************************************
5901 ****************************************************************/
5903 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5904 struct samr_TestPrivateFunctionsDomain *r)
5906 p->rng_fault_state = true;
5907 return NT_STATUS_NOT_IMPLEMENTED;
5910 /****************************************************************
5911 ****************************************************************/
5913 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5914 struct samr_TestPrivateFunctionsUser *r)
5916 p->rng_fault_state = true;
5917 return NT_STATUS_NOT_IMPLEMENTED;
5920 /****************************************************************
5921 ****************************************************************/
5923 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5924 struct samr_QueryUserInfo2 *r)
5926 p->rng_fault_state = true;
5927 return NT_STATUS_NOT_IMPLEMENTED;
5930 /****************************************************************
5931 ****************************************************************/
5933 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5934 struct samr_AddMultipleMembersToAlias *r)
5936 p->rng_fault_state = true;
5937 return NT_STATUS_NOT_IMPLEMENTED;
5940 /****************************************************************
5941 ****************************************************************/
5943 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5944 struct samr_RemoveMultipleMembersFromAlias *r)
5946 p->rng_fault_state = true;
5947 return NT_STATUS_NOT_IMPLEMENTED;
5950 /****************************************************************
5951 ****************************************************************/
5953 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5954 struct samr_OemChangePasswordUser2 *r)
5956 p->rng_fault_state = true;
5957 return NT_STATUS_NOT_IMPLEMENTED;
5960 /****************************************************************
5961 ****************************************************************/
5963 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5964 struct samr_SetBootKeyInformation *r)
5966 p->rng_fault_state = true;
5967 return NT_STATUS_NOT_IMPLEMENTED;
5970 /****************************************************************
5971 ****************************************************************/
5973 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5974 struct samr_GetBootKeyInformation *r)
5976 p->rng_fault_state = true;
5977 return NT_STATUS_NOT_IMPLEMENTED;
5980 /****************************************************************
5981 ****************************************************************/
5983 NTSTATUS _samr_Connect3(pipes_struct *p,
5984 struct samr_Connect3 *r)
5986 p->rng_fault_state = true;
5987 return NT_STATUS_NOT_IMPLEMENTED;
5990 /****************************************************************
5991 ****************************************************************/
5993 NTSTATUS _samr_RidToSid(pipes_struct *p,
5994 struct samr_RidToSid *r)
5996 p->rng_fault_state = true;
5997 return NT_STATUS_NOT_IMPLEMENTED;
6000 /****************************************************************
6001 ****************************************************************/
6003 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6004 struct samr_SetDsrmPassword *r)
6006 p->rng_fault_state = true;
6007 return NT_STATUS_NOT_IMPLEMENTED;
6010 /****************************************************************
6011 ****************************************************************/
6013 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6014 struct samr_ValidatePassword *r)
6016 p->rng_fault_state = true;
6017 return NT_STATUS_NOT_IMPLEMENTED;