netapi: add NetFileEnum to public header.
[Samba.git] / source / rpc_server / srv_samr_nt.c
blob1b1e98c049cc0ade0cdc9d7bcec8d9b8b8d2eccc
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(type);
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->server_info->user_session_key.length) {
4210 status = NT_STATUS_NO_USER_SESSION_KEY;
4212 SamOEMhashBlob(info->info23.password.data, 516,
4213 &p->server_info->user_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->server_info->user_session_key.length) {
4223 status = NT_STATUS_NO_USER_SESSION_KEY;
4225 SamOEMhashBlob(info->info24.password.data,
4226 516,
4227 &p->server_info->user_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->server_info->user_session_key.length) {
4239 status = NT_STATUS_NO_USER_SESSION_KEY;
4241 encode_or_decode_arc4_passwd_buffer(
4242 info->info25.password.data,
4243 &p->server_info->user_session_key);
4245 dump_data(100, info->info25.password.data, 532);
4247 status = set_user_info_25(p->mem_ctx,
4248 &info->info25, pwd);
4249 if (!NT_STATUS_IS_OK(status)) {
4250 goto done;
4252 if (!set_user_info_pw(info->info25.password.data, pwd,
4253 switch_value)) {
4254 status = NT_STATUS_ACCESS_DENIED;
4256 break;
4258 case 26:
4259 if (!p->server_info->user_session_key.length) {
4260 status = NT_STATUS_NO_USER_SESSION_KEY;
4262 encode_or_decode_arc4_passwd_buffer(
4263 info->info26.password.data,
4264 &p->server_info->user_session_key);
4266 dump_data(100, info->info26.password.data, 516);
4268 if (!set_user_info_pw(info->info26.password.data, pwd,
4269 switch_value)) {
4270 status = NT_STATUS_ACCESS_DENIED;
4272 break;
4274 default:
4275 status = NT_STATUS_INVALID_INFO_CLASS;
4278 done:
4280 if (has_enough_rights) {
4281 unbecome_root();
4284 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4286 if (NT_STATUS_IS_OK(status)) {
4287 force_flush_samr_cache(disp_info);
4290 return status;
4293 /*******************************************************************
4294 _samr_SetUserInfo
4295 ********************************************************************/
4297 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4298 struct samr_SetUserInfo *r)
4300 return samr_SetUserInfo_internal("_samr_SetUserInfo",
4302 r->in.user_handle,
4303 r->in.level,
4304 r->in.info);
4307 /*******************************************************************
4308 _samr_SetUserInfo2
4309 ********************************************************************/
4311 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4312 struct samr_SetUserInfo2 *r)
4314 return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4316 r->in.user_handle,
4317 r->in.level,
4318 r->in.info);
4321 /*********************************************************************
4322 _samr_GetAliasMembership
4323 *********************************************************************/
4325 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4326 struct samr_GetAliasMembership *r)
4328 size_t num_alias_rids;
4329 uint32 *alias_rids;
4330 struct samr_info *info = NULL;
4331 size_t i;
4333 NTSTATUS ntstatus1;
4334 NTSTATUS ntstatus2;
4336 DOM_SID *members;
4338 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4340 /* find the policy handle. open a policy on it. */
4341 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4342 return NT_STATUS_INVALID_HANDLE;
4344 ntstatus1 = access_check_samr_function(info->acc_granted,
4345 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4346 "_samr_GetAliasMembership");
4347 ntstatus2 = access_check_samr_function(info->acc_granted,
4348 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4349 "_samr_GetAliasMembership");
4351 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4352 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4353 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4354 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4358 if (!sid_check_is_domain(&info->sid) &&
4359 !sid_check_is_builtin(&info->sid))
4360 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4362 if (r->in.sids->num_sids) {
4363 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4365 if (members == NULL)
4366 return NT_STATUS_NO_MEMORY;
4367 } else {
4368 members = NULL;
4371 for (i=0; i<r->in.sids->num_sids; i++)
4372 sid_copy(&members[i], r->in.sids->sids[i].sid);
4374 alias_rids = NULL;
4375 num_alias_rids = 0;
4377 become_root();
4378 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4379 r->in.sids->num_sids,
4380 &alias_rids, &num_alias_rids);
4381 unbecome_root();
4383 if (!NT_STATUS_IS_OK(ntstatus1)) {
4384 return ntstatus1;
4387 r->out.rids->count = num_alias_rids;
4388 r->out.rids->ids = alias_rids;
4390 return NT_STATUS_OK;
4393 /*********************************************************************
4394 _samr_GetMembersInAlias
4395 *********************************************************************/
4397 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4398 struct samr_GetMembersInAlias *r)
4400 NTSTATUS status;
4401 size_t i;
4402 size_t num_sids = 0;
4403 struct lsa_SidPtr *sids = NULL;
4404 DOM_SID *pdb_sids = NULL;
4406 DOM_SID alias_sid;
4408 uint32 acc_granted;
4410 /* find the policy handle. open a policy on it. */
4411 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4412 return NT_STATUS_INVALID_HANDLE;
4414 status = access_check_samr_function(acc_granted,
4415 SA_RIGHT_ALIAS_GET_MEMBERS,
4416 "_samr_GetMembersInAlias");
4417 if (!NT_STATUS_IS_OK(status)) {
4418 return status;
4421 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4423 become_root();
4424 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4425 unbecome_root();
4427 if (!NT_STATUS_IS_OK(status)) {
4428 return status;
4431 if (num_sids) {
4432 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4433 if (sids == NULL) {
4434 TALLOC_FREE(pdb_sids);
4435 return NT_STATUS_NO_MEMORY;
4439 for (i = 0; i < num_sids; i++) {
4440 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4441 if (!sids[i].sid) {
4442 TALLOC_FREE(pdb_sids);
4443 return NT_STATUS_NO_MEMORY;
4447 r->out.sids->num_sids = num_sids;
4448 r->out.sids->sids = sids;
4450 TALLOC_FREE(pdb_sids);
4452 return NT_STATUS_OK;
4455 /*********************************************************************
4456 _samr_QueryGroupMember
4457 *********************************************************************/
4459 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4460 struct samr_QueryGroupMember *r)
4462 DOM_SID group_sid;
4463 size_t i, num_members;
4465 uint32 *rid=NULL;
4466 uint32 *attr=NULL;
4468 uint32 acc_granted;
4470 NTSTATUS status;
4471 struct samr_RidTypeArray *rids = NULL;
4473 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4474 if (!rids) {
4475 return NT_STATUS_NO_MEMORY;
4478 /* find the policy handle. open a policy on it. */
4479 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4480 return NT_STATUS_INVALID_HANDLE;
4482 status = access_check_samr_function(acc_granted,
4483 SA_RIGHT_GROUP_GET_MEMBERS,
4484 "_samr_QueryGroupMember");
4485 if (!NT_STATUS_IS_OK(status)) {
4486 return status;
4489 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4491 if (!sid_check_is_in_our_domain(&group_sid)) {
4492 DEBUG(3, ("sid %s is not in our domain\n",
4493 sid_string_dbg(&group_sid)));
4494 return NT_STATUS_NO_SUCH_GROUP;
4497 DEBUG(10, ("lookup on Domain SID\n"));
4499 become_root();
4500 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4501 &rid, &num_members);
4502 unbecome_root();
4504 if (!NT_STATUS_IS_OK(status))
4505 return status;
4507 if (num_members) {
4508 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4509 if (attr == NULL) {
4510 return NT_STATUS_NO_MEMORY;
4512 } else {
4513 attr = NULL;
4516 for (i=0; i<num_members; i++)
4517 attr[i] = SID_NAME_USER;
4519 rids->count = num_members;
4520 rids->types = attr;
4521 rids->rids = rid;
4523 *r->out.rids = rids;
4525 return NT_STATUS_OK;
4528 /*********************************************************************
4529 _samr_AddAliasMember
4530 *********************************************************************/
4532 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4533 struct samr_AddAliasMember *r)
4535 DOM_SID alias_sid;
4536 uint32 acc_granted;
4537 SE_PRIV se_rights;
4538 bool can_add_accounts;
4539 NTSTATUS status;
4540 DISP_INFO *disp_info = NULL;
4542 /* Find the policy handle. Open a policy on it. */
4543 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4544 return NT_STATUS_INVALID_HANDLE;
4546 status = access_check_samr_function(acc_granted,
4547 SA_RIGHT_ALIAS_ADD_MEMBER,
4548 "_samr_AddAliasMember");
4549 if (!NT_STATUS_IS_OK(status)) {
4550 return status;
4553 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4555 se_priv_copy( &se_rights, &se_add_users );
4556 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4558 /******** BEGIN SeAddUsers BLOCK *********/
4560 if ( can_add_accounts )
4561 become_root();
4563 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4565 if ( can_add_accounts )
4566 unbecome_root();
4568 /******** END SeAddUsers BLOCK *********/
4570 if (NT_STATUS_IS_OK(status)) {
4571 force_flush_samr_cache(disp_info);
4574 return status;
4577 /*********************************************************************
4578 _samr_DeleteAliasMember
4579 *********************************************************************/
4581 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4582 struct samr_DeleteAliasMember *r)
4584 DOM_SID alias_sid;
4585 uint32 acc_granted;
4586 SE_PRIV se_rights;
4587 bool can_add_accounts;
4588 NTSTATUS status;
4589 DISP_INFO *disp_info = NULL;
4591 /* Find the policy handle. Open a policy on it. */
4592 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4593 return NT_STATUS_INVALID_HANDLE;
4595 status = access_check_samr_function(acc_granted,
4596 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4597 "_samr_DeleteAliasMember");
4598 if (!NT_STATUS_IS_OK(status)) {
4599 return status;
4602 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4603 sid_string_dbg(&alias_sid)));
4605 se_priv_copy( &se_rights, &se_add_users );
4606 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4608 /******** BEGIN SeAddUsers BLOCK *********/
4610 if ( can_add_accounts )
4611 become_root();
4613 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4615 if ( can_add_accounts )
4616 unbecome_root();
4618 /******** END SeAddUsers BLOCK *********/
4620 if (NT_STATUS_IS_OK(status)) {
4621 force_flush_samr_cache(disp_info);
4624 return status;
4627 /*********************************************************************
4628 _samr_AddGroupMember
4629 *********************************************************************/
4631 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4632 struct samr_AddGroupMember *r)
4634 NTSTATUS status;
4635 DOM_SID group_sid;
4636 uint32 group_rid;
4637 uint32 acc_granted;
4638 SE_PRIV se_rights;
4639 bool can_add_accounts;
4640 DISP_INFO *disp_info = NULL;
4642 /* Find the policy handle. Open a policy on it. */
4643 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4644 return NT_STATUS_INVALID_HANDLE;
4646 status = access_check_samr_function(acc_granted,
4647 SA_RIGHT_GROUP_ADD_MEMBER,
4648 "_samr_AddGroupMember");
4649 if (!NT_STATUS_IS_OK(status)) {
4650 return status;
4653 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4655 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4656 &group_rid)) {
4657 return NT_STATUS_INVALID_HANDLE;
4660 se_priv_copy( &se_rights, &se_add_users );
4661 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4663 /******** BEGIN SeAddUsers BLOCK *********/
4665 if ( can_add_accounts )
4666 become_root();
4668 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4670 if ( can_add_accounts )
4671 unbecome_root();
4673 /******** END SeAddUsers BLOCK *********/
4675 force_flush_samr_cache(disp_info);
4677 return status;
4680 /*********************************************************************
4681 _samr_DeleteGroupMember
4682 *********************************************************************/
4684 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4685 struct samr_DeleteGroupMember *r)
4688 NTSTATUS status;
4689 DOM_SID group_sid;
4690 uint32 group_rid;
4691 uint32 acc_granted;
4692 SE_PRIV se_rights;
4693 bool can_add_accounts;
4694 DISP_INFO *disp_info = NULL;
4697 * delete the group member named r->in.rid
4698 * who is a member of the sid associated with the handle
4699 * the rid is a user's rid as the group is a domain group.
4702 /* Find the policy handle. Open a policy on it. */
4703 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4704 return NT_STATUS_INVALID_HANDLE;
4706 status = access_check_samr_function(acc_granted,
4707 SA_RIGHT_GROUP_REMOVE_MEMBER,
4708 "_samr_DeleteGroupMember");
4709 if (!NT_STATUS_IS_OK(status)) {
4710 return status;
4713 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4714 &group_rid)) {
4715 return NT_STATUS_INVALID_HANDLE;
4718 se_priv_copy( &se_rights, &se_add_users );
4719 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4721 /******** BEGIN SeAddUsers BLOCK *********/
4723 if ( can_add_accounts )
4724 become_root();
4726 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4728 if ( can_add_accounts )
4729 unbecome_root();
4731 /******** END SeAddUsers BLOCK *********/
4733 force_flush_samr_cache(disp_info);
4735 return status;
4738 /*********************************************************************
4739 _samr_DeleteUser
4740 *********************************************************************/
4742 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4743 struct samr_DeleteUser *r)
4745 NTSTATUS status;
4746 DOM_SID user_sid;
4747 struct samu *sam_pass=NULL;
4748 uint32 acc_granted;
4749 bool can_add_accounts;
4750 uint32 acb_info;
4751 DISP_INFO *disp_info = NULL;
4752 bool ret;
4754 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4756 /* Find the policy handle. Open a policy on it. */
4757 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4758 return NT_STATUS_INVALID_HANDLE;
4760 status = access_check_samr_function(acc_granted,
4761 STD_RIGHT_DELETE_ACCESS,
4762 "_samr_DeleteUser");
4763 if (!NT_STATUS_IS_OK(status)) {
4764 return status;
4767 if (!sid_check_is_in_our_domain(&user_sid))
4768 return NT_STATUS_CANNOT_DELETE;
4770 /* check if the user exists before trying to delete */
4771 if ( !(sam_pass = samu_new( NULL )) ) {
4772 return NT_STATUS_NO_MEMORY;
4775 become_root();
4776 ret = pdb_getsampwsid(sam_pass, &user_sid);
4777 unbecome_root();
4779 if( !ret ) {
4780 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4781 sid_string_dbg(&user_sid)));
4782 TALLOC_FREE(sam_pass);
4783 return NT_STATUS_NO_SUCH_USER;
4786 acb_info = pdb_get_acct_ctrl(sam_pass);
4788 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4789 if ( acb_info & ACB_WSTRUST ) {
4790 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4791 } else {
4792 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4795 /******** BEGIN SeAddUsers BLOCK *********/
4797 if ( can_add_accounts )
4798 become_root();
4800 status = pdb_delete_user(p->mem_ctx, sam_pass);
4802 if ( can_add_accounts )
4803 unbecome_root();
4805 /******** END SeAddUsers BLOCK *********/
4807 if ( !NT_STATUS_IS_OK(status) ) {
4808 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4809 "user %s: %s.\n", pdb_get_username(sam_pass),
4810 nt_errstr(status)));
4811 TALLOC_FREE(sam_pass);
4812 return status;
4816 TALLOC_FREE(sam_pass);
4818 if (!close_policy_hnd(p, r->in.user_handle))
4819 return NT_STATUS_OBJECT_NAME_INVALID;
4821 force_flush_samr_cache(disp_info);
4823 return NT_STATUS_OK;
4826 /*********************************************************************
4827 _samr_DeleteDomainGroup
4828 *********************************************************************/
4830 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4831 struct samr_DeleteDomainGroup *r)
4833 NTSTATUS status;
4834 DOM_SID group_sid;
4835 uint32 group_rid;
4836 uint32 acc_granted;
4837 SE_PRIV se_rights;
4838 bool can_add_accounts;
4839 DISP_INFO *disp_info = NULL;
4841 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4843 /* Find the policy handle. Open a policy on it. */
4844 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4845 return NT_STATUS_INVALID_HANDLE;
4847 status = access_check_samr_function(acc_granted,
4848 STD_RIGHT_DELETE_ACCESS,
4849 "_samr_DeleteDomainGroup");
4850 if (!NT_STATUS_IS_OK(status)) {
4851 return status;
4854 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4856 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4857 &group_rid)) {
4858 return NT_STATUS_NO_SUCH_GROUP;
4861 se_priv_copy( &se_rights, &se_add_users );
4862 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4864 /******** BEGIN SeAddUsers BLOCK *********/
4866 if ( can_add_accounts )
4867 become_root();
4869 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4871 if ( can_add_accounts )
4872 unbecome_root();
4874 /******** END SeAddUsers BLOCK *********/
4876 if ( !NT_STATUS_IS_OK(status) ) {
4877 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4878 "entry for group %s: %s\n",
4879 sid_string_dbg(&group_sid),
4880 nt_errstr(status)));
4881 return status;
4884 if (!close_policy_hnd(p, r->in.group_handle))
4885 return NT_STATUS_OBJECT_NAME_INVALID;
4887 force_flush_samr_cache(disp_info);
4889 return NT_STATUS_OK;
4892 /*********************************************************************
4893 _samr_DeleteDomAlias
4894 *********************************************************************/
4896 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4897 struct samr_DeleteDomAlias *r)
4899 DOM_SID alias_sid;
4900 uint32 acc_granted;
4901 SE_PRIV se_rights;
4902 bool can_add_accounts;
4903 NTSTATUS status;
4904 DISP_INFO *disp_info = NULL;
4906 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4908 /* Find the policy handle. Open a policy on it. */
4909 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4910 return NT_STATUS_INVALID_HANDLE;
4912 /* copy the handle to the outgoing reply */
4914 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4916 status = access_check_samr_function(acc_granted,
4917 STD_RIGHT_DELETE_ACCESS,
4918 "_samr_DeleteDomAlias");
4919 if (!NT_STATUS_IS_OK(status)) {
4920 return status;
4923 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4925 /* Don't let Windows delete builtin groups */
4927 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4928 return NT_STATUS_SPECIAL_ACCOUNT;
4931 if (!sid_check_is_in_our_domain(&alias_sid))
4932 return NT_STATUS_NO_SUCH_ALIAS;
4934 DEBUG(10, ("lookup on Local SID\n"));
4936 se_priv_copy( &se_rights, &se_add_users );
4937 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4939 /******** BEGIN SeAddUsers BLOCK *********/
4941 if ( can_add_accounts )
4942 become_root();
4944 /* Have passdb delete the alias */
4945 status = pdb_delete_alias(&alias_sid);
4947 if ( can_add_accounts )
4948 unbecome_root();
4950 /******** END SeAddUsers BLOCK *********/
4952 if ( !NT_STATUS_IS_OK(status))
4953 return status;
4955 if (!close_policy_hnd(p, r->in.alias_handle))
4956 return NT_STATUS_OBJECT_NAME_INVALID;
4958 force_flush_samr_cache(disp_info);
4960 return NT_STATUS_OK;
4963 /*********************************************************************
4964 _samr_CreateDomainGroup
4965 *********************************************************************/
4967 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4968 struct samr_CreateDomainGroup *r)
4971 NTSTATUS status;
4972 DOM_SID dom_sid;
4973 DOM_SID info_sid;
4974 const char *name;
4975 struct samr_info *info;
4976 uint32 acc_granted;
4977 SE_PRIV se_rights;
4978 bool can_add_accounts;
4979 DISP_INFO *disp_info = NULL;
4981 /* Find the policy handle. Open a policy on it. */
4982 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4983 return NT_STATUS_INVALID_HANDLE;
4985 status = access_check_samr_function(acc_granted,
4986 SA_RIGHT_DOMAIN_CREATE_GROUP,
4987 "_samr_CreateDomainGroup");
4988 if (!NT_STATUS_IS_OK(status)) {
4989 return status;
4992 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4993 return NT_STATUS_ACCESS_DENIED;
4995 name = r->in.name->string;
4996 if (name == NULL) {
4997 return NT_STATUS_NO_MEMORY;
5000 status = can_create(p->mem_ctx, name);
5001 if (!NT_STATUS_IS_OK(status)) {
5002 return status;
5005 se_priv_copy( &se_rights, &se_add_users );
5006 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5008 /******** BEGIN SeAddUsers BLOCK *********/
5010 if ( can_add_accounts )
5011 become_root();
5013 /* check that we successfully create the UNIX group */
5015 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5017 if ( can_add_accounts )
5018 unbecome_root();
5020 /******** END SeAddUsers BLOCK *********/
5022 /* check if we should bail out here */
5024 if ( !NT_STATUS_IS_OK(status) )
5025 return status;
5027 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5029 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5030 return NT_STATUS_NO_MEMORY;
5032 /* they created it; let the user do what he wants with it */
5034 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5036 /* get a (unique) handle. open a policy on it. */
5037 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5038 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5040 force_flush_samr_cache(disp_info);
5042 return NT_STATUS_OK;
5045 /*********************************************************************
5046 _samr_CreateDomAlias
5047 *********************************************************************/
5049 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5050 struct samr_CreateDomAlias *r)
5052 DOM_SID dom_sid;
5053 DOM_SID info_sid;
5054 const char *name = NULL;
5055 struct samr_info *info;
5056 uint32 acc_granted;
5057 gid_t gid;
5058 NTSTATUS result;
5059 SE_PRIV se_rights;
5060 bool can_add_accounts;
5061 DISP_INFO *disp_info = NULL;
5063 /* Find the policy handle. Open a policy on it. */
5064 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5065 return NT_STATUS_INVALID_HANDLE;
5067 result = access_check_samr_function(acc_granted,
5068 SA_RIGHT_DOMAIN_CREATE_ALIAS,
5069 "_samr_CreateDomAlias");
5070 if (!NT_STATUS_IS_OK(result)) {
5071 return result;
5074 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5075 return NT_STATUS_ACCESS_DENIED;
5077 name = r->in.alias_name->string;
5079 se_priv_copy( &se_rights, &se_add_users );
5080 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5082 result = can_create(p->mem_ctx, name);
5083 if (!NT_STATUS_IS_OK(result)) {
5084 return result;
5087 /******** BEGIN SeAddUsers BLOCK *********/
5089 if ( can_add_accounts )
5090 become_root();
5092 /* Have passdb create the alias */
5093 result = pdb_create_alias(name, r->out.rid);
5095 if ( can_add_accounts )
5096 unbecome_root();
5098 /******** END SeAddUsers BLOCK *********/
5100 if (!NT_STATUS_IS_OK(result)) {
5101 DEBUG(10, ("pdb_create_alias failed: %s\n",
5102 nt_errstr(result)));
5103 return result;
5106 sid_copy(&info_sid, get_global_sam_sid());
5107 sid_append_rid(&info_sid, *r->out.rid);
5109 if (!sid_to_gid(&info_sid, &gid)) {
5110 DEBUG(10, ("Could not find alias just created\n"));
5111 return NT_STATUS_ACCESS_DENIED;
5114 /* check if the group has been successfully created */
5115 if ( getgrgid(gid) == NULL ) {
5116 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5117 gid));
5118 return NT_STATUS_ACCESS_DENIED;
5121 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5122 return NT_STATUS_NO_MEMORY;
5124 /* they created it; let the user do what he wants with it */
5126 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5128 /* get a (unique) handle. open a policy on it. */
5129 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5130 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5132 force_flush_samr_cache(disp_info);
5134 return NT_STATUS_OK;
5137 /*********************************************************************
5138 _samr_QueryGroupInfo
5139 *********************************************************************/
5141 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5142 struct samr_QueryGroupInfo *r)
5144 NTSTATUS status;
5145 DOM_SID group_sid;
5146 GROUP_MAP map;
5147 union samr_GroupInfo *info = NULL;
5148 uint32 acc_granted;
5149 bool ret;
5150 uint32_t attributes = SE_GROUP_MANDATORY |
5151 SE_GROUP_ENABLED_BY_DEFAULT |
5152 SE_GROUP_ENABLED;
5153 const char *group_name = NULL;
5154 const char *group_description = NULL;
5156 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5157 return NT_STATUS_INVALID_HANDLE;
5159 status = access_check_samr_function(acc_granted,
5160 SA_RIGHT_GROUP_LOOKUP_INFO,
5161 "_samr_QueryGroupInfo");
5162 if (!NT_STATUS_IS_OK(status)) {
5163 return status;
5166 become_root();
5167 ret = get_domain_group_from_sid(group_sid, &map);
5168 unbecome_root();
5169 if (!ret)
5170 return NT_STATUS_INVALID_HANDLE;
5172 /* FIXME: map contains fstrings */
5173 group_name = talloc_strdup(r, map.nt_name);
5174 group_description = talloc_strdup(r, map.comment);
5176 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5177 if (!info) {
5178 return NT_STATUS_NO_MEMORY;
5181 switch (r->in.level) {
5182 case 1: {
5183 uint32 *members;
5184 size_t num_members;
5186 become_root();
5187 status = pdb_enum_group_members(
5188 p->mem_ctx, &group_sid, &members, &num_members);
5189 unbecome_root();
5191 if (!NT_STATUS_IS_OK(status)) {
5192 return status;
5195 init_samr_group_info1(&info->all,
5196 group_name,
5197 attributes,
5198 num_members,
5199 group_description);
5200 break;
5202 case 2:
5203 init_samr_group_info2(&info->name,
5204 group_name);
5205 break;
5206 case 3:
5207 init_samr_group_info3(&info->attributes,
5208 attributes);
5209 break;
5210 case 4:
5211 init_samr_group_info4(&info->description,
5212 group_description);
5213 break;
5214 case 5: {
5216 uint32 *members;
5217 size_t num_members;
5221 become_root();
5222 status = pdb_enum_group_members(
5223 p->mem_ctx, &group_sid, &members, &num_members);
5224 unbecome_root();
5226 if (!NT_STATUS_IS_OK(status)) {
5227 return status;
5230 init_samr_group_info5(&info->all2,
5231 group_name,
5232 attributes,
5233 0, /* num_members - in w2k3 this is always 0 */
5234 group_description);
5236 break;
5238 default:
5239 return NT_STATUS_INVALID_INFO_CLASS;
5242 *r->out.info = info;
5244 return NT_STATUS_OK;
5247 /*********************************************************************
5248 _samr_SetGroupInfo
5249 *********************************************************************/
5251 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5252 struct samr_SetGroupInfo *r)
5254 DOM_SID group_sid;
5255 GROUP_MAP map;
5256 uint32 acc_granted;
5257 NTSTATUS status;
5258 bool ret;
5259 bool can_mod_accounts;
5260 DISP_INFO *disp_info = NULL;
5262 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5263 return NT_STATUS_INVALID_HANDLE;
5265 status = access_check_samr_function(acc_granted,
5266 SA_RIGHT_GROUP_SET_INFO,
5267 "_samr_SetGroupInfo");
5268 if (!NT_STATUS_IS_OK(status)) {
5269 return status;
5272 become_root();
5273 ret = get_domain_group_from_sid(group_sid, &map);
5274 unbecome_root();
5275 if (!ret)
5276 return NT_STATUS_NO_SUCH_GROUP;
5278 switch (r->in.level) {
5279 case 1:
5280 fstrcpy(map.comment, r->in.info->all.description.string);
5281 break;
5282 case 4:
5283 fstrcpy(map.comment, r->in.info->description.string);
5284 break;
5285 default:
5286 return NT_STATUS_INVALID_INFO_CLASS;
5289 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5291 /******** BEGIN SeAddUsers BLOCK *********/
5293 if ( can_mod_accounts )
5294 become_root();
5296 status = pdb_update_group_mapping_entry(&map);
5298 if ( can_mod_accounts )
5299 unbecome_root();
5301 /******** End SeAddUsers BLOCK *********/
5303 if (NT_STATUS_IS_OK(status)) {
5304 force_flush_samr_cache(disp_info);
5307 return status;
5310 /*********************************************************************
5311 _samr_SetAliasInfo
5312 *********************************************************************/
5314 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5315 struct samr_SetAliasInfo *r)
5317 DOM_SID group_sid;
5318 struct acct_info info;
5319 uint32 acc_granted;
5320 bool can_mod_accounts;
5321 NTSTATUS status;
5322 DISP_INFO *disp_info = NULL;
5324 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5325 return NT_STATUS_INVALID_HANDLE;
5327 status = access_check_samr_function(acc_granted,
5328 SA_RIGHT_ALIAS_SET_INFO,
5329 "_samr_SetAliasInfo");
5330 if (!NT_STATUS_IS_OK(status)) {
5331 return status;
5334 /* get the current group information */
5336 become_root();
5337 status = pdb_get_aliasinfo( &group_sid, &info );
5338 unbecome_root();
5340 if ( !NT_STATUS_IS_OK(status))
5341 return status;
5343 switch (r->in.level) {
5344 case ALIASINFONAME:
5346 fstring group_name;
5348 /* We currently do not support renaming groups in the
5349 the BUILTIN domain. Refer to util_builtin.c to understand
5350 why. The eventually needs to be fixed to be like Windows
5351 where you can rename builtin groups, just not delete them */
5353 if ( sid_check_is_in_builtin( &group_sid ) ) {
5354 return NT_STATUS_SPECIAL_ACCOUNT;
5357 /* There has to be a valid name (and it has to be different) */
5359 if ( !r->in.info->name.string )
5360 return NT_STATUS_INVALID_PARAMETER;
5362 /* If the name is the same just reply "ok". Yes this
5363 doesn't allow you to change the case of a group name. */
5365 if ( strequal( r->in.info->name.string, info.acct_name ) )
5366 return NT_STATUS_OK;
5368 fstrcpy( info.acct_name, r->in.info->name.string);
5370 /* make sure the name doesn't already exist as a user
5371 or local group */
5373 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5374 status = can_create( p->mem_ctx, group_name );
5375 if ( !NT_STATUS_IS_OK( status ) )
5376 return status;
5377 break;
5379 case ALIASINFODESCRIPTION:
5380 if (r->in.info->description.string) {
5381 fstrcpy(info.acct_desc,
5382 r->in.info->description.string);
5383 } else {
5384 fstrcpy( info.acct_desc, "" );
5386 break;
5387 default:
5388 return NT_STATUS_INVALID_INFO_CLASS;
5391 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5393 /******** BEGIN SeAddUsers BLOCK *********/
5395 if ( can_mod_accounts )
5396 become_root();
5398 status = pdb_set_aliasinfo( &group_sid, &info );
5400 if ( can_mod_accounts )
5401 unbecome_root();
5403 /******** End SeAddUsers BLOCK *********/
5405 if (NT_STATUS_IS_OK(status))
5406 force_flush_samr_cache(disp_info);
5408 return status;
5411 /****************************************************************
5412 _samr_GetDomPwInfo
5413 ****************************************************************/
5415 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5416 struct samr_GetDomPwInfo *r)
5418 uint32_t min_password_length = 0;
5419 uint32_t password_properties = 0;
5421 /* Perform access check. Since this rpc does not require a
5422 policy handle it will not be caught by the access checks on
5423 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5425 if (!pipe_access_check(p)) {
5426 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5427 return NT_STATUS_ACCESS_DENIED;
5430 become_root();
5431 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5432 &min_password_length);
5433 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5434 &password_properties);
5435 unbecome_root();
5437 if (lp_check_password_script() && *lp_check_password_script()) {
5438 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5441 r->out.info->min_password_length = min_password_length;
5442 r->out.info->password_properties = password_properties;
5444 return NT_STATUS_OK;
5447 /*********************************************************************
5448 _samr_OpenGroup
5449 *********************************************************************/
5451 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5452 struct samr_OpenGroup *r)
5455 DOM_SID sid;
5456 DOM_SID info_sid;
5457 GROUP_MAP map;
5458 struct samr_info *info;
5459 SEC_DESC *psd = NULL;
5460 uint32 acc_granted;
5461 uint32 des_access = r->in.access_mask;
5462 size_t sd_size;
5463 NTSTATUS status;
5464 fstring sid_string;
5465 bool ret;
5466 SE_PRIV se_rights;
5468 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5469 return NT_STATUS_INVALID_HANDLE;
5471 status = access_check_samr_function(acc_granted,
5472 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5473 "_samr_OpenGroup");
5475 if ( !NT_STATUS_IS_OK(status) )
5476 return status;
5478 /*check if access can be granted as requested by client. */
5479 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5480 se_map_generic(&des_access,&grp_generic_mapping);
5482 se_priv_copy( &se_rights, &se_add_users );
5484 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5485 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5486 &acc_granted, "_samr_OpenGroup");
5488 if ( !NT_STATUS_IS_OK(status) )
5489 return status;
5491 /* this should not be hard-coded like this */
5493 if (!sid_equal(&sid, get_global_sam_sid()))
5494 return NT_STATUS_ACCESS_DENIED;
5496 sid_copy(&info_sid, get_global_sam_sid());
5497 sid_append_rid(&info_sid, r->in.rid);
5498 sid_to_fstring(sid_string, &info_sid);
5500 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5501 return NT_STATUS_NO_MEMORY;
5503 info->acc_granted = acc_granted;
5505 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5507 /* check if that group really exists */
5508 become_root();
5509 ret = get_domain_group_from_sid(info->sid, &map);
5510 unbecome_root();
5511 if (!ret)
5512 return NT_STATUS_NO_SUCH_GROUP;
5514 /* get a (unique) handle. open a policy on it. */
5515 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5516 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5518 return NT_STATUS_OK;
5521 /*********************************************************************
5522 _samr_RemoveMemberFromForeignDomain
5523 *********************************************************************/
5525 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5526 struct samr_RemoveMemberFromForeignDomain *r)
5528 DOM_SID delete_sid, domain_sid;
5529 uint32 acc_granted;
5530 NTSTATUS result;
5531 DISP_INFO *disp_info = NULL;
5533 sid_copy( &delete_sid, r->in.sid );
5535 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5536 sid_string_dbg(&delete_sid)));
5538 /* Find the policy handle. Open a policy on it. */
5540 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5541 &acc_granted, &disp_info))
5542 return NT_STATUS_INVALID_HANDLE;
5544 result = access_check_samr_function(acc_granted,
5545 STD_RIGHT_DELETE_ACCESS,
5546 "_samr_RemoveMemberFromForeignDomain");
5548 if (!NT_STATUS_IS_OK(result))
5549 return result;
5551 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5552 sid_string_dbg(&domain_sid)));
5554 /* we can only delete a user from a group since we don't have
5555 nested groups anyways. So in the latter case, just say OK */
5557 /* TODO: The above comment nowadays is bogus. Since we have nested
5558 * groups now, and aliases members are never reported out of the unix
5559 * group membership, the "just say OK" makes this call a no-op. For
5560 * us. This needs fixing however. */
5562 /* I've only ever seen this in the wild when deleting a user from
5563 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5564 * is the user about to be deleted. I very much suspect this is the
5565 * only application of this call. To verify this, let people report
5566 * other cases. */
5568 if (!sid_check_is_builtin(&domain_sid)) {
5569 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5570 "global_sam_sid() = %s\n",
5571 sid_string_dbg(&domain_sid),
5572 sid_string_dbg(get_global_sam_sid())));
5573 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5574 return NT_STATUS_OK;
5577 force_flush_samr_cache(disp_info);
5579 result = NT_STATUS_OK;
5581 return result;
5584 /*******************************************************************
5585 _samr_QueryDomainInfo2
5586 ********************************************************************/
5588 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5589 struct samr_QueryDomainInfo2 *r)
5591 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5593 r->in.domain_handle,
5594 r->in.level,
5595 r->out.info);
5598 /*******************************************************************
5599 _samr_SetDomainInfo
5600 ********************************************************************/
5602 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5603 struct samr_SetDomainInfo *r)
5605 time_t u_expire, u_min_age;
5606 time_t u_logout;
5607 time_t u_lock_duration, u_reset_time;
5609 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5611 /* find the policy handle. open a policy on it. */
5612 if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5613 return NT_STATUS_INVALID_HANDLE;
5615 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5617 switch (r->in.level) {
5618 case 0x01:
5619 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5620 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5621 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5622 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5623 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5624 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5625 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5626 break;
5627 case 0x02:
5628 break;
5629 case 0x03:
5630 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5631 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5632 break;
5633 case 0x05:
5634 break;
5635 case 0x06:
5636 break;
5637 case 0x07:
5638 break;
5639 case 0x0c:
5640 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5641 if (u_lock_duration != -1)
5642 u_lock_duration /= 60;
5644 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5646 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5647 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5648 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5649 break;
5650 default:
5651 return NT_STATUS_INVALID_INFO_CLASS;
5654 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5656 return NT_STATUS_OK;
5659 /****************************************************************
5660 _samr_GetDisplayEnumerationIndex
5661 ****************************************************************/
5663 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5664 struct samr_GetDisplayEnumerationIndex *r)
5666 struct samr_info *info = NULL;
5667 uint32_t max_entries = (uint32_t) -1;
5668 uint32_t enum_context = 0;
5669 int i;
5670 uint32_t num_account = 0;
5671 struct samr_displayentry *entries = NULL;
5673 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5675 /* find the policy handle. open a policy on it. */
5676 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5677 return NT_STATUS_INVALID_HANDLE;
5680 if ((r->in.level < 1) || (r->in.level > 3)) {
5681 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5682 "Unknown info level (%u)\n",
5683 r->in.level));
5684 return NT_STATUS_INVALID_INFO_CLASS;
5687 become_root();
5689 /* The following done as ROOT. Don't return without unbecome_root(). */
5691 switch (r->in.level) {
5692 case 1:
5693 if (info->disp_info->users == NULL) {
5694 info->disp_info->users = pdb_search_users(ACB_NORMAL);
5695 if (info->disp_info->users == NULL) {
5696 unbecome_root();
5697 return NT_STATUS_ACCESS_DENIED;
5699 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5700 "starting user enumeration at index %u\n",
5701 (unsigned int)enum_context));
5702 } else {
5703 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5704 "using cached user enumeration at index %u\n",
5705 (unsigned int)enum_context));
5707 num_account = pdb_search_entries(info->disp_info->users,
5708 enum_context, max_entries,
5709 &entries);
5710 break;
5711 case 2:
5712 if (info->disp_info->machines == NULL) {
5713 info->disp_info->machines =
5714 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5715 if (info->disp_info->machines == NULL) {
5716 unbecome_root();
5717 return NT_STATUS_ACCESS_DENIED;
5719 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5720 "starting machine enumeration at index %u\n",
5721 (unsigned int)enum_context));
5722 } else {
5723 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5724 "using cached machine enumeration at index %u\n",
5725 (unsigned int)enum_context));
5727 num_account = pdb_search_entries(info->disp_info->machines,
5728 enum_context, max_entries,
5729 &entries);
5730 break;
5731 case 3:
5732 if (info->disp_info->groups == NULL) {
5733 info->disp_info->groups = pdb_search_groups();
5734 if (info->disp_info->groups == NULL) {
5735 unbecome_root();
5736 return NT_STATUS_ACCESS_DENIED;
5738 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5739 "starting group enumeration at index %u\n",
5740 (unsigned int)enum_context));
5741 } else {
5742 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5743 "using cached group enumeration at index %u\n",
5744 (unsigned int)enum_context));
5746 num_account = pdb_search_entries(info->disp_info->groups,
5747 enum_context, max_entries,
5748 &entries);
5749 break;
5750 default:
5751 unbecome_root();
5752 smb_panic("info class changed");
5753 break;
5756 unbecome_root();
5758 /* Ensure we cache this enumeration. */
5759 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5761 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5762 r->in.name->string));
5764 for (i=0; i<num_account; i++) {
5765 if (strequal(entries[i].account_name, r->in.name->string)) {
5766 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5767 "found %s at idx %d\n",
5768 r->in.name->string, i));
5769 *r->out.idx = i;
5770 return NT_STATUS_OK;
5774 /* assuming account_name lives at the very end */
5775 *r->out.idx = num_account;
5777 return NT_STATUS_NO_MORE_ENTRIES;
5780 /****************************************************************
5781 _samr_GetDisplayEnumerationIndex2
5782 ****************************************************************/
5784 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5785 struct samr_GetDisplayEnumerationIndex2 *r)
5787 struct samr_GetDisplayEnumerationIndex q;
5789 q.in.domain_handle = r->in.domain_handle;
5790 q.in.level = r->in.level;
5791 q.in.name = r->in.name;
5793 q.out.idx = r->out.idx;
5795 return _samr_GetDisplayEnumerationIndex(p, &q);
5798 /****************************************************************
5799 ****************************************************************/
5801 NTSTATUS _samr_Shutdown(pipes_struct *p,
5802 struct samr_Shutdown *r)
5804 p->rng_fault_state = true;
5805 return NT_STATUS_NOT_IMPLEMENTED;
5808 /****************************************************************
5809 ****************************************************************/
5811 NTSTATUS _samr_CreateUser(pipes_struct *p,
5812 struct samr_CreateUser *r)
5814 p->rng_fault_state = true;
5815 return NT_STATUS_NOT_IMPLEMENTED;
5818 /****************************************************************
5819 ****************************************************************/
5821 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5822 struct samr_SetMemberAttributesOfGroup *r)
5824 p->rng_fault_state = true;
5825 return NT_STATUS_NOT_IMPLEMENTED;
5828 /****************************************************************
5829 ****************************************************************/
5831 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5832 struct samr_ChangePasswordUser *r)
5834 p->rng_fault_state = true;
5835 return NT_STATUS_NOT_IMPLEMENTED;
5838 /****************************************************************
5839 ****************************************************************/
5841 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5842 struct samr_TestPrivateFunctionsDomain *r)
5844 p->rng_fault_state = true;
5845 return NT_STATUS_NOT_IMPLEMENTED;
5848 /****************************************************************
5849 ****************************************************************/
5851 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5852 struct samr_TestPrivateFunctionsUser *r)
5854 p->rng_fault_state = true;
5855 return NT_STATUS_NOT_IMPLEMENTED;
5858 /****************************************************************
5859 ****************************************************************/
5861 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5862 struct samr_QueryUserInfo2 *r)
5864 p->rng_fault_state = true;
5865 return NT_STATUS_NOT_IMPLEMENTED;
5868 /****************************************************************
5869 ****************************************************************/
5871 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5872 struct samr_AddMultipleMembersToAlias *r)
5874 p->rng_fault_state = true;
5875 return NT_STATUS_NOT_IMPLEMENTED;
5878 /****************************************************************
5879 ****************************************************************/
5881 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5882 struct samr_RemoveMultipleMembersFromAlias *r)
5884 p->rng_fault_state = true;
5885 return NT_STATUS_NOT_IMPLEMENTED;
5888 /****************************************************************
5889 ****************************************************************/
5891 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5892 struct samr_OemChangePasswordUser2 *r)
5894 p->rng_fault_state = true;
5895 return NT_STATUS_NOT_IMPLEMENTED;
5898 /****************************************************************
5899 ****************************************************************/
5901 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5902 struct samr_SetBootKeyInformation *r)
5904 p->rng_fault_state = true;
5905 return NT_STATUS_NOT_IMPLEMENTED;
5908 /****************************************************************
5909 ****************************************************************/
5911 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5912 struct samr_GetBootKeyInformation *r)
5914 p->rng_fault_state = true;
5915 return NT_STATUS_NOT_IMPLEMENTED;
5918 /****************************************************************
5919 ****************************************************************/
5921 NTSTATUS _samr_Connect3(pipes_struct *p,
5922 struct samr_Connect3 *r)
5924 p->rng_fault_state = true;
5925 return NT_STATUS_NOT_IMPLEMENTED;
5928 /****************************************************************
5929 ****************************************************************/
5931 NTSTATUS _samr_RidToSid(pipes_struct *p,
5932 struct samr_RidToSid *r)
5934 p->rng_fault_state = true;
5935 return NT_STATUS_NOT_IMPLEMENTED;
5938 /****************************************************************
5939 ****************************************************************/
5941 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5942 struct samr_SetDsrmPassword *r)
5944 p->rng_fault_state = true;
5945 return NT_STATUS_NOT_IMPLEMENTED;
5948 /****************************************************************
5949 ****************************************************************/
5951 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5952 struct samr_ValidatePassword *r)
5954 p->rng_fault_state = true;
5955 return NT_STATUS_NOT_IMPLEMENTED;