Fix Bug #5461 and implement a very basic _samr_GetDisplayEnumerationIndex().
[Samba.git] / source / rpc_server / srv_samr_nt.c
blobf28c771d3ed3b5b7d7fd53ec61c29cedd81c14ea
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 SEC_ACCESS mask;
117 size_t i = 0;
119 SEC_ACL *psa = NULL;
121 /* basic access for Everyone */
123 init_sec_access(&mask, map->generic_execute | map->generic_read );
124 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
126 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
128 init_sec_access(&mask, map->generic_all);
130 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
131 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
133 /* Add Full Access for Domain Admins if we are a DC */
135 if ( IS_DC ) {
136 sid_copy( &domadmin_sid, get_global_sam_sid() );
137 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
138 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
141 /* if we have a sid, give it some special access */
143 if ( sid ) {
144 init_sec_access( &mask, sid_access );
145 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
148 /* create the security descriptor */
150 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
151 return NT_STATUS_NO_MEMORY;
153 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
154 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
155 psa, sd_size)) == NULL)
156 return NT_STATUS_NO_MEMORY;
158 return NT_STATUS_OK;
161 /*******************************************************************
162 Checks if access to an object should be granted, and returns that
163 level of access for further checks.
164 ********************************************************************/
166 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
167 SE_PRIV *rights, uint32 rights_mask,
168 uint32 des_access, uint32 *acc_granted,
169 const char *debug )
171 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
172 uint32 saved_mask = 0;
174 /* check privileges; certain SAM access bits should be overridden
175 by privileges (mostly having to do with creating/modifying/deleting
176 users and groups) */
178 if ( rights && user_has_any_privilege( token, rights ) ) {
180 saved_mask = (des_access & rights_mask);
181 des_access &= ~saved_mask;
183 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
184 rights_mask));
188 /* check the security descriptor first */
190 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
191 goto done;
193 /* give root a free pass */
195 if ( geteuid() == sec_initial_uid() ) {
197 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
198 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
200 *acc_granted = des_access;
202 status = NT_STATUS_OK;
203 goto done;
207 done:
208 /* add in any bits saved during the privilege check (only
209 matters is status is ok) */
211 *acc_granted |= rights_mask;
213 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
214 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
215 des_access, *acc_granted));
217 return status;
220 /*******************************************************************
221 Checks if access to a function can be granted
222 ********************************************************************/
224 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
226 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
227 debug, acc_granted, acc_required));
229 /* check the security descriptor first */
231 if ( (acc_granted&acc_required) == acc_required )
232 return NT_STATUS_OK;
234 /* give root a free pass */
236 if (geteuid() == sec_initial_uid()) {
238 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
239 debug, acc_granted, acc_required));
240 DEBUGADD(4,("but overwritten by euid == 0\n"));
242 return NT_STATUS_OK;
245 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
246 debug, acc_granted, acc_required));
248 return NT_STATUS_ACCESS_DENIED;
251 /*******************************************************************
252 Fetch or create a dispinfo struct.
253 ********************************************************************/
255 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
258 * We do a static cache for DISP_INFO's here. Explanation can be found
259 * in Jeremy's checkin message to r11793:
261 * Fix the SAMR cache so it works across completely insane
262 * client behaviour (ie.:
263 * open pipe/open SAMR handle/enumerate 0 - 1024
264 * close SAMR handle, close pipe.
265 * open pipe/open SAMR handle/enumerate 1024 - 2048...
266 * close SAMR handle, close pipe.
267 * And on ad-nausium. Amazing.... probably object-oriented
268 * client side programming in action yet again.
269 * This change should *massively* improve performance when
270 * enumerating users from an LDAP database.
271 * Jeremy.
273 * "Our" and the builtin domain are the only ones where we ever
274 * enumerate stuff, so just cache 2 entries.
277 static struct disp_info builtin_dispinfo;
278 static struct disp_info domain_dispinfo;
280 /* There are two cases to consider here:
281 1) The SID is a domain SID and we look for an equality match, or
282 2) This is an account SID and so we return the DISP_INFO* for our
283 domain */
285 if (psid == NULL) {
286 return NULL;
289 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
291 * Necessary only once, but it does not really hurt.
293 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
295 return &builtin_dispinfo;
298 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
300 * Necessary only once, but it does not really hurt.
302 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
304 return &domain_dispinfo;
307 return NULL;
310 /*******************************************************************
311 Create a samr_info struct.
312 ********************************************************************/
314 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
316 struct samr_info *info;
317 fstring sid_str;
318 TALLOC_CTX *mem_ctx;
320 if (psid) {
321 sid_to_fstring(sid_str, psid);
322 } else {
323 fstrcpy(sid_str,"(NULL)");
326 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
328 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
329 return NULL;
331 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
332 if (psid) {
333 sid_copy( &info->sid, psid);
334 info->builtin_domain = sid_check_is_builtin(psid);
335 } else {
336 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
337 info->builtin_domain = False;
339 info->mem_ctx = mem_ctx;
341 info->disp_info = get_samr_dispinfo_by_sid(psid);
343 return info;
346 /*******************************************************************
347 Function to free the per SID data.
348 ********************************************************************/
350 static void free_samr_cache(DISP_INFO *disp_info)
352 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
353 sid_string_dbg(&disp_info->sid)));
355 /* We need to become root here because the paged search might have to
356 * tell the LDAP server we're not interested in the rest anymore. */
358 become_root();
360 if (disp_info->users) {
361 DEBUG(10,("free_samr_cache: deleting users cache\n"));
362 pdb_search_destroy(disp_info->users);
363 disp_info->users = NULL;
365 if (disp_info->machines) {
366 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
367 pdb_search_destroy(disp_info->machines);
368 disp_info->machines = NULL;
370 if (disp_info->groups) {
371 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
372 pdb_search_destroy(disp_info->groups);
373 disp_info->groups = NULL;
375 if (disp_info->aliases) {
376 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
377 pdb_search_destroy(disp_info->aliases);
378 disp_info->aliases = NULL;
380 if (disp_info->enum_users) {
381 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
382 pdb_search_destroy(disp_info->enum_users);
383 disp_info->enum_users = NULL;
385 disp_info->enum_acb_mask = 0;
387 unbecome_root();
390 /*******************************************************************
391 Function to free the per handle data.
392 ********************************************************************/
394 static void free_samr_info(void *ptr)
396 struct samr_info *info=(struct samr_info *) ptr;
398 /* Only free the dispinfo cache if no one bothered to set up
399 a timeout. */
401 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
402 free_samr_cache(info->disp_info);
405 talloc_destroy(info->mem_ctx);
408 /*******************************************************************
409 Idle event handler. Throw away the disp info cache.
410 ********************************************************************/
412 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
413 struct timed_event *te,
414 const struct timeval *now,
415 void *private_data)
417 DISP_INFO *disp_info = (DISP_INFO *)private_data;
419 TALLOC_FREE(disp_info->cache_timeout_event);
421 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
422 "out\n"));
423 free_samr_cache(disp_info);
426 /*******************************************************************
427 Setup cache removal idle event handler.
428 ********************************************************************/
430 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
432 /* Remove any pending timeout and update. */
434 TALLOC_FREE(disp_info->cache_timeout_event);
436 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
437 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
438 (unsigned int)secs_fromnow ));
440 disp_info->cache_timeout_event = event_add_timed(
441 smbd_event_context(), NULL,
442 timeval_current_ofs(secs_fromnow, 0),
443 "disp_info_cache_idle_timeout_handler",
444 disp_info_cache_idle_timeout_handler, (void *)disp_info);
447 /*******************************************************************
448 Force flush any cache. We do this on any samr_set_xxx call.
449 We must also remove the timeout handler.
450 ********************************************************************/
452 static void force_flush_samr_cache(DISP_INFO *disp_info)
454 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
455 return;
458 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
459 TALLOC_FREE(disp_info->cache_timeout_event);
460 free_samr_cache(disp_info);
463 /*******************************************************************
464 Ensure password info is never given out. Paranioa... JRA.
465 ********************************************************************/
467 static void samr_clear_sam_passwd(struct samu *sam_pass)
470 if (!sam_pass)
471 return;
473 /* These now zero out the old password */
475 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
476 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
479 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
481 struct samr_displayentry *entry;
483 if (info->builtin_domain) {
484 /* No users in builtin. */
485 return 0;
488 if (info->users == NULL) {
489 info->users = pdb_search_users(acct_flags);
490 if (info->users == NULL) {
491 return 0;
494 /* Fetch the last possible entry, thus trigger an enumeration */
495 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
497 /* Ensure we cache this enumeration. */
498 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
500 return info->users->num_entries;
503 static uint32 count_sam_groups(struct disp_info *info)
505 struct samr_displayentry *entry;
507 if (info->builtin_domain) {
508 /* No groups in builtin. */
509 return 0;
512 if (info->groups == NULL) {
513 info->groups = pdb_search_groups();
514 if (info->groups == NULL) {
515 return 0;
518 /* Fetch the last possible entry, thus trigger an enumeration */
519 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
521 /* Ensure we cache this enumeration. */
522 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
524 return info->groups->num_entries;
527 static uint32 count_sam_aliases(struct disp_info *info)
529 struct samr_displayentry *entry;
531 if (info->aliases == NULL) {
532 info->aliases = pdb_search_aliases(&info->sid);
533 if (info->aliases == NULL) {
534 return 0;
537 /* Fetch the last possible entry, thus trigger an enumeration */
538 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
540 /* Ensure we cache this enumeration. */
541 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
543 return info->aliases->num_entries;
546 /*******************************************************************
547 _samr_Close
548 ********************************************************************/
550 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
552 if (!close_policy_hnd(p, r->in.handle)) {
553 return NT_STATUS_INVALID_HANDLE;
556 ZERO_STRUCTP(r->out.handle);
558 return NT_STATUS_OK;
561 /*******************************************************************
562 _samr_OpenDomain
563 ********************************************************************/
565 NTSTATUS _samr_OpenDomain(pipes_struct *p,
566 struct samr_OpenDomain *r)
568 struct samr_info *info;
569 SEC_DESC *psd = NULL;
570 uint32 acc_granted;
571 uint32 des_access = r->in.access_mask;
572 NTSTATUS status;
573 size_t sd_size;
574 SE_PRIV se_rights;
576 /* find the connection policy handle. */
578 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
579 return NT_STATUS_INVALID_HANDLE;
581 status = access_check_samr_function(info->acc_granted,
582 SA_RIGHT_SAM_OPEN_DOMAIN,
583 "_samr_OpenDomain" );
585 if ( !NT_STATUS_IS_OK(status) )
586 return status;
588 /*check if access can be granted as requested by client. */
590 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
591 se_map_generic( &des_access, &dom_generic_mapping );
593 se_priv_copy( &se_rights, &se_machine_account );
594 se_priv_add( &se_rights, &se_add_users );
596 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
597 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
598 &acc_granted, "_samr_OpenDomain" );
600 if ( !NT_STATUS_IS_OK(status) )
601 return status;
603 if (!sid_check_is_domain(r->in.sid) &&
604 !sid_check_is_builtin(r->in.sid)) {
605 return NT_STATUS_NO_SUCH_DOMAIN;
608 /* associate the domain SID with the (unique) handle. */
609 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
610 return NT_STATUS_NO_MEMORY;
611 info->acc_granted = acc_granted;
613 /* get a (unique) handle. open a policy on it. */
614 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
615 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
617 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
619 return NT_STATUS_OK;
622 /*******************************************************************
623 _samr_GetUserPwInfo
624 ********************************************************************/
626 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
627 struct samr_GetUserPwInfo *r)
629 struct samr_info *info = NULL;
630 enum lsa_SidType sid_type;
631 uint32_t min_password_length = 0;
632 uint32_t password_properties = 0;
633 bool ret = false;
634 NTSTATUS status;
636 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
638 /* find the policy handle. open a policy on it. */
639 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
640 return NT_STATUS_INVALID_HANDLE;
643 status = access_check_samr_function(info->acc_granted,
644 SAMR_USER_ACCESS_GET_ATTRIBUTES,
645 "_samr_GetUserPwInfo" );
646 if (!NT_STATUS_IS_OK(status)) {
647 return status;
650 if (!sid_check_is_in_our_domain(&info->sid)) {
651 return NT_STATUS_OBJECT_TYPE_MISMATCH;
654 become_root();
655 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
656 unbecome_root();
657 if (ret == false) {
658 return NT_STATUS_NO_SUCH_USER;
661 switch (sid_type) {
662 case SID_NAME_USER:
663 become_root();
664 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
665 &min_password_length);
666 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
667 &password_properties);
668 unbecome_root();
670 if (lp_check_password_script() && *lp_check_password_script()) {
671 password_properties |= DOMAIN_PASSWORD_COMPLEX;
674 break;
675 default:
676 break;
679 r->out.info->min_password_length = min_password_length;
680 r->out.info->password_properties = password_properties;
682 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
684 return NT_STATUS_OK;
687 /*******************************************************************
688 ********************************************************************/
690 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
691 DOM_SID *sid, uint32 *acc_granted,
692 DISP_INFO **ppdisp_info)
694 struct samr_info *info = NULL;
696 /* find the policy handle. open a policy on it. */
697 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
698 return False;
700 if (!info)
701 return False;
703 *sid = info->sid;
704 *acc_granted = info->acc_granted;
705 if (ppdisp_info) {
706 *ppdisp_info = info->disp_info;
709 return True;
712 /*******************************************************************
713 _samr_SetSecurity
714 ********************************************************************/
716 NTSTATUS _samr_SetSecurity(pipes_struct *p,
717 struct samr_SetSecurity *r)
719 DOM_SID pol_sid;
720 uint32 acc_granted, i;
721 SEC_ACL *dacl;
722 bool ret;
723 struct samu *sampass=NULL;
724 NTSTATUS status;
726 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
727 return NT_STATUS_INVALID_HANDLE;
729 if (!(sampass = samu_new( p->mem_ctx))) {
730 DEBUG(0,("No memory!\n"));
731 return NT_STATUS_NO_MEMORY;
734 /* get the user record */
735 become_root();
736 ret = pdb_getsampwsid(sampass, &pol_sid);
737 unbecome_root();
739 if (!ret) {
740 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
741 TALLOC_FREE(sampass);
742 return NT_STATUS_INVALID_HANDLE;
745 dacl = r->in.sdbuf->sd->dacl;
746 for (i=0; i < dacl->num_aces; i++) {
747 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
748 ret = pdb_set_pass_can_change(sampass,
749 (dacl->aces[i].access_mask &
750 SA_RIGHT_USER_CHANGE_PASSWORD) ?
751 True: False);
752 break;
756 if (!ret) {
757 TALLOC_FREE(sampass);
758 return NT_STATUS_ACCESS_DENIED;
761 status = access_check_samr_function(acc_granted,
762 SA_RIGHT_USER_SET_ATTRIBUTES,
763 "_samr_SetSecurity");
764 if (NT_STATUS_IS_OK(status)) {
765 become_root();
766 status = pdb_update_sam_account(sampass);
767 unbecome_root();
770 TALLOC_FREE(sampass);
772 return status;
775 /*******************************************************************
776 build correct perms based on policies and password times for _samr_query_sec_obj
777 *******************************************************************/
778 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
780 struct samu *sampass=NULL;
781 bool ret;
783 if ( !(sampass = samu_new( mem_ctx )) ) {
784 DEBUG(0,("No memory!\n"));
785 return False;
788 become_root();
789 ret = pdb_getsampwsid(sampass, user_sid);
790 unbecome_root();
792 if (ret == False) {
793 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
794 TALLOC_FREE(sampass);
795 return False;
798 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
800 if (pdb_get_pass_can_change(sampass)) {
801 TALLOC_FREE(sampass);
802 return True;
804 TALLOC_FREE(sampass);
805 return False;
809 /*******************************************************************
810 _samr_QuerySecurity
811 ********************************************************************/
813 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
814 struct samr_QuerySecurity *r)
816 NTSTATUS status;
817 DOM_SID pol_sid;
818 SEC_DESC * psd = NULL;
819 uint32 acc_granted;
820 size_t sd_size;
822 /* Get the SID. */
823 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
824 return NT_STATUS_INVALID_HANDLE;
826 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
827 sid_string_dbg(&pol_sid)));
829 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
831 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
832 if (pol_sid.sid_rev_num == 0) {
833 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
834 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
835 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
836 /* check if it is our domain SID */
837 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
838 "with SID: %s\n", sid_string_dbg(&pol_sid)));
839 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
840 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
841 /* check if it is the Builtin Domain */
842 /* TODO: Builtin probably needs a different SD with restricted write access*/
843 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
844 "Domain 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_check_is_in_our_domain(&pol_sid) ||
847 sid_check_is_in_builtin(&pol_sid)) {
848 /* TODO: different SDs have to be generated for aliases groups and users.
849 Currently all three get a default user SD */
850 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
851 "with SID: %s\n", sid_string_dbg(&pol_sid)));
852 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
853 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
854 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
855 } else {
856 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
857 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
859 } else {
860 return NT_STATUS_OBJECT_TYPE_MISMATCH;
863 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
864 return NT_STATUS_NO_MEMORY;
866 return status;
869 /*******************************************************************
870 makes a SAM_ENTRY / UNISTR2* structure from a user list.
871 ********************************************************************/
873 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
874 struct samr_SamEntry **sam_pp,
875 uint32_t num_entries,
876 uint32_t start_idx,
877 struct samr_displayentry *entries)
879 uint32_t i;
880 struct samr_SamEntry *sam;
882 *sam_pp = NULL;
884 if (num_entries == 0) {
885 return NT_STATUS_OK;
888 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
889 if (sam == NULL) {
890 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
891 return NT_STATUS_NO_MEMORY;
894 for (i = 0; i < num_entries; i++) {
895 #if 0
897 * usrmgr expects a non-NULL terminated string with
898 * trust relationships
900 if (entries[i].acct_flags & ACB_DOMTRUST) {
901 init_unistr2(&uni_temp_name, entries[i].account_name,
902 UNI_FLAGS_NONE);
903 } else {
904 init_unistr2(&uni_temp_name, entries[i].account_name,
905 UNI_STR_TERMINATE);
907 #endif
908 init_lsa_String(&sam[i].name, entries[i].account_name);
909 sam[i].idx = entries[i].rid;
912 *sam_pp = sam;
914 return NT_STATUS_OK;
917 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
919 /*******************************************************************
920 _samr_EnumDomainUsers
921 ********************************************************************/
923 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
924 struct samr_EnumDomainUsers *r)
926 NTSTATUS status;
927 struct samr_info *info = NULL;
928 int num_account;
929 uint32 enum_context = *r->in.resume_handle;
930 enum remote_arch_types ra_type = get_remote_arch();
931 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
932 uint32 max_entries = max_sam_entries;
933 struct samr_displayentry *entries = NULL;
934 struct samr_SamArray *samr_array = NULL;
935 struct samr_SamEntry *samr_entries = NULL;
937 /* find the policy handle. open a policy on it. */
938 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
939 return NT_STATUS_INVALID_HANDLE;
941 status = access_check_samr_function(info->acc_granted,
942 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
943 "_samr_EnumDomainUsers");
944 if (!NT_STATUS_IS_OK(status)) {
945 return status;
948 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
950 if (info->builtin_domain) {
951 /* No users in builtin. */
952 *r->out.resume_handle = *r->in.resume_handle;
953 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
954 return status;
957 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
958 if (!samr_array) {
959 return NT_STATUS_NO_MEMORY;
962 become_root();
964 /* AS ROOT !!!! */
966 if ((info->disp_info->enum_users != NULL) &&
967 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
968 pdb_search_destroy(info->disp_info->enum_users);
969 info->disp_info->enum_users = NULL;
972 if (info->disp_info->enum_users == NULL) {
973 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
974 info->disp_info->enum_acb_mask = r->in.acct_flags;
977 if (info->disp_info->enum_users == NULL) {
978 /* END AS ROOT !!!! */
979 unbecome_root();
980 return NT_STATUS_ACCESS_DENIED;
983 num_account = pdb_search_entries(info->disp_info->enum_users,
984 enum_context, max_entries,
985 &entries);
987 /* END AS ROOT !!!! */
989 unbecome_root();
991 if (num_account == 0) {
992 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
993 "total entries\n"));
994 *r->out.resume_handle = *r->in.resume_handle;
995 return NT_STATUS_OK;
998 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
999 num_account, enum_context,
1000 entries);
1001 if (!NT_STATUS_IS_OK(status)) {
1002 return status;
1005 if (max_entries <= num_account) {
1006 status = STATUS_MORE_ENTRIES;
1007 } else {
1008 status = NT_STATUS_OK;
1011 /* Ensure we cache this enumeration. */
1012 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1014 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1016 samr_array->count = num_account;
1017 samr_array->entries = samr_entries;
1019 *r->out.resume_handle = *r->in.resume_handle + num_account;
1020 *r->out.sam = samr_array;
1021 *r->out.num_entries = num_account;
1023 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1025 return status;
1028 /*******************************************************************
1029 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1030 ********************************************************************/
1032 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1033 struct samr_SamEntry **sam_pp,
1034 uint32_t num_sam_entries,
1035 struct samr_displayentry *entries)
1037 struct samr_SamEntry *sam;
1038 uint32_t i;
1040 *sam_pp = NULL;
1042 if (num_sam_entries == 0) {
1043 return;
1046 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1047 if (sam == NULL) {
1048 return;
1051 for (i = 0; i < num_sam_entries; i++) {
1053 * JRA. I think this should include the null. TNG does not.
1055 init_lsa_String(&sam[i].name, entries[i].account_name);
1056 sam[i].idx = entries[i].rid;
1059 *sam_pp = sam;
1062 /*******************************************************************
1063 _samr_EnumDomainGroups
1064 ********************************************************************/
1066 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1067 struct samr_EnumDomainGroups *r)
1069 NTSTATUS status;
1070 struct samr_info *info = NULL;
1071 struct samr_displayentry *groups;
1072 uint32 num_groups;
1073 struct samr_SamArray *samr_array = NULL;
1074 struct samr_SamEntry *samr_entries = NULL;
1076 /* find the policy handle. open a policy on it. */
1077 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1078 return NT_STATUS_INVALID_HANDLE;
1080 status = access_check_samr_function(info->acc_granted,
1081 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1082 "_samr_EnumDomainGroups");
1083 if (!NT_STATUS_IS_OK(status)) {
1084 return status;
1087 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1089 if (info->builtin_domain) {
1090 /* No groups in builtin. */
1091 *r->out.resume_handle = *r->in.resume_handle;
1092 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1093 return status;
1096 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1097 if (!samr_array) {
1098 return NT_STATUS_NO_MEMORY;
1101 /* the domain group array is being allocated in the function below */
1103 become_root();
1105 if (info->disp_info->groups == NULL) {
1106 info->disp_info->groups = pdb_search_groups();
1108 if (info->disp_info->groups == NULL) {
1109 unbecome_root();
1110 return NT_STATUS_ACCESS_DENIED;
1114 num_groups = pdb_search_entries(info->disp_info->groups,
1115 *r->in.resume_handle,
1116 MAX_SAM_ENTRIES, &groups);
1117 unbecome_root();
1119 /* Ensure we cache this enumeration. */
1120 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1122 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1123 num_groups, groups);
1125 samr_array->count = num_groups;
1126 samr_array->entries = samr_entries;
1128 *r->out.sam = samr_array;
1129 *r->out.num_entries = num_groups;
1130 /* this was missing, IMHO:
1131 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1134 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1136 return status;
1139 /*******************************************************************
1140 _samr_EnumDomainAliases
1141 ********************************************************************/
1143 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1144 struct samr_EnumDomainAliases *r)
1146 NTSTATUS status;
1147 struct samr_info *info;
1148 struct samr_displayentry *aliases;
1149 uint32 num_aliases = 0;
1150 struct samr_SamArray *samr_array = NULL;
1151 struct samr_SamEntry *samr_entries = NULL;
1153 /* find the policy handle. open a policy on it. */
1154 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1155 return NT_STATUS_INVALID_HANDLE;
1157 status = access_check_samr_function(info->acc_granted,
1158 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1159 "_samr_EnumDomainAliases");
1160 if (!NT_STATUS_IS_OK(status)) {
1161 return status;
1164 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1165 sid_string_dbg(&info->sid)));
1167 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1168 if (!samr_array) {
1169 return NT_STATUS_NO_MEMORY;
1172 become_root();
1174 if (info->disp_info->aliases == NULL) {
1175 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1176 if (info->disp_info->aliases == NULL) {
1177 unbecome_root();
1178 return NT_STATUS_ACCESS_DENIED;
1182 num_aliases = pdb_search_entries(info->disp_info->aliases,
1183 *r->in.resume_handle,
1184 MAX_SAM_ENTRIES, &aliases);
1185 unbecome_root();
1187 /* Ensure we cache this enumeration. */
1188 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1190 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1191 num_aliases, aliases);
1193 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1195 samr_array->count = num_aliases;
1196 samr_array->entries = samr_entries;
1198 *r->out.sam = samr_array;
1199 *r->out.num_entries = num_aliases;
1200 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1202 return status;
1205 /*******************************************************************
1206 inits a samr_DispInfoGeneral structure.
1207 ********************************************************************/
1209 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1210 struct samr_DispInfoGeneral *r,
1211 uint32_t num_entries,
1212 uint32_t start_idx,
1213 struct samr_displayentry *entries)
1215 uint32 i;
1217 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1219 if (num_entries == 0) {
1220 return NT_STATUS_OK;
1223 r->count = num_entries;
1225 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1226 if (!r->entries) {
1227 return NT_STATUS_NO_MEMORY;
1230 for (i = 0; i < num_entries ; i++) {
1232 init_lsa_String(&r->entries[i].account_name,
1233 entries[i].account_name);
1235 init_lsa_String(&r->entries[i].description,
1236 entries[i].description);
1238 init_lsa_String(&r->entries[i].full_name,
1239 entries[i].fullname);
1241 r->entries[i].rid = entries[i].rid;
1242 r->entries[i].acct_flags = entries[i].acct_flags;
1243 r->entries[i].idx = start_idx+i+1;
1246 return NT_STATUS_OK;
1249 /*******************************************************************
1250 inits a samr_DispInfoFull structure.
1251 ********************************************************************/
1253 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1254 struct samr_DispInfoFull *r,
1255 uint32_t num_entries,
1256 uint32_t start_idx,
1257 struct samr_displayentry *entries)
1259 uint32_t i;
1261 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1263 if (num_entries == 0) {
1264 return NT_STATUS_OK;
1267 r->count = num_entries;
1269 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1270 if (!r->entries) {
1271 return NT_STATUS_NO_MEMORY;
1274 for (i = 0; i < num_entries ; i++) {
1276 init_lsa_String(&r->entries[i].account_name,
1277 entries[i].account_name);
1279 init_lsa_String(&r->entries[i].description,
1280 entries[i].description);
1282 r->entries[i].rid = entries[i].rid;
1283 r->entries[i].acct_flags = entries[i].acct_flags;
1284 r->entries[i].idx = start_idx+i+1;
1287 return NT_STATUS_OK;
1290 /*******************************************************************
1291 inits a samr_DispInfoFullGroups structure.
1292 ********************************************************************/
1294 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1295 struct samr_DispInfoFullGroups *r,
1296 uint32_t num_entries,
1297 uint32_t start_idx,
1298 struct samr_displayentry *entries)
1300 uint32_t i;
1302 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1304 if (num_entries == 0) {
1305 return NT_STATUS_OK;
1308 r->count = num_entries;
1310 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1311 if (!r->entries) {
1312 return NT_STATUS_NO_MEMORY;
1315 for (i = 0; i < num_entries ; i++) {
1317 init_lsa_String(&r->entries[i].account_name,
1318 entries[i].account_name);
1320 init_lsa_String(&r->entries[i].description,
1321 entries[i].description);
1323 r->entries[i].rid = entries[i].rid;
1324 r->entries[i].acct_flags = entries[i].acct_flags;
1325 r->entries[i].idx = start_idx+i+1;
1328 return NT_STATUS_OK;
1331 /*******************************************************************
1332 inits a samr_DispInfoAscii structure.
1333 ********************************************************************/
1335 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1336 struct samr_DispInfoAscii *r,
1337 uint32_t num_entries,
1338 uint32_t start_idx,
1339 struct samr_displayentry *entries)
1341 uint32_t i;
1343 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1345 if (num_entries == 0) {
1346 return NT_STATUS_OK;
1349 r->count = num_entries;
1351 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1352 if (!r->entries) {
1353 return NT_STATUS_NO_MEMORY;
1356 for (i = 0; i < num_entries ; i++) {
1358 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1359 entries[i].account_name);
1361 r->entries[i].idx = start_idx+i+1;
1364 return NT_STATUS_OK;
1367 /*******************************************************************
1368 inits a samr_DispInfoAscii structure.
1369 ********************************************************************/
1371 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1372 struct samr_DispInfoAscii *r,
1373 uint32_t num_entries,
1374 uint32_t start_idx,
1375 struct samr_displayentry *entries)
1377 uint32_t i;
1379 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1381 if (num_entries == 0) {
1382 return NT_STATUS_OK;
1385 r->count = num_entries;
1387 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1388 if (!r->entries) {
1389 return NT_STATUS_NO_MEMORY;
1392 for (i = 0; i < num_entries ; i++) {
1394 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1395 entries[i].account_name);
1397 r->entries[i].idx = start_idx+i+1;
1400 return NT_STATUS_OK;
1403 /*******************************************************************
1404 _samr_QueryDisplayInfo
1405 ********************************************************************/
1407 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1408 struct samr_QueryDisplayInfo *r)
1410 NTSTATUS status;
1411 struct samr_info *info = NULL;
1412 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1414 uint32 max_entries = r->in.max_entries;
1415 uint32 enum_context = r->in.start_idx;
1416 uint32 max_size = r->in.buf_size;
1418 union samr_DispInfo *disp_info = r->out.info;
1420 uint32 temp_size=0, total_data_size=0;
1421 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1422 uint32 num_account = 0;
1423 enum remote_arch_types ra_type = get_remote_arch();
1424 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1425 struct samr_displayentry *entries = NULL;
1427 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1429 /* find the policy handle. open a policy on it. */
1430 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1431 return NT_STATUS_INVALID_HANDLE;
1434 * calculate how many entries we will return.
1435 * based on
1436 * - the number of entries the client asked
1437 * - our limit on that
1438 * - the starting point (enumeration context)
1439 * - the buffer size the client will accept
1443 * We are a lot more like W2K. Instead of reading the SAM
1444 * each time to find the records we need to send back,
1445 * we read it once and link that copy to the sam handle.
1446 * For large user list (over the MAX_SAM_ENTRIES)
1447 * it's a definitive win.
1448 * second point to notice: between enumerations
1449 * our sam is now the same as it's a snapshoot.
1450 * third point: got rid of the static SAM_USER_21 struct
1451 * no more intermediate.
1452 * con: it uses much more memory, as a full copy is stored
1453 * in memory.
1455 * If you want to change it, think twice and think
1456 * of the second point , that's really important.
1458 * JFM, 12/20/2001
1461 if ((r->in.level < 1) || (r->in.level > 5)) {
1462 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1463 (unsigned int)r->in.level ));
1464 return NT_STATUS_INVALID_INFO_CLASS;
1467 /* first limit the number of entries we will return */
1468 if(max_entries > max_sam_entries) {
1469 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1470 "entries, limiting to %d\n", max_entries,
1471 max_sam_entries));
1472 max_entries = max_sam_entries;
1475 /* calculate the size and limit on the number of entries we will
1476 * return */
1478 temp_size=max_entries*struct_size;
1480 if (temp_size>max_size) {
1481 max_entries=MIN((max_size/struct_size),max_entries);;
1482 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1483 "only %d entries\n", max_entries));
1486 become_root();
1488 /* THe following done as ROOT. Don't return without unbecome_root(). */
1490 switch (r->in.level) {
1491 case 0x1:
1492 case 0x4:
1493 if (info->disp_info->users == NULL) {
1494 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1495 if (info->disp_info->users == NULL) {
1496 unbecome_root();
1497 return NT_STATUS_ACCESS_DENIED;
1499 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1500 (unsigned int)enum_context ));
1501 } else {
1502 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1503 (unsigned int)enum_context ));
1506 num_account = pdb_search_entries(info->disp_info->users,
1507 enum_context, max_entries,
1508 &entries);
1509 break;
1510 case 0x2:
1511 if (info->disp_info->machines == NULL) {
1512 info->disp_info->machines =
1513 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1514 if (info->disp_info->machines == NULL) {
1515 unbecome_root();
1516 return NT_STATUS_ACCESS_DENIED;
1518 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1519 (unsigned int)enum_context ));
1520 } else {
1521 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1522 (unsigned int)enum_context ));
1525 num_account = pdb_search_entries(info->disp_info->machines,
1526 enum_context, max_entries,
1527 &entries);
1528 break;
1529 case 0x3:
1530 case 0x5:
1531 if (info->disp_info->groups == NULL) {
1532 info->disp_info->groups = pdb_search_groups();
1533 if (info->disp_info->groups == NULL) {
1534 unbecome_root();
1535 return NT_STATUS_ACCESS_DENIED;
1537 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1538 (unsigned int)enum_context ));
1539 } else {
1540 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1541 (unsigned int)enum_context ));
1544 num_account = pdb_search_entries(info->disp_info->groups,
1545 enum_context, max_entries,
1546 &entries);
1547 break;
1548 default:
1549 unbecome_root();
1550 smb_panic("info class changed");
1551 break;
1553 unbecome_root();
1556 /* Now create reply structure */
1557 switch (r->in.level) {
1558 case 0x1:
1559 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1560 num_account, enum_context,
1561 entries);
1562 break;
1563 case 0x2:
1564 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1565 num_account, enum_context,
1566 entries);
1567 break;
1568 case 0x3:
1569 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1570 num_account, enum_context,
1571 entries);
1572 break;
1573 case 0x4:
1574 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1575 num_account, enum_context,
1576 entries);
1577 break;
1578 case 0x5:
1579 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1580 num_account, enum_context,
1581 entries);
1582 break;
1583 default:
1584 smb_panic("info class changed");
1585 break;
1588 if (!NT_STATUS_IS_OK(disp_ret))
1589 return disp_ret;
1591 /* calculate the total size */
1592 total_data_size=num_account*struct_size;
1594 if (num_account) {
1595 status = STATUS_MORE_ENTRIES;
1596 } else {
1597 status = NT_STATUS_OK;
1600 /* Ensure we cache this enumeration. */
1601 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1603 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1605 *r->out.total_size = total_data_size;
1606 *r->out.returned_size = temp_size;
1608 return status;
1611 /****************************************************************
1612 _samr_QueryDisplayInfo2
1613 ****************************************************************/
1615 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1616 struct samr_QueryDisplayInfo2 *r)
1618 struct samr_QueryDisplayInfo q;
1620 q.in.domain_handle = r->in.domain_handle;
1621 q.in.level = r->in.level;
1622 q.in.start_idx = r->in.start_idx;
1623 q.in.max_entries = r->in.max_entries;
1624 q.in.buf_size = r->in.buf_size;
1626 q.out.total_size = r->out.total_size;
1627 q.out.returned_size = r->out.returned_size;
1628 q.out.info = r->out.info;
1630 return _samr_QueryDisplayInfo(p, &q);
1633 /****************************************************************
1634 _samr_QueryDisplayInfo3
1635 ****************************************************************/
1637 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1638 struct samr_QueryDisplayInfo3 *r)
1640 struct samr_QueryDisplayInfo q;
1642 q.in.domain_handle = r->in.domain_handle;
1643 q.in.level = r->in.level;
1644 q.in.start_idx = r->in.start_idx;
1645 q.in.max_entries = r->in.max_entries;
1646 q.in.buf_size = r->in.buf_size;
1648 q.out.total_size = r->out.total_size;
1649 q.out.returned_size = r->out.returned_size;
1650 q.out.info = r->out.info;
1652 return _samr_QueryDisplayInfo(p, &q);
1655 /*******************************************************************
1656 _samr_QueryAliasInfo
1657 ********************************************************************/
1659 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1660 struct samr_QueryAliasInfo *r)
1662 DOM_SID sid;
1663 struct acct_info info;
1664 uint32 acc_granted;
1665 NTSTATUS status;
1666 union samr_AliasInfo *alias_info = NULL;
1667 const char *alias_name = NULL;
1668 const char *alias_description = NULL;
1670 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1672 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1673 if (!alias_info) {
1674 return NT_STATUS_NO_MEMORY;
1677 /* find the policy handle. open a policy on it. */
1678 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1679 return NT_STATUS_INVALID_HANDLE;
1681 status = access_check_samr_function(acc_granted,
1682 SA_RIGHT_ALIAS_LOOKUP_INFO,
1683 "_samr_QueryAliasInfo");
1684 if (!NT_STATUS_IS_OK(status)) {
1685 return status;
1688 become_root();
1689 status = pdb_get_aliasinfo(&sid, &info);
1690 unbecome_root();
1692 if ( !NT_STATUS_IS_OK(status))
1693 return status;
1695 /* FIXME: info contains fstrings */
1696 alias_name = talloc_strdup(r, info.acct_name);
1697 alias_description = talloc_strdup(r, info.acct_desc);
1699 switch (r->in.level) {
1700 case ALIASINFOALL:
1701 init_samr_alias_info1(&alias_info->all,
1702 alias_name,
1704 alias_description);
1705 break;
1706 case ALIASINFODESCRIPTION:
1707 init_samr_alias_info3(&alias_info->description,
1708 alias_description);
1709 break;
1710 default:
1711 return NT_STATUS_INVALID_INFO_CLASS;
1714 *r->out.info = alias_info;
1716 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1718 return NT_STATUS_OK;
1721 #if 0
1722 /*******************************************************************
1723 samr_reply_lookup_ids
1724 ********************************************************************/
1726 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1728 uint32 rid[MAX_SAM_ENTRIES];
1729 int num_rids = q_u->num_sids1;
1731 r_u->status = NT_STATUS_OK;
1733 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1735 if (num_rids > MAX_SAM_ENTRIES) {
1736 num_rids = MAX_SAM_ENTRIES;
1737 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1740 #if 0
1741 int i;
1742 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1744 for (i = 0; i < num_rids && status == 0; i++)
1746 struct sam_passwd *sam_pass;
1747 fstring user_name;
1750 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1751 q_u->uni_user_name[i].uni_str_len));
1753 /* find the user account */
1754 become_root();
1755 sam_pass = get_smb21pwd_entry(user_name, 0);
1756 unbecome_root();
1758 if (sam_pass == NULL)
1760 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1761 rid[i] = 0;
1763 else
1765 rid[i] = sam_pass->user_rid;
1768 #endif
1770 num_rids = 1;
1771 rid[0] = BUILTIN_ALIAS_RID_USERS;
1773 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1775 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1777 return r_u->status;
1779 #endif
1781 /*******************************************************************
1782 _samr_LookupNames
1783 ********************************************************************/
1785 NTSTATUS _samr_LookupNames(pipes_struct *p,
1786 struct samr_LookupNames *r)
1788 NTSTATUS status;
1789 uint32 rid[MAX_SAM_ENTRIES];
1790 enum lsa_SidType type[MAX_SAM_ENTRIES];
1791 int i;
1792 int num_rids = r->in.num_names;
1793 DOM_SID pol_sid;
1794 uint32 acc_granted;
1795 struct samr_Ids rids, types;
1797 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1799 ZERO_ARRAY(rid);
1800 ZERO_ARRAY(type);
1802 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1803 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1806 status = access_check_samr_function(acc_granted,
1807 0, /* Don't know the acc_bits yet */
1808 "_samr_LookupNames");
1809 if (!NT_STATUS_IS_OK(status)) {
1810 return status;
1813 if (num_rids > MAX_SAM_ENTRIES) {
1814 num_rids = MAX_SAM_ENTRIES;
1815 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1818 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1819 sid_string_dbg(&pol_sid)));
1821 for (i = 0; i < num_rids; i++) {
1823 status = NT_STATUS_NONE_MAPPED;
1824 type[i] = SID_NAME_UNKNOWN;
1826 rid[i] = 0xffffffff;
1828 if (sid_check_is_builtin(&pol_sid)) {
1829 if (lookup_builtin_name(r->in.names[i].string,
1830 &rid[i]))
1832 type[i] = SID_NAME_ALIAS;
1834 } else {
1835 lookup_global_sam_name(r->in.names[i].string, 0,
1836 &rid[i], &type[i]);
1839 if (type[i] != SID_NAME_UNKNOWN) {
1840 status = NT_STATUS_OK;
1844 rids.count = num_rids;
1845 rids.ids = rid;
1847 types.count = num_rids;
1848 types.ids = type;
1850 *r->out.rids = rids;
1851 *r->out.types = types;
1853 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1855 return status;
1858 /*******************************************************************
1859 _samr_ChangePasswordUser2
1860 ********************************************************************/
1862 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1863 struct samr_ChangePasswordUser2 *r)
1865 NTSTATUS status;
1866 fstring user_name;
1867 fstring wks;
1869 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1871 fstrcpy(user_name, r->in.account->string);
1872 fstrcpy(wks, r->in.server->string);
1874 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1877 * Pass the user through the NT -> unix user mapping
1878 * function.
1881 (void)map_username(user_name);
1884 * UNIX username case mangling not required, pass_oem_change
1885 * is case insensitive.
1888 status = pass_oem_change(user_name,
1889 r->in.lm_password->data,
1890 r->in.lm_verifier->hash,
1891 r->in.nt_password->data,
1892 r->in.nt_verifier->hash,
1893 NULL);
1895 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1897 return status;
1900 /*******************************************************************
1901 _samr_ChangePasswordUser3
1902 ********************************************************************/
1904 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1905 struct samr_ChangePasswordUser3 *r)
1907 NTSTATUS status;
1908 fstring user_name;
1909 const char *wks = NULL;
1910 uint32 reject_reason;
1911 struct samr_DomInfo1 *dominfo = NULL;
1912 struct samr_ChangeReject *reject = NULL;
1914 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1916 fstrcpy(user_name, r->in.account->string);
1917 if (r->in.server && r->in.server->string) {
1918 wks = r->in.server->string;
1921 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1924 * Pass the user through the NT -> unix user mapping
1925 * function.
1928 (void)map_username(user_name);
1931 * UNIX username case mangling not required, pass_oem_change
1932 * is case insensitive.
1935 status = pass_oem_change(user_name,
1936 r->in.lm_password->data,
1937 r->in.lm_verifier->hash,
1938 r->in.nt_password->data,
1939 r->in.nt_verifier->hash,
1940 &reject_reason);
1942 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1943 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1945 uint32 min_pass_len,pass_hist,password_properties;
1946 time_t u_expire, u_min_age;
1947 NTTIME nt_expire, nt_min_age;
1948 uint32 account_policy_temp;
1950 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1951 if (!dominfo) {
1952 return NT_STATUS_NO_MEMORY;
1955 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1956 if (!reject) {
1957 return NT_STATUS_NO_MEMORY;
1960 become_root();
1962 /* AS ROOT !!! */
1964 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1965 min_pass_len = account_policy_temp;
1967 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1968 pass_hist = account_policy_temp;
1970 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1971 password_properties = account_policy_temp;
1973 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1974 u_expire = account_policy_temp;
1976 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1977 u_min_age = account_policy_temp;
1979 /* !AS ROOT */
1981 unbecome_root();
1983 unix_to_nt_time_abs(&nt_expire, u_expire);
1984 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1986 if (lp_check_password_script() && *lp_check_password_script()) {
1987 password_properties |= DOMAIN_PASSWORD_COMPLEX;
1990 init_samr_DomInfo1(dominfo,
1991 min_pass_len,
1992 pass_hist,
1993 password_properties,
1994 u_expire,
1995 u_min_age);
1997 reject->reason = reject_reason;
1999 *r->out.dominfo = dominfo;
2000 *r->out.reject = reject;
2003 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2005 return status;
2008 /*******************************************************************
2009 makes a SAMR_R_LOOKUP_RIDS structure.
2010 ********************************************************************/
2012 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2013 const char **names,
2014 struct lsa_String **lsa_name_array_p)
2016 struct lsa_String *lsa_name_array = NULL;
2017 uint32_t i;
2019 *lsa_name_array_p = NULL;
2021 if (num_names != 0) {
2022 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2023 if (!lsa_name_array) {
2024 return false;
2028 for (i = 0; i < num_names; i++) {
2029 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2030 init_lsa_String(&lsa_name_array[i], names[i]);
2033 *lsa_name_array_p = lsa_name_array;
2035 return true;
2038 /*******************************************************************
2039 _samr_LookupRids
2040 ********************************************************************/
2042 NTSTATUS _samr_LookupRids(pipes_struct *p,
2043 struct samr_LookupRids *r)
2045 NTSTATUS status;
2046 const char **names;
2047 enum lsa_SidType *attrs = NULL;
2048 uint32 *wire_attrs = NULL;
2049 DOM_SID pol_sid;
2050 int num_rids = (int)r->in.num_rids;
2051 uint32 acc_granted;
2052 int i;
2053 struct lsa_Strings names_array;
2054 struct samr_Ids types_array;
2055 struct lsa_String *lsa_names = NULL;
2057 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2059 /* find the policy handle. open a policy on it. */
2060 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2061 return NT_STATUS_INVALID_HANDLE;
2063 if (num_rids > 1000) {
2064 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2065 "to samba4 idl this is not possible\n", num_rids));
2066 return NT_STATUS_UNSUCCESSFUL;
2069 if (num_rids) {
2070 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2071 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2072 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2074 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2075 return NT_STATUS_NO_MEMORY;
2076 } else {
2077 names = NULL;
2078 attrs = NULL;
2079 wire_attrs = NULL;
2082 become_root(); /* lookup_sid can require root privs */
2083 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2084 names, attrs);
2085 unbecome_root();
2087 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2088 status = NT_STATUS_OK;
2091 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2092 &lsa_names)) {
2093 return NT_STATUS_NO_MEMORY;
2096 /* Convert from enum lsa_SidType to uint32 for wire format. */
2097 for (i = 0; i < num_rids; i++) {
2098 wire_attrs[i] = (uint32)attrs[i];
2101 names_array.count = num_rids;
2102 names_array.names = lsa_names;
2104 types_array.count = num_rids;
2105 types_array.ids = wire_attrs;
2107 *r->out.names = names_array;
2108 *r->out.types = types_array;
2110 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2112 return status;
2115 /*******************************************************************
2116 _samr_OpenUser
2117 ********************************************************************/
2119 NTSTATUS _samr_OpenUser(pipes_struct *p,
2120 struct samr_OpenUser *r)
2122 struct samu *sampass=NULL;
2123 DOM_SID sid;
2124 POLICY_HND domain_pol = *r->in.domain_handle;
2125 POLICY_HND *user_pol = r->out.user_handle;
2126 struct samr_info *info = NULL;
2127 SEC_DESC *psd = NULL;
2128 uint32 acc_granted;
2129 uint32 des_access = r->in.access_mask;
2130 size_t sd_size;
2131 bool ret;
2132 NTSTATUS nt_status;
2133 SE_PRIV se_rights;
2135 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2137 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2138 return NT_STATUS_INVALID_HANDLE;
2140 nt_status = access_check_samr_function(acc_granted,
2141 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2142 "_samr_OpenUser" );
2144 if ( !NT_STATUS_IS_OK(nt_status) )
2145 return nt_status;
2147 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2148 return NT_STATUS_NO_MEMORY;
2151 /* append the user's RID to it */
2153 if (!sid_append_rid(&sid, r->in.rid))
2154 return NT_STATUS_NO_SUCH_USER;
2156 /* check if access can be granted as requested by client. */
2158 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2159 se_map_generic(&des_access, &usr_generic_mapping);
2161 se_priv_copy( &se_rights, &se_machine_account );
2162 se_priv_add( &se_rights, &se_add_users );
2164 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2165 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2166 &acc_granted, "_samr_OpenUser");
2168 if ( !NT_STATUS_IS_OK(nt_status) )
2169 return nt_status;
2171 become_root();
2172 ret=pdb_getsampwsid(sampass, &sid);
2173 unbecome_root();
2175 /* check that the SID exists in our domain. */
2176 if (ret == False) {
2177 return NT_STATUS_NO_SUCH_USER;
2180 TALLOC_FREE(sampass);
2182 /* associate the user's SID and access bits with the new handle. */
2183 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2184 return NT_STATUS_NO_MEMORY;
2185 info->acc_granted = acc_granted;
2187 /* get a (unique) handle. open a policy on it. */
2188 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2189 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2191 return NT_STATUS_OK;
2194 /*************************************************************************
2195 *************************************************************************/
2197 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2198 DATA_BLOB *blob,
2199 struct lsa_BinaryString **_r)
2201 struct lsa_BinaryString *r;
2203 if (!blob || !_r) {
2204 return NT_STATUS_INVALID_PARAMETER;
2207 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2208 if (!r) {
2209 return NT_STATUS_NO_MEMORY;
2212 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2213 if (!r->array) {
2214 return NT_STATUS_NO_MEMORY;
2216 memcpy(r->array, blob->data, blob->length);
2217 r->size = blob->length;
2218 r->length = blob->length;
2220 if (!r->array) {
2221 return NT_STATUS_NO_MEMORY;
2224 *_r = r;
2226 return NT_STATUS_OK;
2229 /*************************************************************************
2230 get_user_info_7. Safe. Only gives out account_name.
2231 *************************************************************************/
2233 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2234 struct samr_UserInfo7 *r,
2235 DOM_SID *user_sid)
2237 struct samu *smbpass=NULL;
2238 bool ret;
2239 const char *account_name = NULL;
2241 ZERO_STRUCTP(r);
2243 if ( !(smbpass = samu_new( mem_ctx )) ) {
2244 return NT_STATUS_NO_MEMORY;
2247 become_root();
2248 ret = pdb_getsampwsid(smbpass, user_sid);
2249 unbecome_root();
2251 if ( !ret ) {
2252 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2253 return NT_STATUS_NO_SUCH_USER;
2256 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2257 if (!account_name) {
2258 TALLOC_FREE(smbpass);
2259 return NT_STATUS_NO_MEMORY;
2261 TALLOC_FREE(smbpass);
2263 DEBUG(3,("User:[%s]\n", account_name));
2265 init_samr_user_info7(r, account_name);
2267 return NT_STATUS_OK;
2270 /*************************************************************************
2271 get_user_info_9. Only gives out primary group SID.
2272 *************************************************************************/
2274 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2275 struct samr_UserInfo9 *r,
2276 DOM_SID *user_sid)
2278 struct samu *smbpass=NULL;
2279 bool ret;
2281 ZERO_STRUCTP(r);
2283 if ( !(smbpass = samu_new( mem_ctx )) ) {
2284 return NT_STATUS_NO_MEMORY;
2287 become_root();
2288 ret = pdb_getsampwsid(smbpass, user_sid);
2289 unbecome_root();
2291 if (ret==False) {
2292 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2293 TALLOC_FREE(smbpass);
2294 return NT_STATUS_NO_SUCH_USER;
2297 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2299 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2301 TALLOC_FREE(smbpass);
2303 return NT_STATUS_OK;
2306 /*************************************************************************
2307 get_user_info_16. Safe. Only gives out acb bits.
2308 *************************************************************************/
2310 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2311 struct samr_UserInfo16 *r,
2312 DOM_SID *user_sid)
2314 struct samu *smbpass=NULL;
2315 bool ret;
2317 ZERO_STRUCTP(r);
2319 if ( !(smbpass = samu_new( mem_ctx )) ) {
2320 return NT_STATUS_NO_MEMORY;
2323 become_root();
2324 ret = pdb_getsampwsid(smbpass, user_sid);
2325 unbecome_root();
2327 if (ret==False) {
2328 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2329 TALLOC_FREE(smbpass);
2330 return NT_STATUS_NO_SUCH_USER;
2333 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2335 init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2337 TALLOC_FREE(smbpass);
2339 return NT_STATUS_OK;
2342 /*************************************************************************
2343 get_user_info_18. OK - this is the killer as it gives out password info.
2344 Ensure that this is only allowed on an encrypted connection with a root
2345 user. JRA.
2346 *************************************************************************/
2348 static NTSTATUS get_user_info_18(pipes_struct *p,
2349 TALLOC_CTX *mem_ctx,
2350 struct samr_UserInfo18 *r,
2351 DOM_SID *user_sid)
2353 struct samu *smbpass=NULL;
2354 bool ret;
2356 ZERO_STRUCTP(r);
2358 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2359 return NT_STATUS_ACCESS_DENIED;
2362 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2363 return NT_STATUS_ACCESS_DENIED;
2367 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2370 if ( !(smbpass = samu_new( mem_ctx )) ) {
2371 return NT_STATUS_NO_MEMORY;
2374 ret = pdb_getsampwsid(smbpass, user_sid);
2376 if (ret == False) {
2377 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2378 TALLOC_FREE(smbpass);
2379 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2382 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2384 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2385 TALLOC_FREE(smbpass);
2386 return NT_STATUS_ACCOUNT_DISABLED;
2389 init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2390 pdb_get_nt_passwd(smbpass));
2392 TALLOC_FREE(smbpass);
2394 return NT_STATUS_OK;
2397 /*************************************************************************
2398 get_user_info_20
2399 *************************************************************************/
2401 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2402 struct samr_UserInfo20 *r,
2403 DOM_SID *user_sid)
2405 struct samu *sampass=NULL;
2406 bool ret;
2407 const char *munged_dial = NULL;
2408 DATA_BLOB blob;
2409 NTSTATUS status;
2410 struct lsa_BinaryString *parameters = NULL;
2412 ZERO_STRUCTP(r);
2414 if ( !(sampass = samu_new( mem_ctx )) ) {
2415 return NT_STATUS_NO_MEMORY;
2418 become_root();
2419 ret = pdb_getsampwsid(sampass, user_sid);
2420 unbecome_root();
2422 if (ret == False) {
2423 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2424 TALLOC_FREE(sampass);
2425 return NT_STATUS_NO_SUCH_USER;
2428 munged_dial = pdb_get_munged_dial(sampass);
2430 samr_clear_sam_passwd(sampass);
2432 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2433 munged_dial, (int)strlen(munged_dial)));
2435 if (munged_dial) {
2436 blob = base64_decode_data_blob(munged_dial);
2437 } else {
2438 blob = data_blob_string_const("");
2441 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2442 data_blob_free(&blob);
2443 TALLOC_FREE(sampass);
2444 if (!NT_STATUS_IS_OK(status)) {
2445 return status;
2448 init_samr_user_info20(r, parameters);
2450 return NT_STATUS_OK;
2454 /*************************************************************************
2455 get_user_info_21
2456 *************************************************************************/
2458 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2459 struct samr_UserInfo21 *r,
2460 DOM_SID *user_sid,
2461 DOM_SID *domain_sid)
2463 NTSTATUS status;
2464 struct samu *pw = NULL;
2465 bool ret;
2466 const DOM_SID *sid_user, *sid_group;
2467 uint32_t rid, primary_gid;
2468 NTTIME last_logon, last_logoff, last_password_change,
2469 acct_expiry, allow_password_change, force_password_change;
2470 time_t must_change_time;
2471 uint8_t password_expired;
2472 const char *account_name, *full_name, *home_directory, *home_drive,
2473 *logon_script, *profile_path, *description,
2474 *workstations, *comment;
2475 struct samr_LogonHours logon_hours;
2476 struct lsa_BinaryString *parameters = NULL;
2477 const char *munged_dial = NULL;
2478 DATA_BLOB blob;
2480 ZERO_STRUCTP(r);
2482 if (!(pw = samu_new(mem_ctx))) {
2483 return NT_STATUS_NO_MEMORY;
2486 become_root();
2487 ret = pdb_getsampwsid(pw, user_sid);
2488 unbecome_root();
2490 if (ret == False) {
2491 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2492 TALLOC_FREE(pw);
2493 return NT_STATUS_NO_SUCH_USER;
2496 samr_clear_sam_passwd(pw);
2498 DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2500 sid_user = pdb_get_user_sid(pw);
2502 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2503 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2504 "the domain sid %s. Failing operation.\n",
2505 pdb_get_username(pw), sid_string_dbg(sid_user),
2506 sid_string_dbg(domain_sid)));
2507 TALLOC_FREE(pw);
2508 return NT_STATUS_UNSUCCESSFUL;
2511 become_root();
2512 sid_group = pdb_get_group_sid(pw);
2513 unbecome_root();
2515 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2516 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2517 "which conflicts with the domain sid %s. Failing operation.\n",
2518 pdb_get_username(pw), sid_string_dbg(sid_group),
2519 sid_string_dbg(domain_sid)));
2520 TALLOC_FREE(pw);
2521 return NT_STATUS_UNSUCCESSFUL;
2524 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2525 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2526 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2527 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2528 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2530 must_change_time = pdb_get_pass_must_change_time(pw);
2531 if (must_change_time == get_time_t_max()) {
2532 unix_to_nt_time_abs(&force_password_change, must_change_time);
2533 } else {
2534 unix_to_nt_time(&force_password_change, must_change_time);
2537 if (pdb_get_pass_must_change_time(pw) == 0) {
2538 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2539 } else {
2540 password_expired = 0;
2543 munged_dial = pdb_get_munged_dial(pw);
2544 if (munged_dial) {
2545 blob = base64_decode_data_blob(munged_dial);
2546 } else {
2547 blob = data_blob_string_const("");
2550 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2551 data_blob_free(&blob);
2552 if (!NT_STATUS_IS_OK(status)) {
2553 TALLOC_FREE(pw);
2554 return status;
2557 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2558 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2559 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2560 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2561 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2562 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2563 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2564 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2565 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2567 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2568 #if 0
2571 Look at a user on a real NT4 PDC with usrmgr, press
2572 'ok'. Then you will see that fields_present is set to
2573 0x08f827fa. Look at the user immediately after that again,
2574 and you will see that 0x00fffff is returned. This solves
2575 the problem that you get access denied after having looked
2576 at the user.
2577 -- Volker
2580 #endif
2582 init_samr_user_info21(r,
2583 last_logon,
2584 last_logoff,
2585 last_password_change,
2586 acct_expiry,
2587 allow_password_change,
2588 force_password_change,
2589 account_name,
2590 full_name,
2591 home_directory,
2592 home_drive,
2593 logon_script,
2594 profile_path,
2595 description,
2596 workstations,
2597 comment,
2598 parameters,
2599 rid,
2600 primary_gid,
2601 pdb_get_acct_ctrl(pw),
2602 pdb_build_fields_present(pw),
2603 logon_hours,
2604 pdb_get_bad_password_count(pw),
2605 pdb_get_logon_count(pw),
2606 0, /* country_code */
2607 0, /* code_page */
2608 0, /* nt_password_set */
2609 0, /* lm_password_set */
2610 password_expired);
2611 TALLOC_FREE(pw);
2613 return NT_STATUS_OK;
2616 /*******************************************************************
2617 _samr_QueryUserInfo
2618 ********************************************************************/
2620 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2621 struct samr_QueryUserInfo *r)
2623 NTSTATUS status;
2624 union samr_UserInfo *user_info = NULL;
2625 struct samr_info *info = NULL;
2626 DOM_SID domain_sid;
2627 uint32 rid;
2629 /* search for the handle */
2630 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2631 return NT_STATUS_INVALID_HANDLE;
2633 domain_sid = info->sid;
2635 sid_split_rid(&domain_sid, &rid);
2637 if (!sid_check_is_in_our_domain(&info->sid))
2638 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2640 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2641 sid_string_dbg(&info->sid)));
2643 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2644 if (!user_info) {
2645 return NT_STATUS_NO_MEMORY;
2648 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2650 switch (r->in.level) {
2651 case 7:
2652 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2653 if (!NT_STATUS_IS_OK(status)) {
2654 return status;
2656 break;
2657 case 9:
2658 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2659 if (!NT_STATUS_IS_OK(status)) {
2660 return status;
2662 break;
2663 case 16:
2664 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2665 if (!NT_STATUS_IS_OK(status)) {
2666 return status;
2668 break;
2670 case 18:
2671 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2672 if (!NT_STATUS_IS_OK(status)) {
2673 return status;
2675 break;
2677 case 20:
2678 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2679 if (!NT_STATUS_IS_OK(status)) {
2680 return status;
2682 break;
2684 case 21:
2685 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2686 &info->sid, &domain_sid);
2687 if (!NT_STATUS_IS_OK(status)) {
2688 return status;
2690 break;
2692 default:
2693 return NT_STATUS_INVALID_INFO_CLASS;
2696 *r->out.info = user_info;
2698 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2700 return status;
2703 /*******************************************************************
2704 _samr_GetGroupsForUser
2705 ********************************************************************/
2707 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2708 struct samr_GetGroupsForUser *r)
2710 struct samu *sam_pass=NULL;
2711 DOM_SID sid;
2712 DOM_SID *sids;
2713 struct samr_RidWithAttribute dom_gid;
2714 struct samr_RidWithAttribute *gids = NULL;
2715 uint32 primary_group_rid;
2716 size_t num_groups = 0;
2717 gid_t *unix_gids;
2718 size_t i, num_gids;
2719 uint32 acc_granted;
2720 bool ret;
2721 NTSTATUS result;
2722 bool success = False;
2724 struct samr_RidWithAttributeArray *rids = NULL;
2727 * from the SID in the request:
2728 * we should send back the list of DOMAIN GROUPS
2729 * the user is a member of
2731 * and only the DOMAIN GROUPS
2732 * no ALIASES !!! neither aliases of the domain
2733 * nor aliases of the builtin SID
2735 * JFM, 12/2/2001
2738 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2740 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2741 if (!rids) {
2742 return NT_STATUS_NO_MEMORY;
2745 /* find the policy handle. open a policy on it. */
2746 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2747 return NT_STATUS_INVALID_HANDLE;
2749 result = access_check_samr_function(acc_granted,
2750 SA_RIGHT_USER_GET_GROUPS,
2751 "_samr_GetGroupsForUser");
2752 if (!NT_STATUS_IS_OK(result)) {
2753 return result;
2756 if (!sid_check_is_in_our_domain(&sid))
2757 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2759 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2760 return NT_STATUS_NO_MEMORY;
2763 become_root();
2764 ret = pdb_getsampwsid(sam_pass, &sid);
2765 unbecome_root();
2767 if (!ret) {
2768 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2769 sid_string_dbg(&sid)));
2770 return NT_STATUS_NO_SUCH_USER;
2773 sids = NULL;
2775 /* make both calls inside the root block */
2776 become_root();
2777 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2778 &sids, &unix_gids, &num_groups);
2779 if ( NT_STATUS_IS_OK(result) ) {
2780 success = sid_peek_check_rid(get_global_sam_sid(),
2781 pdb_get_group_sid(sam_pass),
2782 &primary_group_rid);
2784 unbecome_root();
2786 if (!NT_STATUS_IS_OK(result)) {
2787 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2788 sid_string_dbg(&sid)));
2789 return result;
2792 if ( !success ) {
2793 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2794 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2795 pdb_get_username(sam_pass)));
2796 TALLOC_FREE(sam_pass);
2797 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2800 gids = NULL;
2801 num_gids = 0;
2803 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2804 SE_GROUP_ENABLED);
2805 dom_gid.rid = primary_group_rid;
2806 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2808 for (i=0; i<num_groups; i++) {
2810 if (!sid_peek_check_rid(get_global_sam_sid(),
2811 &(sids[i]), &dom_gid.rid)) {
2812 DEBUG(10, ("Found sid %s not in our domain\n",
2813 sid_string_dbg(&sids[i])));
2814 continue;
2817 if (dom_gid.rid == primary_group_rid) {
2818 /* We added the primary group directly from the
2819 * sam_account. The other SIDs are unique from
2820 * enum_group_memberships */
2821 continue;
2824 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2827 rids->count = num_gids;
2828 rids->rids = gids;
2830 *r->out.rids = rids;
2832 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2834 return result;
2837 /*******************************************************************
2838 samr_QueryDomainInfo_internal
2839 ********************************************************************/
2841 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2842 pipes_struct *p,
2843 struct policy_handle *handle,
2844 uint32_t level,
2845 union samr_DomainInfo **dom_info_ptr)
2847 NTSTATUS status = NT_STATUS_OK;
2848 struct samr_info *info = NULL;
2849 union samr_DomainInfo *dom_info;
2850 uint32 min_pass_len,pass_hist,password_properties;
2851 time_t u_expire, u_min_age;
2852 NTTIME nt_expire, nt_min_age;
2854 time_t u_lock_duration, u_reset_time;
2855 NTTIME nt_lock_duration, nt_reset_time;
2856 uint32 lockout;
2857 time_t u_logout;
2858 NTTIME nt_logout;
2860 uint32 account_policy_temp;
2862 time_t seq_num;
2863 uint32 server_role;
2865 uint32 num_users=0, num_groups=0, num_aliases=0;
2867 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2869 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2870 if (!dom_info) {
2871 return NT_STATUS_NO_MEMORY;
2874 *dom_info_ptr = dom_info;
2876 /* find the policy handle. open a policy on it. */
2877 if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2878 return NT_STATUS_INVALID_HANDLE;
2881 switch (level) {
2882 case 0x01:
2884 become_root();
2886 /* AS ROOT !!! */
2888 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2889 min_pass_len = account_policy_temp;
2891 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2892 pass_hist = account_policy_temp;
2894 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2895 password_properties = account_policy_temp;
2897 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2898 u_expire = account_policy_temp;
2900 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2901 u_min_age = account_policy_temp;
2903 /* !AS ROOT */
2905 unbecome_root();
2907 unix_to_nt_time_abs(&nt_expire, u_expire);
2908 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2910 init_samr_DomInfo1(&dom_info->info1,
2911 (uint16)min_pass_len,
2912 (uint16)pass_hist,
2913 password_properties,
2914 nt_expire,
2915 nt_min_age);
2916 break;
2917 case 0x02:
2919 become_root();
2921 /* AS ROOT !!! */
2923 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2924 num_groups = count_sam_groups(info->disp_info);
2925 num_aliases = count_sam_aliases(info->disp_info);
2927 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2928 u_logout = account_policy_temp;
2930 unix_to_nt_time_abs(&nt_logout, u_logout);
2932 if (!pdb_get_seq_num(&seq_num))
2933 seq_num = time(NULL);
2935 /* !AS ROOT */
2937 unbecome_root();
2939 server_role = ROLE_DOMAIN_PDC;
2940 if (lp_server_role() == ROLE_DOMAIN_BDC)
2941 server_role = ROLE_DOMAIN_BDC;
2943 init_samr_DomInfo2(&dom_info->info2,
2944 nt_logout,
2945 lp_serverstring(),
2946 lp_workgroup(),
2947 global_myname(),
2948 seq_num,
2950 server_role,
2952 num_users,
2953 num_groups,
2954 num_aliases);
2955 break;
2956 case 0x03:
2958 become_root();
2960 /* AS ROOT !!! */
2963 uint32 ul;
2964 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2965 u_logout = (time_t)ul;
2968 /* !AS ROOT */
2970 unbecome_root();
2972 unix_to_nt_time_abs(&nt_logout, u_logout);
2974 init_samr_DomInfo3(&dom_info->info3,
2975 nt_logout);
2977 break;
2978 case 0x04:
2979 init_samr_DomInfo4(&dom_info->info4,
2980 lp_serverstring());
2981 break;
2982 case 0x05:
2983 init_samr_DomInfo5(&dom_info->info5,
2984 get_global_sam_name());
2985 break;
2986 case 0x06:
2987 /* NT returns its own name when a PDC. win2k and later
2988 * only the name of the PDC if itself is a BDC (samba4
2989 * idl) */
2990 init_samr_DomInfo6(&dom_info->info6,
2991 global_myname());
2992 break;
2993 case 0x07:
2994 server_role = ROLE_DOMAIN_PDC;
2995 if (lp_server_role() == ROLE_DOMAIN_BDC)
2996 server_role = ROLE_DOMAIN_BDC;
2998 init_samr_DomInfo7(&dom_info->info7,
2999 server_role);
3000 break;
3001 case 0x08:
3003 become_root();
3005 /* AS ROOT !!! */
3007 if (!pdb_get_seq_num(&seq_num)) {
3008 seq_num = time(NULL);
3011 /* !AS ROOT */
3013 unbecome_root();
3015 init_samr_DomInfo8(&dom_info->info8,
3016 seq_num,
3018 break;
3019 case 0x0c:
3021 become_root();
3023 /* AS ROOT !!! */
3025 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3026 u_lock_duration = account_policy_temp;
3027 if (u_lock_duration != -1) {
3028 u_lock_duration *= 60;
3031 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3032 u_reset_time = account_policy_temp * 60;
3034 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3035 lockout = account_policy_temp;
3037 /* !AS ROOT */
3039 unbecome_root();
3041 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3042 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3044 init_samr_DomInfo12(&dom_info->info12,
3045 nt_lock_duration,
3046 nt_reset_time,
3047 (uint16)lockout);
3048 break;
3049 default:
3050 return NT_STATUS_INVALID_INFO_CLASS;
3053 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
3055 return status;
3058 /*******************************************************************
3059 _samr_QueryDomainInfo
3060 ********************************************************************/
3062 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3063 struct samr_QueryDomainInfo *r)
3065 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
3067 r->in.domain_handle,
3068 r->in.level,
3069 r->out.info);
3072 /* W2k3 seems to use the same check for all 3 objects that can be created via
3073 * SAMR, if you try to create for example "Dialup" as an alias it says
3074 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3075 * database. */
3077 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3079 enum lsa_SidType type;
3080 bool result;
3082 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3084 become_root();
3085 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3086 * whether the name already exists */
3087 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3088 NULL, NULL, NULL, &type);
3089 unbecome_root();
3091 if (!result) {
3092 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3093 return NT_STATUS_OK;
3096 DEBUG(5, ("trying to create %s, exists as %s\n",
3097 new_name, sid_type_lookup(type)));
3099 if (type == SID_NAME_DOM_GRP) {
3100 return NT_STATUS_GROUP_EXISTS;
3102 if (type == SID_NAME_ALIAS) {
3103 return NT_STATUS_ALIAS_EXISTS;
3106 /* Yes, the default is NT_STATUS_USER_EXISTS */
3107 return NT_STATUS_USER_EXISTS;
3110 /*******************************************************************
3111 _samr_CreateUser2
3112 ********************************************************************/
3114 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3115 struct samr_CreateUser2 *r)
3117 const char *account = NULL;
3118 DOM_SID sid;
3119 POLICY_HND dom_pol = *r->in.domain_handle;
3120 uint32_t acb_info = r->in.acct_flags;
3121 POLICY_HND *user_pol = r->out.user_handle;
3122 struct samr_info *info = NULL;
3123 NTSTATUS nt_status;
3124 uint32 acc_granted;
3125 SEC_DESC *psd;
3126 size_t sd_size;
3127 /* check this, when giving away 'add computer to domain' privs */
3128 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3129 bool can_add_account = False;
3130 SE_PRIV se_rights;
3131 DISP_INFO *disp_info = NULL;
3133 /* Get the domain SID stored in the domain policy */
3134 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3135 &disp_info))
3136 return NT_STATUS_INVALID_HANDLE;
3138 nt_status = access_check_samr_function(acc_granted,
3139 SA_RIGHT_DOMAIN_CREATE_USER,
3140 "_samr_CreateUser2");
3141 if (!NT_STATUS_IS_OK(nt_status)) {
3142 return nt_status;
3145 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3146 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3147 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3148 this parameter is not an account type */
3149 return NT_STATUS_INVALID_PARAMETER;
3152 account = r->in.account_name->string;
3153 if (account == NULL) {
3154 return NT_STATUS_NO_MEMORY;
3157 nt_status = can_create(p->mem_ctx, account);
3158 if (!NT_STATUS_IS_OK(nt_status)) {
3159 return nt_status;
3162 /* determine which user right we need to check based on the acb_info */
3164 if ( acb_info & ACB_WSTRUST )
3166 se_priv_copy( &se_rights, &se_machine_account );
3167 can_add_account = user_has_privileges(
3168 p->pipe_user.nt_user_token, &se_rights );
3170 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3171 account for domain trusts and changes the ACB flags later */
3172 else if ( acb_info & ACB_NORMAL &&
3173 (account[strlen(account)-1] != '$') )
3175 se_priv_copy( &se_rights, &se_add_users );
3176 can_add_account = user_has_privileges(
3177 p->pipe_user.nt_user_token, &se_rights );
3179 else /* implicit assumption of a BDC or domain trust account here
3180 * (we already check the flags earlier) */
3182 if ( lp_enable_privileges() ) {
3183 /* only Domain Admins can add a BDC or domain trust */
3184 se_priv_copy( &se_rights, &se_priv_none );
3185 can_add_account = nt_token_check_domain_rid(
3186 p->pipe_user.nt_user_token,
3187 DOMAIN_GROUP_RID_ADMINS );
3191 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3192 uidtoname(p->pipe_user.ut.uid),
3193 can_add_account ? "True":"False" ));
3195 /********** BEGIN Admin BLOCK **********/
3197 if ( can_add_account )
3198 become_root();
3200 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3201 r->out.rid);
3203 if ( can_add_account )
3204 unbecome_root();
3206 /********** END Admin BLOCK **********/
3208 /* now check for failure */
3210 if ( !NT_STATUS_IS_OK(nt_status) )
3211 return nt_status;
3213 /* Get the user's SID */
3215 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3217 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3218 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3219 se_map_generic(&des_access, &usr_generic_mapping);
3221 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3222 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3223 &acc_granted, "_samr_CreateUser2");
3225 if ( !NT_STATUS_IS_OK(nt_status) ) {
3226 return nt_status;
3229 /* associate the user's SID with the new handle. */
3230 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3231 return NT_STATUS_NO_MEMORY;
3234 ZERO_STRUCTP(info);
3235 info->sid = sid;
3236 info->acc_granted = acc_granted;
3238 /* get a (unique) handle. open a policy on it. */
3239 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3240 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3243 /* After a "set" ensure we have no cached display info. */
3244 force_flush_samr_cache(info->disp_info);
3246 *r->out.access_granted = acc_granted;
3248 return NT_STATUS_OK;
3251 /*******************************************************************
3252 _samr_Connect
3253 ********************************************************************/
3255 NTSTATUS _samr_Connect(pipes_struct *p,
3256 struct samr_Connect *r)
3258 struct samr_info *info = NULL;
3259 uint32 des_access = r->in.access_mask;
3261 /* Access check */
3263 if (!pipe_access_check(p)) {
3264 DEBUG(3, ("access denied to _samr_Connect\n"));
3265 return NT_STATUS_ACCESS_DENIED;
3268 /* set up the SAMR connect_anon response */
3270 /* associate the user's SID with the new handle. */
3271 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3272 return NT_STATUS_NO_MEMORY;
3274 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3275 was observed from a win98 client trying to enumerate users (when configured
3276 user level access control on shares) --jerry */
3278 if (des_access == MAXIMUM_ALLOWED_ACCESS) {
3279 /* Map to max possible knowing we're filtered below. */
3280 des_access = GENERIC_ALL_ACCESS;
3283 se_map_generic( &des_access, &sam_generic_mapping );
3284 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3286 /* get a (unique) handle. open a policy on it. */
3287 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3288 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3290 return NT_STATUS_OK;
3293 /*******************************************************************
3294 _samr_Connect2
3295 ********************************************************************/
3297 NTSTATUS _samr_Connect2(pipes_struct *p,
3298 struct samr_Connect2 *r)
3300 struct samr_info *info = NULL;
3301 SEC_DESC *psd = NULL;
3302 uint32 acc_granted;
3303 uint32 des_access = r->in.access_mask;
3304 NTSTATUS nt_status;
3305 size_t sd_size;
3308 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3310 /* Access check */
3312 if (!pipe_access_check(p)) {
3313 DEBUG(3, ("access denied to _samr_Connect2\n"));
3314 return NT_STATUS_ACCESS_DENIED;
3317 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3318 se_map_generic(&des_access, &sam_generic_mapping);
3320 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3321 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3323 if ( !NT_STATUS_IS_OK(nt_status) )
3324 return nt_status;
3326 /* associate the user's SID and access granted with the new handle. */
3327 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3328 return NT_STATUS_NO_MEMORY;
3330 info->acc_granted = acc_granted;
3331 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3333 /* get a (unique) handle. open a policy on it. */
3334 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3335 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3337 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3339 return nt_status;
3342 /*******************************************************************
3343 _samr_Connect4
3344 ********************************************************************/
3346 NTSTATUS _samr_Connect4(pipes_struct *p,
3347 struct samr_Connect4 *r)
3349 struct samr_info *info = NULL;
3350 SEC_DESC *psd = NULL;
3351 uint32 acc_granted;
3352 uint32 des_access = r->in.access_mask;
3353 NTSTATUS nt_status;
3354 size_t sd_size;
3357 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3359 /* Access check */
3361 if (!pipe_access_check(p)) {
3362 DEBUG(3, ("access denied to samr_Connect4\n"));
3363 return NT_STATUS_ACCESS_DENIED;
3366 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3367 se_map_generic(&des_access, &sam_generic_mapping);
3369 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3370 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3372 if ( !NT_STATUS_IS_OK(nt_status) )
3373 return nt_status;
3375 /* associate the user's SID and access granted with the new handle. */
3376 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3377 return NT_STATUS_NO_MEMORY;
3379 info->acc_granted = acc_granted;
3380 info->status = r->in.access_mask; /* ??? */
3382 /* get a (unique) handle. open a policy on it. */
3383 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3384 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3386 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3388 return NT_STATUS_OK;
3391 /*******************************************************************
3392 _samr_Connect5
3393 ********************************************************************/
3395 NTSTATUS _samr_Connect5(pipes_struct *p,
3396 struct samr_Connect5 *r)
3398 struct samr_info *info = NULL;
3399 SEC_DESC *psd = NULL;
3400 uint32 acc_granted;
3401 uint32 des_access = r->in.access_mask;
3402 NTSTATUS nt_status;
3403 size_t sd_size;
3404 struct samr_ConnectInfo1 info1;
3406 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3408 /* Access check */
3410 if (!pipe_access_check(p)) {
3411 DEBUG(3, ("access denied to samr_Connect5\n"));
3412 return NT_STATUS_ACCESS_DENIED;
3415 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3416 se_map_generic(&des_access, &sam_generic_mapping);
3418 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3419 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3421 if ( !NT_STATUS_IS_OK(nt_status) )
3422 return nt_status;
3424 /* associate the user's SID and access granted with the new handle. */
3425 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3426 return NT_STATUS_NO_MEMORY;
3428 info->acc_granted = acc_granted;
3429 info->status = r->in.access_mask; /* ??? */
3431 /* get a (unique) handle. open a policy on it. */
3432 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3433 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3435 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3437 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3438 info1.unknown2 = 0;
3440 *r->out.level_out = 1;
3441 r->out.info_out->info1 = info1;
3443 return NT_STATUS_OK;
3446 /**********************************************************************
3447 _samr_LookupDomain
3448 **********************************************************************/
3450 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3451 struct samr_LookupDomain *r)
3453 NTSTATUS status = NT_STATUS_OK;
3454 struct samr_info *info;
3455 const char *domain_name;
3456 DOM_SID *sid = NULL;
3458 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3459 return NT_STATUS_INVALID_HANDLE;
3461 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3462 Reverted that change so we will work with RAS servers again */
3464 status = access_check_samr_function(info->acc_granted,
3465 SA_RIGHT_SAM_OPEN_DOMAIN,
3466 "_samr_LookupDomain");
3467 if (!NT_STATUS_IS_OK(status)) {
3468 return status;
3471 domain_name = r->in.domain_name->string;
3473 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3474 if (!sid) {
3475 return NT_STATUS_NO_MEMORY;
3478 if (strequal(domain_name, builtin_domain_name())) {
3479 sid_copy(sid, &global_sid_Builtin);
3480 } else {
3481 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3482 status = NT_STATUS_NO_SUCH_DOMAIN;
3486 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3487 sid_string_dbg(sid)));
3489 *r->out.sid = sid;
3491 return status;
3494 /**********************************************************************
3495 _samr_EnumDomains
3496 **********************************************************************/
3498 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3499 struct samr_EnumDomains *r)
3501 NTSTATUS status;
3502 struct samr_info *info;
3503 uint32_t num_entries = 2;
3504 struct samr_SamEntry *entry_array = NULL;
3505 struct samr_SamArray *sam;
3507 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3508 return NT_STATUS_INVALID_HANDLE;
3510 status = access_check_samr_function(info->acc_granted,
3511 SA_RIGHT_SAM_ENUM_DOMAINS,
3512 "_samr_EnumDomains");
3513 if (!NT_STATUS_IS_OK(status)) {
3514 return status;
3517 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3518 if (!sam) {
3519 return NT_STATUS_NO_MEMORY;
3522 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3523 struct samr_SamEntry,
3524 num_entries);
3525 if (!entry_array) {
3526 return NT_STATUS_NO_MEMORY;
3529 entry_array[0].idx = 0;
3530 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3532 entry_array[1].idx = 1;
3533 init_lsa_String(&entry_array[1].name, "Builtin");
3535 sam->count = num_entries;
3536 sam->entries = entry_array;
3538 *r->out.sam = sam;
3539 *r->out.num_entries = num_entries;
3541 return status;
3544 /*******************************************************************
3545 _samr_OpenAlias
3546 ********************************************************************/
3548 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3549 struct samr_OpenAlias *r)
3551 DOM_SID sid;
3552 POLICY_HND domain_pol = *r->in.domain_handle;
3553 uint32 alias_rid = r->in.rid;
3554 POLICY_HND *alias_pol = r->out.alias_handle;
3555 struct samr_info *info = NULL;
3556 SEC_DESC *psd = NULL;
3557 uint32 acc_granted;
3558 uint32 des_access = r->in.access_mask;
3559 size_t sd_size;
3560 NTSTATUS status;
3561 SE_PRIV se_rights;
3563 /* find the domain policy and get the SID / access bits stored in the domain policy */
3565 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3566 return NT_STATUS_INVALID_HANDLE;
3568 status = access_check_samr_function(acc_granted,
3569 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3570 "_samr_OpenAlias");
3572 if ( !NT_STATUS_IS_OK(status) )
3573 return status;
3575 /* append the alias' RID to it */
3577 if (!sid_append_rid(&sid, alias_rid))
3578 return NT_STATUS_NO_SUCH_ALIAS;
3580 /*check if access can be granted as requested by client. */
3582 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3583 se_map_generic(&des_access,&ali_generic_mapping);
3585 se_priv_copy( &se_rights, &se_add_users );
3588 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3589 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3590 &acc_granted, "_samr_OpenAlias");
3592 if ( !NT_STATUS_IS_OK(status) )
3593 return status;
3596 /* Check we actually have the requested alias */
3597 enum lsa_SidType type;
3598 bool result;
3599 gid_t gid;
3601 become_root();
3602 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3603 unbecome_root();
3605 if (!result || (type != SID_NAME_ALIAS)) {
3606 return NT_STATUS_NO_SUCH_ALIAS;
3609 /* make sure there is a mapping */
3611 if ( !sid_to_gid( &sid, &gid ) ) {
3612 return NT_STATUS_NO_SUCH_ALIAS;
3617 /* associate the alias SID with the new handle. */
3618 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3619 return NT_STATUS_NO_MEMORY;
3621 info->acc_granted = acc_granted;
3623 /* get a (unique) handle. open a policy on it. */
3624 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3625 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3627 return NT_STATUS_OK;
3630 /*******************************************************************
3631 set_user_info_7
3632 ********************************************************************/
3634 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3635 struct samr_UserInfo7 *id7,
3636 struct samu *pwd)
3638 NTSTATUS rc;
3640 if (id7 == NULL) {
3641 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3642 TALLOC_FREE(pwd);
3643 return NT_STATUS_ACCESS_DENIED;
3646 if (!id7->account_name.string) {
3647 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3648 TALLOC_FREE(pwd);
3649 return NT_STATUS_ACCESS_DENIED;
3652 /* check to see if the new username already exists. Note: we can't
3653 reliably lock all backends, so there is potentially the
3654 possibility that a user can be created in between this check and
3655 the rename. The rename should fail, but may not get the
3656 exact same failure status code. I think this is small enough
3657 of a window for this type of operation and the results are
3658 simply that the rename fails with a slightly different status
3659 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3661 rc = can_create(mem_ctx, id7->account_name.string);
3662 if (!NT_STATUS_IS_OK(rc)) {
3663 return rc;
3666 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3668 TALLOC_FREE(pwd);
3669 return rc;
3672 /*******************************************************************
3673 set_user_info_16
3674 ********************************************************************/
3676 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3677 struct samu *pwd)
3679 if (id16 == NULL) {
3680 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3681 TALLOC_FREE(pwd);
3682 return False;
3685 /* FIX ME: check if the value is really changed --metze */
3686 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3687 TALLOC_FREE(pwd);
3688 return False;
3691 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3692 TALLOC_FREE(pwd);
3693 return False;
3696 TALLOC_FREE(pwd);
3698 return True;
3701 /*******************************************************************
3702 set_user_info_18
3703 ********************************************************************/
3705 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3706 struct samu *pwd)
3708 if (id18 == NULL) {
3709 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3710 TALLOC_FREE(pwd);
3711 return False;
3714 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3715 TALLOC_FREE(pwd);
3716 return False;
3718 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3719 TALLOC_FREE(pwd);
3720 return False;
3722 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3723 TALLOC_FREE(pwd);
3724 return False;
3727 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3728 TALLOC_FREE(pwd);
3729 return False;
3732 TALLOC_FREE(pwd);
3733 return True;
3736 /*******************************************************************
3737 set_user_info_20
3738 ********************************************************************/
3740 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3741 struct samu *pwd)
3743 if (id20 == NULL) {
3744 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3745 return False;
3748 copy_id20_to_sam_passwd(pwd, id20);
3750 /* write the change out */
3751 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3752 TALLOC_FREE(pwd);
3753 return False;
3756 TALLOC_FREE(pwd);
3758 return True;
3761 /*******************************************************************
3762 set_user_info_21
3763 ********************************************************************/
3765 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3766 struct samr_UserInfo21 *id21,
3767 struct samu *pwd)
3769 NTSTATUS status;
3771 if (id21 == NULL) {
3772 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3773 return NT_STATUS_INVALID_PARAMETER;
3776 /* we need to separately check for an account rename first */
3778 if (id21->account_name.string &&
3779 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3782 /* check to see if the new username already exists. Note: we can't
3783 reliably lock all backends, so there is potentially the
3784 possibility that a user can be created in between this check and
3785 the rename. The rename should fail, but may not get the
3786 exact same failure status code. I think this is small enough
3787 of a window for this type of operation and the results are
3788 simply that the rename fails with a slightly different status
3789 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3791 status = can_create(mem_ctx, id21->account_name.string);
3792 if (!NT_STATUS_IS_OK(status)) {
3793 return status;
3796 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3798 if (!NT_STATUS_IS_OK(status)) {
3799 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3800 nt_errstr(status)));
3801 TALLOC_FREE(pwd);
3802 return status;
3805 /* set the new username so that later
3806 functions can work on the new account */
3807 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3810 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3813 * The funny part about the previous two calls is
3814 * that pwd still has the password hashes from the
3815 * passdb entry. These have not been updated from
3816 * id21. I don't know if they need to be set. --jerry
3819 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3820 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3821 if ( !NT_STATUS_IS_OK(status) ) {
3822 return status;
3826 /* Don't worry about writing out the user account since the
3827 primary group SID is generated solely from the user's Unix
3828 primary group. */
3830 /* write the change out */
3831 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3832 TALLOC_FREE(pwd);
3833 return status;
3836 TALLOC_FREE(pwd);
3838 return NT_STATUS_OK;
3841 /*******************************************************************
3842 set_user_info_23
3843 ********************************************************************/
3845 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3846 struct samr_UserInfo23 *id23,
3847 struct samu *pwd)
3849 char *plaintext_buf = NULL;
3850 uint32 len = 0;
3851 uint16 acct_ctrl;
3852 NTSTATUS status;
3854 if (id23 == NULL) {
3855 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3856 return NT_STATUS_INVALID_PARAMETER;
3859 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3860 pdb_get_username(pwd)));
3862 acct_ctrl = pdb_get_acct_ctrl(pwd);
3864 if (!decode_pw_buffer(mem_ctx,
3865 id23->password.data,
3866 &plaintext_buf,
3867 &len,
3868 STR_UNICODE)) {
3869 TALLOC_FREE(pwd);
3870 return NT_STATUS_INVALID_PARAMETER;
3873 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3874 TALLOC_FREE(pwd);
3875 return NT_STATUS_ACCESS_DENIED;
3878 copy_id23_to_sam_passwd(pwd, id23);
3880 /* if it's a trust account, don't update /etc/passwd */
3881 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3882 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3883 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3884 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3885 } else {
3886 /* update the UNIX password */
3887 if (lp_unix_password_sync() ) {
3888 struct passwd *passwd;
3889 if (pdb_get_username(pwd) == NULL) {
3890 DEBUG(1, ("chgpasswd: User without name???\n"));
3891 TALLOC_FREE(pwd);
3892 return NT_STATUS_ACCESS_DENIED;
3895 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3896 if (passwd == NULL) {
3897 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3900 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3901 TALLOC_FREE(pwd);
3902 return NT_STATUS_ACCESS_DENIED;
3904 TALLOC_FREE(passwd);
3908 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3910 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3911 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3912 pwd)))) {
3913 TALLOC_FREE(pwd);
3914 return status;
3917 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3918 TALLOC_FREE(pwd);
3919 return status;
3922 TALLOC_FREE(pwd);
3924 return NT_STATUS_OK;
3927 /*******************************************************************
3928 set_user_info_pw
3929 ********************************************************************/
3931 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
3932 int level)
3934 uint32 len = 0;
3935 char *plaintext_buf = NULL;
3936 uint32 acct_ctrl;
3937 time_t last_set_time;
3938 enum pdb_value_state last_set_state;
3940 DEBUG(5, ("Attempting administrator password change for user %s\n",
3941 pdb_get_username(pwd)));
3943 acct_ctrl = pdb_get_acct_ctrl(pwd);
3944 /* we need to know if it's expired, because this is an admin change, not a
3945 user change, so it's still expired when we're done */
3946 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3947 last_set_time = pdb_get_pass_last_set_time(pwd);
3949 if (!decode_pw_buffer(talloc_tos(),
3950 pass,
3951 &plaintext_buf,
3952 &len,
3953 STR_UNICODE)) {
3954 TALLOC_FREE(pwd);
3955 return False;
3958 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3959 TALLOC_FREE(pwd);
3960 return False;
3963 /* if it's a trust account, don't update /etc/passwd */
3964 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3965 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3966 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3967 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3968 } else {
3969 /* update the UNIX password */
3970 if (lp_unix_password_sync()) {
3971 struct passwd *passwd;
3973 if (pdb_get_username(pwd) == NULL) {
3974 DEBUG(1, ("chgpasswd: User without name???\n"));
3975 TALLOC_FREE(pwd);
3976 return False;
3979 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3980 if (passwd == NULL) {
3981 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3984 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3985 TALLOC_FREE(pwd);
3986 return False;
3988 TALLOC_FREE(passwd);
3992 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3995 * A level 25 change does reset the pwdlastset field, a level 24
3996 * change does not. I know this is probably not the full story, but
3997 * it is needed to make XP join LDAP correctly, without it the later
3998 * auth2 check can fail with PWD_MUST_CHANGE.
4000 if (level != 25) {
4002 * restore last set time as this is an admin change, not a
4003 * user pw change
4005 pdb_set_pass_last_set_time (pwd, last_set_time,
4006 last_set_state);
4009 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4011 /* update the SAMBA password */
4012 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4013 TALLOC_FREE(pwd);
4014 return False;
4017 TALLOC_FREE(pwd);
4019 return True;
4022 /*******************************************************************
4023 set_user_info_25
4024 ********************************************************************/
4026 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4027 struct samr_UserInfo25 *id25,
4028 struct samu *pwd)
4030 NTSTATUS status;
4032 if (id25 == NULL) {
4033 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4034 return NT_STATUS_INVALID_PARAMETER;
4037 copy_id25_to_sam_passwd(pwd, id25);
4039 /* write the change out */
4040 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4041 TALLOC_FREE(pwd);
4042 return status;
4046 * We need to "pdb_update_sam_account" before the unix primary group
4047 * is set, because the idealx scripts would also change the
4048 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4049 * the delete explicit / add explicit, which would then fail to find
4050 * the previous primaryGroupSid value.
4053 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4054 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4055 if ( !NT_STATUS_IS_OK(status) ) {
4056 return status;
4060 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
4061 * hereafter! */
4063 return NT_STATUS_OK;
4066 /*******************************************************************
4067 samr_SetUserInfo_internal
4068 ********************************************************************/
4070 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
4071 pipes_struct *p,
4072 struct policy_handle *user_handle,
4073 uint16_t level,
4074 union samr_UserInfo *info)
4076 NTSTATUS status;
4077 struct samu *pwd = NULL;
4078 DOM_SID sid;
4079 POLICY_HND *pol = user_handle;
4080 uint16_t switch_value = level;
4081 uint32_t acc_granted;
4082 uint32_t acc_required;
4083 bool ret;
4084 bool has_enough_rights = False;
4085 uint32_t acb_info;
4086 DISP_INFO *disp_info = NULL;
4088 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4090 /* find the policy handle. open a policy on it. */
4091 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4092 return NT_STATUS_INVALID_HANDLE;
4095 /* This is tricky. A WinXP domain join sets
4096 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4097 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4098 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4099 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4100 we'll use the set from the WinXP join as the basis. */
4102 switch (switch_value) {
4103 case 18:
4104 case 24:
4105 case 25:
4106 case 26:
4107 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4108 break;
4109 default:
4110 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4111 SA_RIGHT_USER_SET_ATTRIBUTES |
4112 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4113 break;
4116 status = access_check_samr_function(acc_granted,
4117 acc_required,
4118 fn_name);
4119 if (!NT_STATUS_IS_OK(status)) {
4120 return status;
4123 DEBUG(5, ("%s: sid:%s, level:%d\n",
4124 fn_name, sid_string_dbg(&sid), switch_value));
4126 if (info == NULL) {
4127 DEBUG(5, ("%s: NULL info level\n", fn_name));
4128 return NT_STATUS_INVALID_INFO_CLASS;
4131 if (!(pwd = samu_new(NULL))) {
4132 return NT_STATUS_NO_MEMORY;
4135 become_root();
4136 ret = pdb_getsampwsid(pwd, &sid);
4137 unbecome_root();
4139 if (!ret) {
4140 TALLOC_FREE(pwd);
4141 return NT_STATUS_NO_SUCH_USER;
4144 /* deal with machine password changes differently from userinfo changes */
4145 /* check to see if we have the sufficient rights */
4147 acb_info = pdb_get_acct_ctrl(pwd);
4148 if (acb_info & ACB_WSTRUST)
4149 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4150 &se_machine_account);
4151 else if (acb_info & ACB_NORMAL)
4152 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4153 &se_add_users);
4154 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4155 if (lp_enable_privileges()) {
4156 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4157 DOMAIN_GROUP_RID_ADMINS);
4161 DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4162 fn_name,
4163 uidtoname(p->pipe_user.ut.uid),
4164 has_enough_rights ? "" : " not"));
4166 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4168 if (has_enough_rights) {
4169 become_root();
4172 /* ok! user info levels (lots: see MSDEV help), off we go... */
4174 switch (switch_value) {
4176 case 7:
4177 status = set_user_info_7(p->mem_ctx,
4178 &info->info7, pwd);
4179 break;
4181 case 16:
4182 if (!set_user_info_16(&info->info16, pwd)) {
4183 status = NT_STATUS_ACCESS_DENIED;
4185 break;
4187 case 18:
4188 /* Used by AS/U JRA. */
4189 if (!set_user_info_18(&info->info18, pwd)) {
4190 status = NT_STATUS_ACCESS_DENIED;
4192 break;
4194 case 20:
4195 if (!set_user_info_20(&info->info20, pwd)) {
4196 status = NT_STATUS_ACCESS_DENIED;
4198 break;
4200 case 21:
4201 status = set_user_info_21(p->mem_ctx,
4202 &info->info21, pwd);
4203 break;
4205 case 23:
4206 if (!p->session_key.length) {
4207 status = NT_STATUS_NO_USER_SESSION_KEY;
4209 SamOEMhashBlob(info->info23.password.data, 516,
4210 &p->session_key);
4212 dump_data(100, info->info23.password.data, 516);
4214 status = set_user_info_23(p->mem_ctx,
4215 &info->info23, pwd);
4216 break;
4218 case 24:
4219 if (!p->session_key.length) {
4220 status = NT_STATUS_NO_USER_SESSION_KEY;
4222 SamOEMhashBlob(info->info24.password.data,
4223 516,
4224 &p->session_key);
4226 dump_data(100, info->info24.password.data, 516);
4228 if (!set_user_info_pw(info->info24.password.data, pwd,
4229 switch_value)) {
4230 status = NT_STATUS_ACCESS_DENIED;
4232 break;
4234 case 25:
4235 if (!p->session_key.length) {
4236 status = NT_STATUS_NO_USER_SESSION_KEY;
4238 encode_or_decode_arc4_passwd_buffer(info->info25.password.data,
4239 &p->session_key);
4241 dump_data(100, info->info25.password.data, 532);
4243 status = set_user_info_25(p->mem_ctx,
4244 &info->info25, pwd);
4245 if (!NT_STATUS_IS_OK(status)) {
4246 goto done;
4248 if (!set_user_info_pw(info->info25.password.data, pwd,
4249 switch_value)) {
4250 status = NT_STATUS_ACCESS_DENIED;
4252 break;
4254 case 26:
4255 if (!p->session_key.length) {
4256 status = NT_STATUS_NO_USER_SESSION_KEY;
4258 encode_or_decode_arc4_passwd_buffer(info->info26.password.data,
4259 &p->session_key);
4261 dump_data(100, info->info26.password.data, 516);
4263 if (!set_user_info_pw(info->info26.password.data, pwd,
4264 switch_value)) {
4265 status = NT_STATUS_ACCESS_DENIED;
4267 break;
4269 default:
4270 status = NT_STATUS_INVALID_INFO_CLASS;
4273 done:
4275 if (has_enough_rights) {
4276 unbecome_root();
4279 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4281 if (NT_STATUS_IS_OK(status)) {
4282 force_flush_samr_cache(disp_info);
4285 return status;
4288 /*******************************************************************
4289 _samr_SetUserInfo
4290 ********************************************************************/
4292 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4293 struct samr_SetUserInfo *r)
4295 return samr_SetUserInfo_internal("_samr_SetUserInfo",
4297 r->in.user_handle,
4298 r->in.level,
4299 r->in.info);
4302 /*******************************************************************
4303 _samr_SetUserInfo2
4304 ********************************************************************/
4306 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4307 struct samr_SetUserInfo2 *r)
4309 return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4311 r->in.user_handle,
4312 r->in.level,
4313 r->in.info);
4316 /*********************************************************************
4317 _samr_GetAliasMembership
4318 *********************************************************************/
4320 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4321 struct samr_GetAliasMembership *r)
4323 size_t num_alias_rids;
4324 uint32 *alias_rids;
4325 struct samr_info *info = NULL;
4326 size_t i;
4328 NTSTATUS ntstatus1;
4329 NTSTATUS ntstatus2;
4331 DOM_SID *members;
4333 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4335 /* find the policy handle. open a policy on it. */
4336 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4337 return NT_STATUS_INVALID_HANDLE;
4339 ntstatus1 = access_check_samr_function(info->acc_granted,
4340 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4341 "_samr_GetAliasMembership");
4342 ntstatus2 = access_check_samr_function(info->acc_granted,
4343 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4344 "_samr_GetAliasMembership");
4346 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4347 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4348 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4349 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4353 if (!sid_check_is_domain(&info->sid) &&
4354 !sid_check_is_builtin(&info->sid))
4355 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4357 if (r->in.sids->num_sids) {
4358 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4360 if (members == NULL)
4361 return NT_STATUS_NO_MEMORY;
4362 } else {
4363 members = NULL;
4366 for (i=0; i<r->in.sids->num_sids; i++)
4367 sid_copy(&members[i], r->in.sids->sids[i].sid);
4369 alias_rids = NULL;
4370 num_alias_rids = 0;
4372 become_root();
4373 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4374 r->in.sids->num_sids,
4375 &alias_rids, &num_alias_rids);
4376 unbecome_root();
4378 if (!NT_STATUS_IS_OK(ntstatus1)) {
4379 return ntstatus1;
4382 r->out.rids->count = num_alias_rids;
4383 r->out.rids->ids = alias_rids;
4385 return NT_STATUS_OK;
4388 /*********************************************************************
4389 _samr_GetMembersInAlias
4390 *********************************************************************/
4392 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4393 struct samr_GetMembersInAlias *r)
4395 NTSTATUS status;
4396 size_t i;
4397 size_t num_sids = 0;
4398 struct lsa_SidPtr *sids = NULL;
4399 DOM_SID *pdb_sids = NULL;
4401 DOM_SID alias_sid;
4403 uint32 acc_granted;
4405 /* find the policy handle. open a policy on it. */
4406 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4407 return NT_STATUS_INVALID_HANDLE;
4409 status = access_check_samr_function(acc_granted,
4410 SA_RIGHT_ALIAS_GET_MEMBERS,
4411 "_samr_GetMembersInAlias");
4412 if (!NT_STATUS_IS_OK(status)) {
4413 return status;
4416 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4418 become_root();
4419 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4420 unbecome_root();
4422 if (!NT_STATUS_IS_OK(status)) {
4423 return status;
4426 if (num_sids) {
4427 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4428 if (sids == NULL) {
4429 TALLOC_FREE(pdb_sids);
4430 return NT_STATUS_NO_MEMORY;
4434 for (i = 0; i < num_sids; i++) {
4435 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4436 if (!sids[i].sid) {
4437 TALLOC_FREE(pdb_sids);
4438 return NT_STATUS_NO_MEMORY;
4442 r->out.sids->num_sids = num_sids;
4443 r->out.sids->sids = sids;
4445 TALLOC_FREE(pdb_sids);
4447 return NT_STATUS_OK;
4450 /*********************************************************************
4451 _samr_QueryGroupMember
4452 *********************************************************************/
4454 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4455 struct samr_QueryGroupMember *r)
4457 DOM_SID group_sid;
4458 size_t i, num_members;
4460 uint32 *rid=NULL;
4461 uint32 *attr=NULL;
4463 uint32 acc_granted;
4465 NTSTATUS status;
4466 struct samr_RidTypeArray *rids = NULL;
4468 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4469 if (!rids) {
4470 return NT_STATUS_NO_MEMORY;
4473 /* find the policy handle. open a policy on it. */
4474 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4475 return NT_STATUS_INVALID_HANDLE;
4477 status = access_check_samr_function(acc_granted,
4478 SA_RIGHT_GROUP_GET_MEMBERS,
4479 "_samr_QueryGroupMember");
4480 if (!NT_STATUS_IS_OK(status)) {
4481 return status;
4484 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4486 if (!sid_check_is_in_our_domain(&group_sid)) {
4487 DEBUG(3, ("sid %s is not in our domain\n",
4488 sid_string_dbg(&group_sid)));
4489 return NT_STATUS_NO_SUCH_GROUP;
4492 DEBUG(10, ("lookup on Domain SID\n"));
4494 become_root();
4495 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4496 &rid, &num_members);
4497 unbecome_root();
4499 if (!NT_STATUS_IS_OK(status))
4500 return status;
4502 if (num_members) {
4503 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4504 if (attr == NULL) {
4505 return NT_STATUS_NO_MEMORY;
4507 } else {
4508 attr = NULL;
4511 for (i=0; i<num_members; i++)
4512 attr[i] = SID_NAME_USER;
4514 rids->count = num_members;
4515 rids->types = attr;
4516 rids->rids = rid;
4518 *r->out.rids = rids;
4520 return NT_STATUS_OK;
4523 /*********************************************************************
4524 _samr_AddAliasMember
4525 *********************************************************************/
4527 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4528 struct samr_AddAliasMember *r)
4530 DOM_SID alias_sid;
4531 uint32 acc_granted;
4532 SE_PRIV se_rights;
4533 bool can_add_accounts;
4534 NTSTATUS status;
4535 DISP_INFO *disp_info = NULL;
4537 /* Find the policy handle. Open a policy on it. */
4538 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4539 return NT_STATUS_INVALID_HANDLE;
4541 status = access_check_samr_function(acc_granted,
4542 SA_RIGHT_ALIAS_ADD_MEMBER,
4543 "_samr_AddAliasMember");
4544 if (!NT_STATUS_IS_OK(status)) {
4545 return status;
4548 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4550 se_priv_copy( &se_rights, &se_add_users );
4551 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4553 /******** BEGIN SeAddUsers BLOCK *********/
4555 if ( can_add_accounts )
4556 become_root();
4558 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4560 if ( can_add_accounts )
4561 unbecome_root();
4563 /******** END SeAddUsers BLOCK *********/
4565 if (NT_STATUS_IS_OK(status)) {
4566 force_flush_samr_cache(disp_info);
4569 return status;
4572 /*********************************************************************
4573 _samr_DeleteAliasMember
4574 *********************************************************************/
4576 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4577 struct samr_DeleteAliasMember *r)
4579 DOM_SID alias_sid;
4580 uint32 acc_granted;
4581 SE_PRIV se_rights;
4582 bool can_add_accounts;
4583 NTSTATUS status;
4584 DISP_INFO *disp_info = NULL;
4586 /* Find the policy handle. Open a policy on it. */
4587 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4588 return NT_STATUS_INVALID_HANDLE;
4590 status = access_check_samr_function(acc_granted,
4591 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4592 "_samr_DeleteAliasMember");
4593 if (!NT_STATUS_IS_OK(status)) {
4594 return status;
4597 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4598 sid_string_dbg(&alias_sid)));
4600 se_priv_copy( &se_rights, &se_add_users );
4601 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4603 /******** BEGIN SeAddUsers BLOCK *********/
4605 if ( can_add_accounts )
4606 become_root();
4608 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4610 if ( can_add_accounts )
4611 unbecome_root();
4613 /******** END SeAddUsers BLOCK *********/
4615 if (NT_STATUS_IS_OK(status)) {
4616 force_flush_samr_cache(disp_info);
4619 return status;
4622 /*********************************************************************
4623 _samr_AddGroupMember
4624 *********************************************************************/
4626 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4627 struct samr_AddGroupMember *r)
4629 NTSTATUS status;
4630 DOM_SID group_sid;
4631 uint32 group_rid;
4632 uint32 acc_granted;
4633 SE_PRIV se_rights;
4634 bool can_add_accounts;
4635 DISP_INFO *disp_info = NULL;
4637 /* Find the policy handle. Open a policy on it. */
4638 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4639 return NT_STATUS_INVALID_HANDLE;
4641 status = access_check_samr_function(acc_granted,
4642 SA_RIGHT_GROUP_ADD_MEMBER,
4643 "_samr_AddGroupMember");
4644 if (!NT_STATUS_IS_OK(status)) {
4645 return status;
4648 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4650 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4651 &group_rid)) {
4652 return NT_STATUS_INVALID_HANDLE;
4655 se_priv_copy( &se_rights, &se_add_users );
4656 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4658 /******** BEGIN SeAddUsers BLOCK *********/
4660 if ( can_add_accounts )
4661 become_root();
4663 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4665 if ( can_add_accounts )
4666 unbecome_root();
4668 /******** END SeAddUsers BLOCK *********/
4670 force_flush_samr_cache(disp_info);
4672 return status;
4675 /*********************************************************************
4676 _samr_DeleteGroupMember
4677 *********************************************************************/
4679 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4680 struct samr_DeleteGroupMember *r)
4683 NTSTATUS status;
4684 DOM_SID group_sid;
4685 uint32 group_rid;
4686 uint32 acc_granted;
4687 SE_PRIV se_rights;
4688 bool can_add_accounts;
4689 DISP_INFO *disp_info = NULL;
4692 * delete the group member named r->in.rid
4693 * who is a member of the sid associated with the handle
4694 * the rid is a user's rid as the group is a domain group.
4697 /* Find the policy handle. Open a policy on it. */
4698 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4699 return NT_STATUS_INVALID_HANDLE;
4701 status = access_check_samr_function(acc_granted,
4702 SA_RIGHT_GROUP_REMOVE_MEMBER,
4703 "_samr_DeleteGroupMember");
4704 if (!NT_STATUS_IS_OK(status)) {
4705 return status;
4708 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4709 &group_rid)) {
4710 return NT_STATUS_INVALID_HANDLE;
4713 se_priv_copy( &se_rights, &se_add_users );
4714 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4716 /******** BEGIN SeAddUsers BLOCK *********/
4718 if ( can_add_accounts )
4719 become_root();
4721 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4723 if ( can_add_accounts )
4724 unbecome_root();
4726 /******** END SeAddUsers BLOCK *********/
4728 force_flush_samr_cache(disp_info);
4730 return status;
4733 /*********************************************************************
4734 _samr_DeleteUser
4735 *********************************************************************/
4737 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4738 struct samr_DeleteUser *r)
4740 NTSTATUS status;
4741 DOM_SID user_sid;
4742 struct samu *sam_pass=NULL;
4743 uint32 acc_granted;
4744 bool can_add_accounts;
4745 uint32 acb_info;
4746 DISP_INFO *disp_info = NULL;
4747 bool ret;
4749 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4751 /* Find the policy handle. Open a policy on it. */
4752 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4753 return NT_STATUS_INVALID_HANDLE;
4755 status = access_check_samr_function(acc_granted,
4756 STD_RIGHT_DELETE_ACCESS,
4757 "_samr_DeleteUser");
4758 if (!NT_STATUS_IS_OK(status)) {
4759 return status;
4762 if (!sid_check_is_in_our_domain(&user_sid))
4763 return NT_STATUS_CANNOT_DELETE;
4765 /* check if the user exists before trying to delete */
4766 if ( !(sam_pass = samu_new( NULL )) ) {
4767 return NT_STATUS_NO_MEMORY;
4770 become_root();
4771 ret = pdb_getsampwsid(sam_pass, &user_sid);
4772 unbecome_root();
4774 if( !ret ) {
4775 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4776 sid_string_dbg(&user_sid)));
4777 TALLOC_FREE(sam_pass);
4778 return NT_STATUS_NO_SUCH_USER;
4781 acb_info = pdb_get_acct_ctrl(sam_pass);
4783 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4784 if ( acb_info & ACB_WSTRUST ) {
4785 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4786 } else {
4787 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4790 /******** BEGIN SeAddUsers BLOCK *********/
4792 if ( can_add_accounts )
4793 become_root();
4795 status = pdb_delete_user(p->mem_ctx, sam_pass);
4797 if ( can_add_accounts )
4798 unbecome_root();
4800 /******** END SeAddUsers BLOCK *********/
4802 if ( !NT_STATUS_IS_OK(status) ) {
4803 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4804 "user %s: %s.\n", pdb_get_username(sam_pass),
4805 nt_errstr(status)));
4806 TALLOC_FREE(sam_pass);
4807 return status;
4811 TALLOC_FREE(sam_pass);
4813 if (!close_policy_hnd(p, r->in.user_handle))
4814 return NT_STATUS_OBJECT_NAME_INVALID;
4816 force_flush_samr_cache(disp_info);
4818 return NT_STATUS_OK;
4821 /*********************************************************************
4822 _samr_DeleteDomainGroup
4823 *********************************************************************/
4825 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4826 struct samr_DeleteDomainGroup *r)
4828 NTSTATUS status;
4829 DOM_SID group_sid;
4830 uint32 group_rid;
4831 uint32 acc_granted;
4832 SE_PRIV se_rights;
4833 bool can_add_accounts;
4834 DISP_INFO *disp_info = NULL;
4836 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4838 /* Find the policy handle. Open a policy on it. */
4839 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4840 return NT_STATUS_INVALID_HANDLE;
4842 status = access_check_samr_function(acc_granted,
4843 STD_RIGHT_DELETE_ACCESS,
4844 "_samr_DeleteDomainGroup");
4845 if (!NT_STATUS_IS_OK(status)) {
4846 return status;
4849 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4851 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4852 &group_rid)) {
4853 return NT_STATUS_NO_SUCH_GROUP;
4856 se_priv_copy( &se_rights, &se_add_users );
4857 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4859 /******** BEGIN SeAddUsers BLOCK *********/
4861 if ( can_add_accounts )
4862 become_root();
4864 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4866 if ( can_add_accounts )
4867 unbecome_root();
4869 /******** END SeAddUsers BLOCK *********/
4871 if ( !NT_STATUS_IS_OK(status) ) {
4872 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4873 "entry for group %s: %s\n",
4874 sid_string_dbg(&group_sid),
4875 nt_errstr(status)));
4876 return status;
4879 if (!close_policy_hnd(p, r->in.group_handle))
4880 return NT_STATUS_OBJECT_NAME_INVALID;
4882 force_flush_samr_cache(disp_info);
4884 return NT_STATUS_OK;
4887 /*********************************************************************
4888 _samr_DeleteDomAlias
4889 *********************************************************************/
4891 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4892 struct samr_DeleteDomAlias *r)
4894 DOM_SID alias_sid;
4895 uint32 acc_granted;
4896 SE_PRIV se_rights;
4897 bool can_add_accounts;
4898 NTSTATUS status;
4899 DISP_INFO *disp_info = NULL;
4901 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4903 /* Find the policy handle. Open a policy on it. */
4904 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4905 return NT_STATUS_INVALID_HANDLE;
4907 /* copy the handle to the outgoing reply */
4909 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4911 status = access_check_samr_function(acc_granted,
4912 STD_RIGHT_DELETE_ACCESS,
4913 "_samr_DeleteDomAlias");
4914 if (!NT_STATUS_IS_OK(status)) {
4915 return status;
4918 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4920 /* Don't let Windows delete builtin groups */
4922 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4923 return NT_STATUS_SPECIAL_ACCOUNT;
4926 if (!sid_check_is_in_our_domain(&alias_sid))
4927 return NT_STATUS_NO_SUCH_ALIAS;
4929 DEBUG(10, ("lookup on Local SID\n"));
4931 se_priv_copy( &se_rights, &se_add_users );
4932 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4934 /******** BEGIN SeAddUsers BLOCK *********/
4936 if ( can_add_accounts )
4937 become_root();
4939 /* Have passdb delete the alias */
4940 status = pdb_delete_alias(&alias_sid);
4942 if ( can_add_accounts )
4943 unbecome_root();
4945 /******** END SeAddUsers BLOCK *********/
4947 if ( !NT_STATUS_IS_OK(status))
4948 return status;
4950 if (!close_policy_hnd(p, r->in.alias_handle))
4951 return NT_STATUS_OBJECT_NAME_INVALID;
4953 force_flush_samr_cache(disp_info);
4955 return NT_STATUS_OK;
4958 /*********************************************************************
4959 _samr_CreateDomainGroup
4960 *********************************************************************/
4962 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4963 struct samr_CreateDomainGroup *r)
4966 NTSTATUS status;
4967 DOM_SID dom_sid;
4968 DOM_SID info_sid;
4969 const char *name;
4970 struct samr_info *info;
4971 uint32 acc_granted;
4972 SE_PRIV se_rights;
4973 bool can_add_accounts;
4974 DISP_INFO *disp_info = NULL;
4976 /* Find the policy handle. Open a policy on it. */
4977 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4978 return NT_STATUS_INVALID_HANDLE;
4980 status = access_check_samr_function(acc_granted,
4981 SA_RIGHT_DOMAIN_CREATE_GROUP,
4982 "_samr_CreateDomainGroup");
4983 if (!NT_STATUS_IS_OK(status)) {
4984 return status;
4987 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4988 return NT_STATUS_ACCESS_DENIED;
4990 name = r->in.name->string;
4991 if (name == NULL) {
4992 return NT_STATUS_NO_MEMORY;
4995 status = can_create(p->mem_ctx, name);
4996 if (!NT_STATUS_IS_OK(status)) {
4997 return status;
5000 se_priv_copy( &se_rights, &se_add_users );
5001 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5003 /******** BEGIN SeAddUsers BLOCK *********/
5005 if ( can_add_accounts )
5006 become_root();
5008 /* check that we successfully create the UNIX group */
5010 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5012 if ( can_add_accounts )
5013 unbecome_root();
5015 /******** END SeAddUsers BLOCK *********/
5017 /* check if we should bail out here */
5019 if ( !NT_STATUS_IS_OK(status) )
5020 return status;
5022 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5024 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5025 return NT_STATUS_NO_MEMORY;
5027 /* they created it; let the user do what he wants with it */
5029 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5031 /* get a (unique) handle. open a policy on it. */
5032 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5033 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5035 force_flush_samr_cache(disp_info);
5037 return NT_STATUS_OK;
5040 /*********************************************************************
5041 _samr_CreateDomAlias
5042 *********************************************************************/
5044 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5045 struct samr_CreateDomAlias *r)
5047 DOM_SID dom_sid;
5048 DOM_SID info_sid;
5049 const char *name = NULL;
5050 struct samr_info *info;
5051 uint32 acc_granted;
5052 gid_t gid;
5053 NTSTATUS result;
5054 SE_PRIV se_rights;
5055 bool can_add_accounts;
5056 DISP_INFO *disp_info = NULL;
5058 /* Find the policy handle. Open a policy on it. */
5059 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5060 return NT_STATUS_INVALID_HANDLE;
5062 result = access_check_samr_function(acc_granted,
5063 SA_RIGHT_DOMAIN_CREATE_ALIAS,
5064 "_samr_CreateDomAlias");
5065 if (!NT_STATUS_IS_OK(result)) {
5066 return result;
5069 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5070 return NT_STATUS_ACCESS_DENIED;
5072 name = r->in.alias_name->string;
5074 se_priv_copy( &se_rights, &se_add_users );
5075 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5077 result = can_create(p->mem_ctx, name);
5078 if (!NT_STATUS_IS_OK(result)) {
5079 return result;
5082 /******** BEGIN SeAddUsers BLOCK *********/
5084 if ( can_add_accounts )
5085 become_root();
5087 /* Have passdb create the alias */
5088 result = pdb_create_alias(name, r->out.rid);
5090 if ( can_add_accounts )
5091 unbecome_root();
5093 /******** END SeAddUsers BLOCK *********/
5095 if (!NT_STATUS_IS_OK(result)) {
5096 DEBUG(10, ("pdb_create_alias failed: %s\n",
5097 nt_errstr(result)));
5098 return result;
5101 sid_copy(&info_sid, get_global_sam_sid());
5102 sid_append_rid(&info_sid, *r->out.rid);
5104 if (!sid_to_gid(&info_sid, &gid)) {
5105 DEBUG(10, ("Could not find alias just created\n"));
5106 return NT_STATUS_ACCESS_DENIED;
5109 /* check if the group has been successfully created */
5110 if ( getgrgid(gid) == NULL ) {
5111 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5112 gid));
5113 return NT_STATUS_ACCESS_DENIED;
5116 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5117 return NT_STATUS_NO_MEMORY;
5119 /* they created it; let the user do what he wants with it */
5121 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5123 /* get a (unique) handle. open a policy on it. */
5124 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5125 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5127 force_flush_samr_cache(disp_info);
5129 return NT_STATUS_OK;
5132 /*********************************************************************
5133 _samr_QueryGroupInfo
5134 *********************************************************************/
5136 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5137 struct samr_QueryGroupInfo *r)
5139 NTSTATUS status;
5140 DOM_SID group_sid;
5141 GROUP_MAP map;
5142 union samr_GroupInfo *info = NULL;
5143 uint32 acc_granted;
5144 bool ret;
5145 uint32_t attributes = SE_GROUP_MANDATORY |
5146 SE_GROUP_ENABLED_BY_DEFAULT |
5147 SE_GROUP_ENABLED;
5148 const char *group_name = NULL;
5149 const char *group_description = NULL;
5151 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5152 return NT_STATUS_INVALID_HANDLE;
5154 status = access_check_samr_function(acc_granted,
5155 SA_RIGHT_GROUP_LOOKUP_INFO,
5156 "_samr_QueryGroupInfo");
5157 if (!NT_STATUS_IS_OK(status)) {
5158 return status;
5161 become_root();
5162 ret = get_domain_group_from_sid(group_sid, &map);
5163 unbecome_root();
5164 if (!ret)
5165 return NT_STATUS_INVALID_HANDLE;
5167 /* FIXME: map contains fstrings */
5168 group_name = talloc_strdup(r, map.nt_name);
5169 group_description = talloc_strdup(r, map.comment);
5171 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5172 if (!info) {
5173 return NT_STATUS_NO_MEMORY;
5176 switch (r->in.level) {
5177 case 1: {
5178 uint32 *members;
5179 size_t num_members;
5181 become_root();
5182 status = pdb_enum_group_members(
5183 p->mem_ctx, &group_sid, &members, &num_members);
5184 unbecome_root();
5186 if (!NT_STATUS_IS_OK(status)) {
5187 return status;
5190 init_samr_group_info1(&info->all,
5191 group_name,
5192 attributes,
5193 num_members,
5194 group_description);
5195 break;
5197 case 2:
5198 init_samr_group_info2(&info->name,
5199 group_name);
5200 break;
5201 case 3:
5202 init_samr_group_info3(&info->attributes,
5203 attributes);
5204 break;
5205 case 4:
5206 init_samr_group_info4(&info->description,
5207 group_description);
5208 break;
5209 case 5: {
5211 uint32 *members;
5212 size_t num_members;
5216 become_root();
5217 status = pdb_enum_group_members(
5218 p->mem_ctx, &group_sid, &members, &num_members);
5219 unbecome_root();
5221 if (!NT_STATUS_IS_OK(status)) {
5222 return status;
5225 init_samr_group_info5(&info->all2,
5226 group_name,
5227 attributes,
5228 0, /* num_members - in w2k3 this is always 0 */
5229 group_description);
5231 break;
5233 default:
5234 return NT_STATUS_INVALID_INFO_CLASS;
5237 *r->out.info = info;
5239 return NT_STATUS_OK;
5242 /*********************************************************************
5243 _samr_SetGroupInfo
5244 *********************************************************************/
5246 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5247 struct samr_SetGroupInfo *r)
5249 DOM_SID group_sid;
5250 GROUP_MAP map;
5251 uint32 acc_granted;
5252 NTSTATUS status;
5253 bool ret;
5254 bool can_mod_accounts;
5255 DISP_INFO *disp_info = NULL;
5257 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5258 return NT_STATUS_INVALID_HANDLE;
5260 status = access_check_samr_function(acc_granted,
5261 SA_RIGHT_GROUP_SET_INFO,
5262 "_samr_SetGroupInfo");
5263 if (!NT_STATUS_IS_OK(status)) {
5264 return status;
5267 become_root();
5268 ret = get_domain_group_from_sid(group_sid, &map);
5269 unbecome_root();
5270 if (!ret)
5271 return NT_STATUS_NO_SUCH_GROUP;
5273 switch (r->in.level) {
5274 case 1:
5275 fstrcpy(map.comment, r->in.info->all.description.string);
5276 break;
5277 case 4:
5278 fstrcpy(map.comment, r->in.info->description.string);
5279 break;
5280 default:
5281 return NT_STATUS_INVALID_INFO_CLASS;
5284 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5286 /******** BEGIN SeAddUsers BLOCK *********/
5288 if ( can_mod_accounts )
5289 become_root();
5291 status = pdb_update_group_mapping_entry(&map);
5293 if ( can_mod_accounts )
5294 unbecome_root();
5296 /******** End SeAddUsers BLOCK *********/
5298 if (NT_STATUS_IS_OK(status)) {
5299 force_flush_samr_cache(disp_info);
5302 return status;
5305 /*********************************************************************
5306 _samr_SetAliasInfo
5307 *********************************************************************/
5309 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5310 struct samr_SetAliasInfo *r)
5312 DOM_SID group_sid;
5313 struct acct_info info;
5314 uint32 acc_granted;
5315 bool can_mod_accounts;
5316 NTSTATUS status;
5317 DISP_INFO *disp_info = NULL;
5319 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5320 return NT_STATUS_INVALID_HANDLE;
5322 status = access_check_samr_function(acc_granted,
5323 SA_RIGHT_ALIAS_SET_INFO,
5324 "_samr_SetAliasInfo");
5325 if (!NT_STATUS_IS_OK(status)) {
5326 return status;
5329 /* get the current group information */
5331 become_root();
5332 status = pdb_get_aliasinfo( &group_sid, &info );
5333 unbecome_root();
5335 if ( !NT_STATUS_IS_OK(status))
5336 return status;
5338 switch (r->in.level) {
5339 case ALIASINFONAME:
5341 fstring group_name;
5343 /* We currently do not support renaming groups in the
5344 the BUILTIN domain. Refer to util_builtin.c to understand
5345 why. The eventually needs to be fixed to be like Windows
5346 where you can rename builtin groups, just not delete them */
5348 if ( sid_check_is_in_builtin( &group_sid ) ) {
5349 return NT_STATUS_SPECIAL_ACCOUNT;
5352 /* There has to be a valid name (and it has to be different) */
5354 if ( !r->in.info->name.string )
5355 return NT_STATUS_INVALID_PARAMETER;
5357 /* If the name is the same just reply "ok". Yes this
5358 doesn't allow you to change the case of a group name. */
5360 if ( strequal( r->in.info->name.string, info.acct_name ) )
5361 return NT_STATUS_OK;
5363 fstrcpy( info.acct_name, r->in.info->name.string);
5365 /* make sure the name doesn't already exist as a user
5366 or local group */
5368 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5369 status = can_create( p->mem_ctx, group_name );
5370 if ( !NT_STATUS_IS_OK( status ) )
5371 return status;
5372 break;
5374 case ALIASINFODESCRIPTION:
5375 if (r->in.info->description.string) {
5376 fstrcpy(info.acct_desc,
5377 r->in.info->description.string);
5378 } else {
5379 fstrcpy( info.acct_desc, "" );
5381 break;
5382 default:
5383 return NT_STATUS_INVALID_INFO_CLASS;
5386 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5388 /******** BEGIN SeAddUsers BLOCK *********/
5390 if ( can_mod_accounts )
5391 become_root();
5393 status = pdb_set_aliasinfo( &group_sid, &info );
5395 if ( can_mod_accounts )
5396 unbecome_root();
5398 /******** End SeAddUsers BLOCK *********/
5400 if (NT_STATUS_IS_OK(status))
5401 force_flush_samr_cache(disp_info);
5403 return status;
5406 /****************************************************************
5407 _samr_GetDomPwInfo
5408 ****************************************************************/
5410 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5411 struct samr_GetDomPwInfo *r)
5413 uint32_t min_password_length = 0;
5414 uint32_t password_properties = 0;
5416 /* Perform access check. Since this rpc does not require a
5417 policy handle it will not be caught by the access checks on
5418 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5420 if (!pipe_access_check(p)) {
5421 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5422 return NT_STATUS_ACCESS_DENIED;
5425 become_root();
5426 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5427 &min_password_length);
5428 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5429 &password_properties);
5430 unbecome_root();
5432 if (lp_check_password_script() && *lp_check_password_script()) {
5433 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5436 r->out.info->min_password_length = min_password_length;
5437 r->out.info->password_properties = password_properties;
5439 return NT_STATUS_OK;
5442 /*********************************************************************
5443 _samr_OpenGroup
5444 *********************************************************************/
5446 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5447 struct samr_OpenGroup *r)
5450 DOM_SID sid;
5451 DOM_SID info_sid;
5452 GROUP_MAP map;
5453 struct samr_info *info;
5454 SEC_DESC *psd = NULL;
5455 uint32 acc_granted;
5456 uint32 des_access = r->in.access_mask;
5457 size_t sd_size;
5458 NTSTATUS status;
5459 fstring sid_string;
5460 bool ret;
5461 SE_PRIV se_rights;
5463 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5464 return NT_STATUS_INVALID_HANDLE;
5466 status = access_check_samr_function(acc_granted,
5467 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5468 "_samr_OpenGroup");
5470 if ( !NT_STATUS_IS_OK(status) )
5471 return status;
5473 /*check if access can be granted as requested by client. */
5474 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5475 se_map_generic(&des_access,&grp_generic_mapping);
5477 se_priv_copy( &se_rights, &se_add_users );
5479 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5480 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5481 &acc_granted, "_samr_OpenGroup");
5483 if ( !NT_STATUS_IS_OK(status) )
5484 return status;
5486 /* this should not be hard-coded like this */
5488 if (!sid_equal(&sid, get_global_sam_sid()))
5489 return NT_STATUS_ACCESS_DENIED;
5491 sid_copy(&info_sid, get_global_sam_sid());
5492 sid_append_rid(&info_sid, r->in.rid);
5493 sid_to_fstring(sid_string, &info_sid);
5495 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5496 return NT_STATUS_NO_MEMORY;
5498 info->acc_granted = acc_granted;
5500 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5502 /* check if that group really exists */
5503 become_root();
5504 ret = get_domain_group_from_sid(info->sid, &map);
5505 unbecome_root();
5506 if (!ret)
5507 return NT_STATUS_NO_SUCH_GROUP;
5509 /* get a (unique) handle. open a policy on it. */
5510 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5511 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5513 return NT_STATUS_OK;
5516 /*********************************************************************
5517 _samr_RemoveMemberFromForeignDomain
5518 *********************************************************************/
5520 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5521 struct samr_RemoveMemberFromForeignDomain *r)
5523 DOM_SID delete_sid, domain_sid;
5524 uint32 acc_granted;
5525 NTSTATUS result;
5526 DISP_INFO *disp_info = NULL;
5528 sid_copy( &delete_sid, r->in.sid );
5530 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5531 sid_string_dbg(&delete_sid)));
5533 /* Find the policy handle. Open a policy on it. */
5535 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5536 &acc_granted, &disp_info))
5537 return NT_STATUS_INVALID_HANDLE;
5539 result = access_check_samr_function(acc_granted,
5540 STD_RIGHT_DELETE_ACCESS,
5541 "_samr_RemoveMemberFromForeignDomain");
5543 if (!NT_STATUS_IS_OK(result))
5544 return result;
5546 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5547 sid_string_dbg(&domain_sid)));
5549 /* we can only delete a user from a group since we don't have
5550 nested groups anyways. So in the latter case, just say OK */
5552 /* TODO: The above comment nowadays is bogus. Since we have nested
5553 * groups now, and aliases members are never reported out of the unix
5554 * group membership, the "just say OK" makes this call a no-op. For
5555 * us. This needs fixing however. */
5557 /* I've only ever seen this in the wild when deleting a user from
5558 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5559 * is the user about to be deleted. I very much suspect this is the
5560 * only application of this call. To verify this, let people report
5561 * other cases. */
5563 if (!sid_check_is_builtin(&domain_sid)) {
5564 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5565 "global_sam_sid() = %s\n",
5566 sid_string_dbg(&domain_sid),
5567 sid_string_dbg(get_global_sam_sid())));
5568 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5569 return NT_STATUS_OK;
5572 force_flush_samr_cache(disp_info);
5574 result = NT_STATUS_OK;
5576 return result;
5579 /*******************************************************************
5580 _samr_QueryDomainInfo2
5581 ********************************************************************/
5583 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5584 struct samr_QueryDomainInfo2 *r)
5586 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5588 r->in.domain_handle,
5589 r->in.level,
5590 r->out.info);
5593 /*******************************************************************
5594 _samr_SetDomainInfo
5595 ********************************************************************/
5597 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5598 struct samr_SetDomainInfo *r)
5600 time_t u_expire, u_min_age;
5601 time_t u_logout;
5602 time_t u_lock_duration, u_reset_time;
5604 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5606 /* find the policy handle. open a policy on it. */
5607 if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5608 return NT_STATUS_INVALID_HANDLE;
5610 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5612 switch (r->in.level) {
5613 case 0x01:
5614 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5615 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5616 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5617 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5618 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5619 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5620 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5621 break;
5622 case 0x02:
5623 break;
5624 case 0x03:
5625 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5626 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5627 break;
5628 case 0x05:
5629 break;
5630 case 0x06:
5631 break;
5632 case 0x07:
5633 break;
5634 case 0x0c:
5635 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5636 if (u_lock_duration != -1)
5637 u_lock_duration /= 60;
5639 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5641 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5642 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5643 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5644 break;
5645 default:
5646 return NT_STATUS_INVALID_INFO_CLASS;
5649 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5651 return NT_STATUS_OK;
5654 /****************************************************************
5655 _samr_GetDisplayEnumerationIndex
5656 ****************************************************************/
5658 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5659 struct samr_GetDisplayEnumerationIndex *r)
5661 struct samr_info *info = NULL;
5662 uint32_t max_entries = (uint32_t) -1;
5663 uint32_t enum_context = 0;
5664 int i;
5665 uint32_t num_account = 0;
5666 struct samr_displayentry *entries = NULL;
5668 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5670 /* find the policy handle. open a policy on it. */
5671 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5672 return NT_STATUS_INVALID_HANDLE;
5675 if ((r->in.level < 1) || (r->in.level > 3)) {
5676 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5677 "Unknown info level (%u)\n",
5678 r->in.level));
5679 return NT_STATUS_INVALID_INFO_CLASS;
5682 become_root();
5684 /* The following done as ROOT. Don't return without unbecome_root(). */
5686 switch (r->in.level) {
5687 case 1:
5688 if (info->disp_info->users == NULL) {
5689 info->disp_info->users = pdb_search_users(ACB_NORMAL);
5690 if (info->disp_info->users == NULL) {
5691 unbecome_root();
5692 return NT_STATUS_ACCESS_DENIED;
5694 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5695 "starting user enumeration at index %u\n",
5696 (unsigned int)enum_context));
5697 } else {
5698 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5699 "using cached user enumeration at index %u\n",
5700 (unsigned int)enum_context));
5702 num_account = pdb_search_entries(info->disp_info->users,
5703 enum_context, max_entries,
5704 &entries);
5705 break;
5706 case 2:
5707 if (info->disp_info->machines == NULL) {
5708 info->disp_info->machines =
5709 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5710 if (info->disp_info->machines == NULL) {
5711 unbecome_root();
5712 return NT_STATUS_ACCESS_DENIED;
5714 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5715 "starting machine enumeration at index %u\n",
5716 (unsigned int)enum_context));
5717 } else {
5718 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5719 "using cached machine enumeration at index %u\n",
5720 (unsigned int)enum_context));
5722 num_account = pdb_search_entries(info->disp_info->machines,
5723 enum_context, max_entries,
5724 &entries);
5725 break;
5726 case 3:
5727 if (info->disp_info->groups == NULL) {
5728 info->disp_info->groups = pdb_search_groups();
5729 if (info->disp_info->groups == NULL) {
5730 unbecome_root();
5731 return NT_STATUS_ACCESS_DENIED;
5733 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5734 "starting group enumeration at index %u\n",
5735 (unsigned int)enum_context));
5736 } else {
5737 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5738 "using cached group enumeration at index %u\n",
5739 (unsigned int)enum_context));
5741 num_account = pdb_search_entries(info->disp_info->groups,
5742 enum_context, max_entries,
5743 &entries);
5744 break;
5745 default:
5746 unbecome_root();
5747 smb_panic("info class changed");
5748 break;
5751 unbecome_root();
5753 /* Ensure we cache this enumeration. */
5754 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5756 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5757 r->in.name->string));
5759 for (i=0; i<num_account; i++) {
5760 if (strequal(entries[i].account_name, r->in.name->string)) {
5761 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5762 "found %s at idx %d\n",
5763 r->in.name->string, i));
5764 *r->out.idx = i;
5765 return NT_STATUS_OK;
5769 /* assuming account_name lives at the very end */
5770 *r->out.idx = num_account;
5772 return NT_STATUS_NO_MORE_ENTRIES;
5775 /****************************************************************
5776 _samr_GetDisplayEnumerationIndex2
5777 ****************************************************************/
5779 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5780 struct samr_GetDisplayEnumerationIndex2 *r)
5782 struct samr_GetDisplayEnumerationIndex q;
5784 q.in.domain_handle = r->in.domain_handle;
5785 q.in.level = r->in.level;
5786 q.in.name = r->in.name;
5788 q.out.idx = r->out.idx;
5790 return _samr_GetDisplayEnumerationIndex(p, &q);
5793 /****************************************************************
5794 ****************************************************************/
5796 NTSTATUS _samr_Shutdown(pipes_struct *p,
5797 struct samr_Shutdown *r)
5799 p->rng_fault_state = true;
5800 return NT_STATUS_NOT_IMPLEMENTED;
5803 /****************************************************************
5804 ****************************************************************/
5806 NTSTATUS _samr_CreateUser(pipes_struct *p,
5807 struct samr_CreateUser *r)
5809 p->rng_fault_state = true;
5810 return NT_STATUS_NOT_IMPLEMENTED;
5813 /****************************************************************
5814 ****************************************************************/
5816 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5817 struct samr_SetMemberAttributesOfGroup *r)
5819 p->rng_fault_state = true;
5820 return NT_STATUS_NOT_IMPLEMENTED;
5823 /****************************************************************
5824 ****************************************************************/
5826 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5827 struct samr_ChangePasswordUser *r)
5829 p->rng_fault_state = true;
5830 return NT_STATUS_NOT_IMPLEMENTED;
5833 /****************************************************************
5834 ****************************************************************/
5836 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5837 struct samr_TestPrivateFunctionsDomain *r)
5839 p->rng_fault_state = true;
5840 return NT_STATUS_NOT_IMPLEMENTED;
5843 /****************************************************************
5844 ****************************************************************/
5846 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5847 struct samr_TestPrivateFunctionsUser *r)
5849 p->rng_fault_state = true;
5850 return NT_STATUS_NOT_IMPLEMENTED;
5853 /****************************************************************
5854 ****************************************************************/
5856 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5857 struct samr_QueryUserInfo2 *r)
5859 p->rng_fault_state = true;
5860 return NT_STATUS_NOT_IMPLEMENTED;
5863 /****************************************************************
5864 ****************************************************************/
5866 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5867 struct samr_AddMultipleMembersToAlias *r)
5869 p->rng_fault_state = true;
5870 return NT_STATUS_NOT_IMPLEMENTED;
5873 /****************************************************************
5874 ****************************************************************/
5876 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5877 struct samr_RemoveMultipleMembersFromAlias *r)
5879 p->rng_fault_state = true;
5880 return NT_STATUS_NOT_IMPLEMENTED;
5883 /****************************************************************
5884 ****************************************************************/
5886 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5887 struct samr_OemChangePasswordUser2 *r)
5889 p->rng_fault_state = true;
5890 return NT_STATUS_NOT_IMPLEMENTED;
5893 /****************************************************************
5894 ****************************************************************/
5896 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5897 struct samr_SetBootKeyInformation *r)
5899 p->rng_fault_state = true;
5900 return NT_STATUS_NOT_IMPLEMENTED;
5903 /****************************************************************
5904 ****************************************************************/
5906 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5907 struct samr_GetBootKeyInformation *r)
5909 p->rng_fault_state = true;
5910 return NT_STATUS_NOT_IMPLEMENTED;
5913 /****************************************************************
5914 ****************************************************************/
5916 NTSTATUS _samr_Connect3(pipes_struct *p,
5917 struct samr_Connect3 *r)
5919 p->rng_fault_state = true;
5920 return NT_STATUS_NOT_IMPLEMENTED;
5923 /****************************************************************
5924 ****************************************************************/
5926 NTSTATUS _samr_RidToSid(pipes_struct *p,
5927 struct samr_RidToSid *r)
5929 p->rng_fault_state = true;
5930 return NT_STATUS_NOT_IMPLEMENTED;
5933 /****************************************************************
5934 ****************************************************************/
5936 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5937 struct samr_SetDsrmPassword *r)
5939 p->rng_fault_state = true;
5940 return NT_STATUS_NOT_IMPLEMENTED;
5943 /****************************************************************
5944 ****************************************************************/
5946 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5947 struct samr_ValidatePassword *r)
5949 p->rng_fault_state = true;
5950 return NT_STATUS_NOT_IMPLEMENTED;