Merge commit 'origin/master' into libcli-auth-merge-without-netlogond
[Samba/bb.git] / source3 / rpc_server / srv_samr_nt.c
blobb54ed717a304be54ef0b4da6b480a6e60eea2173
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2008,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
34 #include "includes.h"
35 #include "../libcli/auth/libcli_auth.h"
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_RPC_SRV
40 #define SAMR_USR_RIGHTS_WRITE_PW \
41 ( READ_CONTROL_ACCESS | \
42 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
43 SAMR_USER_ACCESS_SET_LOC_COM)
44 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
45 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
47 #define DISP_INFO_CACHE_TIMEOUT 10
49 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
50 #define MAX_SAM_ENTRIES_W95 50
52 struct samr_connect_info {
53 uint8_t dummy;
56 struct samr_domain_info {
57 struct dom_sid sid;
58 struct disp_info *disp_info;
61 typedef struct disp_info {
62 DOM_SID sid; /* identify which domain this is. */
63 struct pdb_search *users; /* querydispinfo 1 and 4 */
64 struct pdb_search *machines; /* querydispinfo 2 */
65 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
66 struct pdb_search *aliases; /* enumaliases */
68 uint16 enum_acb_mask;
69 struct pdb_search *enum_users; /* enumusers with a mask */
71 struct timed_event *cache_timeout_event; /* cache idle timeout
72 * handler. */
73 } DISP_INFO;
75 /* We keep a static list of these by SID as modern clients close down
76 all resources between each request in a complete enumeration. */
78 struct samr_info {
79 /* for use by the \PIPE\samr policy */
80 DOM_SID sid;
81 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
82 uint32 acc_granted;
83 DISP_INFO *disp_info;
86 static const struct generic_mapping sam_generic_mapping = {
87 GENERIC_RIGHTS_SAM_READ,
88 GENERIC_RIGHTS_SAM_WRITE,
89 GENERIC_RIGHTS_SAM_EXECUTE,
90 GENERIC_RIGHTS_SAM_ALL_ACCESS};
91 static const struct generic_mapping dom_generic_mapping = {
92 GENERIC_RIGHTS_DOMAIN_READ,
93 GENERIC_RIGHTS_DOMAIN_WRITE,
94 GENERIC_RIGHTS_DOMAIN_EXECUTE,
95 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
96 static const struct generic_mapping usr_generic_mapping = {
97 GENERIC_RIGHTS_USER_READ,
98 GENERIC_RIGHTS_USER_WRITE,
99 GENERIC_RIGHTS_USER_EXECUTE,
100 GENERIC_RIGHTS_USER_ALL_ACCESS};
101 static const struct generic_mapping usr_nopwchange_generic_mapping = {
102 GENERIC_RIGHTS_USER_READ,
103 GENERIC_RIGHTS_USER_WRITE,
104 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
105 GENERIC_RIGHTS_USER_ALL_ACCESS};
106 static const struct generic_mapping grp_generic_mapping = {
107 GENERIC_RIGHTS_GROUP_READ,
108 GENERIC_RIGHTS_GROUP_WRITE,
109 GENERIC_RIGHTS_GROUP_EXECUTE,
110 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
111 static const struct generic_mapping ali_generic_mapping = {
112 GENERIC_RIGHTS_ALIAS_READ,
113 GENERIC_RIGHTS_ALIAS_WRITE,
114 GENERIC_RIGHTS_ALIAS_EXECUTE,
115 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
117 /*******************************************************************
118 *******************************************************************/
120 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
121 const struct generic_mapping *map,
122 DOM_SID *sid, uint32 sid_access )
124 DOM_SID domadmin_sid;
125 SEC_ACE ace[5]; /* at most 5 entries */
126 size_t i = 0;
128 SEC_ACL *psa = NULL;
130 /* basic access for Everyone */
132 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
133 map->generic_execute | map->generic_read, 0);
135 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
137 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
138 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
139 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
140 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
142 /* Add Full Access for Domain Admins if we are a DC */
144 if ( IS_DC ) {
145 sid_copy( &domadmin_sid, get_global_sam_sid() );
146 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
147 init_sec_ace(&ace[i++], &domadmin_sid,
148 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
151 /* if we have a sid, give it some special access */
153 if ( sid ) {
154 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
157 /* create the security descriptor */
159 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
160 return NT_STATUS_NO_MEMORY;
162 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
163 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
164 psa, sd_size)) == NULL)
165 return NT_STATUS_NO_MEMORY;
167 return NT_STATUS_OK;
170 /*******************************************************************
171 Checks if access to an object should be granted, and returns that
172 level of access for further checks.
173 ********************************************************************/
175 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
176 SE_PRIV *rights, uint32 rights_mask,
177 uint32 des_access, uint32 *acc_granted,
178 const char *debug )
180 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
181 uint32 saved_mask = 0;
183 /* check privileges; certain SAM access bits should be overridden
184 by privileges (mostly having to do with creating/modifying/deleting
185 users and groups) */
187 if ( rights && user_has_any_privilege( token, rights ) ) {
189 saved_mask = (des_access & rights_mask);
190 des_access &= ~saved_mask;
192 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
193 rights_mask));
197 /* check the security descriptor first */
199 status = se_access_check(psd, token, des_access, acc_granted);
200 if (NT_STATUS_IS_OK(status)) {
201 goto done;
204 /* give root a free pass */
206 if ( geteuid() == sec_initial_uid() ) {
208 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
209 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
211 *acc_granted = des_access;
213 status = NT_STATUS_OK;
214 goto done;
218 done:
219 /* add in any bits saved during the privilege check (only
220 matters is status is ok) */
222 *acc_granted |= rights_mask;
224 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
225 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
226 des_access, *acc_granted));
228 return status;
231 /*******************************************************************
232 Checks if access to a function can be granted
233 ********************************************************************/
235 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
237 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
238 debug, acc_granted, acc_required));
240 /* check the security descriptor first */
242 if ( (acc_granted&acc_required) == acc_required )
243 return NT_STATUS_OK;
245 /* give root a free pass */
247 if (geteuid() == sec_initial_uid()) {
249 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
250 debug, acc_granted, acc_required));
251 DEBUGADD(4,("but overwritten by euid == 0\n"));
253 return NT_STATUS_OK;
256 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
257 debug, acc_granted, acc_required));
259 return NT_STATUS_ACCESS_DENIED;
262 /*******************************************************************
263 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
264 ********************************************************************/
266 static void map_max_allowed_access(const NT_USER_TOKEN *token,
267 uint32_t *pacc_requested)
269 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
270 return;
272 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
274 /* At least try for generic read. */
275 *pacc_requested = GENERIC_READ_ACCESS;
277 /* root gets anything. */
278 if (geteuid() == sec_initial_uid()) {
279 *pacc_requested |= GENERIC_ALL_ACCESS;
280 return;
283 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
285 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
286 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
287 *pacc_requested |= GENERIC_ALL_ACCESS;
288 return;
291 /* Full access for DOMAIN\Domain Admins. */
292 if ( IS_DC ) {
293 DOM_SID domadmin_sid;
294 sid_copy( &domadmin_sid, get_global_sam_sid() );
295 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
296 if (is_sid_in_token(token, &domadmin_sid)) {
297 *pacc_requested |= GENERIC_ALL_ACCESS;
298 return;
301 /* TODO ! Check privileges. */
304 /*******************************************************************
305 Fetch or create a dispinfo struct.
306 ********************************************************************/
308 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
311 * We do a static cache for DISP_INFO's here. Explanation can be found
312 * in Jeremy's checkin message to r11793:
314 * Fix the SAMR cache so it works across completely insane
315 * client behaviour (ie.:
316 * open pipe/open SAMR handle/enumerate 0 - 1024
317 * close SAMR handle, close pipe.
318 * open pipe/open SAMR handle/enumerate 1024 - 2048...
319 * close SAMR handle, close pipe.
320 * And on ad-nausium. Amazing.... probably object-oriented
321 * client side programming in action yet again.
322 * This change should *massively* improve performance when
323 * enumerating users from an LDAP database.
324 * Jeremy.
326 * "Our" and the builtin domain are the only ones where we ever
327 * enumerate stuff, so just cache 2 entries.
330 static struct disp_info *builtin_dispinfo;
331 static struct disp_info *domain_dispinfo;
333 /* There are two cases to consider here:
334 1) The SID is a domain SID and we look for an equality match, or
335 2) This is an account SID and so we return the DISP_INFO* for our
336 domain */
338 if (psid == NULL) {
339 return NULL;
342 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
344 * Necessary only once, but it does not really hurt.
346 if (builtin_dispinfo == NULL) {
347 builtin_dispinfo = talloc_zero(
348 talloc_autofree_context(), struct disp_info);
349 if (builtin_dispinfo == NULL) {
350 return NULL;
353 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
355 return builtin_dispinfo;
358 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
360 * Necessary only once, but it does not really hurt.
362 if (domain_dispinfo == NULL) {
363 domain_dispinfo = talloc_zero(
364 talloc_autofree_context(), struct disp_info);
365 if (domain_dispinfo == NULL) {
366 return NULL;
369 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
371 return domain_dispinfo;
374 return NULL;
377 /*******************************************************************
378 Create a samr_info struct.
379 ********************************************************************/
381 static int samr_info_destructor(struct samr_info *info);
383 static struct samr_info *get_samr_info_by_sid(TALLOC_CTX *mem_ctx,
384 DOM_SID *psid)
386 struct samr_info *info;
388 info = talloc_zero(mem_ctx, struct samr_info);
389 if (info == NULL) {
390 return NULL;
392 talloc_set_destructor(info, samr_info_destructor);
394 DEBUG(10, ("get_samr_info_by_sid: created new info for sid %s\n",
395 sid_string_dbg(psid)));
397 if (psid) {
398 sid_copy( &info->sid, psid);
399 } else {
400 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
403 info->disp_info = get_samr_dispinfo_by_sid(psid);
405 return info;
408 /*******************************************************************
409 Function to free the per SID data.
410 ********************************************************************/
412 static void free_samr_cache(DISP_INFO *disp_info)
414 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
415 sid_string_dbg(&disp_info->sid)));
417 /* We need to become root here because the paged search might have to
418 * tell the LDAP server we're not interested in the rest anymore. */
420 become_root();
422 TALLOC_FREE(disp_info->users);
423 TALLOC_FREE(disp_info->machines);
424 TALLOC_FREE(disp_info->groups);
425 TALLOC_FREE(disp_info->aliases);
426 TALLOC_FREE(disp_info->enum_users);
428 unbecome_root();
431 static int samr_info_destructor(struct samr_info *info)
433 /* Only free the dispinfo cache if no one bothered to set up
434 a timeout. */
436 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
437 free_samr_cache(info->disp_info);
439 return 0;
442 /*******************************************************************
443 Idle event handler. Throw away the disp info cache.
444 ********************************************************************/
446 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
447 struct timed_event *te,
448 struct timeval now,
449 void *private_data)
451 DISP_INFO *disp_info = (DISP_INFO *)private_data;
453 TALLOC_FREE(disp_info->cache_timeout_event);
455 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
456 "out\n"));
457 free_samr_cache(disp_info);
460 /*******************************************************************
461 Setup cache removal idle event handler.
462 ********************************************************************/
464 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
466 /* Remove any pending timeout and update. */
468 TALLOC_FREE(disp_info->cache_timeout_event);
470 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
471 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
472 (unsigned int)secs_fromnow ));
474 disp_info->cache_timeout_event = event_add_timed(
475 smbd_event_context(), NULL,
476 timeval_current_ofs(secs_fromnow, 0),
477 disp_info_cache_idle_timeout_handler, (void *)disp_info);
480 /*******************************************************************
481 Force flush any cache. We do this on any samr_set_xxx call.
482 We must also remove the timeout handler.
483 ********************************************************************/
485 static void force_flush_samr_cache(const struct dom_sid *sid)
487 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
489 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
490 return;
493 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
494 TALLOC_FREE(disp_info->cache_timeout_event);
495 free_samr_cache(disp_info);
498 /*******************************************************************
499 Ensure password info is never given out. Paranioa... JRA.
500 ********************************************************************/
502 static void samr_clear_sam_passwd(struct samu *sam_pass)
505 if (!sam_pass)
506 return;
508 /* These now zero out the old password */
510 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
511 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
514 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
516 struct samr_displayentry *entry;
518 if (sid_check_is_builtin(&info->sid)) {
519 /* No users in builtin. */
520 return 0;
523 if (info->users == NULL) {
524 info->users = pdb_search_users(info, acct_flags);
525 if (info->users == NULL) {
526 return 0;
529 /* Fetch the last possible entry, thus trigger an enumeration */
530 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
532 /* Ensure we cache this enumeration. */
533 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
535 return info->users->num_entries;
538 static uint32 count_sam_groups(struct disp_info *info)
540 struct samr_displayentry *entry;
542 if (sid_check_is_builtin(&info->sid)) {
543 /* No groups in builtin. */
544 return 0;
547 if (info->groups == NULL) {
548 info->groups = pdb_search_groups(info);
549 if (info->groups == NULL) {
550 return 0;
553 /* Fetch the last possible entry, thus trigger an enumeration */
554 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
556 /* Ensure we cache this enumeration. */
557 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
559 return info->groups->num_entries;
562 static uint32 count_sam_aliases(struct disp_info *info)
564 struct samr_displayentry *entry;
566 if (info->aliases == NULL) {
567 info->aliases = pdb_search_aliases(info, &info->sid);
568 if (info->aliases == NULL) {
569 return 0;
572 /* Fetch the last possible entry, thus trigger an enumeration */
573 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
575 /* Ensure we cache this enumeration. */
576 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
578 return info->aliases->num_entries;
581 /*******************************************************************
582 _samr_Close
583 ********************************************************************/
585 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
587 if (!close_policy_hnd(p, r->in.handle)) {
588 return NT_STATUS_INVALID_HANDLE;
591 ZERO_STRUCTP(r->out.handle);
593 return NT_STATUS_OK;
596 /*******************************************************************
597 _samr_OpenDomain
598 ********************************************************************/
600 NTSTATUS _samr_OpenDomain(pipes_struct *p,
601 struct samr_OpenDomain *r)
603 struct samr_connect_info *cinfo;
604 struct samr_domain_info *dinfo;
605 SEC_DESC *psd = NULL;
606 uint32 acc_granted;
607 uint32 des_access = r->in.access_mask;
608 NTSTATUS status;
609 size_t sd_size;
610 SE_PRIV se_rights;
612 /* find the connection policy handle. */
614 cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
615 struct samr_connect_info, &status);
616 if (!NT_STATUS_IS_OK(status)) {
617 return status;
620 /*check if access can be granted as requested by client. */
621 map_max_allowed_access(p->server_info->ptok, &des_access);
623 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
624 se_map_generic( &des_access, &dom_generic_mapping );
626 se_priv_copy( &se_rights, &se_machine_account );
627 se_priv_add( &se_rights, &se_add_users );
629 status = access_check_samr_object( psd, p->server_info->ptok,
630 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
631 &acc_granted, "_samr_OpenDomain" );
633 if ( !NT_STATUS_IS_OK(status) )
634 return status;
636 if (!sid_check_is_domain(r->in.sid) &&
637 !sid_check_is_builtin(r->in.sid)) {
638 return NT_STATUS_NO_SUCH_DOMAIN;
641 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
642 struct samr_domain_info, &status);
643 if (!NT_STATUS_IS_OK(status)) {
644 return status;
646 dinfo->sid = *r->in.sid;
647 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
649 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
651 return NT_STATUS_OK;
654 /*******************************************************************
655 _samr_GetUserPwInfo
656 ********************************************************************/
658 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
659 struct samr_GetUserPwInfo *r)
661 struct samr_info *info = NULL;
662 enum lsa_SidType sid_type;
663 uint32_t min_password_length = 0;
664 uint32_t password_properties = 0;
665 bool ret = false;
666 NTSTATUS status;
668 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
670 /* find the policy handle. open a policy on it. */
671 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
672 return NT_STATUS_INVALID_HANDLE;
675 status = access_check_samr_function(info->acc_granted,
676 SAMR_USER_ACCESS_GET_ATTRIBUTES,
677 "_samr_GetUserPwInfo" );
678 if (!NT_STATUS_IS_OK(status)) {
679 return status;
682 if (!sid_check_is_in_our_domain(&info->sid)) {
683 return NT_STATUS_OBJECT_TYPE_MISMATCH;
686 become_root();
687 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
688 unbecome_root();
689 if (ret == false) {
690 return NT_STATUS_NO_SUCH_USER;
693 switch (sid_type) {
694 case SID_NAME_USER:
695 become_root();
696 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
697 &min_password_length);
698 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
699 &password_properties);
700 unbecome_root();
702 if (lp_check_password_script() && *lp_check_password_script()) {
703 password_properties |= DOMAIN_PASSWORD_COMPLEX;
706 break;
707 default:
708 break;
711 r->out.info->min_password_length = min_password_length;
712 r->out.info->password_properties = password_properties;
714 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
716 return NT_STATUS_OK;
719 /*******************************************************************
720 ********************************************************************/
722 static bool get_lsa_policy_samr_sid( pipes_struct *p, struct policy_handle *pol,
723 DOM_SID *sid, uint32 *acc_granted,
724 DISP_INFO **ppdisp_info)
726 struct samr_info *info = NULL;
728 /* find the policy handle. open a policy on it. */
729 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
730 return False;
732 if (!info)
733 return False;
735 *sid = info->sid;
736 *acc_granted = info->acc_granted;
737 if (ppdisp_info) {
738 *ppdisp_info = info->disp_info;
741 return True;
744 /*******************************************************************
745 _samr_SetSecurity
746 ********************************************************************/
748 NTSTATUS _samr_SetSecurity(pipes_struct *p,
749 struct samr_SetSecurity *r)
751 DOM_SID pol_sid;
752 uint32 acc_granted, i;
753 SEC_ACL *dacl;
754 bool ret;
755 struct samu *sampass=NULL;
756 NTSTATUS status;
758 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
759 return NT_STATUS_INVALID_HANDLE;
761 if (!(sampass = samu_new( p->mem_ctx))) {
762 DEBUG(0,("No memory!\n"));
763 return NT_STATUS_NO_MEMORY;
766 /* get the user record */
767 become_root();
768 ret = pdb_getsampwsid(sampass, &pol_sid);
769 unbecome_root();
771 if (!ret) {
772 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
773 TALLOC_FREE(sampass);
774 return NT_STATUS_INVALID_HANDLE;
777 dacl = r->in.sdbuf->sd->dacl;
778 for (i=0; i < dacl->num_aces; i++) {
779 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
780 ret = pdb_set_pass_can_change(sampass,
781 (dacl->aces[i].access_mask &
782 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
783 True: False);
784 break;
788 if (!ret) {
789 TALLOC_FREE(sampass);
790 return NT_STATUS_ACCESS_DENIED;
793 status = access_check_samr_function(acc_granted,
794 SAMR_USER_ACCESS_SET_ATTRIBUTES,
795 "_samr_SetSecurity");
796 if (NT_STATUS_IS_OK(status)) {
797 become_root();
798 status = pdb_update_sam_account(sampass);
799 unbecome_root();
802 TALLOC_FREE(sampass);
804 return status;
807 /*******************************************************************
808 build correct perms based on policies and password times for _samr_query_sec_obj
809 *******************************************************************/
810 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
812 struct samu *sampass=NULL;
813 bool ret;
815 if ( !(sampass = samu_new( mem_ctx )) ) {
816 DEBUG(0,("No memory!\n"));
817 return False;
820 become_root();
821 ret = pdb_getsampwsid(sampass, user_sid);
822 unbecome_root();
824 if (ret == False) {
825 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
826 TALLOC_FREE(sampass);
827 return False;
830 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
832 if (pdb_get_pass_can_change(sampass)) {
833 TALLOC_FREE(sampass);
834 return True;
836 TALLOC_FREE(sampass);
837 return False;
841 /*******************************************************************
842 _samr_QuerySecurity
843 ********************************************************************/
845 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
846 struct samr_QuerySecurity *r)
848 NTSTATUS status;
849 DOM_SID pol_sid;
850 SEC_DESC * psd = NULL;
851 uint32 acc_granted;
852 size_t sd_size;
854 /* Get the SID. */
855 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
856 return NT_STATUS_INVALID_HANDLE;
858 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
859 sid_string_dbg(&pol_sid)));
861 status = access_check_samr_function(acc_granted,
862 STD_RIGHT_READ_CONTROL_ACCESS,
863 "_samr_QuerySecurity");
864 if (!NT_STATUS_IS_OK(status)) {
865 return status;
868 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
870 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
871 if (pol_sid.sid_rev_num == 0) {
872 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
873 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
874 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
875 /* check if it is our domain SID */
876 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
877 "with SID: %s\n", sid_string_dbg(&pol_sid)));
878 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
879 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
880 /* check if it is the Builtin Domain */
881 /* TODO: Builtin probably needs a different SD with restricted write access*/
882 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
883 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
884 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
885 } else if (sid_check_is_in_our_domain(&pol_sid) ||
886 sid_check_is_in_builtin(&pol_sid)) {
887 /* TODO: different SDs have to be generated for aliases groups and users.
888 Currently all three get a default user SD */
889 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
890 "with SID: %s\n", sid_string_dbg(&pol_sid)));
891 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
892 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
893 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
894 } else {
895 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
896 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
898 } else {
899 return NT_STATUS_OBJECT_TYPE_MISMATCH;
902 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
903 return NT_STATUS_NO_MEMORY;
905 return status;
908 /*******************************************************************
909 makes a SAM_ENTRY / UNISTR2* structure from a user list.
910 ********************************************************************/
912 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
913 struct samr_SamEntry **sam_pp,
914 uint32_t num_entries,
915 uint32_t start_idx,
916 struct samr_displayentry *entries)
918 uint32_t i;
919 struct samr_SamEntry *sam;
921 *sam_pp = NULL;
923 if (num_entries == 0) {
924 return NT_STATUS_OK;
927 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
928 if (sam == NULL) {
929 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
930 return NT_STATUS_NO_MEMORY;
933 for (i = 0; i < num_entries; i++) {
934 #if 0
936 * usrmgr expects a non-NULL terminated string with
937 * trust relationships
939 if (entries[i].acct_flags & ACB_DOMTRUST) {
940 init_unistr2(&uni_temp_name, entries[i].account_name,
941 UNI_FLAGS_NONE);
942 } else {
943 init_unistr2(&uni_temp_name, entries[i].account_name,
944 UNI_STR_TERMINATE);
946 #endif
947 init_lsa_String(&sam[i].name, entries[i].account_name);
948 sam[i].idx = entries[i].rid;
951 *sam_pp = sam;
953 return NT_STATUS_OK;
956 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
958 /*******************************************************************
959 _samr_EnumDomainUsers
960 ********************************************************************/
962 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
963 struct samr_EnumDomainUsers *r)
965 NTSTATUS status;
966 struct samr_domain_info *dinfo;
967 int num_account;
968 uint32 enum_context = *r->in.resume_handle;
969 enum remote_arch_types ra_type = get_remote_arch();
970 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
971 uint32 max_entries = max_sam_entries;
972 struct samr_displayentry *entries = NULL;
973 struct samr_SamArray *samr_array = NULL;
974 struct samr_SamEntry *samr_entries = NULL;
976 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
978 dinfo = policy_handle_find(p, r->in.domain_handle,
979 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
980 struct samr_domain_info, &status);
981 if (!NT_STATUS_IS_OK(status)) {
982 return status;
985 if (sid_check_is_builtin(&dinfo->sid)) {
986 /* No users in builtin. */
987 *r->out.resume_handle = *r->in.resume_handle;
988 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
989 return status;
992 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
993 if (!samr_array) {
994 return NT_STATUS_NO_MEMORY;
996 *r->out.sam = samr_array;
998 become_root();
1000 /* AS ROOT !!!! */
1002 if ((dinfo->disp_info->enum_users != NULL) &&
1003 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
1004 TALLOC_FREE(dinfo->disp_info->enum_users);
1007 if (dinfo->disp_info->enum_users == NULL) {
1008 dinfo->disp_info->enum_users = pdb_search_users(
1009 dinfo->disp_info, r->in.acct_flags);
1010 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
1013 if (dinfo->disp_info->enum_users == NULL) {
1014 /* END AS ROOT !!!! */
1015 unbecome_root();
1016 return NT_STATUS_ACCESS_DENIED;
1019 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
1020 enum_context, max_entries,
1021 &entries);
1023 /* END AS ROOT !!!! */
1025 unbecome_root();
1027 if (num_account == 0) {
1028 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1029 "total entries\n"));
1030 *r->out.resume_handle = *r->in.resume_handle;
1031 return NT_STATUS_OK;
1034 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1035 num_account, enum_context,
1036 entries);
1037 if (!NT_STATUS_IS_OK(status)) {
1038 return status;
1041 if (max_entries <= num_account) {
1042 status = STATUS_MORE_ENTRIES;
1043 } else {
1044 status = NT_STATUS_OK;
1047 /* Ensure we cache this enumeration. */
1048 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1050 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1052 samr_array->count = num_account;
1053 samr_array->entries = samr_entries;
1055 *r->out.resume_handle = *r->in.resume_handle + num_account;
1056 *r->out.num_entries = num_account;
1058 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1060 return status;
1063 /*******************************************************************
1064 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1065 ********************************************************************/
1067 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1068 struct samr_SamEntry **sam_pp,
1069 uint32_t num_sam_entries,
1070 struct samr_displayentry *entries)
1072 struct samr_SamEntry *sam;
1073 uint32_t i;
1075 *sam_pp = NULL;
1077 if (num_sam_entries == 0) {
1078 return;
1081 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1082 if (sam == NULL) {
1083 return;
1086 for (i = 0; i < num_sam_entries; i++) {
1088 * JRA. I think this should include the null. TNG does not.
1090 init_lsa_String(&sam[i].name, entries[i].account_name);
1091 sam[i].idx = entries[i].rid;
1094 *sam_pp = sam;
1097 /*******************************************************************
1098 _samr_EnumDomainGroups
1099 ********************************************************************/
1101 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1102 struct samr_EnumDomainGroups *r)
1104 NTSTATUS status;
1105 struct samr_domain_info *dinfo;
1106 struct samr_displayentry *groups;
1107 uint32 num_groups;
1108 struct samr_SamArray *samr_array = NULL;
1109 struct samr_SamEntry *samr_entries = NULL;
1111 dinfo = policy_handle_find(p, r->in.domain_handle,
1112 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1113 struct samr_domain_info, &status);
1114 if (!NT_STATUS_IS_OK(status)) {
1115 return status;
1118 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1120 if (sid_check_is_builtin(&dinfo->sid)) {
1121 /* No groups in builtin. */
1122 *r->out.resume_handle = *r->in.resume_handle;
1123 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1124 return status;
1127 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1128 if (!samr_array) {
1129 return NT_STATUS_NO_MEMORY;
1132 /* the domain group array is being allocated in the function below */
1134 become_root();
1136 if (dinfo->disp_info->groups == NULL) {
1137 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1139 if (dinfo->disp_info->groups == NULL) {
1140 unbecome_root();
1141 return NT_STATUS_ACCESS_DENIED;
1145 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1146 *r->in.resume_handle,
1147 MAX_SAM_ENTRIES, &groups);
1148 unbecome_root();
1150 /* Ensure we cache this enumeration. */
1151 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1153 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1154 num_groups, groups);
1156 samr_array->count = num_groups;
1157 samr_array->entries = samr_entries;
1159 *r->out.sam = samr_array;
1160 *r->out.num_entries = num_groups;
1161 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1163 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1165 return status;
1168 /*******************************************************************
1169 _samr_EnumDomainAliases
1170 ********************************************************************/
1172 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1173 struct samr_EnumDomainAliases *r)
1175 NTSTATUS status;
1176 struct samr_domain_info *dinfo;
1177 struct samr_displayentry *aliases;
1178 uint32 num_aliases = 0;
1179 struct samr_SamArray *samr_array = NULL;
1180 struct samr_SamEntry *samr_entries = NULL;
1182 dinfo = policy_handle_find(p, r->in.domain_handle,
1183 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1184 struct samr_domain_info, &status);
1185 if (!NT_STATUS_IS_OK(status)) {
1186 return status;
1189 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1190 sid_string_dbg(&dinfo->sid)));
1192 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1193 if (!samr_array) {
1194 return NT_STATUS_NO_MEMORY;
1197 become_root();
1199 if (dinfo->disp_info->aliases == NULL) {
1200 dinfo->disp_info->aliases = pdb_search_aliases(
1201 dinfo->disp_info, &dinfo->sid);
1202 if (dinfo->disp_info->aliases == NULL) {
1203 unbecome_root();
1204 return NT_STATUS_ACCESS_DENIED;
1208 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1209 *r->in.resume_handle,
1210 MAX_SAM_ENTRIES, &aliases);
1211 unbecome_root();
1213 /* Ensure we cache this enumeration. */
1214 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1216 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1217 num_aliases, aliases);
1219 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1221 samr_array->count = num_aliases;
1222 samr_array->entries = samr_entries;
1224 *r->out.sam = samr_array;
1225 *r->out.num_entries = num_aliases;
1226 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1228 return status;
1231 /*******************************************************************
1232 inits a samr_DispInfoGeneral structure.
1233 ********************************************************************/
1235 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1236 struct samr_DispInfoGeneral *r,
1237 uint32_t num_entries,
1238 uint32_t start_idx,
1239 struct samr_displayentry *entries)
1241 uint32 i;
1243 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1245 if (num_entries == 0) {
1246 return NT_STATUS_OK;
1249 r->count = num_entries;
1251 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1252 if (!r->entries) {
1253 return NT_STATUS_NO_MEMORY;
1256 for (i = 0; i < num_entries ; i++) {
1258 init_lsa_String(&r->entries[i].account_name,
1259 entries[i].account_name);
1261 init_lsa_String(&r->entries[i].description,
1262 entries[i].description);
1264 init_lsa_String(&r->entries[i].full_name,
1265 entries[i].fullname);
1267 r->entries[i].rid = entries[i].rid;
1268 r->entries[i].acct_flags = entries[i].acct_flags;
1269 r->entries[i].idx = start_idx+i+1;
1272 return NT_STATUS_OK;
1275 /*******************************************************************
1276 inits a samr_DispInfoFull structure.
1277 ********************************************************************/
1279 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1280 struct samr_DispInfoFull *r,
1281 uint32_t num_entries,
1282 uint32_t start_idx,
1283 struct samr_displayentry *entries)
1285 uint32_t i;
1287 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1289 if (num_entries == 0) {
1290 return NT_STATUS_OK;
1293 r->count = num_entries;
1295 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1296 if (!r->entries) {
1297 return NT_STATUS_NO_MEMORY;
1300 for (i = 0; i < num_entries ; i++) {
1302 init_lsa_String(&r->entries[i].account_name,
1303 entries[i].account_name);
1305 init_lsa_String(&r->entries[i].description,
1306 entries[i].description);
1308 r->entries[i].rid = entries[i].rid;
1309 r->entries[i].acct_flags = entries[i].acct_flags;
1310 r->entries[i].idx = start_idx+i+1;
1313 return NT_STATUS_OK;
1316 /*******************************************************************
1317 inits a samr_DispInfoFullGroups structure.
1318 ********************************************************************/
1320 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1321 struct samr_DispInfoFullGroups *r,
1322 uint32_t num_entries,
1323 uint32_t start_idx,
1324 struct samr_displayentry *entries)
1326 uint32_t i;
1328 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1330 if (num_entries == 0) {
1331 return NT_STATUS_OK;
1334 r->count = num_entries;
1336 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1337 if (!r->entries) {
1338 return NT_STATUS_NO_MEMORY;
1341 for (i = 0; i < num_entries ; i++) {
1343 init_lsa_String(&r->entries[i].account_name,
1344 entries[i].account_name);
1346 init_lsa_String(&r->entries[i].description,
1347 entries[i].description);
1349 r->entries[i].rid = entries[i].rid;
1350 r->entries[i].acct_flags = entries[i].acct_flags;
1351 r->entries[i].idx = start_idx+i+1;
1354 return NT_STATUS_OK;
1357 /*******************************************************************
1358 inits a samr_DispInfoAscii structure.
1359 ********************************************************************/
1361 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1362 struct samr_DispInfoAscii *r,
1363 uint32_t num_entries,
1364 uint32_t start_idx,
1365 struct samr_displayentry *entries)
1367 uint32_t i;
1369 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1371 if (num_entries == 0) {
1372 return NT_STATUS_OK;
1375 r->count = num_entries;
1377 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1378 if (!r->entries) {
1379 return NT_STATUS_NO_MEMORY;
1382 for (i = 0; i < num_entries ; i++) {
1384 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1385 entries[i].account_name);
1387 r->entries[i].idx = start_idx+i+1;
1390 return NT_STATUS_OK;
1393 /*******************************************************************
1394 inits a samr_DispInfoAscii structure.
1395 ********************************************************************/
1397 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1398 struct samr_DispInfoAscii *r,
1399 uint32_t num_entries,
1400 uint32_t start_idx,
1401 struct samr_displayentry *entries)
1403 uint32_t i;
1405 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1407 if (num_entries == 0) {
1408 return NT_STATUS_OK;
1411 r->count = num_entries;
1413 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1414 if (!r->entries) {
1415 return NT_STATUS_NO_MEMORY;
1418 for (i = 0; i < num_entries ; i++) {
1420 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1421 entries[i].account_name);
1423 r->entries[i].idx = start_idx+i+1;
1426 return NT_STATUS_OK;
1429 /*******************************************************************
1430 _samr_QueryDisplayInfo
1431 ********************************************************************/
1433 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1434 struct samr_QueryDisplayInfo *r)
1436 NTSTATUS status;
1437 struct samr_domain_info *dinfo;
1438 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1440 uint32 max_entries = r->in.max_entries;
1441 uint32 enum_context = r->in.start_idx;
1442 uint32 max_size = r->in.buf_size;
1444 union samr_DispInfo *disp_info = r->out.info;
1446 uint32 temp_size=0, total_data_size=0;
1447 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1448 uint32 num_account = 0;
1449 enum remote_arch_types ra_type = get_remote_arch();
1450 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1451 struct samr_displayentry *entries = NULL;
1453 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1455 dinfo = policy_handle_find(p, r->in.domain_handle,
1456 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1457 struct samr_domain_info, &status);
1458 if (!NT_STATUS_IS_OK(status)) {
1459 return status;
1463 * calculate how many entries we will return.
1464 * based on
1465 * - the number of entries the client asked
1466 * - our limit on that
1467 * - the starting point (enumeration context)
1468 * - the buffer size the client will accept
1472 * We are a lot more like W2K. Instead of reading the SAM
1473 * each time to find the records we need to send back,
1474 * we read it once and link that copy to the sam handle.
1475 * For large user list (over the MAX_SAM_ENTRIES)
1476 * it's a definitive win.
1477 * second point to notice: between enumerations
1478 * our sam is now the same as it's a snapshoot.
1479 * third point: got rid of the static SAM_USER_21 struct
1480 * no more intermediate.
1481 * con: it uses much more memory, as a full copy is stored
1482 * in memory.
1484 * If you want to change it, think twice and think
1485 * of the second point , that's really important.
1487 * JFM, 12/20/2001
1490 if ((r->in.level < 1) || (r->in.level > 5)) {
1491 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1492 (unsigned int)r->in.level ));
1493 return NT_STATUS_INVALID_INFO_CLASS;
1496 /* first limit the number of entries we will return */
1497 if(max_entries > max_sam_entries) {
1498 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1499 "entries, limiting to %d\n", max_entries,
1500 max_sam_entries));
1501 max_entries = max_sam_entries;
1504 /* calculate the size and limit on the number of entries we will
1505 * return */
1507 temp_size=max_entries*struct_size;
1509 if (temp_size>max_size) {
1510 max_entries=MIN((max_size/struct_size),max_entries);;
1511 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1512 "only %d entries\n", max_entries));
1515 become_root();
1517 /* THe following done as ROOT. Don't return without unbecome_root(). */
1519 switch (r->in.level) {
1520 case 0x1:
1521 case 0x4:
1522 if (dinfo->disp_info->users == NULL) {
1523 dinfo->disp_info->users = pdb_search_users(
1524 dinfo->disp_info, ACB_NORMAL);
1525 if (dinfo->disp_info->users == NULL) {
1526 unbecome_root();
1527 return NT_STATUS_ACCESS_DENIED;
1529 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1530 (unsigned int)enum_context ));
1531 } else {
1532 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1533 (unsigned int)enum_context ));
1536 num_account = pdb_search_entries(dinfo->disp_info->users,
1537 enum_context, max_entries,
1538 &entries);
1539 break;
1540 case 0x2:
1541 if (dinfo->disp_info->machines == NULL) {
1542 dinfo->disp_info->machines = pdb_search_users(
1543 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1544 if (dinfo->disp_info->machines == NULL) {
1545 unbecome_root();
1546 return NT_STATUS_ACCESS_DENIED;
1548 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1549 (unsigned int)enum_context ));
1550 } else {
1551 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1552 (unsigned int)enum_context ));
1555 num_account = pdb_search_entries(dinfo->disp_info->machines,
1556 enum_context, max_entries,
1557 &entries);
1558 break;
1559 case 0x3:
1560 case 0x5:
1561 if (dinfo->disp_info->groups == NULL) {
1562 dinfo->disp_info->groups = pdb_search_groups(
1563 dinfo->disp_info);
1564 if (dinfo->disp_info->groups == NULL) {
1565 unbecome_root();
1566 return NT_STATUS_ACCESS_DENIED;
1568 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1569 (unsigned int)enum_context ));
1570 } else {
1571 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1572 (unsigned int)enum_context ));
1575 num_account = pdb_search_entries(dinfo->disp_info->groups,
1576 enum_context, max_entries,
1577 &entries);
1578 break;
1579 default:
1580 unbecome_root();
1581 smb_panic("info class changed");
1582 break;
1584 unbecome_root();
1587 /* Now create reply structure */
1588 switch (r->in.level) {
1589 case 0x1:
1590 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1591 num_account, enum_context,
1592 entries);
1593 break;
1594 case 0x2:
1595 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1596 num_account, enum_context,
1597 entries);
1598 break;
1599 case 0x3:
1600 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1601 num_account, enum_context,
1602 entries);
1603 break;
1604 case 0x4:
1605 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1606 num_account, enum_context,
1607 entries);
1608 break;
1609 case 0x5:
1610 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1611 num_account, enum_context,
1612 entries);
1613 break;
1614 default:
1615 smb_panic("info class changed");
1616 break;
1619 if (!NT_STATUS_IS_OK(disp_ret))
1620 return disp_ret;
1622 /* calculate the total size */
1623 total_data_size=num_account*struct_size;
1625 if (max_entries <= num_account) {
1626 status = STATUS_MORE_ENTRIES;
1627 } else {
1628 status = NT_STATUS_OK;
1631 /* Ensure we cache this enumeration. */
1632 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1634 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1636 *r->out.total_size = total_data_size;
1637 *r->out.returned_size = temp_size;
1639 return status;
1642 /****************************************************************
1643 _samr_QueryDisplayInfo2
1644 ****************************************************************/
1646 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1647 struct samr_QueryDisplayInfo2 *r)
1649 struct samr_QueryDisplayInfo q;
1651 q.in.domain_handle = r->in.domain_handle;
1652 q.in.level = r->in.level;
1653 q.in.start_idx = r->in.start_idx;
1654 q.in.max_entries = r->in.max_entries;
1655 q.in.buf_size = r->in.buf_size;
1657 q.out.total_size = r->out.total_size;
1658 q.out.returned_size = r->out.returned_size;
1659 q.out.info = r->out.info;
1661 return _samr_QueryDisplayInfo(p, &q);
1664 /****************************************************************
1665 _samr_QueryDisplayInfo3
1666 ****************************************************************/
1668 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1669 struct samr_QueryDisplayInfo3 *r)
1671 struct samr_QueryDisplayInfo q;
1673 q.in.domain_handle = r->in.domain_handle;
1674 q.in.level = r->in.level;
1675 q.in.start_idx = r->in.start_idx;
1676 q.in.max_entries = r->in.max_entries;
1677 q.in.buf_size = r->in.buf_size;
1679 q.out.total_size = r->out.total_size;
1680 q.out.returned_size = r->out.returned_size;
1681 q.out.info = r->out.info;
1683 return _samr_QueryDisplayInfo(p, &q);
1686 /*******************************************************************
1687 _samr_QueryAliasInfo
1688 ********************************************************************/
1690 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1691 struct samr_QueryAliasInfo *r)
1693 DOM_SID sid;
1694 struct acct_info info;
1695 uint32 acc_granted;
1696 NTSTATUS status;
1697 union samr_AliasInfo *alias_info = NULL;
1698 const char *alias_name = NULL;
1699 const char *alias_description = NULL;
1701 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1703 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1704 if (!alias_info) {
1705 return NT_STATUS_NO_MEMORY;
1708 /* find the policy handle. open a policy on it. */
1709 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1710 return NT_STATUS_INVALID_HANDLE;
1712 status = access_check_samr_function(acc_granted,
1713 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1714 "_samr_QueryAliasInfo");
1715 if (!NT_STATUS_IS_OK(status)) {
1716 return status;
1719 become_root();
1720 status = pdb_get_aliasinfo(&sid, &info);
1721 unbecome_root();
1723 if ( !NT_STATUS_IS_OK(status))
1724 return status;
1726 /* FIXME: info contains fstrings */
1727 alias_name = talloc_strdup(r, info.acct_name);
1728 alias_description = talloc_strdup(r, info.acct_desc);
1730 switch (r->in.level) {
1731 case ALIASINFOALL:
1732 alias_info->all.name.string = alias_name;
1733 alias_info->all.num_members = 1; /* ??? */
1734 alias_info->all.description.string = alias_description;
1735 break;
1736 case ALIASINFODESCRIPTION:
1737 alias_info->description.string = alias_description;
1738 break;
1739 default:
1740 return NT_STATUS_INVALID_INFO_CLASS;
1743 *r->out.info = alias_info;
1745 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1747 return NT_STATUS_OK;
1750 /*******************************************************************
1751 _samr_LookupNames
1752 ********************************************************************/
1754 NTSTATUS _samr_LookupNames(pipes_struct *p,
1755 struct samr_LookupNames *r)
1757 struct samr_domain_info *dinfo;
1758 NTSTATUS status;
1759 uint32 *rid;
1760 enum lsa_SidType *type;
1761 int i;
1762 int num_rids = r->in.num_names;
1763 struct samr_Ids rids, types;
1764 uint32_t num_mapped = 0;
1766 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1768 dinfo = policy_handle_find(p, r->in.domain_handle,
1769 0 /* Don't know the acc_bits yet */, NULL,
1770 struct samr_domain_info, &status);
1771 if (!NT_STATUS_IS_OK(status)) {
1772 return status;
1775 if (num_rids > MAX_SAM_ENTRIES) {
1776 num_rids = MAX_SAM_ENTRIES;
1777 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1780 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1781 NT_STATUS_HAVE_NO_MEMORY(rid);
1783 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1784 NT_STATUS_HAVE_NO_MEMORY(type);
1786 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1787 sid_string_dbg(&dinfo->sid)));
1789 for (i = 0; i < num_rids; i++) {
1791 status = NT_STATUS_NONE_MAPPED;
1792 type[i] = SID_NAME_UNKNOWN;
1794 rid[i] = 0xffffffff;
1796 if (sid_check_is_builtin(&dinfo->sid)) {
1797 if (lookup_builtin_name(r->in.names[i].string,
1798 &rid[i]))
1800 type[i] = SID_NAME_ALIAS;
1802 } else {
1803 lookup_global_sam_name(r->in.names[i].string, 0,
1804 &rid[i], &type[i]);
1807 if (type[i] != SID_NAME_UNKNOWN) {
1808 num_mapped++;
1812 if (num_mapped == num_rids) {
1813 status = NT_STATUS_OK;
1814 } else if (num_mapped == 0) {
1815 status = NT_STATUS_NONE_MAPPED;
1816 } else {
1817 status = STATUS_SOME_UNMAPPED;
1820 rids.count = num_rids;
1821 rids.ids = rid;
1823 types.count = num_rids;
1824 types.ids = type;
1826 *r->out.rids = rids;
1827 *r->out.types = types;
1829 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1831 return status;
1834 /*******************************************************************
1835 _samr_ChangePasswordUser2
1836 ********************************************************************/
1838 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1839 struct samr_ChangePasswordUser2 *r)
1841 NTSTATUS status;
1842 fstring user_name;
1843 fstring wks;
1845 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1847 fstrcpy(user_name, r->in.account->string);
1848 fstrcpy(wks, r->in.server->string);
1850 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1853 * Pass the user through the NT -> unix user mapping
1854 * function.
1857 (void)map_username(user_name);
1860 * UNIX username case mangling not required, pass_oem_change
1861 * is case insensitive.
1864 status = pass_oem_change(user_name,
1865 r->in.lm_password->data,
1866 r->in.lm_verifier->hash,
1867 r->in.nt_password->data,
1868 r->in.nt_verifier->hash,
1869 NULL);
1871 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1873 return status;
1876 /*******************************************************************
1877 _samr_ChangePasswordUser3
1878 ********************************************************************/
1880 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1881 struct samr_ChangePasswordUser3 *r)
1883 NTSTATUS status;
1884 fstring user_name;
1885 const char *wks = NULL;
1886 uint32 reject_reason;
1887 struct samr_DomInfo1 *dominfo = NULL;
1888 struct samr_ChangeReject *reject = NULL;
1889 uint32_t tmp;
1891 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1893 fstrcpy(user_name, r->in.account->string);
1894 if (r->in.server && r->in.server->string) {
1895 wks = r->in.server->string;
1898 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1901 * Pass the user through the NT -> unix user mapping
1902 * function.
1905 (void)map_username(user_name);
1908 * UNIX username case mangling not required, pass_oem_change
1909 * is case insensitive.
1912 status = pass_oem_change(user_name,
1913 r->in.lm_password->data,
1914 r->in.lm_verifier->hash,
1915 r->in.nt_password->data,
1916 r->in.nt_verifier->hash,
1917 &reject_reason);
1919 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1920 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1922 time_t u_expire, u_min_age;
1923 uint32 account_policy_temp;
1925 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1926 if (!dominfo) {
1927 return NT_STATUS_NO_MEMORY;
1930 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1931 if (!reject) {
1932 return NT_STATUS_NO_MEMORY;
1935 become_root();
1937 /* AS ROOT !!! */
1939 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
1940 dominfo->min_password_length = tmp;
1942 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
1943 dominfo->password_history_length = tmp;
1945 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
1946 &dominfo->password_properties);
1948 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1949 u_expire = account_policy_temp;
1951 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1952 u_min_age = account_policy_temp;
1954 /* !AS ROOT */
1956 unbecome_root();
1958 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
1959 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
1961 if (lp_check_password_script() && *lp_check_password_script()) {
1962 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
1965 reject->reason = reject_reason;
1967 *r->out.dominfo = dominfo;
1968 *r->out.reject = reject;
1971 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1973 return status;
1976 /*******************************************************************
1977 makes a SAMR_R_LOOKUP_RIDS structure.
1978 ********************************************************************/
1980 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1981 const char **names,
1982 struct lsa_String **lsa_name_array_p)
1984 struct lsa_String *lsa_name_array = NULL;
1985 uint32_t i;
1987 *lsa_name_array_p = NULL;
1989 if (num_names != 0) {
1990 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
1991 if (!lsa_name_array) {
1992 return false;
1996 for (i = 0; i < num_names; i++) {
1997 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
1998 init_lsa_String(&lsa_name_array[i], names[i]);
2001 *lsa_name_array_p = lsa_name_array;
2003 return true;
2006 /*******************************************************************
2007 _samr_LookupRids
2008 ********************************************************************/
2010 NTSTATUS _samr_LookupRids(pipes_struct *p,
2011 struct samr_LookupRids *r)
2013 struct samr_domain_info *dinfo;
2014 NTSTATUS status;
2015 const char **names;
2016 enum lsa_SidType *attrs = NULL;
2017 uint32 *wire_attrs = NULL;
2018 int num_rids = (int)r->in.num_rids;
2019 int i;
2020 struct lsa_Strings names_array;
2021 struct samr_Ids types_array;
2022 struct lsa_String *lsa_names = NULL;
2024 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2026 dinfo = policy_handle_find(p, r->in.domain_handle,
2027 0 /* Don't know the acc_bits yet */, NULL,
2028 struct samr_domain_info, &status);
2029 if (!NT_STATUS_IS_OK(status)) {
2030 return status;
2033 if (num_rids > 1000) {
2034 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2035 "to samba4 idl this is not possible\n", num_rids));
2036 return NT_STATUS_UNSUCCESSFUL;
2039 if (num_rids) {
2040 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2041 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2042 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2044 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2045 return NT_STATUS_NO_MEMORY;
2046 } else {
2047 names = NULL;
2048 attrs = NULL;
2049 wire_attrs = NULL;
2052 become_root(); /* lookup_sid can require root privs */
2053 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2054 names, attrs);
2055 unbecome_root();
2057 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2058 status = NT_STATUS_OK;
2061 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2062 &lsa_names)) {
2063 return NT_STATUS_NO_MEMORY;
2066 /* Convert from enum lsa_SidType to uint32 for wire format. */
2067 for (i = 0; i < num_rids; i++) {
2068 wire_attrs[i] = (uint32)attrs[i];
2071 names_array.count = num_rids;
2072 names_array.names = lsa_names;
2074 types_array.count = num_rids;
2075 types_array.ids = wire_attrs;
2077 *r->out.names = names_array;
2078 *r->out.types = types_array;
2080 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2082 return status;
2085 /*******************************************************************
2086 _samr_OpenUser
2087 ********************************************************************/
2089 NTSTATUS _samr_OpenUser(pipes_struct *p,
2090 struct samr_OpenUser *r)
2092 struct samu *sampass=NULL;
2093 DOM_SID sid;
2094 struct samr_domain_info *dinfo;
2095 struct samr_info *info;
2096 SEC_DESC *psd = NULL;
2097 uint32 acc_granted;
2098 uint32 des_access = r->in.access_mask;
2099 size_t sd_size;
2100 bool ret;
2101 NTSTATUS nt_status;
2102 SE_PRIV se_rights;
2103 NTSTATUS status;
2105 dinfo = policy_handle_find(p, r->in.domain_handle,
2106 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2107 struct samr_domain_info, &status);
2108 if (!NT_STATUS_IS_OK(status)) {
2109 return status;
2112 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2113 return NT_STATUS_NO_MEMORY;
2116 /* append the user's RID to it */
2118 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2119 return NT_STATUS_NO_SUCH_USER;
2121 /* check if access can be granted as requested by client. */
2123 map_max_allowed_access(p->server_info->ptok, &des_access);
2125 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2126 se_map_generic(&des_access, &usr_generic_mapping);
2128 se_priv_copy( &se_rights, &se_machine_account );
2129 se_priv_add( &se_rights, &se_add_users );
2131 nt_status = access_check_samr_object(psd, p->server_info->ptok,
2132 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2133 &acc_granted, "_samr_OpenUser");
2135 if ( !NT_STATUS_IS_OK(nt_status) )
2136 return nt_status;
2138 become_root();
2139 ret=pdb_getsampwsid(sampass, &sid);
2140 unbecome_root();
2142 /* check that the SID exists in our domain. */
2143 if (ret == False) {
2144 return NT_STATUS_NO_SUCH_USER;
2147 TALLOC_FREE(sampass);
2149 /* associate the user's SID and access bits with the new handle. */
2150 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
2151 return NT_STATUS_NO_MEMORY;
2152 info->acc_granted = acc_granted;
2154 /* get a (unique) handle. open a policy on it. */
2155 if (!create_policy_hnd(p, r->out.user_handle, info))
2156 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2158 return NT_STATUS_OK;
2161 /*************************************************************************
2162 *************************************************************************/
2164 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2165 DATA_BLOB *blob,
2166 struct lsa_BinaryString **_r)
2168 struct lsa_BinaryString *r;
2170 if (!blob || !_r) {
2171 return NT_STATUS_INVALID_PARAMETER;
2174 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2175 if (!r) {
2176 return NT_STATUS_NO_MEMORY;
2179 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2180 if (!r->array) {
2181 return NT_STATUS_NO_MEMORY;
2183 memcpy(r->array, blob->data, blob->length);
2184 r->size = blob->length;
2185 r->length = blob->length;
2187 if (!r->array) {
2188 return NT_STATUS_NO_MEMORY;
2191 *_r = r;
2193 return NT_STATUS_OK;
2196 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2197 struct samr_UserInfo5 *r,
2198 struct samu *pw,
2199 DOM_SID *domain_sid)
2201 const DOM_SID *sid_user, *sid_group;
2202 uint32_t rid, primary_gid;
2204 sid_user = pdb_get_user_sid(pw);
2206 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2207 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2208 "the domain sid %s. Failing operation.\n",
2209 pdb_get_username(pw), sid_string_dbg(sid_user),
2210 sid_string_dbg(domain_sid)));
2211 return NT_STATUS_UNSUCCESSFUL;
2214 become_root();
2215 sid_group = pdb_get_group_sid(pw);
2216 unbecome_root();
2218 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2219 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2220 "which conflicts with the domain sid %s. Failing operation.\n",
2221 pdb_get_username(pw), sid_string_dbg(sid_group),
2222 sid_string_dbg(domain_sid)));
2223 return NT_STATUS_UNSUCCESSFUL;
2226 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2227 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2228 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2229 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2231 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2232 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2233 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2234 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2235 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2236 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2237 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2238 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2240 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2241 r->rid = rid;
2242 r->primary_gid = primary_gid;
2243 r->acct_flags = pdb_get_acct_ctrl(pw);
2244 r->bad_password_count = pdb_get_bad_password_count(pw);
2245 r->logon_count = pdb_get_logon_count(pw);
2247 return NT_STATUS_OK;
2250 /*************************************************************************
2251 get_user_info_7. Safe. Only gives out account_name.
2252 *************************************************************************/
2254 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2255 struct samr_UserInfo7 *r,
2256 struct samu *smbpass)
2258 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2259 if (!r->account_name.string) {
2260 return NT_STATUS_NO_MEMORY;
2263 return NT_STATUS_OK;
2266 /*************************************************************************
2267 get_user_info_9. Only gives out primary group SID.
2268 *************************************************************************/
2270 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2271 struct samr_UserInfo9 *r,
2272 struct samu *smbpass)
2274 r->primary_gid = pdb_get_group_rid(smbpass);
2276 return NT_STATUS_OK;
2279 /*************************************************************************
2280 get_user_info_16. Safe. Only gives out acb bits.
2281 *************************************************************************/
2283 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2284 struct samr_UserInfo16 *r,
2285 struct samu *smbpass)
2287 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2289 return NT_STATUS_OK;
2292 /*************************************************************************
2293 get_user_info_18. OK - this is the killer as it gives out password info.
2294 Ensure that this is only allowed on an encrypted connection with a root
2295 user. JRA.
2296 *************************************************************************/
2298 static NTSTATUS get_user_info_18(pipes_struct *p,
2299 TALLOC_CTX *mem_ctx,
2300 struct samr_UserInfo18 *r,
2301 DOM_SID *user_sid)
2303 struct samu *smbpass=NULL;
2304 bool ret;
2306 ZERO_STRUCTP(r);
2308 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2309 return NT_STATUS_ACCESS_DENIED;
2312 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2313 return NT_STATUS_ACCESS_DENIED;
2317 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2320 if ( !(smbpass = samu_new( mem_ctx )) ) {
2321 return NT_STATUS_NO_MEMORY;
2324 ret = pdb_getsampwsid(smbpass, user_sid);
2326 if (ret == False) {
2327 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2328 TALLOC_FREE(smbpass);
2329 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2332 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2334 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2335 TALLOC_FREE(smbpass);
2336 return NT_STATUS_ACCOUNT_DISABLED;
2339 r->lm_pwd_active = true;
2340 r->nt_pwd_active = true;
2341 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2342 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2343 r->password_expired = 0; /* FIXME */
2345 TALLOC_FREE(smbpass);
2347 return NT_STATUS_OK;
2350 /*************************************************************************
2351 get_user_info_20
2352 *************************************************************************/
2354 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2355 struct samr_UserInfo20 *r,
2356 struct samu *sampass)
2358 const char *munged_dial = NULL;
2359 DATA_BLOB blob;
2360 NTSTATUS status;
2361 struct lsa_BinaryString *parameters = NULL;
2363 ZERO_STRUCTP(r);
2365 munged_dial = pdb_get_munged_dial(sampass);
2367 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2368 munged_dial, (int)strlen(munged_dial)));
2370 if (munged_dial) {
2371 blob = base64_decode_data_blob(munged_dial);
2372 } else {
2373 blob = data_blob_string_const_null("");
2376 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2377 data_blob_free(&blob);
2378 if (!NT_STATUS_IS_OK(status)) {
2379 return status;
2382 r->parameters = *parameters;
2384 return NT_STATUS_OK;
2388 /*************************************************************************
2389 get_user_info_21
2390 *************************************************************************/
2392 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2393 struct samr_UserInfo21 *r,
2394 struct samu *pw,
2395 DOM_SID *domain_sid)
2397 NTSTATUS status;
2398 const DOM_SID *sid_user, *sid_group;
2399 uint32_t rid, primary_gid;
2400 NTTIME force_password_change;
2401 time_t must_change_time;
2402 struct lsa_BinaryString *parameters = NULL;
2403 const char *munged_dial = NULL;
2404 DATA_BLOB blob;
2406 ZERO_STRUCTP(r);
2408 sid_user = pdb_get_user_sid(pw);
2410 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2411 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2412 "the domain sid %s. Failing operation.\n",
2413 pdb_get_username(pw), sid_string_dbg(sid_user),
2414 sid_string_dbg(domain_sid)));
2415 return NT_STATUS_UNSUCCESSFUL;
2418 become_root();
2419 sid_group = pdb_get_group_sid(pw);
2420 unbecome_root();
2422 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2423 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2424 "which conflicts with the domain sid %s. Failing operation.\n",
2425 pdb_get_username(pw), sid_string_dbg(sid_group),
2426 sid_string_dbg(domain_sid)));
2427 return NT_STATUS_UNSUCCESSFUL;
2430 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2431 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2432 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2433 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2434 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2436 must_change_time = pdb_get_pass_must_change_time(pw);
2437 if (must_change_time == get_time_t_max()) {
2438 unix_to_nt_time_abs(&force_password_change, must_change_time);
2439 } else {
2440 unix_to_nt_time(&force_password_change, must_change_time);
2443 munged_dial = pdb_get_munged_dial(pw);
2444 if (munged_dial) {
2445 blob = base64_decode_data_blob(munged_dial);
2446 } else {
2447 blob = data_blob_string_const_null("");
2450 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2451 data_blob_free(&blob);
2452 if (!NT_STATUS_IS_OK(status)) {
2453 return status;
2456 r->force_password_change = force_password_change;
2458 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2459 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2460 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2461 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2462 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2463 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2464 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2465 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2466 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2468 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2469 r->parameters = *parameters;
2470 r->rid = rid;
2471 r->primary_gid = primary_gid;
2472 r->acct_flags = pdb_get_acct_ctrl(pw);
2473 r->bad_password_count = pdb_get_bad_password_count(pw);
2474 r->logon_count = pdb_get_logon_count(pw);
2475 r->fields_present = pdb_build_fields_present(pw);
2476 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2477 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2478 r->country_code = 0;
2479 r->code_page = 0;
2480 r->lm_password_set = 0;
2481 r->nt_password_set = 0;
2483 #if 0
2486 Look at a user on a real NT4 PDC with usrmgr, press
2487 'ok'. Then you will see that fields_present is set to
2488 0x08f827fa. Look at the user immediately after that again,
2489 and you will see that 0x00fffff is returned. This solves
2490 the problem that you get access denied after having looked
2491 at the user.
2492 -- Volker
2495 #endif
2498 return NT_STATUS_OK;
2501 /*******************************************************************
2502 _samr_QueryUserInfo
2503 ********************************************************************/
2505 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2506 struct samr_QueryUserInfo *r)
2508 NTSTATUS status;
2509 union samr_UserInfo *user_info = NULL;
2510 struct samr_info *info = NULL;
2511 DOM_SID domain_sid;
2512 uint32 rid;
2513 bool ret = false;
2514 struct samu *pwd = NULL;
2516 /* search for the handle */
2517 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2518 return NT_STATUS_INVALID_HANDLE;
2520 status = access_check_samr_function(info->acc_granted,
2521 SAMR_USER_ACCESS_GET_ATTRIBUTES,
2522 "_samr_QueryUserInfo");
2523 if (!NT_STATUS_IS_OK(status)) {
2524 return status;
2527 domain_sid = info->sid;
2529 sid_split_rid(&domain_sid, &rid);
2531 if (!sid_check_is_in_our_domain(&info->sid))
2532 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2534 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2535 sid_string_dbg(&info->sid)));
2537 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2538 if (!user_info) {
2539 return NT_STATUS_NO_MEMORY;
2542 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2544 if (!(pwd = samu_new(p->mem_ctx))) {
2545 return NT_STATUS_NO_MEMORY;
2548 become_root();
2549 ret = pdb_getsampwsid(pwd, &info->sid);
2550 unbecome_root();
2552 if (ret == false) {
2553 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2554 TALLOC_FREE(pwd);
2555 return NT_STATUS_NO_SUCH_USER;
2558 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2560 samr_clear_sam_passwd(pwd);
2562 switch (r->in.level) {
2563 case 5:
2564 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2565 break;
2566 case 7:
2567 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2568 break;
2569 case 9:
2570 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2571 break;
2572 case 16:
2573 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2574 break;
2575 case 18:
2576 /* level 18 is special */
2577 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2578 break;
2579 case 20:
2580 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
2581 break;
2582 case 21:
2583 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
2584 break;
2585 default:
2586 status = NT_STATUS_INVALID_INFO_CLASS;
2587 break;
2590 TALLOC_FREE(pwd);
2592 *r->out.info = user_info;
2594 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2596 return status;
2599 /****************************************************************
2600 ****************************************************************/
2602 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2603 struct samr_QueryUserInfo2 *r)
2605 struct samr_QueryUserInfo u;
2607 u.in.user_handle = r->in.user_handle;
2608 u.in.level = r->in.level;
2609 u.out.info = r->out.info;
2611 return _samr_QueryUserInfo(p, &u);
2614 /*******************************************************************
2615 _samr_GetGroupsForUser
2616 ********************************************************************/
2618 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2619 struct samr_GetGroupsForUser *r)
2621 struct samu *sam_pass=NULL;
2622 DOM_SID sid;
2623 DOM_SID *sids;
2624 struct samr_RidWithAttribute dom_gid;
2625 struct samr_RidWithAttribute *gids = NULL;
2626 uint32 primary_group_rid;
2627 size_t num_groups = 0;
2628 gid_t *unix_gids;
2629 size_t i, num_gids;
2630 uint32 acc_granted;
2631 bool ret;
2632 NTSTATUS result;
2633 bool success = False;
2635 struct samr_RidWithAttributeArray *rids = NULL;
2638 * from the SID in the request:
2639 * we should send back the list of DOMAIN GROUPS
2640 * the user is a member of
2642 * and only the DOMAIN GROUPS
2643 * no ALIASES !!! neither aliases of the domain
2644 * nor aliases of the builtin SID
2646 * JFM, 12/2/2001
2649 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2651 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2652 if (!rids) {
2653 return NT_STATUS_NO_MEMORY;
2656 /* find the policy handle. open a policy on it. */
2657 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2658 return NT_STATUS_INVALID_HANDLE;
2660 result = access_check_samr_function(acc_granted,
2661 SAMR_USER_ACCESS_GET_GROUPS,
2662 "_samr_GetGroupsForUser");
2663 if (!NT_STATUS_IS_OK(result)) {
2664 return result;
2667 if (!sid_check_is_in_our_domain(&sid))
2668 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2670 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2671 return NT_STATUS_NO_MEMORY;
2674 become_root();
2675 ret = pdb_getsampwsid(sam_pass, &sid);
2676 unbecome_root();
2678 if (!ret) {
2679 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2680 sid_string_dbg(&sid)));
2681 return NT_STATUS_NO_SUCH_USER;
2684 sids = NULL;
2686 /* make both calls inside the root block */
2687 become_root();
2688 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2689 &sids, &unix_gids, &num_groups);
2690 if ( NT_STATUS_IS_OK(result) ) {
2691 success = sid_peek_check_rid(get_global_sam_sid(),
2692 pdb_get_group_sid(sam_pass),
2693 &primary_group_rid);
2695 unbecome_root();
2697 if (!NT_STATUS_IS_OK(result)) {
2698 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2699 sid_string_dbg(&sid)));
2700 return result;
2703 if ( !success ) {
2704 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2705 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2706 pdb_get_username(sam_pass)));
2707 TALLOC_FREE(sam_pass);
2708 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2711 gids = NULL;
2712 num_gids = 0;
2714 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2715 SE_GROUP_ENABLED);
2716 dom_gid.rid = primary_group_rid;
2717 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2719 for (i=0; i<num_groups; i++) {
2721 if (!sid_peek_check_rid(get_global_sam_sid(),
2722 &(sids[i]), &dom_gid.rid)) {
2723 DEBUG(10, ("Found sid %s not in our domain\n",
2724 sid_string_dbg(&sids[i])));
2725 continue;
2728 if (dom_gid.rid == primary_group_rid) {
2729 /* We added the primary group directly from the
2730 * sam_account. The other SIDs are unique from
2731 * enum_group_memberships */
2732 continue;
2735 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2738 rids->count = num_gids;
2739 rids->rids = gids;
2741 *r->out.rids = rids;
2743 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2745 return result;
2748 /*******************************************************************
2749 _samr_QueryDomainInfo
2750 ********************************************************************/
2752 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2753 struct samr_QueryDomainInfo *r)
2755 NTSTATUS status = NT_STATUS_OK;
2756 struct samr_domain_info *dinfo;
2757 union samr_DomainInfo *dom_info;
2758 time_t u_expire, u_min_age;
2760 time_t u_lock_duration, u_reset_time;
2761 uint32_t u_logout;
2763 uint32 account_policy_temp;
2765 time_t seq_num;
2766 uint32 server_role;
2768 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2770 dinfo = policy_handle_find(p, r->in.domain_handle,
2771 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
2772 struct samr_domain_info, &status);
2773 if (!NT_STATUS_IS_OK(status)) {
2774 return status;
2777 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2778 if (!dom_info) {
2779 return NT_STATUS_NO_MEMORY;
2782 switch (r->in.level) {
2783 case 0x01:
2785 become_root();
2787 /* AS ROOT !!! */
2789 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
2790 &account_policy_temp);
2791 dom_info->info1.min_password_length = account_policy_temp;
2793 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2794 dom_info->info1.password_history_length = account_policy_temp;
2796 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2797 &dom_info->info1.password_properties);
2799 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2800 u_expire = account_policy_temp;
2802 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2803 u_min_age = account_policy_temp;
2805 /* !AS ROOT */
2807 unbecome_root();
2809 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
2810 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
2812 if (lp_check_password_script() && *lp_check_password_script()) {
2813 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
2816 break;
2817 case 0x02:
2819 become_root();
2821 /* AS ROOT !!! */
2823 dom_info->general.num_users = count_sam_users(
2824 dinfo->disp_info, ACB_NORMAL);
2825 dom_info->general.num_groups = count_sam_groups(
2826 dinfo->disp_info);
2827 dom_info->general.num_aliases = count_sam_aliases(
2828 dinfo->disp_info);
2830 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
2832 unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
2834 if (!pdb_get_seq_num(&seq_num))
2835 seq_num = time(NULL);
2837 /* !AS ROOT */
2839 unbecome_root();
2841 server_role = ROLE_DOMAIN_PDC;
2842 if (lp_server_role() == ROLE_DOMAIN_BDC)
2843 server_role = ROLE_DOMAIN_BDC;
2845 dom_info->general.oem_information.string = lp_serverstring();
2846 dom_info->general.domain_name.string = lp_workgroup();
2847 dom_info->general.primary.string = global_myname();
2848 dom_info->general.sequence_num = seq_num;
2849 dom_info->general.domain_server_state = DOMAIN_SERVER_ENABLED;
2850 dom_info->general.role = server_role;
2851 dom_info->general.unknown3 = 1;
2853 break;
2854 case 0x03:
2856 become_root();
2858 /* AS ROOT !!! */
2861 uint32 ul;
2862 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2863 u_logout = (time_t)ul;
2866 /* !AS ROOT */
2868 unbecome_root();
2870 unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
2872 break;
2873 case 0x04:
2874 dom_info->oem.oem_information.string = lp_serverstring();
2875 break;
2876 case 0x05:
2877 dom_info->info5.domain_name.string = get_global_sam_name();
2878 break;
2879 case 0x06:
2880 /* NT returns its own name when a PDC. win2k and later
2881 * only the name of the PDC if itself is a BDC (samba4
2882 * idl) */
2883 dom_info->info6.primary.string = global_myname();
2884 break;
2885 case 0x07:
2886 server_role = ROLE_DOMAIN_PDC;
2887 if (lp_server_role() == ROLE_DOMAIN_BDC)
2888 server_role = ROLE_DOMAIN_BDC;
2890 dom_info->info7.role = server_role;
2891 break;
2892 case 0x08:
2894 become_root();
2896 /* AS ROOT !!! */
2898 if (!pdb_get_seq_num(&seq_num)) {
2899 seq_num = time(NULL);
2902 /* !AS ROOT */
2904 unbecome_root();
2906 dom_info->info8.sequence_num = seq_num;
2907 dom_info->info8.domain_create_time = 0;
2909 break;
2910 case 0x0c:
2912 become_root();
2914 /* AS ROOT !!! */
2916 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2917 u_lock_duration = account_policy_temp;
2918 if (u_lock_duration != -1) {
2919 u_lock_duration *= 60;
2922 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2923 u_reset_time = account_policy_temp * 60;
2925 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
2926 &account_policy_temp);
2927 dom_info->info12.lockout_threshold = account_policy_temp;
2929 /* !AS ROOT */
2931 unbecome_root();
2933 unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
2934 u_lock_duration);
2935 unix_to_nt_time_abs(&dom_info->info12.lockout_window,
2936 u_reset_time);
2938 break;
2939 default:
2940 return NT_STATUS_INVALID_INFO_CLASS;
2943 *r->out.info = dom_info;
2945 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2947 return status;
2950 /* W2k3 seems to use the same check for all 3 objects that can be created via
2951 * SAMR, if you try to create for example "Dialup" as an alias it says
2952 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
2953 * database. */
2955 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
2957 enum lsa_SidType type;
2958 bool result;
2960 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
2962 become_root();
2963 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
2964 * whether the name already exists */
2965 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
2966 NULL, NULL, NULL, &type);
2967 unbecome_root();
2969 if (!result) {
2970 DEBUG(10, ("%s does not exist, can create it\n", new_name));
2971 return NT_STATUS_OK;
2974 DEBUG(5, ("trying to create %s, exists as %s\n",
2975 new_name, sid_type_lookup(type)));
2977 if (type == SID_NAME_DOM_GRP) {
2978 return NT_STATUS_GROUP_EXISTS;
2980 if (type == SID_NAME_ALIAS) {
2981 return NT_STATUS_ALIAS_EXISTS;
2984 /* Yes, the default is NT_STATUS_USER_EXISTS */
2985 return NT_STATUS_USER_EXISTS;
2988 /*******************************************************************
2989 _samr_CreateUser2
2990 ********************************************************************/
2992 NTSTATUS _samr_CreateUser2(pipes_struct *p,
2993 struct samr_CreateUser2 *r)
2995 const char *account = NULL;
2996 DOM_SID sid;
2997 uint32_t acb_info = r->in.acct_flags;
2998 struct samr_domain_info *dinfo;
2999 struct samr_info *info;
3000 NTSTATUS nt_status;
3001 uint32 acc_granted;
3002 SEC_DESC *psd;
3003 size_t sd_size;
3004 /* check this, when giving away 'add computer to domain' privs */
3005 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3006 bool can_add_account = False;
3007 SE_PRIV se_rights;
3009 dinfo = policy_handle_find(p, r->in.domain_handle,
3010 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3011 struct samr_domain_info, &nt_status);
3012 if (!NT_STATUS_IS_OK(nt_status)) {
3013 return nt_status;
3016 if (sid_check_is_builtin(&dinfo->sid)) {
3017 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3018 return NT_STATUS_ACCESS_DENIED;
3021 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3022 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3023 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3024 this parameter is not an account type */
3025 return NT_STATUS_INVALID_PARAMETER;
3028 account = r->in.account_name->string;
3029 if (account == NULL) {
3030 return NT_STATUS_NO_MEMORY;
3033 nt_status = can_create(p->mem_ctx, account);
3034 if (!NT_STATUS_IS_OK(nt_status)) {
3035 return nt_status;
3038 /* determine which user right we need to check based on the acb_info */
3040 if ( acb_info & ACB_WSTRUST )
3042 se_priv_copy( &se_rights, &se_machine_account );
3043 can_add_account = user_has_privileges(
3044 p->server_info->ptok, &se_rights );
3046 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3047 account for domain trusts and changes the ACB flags later */
3048 else if ( acb_info & ACB_NORMAL &&
3049 (account[strlen(account)-1] != '$') )
3051 se_priv_copy( &se_rights, &se_add_users );
3052 can_add_account = user_has_privileges(
3053 p->server_info->ptok, &se_rights );
3055 else /* implicit assumption of a BDC or domain trust account here
3056 * (we already check the flags earlier) */
3058 if ( lp_enable_privileges() ) {
3059 /* only Domain Admins can add a BDC or domain trust */
3060 se_priv_copy( &se_rights, &se_priv_none );
3061 can_add_account = nt_token_check_domain_rid(
3062 p->server_info->ptok,
3063 DOMAIN_GROUP_RID_ADMINS );
3067 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3068 uidtoname(p->server_info->utok.uid),
3069 can_add_account ? "True":"False" ));
3071 /********** BEGIN Admin BLOCK **********/
3073 if ( can_add_account )
3074 become_root();
3076 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3077 r->out.rid);
3079 if ( can_add_account )
3080 unbecome_root();
3082 /********** END Admin BLOCK **********/
3084 /* now check for failure */
3086 if ( !NT_STATUS_IS_OK(nt_status) )
3087 return nt_status;
3089 /* Get the user's SID */
3091 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3093 map_max_allowed_access(p->server_info->ptok, &des_access);
3095 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3096 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3097 se_map_generic(&des_access, &usr_generic_mapping);
3099 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3100 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3101 &acc_granted, "_samr_CreateUser2");
3103 if ( !NT_STATUS_IS_OK(nt_status) ) {
3104 return nt_status;
3107 /* associate the user's SID with the new handle. */
3108 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL) {
3109 return NT_STATUS_NO_MEMORY;
3112 ZERO_STRUCTP(info);
3113 info->sid = sid;
3114 info->acc_granted = acc_granted;
3116 /* get a (unique) handle. open a policy on it. */
3117 if (!create_policy_hnd(p, r->out.user_handle, info)) {
3118 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3121 /* After a "set" ensure we have no cached display info. */
3122 force_flush_samr_cache(&sid);
3124 *r->out.access_granted = acc_granted;
3126 return NT_STATUS_OK;
3129 /****************************************************************
3130 ****************************************************************/
3132 NTSTATUS _samr_CreateUser(pipes_struct *p,
3133 struct samr_CreateUser *r)
3135 struct samr_CreateUser2 c;
3136 uint32_t access_granted;
3138 c.in.domain_handle = r->in.domain_handle;
3139 c.in.account_name = r->in.account_name;
3140 c.in.acct_flags = ACB_NORMAL;
3141 c.in.access_mask = r->in.access_mask;
3142 c.out.user_handle = r->out.user_handle;
3143 c.out.access_granted = &access_granted;
3144 c.out.rid = r->out.rid;
3146 return _samr_CreateUser2(p, &c);
3149 /*******************************************************************
3150 _samr_Connect
3151 ********************************************************************/
3153 NTSTATUS _samr_Connect(pipes_struct *p,
3154 struct samr_Connect *r)
3156 struct samr_connect_info *info;
3157 uint32_t acc_granted;
3158 struct policy_handle hnd;
3159 uint32 des_access = r->in.access_mask;
3160 NTSTATUS status;
3162 /* Access check */
3164 if (!pipe_access_check(p)) {
3165 DEBUG(3, ("access denied to _samr_Connect\n"));
3166 return NT_STATUS_ACCESS_DENIED;
3169 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3170 was observed from a win98 client trying to enumerate users (when configured
3171 user level access control on shares) --jerry */
3173 map_max_allowed_access(p->server_info->ptok, &des_access);
3175 se_map_generic( &des_access, &sam_generic_mapping );
3177 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3178 |SAMR_ACCESS_LOOKUP_DOMAIN);
3180 /* set up the SAMR connect_anon response */
3182 info = policy_handle_create(p, &hnd, acc_granted,
3183 struct samr_connect_info,
3184 &status);
3185 if (!NT_STATUS_IS_OK(status)) {
3186 return status;
3189 *r->out.connect_handle = hnd;
3190 return NT_STATUS_OK;
3193 /*******************************************************************
3194 _samr_Connect2
3195 ********************************************************************/
3197 NTSTATUS _samr_Connect2(pipes_struct *p,
3198 struct samr_Connect2 *r)
3200 struct samr_connect_info *info = NULL;
3201 struct policy_handle hnd;
3202 SEC_DESC *psd = NULL;
3203 uint32 acc_granted;
3204 uint32 des_access = r->in.access_mask;
3205 NTSTATUS nt_status;
3206 size_t sd_size;
3207 const char *fn = "_samr_Connect2";
3209 switch (p->hdr_req.opnum) {
3210 case NDR_SAMR_CONNECT2:
3211 fn = "_samr_Connect2";
3212 break;
3213 case NDR_SAMR_CONNECT3:
3214 fn = "_samr_Connect3";
3215 break;
3216 case NDR_SAMR_CONNECT4:
3217 fn = "_samr_Connect4";
3218 break;
3219 case NDR_SAMR_CONNECT5:
3220 fn = "_samr_Connect5";
3221 break;
3224 DEBUG(5,("%s: %d\n", fn, __LINE__));
3226 /* Access check */
3228 if (!pipe_access_check(p)) {
3229 DEBUG(3, ("access denied to %s\n", fn));
3230 return NT_STATUS_ACCESS_DENIED;
3233 map_max_allowed_access(p->server_info->ptok, &des_access);
3235 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3236 se_map_generic(&des_access, &sam_generic_mapping);
3238 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3239 NULL, 0, des_access, &acc_granted, fn);
3241 if ( !NT_STATUS_IS_OK(nt_status) )
3242 return nt_status;
3244 info = policy_handle_create(p, &hnd, acc_granted,
3245 struct samr_connect_info, &nt_status);
3246 if (!NT_STATUS_IS_OK(nt_status)) {
3247 return nt_status;
3250 DEBUG(5,("%s: %d\n", fn, __LINE__));
3252 *r->out.connect_handle = hnd;
3253 return NT_STATUS_OK;
3256 /****************************************************************
3257 _samr_Connect3
3258 ****************************************************************/
3260 NTSTATUS _samr_Connect3(pipes_struct *p,
3261 struct samr_Connect3 *r)
3263 struct samr_Connect2 c;
3265 c.in.system_name = r->in.system_name;
3266 c.in.access_mask = r->in.access_mask;
3267 c.out.connect_handle = r->out.connect_handle;
3269 return _samr_Connect2(p, &c);
3272 /*******************************************************************
3273 _samr_Connect4
3274 ********************************************************************/
3276 NTSTATUS _samr_Connect4(pipes_struct *p,
3277 struct samr_Connect4 *r)
3279 struct samr_Connect2 c;
3281 c.in.system_name = r->in.system_name;
3282 c.in.access_mask = r->in.access_mask;
3283 c.out.connect_handle = r->out.connect_handle;
3285 return _samr_Connect2(p, &c);
3288 /*******************************************************************
3289 _samr_Connect5
3290 ********************************************************************/
3292 NTSTATUS _samr_Connect5(pipes_struct *p,
3293 struct samr_Connect5 *r)
3295 NTSTATUS status;
3296 struct samr_Connect2 c;
3297 struct samr_ConnectInfo1 info1;
3299 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3300 info1.unknown2 = 0;
3302 c.in.system_name = r->in.system_name;
3303 c.in.access_mask = r->in.access_mask;
3304 c.out.connect_handle = r->out.connect_handle;
3306 status = _samr_Connect2(p, &c);
3307 if (!NT_STATUS_IS_OK(status)) {
3308 return status;
3311 *r->out.level_out = 1;
3312 r->out.info_out->info1 = info1;
3314 return NT_STATUS_OK;
3317 /**********************************************************************
3318 _samr_LookupDomain
3319 **********************************************************************/
3321 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3322 struct samr_LookupDomain *r)
3324 NTSTATUS status;
3325 struct samr_connect_info *info;
3326 const char *domain_name;
3327 DOM_SID *sid = NULL;
3329 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3330 Reverted that change so we will work with RAS servers again */
3332 info = policy_handle_find(p, r->in.connect_handle,
3333 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3334 struct samr_connect_info,
3335 &status);
3336 if (!NT_STATUS_IS_OK(status)) {
3337 return status;
3340 domain_name = r->in.domain_name->string;
3341 if (!domain_name) {
3342 return NT_STATUS_INVALID_PARAMETER;
3345 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3346 if (!sid) {
3347 return NT_STATUS_NO_MEMORY;
3350 if (strequal(domain_name, builtin_domain_name())) {
3351 sid_copy(sid, &global_sid_Builtin);
3352 } else {
3353 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3354 status = NT_STATUS_NO_SUCH_DOMAIN;
3358 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3359 sid_string_dbg(sid)));
3361 *r->out.sid = sid;
3363 return status;
3366 /**********************************************************************
3367 _samr_EnumDomains
3368 **********************************************************************/
3370 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3371 struct samr_EnumDomains *r)
3373 NTSTATUS status;
3374 struct samr_connect_info *info;
3375 uint32_t num_entries = 2;
3376 struct samr_SamEntry *entry_array = NULL;
3377 struct samr_SamArray *sam;
3379 info = policy_handle_find(p, r->in.connect_handle,
3380 SAMR_ACCESS_ENUM_DOMAINS, NULL,
3381 struct samr_connect_info, &status);
3382 if (!NT_STATUS_IS_OK(status)) {
3383 return status;
3386 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3387 if (!sam) {
3388 return NT_STATUS_NO_MEMORY;
3391 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3392 struct samr_SamEntry,
3393 num_entries);
3394 if (!entry_array) {
3395 return NT_STATUS_NO_MEMORY;
3398 entry_array[0].idx = 0;
3399 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3401 entry_array[1].idx = 1;
3402 init_lsa_String(&entry_array[1].name, "Builtin");
3404 sam->count = num_entries;
3405 sam->entries = entry_array;
3407 *r->out.sam = sam;
3408 *r->out.num_entries = num_entries;
3410 return status;
3413 /*******************************************************************
3414 _samr_OpenAlias
3415 ********************************************************************/
3417 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3418 struct samr_OpenAlias *r)
3420 DOM_SID sid;
3421 uint32 alias_rid = r->in.rid;
3422 struct samr_info *info = NULL;
3423 struct samr_domain_info *dinfo;
3424 SEC_DESC *psd = NULL;
3425 uint32 acc_granted;
3426 uint32 des_access = r->in.access_mask;
3427 size_t sd_size;
3428 NTSTATUS status;
3429 SE_PRIV se_rights;
3431 dinfo = policy_handle_find(p, r->in.domain_handle,
3432 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
3433 struct samr_domain_info, &status);
3434 if (!NT_STATUS_IS_OK(status)) {
3435 return status;
3438 /* append the alias' RID to it */
3440 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
3441 return NT_STATUS_NO_SUCH_ALIAS;
3443 /*check if access can be granted as requested by client. */
3445 map_max_allowed_access(p->server_info->ptok, &des_access);
3447 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3448 se_map_generic(&des_access,&ali_generic_mapping);
3450 se_priv_copy( &se_rights, &se_add_users );
3453 status = access_check_samr_object(psd, p->server_info->ptok,
3454 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3455 &acc_granted, "_samr_OpenAlias");
3457 if ( !NT_STATUS_IS_OK(status) )
3458 return status;
3461 /* Check we actually have the requested alias */
3462 enum lsa_SidType type;
3463 bool result;
3464 gid_t gid;
3466 become_root();
3467 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3468 unbecome_root();
3470 if (!result || (type != SID_NAME_ALIAS)) {
3471 return NT_STATUS_NO_SUCH_ALIAS;
3474 /* make sure there is a mapping */
3476 if ( !sid_to_gid( &sid, &gid ) ) {
3477 return NT_STATUS_NO_SUCH_ALIAS;
3482 /* associate the alias SID with the new handle. */
3483 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
3484 return NT_STATUS_NO_MEMORY;
3486 info->acc_granted = acc_granted;
3488 /* get a (unique) handle. open a policy on it. */
3489 if (!create_policy_hnd(p, r->out.alias_handle, info))
3490 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3492 return NT_STATUS_OK;
3495 /*******************************************************************
3496 set_user_info_7
3497 ********************************************************************/
3499 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3500 struct samr_UserInfo7 *id7,
3501 struct samu *pwd)
3503 NTSTATUS rc;
3505 if (id7 == NULL) {
3506 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3507 return NT_STATUS_ACCESS_DENIED;
3510 if (!id7->account_name.string) {
3511 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3512 return NT_STATUS_ACCESS_DENIED;
3515 /* check to see if the new username already exists. Note: we can't
3516 reliably lock all backends, so there is potentially the
3517 possibility that a user can be created in between this check and
3518 the rename. The rename should fail, but may not get the
3519 exact same failure status code. I think this is small enough
3520 of a window for this type of operation and the results are
3521 simply that the rename fails with a slightly different status
3522 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3524 rc = can_create(mem_ctx, id7->account_name.string);
3525 if (!NT_STATUS_IS_OK(rc)) {
3526 return rc;
3529 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3531 return rc;
3534 /*******************************************************************
3535 set_user_info_16
3536 ********************************************************************/
3538 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3539 struct samu *pwd)
3541 if (id16 == NULL) {
3542 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3543 return False;
3546 /* FIX ME: check if the value is really changed --metze */
3547 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3548 return False;
3551 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3552 return False;
3555 return True;
3558 /*******************************************************************
3559 set_user_info_18
3560 ********************************************************************/
3562 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
3563 TALLOC_CTX *mem_ctx,
3564 DATA_BLOB *session_key,
3565 struct samu *pwd)
3567 if (id18 == NULL) {
3568 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3569 return NT_STATUS_INVALID_PARAMETER;
3572 if (id18->nt_pwd_active || id18->lm_pwd_active) {
3573 if (!session_key->length) {
3574 return NT_STATUS_NO_USER_SESSION_KEY;
3578 if (id18->nt_pwd_active) {
3580 DATA_BLOB in, out;
3582 in = data_blob_const(id18->nt_pwd.hash, 16);
3583 out = data_blob_talloc_zero(mem_ctx, 16);
3585 sess_crypt_blob(&out, &in, session_key, false);
3587 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
3588 return NT_STATUS_ACCESS_DENIED;
3591 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3594 if (id18->lm_pwd_active) {
3596 DATA_BLOB in, out;
3598 in = data_blob_const(id18->lm_pwd.hash, 16);
3599 out = data_blob_talloc_zero(mem_ctx, 16);
3601 sess_crypt_blob(&out, &in, session_key, false);
3603 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
3604 return NT_STATUS_ACCESS_DENIED;
3607 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3610 copy_id18_to_sam_passwd(pwd, id18);
3612 return pdb_update_sam_account(pwd);
3615 /*******************************************************************
3616 set_user_info_20
3617 ********************************************************************/
3619 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3620 struct samu *pwd)
3622 if (id20 == NULL) {
3623 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3624 return False;
3627 copy_id20_to_sam_passwd(pwd, id20);
3629 /* write the change out */
3630 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3631 return False;
3634 return True;
3637 /*******************************************************************
3638 set_user_info_21
3639 ********************************************************************/
3641 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
3642 TALLOC_CTX *mem_ctx,
3643 DATA_BLOB *session_key,
3644 struct samu *pwd)
3646 NTSTATUS status;
3648 if (id21 == NULL) {
3649 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3650 return NT_STATUS_INVALID_PARAMETER;
3653 if (id21->fields_present == 0) {
3654 return NT_STATUS_INVALID_PARAMETER;
3657 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3658 return NT_STATUS_ACCESS_DENIED;
3661 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
3662 if (id21->nt_password_set) {
3663 DATA_BLOB in, out;
3665 if ((id21->nt_owf_password.length != 16) ||
3666 (id21->nt_owf_password.size != 16)) {
3667 return NT_STATUS_INVALID_PARAMETER;
3670 if (!session_key->length) {
3671 return NT_STATUS_NO_USER_SESSION_KEY;
3674 in = data_blob_const(id21->nt_owf_password.array, 16);
3675 out = data_blob_talloc_zero(mem_ctx, 16);
3677 sess_crypt_blob(&out, &in, session_key, false);
3679 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
3680 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3684 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
3685 if (id21->lm_password_set) {
3686 DATA_BLOB in, out;
3688 if ((id21->lm_owf_password.length != 16) ||
3689 (id21->lm_owf_password.size != 16)) {
3690 return NT_STATUS_INVALID_PARAMETER;
3693 if (!session_key->length) {
3694 return NT_STATUS_NO_USER_SESSION_KEY;
3697 in = data_blob_const(id21->lm_owf_password.array, 16);
3698 out = data_blob_talloc_zero(mem_ctx, 16);
3700 sess_crypt_blob(&out, &in, session_key, false);
3702 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
3703 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3707 /* we need to separately check for an account rename first */
3709 if (id21->account_name.string &&
3710 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3713 /* check to see if the new username already exists. Note: we can't
3714 reliably lock all backends, so there is potentially the
3715 possibility that a user can be created in between this check and
3716 the rename. The rename should fail, but may not get the
3717 exact same failure status code. I think this is small enough
3718 of a window for this type of operation and the results are
3719 simply that the rename fails with a slightly different status
3720 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3722 status = can_create(mem_ctx, id21->account_name.string);
3723 if (!NT_STATUS_IS_OK(status)) {
3724 return status;
3727 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3729 if (!NT_STATUS_IS_OK(status)) {
3730 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3731 nt_errstr(status)));
3732 return status;
3735 /* set the new username so that later
3736 functions can work on the new account */
3737 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3740 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3743 * The funny part about the previous two calls is
3744 * that pwd still has the password hashes from the
3745 * passdb entry. These have not been updated from
3746 * id21. I don't know if they need to be set. --jerry
3749 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3750 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3751 if ( !NT_STATUS_IS_OK(status) ) {
3752 return status;
3756 /* Don't worry about writing out the user account since the
3757 primary group SID is generated solely from the user's Unix
3758 primary group. */
3760 /* write the change out */
3761 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3762 return status;
3765 return NT_STATUS_OK;
3768 /*******************************************************************
3769 set_user_info_23
3770 ********************************************************************/
3772 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3773 struct samr_UserInfo23 *id23,
3774 struct samu *pwd)
3776 char *plaintext_buf = NULL;
3777 size_t len = 0;
3778 uint32_t acct_ctrl;
3779 NTSTATUS status;
3781 if (id23 == NULL) {
3782 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3783 return NT_STATUS_INVALID_PARAMETER;
3786 if (id23->info.fields_present == 0) {
3787 return NT_STATUS_INVALID_PARAMETER;
3790 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3791 return NT_STATUS_ACCESS_DENIED;
3794 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3795 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
3797 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3798 pdb_get_username(pwd)));
3800 if (!decode_pw_buffer(mem_ctx,
3801 id23->password.data,
3802 &plaintext_buf,
3803 &len,
3804 CH_UTF16)) {
3805 return NT_STATUS_WRONG_PASSWORD;
3808 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3809 return NT_STATUS_ACCESS_DENIED;
3813 copy_id23_to_sam_passwd(pwd, id23);
3815 acct_ctrl = pdb_get_acct_ctrl(pwd);
3817 /* if it's a trust account, don't update /etc/passwd */
3818 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3819 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3820 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3821 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3822 } else if (plaintext_buf) {
3823 /* update the UNIX password */
3824 if (lp_unix_password_sync() ) {
3825 struct passwd *passwd;
3826 if (pdb_get_username(pwd) == NULL) {
3827 DEBUG(1, ("chgpasswd: User without name???\n"));
3828 return NT_STATUS_ACCESS_DENIED;
3831 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3832 if (passwd == NULL) {
3833 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3836 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3837 return NT_STATUS_ACCESS_DENIED;
3839 TALLOC_FREE(passwd);
3843 if (plaintext_buf) {
3844 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3847 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3848 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3849 pwd)))) {
3850 return status;
3853 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3854 return status;
3857 return NT_STATUS_OK;
3860 /*******************************************************************
3861 set_user_info_pw
3862 ********************************************************************/
3864 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
3866 size_t len = 0;
3867 char *plaintext_buf = NULL;
3868 uint32 acct_ctrl;
3870 DEBUG(5, ("Attempting administrator password change for user %s\n",
3871 pdb_get_username(pwd)));
3873 acct_ctrl = pdb_get_acct_ctrl(pwd);
3875 if (!decode_pw_buffer(talloc_tos(),
3876 pass,
3877 &plaintext_buf,
3878 &len,
3879 CH_UTF16)) {
3880 return False;
3883 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3884 return False;
3887 /* if it's a trust account, don't update /etc/passwd */
3888 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3889 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3890 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3891 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3892 } else {
3893 /* update the UNIX password */
3894 if (lp_unix_password_sync()) {
3895 struct passwd *passwd;
3897 if (pdb_get_username(pwd) == NULL) {
3898 DEBUG(1, ("chgpasswd: User without name???\n"));
3899 return False;
3902 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3903 if (passwd == NULL) {
3904 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3907 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3908 return False;
3910 TALLOC_FREE(passwd);
3914 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3916 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3918 return True;
3921 /*******************************************************************
3922 set_user_info_24
3923 ********************************************************************/
3925 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
3926 struct samr_UserInfo24 *id24,
3927 struct samu *pwd)
3929 NTSTATUS status;
3931 if (id24 == NULL) {
3932 DEBUG(5, ("set_user_info_24: NULL id24\n"));
3933 return NT_STATUS_INVALID_PARAMETER;
3936 if (!set_user_info_pw(id24->password.data, pwd)) {
3937 return NT_STATUS_WRONG_PASSWORD;
3940 copy_id24_to_sam_passwd(pwd, id24);
3942 status = pdb_update_sam_account(pwd);
3943 if (!NT_STATUS_IS_OK(status)) {
3944 return status;
3947 return NT_STATUS_OK;
3950 /*******************************************************************
3951 set_user_info_25
3952 ********************************************************************/
3954 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
3955 struct samr_UserInfo25 *id25,
3956 struct samu *pwd)
3958 NTSTATUS status;
3960 if (id25 == NULL) {
3961 DEBUG(5, ("set_user_info_25: NULL id25\n"));
3962 return NT_STATUS_INVALID_PARAMETER;
3965 if (id25->info.fields_present == 0) {
3966 return NT_STATUS_INVALID_PARAMETER;
3969 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3970 return NT_STATUS_ACCESS_DENIED;
3973 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3974 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
3976 if (!set_user_info_pw(id25->password.data, pwd)) {
3977 return NT_STATUS_WRONG_PASSWORD;
3981 copy_id25_to_sam_passwd(pwd, id25);
3983 /* write the change out */
3984 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3985 return status;
3989 * We need to "pdb_update_sam_account" before the unix primary group
3990 * is set, because the idealx scripts would also change the
3991 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
3992 * the delete explicit / add explicit, which would then fail to find
3993 * the previous primaryGroupSid value.
3996 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3997 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3998 if ( !NT_STATUS_IS_OK(status) ) {
3999 return status;
4003 return NT_STATUS_OK;
4006 /*******************************************************************
4007 set_user_info_26
4008 ********************************************************************/
4010 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4011 struct samr_UserInfo26 *id26,
4012 struct samu *pwd)
4014 NTSTATUS status;
4016 if (id26 == NULL) {
4017 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4018 return NT_STATUS_INVALID_PARAMETER;
4021 if (!set_user_info_pw(id26->password.data, pwd)) {
4022 return NT_STATUS_WRONG_PASSWORD;
4025 copy_id26_to_sam_passwd(pwd, id26);
4027 status = pdb_update_sam_account(pwd);
4028 if (!NT_STATUS_IS_OK(status)) {
4029 return status;
4032 return NT_STATUS_OK;
4036 /*******************************************************************
4037 samr_SetUserInfo
4038 ********************************************************************/
4040 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4041 struct samr_SetUserInfo *r)
4043 NTSTATUS status;
4044 struct samu *pwd = NULL;
4045 DOM_SID sid;
4046 union samr_UserInfo *info = r->in.info;
4047 uint16_t switch_value = r->in.level;
4048 uint32_t acc_granted;
4049 uint32_t acc_required;
4050 bool ret;
4051 bool has_enough_rights = False;
4052 uint32_t acb_info;
4053 DISP_INFO *disp_info = NULL;
4055 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4057 /* find the policy handle. open a policy on it. */
4058 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) {
4059 return NT_STATUS_INVALID_HANDLE;
4062 /* This is tricky. A WinXP domain join sets
4063 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4064 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4065 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4066 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4067 we'll use the set from the WinXP join as the basis. */
4069 switch (switch_value) {
4070 case 18:
4071 case 24:
4072 case 25:
4073 case 26:
4074 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4075 break;
4076 default:
4077 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4078 SAMR_USER_ACCESS_SET_ATTRIBUTES |
4079 SAMR_USER_ACCESS_GET_ATTRIBUTES;
4080 break;
4083 status = access_check_samr_function(acc_granted,
4084 acc_required,
4085 "_samr_SetUserInfo");
4086 if (!NT_STATUS_IS_OK(status)) {
4087 return status;
4090 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4091 sid_string_dbg(&sid), switch_value));
4093 if (info == NULL) {
4094 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4095 return NT_STATUS_INVALID_INFO_CLASS;
4098 if (!(pwd = samu_new(NULL))) {
4099 return NT_STATUS_NO_MEMORY;
4102 become_root();
4103 ret = pdb_getsampwsid(pwd, &sid);
4104 unbecome_root();
4106 if (!ret) {
4107 TALLOC_FREE(pwd);
4108 return NT_STATUS_NO_SUCH_USER;
4111 /* deal with machine password changes differently from userinfo changes */
4112 /* check to see if we have the sufficient rights */
4114 acb_info = pdb_get_acct_ctrl(pwd);
4115 if (acb_info & ACB_WSTRUST)
4116 has_enough_rights = user_has_privileges(p->server_info->ptok,
4117 &se_machine_account);
4118 else if (acb_info & ACB_NORMAL)
4119 has_enough_rights = user_has_privileges(p->server_info->ptok,
4120 &se_add_users);
4121 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4122 if (lp_enable_privileges()) {
4123 has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
4124 DOMAIN_GROUP_RID_ADMINS);
4128 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4129 uidtoname(p->server_info->utok.uid),
4130 has_enough_rights ? "" : " not"));
4132 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4134 if (has_enough_rights) {
4135 become_root();
4138 /* ok! user info levels (lots: see MSDEV help), off we go... */
4140 switch (switch_value) {
4142 case 7:
4143 status = set_user_info_7(p->mem_ctx,
4144 &info->info7, pwd);
4145 break;
4147 case 16:
4148 if (!set_user_info_16(&info->info16, pwd)) {
4149 status = NT_STATUS_ACCESS_DENIED;
4151 break;
4153 case 18:
4154 /* Used by AS/U JRA. */
4155 status = set_user_info_18(&info->info18,
4156 p->mem_ctx,
4157 &p->server_info->user_session_key,
4158 pwd);
4159 break;
4161 case 20:
4162 if (!set_user_info_20(&info->info20, pwd)) {
4163 status = NT_STATUS_ACCESS_DENIED;
4165 break;
4167 case 21:
4168 status = set_user_info_21(&info->info21,
4169 p->mem_ctx,
4170 &p->server_info->user_session_key,
4171 pwd);
4172 break;
4174 case 23:
4175 if (!p->server_info->user_session_key.length) {
4176 status = NT_STATUS_NO_USER_SESSION_KEY;
4178 arcfour_crypt_blob(info->info23.password.data, 516,
4179 &p->server_info->user_session_key);
4181 dump_data(100, info->info23.password.data, 516);
4183 status = set_user_info_23(p->mem_ctx,
4184 &info->info23, pwd);
4185 break;
4187 case 24:
4188 if (!p->server_info->user_session_key.length) {
4189 status = NT_STATUS_NO_USER_SESSION_KEY;
4191 arcfour_crypt_blob(info->info24.password.data,
4192 516,
4193 &p->server_info->user_session_key);
4195 dump_data(100, info->info24.password.data, 516);
4197 status = set_user_info_24(p->mem_ctx,
4198 &info->info24, pwd);
4199 break;
4201 case 25:
4202 if (!p->server_info->user_session_key.length) {
4203 status = NT_STATUS_NO_USER_SESSION_KEY;
4205 encode_or_decode_arc4_passwd_buffer(
4206 info->info25.password.data,
4207 &p->server_info->user_session_key);
4209 dump_data(100, info->info25.password.data, 532);
4211 status = set_user_info_25(p->mem_ctx,
4212 &info->info25, pwd);
4213 break;
4215 case 26:
4216 if (!p->server_info->user_session_key.length) {
4217 status = NT_STATUS_NO_USER_SESSION_KEY;
4219 encode_or_decode_arc4_passwd_buffer(
4220 info->info26.password.data,
4221 &p->server_info->user_session_key);
4223 dump_data(100, info->info26.password.data, 516);
4225 status = set_user_info_26(p->mem_ctx,
4226 &info->info26, pwd);
4227 break;
4229 default:
4230 status = NT_STATUS_INVALID_INFO_CLASS;
4233 TALLOC_FREE(pwd);
4235 if (has_enough_rights) {
4236 unbecome_root();
4239 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4241 if (NT_STATUS_IS_OK(status)) {
4242 force_flush_samr_cache(&sid);
4245 return status;
4248 /*******************************************************************
4249 _samr_SetUserInfo2
4250 ********************************************************************/
4252 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4253 struct samr_SetUserInfo2 *r)
4255 struct samr_SetUserInfo q;
4257 q.in.user_handle = r->in.user_handle;
4258 q.in.level = r->in.level;
4259 q.in.info = r->in.info;
4261 return _samr_SetUserInfo(p, &q);
4264 /*********************************************************************
4265 _samr_GetAliasMembership
4266 *********************************************************************/
4268 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4269 struct samr_GetAliasMembership *r)
4271 size_t num_alias_rids;
4272 uint32 *alias_rids;
4273 struct samr_domain_info *dinfo;
4274 size_t i;
4276 NTSTATUS status;
4278 DOM_SID *members;
4280 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4282 dinfo = policy_handle_find(p, r->in.domain_handle,
4283 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
4284 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4285 struct samr_domain_info, &status);
4286 if (!NT_STATUS_IS_OK(status)) {
4287 return status;
4290 if (!sid_check_is_domain(&dinfo->sid) &&
4291 !sid_check_is_builtin(&dinfo->sid))
4292 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4294 if (r->in.sids->num_sids) {
4295 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4297 if (members == NULL)
4298 return NT_STATUS_NO_MEMORY;
4299 } else {
4300 members = NULL;
4303 for (i=0; i<r->in.sids->num_sids; i++)
4304 sid_copy(&members[i], r->in.sids->sids[i].sid);
4306 alias_rids = NULL;
4307 num_alias_rids = 0;
4309 become_root();
4310 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
4311 r->in.sids->num_sids,
4312 &alias_rids, &num_alias_rids);
4313 unbecome_root();
4315 if (!NT_STATUS_IS_OK(status)) {
4316 return status;
4319 r->out.rids->count = num_alias_rids;
4320 r->out.rids->ids = alias_rids;
4322 return NT_STATUS_OK;
4325 /*********************************************************************
4326 _samr_GetMembersInAlias
4327 *********************************************************************/
4329 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4330 struct samr_GetMembersInAlias *r)
4332 NTSTATUS status;
4333 size_t i;
4334 size_t num_sids = 0;
4335 struct lsa_SidPtr *sids = NULL;
4336 DOM_SID *pdb_sids = NULL;
4338 DOM_SID alias_sid;
4340 uint32 acc_granted;
4342 /* find the policy handle. open a policy on it. */
4343 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4344 return NT_STATUS_INVALID_HANDLE;
4346 status = access_check_samr_function(acc_granted,
4347 SAMR_ALIAS_ACCESS_GET_MEMBERS,
4348 "_samr_GetMembersInAlias");
4349 if (!NT_STATUS_IS_OK(status)) {
4350 return status;
4353 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4355 become_root();
4356 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4357 unbecome_root();
4359 if (!NT_STATUS_IS_OK(status)) {
4360 return status;
4363 if (num_sids) {
4364 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4365 if (sids == NULL) {
4366 TALLOC_FREE(pdb_sids);
4367 return NT_STATUS_NO_MEMORY;
4371 for (i = 0; i < num_sids; i++) {
4372 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4373 if (!sids[i].sid) {
4374 TALLOC_FREE(pdb_sids);
4375 return NT_STATUS_NO_MEMORY;
4379 r->out.sids->num_sids = num_sids;
4380 r->out.sids->sids = sids;
4382 TALLOC_FREE(pdb_sids);
4384 return NT_STATUS_OK;
4387 /*********************************************************************
4388 _samr_QueryGroupMember
4389 *********************************************************************/
4391 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4392 struct samr_QueryGroupMember *r)
4394 DOM_SID group_sid;
4395 size_t i, num_members;
4397 uint32 *rid=NULL;
4398 uint32 *attr=NULL;
4400 uint32 acc_granted;
4402 NTSTATUS status;
4403 struct samr_RidTypeArray *rids = NULL;
4405 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4406 if (!rids) {
4407 return NT_STATUS_NO_MEMORY;
4410 /* find the policy handle. open a policy on it. */
4411 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4412 return NT_STATUS_INVALID_HANDLE;
4414 status = access_check_samr_function(acc_granted,
4415 SAMR_GROUP_ACCESS_GET_MEMBERS,
4416 "_samr_QueryGroupMember");
4417 if (!NT_STATUS_IS_OK(status)) {
4418 return status;
4421 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4423 if (!sid_check_is_in_our_domain(&group_sid)) {
4424 DEBUG(3, ("sid %s is not in our domain\n",
4425 sid_string_dbg(&group_sid)));
4426 return NT_STATUS_NO_SUCH_GROUP;
4429 DEBUG(10, ("lookup on Domain SID\n"));
4431 become_root();
4432 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4433 &rid, &num_members);
4434 unbecome_root();
4436 if (!NT_STATUS_IS_OK(status))
4437 return status;
4439 if (num_members) {
4440 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4441 if (attr == NULL) {
4442 return NT_STATUS_NO_MEMORY;
4444 } else {
4445 attr = NULL;
4448 for (i=0; i<num_members; i++)
4449 attr[i] = SID_NAME_USER;
4451 rids->count = num_members;
4452 rids->types = attr;
4453 rids->rids = rid;
4455 *r->out.rids = rids;
4457 return NT_STATUS_OK;
4460 /*********************************************************************
4461 _samr_AddAliasMember
4462 *********************************************************************/
4464 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4465 struct samr_AddAliasMember *r)
4467 DOM_SID alias_sid;
4468 uint32 acc_granted;
4469 SE_PRIV se_rights;
4470 bool can_add_accounts;
4471 NTSTATUS status;
4472 DISP_INFO *disp_info = NULL;
4474 /* Find the policy handle. Open a policy on it. */
4475 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4476 return NT_STATUS_INVALID_HANDLE;
4478 status = access_check_samr_function(acc_granted,
4479 SAMR_ALIAS_ACCESS_ADD_MEMBER,
4480 "_samr_AddAliasMember");
4481 if (!NT_STATUS_IS_OK(status)) {
4482 return status;
4485 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4487 se_priv_copy( &se_rights, &se_add_users );
4488 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4490 /******** BEGIN SeAddUsers BLOCK *********/
4492 if ( can_add_accounts )
4493 become_root();
4495 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4497 if ( can_add_accounts )
4498 unbecome_root();
4500 /******** END SeAddUsers BLOCK *********/
4502 if (NT_STATUS_IS_OK(status)) {
4503 force_flush_samr_cache(&alias_sid);
4506 return status;
4509 /*********************************************************************
4510 _samr_DeleteAliasMember
4511 *********************************************************************/
4513 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4514 struct samr_DeleteAliasMember *r)
4516 DOM_SID alias_sid;
4517 uint32 acc_granted;
4518 SE_PRIV se_rights;
4519 bool can_add_accounts;
4520 NTSTATUS status;
4521 DISP_INFO *disp_info = NULL;
4523 /* Find the policy handle. Open a policy on it. */
4524 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4525 return NT_STATUS_INVALID_HANDLE;
4527 status = access_check_samr_function(acc_granted,
4528 SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
4529 "_samr_DeleteAliasMember");
4530 if (!NT_STATUS_IS_OK(status)) {
4531 return status;
4534 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4535 sid_string_dbg(&alias_sid)));
4537 se_priv_copy( &se_rights, &se_add_users );
4538 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4540 /******** BEGIN SeAddUsers BLOCK *********/
4542 if ( can_add_accounts )
4543 become_root();
4545 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4547 if ( can_add_accounts )
4548 unbecome_root();
4550 /******** END SeAddUsers BLOCK *********/
4552 if (NT_STATUS_IS_OK(status)) {
4553 force_flush_samr_cache(&alias_sid);
4556 return status;
4559 /*********************************************************************
4560 _samr_AddGroupMember
4561 *********************************************************************/
4563 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4564 struct samr_AddGroupMember *r)
4566 NTSTATUS status;
4567 DOM_SID group_sid;
4568 uint32 group_rid;
4569 uint32 acc_granted;
4570 SE_PRIV se_rights;
4571 bool can_add_accounts;
4572 DISP_INFO *disp_info = NULL;
4574 /* Find the policy handle. Open a policy on it. */
4575 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4576 return NT_STATUS_INVALID_HANDLE;
4578 status = access_check_samr_function(acc_granted,
4579 SAMR_GROUP_ACCESS_ADD_MEMBER,
4580 "_samr_AddGroupMember");
4581 if (!NT_STATUS_IS_OK(status)) {
4582 return status;
4585 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4587 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4588 &group_rid)) {
4589 return NT_STATUS_INVALID_HANDLE;
4592 se_priv_copy( &se_rights, &se_add_users );
4593 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4595 /******** BEGIN SeAddUsers BLOCK *********/
4597 if ( can_add_accounts )
4598 become_root();
4600 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4602 if ( can_add_accounts )
4603 unbecome_root();
4605 /******** END SeAddUsers BLOCK *********/
4607 force_flush_samr_cache(&group_sid);
4609 return status;
4612 /*********************************************************************
4613 _samr_DeleteGroupMember
4614 *********************************************************************/
4616 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4617 struct samr_DeleteGroupMember *r)
4620 NTSTATUS status;
4621 DOM_SID group_sid;
4622 uint32 group_rid;
4623 uint32 acc_granted;
4624 SE_PRIV se_rights;
4625 bool can_add_accounts;
4626 DISP_INFO *disp_info = NULL;
4629 * delete the group member named r->in.rid
4630 * who is a member of the sid associated with the handle
4631 * the rid is a user's rid as the group is a domain group.
4634 /* Find the policy handle. Open a policy on it. */
4635 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4636 return NT_STATUS_INVALID_HANDLE;
4638 status = access_check_samr_function(acc_granted,
4639 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
4640 "_samr_DeleteGroupMember");
4641 if (!NT_STATUS_IS_OK(status)) {
4642 return status;
4645 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4646 &group_rid)) {
4647 return NT_STATUS_INVALID_HANDLE;
4650 se_priv_copy( &se_rights, &se_add_users );
4651 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4653 /******** BEGIN SeAddUsers BLOCK *********/
4655 if ( can_add_accounts )
4656 become_root();
4658 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4660 if ( can_add_accounts )
4661 unbecome_root();
4663 /******** END SeAddUsers BLOCK *********/
4665 force_flush_samr_cache(&group_sid);
4667 return status;
4670 /*********************************************************************
4671 _samr_DeleteUser
4672 *********************************************************************/
4674 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4675 struct samr_DeleteUser *r)
4677 NTSTATUS status;
4678 DOM_SID user_sid;
4679 struct samu *sam_pass=NULL;
4680 uint32 acc_granted;
4681 bool can_add_accounts;
4682 uint32 acb_info;
4683 DISP_INFO *disp_info = NULL;
4684 bool ret;
4686 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4688 /* Find the policy handle. Open a policy on it. */
4689 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4690 return NT_STATUS_INVALID_HANDLE;
4692 status = access_check_samr_function(acc_granted,
4693 STD_RIGHT_DELETE_ACCESS,
4694 "_samr_DeleteUser");
4695 if (!NT_STATUS_IS_OK(status)) {
4696 return status;
4699 if (!sid_check_is_in_our_domain(&user_sid))
4700 return NT_STATUS_CANNOT_DELETE;
4702 /* check if the user exists before trying to delete */
4703 if ( !(sam_pass = samu_new( NULL )) ) {
4704 return NT_STATUS_NO_MEMORY;
4707 become_root();
4708 ret = pdb_getsampwsid(sam_pass, &user_sid);
4709 unbecome_root();
4711 if( !ret ) {
4712 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4713 sid_string_dbg(&user_sid)));
4714 TALLOC_FREE(sam_pass);
4715 return NT_STATUS_NO_SUCH_USER;
4718 acb_info = pdb_get_acct_ctrl(sam_pass);
4720 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4721 if ( acb_info & ACB_WSTRUST ) {
4722 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
4723 } else {
4724 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
4727 /******** BEGIN SeAddUsers BLOCK *********/
4729 if ( can_add_accounts )
4730 become_root();
4732 status = pdb_delete_user(p->mem_ctx, sam_pass);
4734 if ( can_add_accounts )
4735 unbecome_root();
4737 /******** END SeAddUsers BLOCK *********/
4739 if ( !NT_STATUS_IS_OK(status) ) {
4740 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4741 "user %s: %s.\n", pdb_get_username(sam_pass),
4742 nt_errstr(status)));
4743 TALLOC_FREE(sam_pass);
4744 return status;
4748 TALLOC_FREE(sam_pass);
4750 if (!close_policy_hnd(p, r->in.user_handle))
4751 return NT_STATUS_OBJECT_NAME_INVALID;
4753 ZERO_STRUCTP(r->out.user_handle);
4755 force_flush_samr_cache(&user_sid);
4757 return NT_STATUS_OK;
4760 /*********************************************************************
4761 _samr_DeleteDomainGroup
4762 *********************************************************************/
4764 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4765 struct samr_DeleteDomainGroup *r)
4767 NTSTATUS status;
4768 DOM_SID group_sid;
4769 uint32 group_rid;
4770 uint32 acc_granted;
4771 SE_PRIV se_rights;
4772 bool can_add_accounts;
4773 DISP_INFO *disp_info = NULL;
4775 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4777 /* Find the policy handle. Open a policy on it. */
4778 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4779 return NT_STATUS_INVALID_HANDLE;
4781 status = access_check_samr_function(acc_granted,
4782 STD_RIGHT_DELETE_ACCESS,
4783 "_samr_DeleteDomainGroup");
4784 if (!NT_STATUS_IS_OK(status)) {
4785 return status;
4788 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4790 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4791 &group_rid)) {
4792 return NT_STATUS_NO_SUCH_GROUP;
4795 se_priv_copy( &se_rights, &se_add_users );
4796 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4798 /******** BEGIN SeAddUsers BLOCK *********/
4800 if ( can_add_accounts )
4801 become_root();
4803 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4805 if ( can_add_accounts )
4806 unbecome_root();
4808 /******** END SeAddUsers BLOCK *********/
4810 if ( !NT_STATUS_IS_OK(status) ) {
4811 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4812 "entry for group %s: %s\n",
4813 sid_string_dbg(&group_sid),
4814 nt_errstr(status)));
4815 return status;
4818 if (!close_policy_hnd(p, r->in.group_handle))
4819 return NT_STATUS_OBJECT_NAME_INVALID;
4821 force_flush_samr_cache(&group_sid);
4823 return NT_STATUS_OK;
4826 /*********************************************************************
4827 _samr_DeleteDomAlias
4828 *********************************************************************/
4830 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4831 struct samr_DeleteDomAlias *r)
4833 DOM_SID alias_sid;
4834 uint32 acc_granted;
4835 SE_PRIV se_rights;
4836 bool can_add_accounts;
4837 NTSTATUS status;
4838 DISP_INFO *disp_info = NULL;
4840 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4842 /* Find the policy handle. Open a policy on it. */
4843 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4844 return NT_STATUS_INVALID_HANDLE;
4846 /* copy the handle to the outgoing reply */
4848 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4850 status = access_check_samr_function(acc_granted,
4851 STD_RIGHT_DELETE_ACCESS,
4852 "_samr_DeleteDomAlias");
4853 if (!NT_STATUS_IS_OK(status)) {
4854 return status;
4857 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4859 /* Don't let Windows delete builtin groups */
4861 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4862 return NT_STATUS_SPECIAL_ACCOUNT;
4865 if (!sid_check_is_in_our_domain(&alias_sid))
4866 return NT_STATUS_NO_SUCH_ALIAS;
4868 DEBUG(10, ("lookup on Local SID\n"));
4870 se_priv_copy( &se_rights, &se_add_users );
4871 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4873 /******** BEGIN SeAddUsers BLOCK *********/
4875 if ( can_add_accounts )
4876 become_root();
4878 /* Have passdb delete the alias */
4879 status = pdb_delete_alias(&alias_sid);
4881 if ( can_add_accounts )
4882 unbecome_root();
4884 /******** END SeAddUsers BLOCK *********/
4886 if ( !NT_STATUS_IS_OK(status))
4887 return status;
4889 if (!close_policy_hnd(p, r->in.alias_handle))
4890 return NT_STATUS_OBJECT_NAME_INVALID;
4892 force_flush_samr_cache(&alias_sid);
4894 return NT_STATUS_OK;
4897 /*********************************************************************
4898 _samr_CreateDomainGroup
4899 *********************************************************************/
4901 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4902 struct samr_CreateDomainGroup *r)
4905 NTSTATUS status;
4906 DOM_SID info_sid;
4907 const char *name;
4908 struct samr_domain_info *dinfo;
4909 struct samr_info *info;
4910 SE_PRIV se_rights;
4911 bool can_add_accounts;
4913 dinfo = policy_handle_find(p, r->in.domain_handle,
4914 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
4915 struct samr_domain_info, &status);
4916 if (!NT_STATUS_IS_OK(status)) {
4917 return status;
4920 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
4921 return NT_STATUS_ACCESS_DENIED;
4923 name = r->in.name->string;
4924 if (name == NULL) {
4925 return NT_STATUS_NO_MEMORY;
4928 status = can_create(p->mem_ctx, name);
4929 if (!NT_STATUS_IS_OK(status)) {
4930 return status;
4933 se_priv_copy( &se_rights, &se_add_users );
4934 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4936 /******** BEGIN SeAddUsers BLOCK *********/
4938 if ( can_add_accounts )
4939 become_root();
4941 /* check that we successfully create the UNIX group */
4943 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
4945 if ( can_add_accounts )
4946 unbecome_root();
4948 /******** END SeAddUsers BLOCK *********/
4950 /* check if we should bail out here */
4952 if ( !NT_STATUS_IS_OK(status) )
4953 return status;
4955 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
4957 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
4958 return NT_STATUS_NO_MEMORY;
4960 /* they created it; let the user do what he wants with it */
4962 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
4964 /* get a (unique) handle. open a policy on it. */
4965 if (!create_policy_hnd(p, r->out.group_handle, info))
4966 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4968 force_flush_samr_cache(&info_sid);
4970 return NT_STATUS_OK;
4973 /*********************************************************************
4974 _samr_CreateDomAlias
4975 *********************************************************************/
4977 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
4978 struct samr_CreateDomAlias *r)
4980 DOM_SID info_sid;
4981 const char *name = NULL;
4982 struct samr_domain_info *dinfo;
4983 struct samr_info *info;
4984 gid_t gid;
4985 NTSTATUS result;
4986 SE_PRIV se_rights;
4987 bool can_add_accounts;
4989 dinfo = policy_handle_find(p, r->in.domain_handle,
4990 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
4991 struct samr_domain_info, &result);
4992 if (!NT_STATUS_IS_OK(result)) {
4993 return result;
4996 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
4997 return NT_STATUS_ACCESS_DENIED;
4999 name = r->in.alias_name->string;
5001 se_priv_copy( &se_rights, &se_add_users );
5002 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5004 result = can_create(p->mem_ctx, name);
5005 if (!NT_STATUS_IS_OK(result)) {
5006 return result;
5009 /******** BEGIN SeAddUsers BLOCK *********/
5011 if ( can_add_accounts )
5012 become_root();
5014 /* Have passdb create the alias */
5015 result = pdb_create_alias(name, r->out.rid);
5017 if ( can_add_accounts )
5018 unbecome_root();
5020 /******** END SeAddUsers BLOCK *********/
5022 if (!NT_STATUS_IS_OK(result)) {
5023 DEBUG(10, ("pdb_create_alias failed: %s\n",
5024 nt_errstr(result)));
5025 return result;
5028 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5030 if (!sid_to_gid(&info_sid, &gid)) {
5031 DEBUG(10, ("Could not find alias just created\n"));
5032 return NT_STATUS_ACCESS_DENIED;
5035 /* check if the group has been successfully created */
5036 if ( getgrgid(gid) == NULL ) {
5037 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5038 gid));
5039 return NT_STATUS_ACCESS_DENIED;
5042 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5043 return NT_STATUS_NO_MEMORY;
5045 /* they created it; let the user do what he wants with it */
5047 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5049 /* get a (unique) handle. open a policy on it. */
5050 if (!create_policy_hnd(p, r->out.alias_handle, info))
5051 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5053 force_flush_samr_cache(&info_sid);
5055 return NT_STATUS_OK;
5058 /*********************************************************************
5059 _samr_QueryGroupInfo
5060 *********************************************************************/
5062 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5063 struct samr_QueryGroupInfo *r)
5065 NTSTATUS status;
5066 DOM_SID group_sid;
5067 GROUP_MAP map;
5068 union samr_GroupInfo *info = NULL;
5069 uint32 acc_granted;
5070 bool ret;
5071 uint32_t attributes = SE_GROUP_MANDATORY |
5072 SE_GROUP_ENABLED_BY_DEFAULT |
5073 SE_GROUP_ENABLED;
5074 const char *group_name = NULL;
5075 const char *group_description = NULL;
5077 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5078 return NT_STATUS_INVALID_HANDLE;
5080 status = access_check_samr_function(acc_granted,
5081 SAMR_GROUP_ACCESS_LOOKUP_INFO,
5082 "_samr_QueryGroupInfo");
5083 if (!NT_STATUS_IS_OK(status)) {
5084 return status;
5087 become_root();
5088 ret = get_domain_group_from_sid(group_sid, &map);
5089 unbecome_root();
5090 if (!ret)
5091 return NT_STATUS_INVALID_HANDLE;
5093 /* FIXME: map contains fstrings */
5094 group_name = talloc_strdup(r, map.nt_name);
5095 group_description = talloc_strdup(r, map.comment);
5097 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5098 if (!info) {
5099 return NT_STATUS_NO_MEMORY;
5102 switch (r->in.level) {
5103 case 1: {
5104 uint32 *members;
5105 size_t num_members;
5107 become_root();
5108 status = pdb_enum_group_members(
5109 p->mem_ctx, &group_sid, &members, &num_members);
5110 unbecome_root();
5112 if (!NT_STATUS_IS_OK(status)) {
5113 return status;
5116 info->all.name.string = group_name;
5117 info->all.attributes = attributes;
5118 info->all.num_members = num_members;
5119 info->all.description.string = group_description;
5120 break;
5122 case 2:
5123 info->name.string = group_name;
5124 break;
5125 case 3:
5126 info->attributes.attributes = attributes;
5127 break;
5128 case 4:
5129 info->description.string = group_description;
5130 break;
5131 case 5: {
5133 uint32 *members;
5134 size_t num_members;
5138 become_root();
5139 status = pdb_enum_group_members(
5140 p->mem_ctx, &group_sid, &members, &num_members);
5141 unbecome_root();
5143 if (!NT_STATUS_IS_OK(status)) {
5144 return status;
5147 info->all2.name.string = group_name;
5148 info->all2.attributes = attributes;
5149 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5150 info->all2.description.string = group_description;
5152 break;
5154 default:
5155 return NT_STATUS_INVALID_INFO_CLASS;
5158 *r->out.info = info;
5160 return NT_STATUS_OK;
5163 /*********************************************************************
5164 _samr_SetGroupInfo
5165 *********************************************************************/
5167 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5168 struct samr_SetGroupInfo *r)
5170 DOM_SID group_sid;
5171 GROUP_MAP map;
5172 uint32 acc_granted;
5173 NTSTATUS status;
5174 bool ret;
5175 bool can_mod_accounts;
5176 DISP_INFO *disp_info = NULL;
5178 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5179 return NT_STATUS_INVALID_HANDLE;
5181 status = access_check_samr_function(acc_granted,
5182 SAMR_GROUP_ACCESS_SET_INFO,
5183 "_samr_SetGroupInfo");
5184 if (!NT_STATUS_IS_OK(status)) {
5185 return status;
5188 become_root();
5189 ret = get_domain_group_from_sid(group_sid, &map);
5190 unbecome_root();
5191 if (!ret)
5192 return NT_STATUS_NO_SUCH_GROUP;
5194 switch (r->in.level) {
5195 case 1:
5196 fstrcpy(map.comment, r->in.info->all.description.string);
5197 break;
5198 case 2:
5199 /* group rename is not supported yet */
5200 return NT_STATUS_NOT_SUPPORTED;
5201 case 4:
5202 fstrcpy(map.comment, r->in.info->description.string);
5203 break;
5204 default:
5205 return NT_STATUS_INVALID_INFO_CLASS;
5208 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5210 /******** BEGIN SeAddUsers BLOCK *********/
5212 if ( can_mod_accounts )
5213 become_root();
5215 status = pdb_update_group_mapping_entry(&map);
5217 if ( can_mod_accounts )
5218 unbecome_root();
5220 /******** End SeAddUsers BLOCK *********/
5222 if (NT_STATUS_IS_OK(status)) {
5223 force_flush_samr_cache(&group_sid);
5226 return status;
5229 /*********************************************************************
5230 _samr_SetAliasInfo
5231 *********************************************************************/
5233 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5234 struct samr_SetAliasInfo *r)
5236 DOM_SID group_sid;
5237 struct acct_info info;
5238 uint32 acc_granted;
5239 bool can_mod_accounts;
5240 NTSTATUS status;
5241 DISP_INFO *disp_info = NULL;
5243 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5244 return NT_STATUS_INVALID_HANDLE;
5246 status = access_check_samr_function(acc_granted,
5247 SAMR_ALIAS_ACCESS_SET_INFO,
5248 "_samr_SetAliasInfo");
5249 if (!NT_STATUS_IS_OK(status)) {
5250 return status;
5253 /* get the current group information */
5255 become_root();
5256 status = pdb_get_aliasinfo( &group_sid, &info );
5257 unbecome_root();
5259 if ( !NT_STATUS_IS_OK(status))
5260 return status;
5262 switch (r->in.level) {
5263 case ALIASINFONAME:
5265 fstring group_name;
5267 /* We currently do not support renaming groups in the
5268 the BUILTIN domain. Refer to util_builtin.c to understand
5269 why. The eventually needs to be fixed to be like Windows
5270 where you can rename builtin groups, just not delete them */
5272 if ( sid_check_is_in_builtin( &group_sid ) ) {
5273 return NT_STATUS_SPECIAL_ACCOUNT;
5276 /* There has to be a valid name (and it has to be different) */
5278 if ( !r->in.info->name.string )
5279 return NT_STATUS_INVALID_PARAMETER;
5281 /* If the name is the same just reply "ok". Yes this
5282 doesn't allow you to change the case of a group name. */
5284 if ( strequal( r->in.info->name.string, info.acct_name ) )
5285 return NT_STATUS_OK;
5287 fstrcpy( info.acct_name, r->in.info->name.string);
5289 /* make sure the name doesn't already exist as a user
5290 or local group */
5292 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5293 status = can_create( p->mem_ctx, group_name );
5294 if ( !NT_STATUS_IS_OK( status ) )
5295 return status;
5296 break;
5298 case ALIASINFODESCRIPTION:
5299 if (r->in.info->description.string) {
5300 fstrcpy(info.acct_desc,
5301 r->in.info->description.string);
5302 } else {
5303 fstrcpy( info.acct_desc, "" );
5305 break;
5306 default:
5307 return NT_STATUS_INVALID_INFO_CLASS;
5310 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5312 /******** BEGIN SeAddUsers BLOCK *********/
5314 if ( can_mod_accounts )
5315 become_root();
5317 status = pdb_set_aliasinfo( &group_sid, &info );
5319 if ( can_mod_accounts )
5320 unbecome_root();
5322 /******** End SeAddUsers BLOCK *********/
5324 if (NT_STATUS_IS_OK(status))
5325 force_flush_samr_cache(&group_sid);
5327 return status;
5330 /****************************************************************
5331 _samr_GetDomPwInfo
5332 ****************************************************************/
5334 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5335 struct samr_GetDomPwInfo *r)
5337 uint32_t min_password_length = 0;
5338 uint32_t password_properties = 0;
5340 /* Perform access check. Since this rpc does not require a
5341 policy handle it will not be caught by the access checks on
5342 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5344 if (!pipe_access_check(p)) {
5345 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5346 return NT_STATUS_ACCESS_DENIED;
5349 become_root();
5350 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5351 &min_password_length);
5352 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5353 &password_properties);
5354 unbecome_root();
5356 if (lp_check_password_script() && *lp_check_password_script()) {
5357 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5360 r->out.info->min_password_length = min_password_length;
5361 r->out.info->password_properties = password_properties;
5363 return NT_STATUS_OK;
5366 /*********************************************************************
5367 _samr_OpenGroup
5368 *********************************************************************/
5370 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5371 struct samr_OpenGroup *r)
5374 DOM_SID info_sid;
5375 GROUP_MAP map;
5376 struct samr_domain_info *dinfo;
5377 struct samr_info *info;
5378 SEC_DESC *psd = NULL;
5379 uint32 acc_granted;
5380 uint32 des_access = r->in.access_mask;
5381 size_t sd_size;
5382 NTSTATUS status;
5383 bool ret;
5384 SE_PRIV se_rights;
5386 dinfo = policy_handle_find(p, r->in.domain_handle,
5387 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5388 struct samr_domain_info, &status);
5389 if (!NT_STATUS_IS_OK(status)) {
5390 return status;
5393 /*check if access can be granted as requested by client. */
5394 map_max_allowed_access(p->server_info->ptok, &des_access);
5396 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5397 se_map_generic(&des_access,&grp_generic_mapping);
5399 se_priv_copy( &se_rights, &se_add_users );
5401 status = access_check_samr_object(psd, p->server_info->ptok,
5402 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5403 &acc_granted, "_samr_OpenGroup");
5405 if ( !NT_STATUS_IS_OK(status) )
5406 return status;
5408 /* this should not be hard-coded like this */
5410 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5411 return NT_STATUS_ACCESS_DENIED;
5413 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
5415 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5416 return NT_STATUS_NO_MEMORY;
5418 info->acc_granted = acc_granted;
5420 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
5421 sid_string_dbg(&info_sid)));
5423 /* check if that group really exists */
5424 become_root();
5425 ret = get_domain_group_from_sid(info->sid, &map);
5426 unbecome_root();
5427 if (!ret)
5428 return NT_STATUS_NO_SUCH_GROUP;
5430 /* get a (unique) handle. open a policy on it. */
5431 if (!create_policy_hnd(p, r->out.group_handle, info))
5432 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5434 return NT_STATUS_OK;
5437 /*********************************************************************
5438 _samr_RemoveMemberFromForeignDomain
5439 *********************************************************************/
5441 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5442 struct samr_RemoveMemberFromForeignDomain *r)
5444 struct samr_domain_info *dinfo;
5445 NTSTATUS result;
5447 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5448 sid_string_dbg(r->in.sid)));
5450 /* Find the policy handle. Open a policy on it. */
5452 dinfo = policy_handle_find(p, r->in.domain_handle,
5453 STD_RIGHT_DELETE_ACCESS, NULL,
5454 struct samr_domain_info, &result);
5455 if (!NT_STATUS_IS_OK(result)) {
5456 return result;
5459 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5460 sid_string_dbg(&dinfo->sid)));
5462 /* we can only delete a user from a group since we don't have
5463 nested groups anyways. So in the latter case, just say OK */
5465 /* TODO: The above comment nowadays is bogus. Since we have nested
5466 * groups now, and aliases members are never reported out of the unix
5467 * group membership, the "just say OK" makes this call a no-op. For
5468 * us. This needs fixing however. */
5470 /* I've only ever seen this in the wild when deleting a user from
5471 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5472 * is the user about to be deleted. I very much suspect this is the
5473 * only application of this call. To verify this, let people report
5474 * other cases. */
5476 if (!sid_check_is_builtin(&dinfo->sid)) {
5477 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5478 "global_sam_sid() = %s\n",
5479 sid_string_dbg(&dinfo->sid),
5480 sid_string_dbg(get_global_sam_sid())));
5481 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5482 return NT_STATUS_OK;
5485 force_flush_samr_cache(&dinfo->sid);
5487 result = NT_STATUS_OK;
5489 return result;
5492 /*******************************************************************
5493 _samr_QueryDomainInfo2
5494 ********************************************************************/
5496 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5497 struct samr_QueryDomainInfo2 *r)
5499 struct samr_QueryDomainInfo q;
5501 q.in.domain_handle = r->in.domain_handle;
5502 q.in.level = r->in.level;
5504 q.out.info = r->out.info;
5506 return _samr_QueryDomainInfo(p, &q);
5509 /*******************************************************************
5510 _samr_SetDomainInfo
5511 ********************************************************************/
5513 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5514 struct samr_SetDomainInfo *r)
5516 struct samr_domain_info *dinfo;
5517 time_t u_expire, u_min_age;
5518 time_t u_logout;
5519 time_t u_lock_duration, u_reset_time;
5520 NTSTATUS result;
5522 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5524 /* We do have different access bits for info
5525 * levels here, but we're really just looking for
5526 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5527 * this maps to different specific bits. So
5528 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
5529 * set we are ok. */
5531 dinfo = policy_handle_find(p, r->in.domain_handle,
5532 SAMR_DOMAIN_ACCESS_SET_INFO_1, NULL,
5533 struct samr_domain_info, &result);
5534 if (!NT_STATUS_IS_OK(result)) {
5535 return result;
5538 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5540 switch (r->in.level) {
5541 case 0x01:
5542 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5543 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5544 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5545 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5546 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5547 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5548 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5549 break;
5550 case 0x02:
5551 break;
5552 case 0x03:
5553 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5554 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5555 break;
5556 case 0x05:
5557 break;
5558 case 0x06:
5559 break;
5560 case 0x07:
5561 break;
5562 case 0x0c:
5563 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5564 if (u_lock_duration != -1)
5565 u_lock_duration /= 60;
5567 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5569 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5570 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5571 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5572 break;
5573 default:
5574 return NT_STATUS_INVALID_INFO_CLASS;
5577 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5579 return NT_STATUS_OK;
5582 /****************************************************************
5583 _samr_GetDisplayEnumerationIndex
5584 ****************************************************************/
5586 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5587 struct samr_GetDisplayEnumerationIndex *r)
5589 struct samr_domain_info *dinfo;
5590 uint32_t max_entries = (uint32_t) -1;
5591 uint32_t enum_context = 0;
5592 int i;
5593 uint32_t num_account = 0;
5594 struct samr_displayentry *entries = NULL;
5595 NTSTATUS status;
5597 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5599 dinfo = policy_handle_find(p, r->in.domain_handle,
5600 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
5601 struct samr_domain_info, &status);
5602 if (!NT_STATUS_IS_OK(status)) {
5603 return status;
5606 if ((r->in.level < 1) || (r->in.level > 3)) {
5607 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5608 "Unknown info level (%u)\n",
5609 r->in.level));
5610 return NT_STATUS_INVALID_INFO_CLASS;
5613 become_root();
5615 /* The following done as ROOT. Don't return without unbecome_root(). */
5617 switch (r->in.level) {
5618 case 1:
5619 if (dinfo->disp_info->users == NULL) {
5620 dinfo->disp_info->users = pdb_search_users(
5621 dinfo->disp_info, ACB_NORMAL);
5622 if (dinfo->disp_info->users == NULL) {
5623 unbecome_root();
5624 return NT_STATUS_ACCESS_DENIED;
5626 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5627 "starting user enumeration at index %u\n",
5628 (unsigned int)enum_context));
5629 } else {
5630 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5631 "using cached user enumeration at index %u\n",
5632 (unsigned int)enum_context));
5634 num_account = pdb_search_entries(dinfo->disp_info->users,
5635 enum_context, max_entries,
5636 &entries);
5637 break;
5638 case 2:
5639 if (dinfo->disp_info->machines == NULL) {
5640 dinfo->disp_info->machines = pdb_search_users(
5641 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
5642 if (dinfo->disp_info->machines == NULL) {
5643 unbecome_root();
5644 return NT_STATUS_ACCESS_DENIED;
5646 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5647 "starting machine enumeration at index %u\n",
5648 (unsigned int)enum_context));
5649 } else {
5650 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5651 "using cached machine enumeration at index %u\n",
5652 (unsigned int)enum_context));
5654 num_account = pdb_search_entries(dinfo->disp_info->machines,
5655 enum_context, max_entries,
5656 &entries);
5657 break;
5658 case 3:
5659 if (dinfo->disp_info->groups == NULL) {
5660 dinfo->disp_info->groups = pdb_search_groups(
5661 dinfo->disp_info);
5662 if (dinfo->disp_info->groups == NULL) {
5663 unbecome_root();
5664 return NT_STATUS_ACCESS_DENIED;
5666 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5667 "starting group enumeration at index %u\n",
5668 (unsigned int)enum_context));
5669 } else {
5670 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5671 "using cached group enumeration at index %u\n",
5672 (unsigned int)enum_context));
5674 num_account = pdb_search_entries(dinfo->disp_info->groups,
5675 enum_context, max_entries,
5676 &entries);
5677 break;
5678 default:
5679 unbecome_root();
5680 smb_panic("info class changed");
5681 break;
5684 unbecome_root();
5686 /* Ensure we cache this enumeration. */
5687 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
5689 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5690 r->in.name->string));
5692 for (i=0; i<num_account; i++) {
5693 if (strequal(entries[i].account_name, r->in.name->string)) {
5694 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5695 "found %s at idx %d\n",
5696 r->in.name->string, i));
5697 *r->out.idx = i;
5698 return NT_STATUS_OK;
5702 /* assuming account_name lives at the very end */
5703 *r->out.idx = num_account;
5705 return NT_STATUS_NO_MORE_ENTRIES;
5708 /****************************************************************
5709 _samr_GetDisplayEnumerationIndex2
5710 ****************************************************************/
5712 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5713 struct samr_GetDisplayEnumerationIndex2 *r)
5715 struct samr_GetDisplayEnumerationIndex q;
5717 q.in.domain_handle = r->in.domain_handle;
5718 q.in.level = r->in.level;
5719 q.in.name = r->in.name;
5721 q.out.idx = r->out.idx;
5723 return _samr_GetDisplayEnumerationIndex(p, &q);
5726 /****************************************************************
5727 ****************************************************************/
5729 NTSTATUS _samr_Shutdown(pipes_struct *p,
5730 struct samr_Shutdown *r)
5732 p->rng_fault_state = true;
5733 return NT_STATUS_NOT_IMPLEMENTED;
5736 /****************************************************************
5737 ****************************************************************/
5739 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5740 struct samr_SetMemberAttributesOfGroup *r)
5742 p->rng_fault_state = true;
5743 return NT_STATUS_NOT_IMPLEMENTED;
5746 /****************************************************************
5747 ****************************************************************/
5749 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5750 struct samr_ChangePasswordUser *r)
5752 p->rng_fault_state = true;
5753 return NT_STATUS_NOT_IMPLEMENTED;
5756 /****************************************************************
5757 ****************************************************************/
5759 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5760 struct samr_TestPrivateFunctionsDomain *r)
5762 p->rng_fault_state = true;
5763 return NT_STATUS_NOT_IMPLEMENTED;
5766 /****************************************************************
5767 ****************************************************************/
5769 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5770 struct samr_TestPrivateFunctionsUser *r)
5772 p->rng_fault_state = true;
5773 return NT_STATUS_NOT_IMPLEMENTED;
5776 /****************************************************************
5777 ****************************************************************/
5779 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5780 struct samr_AddMultipleMembersToAlias *r)
5782 p->rng_fault_state = true;
5783 return NT_STATUS_NOT_IMPLEMENTED;
5786 /****************************************************************
5787 ****************************************************************/
5789 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5790 struct samr_RemoveMultipleMembersFromAlias *r)
5792 p->rng_fault_state = true;
5793 return NT_STATUS_NOT_IMPLEMENTED;
5796 /****************************************************************
5797 ****************************************************************/
5799 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5800 struct samr_OemChangePasswordUser2 *r)
5802 p->rng_fault_state = true;
5803 return NT_STATUS_NOT_IMPLEMENTED;
5806 /****************************************************************
5807 ****************************************************************/
5809 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5810 struct samr_SetBootKeyInformation *r)
5812 p->rng_fault_state = true;
5813 return NT_STATUS_NOT_IMPLEMENTED;
5816 /****************************************************************
5817 ****************************************************************/
5819 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5820 struct samr_GetBootKeyInformation *r)
5822 p->rng_fault_state = true;
5823 return NT_STATUS_NOT_IMPLEMENTED;
5826 /****************************************************************
5827 ****************************************************************/
5829 NTSTATUS _samr_RidToSid(pipes_struct *p,
5830 struct samr_RidToSid *r)
5832 p->rng_fault_state = true;
5833 return NT_STATUS_NOT_IMPLEMENTED;
5836 /****************************************************************
5837 ****************************************************************/
5839 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5840 struct samr_SetDsrmPassword *r)
5842 p->rng_fault_state = true;
5843 return NT_STATUS_NOT_IMPLEMENTED;
5846 /****************************************************************
5847 ****************************************************************/
5849 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5850 struct samr_ValidatePassword *r)
5852 p->rng_fault_state = true;
5853 return NT_STATUS_NOT_IMPLEMENTED;