Convert the domain handles to type-safe policy handles
[Samba.git] / source3 / rpc_server / srv_samr_nt.c
blobcc25dbb0c09964e8297d6679cae85d041315c980
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"
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SAMR_USER_ACCESS_CHANGE_PASSWORD | \
42 SAMR_USER_ACCESS_SET_LOC_COM)
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
49 #define MAX_SAM_ENTRIES_W95 50
51 struct samr_connect_info {
52 uint8_t dummy;
55 struct samr_domain_info {
56 struct dom_sid sid;
57 struct disp_info *disp_info;
60 typedef struct disp_info {
61 DOM_SID sid; /* identify which domain this is. */
62 struct pdb_search *users; /* querydispinfo 1 and 4 */
63 struct pdb_search *machines; /* querydispinfo 2 */
64 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
65 struct pdb_search *aliases; /* enumaliases */
67 uint16 enum_acb_mask;
68 struct pdb_search *enum_users; /* enumusers with a mask */
70 struct timed_event *cache_timeout_event; /* cache idle timeout
71 * handler. */
72 } DISP_INFO;
74 /* We keep a static list of these by SID as modern clients close down
75 all resources between each request in a complete enumeration. */
77 struct samr_info {
78 /* for use by the \PIPE\samr policy */
79 DOM_SID sid;
80 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
81 uint32 acc_granted;
82 DISP_INFO *disp_info;
85 static const struct generic_mapping sam_generic_mapping = {
86 GENERIC_RIGHTS_SAM_READ,
87 GENERIC_RIGHTS_SAM_WRITE,
88 GENERIC_RIGHTS_SAM_EXECUTE,
89 GENERIC_RIGHTS_SAM_ALL_ACCESS};
90 static const struct generic_mapping dom_generic_mapping = {
91 GENERIC_RIGHTS_DOMAIN_READ,
92 GENERIC_RIGHTS_DOMAIN_WRITE,
93 GENERIC_RIGHTS_DOMAIN_EXECUTE,
94 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
95 static const struct generic_mapping usr_generic_mapping = {
96 GENERIC_RIGHTS_USER_READ,
97 GENERIC_RIGHTS_USER_WRITE,
98 GENERIC_RIGHTS_USER_EXECUTE,
99 GENERIC_RIGHTS_USER_ALL_ACCESS};
100 static const struct generic_mapping usr_nopwchange_generic_mapping = {
101 GENERIC_RIGHTS_USER_READ,
102 GENERIC_RIGHTS_USER_WRITE,
103 GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
104 GENERIC_RIGHTS_USER_ALL_ACCESS};
105 static const struct generic_mapping grp_generic_mapping = {
106 GENERIC_RIGHTS_GROUP_READ,
107 GENERIC_RIGHTS_GROUP_WRITE,
108 GENERIC_RIGHTS_GROUP_EXECUTE,
109 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
110 static const struct generic_mapping ali_generic_mapping = {
111 GENERIC_RIGHTS_ALIAS_READ,
112 GENERIC_RIGHTS_ALIAS_WRITE,
113 GENERIC_RIGHTS_ALIAS_EXECUTE,
114 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
116 /*******************************************************************
117 *******************************************************************/
119 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
120 const struct generic_mapping *map,
121 DOM_SID *sid, uint32 sid_access )
123 DOM_SID domadmin_sid;
124 SEC_ACE ace[5]; /* at most 5 entries */
125 size_t i = 0;
127 SEC_ACL *psa = NULL;
129 /* basic access for Everyone */
131 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
132 map->generic_execute | map->generic_read, 0);
134 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
136 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
137 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
138 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
139 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
141 /* Add Full Access for Domain Admins if we are a DC */
143 if ( IS_DC ) {
144 sid_copy( &domadmin_sid, get_global_sam_sid() );
145 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
146 init_sec_ace(&ace[i++], &domadmin_sid,
147 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
150 /* if we have a sid, give it some special access */
152 if ( sid ) {
153 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
156 /* create the security descriptor */
158 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
159 return NT_STATUS_NO_MEMORY;
161 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
162 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
163 psa, sd_size)) == NULL)
164 return NT_STATUS_NO_MEMORY;
166 return NT_STATUS_OK;
169 /*******************************************************************
170 Checks if access to an object should be granted, and returns that
171 level of access for further checks.
172 ********************************************************************/
174 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
175 SE_PRIV *rights, uint32 rights_mask,
176 uint32 des_access, uint32 *acc_granted,
177 const char *debug )
179 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
180 uint32 saved_mask = 0;
182 /* check privileges; certain SAM access bits should be overridden
183 by privileges (mostly having to do with creating/modifying/deleting
184 users and groups) */
186 if ( rights && user_has_any_privilege( token, rights ) ) {
188 saved_mask = (des_access & rights_mask);
189 des_access &= ~saved_mask;
191 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
192 rights_mask));
196 /* check the security descriptor first */
198 status = se_access_check(psd, token, des_access, acc_granted);
199 if (NT_STATUS_IS_OK(status)) {
200 goto done;
203 /* give root a free pass */
205 if ( geteuid() == sec_initial_uid() ) {
207 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
208 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
210 *acc_granted = des_access;
212 status = NT_STATUS_OK;
213 goto done;
217 done:
218 /* add in any bits saved during the privilege check (only
219 matters is status is ok) */
221 *acc_granted |= rights_mask;
223 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
224 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
225 des_access, *acc_granted));
227 return status;
230 /*******************************************************************
231 Checks if access to a function can be granted
232 ********************************************************************/
234 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
236 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
237 debug, acc_granted, acc_required));
239 /* check the security descriptor first */
241 if ( (acc_granted&acc_required) == acc_required )
242 return NT_STATUS_OK;
244 /* give root a free pass */
246 if (geteuid() == sec_initial_uid()) {
248 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
249 debug, acc_granted, acc_required));
250 DEBUGADD(4,("but overwritten by euid == 0\n"));
252 return NT_STATUS_OK;
255 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
256 debug, acc_granted, acc_required));
258 return NT_STATUS_ACCESS_DENIED;
261 /*******************************************************************
262 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
263 ********************************************************************/
265 static void map_max_allowed_access(const NT_USER_TOKEN *token,
266 uint32_t *pacc_requested)
268 if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
269 return;
271 *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
273 /* At least try for generic read. */
274 *pacc_requested = GENERIC_READ_ACCESS;
276 /* root gets anything. */
277 if (geteuid() == sec_initial_uid()) {
278 *pacc_requested |= GENERIC_ALL_ACCESS;
279 return;
282 /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
284 if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
285 is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
286 *pacc_requested |= GENERIC_ALL_ACCESS;
287 return;
290 /* Full access for DOMAIN\Domain Admins. */
291 if ( IS_DC ) {
292 DOM_SID domadmin_sid;
293 sid_copy( &domadmin_sid, get_global_sam_sid() );
294 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
295 if (is_sid_in_token(token, &domadmin_sid)) {
296 *pacc_requested |= GENERIC_ALL_ACCESS;
297 return;
300 /* TODO ! Check privileges. */
303 /*******************************************************************
304 Fetch or create a dispinfo struct.
305 ********************************************************************/
307 static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
310 * We do a static cache for DISP_INFO's here. Explanation can be found
311 * in Jeremy's checkin message to r11793:
313 * Fix the SAMR cache so it works across completely insane
314 * client behaviour (ie.:
315 * open pipe/open SAMR handle/enumerate 0 - 1024
316 * close SAMR handle, close pipe.
317 * open pipe/open SAMR handle/enumerate 1024 - 2048...
318 * close SAMR handle, close pipe.
319 * And on ad-nausium. Amazing.... probably object-oriented
320 * client side programming in action yet again.
321 * This change should *massively* improve performance when
322 * enumerating users from an LDAP database.
323 * Jeremy.
325 * "Our" and the builtin domain are the only ones where we ever
326 * enumerate stuff, so just cache 2 entries.
329 static struct disp_info *builtin_dispinfo;
330 static struct disp_info *domain_dispinfo;
332 /* There are two cases to consider here:
333 1) The SID is a domain SID and we look for an equality match, or
334 2) This is an account SID and so we return the DISP_INFO* for our
335 domain */
337 if (psid == NULL) {
338 return NULL;
341 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
343 * Necessary only once, but it does not really hurt.
345 if (builtin_dispinfo == NULL) {
346 builtin_dispinfo = talloc_zero(
347 talloc_autofree_context(), struct disp_info);
348 if (builtin_dispinfo == NULL) {
349 return NULL;
352 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
354 return builtin_dispinfo;
357 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
359 * Necessary only once, but it does not really hurt.
361 if (domain_dispinfo == NULL) {
362 domain_dispinfo = talloc_zero(
363 talloc_autofree_context(), struct disp_info);
364 if (domain_dispinfo == NULL) {
365 return NULL;
368 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
370 return domain_dispinfo;
373 return NULL;
376 /*******************************************************************
377 Create a samr_info struct.
378 ********************************************************************/
380 static int samr_info_destructor(struct samr_info *info);
382 static struct samr_info *get_samr_info_by_sid(TALLOC_CTX *mem_ctx,
383 DOM_SID *psid)
385 struct samr_info *info;
387 info = talloc_zero(mem_ctx, struct samr_info);
388 if (info == NULL) {
389 return NULL;
391 talloc_set_destructor(info, samr_info_destructor);
393 DEBUG(10, ("get_samr_info_by_sid: created new info for sid %s\n",
394 sid_string_dbg(psid)));
396 if (psid) {
397 sid_copy( &info->sid, psid);
398 } else {
399 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
402 info->disp_info = get_samr_dispinfo_by_sid(psid);
404 return info;
407 /*******************************************************************
408 Function to free the per SID data.
409 ********************************************************************/
411 static void free_samr_cache(DISP_INFO *disp_info)
413 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
414 sid_string_dbg(&disp_info->sid)));
416 /* We need to become root here because the paged search might have to
417 * tell the LDAP server we're not interested in the rest anymore. */
419 become_root();
421 TALLOC_FREE(disp_info->users);
422 TALLOC_FREE(disp_info->machines);
423 TALLOC_FREE(disp_info->groups);
424 TALLOC_FREE(disp_info->aliases);
425 TALLOC_FREE(disp_info->enum_users);
427 unbecome_root();
430 static int samr_info_destructor(struct samr_info *info)
432 /* Only free the dispinfo cache if no one bothered to set up
433 a timeout. */
435 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
436 free_samr_cache(info->disp_info);
438 return 0;
441 /*******************************************************************
442 Idle event handler. Throw away the disp info cache.
443 ********************************************************************/
445 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
446 struct timed_event *te,
447 struct timeval now,
448 void *private_data)
450 DISP_INFO *disp_info = (DISP_INFO *)private_data;
452 TALLOC_FREE(disp_info->cache_timeout_event);
454 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
455 "out\n"));
456 free_samr_cache(disp_info);
459 /*******************************************************************
460 Setup cache removal idle event handler.
461 ********************************************************************/
463 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
465 /* Remove any pending timeout and update. */
467 TALLOC_FREE(disp_info->cache_timeout_event);
469 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
470 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
471 (unsigned int)secs_fromnow ));
473 disp_info->cache_timeout_event = event_add_timed(
474 smbd_event_context(), NULL,
475 timeval_current_ofs(secs_fromnow, 0),
476 disp_info_cache_idle_timeout_handler, (void *)disp_info);
479 /*******************************************************************
480 Force flush any cache. We do this on any samr_set_xxx call.
481 We must also remove the timeout handler.
482 ********************************************************************/
484 static void force_flush_samr_cache(const struct dom_sid *sid)
486 struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
488 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
489 return;
492 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
493 TALLOC_FREE(disp_info->cache_timeout_event);
494 free_samr_cache(disp_info);
497 /*******************************************************************
498 Ensure password info is never given out. Paranioa... JRA.
499 ********************************************************************/
501 static void samr_clear_sam_passwd(struct samu *sam_pass)
504 if (!sam_pass)
505 return;
507 /* These now zero out the old password */
509 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
510 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
513 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
515 struct samr_displayentry *entry;
517 if (sid_check_is_builtin(&info->sid)) {
518 /* No users in builtin. */
519 return 0;
522 if (info->users == NULL) {
523 info->users = pdb_search_users(info, acct_flags);
524 if (info->users == NULL) {
525 return 0;
528 /* Fetch the last possible entry, thus trigger an enumeration */
529 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
531 /* Ensure we cache this enumeration. */
532 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
534 return info->users->num_entries;
537 static uint32 count_sam_groups(struct disp_info *info)
539 struct samr_displayentry *entry;
541 if (sid_check_is_builtin(&info->sid)) {
542 /* No groups in builtin. */
543 return 0;
546 if (info->groups == NULL) {
547 info->groups = pdb_search_groups(info);
548 if (info->groups == NULL) {
549 return 0;
552 /* Fetch the last possible entry, thus trigger an enumeration */
553 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
555 /* Ensure we cache this enumeration. */
556 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
558 return info->groups->num_entries;
561 static uint32 count_sam_aliases(struct disp_info *info)
563 struct samr_displayentry *entry;
565 if (info->aliases == NULL) {
566 info->aliases = pdb_search_aliases(info, &info->sid);
567 if (info->aliases == NULL) {
568 return 0;
571 /* Fetch the last possible entry, thus trigger an enumeration */
572 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
574 /* Ensure we cache this enumeration. */
575 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
577 return info->aliases->num_entries;
580 /*******************************************************************
581 _samr_Close
582 ********************************************************************/
584 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
586 if (!close_policy_hnd(p, r->in.handle)) {
587 return NT_STATUS_INVALID_HANDLE;
590 ZERO_STRUCTP(r->out.handle);
592 return NT_STATUS_OK;
595 /*******************************************************************
596 _samr_OpenDomain
597 ********************************************************************/
599 NTSTATUS _samr_OpenDomain(pipes_struct *p,
600 struct samr_OpenDomain *r)
602 struct samr_connect_info *cinfo;
603 struct samr_domain_info *dinfo;
604 SEC_DESC *psd = NULL;
605 uint32 acc_granted;
606 uint32 des_access = r->in.access_mask;
607 NTSTATUS status;
608 size_t sd_size;
609 SE_PRIV se_rights;
611 /* find the connection policy handle. */
613 cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
614 struct samr_connect_info, &status);
615 if (!NT_STATUS_IS_OK(status)) {
616 return status;
619 /*check if access can be granted as requested by client. */
620 map_max_allowed_access(p->server_info->ptok, &des_access);
622 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
623 se_map_generic( &des_access, &dom_generic_mapping );
625 se_priv_copy( &se_rights, &se_machine_account );
626 se_priv_add( &se_rights, &se_add_users );
628 status = access_check_samr_object( psd, p->server_info->ptok,
629 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
630 &acc_granted, "_samr_OpenDomain" );
632 if ( !NT_STATUS_IS_OK(status) )
633 return status;
635 if (!sid_check_is_domain(r->in.sid) &&
636 !sid_check_is_builtin(r->in.sid)) {
637 return NT_STATUS_NO_SUCH_DOMAIN;
640 dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
641 struct samr_domain_info, &status);
642 if (!NT_STATUS_IS_OK(status)) {
643 return status;
645 dinfo->sid = *r->in.sid;
646 dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
648 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
650 return NT_STATUS_OK;
653 /*******************************************************************
654 _samr_GetUserPwInfo
655 ********************************************************************/
657 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
658 struct samr_GetUserPwInfo *r)
660 struct samr_info *info = NULL;
661 enum lsa_SidType sid_type;
662 uint32_t min_password_length = 0;
663 uint32_t password_properties = 0;
664 bool ret = false;
665 NTSTATUS status;
667 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
669 /* find the policy handle. open a policy on it. */
670 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
671 return NT_STATUS_INVALID_HANDLE;
674 status = access_check_samr_function(info->acc_granted,
675 SAMR_USER_ACCESS_GET_ATTRIBUTES,
676 "_samr_GetUserPwInfo" );
677 if (!NT_STATUS_IS_OK(status)) {
678 return status;
681 if (!sid_check_is_in_our_domain(&info->sid)) {
682 return NT_STATUS_OBJECT_TYPE_MISMATCH;
685 become_root();
686 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
687 unbecome_root();
688 if (ret == false) {
689 return NT_STATUS_NO_SUCH_USER;
692 switch (sid_type) {
693 case SID_NAME_USER:
694 become_root();
695 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
696 &min_password_length);
697 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
698 &password_properties);
699 unbecome_root();
701 if (lp_check_password_script() && *lp_check_password_script()) {
702 password_properties |= DOMAIN_PASSWORD_COMPLEX;
705 break;
706 default:
707 break;
710 r->out.info->min_password_length = min_password_length;
711 r->out.info->password_properties = password_properties;
713 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
715 return NT_STATUS_OK;
718 /*******************************************************************
719 ********************************************************************/
721 static bool get_lsa_policy_samr_sid( pipes_struct *p, struct policy_handle *pol,
722 DOM_SID *sid, uint32 *acc_granted,
723 DISP_INFO **ppdisp_info)
725 struct samr_info *info = NULL;
727 /* find the policy handle. open a policy on it. */
728 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
729 return False;
731 if (!info)
732 return False;
734 *sid = info->sid;
735 *acc_granted = info->acc_granted;
736 if (ppdisp_info) {
737 *ppdisp_info = info->disp_info;
740 return True;
743 /*******************************************************************
744 _samr_SetSecurity
745 ********************************************************************/
747 NTSTATUS _samr_SetSecurity(pipes_struct *p,
748 struct samr_SetSecurity *r)
750 DOM_SID pol_sid;
751 uint32 acc_granted, i;
752 SEC_ACL *dacl;
753 bool ret;
754 struct samu *sampass=NULL;
755 NTSTATUS status;
757 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
758 return NT_STATUS_INVALID_HANDLE;
760 if (!(sampass = samu_new( p->mem_ctx))) {
761 DEBUG(0,("No memory!\n"));
762 return NT_STATUS_NO_MEMORY;
765 /* get the user record */
766 become_root();
767 ret = pdb_getsampwsid(sampass, &pol_sid);
768 unbecome_root();
770 if (!ret) {
771 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
772 TALLOC_FREE(sampass);
773 return NT_STATUS_INVALID_HANDLE;
776 dacl = r->in.sdbuf->sd->dacl;
777 for (i=0; i < dacl->num_aces; i++) {
778 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
779 ret = pdb_set_pass_can_change(sampass,
780 (dacl->aces[i].access_mask &
781 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
782 True: False);
783 break;
787 if (!ret) {
788 TALLOC_FREE(sampass);
789 return NT_STATUS_ACCESS_DENIED;
792 status = access_check_samr_function(acc_granted,
793 SAMR_USER_ACCESS_SET_ATTRIBUTES,
794 "_samr_SetSecurity");
795 if (NT_STATUS_IS_OK(status)) {
796 become_root();
797 status = pdb_update_sam_account(sampass);
798 unbecome_root();
801 TALLOC_FREE(sampass);
803 return status;
806 /*******************************************************************
807 build correct perms based on policies and password times for _samr_query_sec_obj
808 *******************************************************************/
809 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
811 struct samu *sampass=NULL;
812 bool ret;
814 if ( !(sampass = samu_new( mem_ctx )) ) {
815 DEBUG(0,("No memory!\n"));
816 return False;
819 become_root();
820 ret = pdb_getsampwsid(sampass, user_sid);
821 unbecome_root();
823 if (ret == False) {
824 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
825 TALLOC_FREE(sampass);
826 return False;
829 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
831 if (pdb_get_pass_can_change(sampass)) {
832 TALLOC_FREE(sampass);
833 return True;
835 TALLOC_FREE(sampass);
836 return False;
840 /*******************************************************************
841 _samr_QuerySecurity
842 ********************************************************************/
844 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
845 struct samr_QuerySecurity *r)
847 NTSTATUS status;
848 DOM_SID pol_sid;
849 SEC_DESC * psd = NULL;
850 uint32 acc_granted;
851 size_t sd_size;
853 /* Get the SID. */
854 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
855 return NT_STATUS_INVALID_HANDLE;
857 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
858 sid_string_dbg(&pol_sid)));
860 status = access_check_samr_function(acc_granted,
861 STD_RIGHT_READ_CONTROL_ACCESS,
862 "_samr_QuerySecurity");
863 if (!NT_STATUS_IS_OK(status)) {
864 return status;
867 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
869 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
870 if (pol_sid.sid_rev_num == 0) {
871 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
872 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
873 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
874 /* check if it is our domain SID */
875 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
876 "with SID: %s\n", sid_string_dbg(&pol_sid)));
877 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
878 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
879 /* check if it is the Builtin Domain */
880 /* TODO: Builtin probably needs a different SD with restricted write access*/
881 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
882 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
883 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
884 } else if (sid_check_is_in_our_domain(&pol_sid) ||
885 sid_check_is_in_builtin(&pol_sid)) {
886 /* TODO: different SDs have to be generated for aliases groups and users.
887 Currently all three get a default user SD */
888 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
889 "with SID: %s\n", sid_string_dbg(&pol_sid)));
890 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
891 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
892 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
893 } else {
894 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
895 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
897 } else {
898 return NT_STATUS_OBJECT_TYPE_MISMATCH;
901 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
902 return NT_STATUS_NO_MEMORY;
904 return status;
907 /*******************************************************************
908 makes a SAM_ENTRY / UNISTR2* structure from a user list.
909 ********************************************************************/
911 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
912 struct samr_SamEntry **sam_pp,
913 uint32_t num_entries,
914 uint32_t start_idx,
915 struct samr_displayentry *entries)
917 uint32_t i;
918 struct samr_SamEntry *sam;
920 *sam_pp = NULL;
922 if (num_entries == 0) {
923 return NT_STATUS_OK;
926 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
927 if (sam == NULL) {
928 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
929 return NT_STATUS_NO_MEMORY;
932 for (i = 0; i < num_entries; i++) {
933 #if 0
935 * usrmgr expects a non-NULL terminated string with
936 * trust relationships
938 if (entries[i].acct_flags & ACB_DOMTRUST) {
939 init_unistr2(&uni_temp_name, entries[i].account_name,
940 UNI_FLAGS_NONE);
941 } else {
942 init_unistr2(&uni_temp_name, entries[i].account_name,
943 UNI_STR_TERMINATE);
945 #endif
946 init_lsa_String(&sam[i].name, entries[i].account_name);
947 sam[i].idx = entries[i].rid;
950 *sam_pp = sam;
952 return NT_STATUS_OK;
955 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
957 /*******************************************************************
958 _samr_EnumDomainUsers
959 ********************************************************************/
961 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
962 struct samr_EnumDomainUsers *r)
964 NTSTATUS status;
965 struct samr_domain_info *dinfo;
966 int num_account;
967 uint32 enum_context = *r->in.resume_handle;
968 enum remote_arch_types ra_type = get_remote_arch();
969 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
970 uint32 max_entries = max_sam_entries;
971 struct samr_displayentry *entries = NULL;
972 struct samr_SamArray *samr_array = NULL;
973 struct samr_SamEntry *samr_entries = NULL;
975 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
977 dinfo = policy_handle_find(p, r->in.domain_handle,
978 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
979 struct samr_domain_info, &status);
980 if (!NT_STATUS_IS_OK(status)) {
981 return status;
984 if (sid_check_is_builtin(&dinfo->sid)) {
985 /* No users in builtin. */
986 *r->out.resume_handle = *r->in.resume_handle;
987 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
988 return status;
991 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
992 if (!samr_array) {
993 return NT_STATUS_NO_MEMORY;
995 *r->out.sam = samr_array;
997 become_root();
999 /* AS ROOT !!!! */
1001 if ((dinfo->disp_info->enum_users != NULL) &&
1002 (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
1003 TALLOC_FREE(dinfo->disp_info->enum_users);
1006 if (dinfo->disp_info->enum_users == NULL) {
1007 dinfo->disp_info->enum_users = pdb_search_users(
1008 dinfo->disp_info, r->in.acct_flags);
1009 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
1012 if (dinfo->disp_info->enum_users == NULL) {
1013 /* END AS ROOT !!!! */
1014 unbecome_root();
1015 return NT_STATUS_ACCESS_DENIED;
1018 num_account = pdb_search_entries(dinfo->disp_info->enum_users,
1019 enum_context, max_entries,
1020 &entries);
1022 /* END AS ROOT !!!! */
1024 unbecome_root();
1026 if (num_account == 0) {
1027 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
1028 "total entries\n"));
1029 *r->out.resume_handle = *r->in.resume_handle;
1030 return NT_STATUS_OK;
1033 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
1034 num_account, enum_context,
1035 entries);
1036 if (!NT_STATUS_IS_OK(status)) {
1037 return status;
1040 if (max_entries <= num_account) {
1041 status = STATUS_MORE_ENTRIES;
1042 } else {
1043 status = NT_STATUS_OK;
1046 /* Ensure we cache this enumeration. */
1047 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1049 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1051 samr_array->count = num_account;
1052 samr_array->entries = samr_entries;
1054 *r->out.resume_handle = *r->in.resume_handle + num_account;
1055 *r->out.num_entries = num_account;
1057 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1059 return status;
1062 /*******************************************************************
1063 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1064 ********************************************************************/
1066 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1067 struct samr_SamEntry **sam_pp,
1068 uint32_t num_sam_entries,
1069 struct samr_displayentry *entries)
1071 struct samr_SamEntry *sam;
1072 uint32_t i;
1074 *sam_pp = NULL;
1076 if (num_sam_entries == 0) {
1077 return;
1080 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1081 if (sam == NULL) {
1082 return;
1085 for (i = 0; i < num_sam_entries; i++) {
1087 * JRA. I think this should include the null. TNG does not.
1089 init_lsa_String(&sam[i].name, entries[i].account_name);
1090 sam[i].idx = entries[i].rid;
1093 *sam_pp = sam;
1096 /*******************************************************************
1097 _samr_EnumDomainGroups
1098 ********************************************************************/
1100 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1101 struct samr_EnumDomainGroups *r)
1103 NTSTATUS status;
1104 struct samr_domain_info *dinfo;
1105 struct samr_displayentry *groups;
1106 uint32 num_groups;
1107 struct samr_SamArray *samr_array = NULL;
1108 struct samr_SamEntry *samr_entries = NULL;
1110 dinfo = policy_handle_find(p, r->in.domain_handle,
1111 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1112 struct samr_domain_info, &status);
1113 if (!NT_STATUS_IS_OK(status)) {
1114 return status;
1117 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1119 if (sid_check_is_builtin(&dinfo->sid)) {
1120 /* No groups in builtin. */
1121 *r->out.resume_handle = *r->in.resume_handle;
1122 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1123 return status;
1126 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1127 if (!samr_array) {
1128 return NT_STATUS_NO_MEMORY;
1131 /* the domain group array is being allocated in the function below */
1133 become_root();
1135 if (dinfo->disp_info->groups == NULL) {
1136 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1138 if (dinfo->disp_info->groups == NULL) {
1139 unbecome_root();
1140 return NT_STATUS_ACCESS_DENIED;
1144 num_groups = pdb_search_entries(dinfo->disp_info->groups,
1145 *r->in.resume_handle,
1146 MAX_SAM_ENTRIES, &groups);
1147 unbecome_root();
1149 /* Ensure we cache this enumeration. */
1150 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1152 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1153 num_groups, groups);
1155 samr_array->count = num_groups;
1156 samr_array->entries = samr_entries;
1158 *r->out.sam = samr_array;
1159 *r->out.num_entries = num_groups;
1160 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1162 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1164 return status;
1167 /*******************************************************************
1168 _samr_EnumDomainAliases
1169 ********************************************************************/
1171 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1172 struct samr_EnumDomainAliases *r)
1174 NTSTATUS status;
1175 struct samr_domain_info *dinfo;
1176 struct samr_displayentry *aliases;
1177 uint32 num_aliases = 0;
1178 struct samr_SamArray *samr_array = NULL;
1179 struct samr_SamEntry *samr_entries = NULL;
1181 dinfo = policy_handle_find(p, r->in.domain_handle,
1182 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1183 struct samr_domain_info, &status);
1184 if (!NT_STATUS_IS_OK(status)) {
1185 return status;
1188 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1189 sid_string_dbg(&dinfo->sid)));
1191 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1192 if (!samr_array) {
1193 return NT_STATUS_NO_MEMORY;
1196 become_root();
1198 if (dinfo->disp_info->aliases == NULL) {
1199 dinfo->disp_info->aliases = pdb_search_aliases(
1200 dinfo->disp_info, &dinfo->sid);
1201 if (dinfo->disp_info->aliases == NULL) {
1202 unbecome_root();
1203 return NT_STATUS_ACCESS_DENIED;
1207 num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1208 *r->in.resume_handle,
1209 MAX_SAM_ENTRIES, &aliases);
1210 unbecome_root();
1212 /* Ensure we cache this enumeration. */
1213 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1215 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1216 num_aliases, aliases);
1218 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1220 samr_array->count = num_aliases;
1221 samr_array->entries = samr_entries;
1223 *r->out.sam = samr_array;
1224 *r->out.num_entries = num_aliases;
1225 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1227 return status;
1230 /*******************************************************************
1231 inits a samr_DispInfoGeneral structure.
1232 ********************************************************************/
1234 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1235 struct samr_DispInfoGeneral *r,
1236 uint32_t num_entries,
1237 uint32_t start_idx,
1238 struct samr_displayentry *entries)
1240 uint32 i;
1242 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1244 if (num_entries == 0) {
1245 return NT_STATUS_OK;
1248 r->count = num_entries;
1250 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1251 if (!r->entries) {
1252 return NT_STATUS_NO_MEMORY;
1255 for (i = 0; i < num_entries ; i++) {
1257 init_lsa_String(&r->entries[i].account_name,
1258 entries[i].account_name);
1260 init_lsa_String(&r->entries[i].description,
1261 entries[i].description);
1263 init_lsa_String(&r->entries[i].full_name,
1264 entries[i].fullname);
1266 r->entries[i].rid = entries[i].rid;
1267 r->entries[i].acct_flags = entries[i].acct_flags;
1268 r->entries[i].idx = start_idx+i+1;
1271 return NT_STATUS_OK;
1274 /*******************************************************************
1275 inits a samr_DispInfoFull structure.
1276 ********************************************************************/
1278 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1279 struct samr_DispInfoFull *r,
1280 uint32_t num_entries,
1281 uint32_t start_idx,
1282 struct samr_displayentry *entries)
1284 uint32_t i;
1286 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1288 if (num_entries == 0) {
1289 return NT_STATUS_OK;
1292 r->count = num_entries;
1294 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1295 if (!r->entries) {
1296 return NT_STATUS_NO_MEMORY;
1299 for (i = 0; i < num_entries ; i++) {
1301 init_lsa_String(&r->entries[i].account_name,
1302 entries[i].account_name);
1304 init_lsa_String(&r->entries[i].description,
1305 entries[i].description);
1307 r->entries[i].rid = entries[i].rid;
1308 r->entries[i].acct_flags = entries[i].acct_flags;
1309 r->entries[i].idx = start_idx+i+1;
1312 return NT_STATUS_OK;
1315 /*******************************************************************
1316 inits a samr_DispInfoFullGroups structure.
1317 ********************************************************************/
1319 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1320 struct samr_DispInfoFullGroups *r,
1321 uint32_t num_entries,
1322 uint32_t start_idx,
1323 struct samr_displayentry *entries)
1325 uint32_t i;
1327 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1329 if (num_entries == 0) {
1330 return NT_STATUS_OK;
1333 r->count = num_entries;
1335 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1336 if (!r->entries) {
1337 return NT_STATUS_NO_MEMORY;
1340 for (i = 0; i < num_entries ; i++) {
1342 init_lsa_String(&r->entries[i].account_name,
1343 entries[i].account_name);
1345 init_lsa_String(&r->entries[i].description,
1346 entries[i].description);
1348 r->entries[i].rid = entries[i].rid;
1349 r->entries[i].acct_flags = entries[i].acct_flags;
1350 r->entries[i].idx = start_idx+i+1;
1353 return NT_STATUS_OK;
1356 /*******************************************************************
1357 inits a samr_DispInfoAscii structure.
1358 ********************************************************************/
1360 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1361 struct samr_DispInfoAscii *r,
1362 uint32_t num_entries,
1363 uint32_t start_idx,
1364 struct samr_displayentry *entries)
1366 uint32_t i;
1368 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1370 if (num_entries == 0) {
1371 return NT_STATUS_OK;
1374 r->count = num_entries;
1376 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1377 if (!r->entries) {
1378 return NT_STATUS_NO_MEMORY;
1381 for (i = 0; i < num_entries ; i++) {
1383 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1384 entries[i].account_name);
1386 r->entries[i].idx = start_idx+i+1;
1389 return NT_STATUS_OK;
1392 /*******************************************************************
1393 inits a samr_DispInfoAscii structure.
1394 ********************************************************************/
1396 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1397 struct samr_DispInfoAscii *r,
1398 uint32_t num_entries,
1399 uint32_t start_idx,
1400 struct samr_displayentry *entries)
1402 uint32_t i;
1404 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1406 if (num_entries == 0) {
1407 return NT_STATUS_OK;
1410 r->count = num_entries;
1412 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1413 if (!r->entries) {
1414 return NT_STATUS_NO_MEMORY;
1417 for (i = 0; i < num_entries ; i++) {
1419 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1420 entries[i].account_name);
1422 r->entries[i].idx = start_idx+i+1;
1425 return NT_STATUS_OK;
1428 /*******************************************************************
1429 _samr_QueryDisplayInfo
1430 ********************************************************************/
1432 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1433 struct samr_QueryDisplayInfo *r)
1435 NTSTATUS status;
1436 struct samr_domain_info *dinfo;
1437 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1439 uint32 max_entries = r->in.max_entries;
1440 uint32 enum_context = r->in.start_idx;
1441 uint32 max_size = r->in.buf_size;
1443 union samr_DispInfo *disp_info = r->out.info;
1445 uint32 temp_size=0, total_data_size=0;
1446 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1447 uint32 num_account = 0;
1448 enum remote_arch_types ra_type = get_remote_arch();
1449 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1450 struct samr_displayentry *entries = NULL;
1452 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1454 dinfo = policy_handle_find(p, r->in.domain_handle,
1455 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1456 struct samr_domain_info, &status);
1457 if (!NT_STATUS_IS_OK(status)) {
1458 return status;
1462 * calculate how many entries we will return.
1463 * based on
1464 * - the number of entries the client asked
1465 * - our limit on that
1466 * - the starting point (enumeration context)
1467 * - the buffer size the client will accept
1471 * We are a lot more like W2K. Instead of reading the SAM
1472 * each time to find the records we need to send back,
1473 * we read it once and link that copy to the sam handle.
1474 * For large user list (over the MAX_SAM_ENTRIES)
1475 * it's a definitive win.
1476 * second point to notice: between enumerations
1477 * our sam is now the same as it's a snapshoot.
1478 * third point: got rid of the static SAM_USER_21 struct
1479 * no more intermediate.
1480 * con: it uses much more memory, as a full copy is stored
1481 * in memory.
1483 * If you want to change it, think twice and think
1484 * of the second point , that's really important.
1486 * JFM, 12/20/2001
1489 if ((r->in.level < 1) || (r->in.level > 5)) {
1490 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1491 (unsigned int)r->in.level ));
1492 return NT_STATUS_INVALID_INFO_CLASS;
1495 /* first limit the number of entries we will return */
1496 if(max_entries > max_sam_entries) {
1497 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1498 "entries, limiting to %d\n", max_entries,
1499 max_sam_entries));
1500 max_entries = max_sam_entries;
1503 /* calculate the size and limit on the number of entries we will
1504 * return */
1506 temp_size=max_entries*struct_size;
1508 if (temp_size>max_size) {
1509 max_entries=MIN((max_size/struct_size),max_entries);;
1510 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1511 "only %d entries\n", max_entries));
1514 become_root();
1516 /* THe following done as ROOT. Don't return without unbecome_root(). */
1518 switch (r->in.level) {
1519 case 0x1:
1520 case 0x4:
1521 if (dinfo->disp_info->users == NULL) {
1522 dinfo->disp_info->users = pdb_search_users(
1523 dinfo->disp_info, ACB_NORMAL);
1524 if (dinfo->disp_info->users == NULL) {
1525 unbecome_root();
1526 return NT_STATUS_ACCESS_DENIED;
1528 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1529 (unsigned int)enum_context ));
1530 } else {
1531 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1532 (unsigned int)enum_context ));
1535 num_account = pdb_search_entries(dinfo->disp_info->users,
1536 enum_context, max_entries,
1537 &entries);
1538 break;
1539 case 0x2:
1540 if (dinfo->disp_info->machines == NULL) {
1541 dinfo->disp_info->machines = pdb_search_users(
1542 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1543 if (dinfo->disp_info->machines == NULL) {
1544 unbecome_root();
1545 return NT_STATUS_ACCESS_DENIED;
1547 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1548 (unsigned int)enum_context ));
1549 } else {
1550 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1551 (unsigned int)enum_context ));
1554 num_account = pdb_search_entries(dinfo->disp_info->machines,
1555 enum_context, max_entries,
1556 &entries);
1557 break;
1558 case 0x3:
1559 case 0x5:
1560 if (dinfo->disp_info->groups == NULL) {
1561 dinfo->disp_info->groups = pdb_search_groups(
1562 dinfo->disp_info);
1563 if (dinfo->disp_info->groups == NULL) {
1564 unbecome_root();
1565 return NT_STATUS_ACCESS_DENIED;
1567 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1568 (unsigned int)enum_context ));
1569 } else {
1570 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1571 (unsigned int)enum_context ));
1574 num_account = pdb_search_entries(dinfo->disp_info->groups,
1575 enum_context, max_entries,
1576 &entries);
1577 break;
1578 default:
1579 unbecome_root();
1580 smb_panic("info class changed");
1581 break;
1583 unbecome_root();
1586 /* Now create reply structure */
1587 switch (r->in.level) {
1588 case 0x1:
1589 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1590 num_account, enum_context,
1591 entries);
1592 break;
1593 case 0x2:
1594 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1595 num_account, enum_context,
1596 entries);
1597 break;
1598 case 0x3:
1599 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1600 num_account, enum_context,
1601 entries);
1602 break;
1603 case 0x4:
1604 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1605 num_account, enum_context,
1606 entries);
1607 break;
1608 case 0x5:
1609 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1610 num_account, enum_context,
1611 entries);
1612 break;
1613 default:
1614 smb_panic("info class changed");
1615 break;
1618 if (!NT_STATUS_IS_OK(disp_ret))
1619 return disp_ret;
1621 /* calculate the total size */
1622 total_data_size=num_account*struct_size;
1624 if (max_entries <= num_account) {
1625 status = STATUS_MORE_ENTRIES;
1626 } else {
1627 status = NT_STATUS_OK;
1630 /* Ensure we cache this enumeration. */
1631 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1633 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1635 *r->out.total_size = total_data_size;
1636 *r->out.returned_size = temp_size;
1638 return status;
1641 /****************************************************************
1642 _samr_QueryDisplayInfo2
1643 ****************************************************************/
1645 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1646 struct samr_QueryDisplayInfo2 *r)
1648 struct samr_QueryDisplayInfo q;
1650 q.in.domain_handle = r->in.domain_handle;
1651 q.in.level = r->in.level;
1652 q.in.start_idx = r->in.start_idx;
1653 q.in.max_entries = r->in.max_entries;
1654 q.in.buf_size = r->in.buf_size;
1656 q.out.total_size = r->out.total_size;
1657 q.out.returned_size = r->out.returned_size;
1658 q.out.info = r->out.info;
1660 return _samr_QueryDisplayInfo(p, &q);
1663 /****************************************************************
1664 _samr_QueryDisplayInfo3
1665 ****************************************************************/
1667 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1668 struct samr_QueryDisplayInfo3 *r)
1670 struct samr_QueryDisplayInfo q;
1672 q.in.domain_handle = r->in.domain_handle;
1673 q.in.level = r->in.level;
1674 q.in.start_idx = r->in.start_idx;
1675 q.in.max_entries = r->in.max_entries;
1676 q.in.buf_size = r->in.buf_size;
1678 q.out.total_size = r->out.total_size;
1679 q.out.returned_size = r->out.returned_size;
1680 q.out.info = r->out.info;
1682 return _samr_QueryDisplayInfo(p, &q);
1685 /*******************************************************************
1686 _samr_QueryAliasInfo
1687 ********************************************************************/
1689 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1690 struct samr_QueryAliasInfo *r)
1692 DOM_SID sid;
1693 struct acct_info info;
1694 uint32 acc_granted;
1695 NTSTATUS status;
1696 union samr_AliasInfo *alias_info = NULL;
1697 const char *alias_name = NULL;
1698 const char *alias_description = NULL;
1700 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1702 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1703 if (!alias_info) {
1704 return NT_STATUS_NO_MEMORY;
1707 /* find the policy handle. open a policy on it. */
1708 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1709 return NT_STATUS_INVALID_HANDLE;
1711 status = access_check_samr_function(acc_granted,
1712 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1713 "_samr_QueryAliasInfo");
1714 if (!NT_STATUS_IS_OK(status)) {
1715 return status;
1718 become_root();
1719 status = pdb_get_aliasinfo(&sid, &info);
1720 unbecome_root();
1722 if ( !NT_STATUS_IS_OK(status))
1723 return status;
1725 /* FIXME: info contains fstrings */
1726 alias_name = talloc_strdup(r, info.acct_name);
1727 alias_description = talloc_strdup(r, info.acct_desc);
1729 switch (r->in.level) {
1730 case ALIASINFOALL:
1731 alias_info->all.name.string = alias_name;
1732 alias_info->all.num_members = 1; /* ??? */
1733 alias_info->all.description.string = alias_description;
1734 break;
1735 case ALIASINFODESCRIPTION:
1736 alias_info->description.string = alias_description;
1737 break;
1738 default:
1739 return NT_STATUS_INVALID_INFO_CLASS;
1742 *r->out.info = alias_info;
1744 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1746 return NT_STATUS_OK;
1749 /*******************************************************************
1750 _samr_LookupNames
1751 ********************************************************************/
1753 NTSTATUS _samr_LookupNames(pipes_struct *p,
1754 struct samr_LookupNames *r)
1756 struct samr_domain_info *dinfo;
1757 NTSTATUS status;
1758 uint32 *rid;
1759 enum lsa_SidType *type;
1760 int i;
1761 int num_rids = r->in.num_names;
1762 struct samr_Ids rids, types;
1763 uint32_t num_mapped = 0;
1765 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1767 dinfo = policy_handle_find(p, r->in.domain_handle,
1768 0 /* Don't know the acc_bits yet */, NULL,
1769 struct samr_domain_info, &status);
1770 if (!NT_STATUS_IS_OK(status)) {
1771 return status;
1774 if (num_rids > MAX_SAM_ENTRIES) {
1775 num_rids = MAX_SAM_ENTRIES;
1776 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1779 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1780 NT_STATUS_HAVE_NO_MEMORY(rid);
1782 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1783 NT_STATUS_HAVE_NO_MEMORY(type);
1785 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1786 sid_string_dbg(&dinfo->sid)));
1788 for (i = 0; i < num_rids; i++) {
1790 status = NT_STATUS_NONE_MAPPED;
1791 type[i] = SID_NAME_UNKNOWN;
1793 rid[i] = 0xffffffff;
1795 if (sid_check_is_builtin(&dinfo->sid)) {
1796 if (lookup_builtin_name(r->in.names[i].string,
1797 &rid[i]))
1799 type[i] = SID_NAME_ALIAS;
1801 } else {
1802 lookup_global_sam_name(r->in.names[i].string, 0,
1803 &rid[i], &type[i]);
1806 if (type[i] != SID_NAME_UNKNOWN) {
1807 num_mapped++;
1811 if (num_mapped == num_rids) {
1812 status = NT_STATUS_OK;
1813 } else if (num_mapped == 0) {
1814 status = NT_STATUS_NONE_MAPPED;
1815 } else {
1816 status = STATUS_SOME_UNMAPPED;
1819 rids.count = num_rids;
1820 rids.ids = rid;
1822 types.count = num_rids;
1823 types.ids = type;
1825 *r->out.rids = rids;
1826 *r->out.types = types;
1828 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1830 return status;
1833 /*******************************************************************
1834 _samr_ChangePasswordUser2
1835 ********************************************************************/
1837 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1838 struct samr_ChangePasswordUser2 *r)
1840 NTSTATUS status;
1841 fstring user_name;
1842 fstring wks;
1844 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1846 fstrcpy(user_name, r->in.account->string);
1847 fstrcpy(wks, r->in.server->string);
1849 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1852 * Pass the user through the NT -> unix user mapping
1853 * function.
1856 (void)map_username(user_name);
1859 * UNIX username case mangling not required, pass_oem_change
1860 * is case insensitive.
1863 status = pass_oem_change(user_name,
1864 r->in.lm_password->data,
1865 r->in.lm_verifier->hash,
1866 r->in.nt_password->data,
1867 r->in.nt_verifier->hash,
1868 NULL);
1870 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1872 return status;
1875 /*******************************************************************
1876 _samr_ChangePasswordUser3
1877 ********************************************************************/
1879 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1880 struct samr_ChangePasswordUser3 *r)
1882 NTSTATUS status;
1883 fstring user_name;
1884 const char *wks = NULL;
1885 uint32 reject_reason;
1886 struct samr_DomInfo1 *dominfo = NULL;
1887 struct samr_ChangeReject *reject = NULL;
1888 uint32_t tmp;
1890 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1892 fstrcpy(user_name, r->in.account->string);
1893 if (r->in.server && r->in.server->string) {
1894 wks = r->in.server->string;
1897 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1900 * Pass the user through the NT -> unix user mapping
1901 * function.
1904 (void)map_username(user_name);
1907 * UNIX username case mangling not required, pass_oem_change
1908 * is case insensitive.
1911 status = pass_oem_change(user_name,
1912 r->in.lm_password->data,
1913 r->in.lm_verifier->hash,
1914 r->in.nt_password->data,
1915 r->in.nt_verifier->hash,
1916 &reject_reason);
1918 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1919 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1921 time_t u_expire, u_min_age;
1922 uint32 account_policy_temp;
1924 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1925 if (!dominfo) {
1926 return NT_STATUS_NO_MEMORY;
1929 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1930 if (!reject) {
1931 return NT_STATUS_NO_MEMORY;
1934 become_root();
1936 /* AS ROOT !!! */
1938 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
1939 dominfo->min_password_length = tmp;
1941 pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
1942 dominfo->password_history_length = tmp;
1944 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
1945 &dominfo->password_properties);
1947 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1948 u_expire = account_policy_temp;
1950 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1951 u_min_age = account_policy_temp;
1953 /* !AS ROOT */
1955 unbecome_root();
1957 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
1958 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
1960 if (lp_check_password_script() && *lp_check_password_script()) {
1961 dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
1964 reject->reason = reject_reason;
1966 *r->out.dominfo = dominfo;
1967 *r->out.reject = reject;
1970 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1972 return status;
1975 /*******************************************************************
1976 makes a SAMR_R_LOOKUP_RIDS structure.
1977 ********************************************************************/
1979 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1980 const char **names,
1981 struct lsa_String **lsa_name_array_p)
1983 struct lsa_String *lsa_name_array = NULL;
1984 uint32_t i;
1986 *lsa_name_array_p = NULL;
1988 if (num_names != 0) {
1989 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
1990 if (!lsa_name_array) {
1991 return false;
1995 for (i = 0; i < num_names; i++) {
1996 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
1997 init_lsa_String(&lsa_name_array[i], names[i]);
2000 *lsa_name_array_p = lsa_name_array;
2002 return true;
2005 /*******************************************************************
2006 _samr_LookupRids
2007 ********************************************************************/
2009 NTSTATUS _samr_LookupRids(pipes_struct *p,
2010 struct samr_LookupRids *r)
2012 struct samr_domain_info *dinfo;
2013 NTSTATUS status;
2014 const char **names;
2015 enum lsa_SidType *attrs = NULL;
2016 uint32 *wire_attrs = NULL;
2017 int num_rids = (int)r->in.num_rids;
2018 int i;
2019 struct lsa_Strings names_array;
2020 struct samr_Ids types_array;
2021 struct lsa_String *lsa_names = NULL;
2023 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2025 dinfo = policy_handle_find(p, r->in.domain_handle,
2026 0 /* Don't know the acc_bits yet */, NULL,
2027 struct samr_domain_info, &status);
2028 if (!NT_STATUS_IS_OK(status)) {
2029 return status;
2032 if (num_rids > 1000) {
2033 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2034 "to samba4 idl this is not possible\n", num_rids));
2035 return NT_STATUS_UNSUCCESSFUL;
2038 if (num_rids) {
2039 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2040 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2041 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2043 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2044 return NT_STATUS_NO_MEMORY;
2045 } else {
2046 names = NULL;
2047 attrs = NULL;
2048 wire_attrs = NULL;
2051 become_root(); /* lookup_sid can require root privs */
2052 status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2053 names, attrs);
2054 unbecome_root();
2056 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2057 status = NT_STATUS_OK;
2060 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2061 &lsa_names)) {
2062 return NT_STATUS_NO_MEMORY;
2065 /* Convert from enum lsa_SidType to uint32 for wire format. */
2066 for (i = 0; i < num_rids; i++) {
2067 wire_attrs[i] = (uint32)attrs[i];
2070 names_array.count = num_rids;
2071 names_array.names = lsa_names;
2073 types_array.count = num_rids;
2074 types_array.ids = wire_attrs;
2076 *r->out.names = names_array;
2077 *r->out.types = types_array;
2079 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2081 return status;
2084 /*******************************************************************
2085 _samr_OpenUser
2086 ********************************************************************/
2088 NTSTATUS _samr_OpenUser(pipes_struct *p,
2089 struct samr_OpenUser *r)
2091 struct samu *sampass=NULL;
2092 DOM_SID sid;
2093 struct samr_domain_info *dinfo;
2094 struct samr_info *info;
2095 SEC_DESC *psd = NULL;
2096 uint32 acc_granted;
2097 uint32 des_access = r->in.access_mask;
2098 size_t sd_size;
2099 bool ret;
2100 NTSTATUS nt_status;
2101 SE_PRIV se_rights;
2102 NTSTATUS status;
2104 dinfo = policy_handle_find(p, r->in.domain_handle,
2105 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2106 struct samr_domain_info, &status);
2107 if (!NT_STATUS_IS_OK(status)) {
2108 return status;
2111 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2112 return NT_STATUS_NO_MEMORY;
2115 /* append the user's RID to it */
2117 if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2118 return NT_STATUS_NO_SUCH_USER;
2120 /* check if access can be granted as requested by client. */
2122 map_max_allowed_access(p->server_info->ptok, &des_access);
2124 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2125 se_map_generic(&des_access, &usr_generic_mapping);
2127 se_priv_copy( &se_rights, &se_machine_account );
2128 se_priv_add( &se_rights, &se_add_users );
2130 nt_status = access_check_samr_object(psd, p->server_info->ptok,
2131 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2132 &acc_granted, "_samr_OpenUser");
2134 if ( !NT_STATUS_IS_OK(nt_status) )
2135 return nt_status;
2137 become_root();
2138 ret=pdb_getsampwsid(sampass, &sid);
2139 unbecome_root();
2141 /* check that the SID exists in our domain. */
2142 if (ret == False) {
2143 return NT_STATUS_NO_SUCH_USER;
2146 TALLOC_FREE(sampass);
2148 /* associate the user's SID and access bits with the new handle. */
2149 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
2150 return NT_STATUS_NO_MEMORY;
2151 info->acc_granted = acc_granted;
2153 /* get a (unique) handle. open a policy on it. */
2154 if (!create_policy_hnd(p, r->out.user_handle, info))
2155 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2157 return NT_STATUS_OK;
2160 /*************************************************************************
2161 *************************************************************************/
2163 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2164 DATA_BLOB *blob,
2165 struct lsa_BinaryString **_r)
2167 struct lsa_BinaryString *r;
2169 if (!blob || !_r) {
2170 return NT_STATUS_INVALID_PARAMETER;
2173 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2174 if (!r) {
2175 return NT_STATUS_NO_MEMORY;
2178 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2179 if (!r->array) {
2180 return NT_STATUS_NO_MEMORY;
2182 memcpy(r->array, blob->data, blob->length);
2183 r->size = blob->length;
2184 r->length = blob->length;
2186 if (!r->array) {
2187 return NT_STATUS_NO_MEMORY;
2190 *_r = r;
2192 return NT_STATUS_OK;
2195 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2196 struct samr_UserInfo5 *r,
2197 struct samu *pw,
2198 DOM_SID *domain_sid)
2200 const DOM_SID *sid_user, *sid_group;
2201 uint32_t rid, primary_gid;
2203 sid_user = pdb_get_user_sid(pw);
2205 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2206 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2207 "the domain sid %s. Failing operation.\n",
2208 pdb_get_username(pw), sid_string_dbg(sid_user),
2209 sid_string_dbg(domain_sid)));
2210 return NT_STATUS_UNSUCCESSFUL;
2213 become_root();
2214 sid_group = pdb_get_group_sid(pw);
2215 unbecome_root();
2217 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2218 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2219 "which conflicts with the domain sid %s. Failing operation.\n",
2220 pdb_get_username(pw), sid_string_dbg(sid_group),
2221 sid_string_dbg(domain_sid)));
2222 return NT_STATUS_UNSUCCESSFUL;
2225 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2226 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2227 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2228 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2230 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2231 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2232 r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2233 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2234 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2235 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2236 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2237 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2239 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2240 r->rid = rid;
2241 r->primary_gid = primary_gid;
2242 r->acct_flags = pdb_get_acct_ctrl(pw);
2243 r->bad_password_count = pdb_get_bad_password_count(pw);
2244 r->logon_count = pdb_get_logon_count(pw);
2246 return NT_STATUS_OK;
2249 /*************************************************************************
2250 get_user_info_7. Safe. Only gives out account_name.
2251 *************************************************************************/
2253 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2254 struct samr_UserInfo7 *r,
2255 struct samu *smbpass)
2257 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2258 if (!r->account_name.string) {
2259 return NT_STATUS_NO_MEMORY;
2262 return NT_STATUS_OK;
2265 /*************************************************************************
2266 get_user_info_9. Only gives out primary group SID.
2267 *************************************************************************/
2269 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2270 struct samr_UserInfo9 *r,
2271 struct samu *smbpass)
2273 r->primary_gid = pdb_get_group_rid(smbpass);
2275 return NT_STATUS_OK;
2278 /*************************************************************************
2279 get_user_info_16. Safe. Only gives out acb bits.
2280 *************************************************************************/
2282 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2283 struct samr_UserInfo16 *r,
2284 struct samu *smbpass)
2286 r->acct_flags = pdb_get_acct_ctrl(smbpass);
2288 return NT_STATUS_OK;
2291 /*************************************************************************
2292 get_user_info_18. OK - this is the killer as it gives out password info.
2293 Ensure that this is only allowed on an encrypted connection with a root
2294 user. JRA.
2295 *************************************************************************/
2297 static NTSTATUS get_user_info_18(pipes_struct *p,
2298 TALLOC_CTX *mem_ctx,
2299 struct samr_UserInfo18 *r,
2300 DOM_SID *user_sid)
2302 struct samu *smbpass=NULL;
2303 bool ret;
2305 ZERO_STRUCTP(r);
2307 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2308 return NT_STATUS_ACCESS_DENIED;
2311 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2312 return NT_STATUS_ACCESS_DENIED;
2316 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2319 if ( !(smbpass = samu_new( mem_ctx )) ) {
2320 return NT_STATUS_NO_MEMORY;
2323 ret = pdb_getsampwsid(smbpass, user_sid);
2325 if (ret == False) {
2326 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2327 TALLOC_FREE(smbpass);
2328 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2331 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2333 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2334 TALLOC_FREE(smbpass);
2335 return NT_STATUS_ACCOUNT_DISABLED;
2338 r->lm_pwd_active = true;
2339 r->nt_pwd_active = true;
2340 memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
2341 memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
2342 r->password_expired = 0; /* FIXME */
2344 TALLOC_FREE(smbpass);
2346 return NT_STATUS_OK;
2349 /*************************************************************************
2350 get_user_info_20
2351 *************************************************************************/
2353 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2354 struct samr_UserInfo20 *r,
2355 struct samu *sampass)
2357 const char *munged_dial = NULL;
2358 DATA_BLOB blob;
2359 NTSTATUS status;
2360 struct lsa_BinaryString *parameters = NULL;
2362 ZERO_STRUCTP(r);
2364 munged_dial = pdb_get_munged_dial(sampass);
2366 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2367 munged_dial, (int)strlen(munged_dial)));
2369 if (munged_dial) {
2370 blob = base64_decode_data_blob(munged_dial);
2371 } else {
2372 blob = data_blob_string_const_null("");
2375 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2376 data_blob_free(&blob);
2377 if (!NT_STATUS_IS_OK(status)) {
2378 return status;
2381 r->parameters = *parameters;
2383 return NT_STATUS_OK;
2387 /*************************************************************************
2388 get_user_info_21
2389 *************************************************************************/
2391 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2392 struct samr_UserInfo21 *r,
2393 struct samu *pw,
2394 DOM_SID *domain_sid)
2396 NTSTATUS status;
2397 const DOM_SID *sid_user, *sid_group;
2398 uint32_t rid, primary_gid;
2399 NTTIME force_password_change;
2400 time_t must_change_time;
2401 struct lsa_BinaryString *parameters = NULL;
2402 const char *munged_dial = NULL;
2403 DATA_BLOB blob;
2405 ZERO_STRUCTP(r);
2407 sid_user = pdb_get_user_sid(pw);
2409 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2410 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2411 "the domain sid %s. Failing operation.\n",
2412 pdb_get_username(pw), sid_string_dbg(sid_user),
2413 sid_string_dbg(domain_sid)));
2414 return NT_STATUS_UNSUCCESSFUL;
2417 become_root();
2418 sid_group = pdb_get_group_sid(pw);
2419 unbecome_root();
2421 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2422 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2423 "which conflicts with the domain sid %s. Failing operation.\n",
2424 pdb_get_username(pw), sid_string_dbg(sid_group),
2425 sid_string_dbg(domain_sid)));
2426 return NT_STATUS_UNSUCCESSFUL;
2429 unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2430 unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2431 unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2432 unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2433 unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2435 must_change_time = pdb_get_pass_must_change_time(pw);
2436 if (must_change_time == get_time_t_max()) {
2437 unix_to_nt_time_abs(&force_password_change, must_change_time);
2438 } else {
2439 unix_to_nt_time(&force_password_change, must_change_time);
2442 munged_dial = pdb_get_munged_dial(pw);
2443 if (munged_dial) {
2444 blob = base64_decode_data_blob(munged_dial);
2445 } else {
2446 blob = data_blob_string_const_null("");
2449 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2450 data_blob_free(&blob);
2451 if (!NT_STATUS_IS_OK(status)) {
2452 return status;
2455 r->force_password_change = force_password_change;
2457 r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(pw));
2458 r->full_name.string = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2459 r->home_directory.string = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2460 r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2461 r->logon_script.string = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2462 r->profile_path.string = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2463 r->description.string = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2464 r->workstations.string = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2465 r->comment.string = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2467 r->logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2468 r->parameters = *parameters;
2469 r->rid = rid;
2470 r->primary_gid = primary_gid;
2471 r->acct_flags = pdb_get_acct_ctrl(pw);
2472 r->bad_password_count = pdb_get_bad_password_count(pw);
2473 r->logon_count = pdb_get_logon_count(pw);
2474 r->fields_present = pdb_build_fields_present(pw);
2475 r->password_expired = (pdb_get_pass_must_change_time(pw) == 0) ?
2476 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2477 r->country_code = 0;
2478 r->code_page = 0;
2479 r->lm_password_set = 0;
2480 r->nt_password_set = 0;
2482 #if 0
2485 Look at a user on a real NT4 PDC with usrmgr, press
2486 'ok'. Then you will see that fields_present is set to
2487 0x08f827fa. Look at the user immediately after that again,
2488 and you will see that 0x00fffff is returned. This solves
2489 the problem that you get access denied after having looked
2490 at the user.
2491 -- Volker
2494 #endif
2497 return NT_STATUS_OK;
2500 /*******************************************************************
2501 _samr_QueryUserInfo
2502 ********************************************************************/
2504 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2505 struct samr_QueryUserInfo *r)
2507 NTSTATUS status;
2508 union samr_UserInfo *user_info = NULL;
2509 struct samr_info *info = NULL;
2510 DOM_SID domain_sid;
2511 uint32 rid;
2512 bool ret = false;
2513 struct samu *pwd = NULL;
2515 /* search for the handle */
2516 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2517 return NT_STATUS_INVALID_HANDLE;
2519 status = access_check_samr_function(info->acc_granted,
2520 SAMR_USER_ACCESS_GET_ATTRIBUTES,
2521 "_samr_QueryUserInfo");
2522 if (!NT_STATUS_IS_OK(status)) {
2523 return status;
2526 domain_sid = info->sid;
2528 sid_split_rid(&domain_sid, &rid);
2530 if (!sid_check_is_in_our_domain(&info->sid))
2531 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2533 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2534 sid_string_dbg(&info->sid)));
2536 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2537 if (!user_info) {
2538 return NT_STATUS_NO_MEMORY;
2541 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2543 if (!(pwd = samu_new(p->mem_ctx))) {
2544 return NT_STATUS_NO_MEMORY;
2547 become_root();
2548 ret = pdb_getsampwsid(pwd, &info->sid);
2549 unbecome_root();
2551 if (ret == false) {
2552 DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
2553 TALLOC_FREE(pwd);
2554 return NT_STATUS_NO_SUCH_USER;
2557 DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
2559 samr_clear_sam_passwd(pwd);
2561 switch (r->in.level) {
2562 case 5:
2563 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
2564 break;
2565 case 7:
2566 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
2567 break;
2568 case 9:
2569 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
2570 break;
2571 case 16:
2572 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
2573 break;
2574 case 18:
2575 /* level 18 is special */
2576 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2577 break;
2578 case 20:
2579 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
2580 break;
2581 case 21:
2582 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
2583 break;
2584 default:
2585 status = NT_STATUS_INVALID_INFO_CLASS;
2586 break;
2589 TALLOC_FREE(pwd);
2591 *r->out.info = user_info;
2593 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2595 return status;
2598 /****************************************************************
2599 ****************************************************************/
2601 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
2602 struct samr_QueryUserInfo2 *r)
2604 struct samr_QueryUserInfo u;
2606 u.in.user_handle = r->in.user_handle;
2607 u.in.level = r->in.level;
2608 u.out.info = r->out.info;
2610 return _samr_QueryUserInfo(p, &u);
2613 /*******************************************************************
2614 _samr_GetGroupsForUser
2615 ********************************************************************/
2617 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2618 struct samr_GetGroupsForUser *r)
2620 struct samu *sam_pass=NULL;
2621 DOM_SID sid;
2622 DOM_SID *sids;
2623 struct samr_RidWithAttribute dom_gid;
2624 struct samr_RidWithAttribute *gids = NULL;
2625 uint32 primary_group_rid;
2626 size_t num_groups = 0;
2627 gid_t *unix_gids;
2628 size_t i, num_gids;
2629 uint32 acc_granted;
2630 bool ret;
2631 NTSTATUS result;
2632 bool success = False;
2634 struct samr_RidWithAttributeArray *rids = NULL;
2637 * from the SID in the request:
2638 * we should send back the list of DOMAIN GROUPS
2639 * the user is a member of
2641 * and only the DOMAIN GROUPS
2642 * no ALIASES !!! neither aliases of the domain
2643 * nor aliases of the builtin SID
2645 * JFM, 12/2/2001
2648 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2650 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2651 if (!rids) {
2652 return NT_STATUS_NO_MEMORY;
2655 /* find the policy handle. open a policy on it. */
2656 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2657 return NT_STATUS_INVALID_HANDLE;
2659 result = access_check_samr_function(acc_granted,
2660 SAMR_USER_ACCESS_GET_GROUPS,
2661 "_samr_GetGroupsForUser");
2662 if (!NT_STATUS_IS_OK(result)) {
2663 return result;
2666 if (!sid_check_is_in_our_domain(&sid))
2667 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2669 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2670 return NT_STATUS_NO_MEMORY;
2673 become_root();
2674 ret = pdb_getsampwsid(sam_pass, &sid);
2675 unbecome_root();
2677 if (!ret) {
2678 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2679 sid_string_dbg(&sid)));
2680 return NT_STATUS_NO_SUCH_USER;
2683 sids = NULL;
2685 /* make both calls inside the root block */
2686 become_root();
2687 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2688 &sids, &unix_gids, &num_groups);
2689 if ( NT_STATUS_IS_OK(result) ) {
2690 success = sid_peek_check_rid(get_global_sam_sid(),
2691 pdb_get_group_sid(sam_pass),
2692 &primary_group_rid);
2694 unbecome_root();
2696 if (!NT_STATUS_IS_OK(result)) {
2697 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2698 sid_string_dbg(&sid)));
2699 return result;
2702 if ( !success ) {
2703 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2704 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2705 pdb_get_username(sam_pass)));
2706 TALLOC_FREE(sam_pass);
2707 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2710 gids = NULL;
2711 num_gids = 0;
2713 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2714 SE_GROUP_ENABLED);
2715 dom_gid.rid = primary_group_rid;
2716 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2718 for (i=0; i<num_groups; i++) {
2720 if (!sid_peek_check_rid(get_global_sam_sid(),
2721 &(sids[i]), &dom_gid.rid)) {
2722 DEBUG(10, ("Found sid %s not in our domain\n",
2723 sid_string_dbg(&sids[i])));
2724 continue;
2727 if (dom_gid.rid == primary_group_rid) {
2728 /* We added the primary group directly from the
2729 * sam_account. The other SIDs are unique from
2730 * enum_group_memberships */
2731 continue;
2734 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2737 rids->count = num_gids;
2738 rids->rids = gids;
2740 *r->out.rids = rids;
2742 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2744 return result;
2747 /*******************************************************************
2748 _samr_QueryDomainInfo
2749 ********************************************************************/
2751 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
2752 struct samr_QueryDomainInfo *r)
2754 NTSTATUS status = NT_STATUS_OK;
2755 struct samr_domain_info *dinfo;
2756 union samr_DomainInfo *dom_info;
2757 time_t u_expire, u_min_age;
2759 time_t u_lock_duration, u_reset_time;
2760 uint32_t u_logout;
2762 uint32 account_policy_temp;
2764 time_t seq_num;
2765 uint32 server_role;
2767 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2769 dinfo = policy_handle_find(p, r->in.domain_handle,
2770 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
2771 struct samr_domain_info, &status);
2772 if (!NT_STATUS_IS_OK(status)) {
2773 return status;
2776 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2777 if (!dom_info) {
2778 return NT_STATUS_NO_MEMORY;
2781 switch (r->in.level) {
2782 case 0x01:
2784 become_root();
2786 /* AS ROOT !!! */
2788 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
2789 &account_policy_temp);
2790 dom_info->info1.min_password_length = account_policy_temp;
2792 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2793 dom_info->info1.password_history_length = account_policy_temp;
2795 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
2796 &dom_info->info1.password_properties);
2798 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2799 u_expire = account_policy_temp;
2801 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2802 u_min_age = account_policy_temp;
2804 /* !AS ROOT */
2806 unbecome_root();
2808 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.max_password_age, u_expire);
2809 unix_to_nt_time_abs((NTTIME *)&dom_info->info1.min_password_age, u_min_age);
2811 if (lp_check_password_script() && *lp_check_password_script()) {
2812 dom_info->info1.password_properties |= DOMAIN_PASSWORD_COMPLEX;
2815 break;
2816 case 0x02:
2818 become_root();
2820 /* AS ROOT !!! */
2822 dom_info->general.num_users = count_sam_users(
2823 dinfo->disp_info, ACB_NORMAL);
2824 dom_info->general.num_groups = count_sam_groups(
2825 dinfo->disp_info);
2826 dom_info->general.num_aliases = count_sam_aliases(
2827 dinfo->disp_info);
2829 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
2831 unix_to_nt_time_abs(&dom_info->general.force_logoff_time, u_logout);
2833 if (!pdb_get_seq_num(&seq_num))
2834 seq_num = time(NULL);
2836 /* !AS ROOT */
2838 unbecome_root();
2840 server_role = ROLE_DOMAIN_PDC;
2841 if (lp_server_role() == ROLE_DOMAIN_BDC)
2842 server_role = ROLE_DOMAIN_BDC;
2844 dom_info->general.oem_information.string = lp_serverstring();
2845 dom_info->general.domain_name.string = lp_workgroup();
2846 dom_info->general.primary.string = global_myname();
2847 dom_info->general.sequence_num = seq_num;
2848 dom_info->general.domain_server_state = DOMAIN_SERVER_ENABLED;
2849 dom_info->general.role = server_role;
2850 dom_info->general.unknown3 = 1;
2852 break;
2853 case 0x03:
2855 become_root();
2857 /* AS ROOT !!! */
2860 uint32 ul;
2861 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2862 u_logout = (time_t)ul;
2865 /* !AS ROOT */
2867 unbecome_root();
2869 unix_to_nt_time_abs(&dom_info->info3.force_logoff_time, u_logout);
2871 break;
2872 case 0x04:
2873 dom_info->oem.oem_information.string = lp_serverstring();
2874 break;
2875 case 0x05:
2876 dom_info->info5.domain_name.string = get_global_sam_name();
2877 break;
2878 case 0x06:
2879 /* NT returns its own name when a PDC. win2k and later
2880 * only the name of the PDC if itself is a BDC (samba4
2881 * idl) */
2882 dom_info->info6.primary.string = global_myname();
2883 break;
2884 case 0x07:
2885 server_role = ROLE_DOMAIN_PDC;
2886 if (lp_server_role() == ROLE_DOMAIN_BDC)
2887 server_role = ROLE_DOMAIN_BDC;
2889 dom_info->info7.role = server_role;
2890 break;
2891 case 0x08:
2893 become_root();
2895 /* AS ROOT !!! */
2897 if (!pdb_get_seq_num(&seq_num)) {
2898 seq_num = time(NULL);
2901 /* !AS ROOT */
2903 unbecome_root();
2905 dom_info->info8.sequence_num = seq_num;
2906 dom_info->info8.domain_create_time = 0;
2908 break;
2909 case 0x0c:
2911 become_root();
2913 /* AS ROOT !!! */
2915 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2916 u_lock_duration = account_policy_temp;
2917 if (u_lock_duration != -1) {
2918 u_lock_duration *= 60;
2921 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2922 u_reset_time = account_policy_temp * 60;
2924 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
2925 &account_policy_temp);
2926 dom_info->info12.lockout_threshold = account_policy_temp;
2928 /* !AS ROOT */
2930 unbecome_root();
2932 unix_to_nt_time_abs(&dom_info->info12.lockout_duration,
2933 u_lock_duration);
2934 unix_to_nt_time_abs(&dom_info->info12.lockout_window,
2935 u_reset_time);
2937 break;
2938 default:
2939 return NT_STATUS_INVALID_INFO_CLASS;
2942 *r->out.info = dom_info;
2944 DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
2946 return status;
2949 /* W2k3 seems to use the same check for all 3 objects that can be created via
2950 * SAMR, if you try to create for example "Dialup" as an alias it says
2951 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
2952 * database. */
2954 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
2956 enum lsa_SidType type;
2957 bool result;
2959 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
2961 become_root();
2962 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
2963 * whether the name already exists */
2964 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
2965 NULL, NULL, NULL, &type);
2966 unbecome_root();
2968 if (!result) {
2969 DEBUG(10, ("%s does not exist, can create it\n", new_name));
2970 return NT_STATUS_OK;
2973 DEBUG(5, ("trying to create %s, exists as %s\n",
2974 new_name, sid_type_lookup(type)));
2976 if (type == SID_NAME_DOM_GRP) {
2977 return NT_STATUS_GROUP_EXISTS;
2979 if (type == SID_NAME_ALIAS) {
2980 return NT_STATUS_ALIAS_EXISTS;
2983 /* Yes, the default is NT_STATUS_USER_EXISTS */
2984 return NT_STATUS_USER_EXISTS;
2987 /*******************************************************************
2988 _samr_CreateUser2
2989 ********************************************************************/
2991 NTSTATUS _samr_CreateUser2(pipes_struct *p,
2992 struct samr_CreateUser2 *r)
2994 const char *account = NULL;
2995 DOM_SID sid;
2996 uint32_t acb_info = r->in.acct_flags;
2997 struct samr_domain_info *dinfo;
2998 struct samr_info *info;
2999 NTSTATUS nt_status;
3000 uint32 acc_granted;
3001 SEC_DESC *psd;
3002 size_t sd_size;
3003 /* check this, when giving away 'add computer to domain' privs */
3004 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3005 bool can_add_account = False;
3006 SE_PRIV se_rights;
3008 dinfo = policy_handle_find(p, r->in.domain_handle,
3009 SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3010 struct samr_domain_info, &nt_status);
3011 if (!NT_STATUS_IS_OK(nt_status)) {
3012 return nt_status;
3015 if (sid_check_is_builtin(&dinfo->sid)) {
3016 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3017 return NT_STATUS_ACCESS_DENIED;
3020 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3021 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3022 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3023 this parameter is not an account type */
3024 return NT_STATUS_INVALID_PARAMETER;
3027 account = r->in.account_name->string;
3028 if (account == NULL) {
3029 return NT_STATUS_NO_MEMORY;
3032 nt_status = can_create(p->mem_ctx, account);
3033 if (!NT_STATUS_IS_OK(nt_status)) {
3034 return nt_status;
3037 /* determine which user right we need to check based on the acb_info */
3039 if ( acb_info & ACB_WSTRUST )
3041 se_priv_copy( &se_rights, &se_machine_account );
3042 can_add_account = user_has_privileges(
3043 p->server_info->ptok, &se_rights );
3045 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3046 account for domain trusts and changes the ACB flags later */
3047 else if ( acb_info & ACB_NORMAL &&
3048 (account[strlen(account)-1] != '$') )
3050 se_priv_copy( &se_rights, &se_add_users );
3051 can_add_account = user_has_privileges(
3052 p->server_info->ptok, &se_rights );
3054 else /* implicit assumption of a BDC or domain trust account here
3055 * (we already check the flags earlier) */
3057 if ( lp_enable_privileges() ) {
3058 /* only Domain Admins can add a BDC or domain trust */
3059 se_priv_copy( &se_rights, &se_priv_none );
3060 can_add_account = nt_token_check_domain_rid(
3061 p->server_info->ptok,
3062 DOMAIN_GROUP_RID_ADMINS );
3066 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3067 uidtoname(p->server_info->utok.uid),
3068 can_add_account ? "True":"False" ));
3070 /********** BEGIN Admin BLOCK **********/
3072 if ( can_add_account )
3073 become_root();
3075 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3076 r->out.rid);
3078 if ( can_add_account )
3079 unbecome_root();
3081 /********** END Admin BLOCK **********/
3083 /* now check for failure */
3085 if ( !NT_STATUS_IS_OK(nt_status) )
3086 return nt_status;
3088 /* Get the user's SID */
3090 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3092 map_max_allowed_access(p->server_info->ptok, &des_access);
3094 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3095 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3096 se_map_generic(&des_access, &usr_generic_mapping);
3098 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3099 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3100 &acc_granted, "_samr_CreateUser2");
3102 if ( !NT_STATUS_IS_OK(nt_status) ) {
3103 return nt_status;
3106 /* associate the user's SID with the new handle. */
3107 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL) {
3108 return NT_STATUS_NO_MEMORY;
3111 ZERO_STRUCTP(info);
3112 info->sid = sid;
3113 info->acc_granted = acc_granted;
3115 /* get a (unique) handle. open a policy on it. */
3116 if (!create_policy_hnd(p, r->out.user_handle, info)) {
3117 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3120 /* After a "set" ensure we have no cached display info. */
3121 force_flush_samr_cache(&sid);
3123 *r->out.access_granted = acc_granted;
3125 return NT_STATUS_OK;
3128 /****************************************************************
3129 ****************************************************************/
3131 NTSTATUS _samr_CreateUser(pipes_struct *p,
3132 struct samr_CreateUser *r)
3134 struct samr_CreateUser2 c;
3135 uint32_t access_granted;
3137 c.in.domain_handle = r->in.domain_handle;
3138 c.in.account_name = r->in.account_name;
3139 c.in.acct_flags = ACB_NORMAL;
3140 c.in.access_mask = r->in.access_mask;
3141 c.out.user_handle = r->out.user_handle;
3142 c.out.access_granted = &access_granted;
3143 c.out.rid = r->out.rid;
3145 return _samr_CreateUser2(p, &c);
3148 /*******************************************************************
3149 _samr_Connect
3150 ********************************************************************/
3152 NTSTATUS _samr_Connect(pipes_struct *p,
3153 struct samr_Connect *r)
3155 struct samr_connect_info *info;
3156 uint32_t acc_granted;
3157 struct policy_handle hnd;
3158 uint32 des_access = r->in.access_mask;
3159 NTSTATUS status;
3161 /* Access check */
3163 if (!pipe_access_check(p)) {
3164 DEBUG(3, ("access denied to _samr_Connect\n"));
3165 return NT_STATUS_ACCESS_DENIED;
3168 /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
3169 was observed from a win98 client trying to enumerate users (when configured
3170 user level access control on shares) --jerry */
3172 map_max_allowed_access(p->server_info->ptok, &des_access);
3174 se_map_generic( &des_access, &sam_generic_mapping );
3176 acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3177 |SAMR_ACCESS_LOOKUP_DOMAIN);
3179 /* set up the SAMR connect_anon response */
3181 info = policy_handle_create(p, &hnd, acc_granted,
3182 struct samr_connect_info,
3183 &status);
3184 if (!NT_STATUS_IS_OK(status)) {
3185 return status;
3188 *r->out.connect_handle = hnd;
3189 return NT_STATUS_OK;
3192 /*******************************************************************
3193 _samr_Connect2
3194 ********************************************************************/
3196 NTSTATUS _samr_Connect2(pipes_struct *p,
3197 struct samr_Connect2 *r)
3199 struct samr_connect_info *info = NULL;
3200 struct policy_handle hnd;
3201 SEC_DESC *psd = NULL;
3202 uint32 acc_granted;
3203 uint32 des_access = r->in.access_mask;
3204 NTSTATUS nt_status;
3205 size_t sd_size;
3206 const char *fn = "_samr_Connect2";
3208 switch (p->hdr_req.opnum) {
3209 case NDR_SAMR_CONNECT2:
3210 fn = "_samr_Connect2";
3211 break;
3212 case NDR_SAMR_CONNECT3:
3213 fn = "_samr_Connect3";
3214 break;
3215 case NDR_SAMR_CONNECT4:
3216 fn = "_samr_Connect4";
3217 break;
3218 case NDR_SAMR_CONNECT5:
3219 fn = "_samr_Connect5";
3220 break;
3223 DEBUG(5,("%s: %d\n", fn, __LINE__));
3225 /* Access check */
3227 if (!pipe_access_check(p)) {
3228 DEBUG(3, ("access denied to %s\n", fn));
3229 return NT_STATUS_ACCESS_DENIED;
3232 map_max_allowed_access(p->server_info->ptok, &des_access);
3234 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3235 se_map_generic(&des_access, &sam_generic_mapping);
3237 nt_status = access_check_samr_object(psd, p->server_info->ptok,
3238 NULL, 0, des_access, &acc_granted, fn);
3240 if ( !NT_STATUS_IS_OK(nt_status) )
3241 return nt_status;
3243 info = policy_handle_create(p, &hnd, acc_granted,
3244 struct samr_connect_info, &nt_status);
3245 if (!NT_STATUS_IS_OK(nt_status)) {
3246 return nt_status;
3249 DEBUG(5,("%s: %d\n", fn, __LINE__));
3251 *r->out.connect_handle = hnd;
3252 return NT_STATUS_OK;
3255 /****************************************************************
3256 _samr_Connect3
3257 ****************************************************************/
3259 NTSTATUS _samr_Connect3(pipes_struct *p,
3260 struct samr_Connect3 *r)
3262 struct samr_Connect2 c;
3264 c.in.system_name = r->in.system_name;
3265 c.in.access_mask = r->in.access_mask;
3266 c.out.connect_handle = r->out.connect_handle;
3268 return _samr_Connect2(p, &c);
3271 /*******************************************************************
3272 _samr_Connect4
3273 ********************************************************************/
3275 NTSTATUS _samr_Connect4(pipes_struct *p,
3276 struct samr_Connect4 *r)
3278 struct samr_Connect2 c;
3280 c.in.system_name = r->in.system_name;
3281 c.in.access_mask = r->in.access_mask;
3282 c.out.connect_handle = r->out.connect_handle;
3284 return _samr_Connect2(p, &c);
3287 /*******************************************************************
3288 _samr_Connect5
3289 ********************************************************************/
3291 NTSTATUS _samr_Connect5(pipes_struct *p,
3292 struct samr_Connect5 *r)
3294 NTSTATUS status;
3295 struct samr_Connect2 c;
3296 struct samr_ConnectInfo1 info1;
3298 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3299 info1.unknown2 = 0;
3301 c.in.system_name = r->in.system_name;
3302 c.in.access_mask = r->in.access_mask;
3303 c.out.connect_handle = r->out.connect_handle;
3305 status = _samr_Connect2(p, &c);
3306 if (!NT_STATUS_IS_OK(status)) {
3307 return status;
3310 *r->out.level_out = 1;
3311 r->out.info_out->info1 = info1;
3313 return NT_STATUS_OK;
3316 /**********************************************************************
3317 _samr_LookupDomain
3318 **********************************************************************/
3320 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3321 struct samr_LookupDomain *r)
3323 NTSTATUS status;
3324 struct samr_connect_info *info;
3325 const char *domain_name;
3326 DOM_SID *sid = NULL;
3328 /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
3329 Reverted that change so we will work with RAS servers again */
3331 info = policy_handle_find(p, r->in.connect_handle,
3332 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
3333 struct samr_connect_info,
3334 &status);
3335 if (!NT_STATUS_IS_OK(status)) {
3336 return status;
3339 domain_name = r->in.domain_name->string;
3340 if (!domain_name) {
3341 return NT_STATUS_INVALID_PARAMETER;
3344 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3345 if (!sid) {
3346 return NT_STATUS_NO_MEMORY;
3349 if (strequal(domain_name, builtin_domain_name())) {
3350 sid_copy(sid, &global_sid_Builtin);
3351 } else {
3352 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3353 status = NT_STATUS_NO_SUCH_DOMAIN;
3357 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3358 sid_string_dbg(sid)));
3360 *r->out.sid = sid;
3362 return status;
3365 /**********************************************************************
3366 _samr_EnumDomains
3367 **********************************************************************/
3369 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3370 struct samr_EnumDomains *r)
3372 NTSTATUS status;
3373 struct samr_connect_info *info;
3374 uint32_t num_entries = 2;
3375 struct samr_SamEntry *entry_array = NULL;
3376 struct samr_SamArray *sam;
3378 info = policy_handle_find(p, r->in.connect_handle,
3379 SAMR_ACCESS_ENUM_DOMAINS, NULL,
3380 struct samr_connect_info, &status);
3381 if (!NT_STATUS_IS_OK(status)) {
3382 return status;
3385 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3386 if (!sam) {
3387 return NT_STATUS_NO_MEMORY;
3390 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3391 struct samr_SamEntry,
3392 num_entries);
3393 if (!entry_array) {
3394 return NT_STATUS_NO_MEMORY;
3397 entry_array[0].idx = 0;
3398 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3400 entry_array[1].idx = 1;
3401 init_lsa_String(&entry_array[1].name, "Builtin");
3403 sam->count = num_entries;
3404 sam->entries = entry_array;
3406 *r->out.sam = sam;
3407 *r->out.num_entries = num_entries;
3409 return status;
3412 /*******************************************************************
3413 _samr_OpenAlias
3414 ********************************************************************/
3416 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3417 struct samr_OpenAlias *r)
3419 DOM_SID sid;
3420 uint32 alias_rid = r->in.rid;
3421 struct samr_info *info = NULL;
3422 struct samr_domain_info *dinfo;
3423 SEC_DESC *psd = NULL;
3424 uint32 acc_granted;
3425 uint32 des_access = r->in.access_mask;
3426 size_t sd_size;
3427 NTSTATUS status;
3428 SE_PRIV se_rights;
3430 dinfo = policy_handle_find(p, r->in.domain_handle,
3431 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
3432 struct samr_domain_info, &status);
3433 if (!NT_STATUS_IS_OK(status)) {
3434 return status;
3437 /* append the alias' RID to it */
3439 if (!sid_compose(&sid, &dinfo->sid, alias_rid))
3440 return NT_STATUS_NO_SUCH_ALIAS;
3442 /*check if access can be granted as requested by client. */
3444 map_max_allowed_access(p->server_info->ptok, &des_access);
3446 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3447 se_map_generic(&des_access,&ali_generic_mapping);
3449 se_priv_copy( &se_rights, &se_add_users );
3452 status = access_check_samr_object(psd, p->server_info->ptok,
3453 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3454 &acc_granted, "_samr_OpenAlias");
3456 if ( !NT_STATUS_IS_OK(status) )
3457 return status;
3460 /* Check we actually have the requested alias */
3461 enum lsa_SidType type;
3462 bool result;
3463 gid_t gid;
3465 become_root();
3466 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3467 unbecome_root();
3469 if (!result || (type != SID_NAME_ALIAS)) {
3470 return NT_STATUS_NO_SUCH_ALIAS;
3473 /* make sure there is a mapping */
3475 if ( !sid_to_gid( &sid, &gid ) ) {
3476 return NT_STATUS_NO_SUCH_ALIAS;
3481 /* associate the alias SID with the new handle. */
3482 if ((info = get_samr_info_by_sid(p->mem_ctx, &sid)) == NULL)
3483 return NT_STATUS_NO_MEMORY;
3485 info->acc_granted = acc_granted;
3487 /* get a (unique) handle. open a policy on it. */
3488 if (!create_policy_hnd(p, r->out.alias_handle, info))
3489 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3491 return NT_STATUS_OK;
3494 /*******************************************************************
3495 set_user_info_7
3496 ********************************************************************/
3498 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3499 struct samr_UserInfo7 *id7,
3500 struct samu *pwd)
3502 NTSTATUS rc;
3504 if (id7 == NULL) {
3505 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3506 return NT_STATUS_ACCESS_DENIED;
3509 if (!id7->account_name.string) {
3510 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3511 return NT_STATUS_ACCESS_DENIED;
3514 /* check to see if the new username already exists. Note: we can't
3515 reliably lock all backends, so there is potentially the
3516 possibility that a user can be created in between this check and
3517 the rename. The rename should fail, but may not get the
3518 exact same failure status code. I think this is small enough
3519 of a window for this type of operation and the results are
3520 simply that the rename fails with a slightly different status
3521 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3523 rc = can_create(mem_ctx, id7->account_name.string);
3524 if (!NT_STATUS_IS_OK(rc)) {
3525 return rc;
3528 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3530 return rc;
3533 /*******************************************************************
3534 set_user_info_16
3535 ********************************************************************/
3537 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3538 struct samu *pwd)
3540 if (id16 == NULL) {
3541 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3542 return False;
3545 /* FIX ME: check if the value is really changed --metze */
3546 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3547 return False;
3550 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3551 return False;
3554 return True;
3557 /*******************************************************************
3558 set_user_info_18
3559 ********************************************************************/
3561 static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
3562 TALLOC_CTX *mem_ctx,
3563 DATA_BLOB *session_key,
3564 struct samu *pwd)
3566 if (id18 == NULL) {
3567 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3568 return NT_STATUS_INVALID_PARAMETER;
3571 if (id18->nt_pwd_active || id18->lm_pwd_active) {
3572 if (!session_key->length) {
3573 return NT_STATUS_NO_USER_SESSION_KEY;
3577 if (id18->nt_pwd_active) {
3579 DATA_BLOB in, out;
3581 in = data_blob_const(id18->nt_pwd.hash, 16);
3582 out = data_blob_talloc_zero(mem_ctx, 16);
3584 sess_crypt_blob(&out, &in, session_key, false);
3586 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
3587 return NT_STATUS_ACCESS_DENIED;
3590 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3593 if (id18->lm_pwd_active) {
3595 DATA_BLOB in, out;
3597 in = data_blob_const(id18->lm_pwd.hash, 16);
3598 out = data_blob_talloc_zero(mem_ctx, 16);
3600 sess_crypt_blob(&out, &in, session_key, false);
3602 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
3603 return NT_STATUS_ACCESS_DENIED;
3606 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3609 copy_id18_to_sam_passwd(pwd, id18);
3611 return pdb_update_sam_account(pwd);
3614 /*******************************************************************
3615 set_user_info_20
3616 ********************************************************************/
3618 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3619 struct samu *pwd)
3621 if (id20 == NULL) {
3622 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3623 return False;
3626 copy_id20_to_sam_passwd(pwd, id20);
3628 /* write the change out */
3629 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3630 return False;
3633 return True;
3636 /*******************************************************************
3637 set_user_info_21
3638 ********************************************************************/
3640 static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
3641 TALLOC_CTX *mem_ctx,
3642 DATA_BLOB *session_key,
3643 struct samu *pwd)
3645 NTSTATUS status;
3647 if (id21 == NULL) {
3648 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3649 return NT_STATUS_INVALID_PARAMETER;
3652 if (id21->fields_present == 0) {
3653 return NT_STATUS_INVALID_PARAMETER;
3656 if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3657 return NT_STATUS_ACCESS_DENIED;
3660 if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
3661 if (id21->nt_password_set) {
3662 DATA_BLOB in, out;
3664 if ((id21->nt_owf_password.length != 16) ||
3665 (id21->nt_owf_password.size != 16)) {
3666 return NT_STATUS_INVALID_PARAMETER;
3669 if (!session_key->length) {
3670 return NT_STATUS_NO_USER_SESSION_KEY;
3673 in = data_blob_const(id21->nt_owf_password.array, 16);
3674 out = data_blob_talloc_zero(mem_ctx, 16);
3676 sess_crypt_blob(&out, &in, session_key, false);
3678 pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
3679 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3683 if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
3684 if (id21->lm_password_set) {
3685 DATA_BLOB in, out;
3687 if ((id21->lm_owf_password.length != 16) ||
3688 (id21->lm_owf_password.size != 16)) {
3689 return NT_STATUS_INVALID_PARAMETER;
3692 if (!session_key->length) {
3693 return NT_STATUS_NO_USER_SESSION_KEY;
3696 in = data_blob_const(id21->lm_owf_password.array, 16);
3697 out = data_blob_talloc_zero(mem_ctx, 16);
3699 sess_crypt_blob(&out, &in, session_key, false);
3701 pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
3702 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
3706 /* we need to separately check for an account rename first */
3708 if (id21->account_name.string &&
3709 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3712 /* check to see if the new username already exists. Note: we can't
3713 reliably lock all backends, so there is potentially the
3714 possibility that a user can be created in between this check and
3715 the rename. The rename should fail, but may not get the
3716 exact same failure status code. I think this is small enough
3717 of a window for this type of operation and the results are
3718 simply that the rename fails with a slightly different status
3719 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3721 status = can_create(mem_ctx, id21->account_name.string);
3722 if (!NT_STATUS_IS_OK(status)) {
3723 return status;
3726 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3728 if (!NT_STATUS_IS_OK(status)) {
3729 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3730 nt_errstr(status)));
3731 return status;
3734 /* set the new username so that later
3735 functions can work on the new account */
3736 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3739 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3742 * The funny part about the previous two calls is
3743 * that pwd still has the password hashes from the
3744 * passdb entry. These have not been updated from
3745 * id21. I don't know if they need to be set. --jerry
3748 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3749 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3750 if ( !NT_STATUS_IS_OK(status) ) {
3751 return status;
3755 /* Don't worry about writing out the user account since the
3756 primary group SID is generated solely from the user's Unix
3757 primary group. */
3759 /* write the change out */
3760 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3761 return status;
3764 return NT_STATUS_OK;
3767 /*******************************************************************
3768 set_user_info_23
3769 ********************************************************************/
3771 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3772 struct samr_UserInfo23 *id23,
3773 struct samu *pwd)
3775 char *plaintext_buf = NULL;
3776 uint32 len = 0;
3777 uint32_t acct_ctrl;
3778 NTSTATUS status;
3780 if (id23 == NULL) {
3781 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3782 return NT_STATUS_INVALID_PARAMETER;
3785 if (id23->info.fields_present == 0) {
3786 return NT_STATUS_INVALID_PARAMETER;
3789 if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3790 return NT_STATUS_ACCESS_DENIED;
3793 if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3794 (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
3796 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3797 pdb_get_username(pwd)));
3799 if (!decode_pw_buffer(mem_ctx,
3800 id23->password.data,
3801 &plaintext_buf,
3802 &len,
3803 STR_UNICODE)) {
3804 return NT_STATUS_WRONG_PASSWORD;
3807 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3808 return NT_STATUS_ACCESS_DENIED;
3812 copy_id23_to_sam_passwd(pwd, id23);
3814 acct_ctrl = pdb_get_acct_ctrl(pwd);
3816 /* if it's a trust account, don't update /etc/passwd */
3817 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3818 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3819 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3820 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3821 } else if (plaintext_buf) {
3822 /* update the UNIX password */
3823 if (lp_unix_password_sync() ) {
3824 struct passwd *passwd;
3825 if (pdb_get_username(pwd) == NULL) {
3826 DEBUG(1, ("chgpasswd: User without name???\n"));
3827 return NT_STATUS_ACCESS_DENIED;
3830 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3831 if (passwd == NULL) {
3832 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3835 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3836 return NT_STATUS_ACCESS_DENIED;
3838 TALLOC_FREE(passwd);
3842 if (plaintext_buf) {
3843 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3846 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3847 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3848 pwd)))) {
3849 return status;
3852 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3853 return status;
3856 return NT_STATUS_OK;
3859 /*******************************************************************
3860 set_user_info_pw
3861 ********************************************************************/
3863 static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
3865 uint32 len = 0;
3866 char *plaintext_buf = NULL;
3867 uint32 acct_ctrl;
3869 DEBUG(5, ("Attempting administrator password change for user %s\n",
3870 pdb_get_username(pwd)));
3872 acct_ctrl = pdb_get_acct_ctrl(pwd);
3874 if (!decode_pw_buffer(talloc_tos(),
3875 pass,
3876 &plaintext_buf,
3877 &len,
3878 STR_UNICODE)) {
3879 return False;
3882 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3883 return False;
3886 /* if it's a trust account, don't update /etc/passwd */
3887 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3888 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3889 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3890 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3891 } else {
3892 /* update the UNIX password */
3893 if (lp_unix_password_sync()) {
3894 struct passwd *passwd;
3896 if (pdb_get_username(pwd) == NULL) {
3897 DEBUG(1, ("chgpasswd: User without name???\n"));
3898 return False;
3901 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3902 if (passwd == NULL) {
3903 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3906 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3907 return False;
3909 TALLOC_FREE(passwd);
3913 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3915 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3917 return True;
3920 /*******************************************************************
3921 set_user_info_24
3922 ********************************************************************/
3924 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
3925 struct samr_UserInfo24 *id24,
3926 struct samu *pwd)
3928 NTSTATUS status;
3930 if (id24 == NULL) {
3931 DEBUG(5, ("set_user_info_24: NULL id24\n"));
3932 return NT_STATUS_INVALID_PARAMETER;
3935 if (!set_user_info_pw(id24->password.data, pwd)) {
3936 return NT_STATUS_WRONG_PASSWORD;
3939 copy_id24_to_sam_passwd(pwd, id24);
3941 status = pdb_update_sam_account(pwd);
3942 if (!NT_STATUS_IS_OK(status)) {
3943 return status;
3946 return NT_STATUS_OK;
3949 /*******************************************************************
3950 set_user_info_25
3951 ********************************************************************/
3953 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
3954 struct samr_UserInfo25 *id25,
3955 struct samu *pwd)
3957 NTSTATUS status;
3959 if (id25 == NULL) {
3960 DEBUG(5, ("set_user_info_25: NULL id25\n"));
3961 return NT_STATUS_INVALID_PARAMETER;
3964 if (id25->info.fields_present == 0) {
3965 return NT_STATUS_INVALID_PARAMETER;
3968 if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
3969 return NT_STATUS_ACCESS_DENIED;
3972 if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3973 (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
3975 if (!set_user_info_pw(id25->password.data, pwd)) {
3976 return NT_STATUS_WRONG_PASSWORD;
3980 copy_id25_to_sam_passwd(pwd, id25);
3982 /* write the change out */
3983 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3984 return status;
3988 * We need to "pdb_update_sam_account" before the unix primary group
3989 * is set, because the idealx scripts would also change the
3990 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
3991 * the delete explicit / add explicit, which would then fail to find
3992 * the previous primaryGroupSid value.
3995 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3996 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3997 if ( !NT_STATUS_IS_OK(status) ) {
3998 return status;
4002 return NT_STATUS_OK;
4005 /*******************************************************************
4006 set_user_info_26
4007 ********************************************************************/
4009 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4010 struct samr_UserInfo26 *id26,
4011 struct samu *pwd)
4013 NTSTATUS status;
4015 if (id26 == NULL) {
4016 DEBUG(5, ("set_user_info_26: NULL id26\n"));
4017 return NT_STATUS_INVALID_PARAMETER;
4020 if (!set_user_info_pw(id26->password.data, pwd)) {
4021 return NT_STATUS_WRONG_PASSWORD;
4024 copy_id26_to_sam_passwd(pwd, id26);
4026 status = pdb_update_sam_account(pwd);
4027 if (!NT_STATUS_IS_OK(status)) {
4028 return status;
4031 return NT_STATUS_OK;
4035 /*******************************************************************
4036 samr_SetUserInfo
4037 ********************************************************************/
4039 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4040 struct samr_SetUserInfo *r)
4042 NTSTATUS status;
4043 struct samu *pwd = NULL;
4044 DOM_SID sid;
4045 union samr_UserInfo *info = r->in.info;
4046 uint16_t switch_value = r->in.level;
4047 uint32_t acc_granted;
4048 uint32_t acc_required;
4049 bool ret;
4050 bool has_enough_rights = False;
4051 uint32_t acb_info;
4052 DISP_INFO *disp_info = NULL;
4054 DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
4056 /* find the policy handle. open a policy on it. */
4057 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) {
4058 return NT_STATUS_INVALID_HANDLE;
4061 /* This is tricky. A WinXP domain join sets
4062 (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
4063 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4064 standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
4065 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4066 we'll use the set from the WinXP join as the basis. */
4068 switch (switch_value) {
4069 case 18:
4070 case 24:
4071 case 25:
4072 case 26:
4073 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
4074 break;
4075 default:
4076 acc_required = SAMR_USER_ACCESS_SET_PASSWORD |
4077 SAMR_USER_ACCESS_SET_ATTRIBUTES |
4078 SAMR_USER_ACCESS_GET_ATTRIBUTES;
4079 break;
4082 status = access_check_samr_function(acc_granted,
4083 acc_required,
4084 "_samr_SetUserInfo");
4085 if (!NT_STATUS_IS_OK(status)) {
4086 return status;
4089 DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
4090 sid_string_dbg(&sid), switch_value));
4092 if (info == NULL) {
4093 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
4094 return NT_STATUS_INVALID_INFO_CLASS;
4097 if (!(pwd = samu_new(NULL))) {
4098 return NT_STATUS_NO_MEMORY;
4101 become_root();
4102 ret = pdb_getsampwsid(pwd, &sid);
4103 unbecome_root();
4105 if (!ret) {
4106 TALLOC_FREE(pwd);
4107 return NT_STATUS_NO_SUCH_USER;
4110 /* deal with machine password changes differently from userinfo changes */
4111 /* check to see if we have the sufficient rights */
4113 acb_info = pdb_get_acct_ctrl(pwd);
4114 if (acb_info & ACB_WSTRUST)
4115 has_enough_rights = user_has_privileges(p->server_info->ptok,
4116 &se_machine_account);
4117 else if (acb_info & ACB_NORMAL)
4118 has_enough_rights = user_has_privileges(p->server_info->ptok,
4119 &se_add_users);
4120 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4121 if (lp_enable_privileges()) {
4122 has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
4123 DOMAIN_GROUP_RID_ADMINS);
4127 DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
4128 uidtoname(p->server_info->utok.uid),
4129 has_enough_rights ? "" : " not"));
4131 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4133 if (has_enough_rights) {
4134 become_root();
4137 /* ok! user info levels (lots: see MSDEV help), off we go... */
4139 switch (switch_value) {
4141 case 7:
4142 status = set_user_info_7(p->mem_ctx,
4143 &info->info7, pwd);
4144 break;
4146 case 16:
4147 if (!set_user_info_16(&info->info16, pwd)) {
4148 status = NT_STATUS_ACCESS_DENIED;
4150 break;
4152 case 18:
4153 /* Used by AS/U JRA. */
4154 status = set_user_info_18(&info->info18,
4155 p->mem_ctx,
4156 &p->server_info->user_session_key,
4157 pwd);
4158 break;
4160 case 20:
4161 if (!set_user_info_20(&info->info20, pwd)) {
4162 status = NT_STATUS_ACCESS_DENIED;
4164 break;
4166 case 21:
4167 status = set_user_info_21(&info->info21,
4168 p->mem_ctx,
4169 &p->server_info->user_session_key,
4170 pwd);
4171 break;
4173 case 23:
4174 if (!p->server_info->user_session_key.length) {
4175 status = NT_STATUS_NO_USER_SESSION_KEY;
4177 SamOEMhashBlob(info->info23.password.data, 516,
4178 &p->server_info->user_session_key);
4180 dump_data(100, info->info23.password.data, 516);
4182 status = set_user_info_23(p->mem_ctx,
4183 &info->info23, pwd);
4184 break;
4186 case 24:
4187 if (!p->server_info->user_session_key.length) {
4188 status = NT_STATUS_NO_USER_SESSION_KEY;
4190 SamOEMhashBlob(info->info24.password.data,
4191 516,
4192 &p->server_info->user_session_key);
4194 dump_data(100, info->info24.password.data, 516);
4196 status = set_user_info_24(p->mem_ctx,
4197 &info->info24, pwd);
4198 break;
4200 case 25:
4201 if (!p->server_info->user_session_key.length) {
4202 status = NT_STATUS_NO_USER_SESSION_KEY;
4204 encode_or_decode_arc4_passwd_buffer(
4205 info->info25.password.data,
4206 &p->server_info->user_session_key);
4208 dump_data(100, info->info25.password.data, 532);
4210 status = set_user_info_25(p->mem_ctx,
4211 &info->info25, pwd);
4212 break;
4214 case 26:
4215 if (!p->server_info->user_session_key.length) {
4216 status = NT_STATUS_NO_USER_SESSION_KEY;
4218 encode_or_decode_arc4_passwd_buffer(
4219 info->info26.password.data,
4220 &p->server_info->user_session_key);
4222 dump_data(100, info->info26.password.data, 516);
4224 status = set_user_info_26(p->mem_ctx,
4225 &info->info26, pwd);
4226 break;
4228 default:
4229 status = NT_STATUS_INVALID_INFO_CLASS;
4232 TALLOC_FREE(pwd);
4234 if (has_enough_rights) {
4235 unbecome_root();
4238 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4240 if (NT_STATUS_IS_OK(status)) {
4241 force_flush_samr_cache(&sid);
4244 return status;
4247 /*******************************************************************
4248 _samr_SetUserInfo2
4249 ********************************************************************/
4251 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4252 struct samr_SetUserInfo2 *r)
4254 struct samr_SetUserInfo q;
4256 q.in.user_handle = r->in.user_handle;
4257 q.in.level = r->in.level;
4258 q.in.info = r->in.info;
4260 return _samr_SetUserInfo(p, &q);
4263 /*********************************************************************
4264 _samr_GetAliasMembership
4265 *********************************************************************/
4267 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4268 struct samr_GetAliasMembership *r)
4270 size_t num_alias_rids;
4271 uint32 *alias_rids;
4272 struct samr_domain_info *dinfo;
4273 size_t i;
4275 NTSTATUS status;
4277 DOM_SID *members;
4279 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4281 dinfo = policy_handle_find(p, r->in.domain_handle,
4282 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
4283 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4284 struct samr_domain_info, &status);
4285 if (!NT_STATUS_IS_OK(status)) {
4286 return status;
4289 if (!sid_check_is_domain(&dinfo->sid) &&
4290 !sid_check_is_builtin(&dinfo->sid))
4291 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4293 if (r->in.sids->num_sids) {
4294 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4296 if (members == NULL)
4297 return NT_STATUS_NO_MEMORY;
4298 } else {
4299 members = NULL;
4302 for (i=0; i<r->in.sids->num_sids; i++)
4303 sid_copy(&members[i], r->in.sids->sids[i].sid);
4305 alias_rids = NULL;
4306 num_alias_rids = 0;
4308 become_root();
4309 status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
4310 r->in.sids->num_sids,
4311 &alias_rids, &num_alias_rids);
4312 unbecome_root();
4314 if (!NT_STATUS_IS_OK(status)) {
4315 return status;
4318 r->out.rids->count = num_alias_rids;
4319 r->out.rids->ids = alias_rids;
4321 return NT_STATUS_OK;
4324 /*********************************************************************
4325 _samr_GetMembersInAlias
4326 *********************************************************************/
4328 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4329 struct samr_GetMembersInAlias *r)
4331 NTSTATUS status;
4332 size_t i;
4333 size_t num_sids = 0;
4334 struct lsa_SidPtr *sids = NULL;
4335 DOM_SID *pdb_sids = NULL;
4337 DOM_SID alias_sid;
4339 uint32 acc_granted;
4341 /* find the policy handle. open a policy on it. */
4342 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4343 return NT_STATUS_INVALID_HANDLE;
4345 status = access_check_samr_function(acc_granted,
4346 SAMR_ALIAS_ACCESS_GET_MEMBERS,
4347 "_samr_GetMembersInAlias");
4348 if (!NT_STATUS_IS_OK(status)) {
4349 return status;
4352 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4354 become_root();
4355 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4356 unbecome_root();
4358 if (!NT_STATUS_IS_OK(status)) {
4359 return status;
4362 if (num_sids) {
4363 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4364 if (sids == NULL) {
4365 TALLOC_FREE(pdb_sids);
4366 return NT_STATUS_NO_MEMORY;
4370 for (i = 0; i < num_sids; i++) {
4371 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4372 if (!sids[i].sid) {
4373 TALLOC_FREE(pdb_sids);
4374 return NT_STATUS_NO_MEMORY;
4378 r->out.sids->num_sids = num_sids;
4379 r->out.sids->sids = sids;
4381 TALLOC_FREE(pdb_sids);
4383 return NT_STATUS_OK;
4386 /*********************************************************************
4387 _samr_QueryGroupMember
4388 *********************************************************************/
4390 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4391 struct samr_QueryGroupMember *r)
4393 DOM_SID group_sid;
4394 size_t i, num_members;
4396 uint32 *rid=NULL;
4397 uint32 *attr=NULL;
4399 uint32 acc_granted;
4401 NTSTATUS status;
4402 struct samr_RidTypeArray *rids = NULL;
4404 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4405 if (!rids) {
4406 return NT_STATUS_NO_MEMORY;
4409 /* find the policy handle. open a policy on it. */
4410 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4411 return NT_STATUS_INVALID_HANDLE;
4413 status = access_check_samr_function(acc_granted,
4414 SAMR_GROUP_ACCESS_GET_MEMBERS,
4415 "_samr_QueryGroupMember");
4416 if (!NT_STATUS_IS_OK(status)) {
4417 return status;
4420 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4422 if (!sid_check_is_in_our_domain(&group_sid)) {
4423 DEBUG(3, ("sid %s is not in our domain\n",
4424 sid_string_dbg(&group_sid)));
4425 return NT_STATUS_NO_SUCH_GROUP;
4428 DEBUG(10, ("lookup on Domain SID\n"));
4430 become_root();
4431 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4432 &rid, &num_members);
4433 unbecome_root();
4435 if (!NT_STATUS_IS_OK(status))
4436 return status;
4438 if (num_members) {
4439 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4440 if (attr == NULL) {
4441 return NT_STATUS_NO_MEMORY;
4443 } else {
4444 attr = NULL;
4447 for (i=0; i<num_members; i++)
4448 attr[i] = SID_NAME_USER;
4450 rids->count = num_members;
4451 rids->types = attr;
4452 rids->rids = rid;
4454 *r->out.rids = rids;
4456 return NT_STATUS_OK;
4459 /*********************************************************************
4460 _samr_AddAliasMember
4461 *********************************************************************/
4463 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4464 struct samr_AddAliasMember *r)
4466 DOM_SID alias_sid;
4467 uint32 acc_granted;
4468 SE_PRIV se_rights;
4469 bool can_add_accounts;
4470 NTSTATUS status;
4471 DISP_INFO *disp_info = NULL;
4473 /* Find the policy handle. Open a policy on it. */
4474 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4475 return NT_STATUS_INVALID_HANDLE;
4477 status = access_check_samr_function(acc_granted,
4478 SAMR_ALIAS_ACCESS_ADD_MEMBER,
4479 "_samr_AddAliasMember");
4480 if (!NT_STATUS_IS_OK(status)) {
4481 return status;
4484 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4486 se_priv_copy( &se_rights, &se_add_users );
4487 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4489 /******** BEGIN SeAddUsers BLOCK *********/
4491 if ( can_add_accounts )
4492 become_root();
4494 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4496 if ( can_add_accounts )
4497 unbecome_root();
4499 /******** END SeAddUsers BLOCK *********/
4501 if (NT_STATUS_IS_OK(status)) {
4502 force_flush_samr_cache(&alias_sid);
4505 return status;
4508 /*********************************************************************
4509 _samr_DeleteAliasMember
4510 *********************************************************************/
4512 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4513 struct samr_DeleteAliasMember *r)
4515 DOM_SID alias_sid;
4516 uint32 acc_granted;
4517 SE_PRIV se_rights;
4518 bool can_add_accounts;
4519 NTSTATUS status;
4520 DISP_INFO *disp_info = NULL;
4522 /* Find the policy handle. Open a policy on it. */
4523 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4524 return NT_STATUS_INVALID_HANDLE;
4526 status = access_check_samr_function(acc_granted,
4527 SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
4528 "_samr_DeleteAliasMember");
4529 if (!NT_STATUS_IS_OK(status)) {
4530 return status;
4533 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4534 sid_string_dbg(&alias_sid)));
4536 se_priv_copy( &se_rights, &se_add_users );
4537 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4539 /******** BEGIN SeAddUsers BLOCK *********/
4541 if ( can_add_accounts )
4542 become_root();
4544 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4546 if ( can_add_accounts )
4547 unbecome_root();
4549 /******** END SeAddUsers BLOCK *********/
4551 if (NT_STATUS_IS_OK(status)) {
4552 force_flush_samr_cache(&alias_sid);
4555 return status;
4558 /*********************************************************************
4559 _samr_AddGroupMember
4560 *********************************************************************/
4562 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4563 struct samr_AddGroupMember *r)
4565 NTSTATUS status;
4566 DOM_SID group_sid;
4567 uint32 group_rid;
4568 uint32 acc_granted;
4569 SE_PRIV se_rights;
4570 bool can_add_accounts;
4571 DISP_INFO *disp_info = NULL;
4573 /* Find the policy handle. Open a policy on it. */
4574 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4575 return NT_STATUS_INVALID_HANDLE;
4577 status = access_check_samr_function(acc_granted,
4578 SAMR_GROUP_ACCESS_ADD_MEMBER,
4579 "_samr_AddGroupMember");
4580 if (!NT_STATUS_IS_OK(status)) {
4581 return status;
4584 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4586 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4587 &group_rid)) {
4588 return NT_STATUS_INVALID_HANDLE;
4591 se_priv_copy( &se_rights, &se_add_users );
4592 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4594 /******** BEGIN SeAddUsers BLOCK *********/
4596 if ( can_add_accounts )
4597 become_root();
4599 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4601 if ( can_add_accounts )
4602 unbecome_root();
4604 /******** END SeAddUsers BLOCK *********/
4606 force_flush_samr_cache(&group_sid);
4608 return status;
4611 /*********************************************************************
4612 _samr_DeleteGroupMember
4613 *********************************************************************/
4615 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4616 struct samr_DeleteGroupMember *r)
4619 NTSTATUS status;
4620 DOM_SID group_sid;
4621 uint32 group_rid;
4622 uint32 acc_granted;
4623 SE_PRIV se_rights;
4624 bool can_add_accounts;
4625 DISP_INFO *disp_info = NULL;
4628 * delete the group member named r->in.rid
4629 * who is a member of the sid associated with the handle
4630 * the rid is a user's rid as the group is a domain group.
4633 /* Find the policy handle. Open a policy on it. */
4634 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4635 return NT_STATUS_INVALID_HANDLE;
4637 status = access_check_samr_function(acc_granted,
4638 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
4639 "_samr_DeleteGroupMember");
4640 if (!NT_STATUS_IS_OK(status)) {
4641 return status;
4644 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4645 &group_rid)) {
4646 return NT_STATUS_INVALID_HANDLE;
4649 se_priv_copy( &se_rights, &se_add_users );
4650 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4652 /******** BEGIN SeAddUsers BLOCK *********/
4654 if ( can_add_accounts )
4655 become_root();
4657 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4659 if ( can_add_accounts )
4660 unbecome_root();
4662 /******** END SeAddUsers BLOCK *********/
4664 force_flush_samr_cache(&group_sid);
4666 return status;
4669 /*********************************************************************
4670 _samr_DeleteUser
4671 *********************************************************************/
4673 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4674 struct samr_DeleteUser *r)
4676 NTSTATUS status;
4677 DOM_SID user_sid;
4678 struct samu *sam_pass=NULL;
4679 uint32 acc_granted;
4680 bool can_add_accounts;
4681 uint32 acb_info;
4682 DISP_INFO *disp_info = NULL;
4683 bool ret;
4685 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4687 /* Find the policy handle. Open a policy on it. */
4688 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4689 return NT_STATUS_INVALID_HANDLE;
4691 status = access_check_samr_function(acc_granted,
4692 STD_RIGHT_DELETE_ACCESS,
4693 "_samr_DeleteUser");
4694 if (!NT_STATUS_IS_OK(status)) {
4695 return status;
4698 if (!sid_check_is_in_our_domain(&user_sid))
4699 return NT_STATUS_CANNOT_DELETE;
4701 /* check if the user exists before trying to delete */
4702 if ( !(sam_pass = samu_new( NULL )) ) {
4703 return NT_STATUS_NO_MEMORY;
4706 become_root();
4707 ret = pdb_getsampwsid(sam_pass, &user_sid);
4708 unbecome_root();
4710 if( !ret ) {
4711 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4712 sid_string_dbg(&user_sid)));
4713 TALLOC_FREE(sam_pass);
4714 return NT_STATUS_NO_SUCH_USER;
4717 acb_info = pdb_get_acct_ctrl(sam_pass);
4719 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4720 if ( acb_info & ACB_WSTRUST ) {
4721 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
4722 } else {
4723 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
4726 /******** BEGIN SeAddUsers BLOCK *********/
4728 if ( can_add_accounts )
4729 become_root();
4731 status = pdb_delete_user(p->mem_ctx, sam_pass);
4733 if ( can_add_accounts )
4734 unbecome_root();
4736 /******** END SeAddUsers BLOCK *********/
4738 if ( !NT_STATUS_IS_OK(status) ) {
4739 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4740 "user %s: %s.\n", pdb_get_username(sam_pass),
4741 nt_errstr(status)));
4742 TALLOC_FREE(sam_pass);
4743 return status;
4747 TALLOC_FREE(sam_pass);
4749 if (!close_policy_hnd(p, r->in.user_handle))
4750 return NT_STATUS_OBJECT_NAME_INVALID;
4752 ZERO_STRUCTP(r->out.user_handle);
4754 force_flush_samr_cache(&user_sid);
4756 return NT_STATUS_OK;
4759 /*********************************************************************
4760 _samr_DeleteDomainGroup
4761 *********************************************************************/
4763 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4764 struct samr_DeleteDomainGroup *r)
4766 NTSTATUS status;
4767 DOM_SID group_sid;
4768 uint32 group_rid;
4769 uint32 acc_granted;
4770 SE_PRIV se_rights;
4771 bool can_add_accounts;
4772 DISP_INFO *disp_info = NULL;
4774 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4776 /* Find the policy handle. Open a policy on it. */
4777 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4778 return NT_STATUS_INVALID_HANDLE;
4780 status = access_check_samr_function(acc_granted,
4781 STD_RIGHT_DELETE_ACCESS,
4782 "_samr_DeleteDomainGroup");
4783 if (!NT_STATUS_IS_OK(status)) {
4784 return status;
4787 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4789 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4790 &group_rid)) {
4791 return NT_STATUS_NO_SUCH_GROUP;
4794 se_priv_copy( &se_rights, &se_add_users );
4795 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4797 /******** BEGIN SeAddUsers BLOCK *********/
4799 if ( can_add_accounts )
4800 become_root();
4802 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4804 if ( can_add_accounts )
4805 unbecome_root();
4807 /******** END SeAddUsers BLOCK *********/
4809 if ( !NT_STATUS_IS_OK(status) ) {
4810 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4811 "entry for group %s: %s\n",
4812 sid_string_dbg(&group_sid),
4813 nt_errstr(status)));
4814 return status;
4817 if (!close_policy_hnd(p, r->in.group_handle))
4818 return NT_STATUS_OBJECT_NAME_INVALID;
4820 force_flush_samr_cache(&group_sid);
4822 return NT_STATUS_OK;
4825 /*********************************************************************
4826 _samr_DeleteDomAlias
4827 *********************************************************************/
4829 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4830 struct samr_DeleteDomAlias *r)
4832 DOM_SID alias_sid;
4833 uint32 acc_granted;
4834 SE_PRIV se_rights;
4835 bool can_add_accounts;
4836 NTSTATUS status;
4837 DISP_INFO *disp_info = NULL;
4839 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4841 /* Find the policy handle. Open a policy on it. */
4842 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4843 return NT_STATUS_INVALID_HANDLE;
4845 /* copy the handle to the outgoing reply */
4847 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4849 status = access_check_samr_function(acc_granted,
4850 STD_RIGHT_DELETE_ACCESS,
4851 "_samr_DeleteDomAlias");
4852 if (!NT_STATUS_IS_OK(status)) {
4853 return status;
4856 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4858 /* Don't let Windows delete builtin groups */
4860 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4861 return NT_STATUS_SPECIAL_ACCOUNT;
4864 if (!sid_check_is_in_our_domain(&alias_sid))
4865 return NT_STATUS_NO_SUCH_ALIAS;
4867 DEBUG(10, ("lookup on Local SID\n"));
4869 se_priv_copy( &se_rights, &se_add_users );
4870 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4872 /******** BEGIN SeAddUsers BLOCK *********/
4874 if ( can_add_accounts )
4875 become_root();
4877 /* Have passdb delete the alias */
4878 status = pdb_delete_alias(&alias_sid);
4880 if ( can_add_accounts )
4881 unbecome_root();
4883 /******** END SeAddUsers BLOCK *********/
4885 if ( !NT_STATUS_IS_OK(status))
4886 return status;
4888 if (!close_policy_hnd(p, r->in.alias_handle))
4889 return NT_STATUS_OBJECT_NAME_INVALID;
4891 force_flush_samr_cache(&alias_sid);
4893 return NT_STATUS_OK;
4896 /*********************************************************************
4897 _samr_CreateDomainGroup
4898 *********************************************************************/
4900 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4901 struct samr_CreateDomainGroup *r)
4904 NTSTATUS status;
4905 DOM_SID info_sid;
4906 const char *name;
4907 struct samr_domain_info *dinfo;
4908 struct samr_info *info;
4909 SE_PRIV se_rights;
4910 bool can_add_accounts;
4912 dinfo = policy_handle_find(p, r->in.domain_handle,
4913 SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
4914 struct samr_domain_info, &status);
4915 if (!NT_STATUS_IS_OK(status)) {
4916 return status;
4919 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
4920 return NT_STATUS_ACCESS_DENIED;
4922 name = r->in.name->string;
4923 if (name == NULL) {
4924 return NT_STATUS_NO_MEMORY;
4927 status = can_create(p->mem_ctx, name);
4928 if (!NT_STATUS_IS_OK(status)) {
4929 return status;
4932 se_priv_copy( &se_rights, &se_add_users );
4933 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
4935 /******** BEGIN SeAddUsers BLOCK *********/
4937 if ( can_add_accounts )
4938 become_root();
4940 /* check that we successfully create the UNIX group */
4942 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
4944 if ( can_add_accounts )
4945 unbecome_root();
4947 /******** END SeAddUsers BLOCK *********/
4949 /* check if we should bail out here */
4951 if ( !NT_STATUS_IS_OK(status) )
4952 return status;
4954 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
4956 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
4957 return NT_STATUS_NO_MEMORY;
4959 /* they created it; let the user do what he wants with it */
4961 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
4963 /* get a (unique) handle. open a policy on it. */
4964 if (!create_policy_hnd(p, r->out.group_handle, info))
4965 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4967 force_flush_samr_cache(&info_sid);
4969 return NT_STATUS_OK;
4972 /*********************************************************************
4973 _samr_CreateDomAlias
4974 *********************************************************************/
4976 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
4977 struct samr_CreateDomAlias *r)
4979 DOM_SID info_sid;
4980 const char *name = NULL;
4981 struct samr_domain_info *dinfo;
4982 struct samr_info *info;
4983 gid_t gid;
4984 NTSTATUS result;
4985 SE_PRIV se_rights;
4986 bool can_add_accounts;
4988 dinfo = policy_handle_find(p, r->in.domain_handle,
4989 SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
4990 struct samr_domain_info, &result);
4991 if (!NT_STATUS_IS_OK(result)) {
4992 return result;
4995 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
4996 return NT_STATUS_ACCESS_DENIED;
4998 name = r->in.alias_name->string;
5000 se_priv_copy( &se_rights, &se_add_users );
5001 can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
5003 result = can_create(p->mem_ctx, name);
5004 if (!NT_STATUS_IS_OK(result)) {
5005 return result;
5008 /******** BEGIN SeAddUsers BLOCK *********/
5010 if ( can_add_accounts )
5011 become_root();
5013 /* Have passdb create the alias */
5014 result = pdb_create_alias(name, r->out.rid);
5016 if ( can_add_accounts )
5017 unbecome_root();
5019 /******** END SeAddUsers BLOCK *********/
5021 if (!NT_STATUS_IS_OK(result)) {
5022 DEBUG(10, ("pdb_create_alias failed: %s\n",
5023 nt_errstr(result)));
5024 return result;
5027 sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5029 if (!sid_to_gid(&info_sid, &gid)) {
5030 DEBUG(10, ("Could not find alias just created\n"));
5031 return NT_STATUS_ACCESS_DENIED;
5034 /* check if the group has been successfully created */
5035 if ( getgrgid(gid) == NULL ) {
5036 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5037 gid));
5038 return NT_STATUS_ACCESS_DENIED;
5041 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5042 return NT_STATUS_NO_MEMORY;
5044 /* they created it; let the user do what he wants with it */
5046 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5048 /* get a (unique) handle. open a policy on it. */
5049 if (!create_policy_hnd(p, r->out.alias_handle, info))
5050 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5052 force_flush_samr_cache(&info_sid);
5054 return NT_STATUS_OK;
5057 /*********************************************************************
5058 _samr_QueryGroupInfo
5059 *********************************************************************/
5061 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5062 struct samr_QueryGroupInfo *r)
5064 NTSTATUS status;
5065 DOM_SID group_sid;
5066 GROUP_MAP map;
5067 union samr_GroupInfo *info = NULL;
5068 uint32 acc_granted;
5069 bool ret;
5070 uint32_t attributes = SE_GROUP_MANDATORY |
5071 SE_GROUP_ENABLED_BY_DEFAULT |
5072 SE_GROUP_ENABLED;
5073 const char *group_name = NULL;
5074 const char *group_description = NULL;
5076 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5077 return NT_STATUS_INVALID_HANDLE;
5079 status = access_check_samr_function(acc_granted,
5080 SAMR_GROUP_ACCESS_LOOKUP_INFO,
5081 "_samr_QueryGroupInfo");
5082 if (!NT_STATUS_IS_OK(status)) {
5083 return status;
5086 become_root();
5087 ret = get_domain_group_from_sid(group_sid, &map);
5088 unbecome_root();
5089 if (!ret)
5090 return NT_STATUS_INVALID_HANDLE;
5092 /* FIXME: map contains fstrings */
5093 group_name = talloc_strdup(r, map.nt_name);
5094 group_description = talloc_strdup(r, map.comment);
5096 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5097 if (!info) {
5098 return NT_STATUS_NO_MEMORY;
5101 switch (r->in.level) {
5102 case 1: {
5103 uint32 *members;
5104 size_t num_members;
5106 become_root();
5107 status = pdb_enum_group_members(
5108 p->mem_ctx, &group_sid, &members, &num_members);
5109 unbecome_root();
5111 if (!NT_STATUS_IS_OK(status)) {
5112 return status;
5115 info->all.name.string = group_name;
5116 info->all.attributes = attributes;
5117 info->all.num_members = num_members;
5118 info->all.description.string = group_description;
5119 break;
5121 case 2:
5122 info->name.string = group_name;
5123 break;
5124 case 3:
5125 info->attributes.attributes = attributes;
5126 break;
5127 case 4:
5128 info->description.string = group_description;
5129 break;
5130 case 5: {
5132 uint32 *members;
5133 size_t num_members;
5137 become_root();
5138 status = pdb_enum_group_members(
5139 p->mem_ctx, &group_sid, &members, &num_members);
5140 unbecome_root();
5142 if (!NT_STATUS_IS_OK(status)) {
5143 return status;
5146 info->all2.name.string = group_name;
5147 info->all2.attributes = attributes;
5148 info->all2.num_members = 0; /* num_members - in w2k3 this is always 0 */
5149 info->all2.description.string = group_description;
5151 break;
5153 default:
5154 return NT_STATUS_INVALID_INFO_CLASS;
5157 *r->out.info = info;
5159 return NT_STATUS_OK;
5162 /*********************************************************************
5163 _samr_SetGroupInfo
5164 *********************************************************************/
5166 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5167 struct samr_SetGroupInfo *r)
5169 DOM_SID group_sid;
5170 GROUP_MAP map;
5171 uint32 acc_granted;
5172 NTSTATUS status;
5173 bool ret;
5174 bool can_mod_accounts;
5175 DISP_INFO *disp_info = NULL;
5177 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5178 return NT_STATUS_INVALID_HANDLE;
5180 status = access_check_samr_function(acc_granted,
5181 SAMR_GROUP_ACCESS_SET_INFO,
5182 "_samr_SetGroupInfo");
5183 if (!NT_STATUS_IS_OK(status)) {
5184 return status;
5187 become_root();
5188 ret = get_domain_group_from_sid(group_sid, &map);
5189 unbecome_root();
5190 if (!ret)
5191 return NT_STATUS_NO_SUCH_GROUP;
5193 switch (r->in.level) {
5194 case 1:
5195 fstrcpy(map.comment, r->in.info->all.description.string);
5196 break;
5197 case 2:
5198 /* group rename is not supported yet */
5199 return NT_STATUS_NOT_SUPPORTED;
5200 case 4:
5201 fstrcpy(map.comment, r->in.info->description.string);
5202 break;
5203 default:
5204 return NT_STATUS_INVALID_INFO_CLASS;
5207 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5209 /******** BEGIN SeAddUsers BLOCK *********/
5211 if ( can_mod_accounts )
5212 become_root();
5214 status = pdb_update_group_mapping_entry(&map);
5216 if ( can_mod_accounts )
5217 unbecome_root();
5219 /******** End SeAddUsers BLOCK *********/
5221 if (NT_STATUS_IS_OK(status)) {
5222 force_flush_samr_cache(&group_sid);
5225 return status;
5228 /*********************************************************************
5229 _samr_SetAliasInfo
5230 *********************************************************************/
5232 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5233 struct samr_SetAliasInfo *r)
5235 DOM_SID group_sid;
5236 struct acct_info info;
5237 uint32 acc_granted;
5238 bool can_mod_accounts;
5239 NTSTATUS status;
5240 DISP_INFO *disp_info = NULL;
5242 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5243 return NT_STATUS_INVALID_HANDLE;
5245 status = access_check_samr_function(acc_granted,
5246 SAMR_ALIAS_ACCESS_SET_INFO,
5247 "_samr_SetAliasInfo");
5248 if (!NT_STATUS_IS_OK(status)) {
5249 return status;
5252 /* get the current group information */
5254 become_root();
5255 status = pdb_get_aliasinfo( &group_sid, &info );
5256 unbecome_root();
5258 if ( !NT_STATUS_IS_OK(status))
5259 return status;
5261 switch (r->in.level) {
5262 case ALIASINFONAME:
5264 fstring group_name;
5266 /* We currently do not support renaming groups in the
5267 the BUILTIN domain. Refer to util_builtin.c to understand
5268 why. The eventually needs to be fixed to be like Windows
5269 where you can rename builtin groups, just not delete them */
5271 if ( sid_check_is_in_builtin( &group_sid ) ) {
5272 return NT_STATUS_SPECIAL_ACCOUNT;
5275 /* There has to be a valid name (and it has to be different) */
5277 if ( !r->in.info->name.string )
5278 return NT_STATUS_INVALID_PARAMETER;
5280 /* If the name is the same just reply "ok". Yes this
5281 doesn't allow you to change the case of a group name. */
5283 if ( strequal( r->in.info->name.string, info.acct_name ) )
5284 return NT_STATUS_OK;
5286 fstrcpy( info.acct_name, r->in.info->name.string);
5288 /* make sure the name doesn't already exist as a user
5289 or local group */
5291 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5292 status = can_create( p->mem_ctx, group_name );
5293 if ( !NT_STATUS_IS_OK( status ) )
5294 return status;
5295 break;
5297 case ALIASINFODESCRIPTION:
5298 if (r->in.info->description.string) {
5299 fstrcpy(info.acct_desc,
5300 r->in.info->description.string);
5301 } else {
5302 fstrcpy( info.acct_desc, "" );
5304 break;
5305 default:
5306 return NT_STATUS_INVALID_INFO_CLASS;
5309 can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
5311 /******** BEGIN SeAddUsers BLOCK *********/
5313 if ( can_mod_accounts )
5314 become_root();
5316 status = pdb_set_aliasinfo( &group_sid, &info );
5318 if ( can_mod_accounts )
5319 unbecome_root();
5321 /******** End SeAddUsers BLOCK *********/
5323 if (NT_STATUS_IS_OK(status))
5324 force_flush_samr_cache(&group_sid);
5326 return status;
5329 /****************************************************************
5330 _samr_GetDomPwInfo
5331 ****************************************************************/
5333 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5334 struct samr_GetDomPwInfo *r)
5336 uint32_t min_password_length = 0;
5337 uint32_t password_properties = 0;
5339 /* Perform access check. Since this rpc does not require a
5340 policy handle it will not be caught by the access checks on
5341 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5343 if (!pipe_access_check(p)) {
5344 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5345 return NT_STATUS_ACCESS_DENIED;
5348 become_root();
5349 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5350 &min_password_length);
5351 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5352 &password_properties);
5353 unbecome_root();
5355 if (lp_check_password_script() && *lp_check_password_script()) {
5356 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5359 r->out.info->min_password_length = min_password_length;
5360 r->out.info->password_properties = password_properties;
5362 return NT_STATUS_OK;
5365 /*********************************************************************
5366 _samr_OpenGroup
5367 *********************************************************************/
5369 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5370 struct samr_OpenGroup *r)
5373 DOM_SID info_sid;
5374 GROUP_MAP map;
5375 struct samr_domain_info *dinfo;
5376 struct samr_info *info;
5377 SEC_DESC *psd = NULL;
5378 uint32 acc_granted;
5379 uint32 des_access = r->in.access_mask;
5380 size_t sd_size;
5381 NTSTATUS status;
5382 bool ret;
5383 SE_PRIV se_rights;
5385 dinfo = policy_handle_find(p, r->in.domain_handle,
5386 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5387 struct samr_domain_info, &status);
5388 if (!NT_STATUS_IS_OK(status)) {
5389 return status;
5392 /*check if access can be granted as requested by client. */
5393 map_max_allowed_access(p->server_info->ptok, &des_access);
5395 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5396 se_map_generic(&des_access,&grp_generic_mapping);
5398 se_priv_copy( &se_rights, &se_add_users );
5400 status = access_check_samr_object(psd, p->server_info->ptok,
5401 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5402 &acc_granted, "_samr_OpenGroup");
5404 if ( !NT_STATUS_IS_OK(status) )
5405 return status;
5407 /* this should not be hard-coded like this */
5409 if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5410 return NT_STATUS_ACCESS_DENIED;
5412 sid_compose(&info_sid, &dinfo->sid, r->in.rid);
5414 if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
5415 return NT_STATUS_NO_MEMORY;
5417 info->acc_granted = acc_granted;
5419 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
5420 sid_string_dbg(&info_sid)));
5422 /* check if that group really exists */
5423 become_root();
5424 ret = get_domain_group_from_sid(info->sid, &map);
5425 unbecome_root();
5426 if (!ret)
5427 return NT_STATUS_NO_SUCH_GROUP;
5429 /* get a (unique) handle. open a policy on it. */
5430 if (!create_policy_hnd(p, r->out.group_handle, info))
5431 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5433 return NT_STATUS_OK;
5436 /*********************************************************************
5437 _samr_RemoveMemberFromForeignDomain
5438 *********************************************************************/
5440 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5441 struct samr_RemoveMemberFromForeignDomain *r)
5443 struct samr_domain_info *dinfo;
5444 NTSTATUS result;
5446 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5447 sid_string_dbg(r->in.sid)));
5449 /* Find the policy handle. Open a policy on it. */
5451 dinfo = policy_handle_find(p, r->in.domain_handle,
5452 STD_RIGHT_DELETE_ACCESS, NULL,
5453 struct samr_domain_info, &result);
5454 if (!NT_STATUS_IS_OK(result)) {
5455 return result;
5458 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5459 sid_string_dbg(&dinfo->sid)));
5461 /* we can only delete a user from a group since we don't have
5462 nested groups anyways. So in the latter case, just say OK */
5464 /* TODO: The above comment nowadays is bogus. Since we have nested
5465 * groups now, and aliases members are never reported out of the unix
5466 * group membership, the "just say OK" makes this call a no-op. For
5467 * us. This needs fixing however. */
5469 /* I've only ever seen this in the wild when deleting a user from
5470 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5471 * is the user about to be deleted. I very much suspect this is the
5472 * only application of this call. To verify this, let people report
5473 * other cases. */
5475 if (!sid_check_is_builtin(&dinfo->sid)) {
5476 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5477 "global_sam_sid() = %s\n",
5478 sid_string_dbg(&dinfo->sid),
5479 sid_string_dbg(get_global_sam_sid())));
5480 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5481 return NT_STATUS_OK;
5484 force_flush_samr_cache(&dinfo->sid);
5486 result = NT_STATUS_OK;
5488 return result;
5491 /*******************************************************************
5492 _samr_QueryDomainInfo2
5493 ********************************************************************/
5495 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5496 struct samr_QueryDomainInfo2 *r)
5498 struct samr_QueryDomainInfo q;
5500 q.in.domain_handle = r->in.domain_handle;
5501 q.in.level = r->in.level;
5503 q.out.info = r->out.info;
5505 return _samr_QueryDomainInfo(p, &q);
5508 /*******************************************************************
5509 _samr_SetDomainInfo
5510 ********************************************************************/
5512 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5513 struct samr_SetDomainInfo *r)
5515 struct samr_domain_info *dinfo;
5516 time_t u_expire, u_min_age;
5517 time_t u_logout;
5518 time_t u_lock_duration, u_reset_time;
5519 NTSTATUS result;
5521 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5523 /* We do have different access bits for info
5524 * levels here, but we're really just looking for
5525 * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
5526 * this maps to different specific bits. So
5527 * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
5528 * set we are ok. */
5530 dinfo = policy_handle_find(p, r->in.domain_handle,
5531 SAMR_DOMAIN_ACCESS_SET_INFO_1, NULL,
5532 struct samr_domain_info, &result);
5533 if (!NT_STATUS_IS_OK(result)) {
5534 return result;
5537 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5539 switch (r->in.level) {
5540 case 0x01:
5541 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5542 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5543 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5544 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5545 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5546 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5547 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5548 break;
5549 case 0x02:
5550 break;
5551 case 0x03:
5552 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5553 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5554 break;
5555 case 0x05:
5556 break;
5557 case 0x06:
5558 break;
5559 case 0x07:
5560 break;
5561 case 0x0c:
5562 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5563 if (u_lock_duration != -1)
5564 u_lock_duration /= 60;
5566 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5568 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5569 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5570 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5571 break;
5572 default:
5573 return NT_STATUS_INVALID_INFO_CLASS;
5576 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5578 return NT_STATUS_OK;
5581 /****************************************************************
5582 _samr_GetDisplayEnumerationIndex
5583 ****************************************************************/
5585 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5586 struct samr_GetDisplayEnumerationIndex *r)
5588 struct samr_domain_info *dinfo;
5589 uint32_t max_entries = (uint32_t) -1;
5590 uint32_t enum_context = 0;
5591 int i;
5592 uint32_t num_account = 0;
5593 struct samr_displayentry *entries = NULL;
5594 NTSTATUS status;
5596 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5598 dinfo = policy_handle_find(p, r->in.domain_handle,
5599 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
5600 struct samr_domain_info, &status);
5601 if (!NT_STATUS_IS_OK(status)) {
5602 return status;
5605 if ((r->in.level < 1) || (r->in.level > 3)) {
5606 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5607 "Unknown info level (%u)\n",
5608 r->in.level));
5609 return NT_STATUS_INVALID_INFO_CLASS;
5612 become_root();
5614 /* The following done as ROOT. Don't return without unbecome_root(). */
5616 switch (r->in.level) {
5617 case 1:
5618 if (dinfo->disp_info->users == NULL) {
5619 dinfo->disp_info->users = pdb_search_users(
5620 dinfo->disp_info, ACB_NORMAL);
5621 if (dinfo->disp_info->users == NULL) {
5622 unbecome_root();
5623 return NT_STATUS_ACCESS_DENIED;
5625 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5626 "starting user enumeration at index %u\n",
5627 (unsigned int)enum_context));
5628 } else {
5629 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5630 "using cached user enumeration at index %u\n",
5631 (unsigned int)enum_context));
5633 num_account = pdb_search_entries(dinfo->disp_info->users,
5634 enum_context, max_entries,
5635 &entries);
5636 break;
5637 case 2:
5638 if (dinfo->disp_info->machines == NULL) {
5639 dinfo->disp_info->machines = pdb_search_users(
5640 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
5641 if (dinfo->disp_info->machines == NULL) {
5642 unbecome_root();
5643 return NT_STATUS_ACCESS_DENIED;
5645 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5646 "starting machine enumeration at index %u\n",
5647 (unsigned int)enum_context));
5648 } else {
5649 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5650 "using cached machine enumeration at index %u\n",
5651 (unsigned int)enum_context));
5653 num_account = pdb_search_entries(dinfo->disp_info->machines,
5654 enum_context, max_entries,
5655 &entries);
5656 break;
5657 case 3:
5658 if (dinfo->disp_info->groups == NULL) {
5659 dinfo->disp_info->groups = pdb_search_groups(
5660 dinfo->disp_info);
5661 if (dinfo->disp_info->groups == NULL) {
5662 unbecome_root();
5663 return NT_STATUS_ACCESS_DENIED;
5665 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5666 "starting group enumeration at index %u\n",
5667 (unsigned int)enum_context));
5668 } else {
5669 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5670 "using cached group enumeration at index %u\n",
5671 (unsigned int)enum_context));
5673 num_account = pdb_search_entries(dinfo->disp_info->groups,
5674 enum_context, max_entries,
5675 &entries);
5676 break;
5677 default:
5678 unbecome_root();
5679 smb_panic("info class changed");
5680 break;
5683 unbecome_root();
5685 /* Ensure we cache this enumeration. */
5686 set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
5688 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5689 r->in.name->string));
5691 for (i=0; i<num_account; i++) {
5692 if (strequal(entries[i].account_name, r->in.name->string)) {
5693 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5694 "found %s at idx %d\n",
5695 r->in.name->string, i));
5696 *r->out.idx = i;
5697 return NT_STATUS_OK;
5701 /* assuming account_name lives at the very end */
5702 *r->out.idx = num_account;
5704 return NT_STATUS_NO_MORE_ENTRIES;
5707 /****************************************************************
5708 _samr_GetDisplayEnumerationIndex2
5709 ****************************************************************/
5711 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5712 struct samr_GetDisplayEnumerationIndex2 *r)
5714 struct samr_GetDisplayEnumerationIndex q;
5716 q.in.domain_handle = r->in.domain_handle;
5717 q.in.level = r->in.level;
5718 q.in.name = r->in.name;
5720 q.out.idx = r->out.idx;
5722 return _samr_GetDisplayEnumerationIndex(p, &q);
5725 /****************************************************************
5726 ****************************************************************/
5728 NTSTATUS _samr_Shutdown(pipes_struct *p,
5729 struct samr_Shutdown *r)
5731 p->rng_fault_state = true;
5732 return NT_STATUS_NOT_IMPLEMENTED;
5735 /****************************************************************
5736 ****************************************************************/
5738 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5739 struct samr_SetMemberAttributesOfGroup *r)
5741 p->rng_fault_state = true;
5742 return NT_STATUS_NOT_IMPLEMENTED;
5745 /****************************************************************
5746 ****************************************************************/
5748 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5749 struct samr_ChangePasswordUser *r)
5751 p->rng_fault_state = true;
5752 return NT_STATUS_NOT_IMPLEMENTED;
5755 /****************************************************************
5756 ****************************************************************/
5758 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5759 struct samr_TestPrivateFunctionsDomain *r)
5761 p->rng_fault_state = true;
5762 return NT_STATUS_NOT_IMPLEMENTED;
5765 /****************************************************************
5766 ****************************************************************/
5768 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5769 struct samr_TestPrivateFunctionsUser *r)
5771 p->rng_fault_state = true;
5772 return NT_STATUS_NOT_IMPLEMENTED;
5775 /****************************************************************
5776 ****************************************************************/
5778 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5779 struct samr_AddMultipleMembersToAlias *r)
5781 p->rng_fault_state = true;
5782 return NT_STATUS_NOT_IMPLEMENTED;
5785 /****************************************************************
5786 ****************************************************************/
5788 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5789 struct samr_RemoveMultipleMembersFromAlias *r)
5791 p->rng_fault_state = true;
5792 return NT_STATUS_NOT_IMPLEMENTED;
5795 /****************************************************************
5796 ****************************************************************/
5798 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5799 struct samr_OemChangePasswordUser2 *r)
5801 p->rng_fault_state = true;
5802 return NT_STATUS_NOT_IMPLEMENTED;
5805 /****************************************************************
5806 ****************************************************************/
5808 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5809 struct samr_SetBootKeyInformation *r)
5811 p->rng_fault_state = true;
5812 return NT_STATUS_NOT_IMPLEMENTED;
5815 /****************************************************************
5816 ****************************************************************/
5818 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5819 struct samr_GetBootKeyInformation *r)
5821 p->rng_fault_state = true;
5822 return NT_STATUS_NOT_IMPLEMENTED;
5825 /****************************************************************
5826 ****************************************************************/
5828 NTSTATUS _samr_RidToSid(pipes_struct *p,
5829 struct samr_RidToSid *r)
5831 p->rng_fault_state = true;
5832 return NT_STATUS_NOT_IMPLEMENTED;
5835 /****************************************************************
5836 ****************************************************************/
5838 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5839 struct samr_SetDsrmPassword *r)
5841 p->rng_fault_state = true;
5842 return NT_STATUS_NOT_IMPLEMENTED;
5845 /****************************************************************
5846 ****************************************************************/
5848 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5849 struct samr_ValidatePassword *r)
5851 p->rng_fault_state = true;
5852 return NT_STATUS_NOT_IMPLEMENTED;