Fix a valgrind error in _samr_LookupNames
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_samr_nt.c
blob42431bd482512987194a9ef74fed726d0ec86b8a
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;
1790 enum lsa_SidType *type;
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 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1800 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1803 status = access_check_samr_function(acc_granted,
1804 0, /* Don't know the acc_bits yet */
1805 "_samr_LookupNames");
1806 if (!NT_STATUS_IS_OK(status)) {
1807 return status;
1810 if (num_rids > MAX_SAM_ENTRIES) {
1811 num_rids = MAX_SAM_ENTRIES;
1812 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1815 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1816 NT_STATUS_HAVE_NO_MEMORY(rid);
1818 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1819 NT_STATUS_HAVE_NO_MEMORY(rid);
1821 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1822 sid_string_dbg(&pol_sid)));
1824 for (i = 0; i < num_rids; i++) {
1826 status = NT_STATUS_NONE_MAPPED;
1827 type[i] = SID_NAME_UNKNOWN;
1829 rid[i] = 0xffffffff;
1831 if (sid_check_is_builtin(&pol_sid)) {
1832 if (lookup_builtin_name(r->in.names[i].string,
1833 &rid[i]))
1835 type[i] = SID_NAME_ALIAS;
1837 } else {
1838 lookup_global_sam_name(r->in.names[i].string, 0,
1839 &rid[i], &type[i]);
1842 if (type[i] != SID_NAME_UNKNOWN) {
1843 status = NT_STATUS_OK;
1847 rids.count = num_rids;
1848 rids.ids = rid;
1850 types.count = num_rids;
1851 types.ids = type;
1853 *r->out.rids = rids;
1854 *r->out.types = types;
1856 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1858 return status;
1861 /*******************************************************************
1862 _samr_ChangePasswordUser2
1863 ********************************************************************/
1865 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1866 struct samr_ChangePasswordUser2 *r)
1868 NTSTATUS status;
1869 fstring user_name;
1870 fstring wks;
1872 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1874 fstrcpy(user_name, r->in.account->string);
1875 fstrcpy(wks, r->in.server->string);
1877 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1880 * Pass the user through the NT -> unix user mapping
1881 * function.
1884 (void)map_username(user_name);
1887 * UNIX username case mangling not required, pass_oem_change
1888 * is case insensitive.
1891 status = pass_oem_change(user_name,
1892 r->in.lm_password->data,
1893 r->in.lm_verifier->hash,
1894 r->in.nt_password->data,
1895 r->in.nt_verifier->hash,
1896 NULL);
1898 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1900 return status;
1903 /*******************************************************************
1904 _samr_ChangePasswordUser3
1905 ********************************************************************/
1907 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1908 struct samr_ChangePasswordUser3 *r)
1910 NTSTATUS status;
1911 fstring user_name;
1912 const char *wks = NULL;
1913 uint32 reject_reason;
1914 struct samr_DomInfo1 *dominfo = NULL;
1915 struct samr_ChangeReject *reject = NULL;
1917 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1919 fstrcpy(user_name, r->in.account->string);
1920 if (r->in.server && r->in.server->string) {
1921 wks = r->in.server->string;
1924 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1927 * Pass the user through the NT -> unix user mapping
1928 * function.
1931 (void)map_username(user_name);
1934 * UNIX username case mangling not required, pass_oem_change
1935 * is case insensitive.
1938 status = pass_oem_change(user_name,
1939 r->in.lm_password->data,
1940 r->in.lm_verifier->hash,
1941 r->in.nt_password->data,
1942 r->in.nt_verifier->hash,
1943 &reject_reason);
1945 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1946 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1948 uint32 min_pass_len,pass_hist,password_properties;
1949 time_t u_expire, u_min_age;
1950 NTTIME nt_expire, nt_min_age;
1951 uint32 account_policy_temp;
1953 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1954 if (!dominfo) {
1955 return NT_STATUS_NO_MEMORY;
1958 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1959 if (!reject) {
1960 return NT_STATUS_NO_MEMORY;
1963 become_root();
1965 /* AS ROOT !!! */
1967 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1968 min_pass_len = account_policy_temp;
1970 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1971 pass_hist = account_policy_temp;
1973 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1974 password_properties = account_policy_temp;
1976 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1977 u_expire = account_policy_temp;
1979 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1980 u_min_age = account_policy_temp;
1982 /* !AS ROOT */
1984 unbecome_root();
1986 unix_to_nt_time_abs(&nt_expire, u_expire);
1987 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1989 if (lp_check_password_script() && *lp_check_password_script()) {
1990 password_properties |= DOMAIN_PASSWORD_COMPLEX;
1993 init_samr_DomInfo1(dominfo,
1994 min_pass_len,
1995 pass_hist,
1996 password_properties,
1997 u_expire,
1998 u_min_age);
2000 reject->reason = reject_reason;
2002 *r->out.dominfo = dominfo;
2003 *r->out.reject = reject;
2006 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2008 return status;
2011 /*******************************************************************
2012 makes a SAMR_R_LOOKUP_RIDS structure.
2013 ********************************************************************/
2015 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2016 const char **names,
2017 struct lsa_String **lsa_name_array_p)
2019 struct lsa_String *lsa_name_array = NULL;
2020 uint32_t i;
2022 *lsa_name_array_p = NULL;
2024 if (num_names != 0) {
2025 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2026 if (!lsa_name_array) {
2027 return false;
2031 for (i = 0; i < num_names; i++) {
2032 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2033 init_lsa_String(&lsa_name_array[i], names[i]);
2036 *lsa_name_array_p = lsa_name_array;
2038 return true;
2041 /*******************************************************************
2042 _samr_LookupRids
2043 ********************************************************************/
2045 NTSTATUS _samr_LookupRids(pipes_struct *p,
2046 struct samr_LookupRids *r)
2048 NTSTATUS status;
2049 const char **names;
2050 enum lsa_SidType *attrs = NULL;
2051 uint32 *wire_attrs = NULL;
2052 DOM_SID pol_sid;
2053 int num_rids = (int)r->in.num_rids;
2054 uint32 acc_granted;
2055 int i;
2056 struct lsa_Strings names_array;
2057 struct samr_Ids types_array;
2058 struct lsa_String *lsa_names = NULL;
2060 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2062 /* find the policy handle. open a policy on it. */
2063 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2064 return NT_STATUS_INVALID_HANDLE;
2066 if (num_rids > 1000) {
2067 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2068 "to samba4 idl this is not possible\n", num_rids));
2069 return NT_STATUS_UNSUCCESSFUL;
2072 if (num_rids) {
2073 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2074 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2075 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2077 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2078 return NT_STATUS_NO_MEMORY;
2079 } else {
2080 names = NULL;
2081 attrs = NULL;
2082 wire_attrs = NULL;
2085 become_root(); /* lookup_sid can require root privs */
2086 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2087 names, attrs);
2088 unbecome_root();
2090 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2091 status = NT_STATUS_OK;
2094 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2095 &lsa_names)) {
2096 return NT_STATUS_NO_MEMORY;
2099 /* Convert from enum lsa_SidType to uint32 for wire format. */
2100 for (i = 0; i < num_rids; i++) {
2101 wire_attrs[i] = (uint32)attrs[i];
2104 names_array.count = num_rids;
2105 names_array.names = lsa_names;
2107 types_array.count = num_rids;
2108 types_array.ids = wire_attrs;
2110 *r->out.names = names_array;
2111 *r->out.types = types_array;
2113 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2115 return status;
2118 /*******************************************************************
2119 _samr_OpenUser
2120 ********************************************************************/
2122 NTSTATUS _samr_OpenUser(pipes_struct *p,
2123 struct samr_OpenUser *r)
2125 struct samu *sampass=NULL;
2126 DOM_SID sid;
2127 POLICY_HND domain_pol = *r->in.domain_handle;
2128 POLICY_HND *user_pol = r->out.user_handle;
2129 struct samr_info *info = NULL;
2130 SEC_DESC *psd = NULL;
2131 uint32 acc_granted;
2132 uint32 des_access = r->in.access_mask;
2133 size_t sd_size;
2134 bool ret;
2135 NTSTATUS nt_status;
2136 SE_PRIV se_rights;
2138 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2140 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2141 return NT_STATUS_INVALID_HANDLE;
2143 nt_status = access_check_samr_function(acc_granted,
2144 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2145 "_samr_OpenUser" );
2147 if ( !NT_STATUS_IS_OK(nt_status) )
2148 return nt_status;
2150 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2151 return NT_STATUS_NO_MEMORY;
2154 /* append the user's RID to it */
2156 if (!sid_append_rid(&sid, r->in.rid))
2157 return NT_STATUS_NO_SUCH_USER;
2159 /* check if access can be granted as requested by client. */
2161 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2162 se_map_generic(&des_access, &usr_generic_mapping);
2164 se_priv_copy( &se_rights, &se_machine_account );
2165 se_priv_add( &se_rights, &se_add_users );
2167 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2168 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2169 &acc_granted, "_samr_OpenUser");
2171 if ( !NT_STATUS_IS_OK(nt_status) )
2172 return nt_status;
2174 become_root();
2175 ret=pdb_getsampwsid(sampass, &sid);
2176 unbecome_root();
2178 /* check that the SID exists in our domain. */
2179 if (ret == False) {
2180 return NT_STATUS_NO_SUCH_USER;
2183 TALLOC_FREE(sampass);
2185 /* associate the user's SID and access bits with the new handle. */
2186 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2187 return NT_STATUS_NO_MEMORY;
2188 info->acc_granted = acc_granted;
2190 /* get a (unique) handle. open a policy on it. */
2191 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2192 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2194 return NT_STATUS_OK;
2197 /*************************************************************************
2198 *************************************************************************/
2200 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2201 DATA_BLOB *blob,
2202 struct lsa_BinaryString **_r)
2204 struct lsa_BinaryString *r;
2206 if (!blob || !_r) {
2207 return NT_STATUS_INVALID_PARAMETER;
2210 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2211 if (!r) {
2212 return NT_STATUS_NO_MEMORY;
2215 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2216 if (!r->array) {
2217 return NT_STATUS_NO_MEMORY;
2219 memcpy(r->array, blob->data, blob->length);
2220 r->size = blob->length;
2221 r->length = blob->length;
2223 if (!r->array) {
2224 return NT_STATUS_NO_MEMORY;
2227 *_r = r;
2229 return NT_STATUS_OK;
2232 /*************************************************************************
2233 get_user_info_7. Safe. Only gives out account_name.
2234 *************************************************************************/
2236 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2237 struct samr_UserInfo7 *r,
2238 DOM_SID *user_sid)
2240 struct samu *smbpass=NULL;
2241 bool ret;
2242 const char *account_name = NULL;
2244 ZERO_STRUCTP(r);
2246 if ( !(smbpass = samu_new( mem_ctx )) ) {
2247 return NT_STATUS_NO_MEMORY;
2250 become_root();
2251 ret = pdb_getsampwsid(smbpass, user_sid);
2252 unbecome_root();
2254 if ( !ret ) {
2255 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2256 return NT_STATUS_NO_SUCH_USER;
2259 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2260 if (!account_name) {
2261 TALLOC_FREE(smbpass);
2262 return NT_STATUS_NO_MEMORY;
2264 TALLOC_FREE(smbpass);
2266 DEBUG(3,("User:[%s]\n", account_name));
2268 init_samr_user_info7(r, account_name);
2270 return NT_STATUS_OK;
2273 /*************************************************************************
2274 get_user_info_9. Only gives out primary group SID.
2275 *************************************************************************/
2277 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2278 struct samr_UserInfo9 *r,
2279 DOM_SID *user_sid)
2281 struct samu *smbpass=NULL;
2282 bool ret;
2284 ZERO_STRUCTP(r);
2286 if ( !(smbpass = samu_new( mem_ctx )) ) {
2287 return NT_STATUS_NO_MEMORY;
2290 become_root();
2291 ret = pdb_getsampwsid(smbpass, user_sid);
2292 unbecome_root();
2294 if (ret==False) {
2295 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2296 TALLOC_FREE(smbpass);
2297 return NT_STATUS_NO_SUCH_USER;
2300 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2302 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2304 TALLOC_FREE(smbpass);
2306 return NT_STATUS_OK;
2309 /*************************************************************************
2310 get_user_info_16. Safe. Only gives out acb bits.
2311 *************************************************************************/
2313 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2314 struct samr_UserInfo16 *r,
2315 DOM_SID *user_sid)
2317 struct samu *smbpass=NULL;
2318 bool ret;
2320 ZERO_STRUCTP(r);
2322 if ( !(smbpass = samu_new( mem_ctx )) ) {
2323 return NT_STATUS_NO_MEMORY;
2326 become_root();
2327 ret = pdb_getsampwsid(smbpass, user_sid);
2328 unbecome_root();
2330 if (ret==False) {
2331 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2332 TALLOC_FREE(smbpass);
2333 return NT_STATUS_NO_SUCH_USER;
2336 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2338 init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2340 TALLOC_FREE(smbpass);
2342 return NT_STATUS_OK;
2345 /*************************************************************************
2346 get_user_info_18. OK - this is the killer as it gives out password info.
2347 Ensure that this is only allowed on an encrypted connection with a root
2348 user. JRA.
2349 *************************************************************************/
2351 static NTSTATUS get_user_info_18(pipes_struct *p,
2352 TALLOC_CTX *mem_ctx,
2353 struct samr_UserInfo18 *r,
2354 DOM_SID *user_sid)
2356 struct samu *smbpass=NULL;
2357 bool ret;
2359 ZERO_STRUCTP(r);
2361 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2362 return NT_STATUS_ACCESS_DENIED;
2365 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2366 return NT_STATUS_ACCESS_DENIED;
2370 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2373 if ( !(smbpass = samu_new( mem_ctx )) ) {
2374 return NT_STATUS_NO_MEMORY;
2377 ret = pdb_getsampwsid(smbpass, user_sid);
2379 if (ret == False) {
2380 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2381 TALLOC_FREE(smbpass);
2382 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2385 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2387 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2388 TALLOC_FREE(smbpass);
2389 return NT_STATUS_ACCOUNT_DISABLED;
2392 init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2393 pdb_get_nt_passwd(smbpass));
2395 TALLOC_FREE(smbpass);
2397 return NT_STATUS_OK;
2400 /*************************************************************************
2401 get_user_info_20
2402 *************************************************************************/
2404 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2405 struct samr_UserInfo20 *r,
2406 DOM_SID *user_sid)
2408 struct samu *sampass=NULL;
2409 bool ret;
2410 const char *munged_dial = NULL;
2411 DATA_BLOB blob;
2412 NTSTATUS status;
2413 struct lsa_BinaryString *parameters = NULL;
2415 ZERO_STRUCTP(r);
2417 if ( !(sampass = samu_new( mem_ctx )) ) {
2418 return NT_STATUS_NO_MEMORY;
2421 become_root();
2422 ret = pdb_getsampwsid(sampass, user_sid);
2423 unbecome_root();
2425 if (ret == False) {
2426 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2427 TALLOC_FREE(sampass);
2428 return NT_STATUS_NO_SUCH_USER;
2431 munged_dial = pdb_get_munged_dial(sampass);
2433 samr_clear_sam_passwd(sampass);
2435 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2436 munged_dial, (int)strlen(munged_dial)));
2438 if (munged_dial) {
2439 blob = base64_decode_data_blob(munged_dial);
2440 } else {
2441 blob = data_blob_string_const("");
2444 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2445 data_blob_free(&blob);
2446 TALLOC_FREE(sampass);
2447 if (!NT_STATUS_IS_OK(status)) {
2448 return status;
2451 init_samr_user_info20(r, parameters);
2453 return NT_STATUS_OK;
2457 /*************************************************************************
2458 get_user_info_21
2459 *************************************************************************/
2461 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2462 struct samr_UserInfo21 *r,
2463 DOM_SID *user_sid,
2464 DOM_SID *domain_sid)
2466 NTSTATUS status;
2467 struct samu *pw = NULL;
2468 bool ret;
2469 const DOM_SID *sid_user, *sid_group;
2470 uint32_t rid, primary_gid;
2471 NTTIME last_logon, last_logoff, last_password_change,
2472 acct_expiry, allow_password_change, force_password_change;
2473 time_t must_change_time;
2474 uint8_t password_expired;
2475 const char *account_name, *full_name, *home_directory, *home_drive,
2476 *logon_script, *profile_path, *description,
2477 *workstations, *comment;
2478 struct samr_LogonHours logon_hours;
2479 struct lsa_BinaryString *parameters = NULL;
2480 const char *munged_dial = NULL;
2481 DATA_BLOB blob;
2483 ZERO_STRUCTP(r);
2485 if (!(pw = samu_new(mem_ctx))) {
2486 return NT_STATUS_NO_MEMORY;
2489 become_root();
2490 ret = pdb_getsampwsid(pw, user_sid);
2491 unbecome_root();
2493 if (ret == False) {
2494 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2495 TALLOC_FREE(pw);
2496 return NT_STATUS_NO_SUCH_USER;
2499 samr_clear_sam_passwd(pw);
2501 DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2503 sid_user = pdb_get_user_sid(pw);
2505 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2506 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2507 "the domain sid %s. Failing operation.\n",
2508 pdb_get_username(pw), sid_string_dbg(sid_user),
2509 sid_string_dbg(domain_sid)));
2510 TALLOC_FREE(pw);
2511 return NT_STATUS_UNSUCCESSFUL;
2514 become_root();
2515 sid_group = pdb_get_group_sid(pw);
2516 unbecome_root();
2518 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2519 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2520 "which conflicts with the domain sid %s. Failing operation.\n",
2521 pdb_get_username(pw), sid_string_dbg(sid_group),
2522 sid_string_dbg(domain_sid)));
2523 TALLOC_FREE(pw);
2524 return NT_STATUS_UNSUCCESSFUL;
2527 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2528 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2529 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2530 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2531 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2533 must_change_time = pdb_get_pass_must_change_time(pw);
2534 if (must_change_time == get_time_t_max()) {
2535 unix_to_nt_time_abs(&force_password_change, must_change_time);
2536 } else {
2537 unix_to_nt_time(&force_password_change, must_change_time);
2540 if (pdb_get_pass_must_change_time(pw) == 0) {
2541 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2542 } else {
2543 password_expired = 0;
2546 munged_dial = pdb_get_munged_dial(pw);
2547 if (munged_dial) {
2548 blob = base64_decode_data_blob(munged_dial);
2549 } else {
2550 blob = data_blob_string_const("");
2553 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2554 data_blob_free(&blob);
2555 if (!NT_STATUS_IS_OK(status)) {
2556 TALLOC_FREE(pw);
2557 return status;
2560 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2561 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2562 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2563 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2564 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2565 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2566 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2567 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2568 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2570 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2571 #if 0
2574 Look at a user on a real NT4 PDC with usrmgr, press
2575 'ok'. Then you will see that fields_present is set to
2576 0x08f827fa. Look at the user immediately after that again,
2577 and you will see that 0x00fffff is returned. This solves
2578 the problem that you get access denied after having looked
2579 at the user.
2580 -- Volker
2583 #endif
2585 init_samr_user_info21(r,
2586 last_logon,
2587 last_logoff,
2588 last_password_change,
2589 acct_expiry,
2590 allow_password_change,
2591 force_password_change,
2592 account_name,
2593 full_name,
2594 home_directory,
2595 home_drive,
2596 logon_script,
2597 profile_path,
2598 description,
2599 workstations,
2600 comment,
2601 parameters,
2602 rid,
2603 primary_gid,
2604 pdb_get_acct_ctrl(pw),
2605 pdb_build_fields_present(pw),
2606 logon_hours,
2607 pdb_get_bad_password_count(pw),
2608 pdb_get_logon_count(pw),
2609 0, /* country_code */
2610 0, /* code_page */
2611 0, /* nt_password_set */
2612 0, /* lm_password_set */
2613 password_expired);
2614 TALLOC_FREE(pw);
2616 return NT_STATUS_OK;
2619 /*******************************************************************
2620 _samr_QueryUserInfo
2621 ********************************************************************/
2623 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2624 struct samr_QueryUserInfo *r)
2626 NTSTATUS status;
2627 union samr_UserInfo *user_info = NULL;
2628 struct samr_info *info = NULL;
2629 DOM_SID domain_sid;
2630 uint32 rid;
2632 /* search for the handle */
2633 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2634 return NT_STATUS_INVALID_HANDLE;
2636 domain_sid = info->sid;
2638 sid_split_rid(&domain_sid, &rid);
2640 if (!sid_check_is_in_our_domain(&info->sid))
2641 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2643 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2644 sid_string_dbg(&info->sid)));
2646 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2647 if (!user_info) {
2648 return NT_STATUS_NO_MEMORY;
2651 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2653 switch (r->in.level) {
2654 case 7:
2655 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2656 if (!NT_STATUS_IS_OK(status)) {
2657 return status;
2659 break;
2660 case 9:
2661 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2662 if (!NT_STATUS_IS_OK(status)) {
2663 return status;
2665 break;
2666 case 16:
2667 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2668 if (!NT_STATUS_IS_OK(status)) {
2669 return status;
2671 break;
2673 case 18:
2674 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2675 if (!NT_STATUS_IS_OK(status)) {
2676 return status;
2678 break;
2680 case 20:
2681 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2682 if (!NT_STATUS_IS_OK(status)) {
2683 return status;
2685 break;
2687 case 21:
2688 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2689 &info->sid, &domain_sid);
2690 if (!NT_STATUS_IS_OK(status)) {
2691 return status;
2693 break;
2695 default:
2696 return NT_STATUS_INVALID_INFO_CLASS;
2699 *r->out.info = user_info;
2701 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2703 return status;
2706 /*******************************************************************
2707 _samr_GetGroupsForUser
2708 ********************************************************************/
2710 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2711 struct samr_GetGroupsForUser *r)
2713 struct samu *sam_pass=NULL;
2714 DOM_SID sid;
2715 DOM_SID *sids;
2716 struct samr_RidWithAttribute dom_gid;
2717 struct samr_RidWithAttribute *gids = NULL;
2718 uint32 primary_group_rid;
2719 size_t num_groups = 0;
2720 gid_t *unix_gids;
2721 size_t i, num_gids;
2722 uint32 acc_granted;
2723 bool ret;
2724 NTSTATUS result;
2725 bool success = False;
2727 struct samr_RidWithAttributeArray *rids = NULL;
2730 * from the SID in the request:
2731 * we should send back the list of DOMAIN GROUPS
2732 * the user is a member of
2734 * and only the DOMAIN GROUPS
2735 * no ALIASES !!! neither aliases of the domain
2736 * nor aliases of the builtin SID
2738 * JFM, 12/2/2001
2741 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2743 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2744 if (!rids) {
2745 return NT_STATUS_NO_MEMORY;
2748 /* find the policy handle. open a policy on it. */
2749 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2750 return NT_STATUS_INVALID_HANDLE;
2752 result = access_check_samr_function(acc_granted,
2753 SA_RIGHT_USER_GET_GROUPS,
2754 "_samr_GetGroupsForUser");
2755 if (!NT_STATUS_IS_OK(result)) {
2756 return result;
2759 if (!sid_check_is_in_our_domain(&sid))
2760 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2762 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2763 return NT_STATUS_NO_MEMORY;
2766 become_root();
2767 ret = pdb_getsampwsid(sam_pass, &sid);
2768 unbecome_root();
2770 if (!ret) {
2771 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2772 sid_string_dbg(&sid)));
2773 return NT_STATUS_NO_SUCH_USER;
2776 sids = NULL;
2778 /* make both calls inside the root block */
2779 become_root();
2780 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2781 &sids, &unix_gids, &num_groups);
2782 if ( NT_STATUS_IS_OK(result) ) {
2783 success = sid_peek_check_rid(get_global_sam_sid(),
2784 pdb_get_group_sid(sam_pass),
2785 &primary_group_rid);
2787 unbecome_root();
2789 if (!NT_STATUS_IS_OK(result)) {
2790 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2791 sid_string_dbg(&sid)));
2792 return result;
2795 if ( !success ) {
2796 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2797 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2798 pdb_get_username(sam_pass)));
2799 TALLOC_FREE(sam_pass);
2800 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2803 gids = NULL;
2804 num_gids = 0;
2806 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2807 SE_GROUP_ENABLED);
2808 dom_gid.rid = primary_group_rid;
2809 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2811 for (i=0; i<num_groups; i++) {
2813 if (!sid_peek_check_rid(get_global_sam_sid(),
2814 &(sids[i]), &dom_gid.rid)) {
2815 DEBUG(10, ("Found sid %s not in our domain\n",
2816 sid_string_dbg(&sids[i])));
2817 continue;
2820 if (dom_gid.rid == primary_group_rid) {
2821 /* We added the primary group directly from the
2822 * sam_account. The other SIDs are unique from
2823 * enum_group_memberships */
2824 continue;
2827 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2830 rids->count = num_gids;
2831 rids->rids = gids;
2833 *r->out.rids = rids;
2835 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2837 return result;
2840 /*******************************************************************
2841 samr_QueryDomainInfo_internal
2842 ********************************************************************/
2844 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2845 pipes_struct *p,
2846 struct policy_handle *handle,
2847 uint32_t level,
2848 union samr_DomainInfo **dom_info_ptr)
2850 NTSTATUS status = NT_STATUS_OK;
2851 struct samr_info *info = NULL;
2852 union samr_DomainInfo *dom_info;
2853 uint32 min_pass_len,pass_hist,password_properties;
2854 time_t u_expire, u_min_age;
2855 NTTIME nt_expire, nt_min_age;
2857 time_t u_lock_duration, u_reset_time;
2858 NTTIME nt_lock_duration, nt_reset_time;
2859 uint32 lockout;
2860 time_t u_logout;
2861 NTTIME nt_logout;
2863 uint32 account_policy_temp;
2865 time_t seq_num;
2866 uint32 server_role;
2868 uint32 num_users=0, num_groups=0, num_aliases=0;
2870 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2872 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2873 if (!dom_info) {
2874 return NT_STATUS_NO_MEMORY;
2877 *dom_info_ptr = dom_info;
2879 /* find the policy handle. open a policy on it. */
2880 if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2881 return NT_STATUS_INVALID_HANDLE;
2884 switch (level) {
2885 case 0x01:
2887 become_root();
2889 /* AS ROOT !!! */
2891 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2892 min_pass_len = account_policy_temp;
2894 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2895 pass_hist = account_policy_temp;
2897 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2898 password_properties = account_policy_temp;
2900 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2901 u_expire = account_policy_temp;
2903 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2904 u_min_age = account_policy_temp;
2906 /* !AS ROOT */
2908 unbecome_root();
2910 unix_to_nt_time_abs(&nt_expire, u_expire);
2911 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2913 init_samr_DomInfo1(&dom_info->info1,
2914 (uint16)min_pass_len,
2915 (uint16)pass_hist,
2916 password_properties,
2917 nt_expire,
2918 nt_min_age);
2919 break;
2920 case 0x02:
2922 become_root();
2924 /* AS ROOT !!! */
2926 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2927 num_groups = count_sam_groups(info->disp_info);
2928 num_aliases = count_sam_aliases(info->disp_info);
2930 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2931 u_logout = account_policy_temp;
2933 unix_to_nt_time_abs(&nt_logout, u_logout);
2935 if (!pdb_get_seq_num(&seq_num))
2936 seq_num = time(NULL);
2938 /* !AS ROOT */
2940 unbecome_root();
2942 server_role = ROLE_DOMAIN_PDC;
2943 if (lp_server_role() == ROLE_DOMAIN_BDC)
2944 server_role = ROLE_DOMAIN_BDC;
2946 init_samr_DomInfo2(&dom_info->info2,
2947 nt_logout,
2948 lp_serverstring(),
2949 lp_workgroup(),
2950 global_myname(),
2951 seq_num,
2953 server_role,
2955 num_users,
2956 num_groups,
2957 num_aliases);
2958 break;
2959 case 0x03:
2961 become_root();
2963 /* AS ROOT !!! */
2966 uint32 ul;
2967 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2968 u_logout = (time_t)ul;
2971 /* !AS ROOT */
2973 unbecome_root();
2975 unix_to_nt_time_abs(&nt_logout, u_logout);
2977 init_samr_DomInfo3(&dom_info->info3,
2978 nt_logout);
2980 break;
2981 case 0x04:
2982 init_samr_DomInfo4(&dom_info->info4,
2983 lp_serverstring());
2984 break;
2985 case 0x05:
2986 init_samr_DomInfo5(&dom_info->info5,
2987 get_global_sam_name());
2988 break;
2989 case 0x06:
2990 /* NT returns its own name when a PDC. win2k and later
2991 * only the name of the PDC if itself is a BDC (samba4
2992 * idl) */
2993 init_samr_DomInfo6(&dom_info->info6,
2994 global_myname());
2995 break;
2996 case 0x07:
2997 server_role = ROLE_DOMAIN_PDC;
2998 if (lp_server_role() == ROLE_DOMAIN_BDC)
2999 server_role = ROLE_DOMAIN_BDC;
3001 init_samr_DomInfo7(&dom_info->info7,
3002 server_role);
3003 break;
3004 case 0x08:
3006 become_root();
3008 /* AS ROOT !!! */
3010 if (!pdb_get_seq_num(&seq_num)) {
3011 seq_num = time(NULL);
3014 /* !AS ROOT */
3016 unbecome_root();
3018 init_samr_DomInfo8(&dom_info->info8,
3019 seq_num,
3021 break;
3022 case 0x0c:
3024 become_root();
3026 /* AS ROOT !!! */
3028 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3029 u_lock_duration = account_policy_temp;
3030 if (u_lock_duration != -1) {
3031 u_lock_duration *= 60;
3034 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3035 u_reset_time = account_policy_temp * 60;
3037 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3038 lockout = account_policy_temp;
3040 /* !AS ROOT */
3042 unbecome_root();
3044 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3045 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3047 init_samr_DomInfo12(&dom_info->info12,
3048 nt_lock_duration,
3049 nt_reset_time,
3050 (uint16)lockout);
3051 break;
3052 default:
3053 return NT_STATUS_INVALID_INFO_CLASS;
3056 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
3058 return status;
3061 /*******************************************************************
3062 _samr_QueryDomainInfo
3063 ********************************************************************/
3065 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3066 struct samr_QueryDomainInfo *r)
3068 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
3070 r->in.domain_handle,
3071 r->in.level,
3072 r->out.info);
3075 /* W2k3 seems to use the same check for all 3 objects that can be created via
3076 * SAMR, if you try to create for example "Dialup" as an alias it says
3077 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3078 * database. */
3080 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3082 enum lsa_SidType type;
3083 bool result;
3085 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3087 become_root();
3088 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3089 * whether the name already exists */
3090 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3091 NULL, NULL, NULL, &type);
3092 unbecome_root();
3094 if (!result) {
3095 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3096 return NT_STATUS_OK;
3099 DEBUG(5, ("trying to create %s, exists as %s\n",
3100 new_name, sid_type_lookup(type)));
3102 if (type == SID_NAME_DOM_GRP) {
3103 return NT_STATUS_GROUP_EXISTS;
3105 if (type == SID_NAME_ALIAS) {
3106 return NT_STATUS_ALIAS_EXISTS;
3109 /* Yes, the default is NT_STATUS_USER_EXISTS */
3110 return NT_STATUS_USER_EXISTS;
3113 /*******************************************************************
3114 _samr_CreateUser2
3115 ********************************************************************/
3117 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3118 struct samr_CreateUser2 *r)
3120 const char *account = NULL;
3121 DOM_SID sid;
3122 POLICY_HND dom_pol = *r->in.domain_handle;
3123 uint32_t acb_info = r->in.acct_flags;
3124 POLICY_HND *user_pol = r->out.user_handle;
3125 struct samr_info *info = NULL;
3126 NTSTATUS nt_status;
3127 uint32 acc_granted;
3128 SEC_DESC *psd;
3129 size_t sd_size;
3130 /* check this, when giving away 'add computer to domain' privs */
3131 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3132 bool can_add_account = False;
3133 SE_PRIV se_rights;
3134 DISP_INFO *disp_info = NULL;
3136 /* Get the domain SID stored in the domain policy */
3137 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3138 &disp_info))
3139 return NT_STATUS_INVALID_HANDLE;
3141 nt_status = access_check_samr_function(acc_granted,
3142 SA_RIGHT_DOMAIN_CREATE_USER,
3143 "_samr_CreateUser2");
3144 if (!NT_STATUS_IS_OK(nt_status)) {
3145 return nt_status;
3148 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3149 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3150 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3151 this parameter is not an account type */
3152 return NT_STATUS_INVALID_PARAMETER;
3155 account = r->in.account_name->string;
3156 if (account == NULL) {
3157 return NT_STATUS_NO_MEMORY;
3160 nt_status = can_create(p->mem_ctx, account);
3161 if (!NT_STATUS_IS_OK(nt_status)) {
3162 return nt_status;
3165 /* determine which user right we need to check based on the acb_info */
3167 if ( acb_info & ACB_WSTRUST )
3169 se_priv_copy( &se_rights, &se_machine_account );
3170 can_add_account = user_has_privileges(
3171 p->pipe_user.nt_user_token, &se_rights );
3173 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3174 account for domain trusts and changes the ACB flags later */
3175 else if ( acb_info & ACB_NORMAL &&
3176 (account[strlen(account)-1] != '$') )
3178 se_priv_copy( &se_rights, &se_add_users );
3179 can_add_account = user_has_privileges(
3180 p->pipe_user.nt_user_token, &se_rights );
3182 else /* implicit assumption of a BDC or domain trust account here
3183 * (we already check the flags earlier) */
3185 if ( lp_enable_privileges() ) {
3186 /* only Domain Admins can add a BDC or domain trust */
3187 se_priv_copy( &se_rights, &se_priv_none );
3188 can_add_account = nt_token_check_domain_rid(
3189 p->pipe_user.nt_user_token,
3190 DOMAIN_GROUP_RID_ADMINS );
3194 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3195 uidtoname(p->pipe_user.ut.uid),
3196 can_add_account ? "True":"False" ));
3198 /********** BEGIN Admin BLOCK **********/
3200 if ( can_add_account )
3201 become_root();
3203 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3204 r->out.rid);
3206 if ( can_add_account )
3207 unbecome_root();
3209 /********** END Admin BLOCK **********/
3211 /* now check for failure */
3213 if ( !NT_STATUS_IS_OK(nt_status) )
3214 return nt_status;
3216 /* Get the user's SID */
3218 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3220 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3221 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3222 se_map_generic(&des_access, &usr_generic_mapping);
3224 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3225 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3226 &acc_granted, "_samr_CreateUser2");
3228 if ( !NT_STATUS_IS_OK(nt_status) ) {
3229 return nt_status;
3232 /* associate the user's SID with the new handle. */
3233 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3234 return NT_STATUS_NO_MEMORY;
3237 ZERO_STRUCTP(info);
3238 info->sid = sid;
3239 info->acc_granted = acc_granted;
3241 /* get a (unique) handle. open a policy on it. */
3242 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3243 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3246 /* After a "set" ensure we have no cached display info. */
3247 force_flush_samr_cache(info->disp_info);
3249 *r->out.access_granted = acc_granted;
3251 return NT_STATUS_OK;
3254 /*******************************************************************
3255 _samr_Connect
3256 ********************************************************************/
3258 NTSTATUS _samr_Connect(pipes_struct *p,
3259 struct samr_Connect *r)
3261 struct samr_info *info = NULL;
3262 uint32 des_access = r->in.access_mask;
3264 /* Access check */
3266 if (!pipe_access_check(p)) {
3267 DEBUG(3, ("access denied to _samr_Connect\n"));
3268 return NT_STATUS_ACCESS_DENIED;
3271 /* set up the SAMR connect_anon response */
3273 /* associate the user's SID with the new handle. */
3274 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3275 return NT_STATUS_NO_MEMORY;
3277 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3278 was observed from a win98 client trying to enumerate users (when configured
3279 user level access control on shares) --jerry */
3281 if (des_access == MAXIMUM_ALLOWED_ACCESS) {
3282 /* Map to max possible knowing we're filtered below. */
3283 des_access = GENERIC_ALL_ACCESS;
3286 se_map_generic( &des_access, &sam_generic_mapping );
3287 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3289 /* get a (unique) handle. open a policy on it. */
3290 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3291 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3293 return NT_STATUS_OK;
3296 /*******************************************************************
3297 _samr_Connect2
3298 ********************************************************************/
3300 NTSTATUS _samr_Connect2(pipes_struct *p,
3301 struct samr_Connect2 *r)
3303 struct samr_info *info = NULL;
3304 SEC_DESC *psd = NULL;
3305 uint32 acc_granted;
3306 uint32 des_access = r->in.access_mask;
3307 NTSTATUS nt_status;
3308 size_t sd_size;
3311 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3313 /* Access check */
3315 if (!pipe_access_check(p)) {
3316 DEBUG(3, ("access denied to _samr_Connect2\n"));
3317 return NT_STATUS_ACCESS_DENIED;
3320 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3321 se_map_generic(&des_access, &sam_generic_mapping);
3323 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3324 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3326 if ( !NT_STATUS_IS_OK(nt_status) )
3327 return nt_status;
3329 /* associate the user's SID and access granted with the new handle. */
3330 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3331 return NT_STATUS_NO_MEMORY;
3333 info->acc_granted = acc_granted;
3334 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3336 /* get a (unique) handle. open a policy on it. */
3337 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3338 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3340 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3342 return nt_status;
3345 /*******************************************************************
3346 _samr_Connect4
3347 ********************************************************************/
3349 NTSTATUS _samr_Connect4(pipes_struct *p,
3350 struct samr_Connect4 *r)
3352 struct samr_info *info = NULL;
3353 SEC_DESC *psd = NULL;
3354 uint32 acc_granted;
3355 uint32 des_access = r->in.access_mask;
3356 NTSTATUS nt_status;
3357 size_t sd_size;
3360 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3362 /* Access check */
3364 if (!pipe_access_check(p)) {
3365 DEBUG(3, ("access denied to samr_Connect4\n"));
3366 return NT_STATUS_ACCESS_DENIED;
3369 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3370 se_map_generic(&des_access, &sam_generic_mapping);
3372 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3373 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3375 if ( !NT_STATUS_IS_OK(nt_status) )
3376 return nt_status;
3378 /* associate the user's SID and access granted with the new handle. */
3379 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3380 return NT_STATUS_NO_MEMORY;
3382 info->acc_granted = acc_granted;
3383 info->status = r->in.access_mask; /* ??? */
3385 /* get a (unique) handle. open a policy on it. */
3386 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3387 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3389 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3391 return NT_STATUS_OK;
3394 /*******************************************************************
3395 _samr_Connect5
3396 ********************************************************************/
3398 NTSTATUS _samr_Connect5(pipes_struct *p,
3399 struct samr_Connect5 *r)
3401 struct samr_info *info = NULL;
3402 SEC_DESC *psd = NULL;
3403 uint32 acc_granted;
3404 uint32 des_access = r->in.access_mask;
3405 NTSTATUS nt_status;
3406 size_t sd_size;
3407 struct samr_ConnectInfo1 info1;
3409 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3411 /* Access check */
3413 if (!pipe_access_check(p)) {
3414 DEBUG(3, ("access denied to samr_Connect5\n"));
3415 return NT_STATUS_ACCESS_DENIED;
3418 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3419 se_map_generic(&des_access, &sam_generic_mapping);
3421 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3422 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3424 if ( !NT_STATUS_IS_OK(nt_status) )
3425 return nt_status;
3427 /* associate the user's SID and access granted with the new handle. */
3428 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3429 return NT_STATUS_NO_MEMORY;
3431 info->acc_granted = acc_granted;
3432 info->status = r->in.access_mask; /* ??? */
3434 /* get a (unique) handle. open a policy on it. */
3435 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3436 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3438 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3440 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3441 info1.unknown2 = 0;
3443 *r->out.level_out = 1;
3444 r->out.info_out->info1 = info1;
3446 return NT_STATUS_OK;
3449 /**********************************************************************
3450 _samr_LookupDomain
3451 **********************************************************************/
3453 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3454 struct samr_LookupDomain *r)
3456 NTSTATUS status = NT_STATUS_OK;
3457 struct samr_info *info;
3458 const char *domain_name;
3459 DOM_SID *sid = NULL;
3461 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3462 return NT_STATUS_INVALID_HANDLE;
3464 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3465 Reverted that change so we will work with RAS servers again */
3467 status = access_check_samr_function(info->acc_granted,
3468 SA_RIGHT_SAM_OPEN_DOMAIN,
3469 "_samr_LookupDomain");
3470 if (!NT_STATUS_IS_OK(status)) {
3471 return status;
3474 domain_name = r->in.domain_name->string;
3476 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3477 if (!sid) {
3478 return NT_STATUS_NO_MEMORY;
3481 if (strequal(domain_name, builtin_domain_name())) {
3482 sid_copy(sid, &global_sid_Builtin);
3483 } else {
3484 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3485 status = NT_STATUS_NO_SUCH_DOMAIN;
3489 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3490 sid_string_dbg(sid)));
3492 *r->out.sid = sid;
3494 return status;
3497 /**********************************************************************
3498 _samr_EnumDomains
3499 **********************************************************************/
3501 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3502 struct samr_EnumDomains *r)
3504 NTSTATUS status;
3505 struct samr_info *info;
3506 uint32_t num_entries = 2;
3507 struct samr_SamEntry *entry_array = NULL;
3508 struct samr_SamArray *sam;
3510 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3511 return NT_STATUS_INVALID_HANDLE;
3513 status = access_check_samr_function(info->acc_granted,
3514 SA_RIGHT_SAM_ENUM_DOMAINS,
3515 "_samr_EnumDomains");
3516 if (!NT_STATUS_IS_OK(status)) {
3517 return status;
3520 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3521 if (!sam) {
3522 return NT_STATUS_NO_MEMORY;
3525 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3526 struct samr_SamEntry,
3527 num_entries);
3528 if (!entry_array) {
3529 return NT_STATUS_NO_MEMORY;
3532 entry_array[0].idx = 0;
3533 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3535 entry_array[1].idx = 1;
3536 init_lsa_String(&entry_array[1].name, "Builtin");
3538 sam->count = num_entries;
3539 sam->entries = entry_array;
3541 *r->out.sam = sam;
3542 *r->out.num_entries = num_entries;
3544 return status;
3547 /*******************************************************************
3548 _samr_OpenAlias
3549 ********************************************************************/
3551 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3552 struct samr_OpenAlias *r)
3554 DOM_SID sid;
3555 POLICY_HND domain_pol = *r->in.domain_handle;
3556 uint32 alias_rid = r->in.rid;
3557 POLICY_HND *alias_pol = r->out.alias_handle;
3558 struct samr_info *info = NULL;
3559 SEC_DESC *psd = NULL;
3560 uint32 acc_granted;
3561 uint32 des_access = r->in.access_mask;
3562 size_t sd_size;
3563 NTSTATUS status;
3564 SE_PRIV se_rights;
3566 /* find the domain policy and get the SID / access bits stored in the domain policy */
3568 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3569 return NT_STATUS_INVALID_HANDLE;
3571 status = access_check_samr_function(acc_granted,
3572 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3573 "_samr_OpenAlias");
3575 if ( !NT_STATUS_IS_OK(status) )
3576 return status;
3578 /* append the alias' RID to it */
3580 if (!sid_append_rid(&sid, alias_rid))
3581 return NT_STATUS_NO_SUCH_ALIAS;
3583 /*check if access can be granted as requested by client. */
3585 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3586 se_map_generic(&des_access,&ali_generic_mapping);
3588 se_priv_copy( &se_rights, &se_add_users );
3591 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3592 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3593 &acc_granted, "_samr_OpenAlias");
3595 if ( !NT_STATUS_IS_OK(status) )
3596 return status;
3599 /* Check we actually have the requested alias */
3600 enum lsa_SidType type;
3601 bool result;
3602 gid_t gid;
3604 become_root();
3605 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3606 unbecome_root();
3608 if (!result || (type != SID_NAME_ALIAS)) {
3609 return NT_STATUS_NO_SUCH_ALIAS;
3612 /* make sure there is a mapping */
3614 if ( !sid_to_gid( &sid, &gid ) ) {
3615 return NT_STATUS_NO_SUCH_ALIAS;
3620 /* associate the alias SID with the new handle. */
3621 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3622 return NT_STATUS_NO_MEMORY;
3624 info->acc_granted = acc_granted;
3626 /* get a (unique) handle. open a policy on it. */
3627 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3628 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3630 return NT_STATUS_OK;
3633 /*******************************************************************
3634 set_user_info_7
3635 ********************************************************************/
3637 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3638 struct samr_UserInfo7 *id7,
3639 struct samu *pwd)
3641 NTSTATUS rc;
3643 if (id7 == NULL) {
3644 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3645 TALLOC_FREE(pwd);
3646 return NT_STATUS_ACCESS_DENIED;
3649 if (!id7->account_name.string) {
3650 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3651 TALLOC_FREE(pwd);
3652 return NT_STATUS_ACCESS_DENIED;
3655 /* check to see if the new username already exists. Note: we can't
3656 reliably lock all backends, so there is potentially the
3657 possibility that a user can be created in between this check and
3658 the rename. The rename should fail, but may not get the
3659 exact same failure status code. I think this is small enough
3660 of a window for this type of operation and the results are
3661 simply that the rename fails with a slightly different status
3662 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3664 rc = can_create(mem_ctx, id7->account_name.string);
3665 if (!NT_STATUS_IS_OK(rc)) {
3666 return rc;
3669 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3671 TALLOC_FREE(pwd);
3672 return rc;
3675 /*******************************************************************
3676 set_user_info_16
3677 ********************************************************************/
3679 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3680 struct samu *pwd)
3682 if (id16 == NULL) {
3683 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3684 TALLOC_FREE(pwd);
3685 return False;
3688 /* FIX ME: check if the value is really changed --metze */
3689 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3690 TALLOC_FREE(pwd);
3691 return False;
3694 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3695 TALLOC_FREE(pwd);
3696 return False;
3699 TALLOC_FREE(pwd);
3701 return True;
3704 /*******************************************************************
3705 set_user_info_18
3706 ********************************************************************/
3708 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3709 struct samu *pwd)
3711 if (id18 == NULL) {
3712 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3713 TALLOC_FREE(pwd);
3714 return False;
3717 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3718 TALLOC_FREE(pwd);
3719 return False;
3721 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3722 TALLOC_FREE(pwd);
3723 return False;
3725 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3726 TALLOC_FREE(pwd);
3727 return False;
3730 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3731 TALLOC_FREE(pwd);
3732 return False;
3735 TALLOC_FREE(pwd);
3736 return True;
3739 /*******************************************************************
3740 set_user_info_20
3741 ********************************************************************/
3743 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3744 struct samu *pwd)
3746 if (id20 == NULL) {
3747 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3748 return False;
3751 copy_id20_to_sam_passwd(pwd, id20);
3753 /* write the change out */
3754 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3755 TALLOC_FREE(pwd);
3756 return False;
3759 TALLOC_FREE(pwd);
3761 return True;
3764 /*******************************************************************
3765 set_user_info_21
3766 ********************************************************************/
3768 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3769 struct samr_UserInfo21 *id21,
3770 struct samu *pwd)
3772 NTSTATUS status;
3774 if (id21 == NULL) {
3775 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3776 return NT_STATUS_INVALID_PARAMETER;
3779 /* we need to separately check for an account rename first */
3781 if (id21->account_name.string &&
3782 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3785 /* check to see if the new username already exists. Note: we can't
3786 reliably lock all backends, so there is potentially the
3787 possibility that a user can be created in between this check and
3788 the rename. The rename should fail, but may not get the
3789 exact same failure status code. I think this is small enough
3790 of a window for this type of operation and the results are
3791 simply that the rename fails with a slightly different status
3792 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3794 status = can_create(mem_ctx, id21->account_name.string);
3795 if (!NT_STATUS_IS_OK(status)) {
3796 return status;
3799 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3801 if (!NT_STATUS_IS_OK(status)) {
3802 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3803 nt_errstr(status)));
3804 TALLOC_FREE(pwd);
3805 return status;
3808 /* set the new username so that later
3809 functions can work on the new account */
3810 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3813 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3816 * The funny part about the previous two calls is
3817 * that pwd still has the password hashes from the
3818 * passdb entry. These have not been updated from
3819 * id21. I don't know if they need to be set. --jerry
3822 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3823 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3824 if ( !NT_STATUS_IS_OK(status) ) {
3825 return status;
3829 /* Don't worry about writing out the user account since the
3830 primary group SID is generated solely from the user's Unix
3831 primary group. */
3833 /* write the change out */
3834 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3835 TALLOC_FREE(pwd);
3836 return status;
3839 TALLOC_FREE(pwd);
3841 return NT_STATUS_OK;
3844 /*******************************************************************
3845 set_user_info_23
3846 ********************************************************************/
3848 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3849 struct samr_UserInfo23 *id23,
3850 struct samu *pwd)
3852 char *plaintext_buf = NULL;
3853 uint32 len = 0;
3854 uint16 acct_ctrl;
3855 NTSTATUS status;
3857 if (id23 == NULL) {
3858 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3859 return NT_STATUS_INVALID_PARAMETER;
3862 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3863 pdb_get_username(pwd)));
3865 acct_ctrl = pdb_get_acct_ctrl(pwd);
3867 if (!decode_pw_buffer(mem_ctx,
3868 id23->password.data,
3869 &plaintext_buf,
3870 &len,
3871 STR_UNICODE)) {
3872 TALLOC_FREE(pwd);
3873 return NT_STATUS_INVALID_PARAMETER;
3876 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3877 TALLOC_FREE(pwd);
3878 return NT_STATUS_ACCESS_DENIED;
3881 copy_id23_to_sam_passwd(pwd, id23);
3883 /* if it's a trust account, don't update /etc/passwd */
3884 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3885 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3886 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3887 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3888 } else {
3889 /* update the UNIX password */
3890 if (lp_unix_password_sync() ) {
3891 struct passwd *passwd;
3892 if (pdb_get_username(pwd) == NULL) {
3893 DEBUG(1, ("chgpasswd: User without name???\n"));
3894 TALLOC_FREE(pwd);
3895 return NT_STATUS_ACCESS_DENIED;
3898 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3899 if (passwd == NULL) {
3900 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3903 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3904 TALLOC_FREE(pwd);
3905 return NT_STATUS_ACCESS_DENIED;
3907 TALLOC_FREE(passwd);
3911 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3913 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3914 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3915 pwd)))) {
3916 TALLOC_FREE(pwd);
3917 return status;
3920 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3921 TALLOC_FREE(pwd);
3922 return status;
3925 TALLOC_FREE(pwd);
3927 return NT_STATUS_OK;
3930 /*******************************************************************
3931 set_user_info_pw
3932 ********************************************************************/
3934 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
3935 int level)
3937 uint32 len = 0;
3938 char *plaintext_buf = NULL;
3939 uint32 acct_ctrl;
3940 time_t last_set_time;
3941 enum pdb_value_state last_set_state;
3943 DEBUG(5, ("Attempting administrator password change for user %s\n",
3944 pdb_get_username(pwd)));
3946 acct_ctrl = pdb_get_acct_ctrl(pwd);
3947 /* we need to know if it's expired, because this is an admin change, not a
3948 user change, so it's still expired when we're done */
3949 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3950 last_set_time = pdb_get_pass_last_set_time(pwd);
3952 if (!decode_pw_buffer(talloc_tos(),
3953 pass,
3954 &plaintext_buf,
3955 &len,
3956 STR_UNICODE)) {
3957 TALLOC_FREE(pwd);
3958 return False;
3961 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3962 TALLOC_FREE(pwd);
3963 return False;
3966 /* if it's a trust account, don't update /etc/passwd */
3967 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3968 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3969 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3970 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3971 } else {
3972 /* update the UNIX password */
3973 if (lp_unix_password_sync()) {
3974 struct passwd *passwd;
3976 if (pdb_get_username(pwd) == NULL) {
3977 DEBUG(1, ("chgpasswd: User without name???\n"));
3978 TALLOC_FREE(pwd);
3979 return False;
3982 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3983 if (passwd == NULL) {
3984 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3987 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3988 TALLOC_FREE(pwd);
3989 return False;
3991 TALLOC_FREE(passwd);
3995 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3998 * A level 25 change does reset the pwdlastset field, a level 24
3999 * change does not. I know this is probably not the full story, but
4000 * it is needed to make XP join LDAP correctly, without it the later
4001 * auth2 check can fail with PWD_MUST_CHANGE.
4003 if (level != 25) {
4005 * restore last set time as this is an admin change, not a
4006 * user pw change
4008 pdb_set_pass_last_set_time (pwd, last_set_time,
4009 last_set_state);
4012 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4014 /* update the SAMBA password */
4015 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4016 TALLOC_FREE(pwd);
4017 return False;
4020 TALLOC_FREE(pwd);
4022 return True;
4025 /*******************************************************************
4026 set_user_info_25
4027 ********************************************************************/
4029 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4030 struct samr_UserInfo25 *id25,
4031 struct samu *pwd)
4033 NTSTATUS status;
4035 if (id25 == NULL) {
4036 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4037 return NT_STATUS_INVALID_PARAMETER;
4040 copy_id25_to_sam_passwd(pwd, id25);
4042 /* write the change out */
4043 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4044 TALLOC_FREE(pwd);
4045 return status;
4049 * We need to "pdb_update_sam_account" before the unix primary group
4050 * is set, because the idealx scripts would also change the
4051 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4052 * the delete explicit / add explicit, which would then fail to find
4053 * the previous primaryGroupSid value.
4056 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4057 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4058 if ( !NT_STATUS_IS_OK(status) ) {
4059 return status;
4063 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
4064 * hereafter! */
4066 return NT_STATUS_OK;
4069 /*******************************************************************
4070 samr_SetUserInfo_internal
4071 ********************************************************************/
4073 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
4074 pipes_struct *p,
4075 struct policy_handle *user_handle,
4076 uint16_t level,
4077 union samr_UserInfo *info)
4079 NTSTATUS status;
4080 struct samu *pwd = NULL;
4081 DOM_SID sid;
4082 POLICY_HND *pol = user_handle;
4083 uint16_t switch_value = level;
4084 uint32_t acc_granted;
4085 uint32_t acc_required;
4086 bool ret;
4087 bool has_enough_rights = False;
4088 uint32_t acb_info;
4089 DISP_INFO *disp_info = NULL;
4091 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4093 /* find the policy handle. open a policy on it. */
4094 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4095 return NT_STATUS_INVALID_HANDLE;
4098 /* This is tricky. A WinXP domain join sets
4099 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4100 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4101 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4102 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4103 we'll use the set from the WinXP join as the basis. */
4105 switch (switch_value) {
4106 case 18:
4107 case 24:
4108 case 25:
4109 case 26:
4110 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4111 break;
4112 default:
4113 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4114 SA_RIGHT_USER_SET_ATTRIBUTES |
4115 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4116 break;
4119 status = access_check_samr_function(acc_granted,
4120 acc_required,
4121 fn_name);
4122 if (!NT_STATUS_IS_OK(status)) {
4123 return status;
4126 DEBUG(5, ("%s: sid:%s, level:%d\n",
4127 fn_name, sid_string_dbg(&sid), switch_value));
4129 if (info == NULL) {
4130 DEBUG(5, ("%s: NULL info level\n", fn_name));
4131 return NT_STATUS_INVALID_INFO_CLASS;
4134 if (!(pwd = samu_new(NULL))) {
4135 return NT_STATUS_NO_MEMORY;
4138 become_root();
4139 ret = pdb_getsampwsid(pwd, &sid);
4140 unbecome_root();
4142 if (!ret) {
4143 TALLOC_FREE(pwd);
4144 return NT_STATUS_NO_SUCH_USER;
4147 /* deal with machine password changes differently from userinfo changes */
4148 /* check to see if we have the sufficient rights */
4150 acb_info = pdb_get_acct_ctrl(pwd);
4151 if (acb_info & ACB_WSTRUST)
4152 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4153 &se_machine_account);
4154 else if (acb_info & ACB_NORMAL)
4155 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4156 &se_add_users);
4157 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4158 if (lp_enable_privileges()) {
4159 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4160 DOMAIN_GROUP_RID_ADMINS);
4164 DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4165 fn_name,
4166 uidtoname(p->pipe_user.ut.uid),
4167 has_enough_rights ? "" : " not"));
4169 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4171 if (has_enough_rights) {
4172 become_root();
4175 /* ok! user info levels (lots: see MSDEV help), off we go... */
4177 switch (switch_value) {
4179 case 7:
4180 status = set_user_info_7(p->mem_ctx,
4181 &info->info7, pwd);
4182 break;
4184 case 16:
4185 if (!set_user_info_16(&info->info16, pwd)) {
4186 status = NT_STATUS_ACCESS_DENIED;
4188 break;
4190 case 18:
4191 /* Used by AS/U JRA. */
4192 if (!set_user_info_18(&info->info18, pwd)) {
4193 status = NT_STATUS_ACCESS_DENIED;
4195 break;
4197 case 20:
4198 if (!set_user_info_20(&info->info20, pwd)) {
4199 status = NT_STATUS_ACCESS_DENIED;
4201 break;
4203 case 21:
4204 status = set_user_info_21(p->mem_ctx,
4205 &info->info21, pwd);
4206 break;
4208 case 23:
4209 if (!p->session_key.length) {
4210 status = NT_STATUS_NO_USER_SESSION_KEY;
4212 SamOEMhashBlob(info->info23.password.data, 516,
4213 &p->session_key);
4215 dump_data(100, info->info23.password.data, 516);
4217 status = set_user_info_23(p->mem_ctx,
4218 &info->info23, pwd);
4219 break;
4221 case 24:
4222 if (!p->session_key.length) {
4223 status = NT_STATUS_NO_USER_SESSION_KEY;
4225 SamOEMhashBlob(info->info24.password.data,
4226 516,
4227 &p->session_key);
4229 dump_data(100, info->info24.password.data, 516);
4231 if (!set_user_info_pw(info->info24.password.data, pwd,
4232 switch_value)) {
4233 status = NT_STATUS_ACCESS_DENIED;
4235 break;
4237 case 25:
4238 if (!p->session_key.length) {
4239 status = NT_STATUS_NO_USER_SESSION_KEY;
4241 encode_or_decode_arc4_passwd_buffer(info->info25.password.data,
4242 &p->session_key);
4244 dump_data(100, info->info25.password.data, 532);
4246 status = set_user_info_25(p->mem_ctx,
4247 &info->info25, pwd);
4248 if (!NT_STATUS_IS_OK(status)) {
4249 goto done;
4251 if (!set_user_info_pw(info->info25.password.data, pwd,
4252 switch_value)) {
4253 status = NT_STATUS_ACCESS_DENIED;
4255 break;
4257 case 26:
4258 if (!p->session_key.length) {
4259 status = NT_STATUS_NO_USER_SESSION_KEY;
4261 encode_or_decode_arc4_passwd_buffer(info->info26.password.data,
4262 &p->session_key);
4264 dump_data(100, info->info26.password.data, 516);
4266 if (!set_user_info_pw(info->info26.password.data, pwd,
4267 switch_value)) {
4268 status = NT_STATUS_ACCESS_DENIED;
4270 break;
4272 default:
4273 status = NT_STATUS_INVALID_INFO_CLASS;
4276 done:
4278 if (has_enough_rights) {
4279 unbecome_root();
4282 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4284 if (NT_STATUS_IS_OK(status)) {
4285 force_flush_samr_cache(disp_info);
4288 return status;
4291 /*******************************************************************
4292 _samr_SetUserInfo
4293 ********************************************************************/
4295 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4296 struct samr_SetUserInfo *r)
4298 return samr_SetUserInfo_internal("_samr_SetUserInfo",
4300 r->in.user_handle,
4301 r->in.level,
4302 r->in.info);
4305 /*******************************************************************
4306 _samr_SetUserInfo2
4307 ********************************************************************/
4309 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4310 struct samr_SetUserInfo2 *r)
4312 return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4314 r->in.user_handle,
4315 r->in.level,
4316 r->in.info);
4319 /*********************************************************************
4320 _samr_GetAliasMembership
4321 *********************************************************************/
4323 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4324 struct samr_GetAliasMembership *r)
4326 size_t num_alias_rids;
4327 uint32 *alias_rids;
4328 struct samr_info *info = NULL;
4329 size_t i;
4331 NTSTATUS ntstatus1;
4332 NTSTATUS ntstatus2;
4334 DOM_SID *members;
4336 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4338 /* find the policy handle. open a policy on it. */
4339 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4340 return NT_STATUS_INVALID_HANDLE;
4342 ntstatus1 = access_check_samr_function(info->acc_granted,
4343 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4344 "_samr_GetAliasMembership");
4345 ntstatus2 = access_check_samr_function(info->acc_granted,
4346 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4347 "_samr_GetAliasMembership");
4349 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4350 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4351 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4352 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4356 if (!sid_check_is_domain(&info->sid) &&
4357 !sid_check_is_builtin(&info->sid))
4358 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4360 if (r->in.sids->num_sids) {
4361 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4363 if (members == NULL)
4364 return NT_STATUS_NO_MEMORY;
4365 } else {
4366 members = NULL;
4369 for (i=0; i<r->in.sids->num_sids; i++)
4370 sid_copy(&members[i], r->in.sids->sids[i].sid);
4372 alias_rids = NULL;
4373 num_alias_rids = 0;
4375 become_root();
4376 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4377 r->in.sids->num_sids,
4378 &alias_rids, &num_alias_rids);
4379 unbecome_root();
4381 if (!NT_STATUS_IS_OK(ntstatus1)) {
4382 return ntstatus1;
4385 r->out.rids->count = num_alias_rids;
4386 r->out.rids->ids = alias_rids;
4388 return NT_STATUS_OK;
4391 /*********************************************************************
4392 _samr_GetMembersInAlias
4393 *********************************************************************/
4395 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4396 struct samr_GetMembersInAlias *r)
4398 NTSTATUS status;
4399 size_t i;
4400 size_t num_sids = 0;
4401 struct lsa_SidPtr *sids = NULL;
4402 DOM_SID *pdb_sids = NULL;
4404 DOM_SID alias_sid;
4406 uint32 acc_granted;
4408 /* find the policy handle. open a policy on it. */
4409 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4410 return NT_STATUS_INVALID_HANDLE;
4412 status = access_check_samr_function(acc_granted,
4413 SA_RIGHT_ALIAS_GET_MEMBERS,
4414 "_samr_GetMembersInAlias");
4415 if (!NT_STATUS_IS_OK(status)) {
4416 return status;
4419 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4421 become_root();
4422 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4423 unbecome_root();
4425 if (!NT_STATUS_IS_OK(status)) {
4426 return status;
4429 if (num_sids) {
4430 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4431 if (sids == NULL) {
4432 TALLOC_FREE(pdb_sids);
4433 return NT_STATUS_NO_MEMORY;
4437 for (i = 0; i < num_sids; i++) {
4438 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4439 if (!sids[i].sid) {
4440 TALLOC_FREE(pdb_sids);
4441 return NT_STATUS_NO_MEMORY;
4445 r->out.sids->num_sids = num_sids;
4446 r->out.sids->sids = sids;
4448 TALLOC_FREE(pdb_sids);
4450 return NT_STATUS_OK;
4453 /*********************************************************************
4454 _samr_QueryGroupMember
4455 *********************************************************************/
4457 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4458 struct samr_QueryGroupMember *r)
4460 DOM_SID group_sid;
4461 size_t i, num_members;
4463 uint32 *rid=NULL;
4464 uint32 *attr=NULL;
4466 uint32 acc_granted;
4468 NTSTATUS status;
4469 struct samr_RidTypeArray *rids = NULL;
4471 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4472 if (!rids) {
4473 return NT_STATUS_NO_MEMORY;
4476 /* find the policy handle. open a policy on it. */
4477 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4478 return NT_STATUS_INVALID_HANDLE;
4480 status = access_check_samr_function(acc_granted,
4481 SA_RIGHT_GROUP_GET_MEMBERS,
4482 "_samr_QueryGroupMember");
4483 if (!NT_STATUS_IS_OK(status)) {
4484 return status;
4487 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4489 if (!sid_check_is_in_our_domain(&group_sid)) {
4490 DEBUG(3, ("sid %s is not in our domain\n",
4491 sid_string_dbg(&group_sid)));
4492 return NT_STATUS_NO_SUCH_GROUP;
4495 DEBUG(10, ("lookup on Domain SID\n"));
4497 become_root();
4498 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4499 &rid, &num_members);
4500 unbecome_root();
4502 if (!NT_STATUS_IS_OK(status))
4503 return status;
4505 if (num_members) {
4506 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4507 if (attr == NULL) {
4508 return NT_STATUS_NO_MEMORY;
4510 } else {
4511 attr = NULL;
4514 for (i=0; i<num_members; i++)
4515 attr[i] = SID_NAME_USER;
4517 rids->count = num_members;
4518 rids->types = attr;
4519 rids->rids = rid;
4521 *r->out.rids = rids;
4523 return NT_STATUS_OK;
4526 /*********************************************************************
4527 _samr_AddAliasMember
4528 *********************************************************************/
4530 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4531 struct samr_AddAliasMember *r)
4533 DOM_SID alias_sid;
4534 uint32 acc_granted;
4535 SE_PRIV se_rights;
4536 bool can_add_accounts;
4537 NTSTATUS status;
4538 DISP_INFO *disp_info = NULL;
4540 /* Find the policy handle. Open a policy on it. */
4541 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4542 return NT_STATUS_INVALID_HANDLE;
4544 status = access_check_samr_function(acc_granted,
4545 SA_RIGHT_ALIAS_ADD_MEMBER,
4546 "_samr_AddAliasMember");
4547 if (!NT_STATUS_IS_OK(status)) {
4548 return status;
4551 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4553 se_priv_copy( &se_rights, &se_add_users );
4554 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4556 /******** BEGIN SeAddUsers BLOCK *********/
4558 if ( can_add_accounts )
4559 become_root();
4561 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4563 if ( can_add_accounts )
4564 unbecome_root();
4566 /******** END SeAddUsers BLOCK *********/
4568 if (NT_STATUS_IS_OK(status)) {
4569 force_flush_samr_cache(disp_info);
4572 return status;
4575 /*********************************************************************
4576 _samr_DeleteAliasMember
4577 *********************************************************************/
4579 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4580 struct samr_DeleteAliasMember *r)
4582 DOM_SID alias_sid;
4583 uint32 acc_granted;
4584 SE_PRIV se_rights;
4585 bool can_add_accounts;
4586 NTSTATUS status;
4587 DISP_INFO *disp_info = NULL;
4589 /* Find the policy handle. Open a policy on it. */
4590 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4591 return NT_STATUS_INVALID_HANDLE;
4593 status = access_check_samr_function(acc_granted,
4594 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4595 "_samr_DeleteAliasMember");
4596 if (!NT_STATUS_IS_OK(status)) {
4597 return status;
4600 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4601 sid_string_dbg(&alias_sid)));
4603 se_priv_copy( &se_rights, &se_add_users );
4604 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4606 /******** BEGIN SeAddUsers BLOCK *********/
4608 if ( can_add_accounts )
4609 become_root();
4611 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4613 if ( can_add_accounts )
4614 unbecome_root();
4616 /******** END SeAddUsers BLOCK *********/
4618 if (NT_STATUS_IS_OK(status)) {
4619 force_flush_samr_cache(disp_info);
4622 return status;
4625 /*********************************************************************
4626 _samr_AddGroupMember
4627 *********************************************************************/
4629 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4630 struct samr_AddGroupMember *r)
4632 NTSTATUS status;
4633 DOM_SID group_sid;
4634 uint32 group_rid;
4635 uint32 acc_granted;
4636 SE_PRIV se_rights;
4637 bool can_add_accounts;
4638 DISP_INFO *disp_info = NULL;
4640 /* Find the policy handle. Open a policy on it. */
4641 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4642 return NT_STATUS_INVALID_HANDLE;
4644 status = access_check_samr_function(acc_granted,
4645 SA_RIGHT_GROUP_ADD_MEMBER,
4646 "_samr_AddGroupMember");
4647 if (!NT_STATUS_IS_OK(status)) {
4648 return status;
4651 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4653 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4654 &group_rid)) {
4655 return NT_STATUS_INVALID_HANDLE;
4658 se_priv_copy( &se_rights, &se_add_users );
4659 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4661 /******** BEGIN SeAddUsers BLOCK *********/
4663 if ( can_add_accounts )
4664 become_root();
4666 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4668 if ( can_add_accounts )
4669 unbecome_root();
4671 /******** END SeAddUsers BLOCK *********/
4673 force_flush_samr_cache(disp_info);
4675 return status;
4678 /*********************************************************************
4679 _samr_DeleteGroupMember
4680 *********************************************************************/
4682 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4683 struct samr_DeleteGroupMember *r)
4686 NTSTATUS status;
4687 DOM_SID group_sid;
4688 uint32 group_rid;
4689 uint32 acc_granted;
4690 SE_PRIV se_rights;
4691 bool can_add_accounts;
4692 DISP_INFO *disp_info = NULL;
4695 * delete the group member named r->in.rid
4696 * who is a member of the sid associated with the handle
4697 * the rid is a user's rid as the group is a domain group.
4700 /* Find the policy handle. Open a policy on it. */
4701 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4702 return NT_STATUS_INVALID_HANDLE;
4704 status = access_check_samr_function(acc_granted,
4705 SA_RIGHT_GROUP_REMOVE_MEMBER,
4706 "_samr_DeleteGroupMember");
4707 if (!NT_STATUS_IS_OK(status)) {
4708 return status;
4711 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4712 &group_rid)) {
4713 return NT_STATUS_INVALID_HANDLE;
4716 se_priv_copy( &se_rights, &se_add_users );
4717 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4719 /******** BEGIN SeAddUsers BLOCK *********/
4721 if ( can_add_accounts )
4722 become_root();
4724 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4726 if ( can_add_accounts )
4727 unbecome_root();
4729 /******** END SeAddUsers BLOCK *********/
4731 force_flush_samr_cache(disp_info);
4733 return status;
4736 /*********************************************************************
4737 _samr_DeleteUser
4738 *********************************************************************/
4740 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4741 struct samr_DeleteUser *r)
4743 NTSTATUS status;
4744 DOM_SID user_sid;
4745 struct samu *sam_pass=NULL;
4746 uint32 acc_granted;
4747 bool can_add_accounts;
4748 uint32 acb_info;
4749 DISP_INFO *disp_info = NULL;
4750 bool ret;
4752 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4754 /* Find the policy handle. Open a policy on it. */
4755 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4756 return NT_STATUS_INVALID_HANDLE;
4758 status = access_check_samr_function(acc_granted,
4759 STD_RIGHT_DELETE_ACCESS,
4760 "_samr_DeleteUser");
4761 if (!NT_STATUS_IS_OK(status)) {
4762 return status;
4765 if (!sid_check_is_in_our_domain(&user_sid))
4766 return NT_STATUS_CANNOT_DELETE;
4768 /* check if the user exists before trying to delete */
4769 if ( !(sam_pass = samu_new( NULL )) ) {
4770 return NT_STATUS_NO_MEMORY;
4773 become_root();
4774 ret = pdb_getsampwsid(sam_pass, &user_sid);
4775 unbecome_root();
4777 if( !ret ) {
4778 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4779 sid_string_dbg(&user_sid)));
4780 TALLOC_FREE(sam_pass);
4781 return NT_STATUS_NO_SUCH_USER;
4784 acb_info = pdb_get_acct_ctrl(sam_pass);
4786 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4787 if ( acb_info & ACB_WSTRUST ) {
4788 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4789 } else {
4790 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4793 /******** BEGIN SeAddUsers BLOCK *********/
4795 if ( can_add_accounts )
4796 become_root();
4798 status = pdb_delete_user(p->mem_ctx, sam_pass);
4800 if ( can_add_accounts )
4801 unbecome_root();
4803 /******** END SeAddUsers BLOCK *********/
4805 if ( !NT_STATUS_IS_OK(status) ) {
4806 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4807 "user %s: %s.\n", pdb_get_username(sam_pass),
4808 nt_errstr(status)));
4809 TALLOC_FREE(sam_pass);
4810 return status;
4814 TALLOC_FREE(sam_pass);
4816 if (!close_policy_hnd(p, r->in.user_handle))
4817 return NT_STATUS_OBJECT_NAME_INVALID;
4819 force_flush_samr_cache(disp_info);
4821 return NT_STATUS_OK;
4824 /*********************************************************************
4825 _samr_DeleteDomainGroup
4826 *********************************************************************/
4828 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4829 struct samr_DeleteDomainGroup *r)
4831 NTSTATUS status;
4832 DOM_SID group_sid;
4833 uint32 group_rid;
4834 uint32 acc_granted;
4835 SE_PRIV se_rights;
4836 bool can_add_accounts;
4837 DISP_INFO *disp_info = NULL;
4839 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4841 /* Find the policy handle. Open a policy on it. */
4842 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4843 return NT_STATUS_INVALID_HANDLE;
4845 status = access_check_samr_function(acc_granted,
4846 STD_RIGHT_DELETE_ACCESS,
4847 "_samr_DeleteDomainGroup");
4848 if (!NT_STATUS_IS_OK(status)) {
4849 return status;
4852 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4854 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4855 &group_rid)) {
4856 return NT_STATUS_NO_SUCH_GROUP;
4859 se_priv_copy( &se_rights, &se_add_users );
4860 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4862 /******** BEGIN SeAddUsers BLOCK *********/
4864 if ( can_add_accounts )
4865 become_root();
4867 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4869 if ( can_add_accounts )
4870 unbecome_root();
4872 /******** END SeAddUsers BLOCK *********/
4874 if ( !NT_STATUS_IS_OK(status) ) {
4875 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4876 "entry for group %s: %s\n",
4877 sid_string_dbg(&group_sid),
4878 nt_errstr(status)));
4879 return status;
4882 if (!close_policy_hnd(p, r->in.group_handle))
4883 return NT_STATUS_OBJECT_NAME_INVALID;
4885 force_flush_samr_cache(disp_info);
4887 return NT_STATUS_OK;
4890 /*********************************************************************
4891 _samr_DeleteDomAlias
4892 *********************************************************************/
4894 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4895 struct samr_DeleteDomAlias *r)
4897 DOM_SID alias_sid;
4898 uint32 acc_granted;
4899 SE_PRIV se_rights;
4900 bool can_add_accounts;
4901 NTSTATUS status;
4902 DISP_INFO *disp_info = NULL;
4904 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4906 /* Find the policy handle. Open a policy on it. */
4907 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4908 return NT_STATUS_INVALID_HANDLE;
4910 /* copy the handle to the outgoing reply */
4912 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4914 status = access_check_samr_function(acc_granted,
4915 STD_RIGHT_DELETE_ACCESS,
4916 "_samr_DeleteDomAlias");
4917 if (!NT_STATUS_IS_OK(status)) {
4918 return status;
4921 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4923 /* Don't let Windows delete builtin groups */
4925 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4926 return NT_STATUS_SPECIAL_ACCOUNT;
4929 if (!sid_check_is_in_our_domain(&alias_sid))
4930 return NT_STATUS_NO_SUCH_ALIAS;
4932 DEBUG(10, ("lookup on Local SID\n"));
4934 se_priv_copy( &se_rights, &se_add_users );
4935 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4937 /******** BEGIN SeAddUsers BLOCK *********/
4939 if ( can_add_accounts )
4940 become_root();
4942 /* Have passdb delete the alias */
4943 status = pdb_delete_alias(&alias_sid);
4945 if ( can_add_accounts )
4946 unbecome_root();
4948 /******** END SeAddUsers BLOCK *********/
4950 if ( !NT_STATUS_IS_OK(status))
4951 return status;
4953 if (!close_policy_hnd(p, r->in.alias_handle))
4954 return NT_STATUS_OBJECT_NAME_INVALID;
4956 force_flush_samr_cache(disp_info);
4958 return NT_STATUS_OK;
4961 /*********************************************************************
4962 _samr_CreateDomainGroup
4963 *********************************************************************/
4965 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4966 struct samr_CreateDomainGroup *r)
4969 NTSTATUS status;
4970 DOM_SID dom_sid;
4971 DOM_SID info_sid;
4972 const char *name;
4973 struct samr_info *info;
4974 uint32 acc_granted;
4975 SE_PRIV se_rights;
4976 bool can_add_accounts;
4977 DISP_INFO *disp_info = NULL;
4979 /* Find the policy handle. Open a policy on it. */
4980 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4981 return NT_STATUS_INVALID_HANDLE;
4983 status = access_check_samr_function(acc_granted,
4984 SA_RIGHT_DOMAIN_CREATE_GROUP,
4985 "_samr_CreateDomainGroup");
4986 if (!NT_STATUS_IS_OK(status)) {
4987 return status;
4990 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4991 return NT_STATUS_ACCESS_DENIED;
4993 name = r->in.name->string;
4994 if (name == NULL) {
4995 return NT_STATUS_NO_MEMORY;
4998 status = can_create(p->mem_ctx, name);
4999 if (!NT_STATUS_IS_OK(status)) {
5000 return status;
5003 se_priv_copy( &se_rights, &se_add_users );
5004 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5006 /******** BEGIN SeAddUsers BLOCK *********/
5008 if ( can_add_accounts )
5009 become_root();
5011 /* check that we successfully create the UNIX group */
5013 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5015 if ( can_add_accounts )
5016 unbecome_root();
5018 /******** END SeAddUsers BLOCK *********/
5020 /* check if we should bail out here */
5022 if ( !NT_STATUS_IS_OK(status) )
5023 return status;
5025 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5027 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5028 return NT_STATUS_NO_MEMORY;
5030 /* they created it; let the user do what he wants with it */
5032 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5034 /* get a (unique) handle. open a policy on it. */
5035 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5036 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5038 force_flush_samr_cache(disp_info);
5040 return NT_STATUS_OK;
5043 /*********************************************************************
5044 _samr_CreateDomAlias
5045 *********************************************************************/
5047 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5048 struct samr_CreateDomAlias *r)
5050 DOM_SID dom_sid;
5051 DOM_SID info_sid;
5052 const char *name = NULL;
5053 struct samr_info *info;
5054 uint32 acc_granted;
5055 gid_t gid;
5056 NTSTATUS result;
5057 SE_PRIV se_rights;
5058 bool can_add_accounts;
5059 DISP_INFO *disp_info = NULL;
5061 /* Find the policy handle. Open a policy on it. */
5062 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5063 return NT_STATUS_INVALID_HANDLE;
5065 result = access_check_samr_function(acc_granted,
5066 SA_RIGHT_DOMAIN_CREATE_ALIAS,
5067 "_samr_CreateDomAlias");
5068 if (!NT_STATUS_IS_OK(result)) {
5069 return result;
5072 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5073 return NT_STATUS_ACCESS_DENIED;
5075 name = r->in.alias_name->string;
5077 se_priv_copy( &se_rights, &se_add_users );
5078 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5080 result = can_create(p->mem_ctx, name);
5081 if (!NT_STATUS_IS_OK(result)) {
5082 return result;
5085 /******** BEGIN SeAddUsers BLOCK *********/
5087 if ( can_add_accounts )
5088 become_root();
5090 /* Have passdb create the alias */
5091 result = pdb_create_alias(name, r->out.rid);
5093 if ( can_add_accounts )
5094 unbecome_root();
5096 /******** END SeAddUsers BLOCK *********/
5098 if (!NT_STATUS_IS_OK(result)) {
5099 DEBUG(10, ("pdb_create_alias failed: %s\n",
5100 nt_errstr(result)));
5101 return result;
5104 sid_copy(&info_sid, get_global_sam_sid());
5105 sid_append_rid(&info_sid, *r->out.rid);
5107 if (!sid_to_gid(&info_sid, &gid)) {
5108 DEBUG(10, ("Could not find alias just created\n"));
5109 return NT_STATUS_ACCESS_DENIED;
5112 /* check if the group has been successfully created */
5113 if ( getgrgid(gid) == NULL ) {
5114 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5115 gid));
5116 return NT_STATUS_ACCESS_DENIED;
5119 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5120 return NT_STATUS_NO_MEMORY;
5122 /* they created it; let the user do what he wants with it */
5124 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5126 /* get a (unique) handle. open a policy on it. */
5127 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5128 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5130 force_flush_samr_cache(disp_info);
5132 return NT_STATUS_OK;
5135 /*********************************************************************
5136 _samr_QueryGroupInfo
5137 *********************************************************************/
5139 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5140 struct samr_QueryGroupInfo *r)
5142 NTSTATUS status;
5143 DOM_SID group_sid;
5144 GROUP_MAP map;
5145 union samr_GroupInfo *info = NULL;
5146 uint32 acc_granted;
5147 bool ret;
5148 uint32_t attributes = SE_GROUP_MANDATORY |
5149 SE_GROUP_ENABLED_BY_DEFAULT |
5150 SE_GROUP_ENABLED;
5151 const char *group_name = NULL;
5152 const char *group_description = NULL;
5154 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5155 return NT_STATUS_INVALID_HANDLE;
5157 status = access_check_samr_function(acc_granted,
5158 SA_RIGHT_GROUP_LOOKUP_INFO,
5159 "_samr_QueryGroupInfo");
5160 if (!NT_STATUS_IS_OK(status)) {
5161 return status;
5164 become_root();
5165 ret = get_domain_group_from_sid(group_sid, &map);
5166 unbecome_root();
5167 if (!ret)
5168 return NT_STATUS_INVALID_HANDLE;
5170 /* FIXME: map contains fstrings */
5171 group_name = talloc_strdup(r, map.nt_name);
5172 group_description = talloc_strdup(r, map.comment);
5174 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5175 if (!info) {
5176 return NT_STATUS_NO_MEMORY;
5179 switch (r->in.level) {
5180 case 1: {
5181 uint32 *members;
5182 size_t num_members;
5184 become_root();
5185 status = pdb_enum_group_members(
5186 p->mem_ctx, &group_sid, &members, &num_members);
5187 unbecome_root();
5189 if (!NT_STATUS_IS_OK(status)) {
5190 return status;
5193 init_samr_group_info1(&info->all,
5194 group_name,
5195 attributes,
5196 num_members,
5197 group_description);
5198 break;
5200 case 2:
5201 init_samr_group_info2(&info->name,
5202 group_name);
5203 break;
5204 case 3:
5205 init_samr_group_info3(&info->attributes,
5206 attributes);
5207 break;
5208 case 4:
5209 init_samr_group_info4(&info->description,
5210 group_description);
5211 break;
5212 case 5: {
5214 uint32 *members;
5215 size_t num_members;
5219 become_root();
5220 status = pdb_enum_group_members(
5221 p->mem_ctx, &group_sid, &members, &num_members);
5222 unbecome_root();
5224 if (!NT_STATUS_IS_OK(status)) {
5225 return status;
5228 init_samr_group_info5(&info->all2,
5229 group_name,
5230 attributes,
5231 0, /* num_members - in w2k3 this is always 0 */
5232 group_description);
5234 break;
5236 default:
5237 return NT_STATUS_INVALID_INFO_CLASS;
5240 *r->out.info = info;
5242 return NT_STATUS_OK;
5245 /*********************************************************************
5246 _samr_SetGroupInfo
5247 *********************************************************************/
5249 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5250 struct samr_SetGroupInfo *r)
5252 DOM_SID group_sid;
5253 GROUP_MAP map;
5254 uint32 acc_granted;
5255 NTSTATUS status;
5256 bool ret;
5257 bool can_mod_accounts;
5258 DISP_INFO *disp_info = NULL;
5260 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5261 return NT_STATUS_INVALID_HANDLE;
5263 status = access_check_samr_function(acc_granted,
5264 SA_RIGHT_GROUP_SET_INFO,
5265 "_samr_SetGroupInfo");
5266 if (!NT_STATUS_IS_OK(status)) {
5267 return status;
5270 become_root();
5271 ret = get_domain_group_from_sid(group_sid, &map);
5272 unbecome_root();
5273 if (!ret)
5274 return NT_STATUS_NO_SUCH_GROUP;
5276 switch (r->in.level) {
5277 case 1:
5278 fstrcpy(map.comment, r->in.info->all.description.string);
5279 break;
5280 case 4:
5281 fstrcpy(map.comment, r->in.info->description.string);
5282 break;
5283 default:
5284 return NT_STATUS_INVALID_INFO_CLASS;
5287 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5289 /******** BEGIN SeAddUsers BLOCK *********/
5291 if ( can_mod_accounts )
5292 become_root();
5294 status = pdb_update_group_mapping_entry(&map);
5296 if ( can_mod_accounts )
5297 unbecome_root();
5299 /******** End SeAddUsers BLOCK *********/
5301 if (NT_STATUS_IS_OK(status)) {
5302 force_flush_samr_cache(disp_info);
5305 return status;
5308 /*********************************************************************
5309 _samr_SetAliasInfo
5310 *********************************************************************/
5312 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5313 struct samr_SetAliasInfo *r)
5315 DOM_SID group_sid;
5316 struct acct_info info;
5317 uint32 acc_granted;
5318 bool can_mod_accounts;
5319 NTSTATUS status;
5320 DISP_INFO *disp_info = NULL;
5322 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5323 return NT_STATUS_INVALID_HANDLE;
5325 status = access_check_samr_function(acc_granted,
5326 SA_RIGHT_ALIAS_SET_INFO,
5327 "_samr_SetAliasInfo");
5328 if (!NT_STATUS_IS_OK(status)) {
5329 return status;
5332 /* get the current group information */
5334 become_root();
5335 status = pdb_get_aliasinfo( &group_sid, &info );
5336 unbecome_root();
5338 if ( !NT_STATUS_IS_OK(status))
5339 return status;
5341 switch (r->in.level) {
5342 case ALIASINFONAME:
5344 fstring group_name;
5346 /* We currently do not support renaming groups in the
5347 the BUILTIN domain. Refer to util_builtin.c to understand
5348 why. The eventually needs to be fixed to be like Windows
5349 where you can rename builtin groups, just not delete them */
5351 if ( sid_check_is_in_builtin( &group_sid ) ) {
5352 return NT_STATUS_SPECIAL_ACCOUNT;
5355 /* There has to be a valid name (and it has to be different) */
5357 if ( !r->in.info->name.string )
5358 return NT_STATUS_INVALID_PARAMETER;
5360 /* If the name is the same just reply "ok". Yes this
5361 doesn't allow you to change the case of a group name. */
5363 if ( strequal( r->in.info->name.string, info.acct_name ) )
5364 return NT_STATUS_OK;
5366 fstrcpy( info.acct_name, r->in.info->name.string);
5368 /* make sure the name doesn't already exist as a user
5369 or local group */
5371 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5372 status = can_create( p->mem_ctx, group_name );
5373 if ( !NT_STATUS_IS_OK( status ) )
5374 return status;
5375 break;
5377 case ALIASINFODESCRIPTION:
5378 if (r->in.info->description.string) {
5379 fstrcpy(info.acct_desc,
5380 r->in.info->description.string);
5381 } else {
5382 fstrcpy( info.acct_desc, "" );
5384 break;
5385 default:
5386 return NT_STATUS_INVALID_INFO_CLASS;
5389 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5391 /******** BEGIN SeAddUsers BLOCK *********/
5393 if ( can_mod_accounts )
5394 become_root();
5396 status = pdb_set_aliasinfo( &group_sid, &info );
5398 if ( can_mod_accounts )
5399 unbecome_root();
5401 /******** End SeAddUsers BLOCK *********/
5403 if (NT_STATUS_IS_OK(status))
5404 force_flush_samr_cache(disp_info);
5406 return status;
5409 /****************************************************************
5410 _samr_GetDomPwInfo
5411 ****************************************************************/
5413 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5414 struct samr_GetDomPwInfo *r)
5416 uint32_t min_password_length = 0;
5417 uint32_t password_properties = 0;
5419 /* Perform access check. Since this rpc does not require a
5420 policy handle it will not be caught by the access checks on
5421 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5423 if (!pipe_access_check(p)) {
5424 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5425 return NT_STATUS_ACCESS_DENIED;
5428 become_root();
5429 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5430 &min_password_length);
5431 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5432 &password_properties);
5433 unbecome_root();
5435 if (lp_check_password_script() && *lp_check_password_script()) {
5436 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5439 r->out.info->min_password_length = min_password_length;
5440 r->out.info->password_properties = password_properties;
5442 return NT_STATUS_OK;
5445 /*********************************************************************
5446 _samr_OpenGroup
5447 *********************************************************************/
5449 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5450 struct samr_OpenGroup *r)
5453 DOM_SID sid;
5454 DOM_SID info_sid;
5455 GROUP_MAP map;
5456 struct samr_info *info;
5457 SEC_DESC *psd = NULL;
5458 uint32 acc_granted;
5459 uint32 des_access = r->in.access_mask;
5460 size_t sd_size;
5461 NTSTATUS status;
5462 fstring sid_string;
5463 bool ret;
5464 SE_PRIV se_rights;
5466 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5467 return NT_STATUS_INVALID_HANDLE;
5469 status = access_check_samr_function(acc_granted,
5470 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5471 "_samr_OpenGroup");
5473 if ( !NT_STATUS_IS_OK(status) )
5474 return status;
5476 /*check if access can be granted as requested by client. */
5477 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5478 se_map_generic(&des_access,&grp_generic_mapping);
5480 se_priv_copy( &se_rights, &se_add_users );
5482 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5483 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5484 &acc_granted, "_samr_OpenGroup");
5486 if ( !NT_STATUS_IS_OK(status) )
5487 return status;
5489 /* this should not be hard-coded like this */
5491 if (!sid_equal(&sid, get_global_sam_sid()))
5492 return NT_STATUS_ACCESS_DENIED;
5494 sid_copy(&info_sid, get_global_sam_sid());
5495 sid_append_rid(&info_sid, r->in.rid);
5496 sid_to_fstring(sid_string, &info_sid);
5498 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5499 return NT_STATUS_NO_MEMORY;
5501 info->acc_granted = acc_granted;
5503 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5505 /* check if that group really exists */
5506 become_root();
5507 ret = get_domain_group_from_sid(info->sid, &map);
5508 unbecome_root();
5509 if (!ret)
5510 return NT_STATUS_NO_SUCH_GROUP;
5512 /* get a (unique) handle. open a policy on it. */
5513 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5514 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5516 return NT_STATUS_OK;
5519 /*********************************************************************
5520 _samr_RemoveMemberFromForeignDomain
5521 *********************************************************************/
5523 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5524 struct samr_RemoveMemberFromForeignDomain *r)
5526 DOM_SID delete_sid, domain_sid;
5527 uint32 acc_granted;
5528 NTSTATUS result;
5529 DISP_INFO *disp_info = NULL;
5531 sid_copy( &delete_sid, r->in.sid );
5533 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5534 sid_string_dbg(&delete_sid)));
5536 /* Find the policy handle. Open a policy on it. */
5538 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5539 &acc_granted, &disp_info))
5540 return NT_STATUS_INVALID_HANDLE;
5542 result = access_check_samr_function(acc_granted,
5543 STD_RIGHT_DELETE_ACCESS,
5544 "_samr_RemoveMemberFromForeignDomain");
5546 if (!NT_STATUS_IS_OK(result))
5547 return result;
5549 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5550 sid_string_dbg(&domain_sid)));
5552 /* we can only delete a user from a group since we don't have
5553 nested groups anyways. So in the latter case, just say OK */
5555 /* TODO: The above comment nowadays is bogus. Since we have nested
5556 * groups now, and aliases members are never reported out of the unix
5557 * group membership, the "just say OK" makes this call a no-op. For
5558 * us. This needs fixing however. */
5560 /* I've only ever seen this in the wild when deleting a user from
5561 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5562 * is the user about to be deleted. I very much suspect this is the
5563 * only application of this call. To verify this, let people report
5564 * other cases. */
5566 if (!sid_check_is_builtin(&domain_sid)) {
5567 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5568 "global_sam_sid() = %s\n",
5569 sid_string_dbg(&domain_sid),
5570 sid_string_dbg(get_global_sam_sid())));
5571 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5572 return NT_STATUS_OK;
5575 force_flush_samr_cache(disp_info);
5577 result = NT_STATUS_OK;
5579 return result;
5582 /*******************************************************************
5583 _samr_QueryDomainInfo2
5584 ********************************************************************/
5586 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5587 struct samr_QueryDomainInfo2 *r)
5589 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5591 r->in.domain_handle,
5592 r->in.level,
5593 r->out.info);
5596 /*******************************************************************
5597 _samr_SetDomainInfo
5598 ********************************************************************/
5600 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5601 struct samr_SetDomainInfo *r)
5603 time_t u_expire, u_min_age;
5604 time_t u_logout;
5605 time_t u_lock_duration, u_reset_time;
5607 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5609 /* find the policy handle. open a policy on it. */
5610 if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5611 return NT_STATUS_INVALID_HANDLE;
5613 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5615 switch (r->in.level) {
5616 case 0x01:
5617 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5618 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5619 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5620 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5621 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5622 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5623 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5624 break;
5625 case 0x02:
5626 break;
5627 case 0x03:
5628 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5629 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5630 break;
5631 case 0x05:
5632 break;
5633 case 0x06:
5634 break;
5635 case 0x07:
5636 break;
5637 case 0x0c:
5638 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5639 if (u_lock_duration != -1)
5640 u_lock_duration /= 60;
5642 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5644 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5645 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5646 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5647 break;
5648 default:
5649 return NT_STATUS_INVALID_INFO_CLASS;
5652 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5654 return NT_STATUS_OK;
5657 /****************************************************************
5658 _samr_GetDisplayEnumerationIndex
5659 ****************************************************************/
5661 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5662 struct samr_GetDisplayEnumerationIndex *r)
5664 struct samr_info *info = NULL;
5665 uint32_t max_entries = (uint32_t) -1;
5666 uint32_t enum_context = 0;
5667 int i;
5668 uint32_t num_account = 0;
5669 struct samr_displayentry *entries = NULL;
5671 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5673 /* find the policy handle. open a policy on it. */
5674 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5675 return NT_STATUS_INVALID_HANDLE;
5678 if ((r->in.level < 1) || (r->in.level > 3)) {
5679 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5680 "Unknown info level (%u)\n",
5681 r->in.level));
5682 return NT_STATUS_INVALID_INFO_CLASS;
5685 become_root();
5687 /* The following done as ROOT. Don't return without unbecome_root(). */
5689 switch (r->in.level) {
5690 case 1:
5691 if (info->disp_info->users == NULL) {
5692 info->disp_info->users = pdb_search_users(ACB_NORMAL);
5693 if (info->disp_info->users == NULL) {
5694 unbecome_root();
5695 return NT_STATUS_ACCESS_DENIED;
5697 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5698 "starting user enumeration at index %u\n",
5699 (unsigned int)enum_context));
5700 } else {
5701 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5702 "using cached user enumeration at index %u\n",
5703 (unsigned int)enum_context));
5705 num_account = pdb_search_entries(info->disp_info->users,
5706 enum_context, max_entries,
5707 &entries);
5708 break;
5709 case 2:
5710 if (info->disp_info->machines == NULL) {
5711 info->disp_info->machines =
5712 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5713 if (info->disp_info->machines == NULL) {
5714 unbecome_root();
5715 return NT_STATUS_ACCESS_DENIED;
5717 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5718 "starting machine enumeration at index %u\n",
5719 (unsigned int)enum_context));
5720 } else {
5721 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5722 "using cached machine enumeration at index %u\n",
5723 (unsigned int)enum_context));
5725 num_account = pdb_search_entries(info->disp_info->machines,
5726 enum_context, max_entries,
5727 &entries);
5728 break;
5729 case 3:
5730 if (info->disp_info->groups == NULL) {
5731 info->disp_info->groups = pdb_search_groups();
5732 if (info->disp_info->groups == NULL) {
5733 unbecome_root();
5734 return NT_STATUS_ACCESS_DENIED;
5736 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5737 "starting group enumeration at index %u\n",
5738 (unsigned int)enum_context));
5739 } else {
5740 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5741 "using cached group enumeration at index %u\n",
5742 (unsigned int)enum_context));
5744 num_account = pdb_search_entries(info->disp_info->groups,
5745 enum_context, max_entries,
5746 &entries);
5747 break;
5748 default:
5749 unbecome_root();
5750 smb_panic("info class changed");
5751 break;
5754 unbecome_root();
5756 /* Ensure we cache this enumeration. */
5757 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5759 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5760 r->in.name->string));
5762 for (i=0; i<num_account; i++) {
5763 if (strequal(entries[i].account_name, r->in.name->string)) {
5764 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5765 "found %s at idx %d\n",
5766 r->in.name->string, i));
5767 *r->out.idx = i;
5768 return NT_STATUS_OK;
5772 /* assuming account_name lives at the very end */
5773 *r->out.idx = num_account;
5775 return NT_STATUS_NO_MORE_ENTRIES;
5778 /****************************************************************
5779 _samr_GetDisplayEnumerationIndex2
5780 ****************************************************************/
5782 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5783 struct samr_GetDisplayEnumerationIndex2 *r)
5785 struct samr_GetDisplayEnumerationIndex q;
5787 q.in.domain_handle = r->in.domain_handle;
5788 q.in.level = r->in.level;
5789 q.in.name = r->in.name;
5791 q.out.idx = r->out.idx;
5793 return _samr_GetDisplayEnumerationIndex(p, &q);
5796 /****************************************************************
5797 ****************************************************************/
5799 NTSTATUS _samr_Shutdown(pipes_struct *p,
5800 struct samr_Shutdown *r)
5802 p->rng_fault_state = true;
5803 return NT_STATUS_NOT_IMPLEMENTED;
5806 /****************************************************************
5807 ****************************************************************/
5809 NTSTATUS _samr_CreateUser(pipes_struct *p,
5810 struct samr_CreateUser *r)
5812 p->rng_fault_state = true;
5813 return NT_STATUS_NOT_IMPLEMENTED;
5816 /****************************************************************
5817 ****************************************************************/
5819 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5820 struct samr_SetMemberAttributesOfGroup *r)
5822 p->rng_fault_state = true;
5823 return NT_STATUS_NOT_IMPLEMENTED;
5826 /****************************************************************
5827 ****************************************************************/
5829 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5830 struct samr_ChangePasswordUser *r)
5832 p->rng_fault_state = true;
5833 return NT_STATUS_NOT_IMPLEMENTED;
5836 /****************************************************************
5837 ****************************************************************/
5839 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5840 struct samr_TestPrivateFunctionsDomain *r)
5842 p->rng_fault_state = true;
5843 return NT_STATUS_NOT_IMPLEMENTED;
5846 /****************************************************************
5847 ****************************************************************/
5849 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5850 struct samr_TestPrivateFunctionsUser *r)
5852 p->rng_fault_state = true;
5853 return NT_STATUS_NOT_IMPLEMENTED;
5856 /****************************************************************
5857 ****************************************************************/
5859 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5860 struct samr_QueryUserInfo2 *r)
5862 p->rng_fault_state = true;
5863 return NT_STATUS_NOT_IMPLEMENTED;
5866 /****************************************************************
5867 ****************************************************************/
5869 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5870 struct samr_AddMultipleMembersToAlias *r)
5872 p->rng_fault_state = true;
5873 return NT_STATUS_NOT_IMPLEMENTED;
5876 /****************************************************************
5877 ****************************************************************/
5879 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5880 struct samr_RemoveMultipleMembersFromAlias *r)
5882 p->rng_fault_state = true;
5883 return NT_STATUS_NOT_IMPLEMENTED;
5886 /****************************************************************
5887 ****************************************************************/
5889 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5890 struct samr_OemChangePasswordUser2 *r)
5892 p->rng_fault_state = true;
5893 return NT_STATUS_NOT_IMPLEMENTED;
5896 /****************************************************************
5897 ****************************************************************/
5899 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5900 struct samr_SetBootKeyInformation *r)
5902 p->rng_fault_state = true;
5903 return NT_STATUS_NOT_IMPLEMENTED;
5906 /****************************************************************
5907 ****************************************************************/
5909 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5910 struct samr_GetBootKeyInformation *r)
5912 p->rng_fault_state = true;
5913 return NT_STATUS_NOT_IMPLEMENTED;
5916 /****************************************************************
5917 ****************************************************************/
5919 NTSTATUS _samr_Connect3(pipes_struct *p,
5920 struct samr_Connect3 *r)
5922 p->rng_fault_state = true;
5923 return NT_STATUS_NOT_IMPLEMENTED;
5926 /****************************************************************
5927 ****************************************************************/
5929 NTSTATUS _samr_RidToSid(pipes_struct *p,
5930 struct samr_RidToSid *r)
5932 p->rng_fault_state = true;
5933 return NT_STATUS_NOT_IMPLEMENTED;
5936 /****************************************************************
5937 ****************************************************************/
5939 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5940 struct samr_SetDsrmPassword *r)
5942 p->rng_fault_state = true;
5943 return NT_STATUS_NOT_IMPLEMENTED;
5946 /****************************************************************
5947 ****************************************************************/
5949 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5950 struct samr_ValidatePassword *r)
5952 p->rng_fault_state = true;
5953 return NT_STATUS_NOT_IMPLEMENTED;