Cosmetic corrections for the DSDB module
[Samba/nascimento.git] / source3 / rpc_server / srv_samr_nt.c
blobd4ce34934ea18211beaffcae917b500070dd3916
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2005,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003-2004,
12 * Copyright (C) Simo Sorce 2003.
13 * Copyright (C) Volker Lendecke 2005.
14 * Copyright (C) Guenther Deschner 2008.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 * This is the implementation of the SAMR code.
34 #include "includes.h"
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40 ( READ_CONTROL_ACCESS | \
41 SA_RIGHT_USER_CHANGE_PASSWORD | \
42 SA_RIGHT_USER_SET_LOC_COM )
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
46 #define DISP_INFO_CACHE_TIMEOUT 10
48 typedef struct disp_info {
49 DOM_SID sid; /* identify which domain this is. */
50 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
51 struct pdb_search *users; /* querydispinfo 1 and 4 */
52 struct pdb_search *machines; /* querydispinfo 2 */
53 struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
54 struct pdb_search *aliases; /* enumaliases */
56 uint16 enum_acb_mask;
57 struct pdb_search *enum_users; /* enumusers with a mask */
59 struct timed_event *cache_timeout_event; /* cache idle timeout
60 * handler. */
61 } DISP_INFO;
63 /* We keep a static list of these by SID as modern clients close down
64 all resources between each request in a complete enumeration. */
66 struct samr_info {
67 /* for use by the \PIPE\samr policy */
68 DOM_SID sid;
69 bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
70 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
71 uint32 acc_granted;
72 DISP_INFO *disp_info;
73 TALLOC_CTX *mem_ctx;
76 static const struct generic_mapping sam_generic_mapping = {
77 GENERIC_RIGHTS_SAM_READ,
78 GENERIC_RIGHTS_SAM_WRITE,
79 GENERIC_RIGHTS_SAM_EXECUTE,
80 GENERIC_RIGHTS_SAM_ALL_ACCESS};
81 static const struct generic_mapping dom_generic_mapping = {
82 GENERIC_RIGHTS_DOMAIN_READ,
83 GENERIC_RIGHTS_DOMAIN_WRITE,
84 GENERIC_RIGHTS_DOMAIN_EXECUTE,
85 GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
86 static const struct generic_mapping usr_generic_mapping = {
87 GENERIC_RIGHTS_USER_READ,
88 GENERIC_RIGHTS_USER_WRITE,
89 GENERIC_RIGHTS_USER_EXECUTE,
90 GENERIC_RIGHTS_USER_ALL_ACCESS};
91 static const struct generic_mapping usr_nopwchange_generic_mapping = {
92 GENERIC_RIGHTS_USER_READ,
93 GENERIC_RIGHTS_USER_WRITE,
94 GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
95 GENERIC_RIGHTS_USER_ALL_ACCESS};
96 static const struct generic_mapping grp_generic_mapping = {
97 GENERIC_RIGHTS_GROUP_READ,
98 GENERIC_RIGHTS_GROUP_WRITE,
99 GENERIC_RIGHTS_GROUP_EXECUTE,
100 GENERIC_RIGHTS_GROUP_ALL_ACCESS};
101 static const struct generic_mapping ali_generic_mapping = {
102 GENERIC_RIGHTS_ALIAS_READ,
103 GENERIC_RIGHTS_ALIAS_WRITE,
104 GENERIC_RIGHTS_ALIAS_EXECUTE,
105 GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
107 /*******************************************************************
108 *******************************************************************/
110 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
111 const struct generic_mapping *map,
112 DOM_SID *sid, uint32 sid_access )
114 DOM_SID domadmin_sid;
115 SEC_ACE ace[5]; /* at most 5 entries */
116 size_t i = 0;
118 SEC_ACL *psa = NULL;
120 /* basic access for Everyone */
122 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
123 map->generic_execute | map->generic_read, 0);
125 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
127 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
128 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
129 init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
130 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
132 /* Add Full Access for Domain Admins if we are a DC */
134 if ( IS_DC ) {
135 sid_copy( &domadmin_sid, get_global_sam_sid() );
136 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
137 init_sec_ace(&ace[i++], &domadmin_sid,
138 SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
141 /* if we have a sid, give it some special access */
143 if ( sid ) {
144 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
147 /* create the security descriptor */
149 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
150 return NT_STATUS_NO_MEMORY;
152 if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
153 SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
154 psa, sd_size)) == NULL)
155 return NT_STATUS_NO_MEMORY;
157 return NT_STATUS_OK;
160 /*******************************************************************
161 Checks if access to an object should be granted, and returns that
162 level of access for further checks.
163 ********************************************************************/
165 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
166 SE_PRIV *rights, uint32 rights_mask,
167 uint32 des_access, uint32 *acc_granted,
168 const char *debug )
170 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
171 uint32 saved_mask = 0;
173 /* check privileges; certain SAM access bits should be overridden
174 by privileges (mostly having to do with creating/modifying/deleting
175 users and groups) */
177 if ( rights && user_has_any_privilege( token, rights ) ) {
179 saved_mask = (des_access & rights_mask);
180 des_access &= ~saved_mask;
182 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
183 rights_mask));
187 /* check the security descriptor first */
189 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
190 goto done;
192 /* give root a free pass */
194 if ( geteuid() == sec_initial_uid() ) {
196 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
197 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
199 *acc_granted = des_access;
201 status = NT_STATUS_OK;
202 goto done;
206 done:
207 /* add in any bits saved during the privilege check (only
208 matters is status is ok) */
210 *acc_granted |= rights_mask;
212 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
213 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
214 des_access, *acc_granted));
216 return status;
219 /*******************************************************************
220 Checks if access to a function can be granted
221 ********************************************************************/
223 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
225 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
226 debug, acc_granted, acc_required));
228 /* check the security descriptor first */
230 if ( (acc_granted&acc_required) == acc_required )
231 return NT_STATUS_OK;
233 /* give root a free pass */
235 if (geteuid() == sec_initial_uid()) {
237 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
238 debug, acc_granted, acc_required));
239 DEBUGADD(4,("but overwritten by euid == 0\n"));
241 return NT_STATUS_OK;
244 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
245 debug, acc_granted, acc_required));
247 return NT_STATUS_ACCESS_DENIED;
250 /*******************************************************************
251 Fetch or create a dispinfo struct.
252 ********************************************************************/
254 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
257 * We do a static cache for DISP_INFO's here. Explanation can be found
258 * in Jeremy's checkin message to r11793:
260 * Fix the SAMR cache so it works across completely insane
261 * client behaviour (ie.:
262 * open pipe/open SAMR handle/enumerate 0 - 1024
263 * close SAMR handle, close pipe.
264 * open pipe/open SAMR handle/enumerate 1024 - 2048...
265 * close SAMR handle, close pipe.
266 * And on ad-nausium. Amazing.... probably object-oriented
267 * client side programming in action yet again.
268 * This change should *massively* improve performance when
269 * enumerating users from an LDAP database.
270 * Jeremy.
272 * "Our" and the builtin domain are the only ones where we ever
273 * enumerate stuff, so just cache 2 entries.
276 static struct disp_info builtin_dispinfo;
277 static struct disp_info domain_dispinfo;
279 /* There are two cases to consider here:
280 1) The SID is a domain SID and we look for an equality match, or
281 2) This is an account SID and so we return the DISP_INFO* for our
282 domain */
284 if (psid == NULL) {
285 return NULL;
288 if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
290 * Necessary only once, but it does not really hurt.
292 sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
294 return &builtin_dispinfo;
297 if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
299 * Necessary only once, but it does not really hurt.
301 sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
303 return &domain_dispinfo;
306 return NULL;
309 /*******************************************************************
310 Create a samr_info struct.
311 ********************************************************************/
313 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
315 struct samr_info *info;
316 fstring sid_str;
317 TALLOC_CTX *mem_ctx;
319 if (psid) {
320 sid_to_fstring(sid_str, psid);
321 } else {
322 fstrcpy(sid_str,"(NULL)");
325 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
327 if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
328 return NULL;
330 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
331 if (psid) {
332 sid_copy( &info->sid, psid);
333 info->builtin_domain = sid_check_is_builtin(psid);
334 } else {
335 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
336 info->builtin_domain = False;
338 info->mem_ctx = mem_ctx;
340 info->disp_info = get_samr_dispinfo_by_sid(psid);
342 return info;
345 /*******************************************************************
346 Function to free the per SID data.
347 ********************************************************************/
349 static void free_samr_cache(DISP_INFO *disp_info)
351 DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
352 sid_string_dbg(&disp_info->sid)));
354 /* We need to become root here because the paged search might have to
355 * tell the LDAP server we're not interested in the rest anymore. */
357 become_root();
359 if (disp_info->users) {
360 DEBUG(10,("free_samr_cache: deleting users cache\n"));
361 pdb_search_destroy(disp_info->users);
362 disp_info->users = NULL;
364 if (disp_info->machines) {
365 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
366 pdb_search_destroy(disp_info->machines);
367 disp_info->machines = NULL;
369 if (disp_info->groups) {
370 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
371 pdb_search_destroy(disp_info->groups);
372 disp_info->groups = NULL;
374 if (disp_info->aliases) {
375 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
376 pdb_search_destroy(disp_info->aliases);
377 disp_info->aliases = NULL;
379 if (disp_info->enum_users) {
380 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
381 pdb_search_destroy(disp_info->enum_users);
382 disp_info->enum_users = NULL;
384 disp_info->enum_acb_mask = 0;
386 unbecome_root();
389 /*******************************************************************
390 Function to free the per handle data.
391 ********************************************************************/
393 static void free_samr_info(void *ptr)
395 struct samr_info *info=(struct samr_info *) ptr;
397 /* Only free the dispinfo cache if no one bothered to set up
398 a timeout. */
400 if (info->disp_info && info->disp_info->cache_timeout_event == NULL) {
401 free_samr_cache(info->disp_info);
404 talloc_destroy(info->mem_ctx);
407 /*******************************************************************
408 Idle event handler. Throw away the disp info cache.
409 ********************************************************************/
411 static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
412 struct timed_event *te,
413 const struct timeval *now,
414 void *private_data)
416 DISP_INFO *disp_info = (DISP_INFO *)private_data;
418 TALLOC_FREE(disp_info->cache_timeout_event);
420 DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
421 "out\n"));
422 free_samr_cache(disp_info);
425 /*******************************************************************
426 Setup cache removal idle event handler.
427 ********************************************************************/
429 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
431 /* Remove any pending timeout and update. */
433 TALLOC_FREE(disp_info->cache_timeout_event);
435 DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
436 "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
437 (unsigned int)secs_fromnow ));
439 disp_info->cache_timeout_event = event_add_timed(
440 smbd_event_context(), NULL,
441 timeval_current_ofs(secs_fromnow, 0),
442 "disp_info_cache_idle_timeout_handler",
443 disp_info_cache_idle_timeout_handler, (void *)disp_info);
446 /*******************************************************************
447 Force flush any cache. We do this on any samr_set_xxx call.
448 We must also remove the timeout handler.
449 ********************************************************************/
451 static void force_flush_samr_cache(DISP_INFO *disp_info)
453 if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
454 return;
457 DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
458 TALLOC_FREE(disp_info->cache_timeout_event);
459 free_samr_cache(disp_info);
462 /*******************************************************************
463 Ensure password info is never given out. Paranioa... JRA.
464 ********************************************************************/
466 static void samr_clear_sam_passwd(struct samu *sam_pass)
469 if (!sam_pass)
470 return;
472 /* These now zero out the old password */
474 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
475 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
478 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
480 struct samr_displayentry *entry;
482 if (info->builtin_domain) {
483 /* No users in builtin. */
484 return 0;
487 if (info->users == NULL) {
488 info->users = pdb_search_users(acct_flags);
489 if (info->users == NULL) {
490 return 0;
493 /* Fetch the last possible entry, thus trigger an enumeration */
494 pdb_search_entries(info->users, 0xffffffff, 1, &entry);
496 /* Ensure we cache this enumeration. */
497 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
499 return info->users->num_entries;
502 static uint32 count_sam_groups(struct disp_info *info)
504 struct samr_displayentry *entry;
506 if (info->builtin_domain) {
507 /* No groups in builtin. */
508 return 0;
511 if (info->groups == NULL) {
512 info->groups = pdb_search_groups();
513 if (info->groups == NULL) {
514 return 0;
517 /* Fetch the last possible entry, thus trigger an enumeration */
518 pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
520 /* Ensure we cache this enumeration. */
521 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
523 return info->groups->num_entries;
526 static uint32 count_sam_aliases(struct disp_info *info)
528 struct samr_displayentry *entry;
530 if (info->aliases == NULL) {
531 info->aliases = pdb_search_aliases(&info->sid);
532 if (info->aliases == NULL) {
533 return 0;
536 /* Fetch the last possible entry, thus trigger an enumeration */
537 pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
539 /* Ensure we cache this enumeration. */
540 set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
542 return info->aliases->num_entries;
545 /*******************************************************************
546 _samr_Close
547 ********************************************************************/
549 NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
551 if (!close_policy_hnd(p, r->in.handle)) {
552 return NT_STATUS_INVALID_HANDLE;
555 ZERO_STRUCTP(r->out.handle);
557 return NT_STATUS_OK;
560 /*******************************************************************
561 _samr_OpenDomain
562 ********************************************************************/
564 NTSTATUS _samr_OpenDomain(pipes_struct *p,
565 struct samr_OpenDomain *r)
567 struct samr_info *info;
568 SEC_DESC *psd = NULL;
569 uint32 acc_granted;
570 uint32 des_access = r->in.access_mask;
571 NTSTATUS status;
572 size_t sd_size;
573 SE_PRIV se_rights;
575 /* find the connection policy handle. */
577 if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
578 return NT_STATUS_INVALID_HANDLE;
580 status = access_check_samr_function(info->acc_granted,
581 SA_RIGHT_SAM_OPEN_DOMAIN,
582 "_samr_OpenDomain" );
584 if ( !NT_STATUS_IS_OK(status) )
585 return status;
587 /*check if access can be granted as requested by client. */
589 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
590 se_map_generic( &des_access, &dom_generic_mapping );
592 se_priv_copy( &se_rights, &se_machine_account );
593 se_priv_add( &se_rights, &se_add_users );
595 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
596 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
597 &acc_granted, "_samr_OpenDomain" );
599 if ( !NT_STATUS_IS_OK(status) )
600 return status;
602 if (!sid_check_is_domain(r->in.sid) &&
603 !sid_check_is_builtin(r->in.sid)) {
604 return NT_STATUS_NO_SUCH_DOMAIN;
607 /* associate the domain SID with the (unique) handle. */
608 if ((info = get_samr_info_by_sid(r->in.sid))==NULL)
609 return NT_STATUS_NO_MEMORY;
610 info->acc_granted = acc_granted;
612 /* get a (unique) handle. open a policy on it. */
613 if (!create_policy_hnd(p, r->out.domain_handle, free_samr_info, (void *)info))
614 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
616 DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
618 return NT_STATUS_OK;
621 /*******************************************************************
622 _samr_GetUserPwInfo
623 ********************************************************************/
625 NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
626 struct samr_GetUserPwInfo *r)
628 struct samr_info *info = NULL;
629 enum lsa_SidType sid_type;
630 uint32_t min_password_length = 0;
631 uint32_t password_properties = 0;
632 bool ret = false;
633 NTSTATUS status;
635 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
637 /* find the policy handle. open a policy on it. */
638 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) {
639 return NT_STATUS_INVALID_HANDLE;
642 status = access_check_samr_function(info->acc_granted,
643 SAMR_USER_ACCESS_GET_ATTRIBUTES,
644 "_samr_GetUserPwInfo" );
645 if (!NT_STATUS_IS_OK(status)) {
646 return status;
649 if (!sid_check_is_in_our_domain(&info->sid)) {
650 return NT_STATUS_OBJECT_TYPE_MISMATCH;
653 become_root();
654 ret = lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, &sid_type);
655 unbecome_root();
656 if (ret == false) {
657 return NT_STATUS_NO_SUCH_USER;
660 switch (sid_type) {
661 case SID_NAME_USER:
662 become_root();
663 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
664 &min_password_length);
665 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
666 &password_properties);
667 unbecome_root();
669 if (lp_check_password_script() && *lp_check_password_script()) {
670 password_properties |= DOMAIN_PASSWORD_COMPLEX;
673 break;
674 default:
675 break;
678 r->out.info->min_password_length = min_password_length;
679 r->out.info->password_properties = password_properties;
681 DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
683 return NT_STATUS_OK;
686 /*******************************************************************
687 ********************************************************************/
689 static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
690 DOM_SID *sid, uint32 *acc_granted,
691 DISP_INFO **ppdisp_info)
693 struct samr_info *info = NULL;
695 /* find the policy handle. open a policy on it. */
696 if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
697 return False;
699 if (!info)
700 return False;
702 *sid = info->sid;
703 *acc_granted = info->acc_granted;
704 if (ppdisp_info) {
705 *ppdisp_info = info->disp_info;
708 return True;
711 /*******************************************************************
712 _samr_SetSecurity
713 ********************************************************************/
715 NTSTATUS _samr_SetSecurity(pipes_struct *p,
716 struct samr_SetSecurity *r)
718 DOM_SID pol_sid;
719 uint32 acc_granted, i;
720 SEC_ACL *dacl;
721 bool ret;
722 struct samu *sampass=NULL;
723 NTSTATUS status;
725 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
726 return NT_STATUS_INVALID_HANDLE;
728 if (!(sampass = samu_new( p->mem_ctx))) {
729 DEBUG(0,("No memory!\n"));
730 return NT_STATUS_NO_MEMORY;
733 /* get the user record */
734 become_root();
735 ret = pdb_getsampwsid(sampass, &pol_sid);
736 unbecome_root();
738 if (!ret) {
739 DEBUG(4, ("User %s not found\n", sid_string_dbg(&pol_sid)));
740 TALLOC_FREE(sampass);
741 return NT_STATUS_INVALID_HANDLE;
744 dacl = r->in.sdbuf->sd->dacl;
745 for (i=0; i < dacl->num_aces; i++) {
746 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
747 ret = pdb_set_pass_can_change(sampass,
748 (dacl->aces[i].access_mask &
749 SA_RIGHT_USER_CHANGE_PASSWORD) ?
750 True: False);
751 break;
755 if (!ret) {
756 TALLOC_FREE(sampass);
757 return NT_STATUS_ACCESS_DENIED;
760 status = access_check_samr_function(acc_granted,
761 SA_RIGHT_USER_SET_ATTRIBUTES,
762 "_samr_SetSecurity");
763 if (NT_STATUS_IS_OK(status)) {
764 become_root();
765 status = pdb_update_sam_account(sampass);
766 unbecome_root();
769 TALLOC_FREE(sampass);
771 return status;
774 /*******************************************************************
775 build correct perms based on policies and password times for _samr_query_sec_obj
776 *******************************************************************/
777 static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
779 struct samu *sampass=NULL;
780 bool ret;
782 if ( !(sampass = samu_new( mem_ctx )) ) {
783 DEBUG(0,("No memory!\n"));
784 return False;
787 become_root();
788 ret = pdb_getsampwsid(sampass, user_sid);
789 unbecome_root();
791 if (ret == False) {
792 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
793 TALLOC_FREE(sampass);
794 return False;
797 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
799 if (pdb_get_pass_can_change(sampass)) {
800 TALLOC_FREE(sampass);
801 return True;
803 TALLOC_FREE(sampass);
804 return False;
808 /*******************************************************************
809 _samr_QuerySecurity
810 ********************************************************************/
812 NTSTATUS _samr_QuerySecurity(pipes_struct *p,
813 struct samr_QuerySecurity *r)
815 NTSTATUS status;
816 DOM_SID pol_sid;
817 SEC_DESC * psd = NULL;
818 uint32 acc_granted;
819 size_t sd_size;
821 /* Get the SID. */
822 if (!get_lsa_policy_samr_sid(p, r->in.handle, &pol_sid, &acc_granted, NULL))
823 return NT_STATUS_INVALID_HANDLE;
825 DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
826 sid_string_dbg(&pol_sid)));
828 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
830 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
831 if (pol_sid.sid_rev_num == 0) {
832 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
833 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
834 } else if (sid_equal(&pol_sid,get_global_sam_sid())) {
835 /* check if it is our domain SID */
836 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
837 "with SID: %s\n", sid_string_dbg(&pol_sid)));
838 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
839 } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
840 /* check if it is the Builtin Domain */
841 /* TODO: Builtin probably needs a different SD with restricted write access*/
842 DEBUG(5,("_samr_QuerySecurity: querying security on Builtin "
843 "Domain with SID: %s\n", sid_string_dbg(&pol_sid)));
844 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
845 } else if (sid_check_is_in_our_domain(&pol_sid) ||
846 sid_check_is_in_builtin(&pol_sid)) {
847 /* TODO: different SDs have to be generated for aliases groups and users.
848 Currently all three get a default user SD */
849 DEBUG(10,("_samr_QuerySecurity: querying security on Object "
850 "with SID: %s\n", sid_string_dbg(&pol_sid)));
851 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
852 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
853 &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
854 } else {
855 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping,
856 &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
858 } else {
859 return NT_STATUS_OBJECT_TYPE_MISMATCH;
862 if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
863 return NT_STATUS_NO_MEMORY;
865 return status;
868 /*******************************************************************
869 makes a SAM_ENTRY / UNISTR2* structure from a user list.
870 ********************************************************************/
872 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
873 struct samr_SamEntry **sam_pp,
874 uint32_t num_entries,
875 uint32_t start_idx,
876 struct samr_displayentry *entries)
878 uint32_t i;
879 struct samr_SamEntry *sam;
881 *sam_pp = NULL;
883 if (num_entries == 0) {
884 return NT_STATUS_OK;
887 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
888 if (sam == NULL) {
889 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
890 return NT_STATUS_NO_MEMORY;
893 for (i = 0; i < num_entries; i++) {
894 #if 0
896 * usrmgr expects a non-NULL terminated string with
897 * trust relationships
899 if (entries[i].acct_flags & ACB_DOMTRUST) {
900 init_unistr2(&uni_temp_name, entries[i].account_name,
901 UNI_FLAGS_NONE);
902 } else {
903 init_unistr2(&uni_temp_name, entries[i].account_name,
904 UNI_STR_TERMINATE);
906 #endif
907 init_lsa_String(&sam[i].name, entries[i].account_name);
908 sam[i].idx = entries[i].rid;
911 *sam_pp = sam;
913 return NT_STATUS_OK;
916 #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
918 /*******************************************************************
919 _samr_EnumDomainUsers
920 ********************************************************************/
922 NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
923 struct samr_EnumDomainUsers *r)
925 NTSTATUS status;
926 struct samr_info *info = NULL;
927 int num_account;
928 uint32 enum_context = *r->in.resume_handle;
929 enum remote_arch_types ra_type = get_remote_arch();
930 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
931 uint32 max_entries = max_sam_entries;
932 struct samr_displayentry *entries = NULL;
933 struct samr_SamArray *samr_array = NULL;
934 struct samr_SamEntry *samr_entries = NULL;
936 /* find the policy handle. open a policy on it. */
937 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
938 return NT_STATUS_INVALID_HANDLE;
940 status = access_check_samr_function(info->acc_granted,
941 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
942 "_samr_EnumDomainUsers");
943 if (!NT_STATUS_IS_OK(status)) {
944 return status;
947 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
949 if (info->builtin_domain) {
950 /* No users in builtin. */
951 *r->out.resume_handle = *r->in.resume_handle;
952 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
953 return status;
956 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
957 if (!samr_array) {
958 return NT_STATUS_NO_MEMORY;
961 become_root();
963 /* AS ROOT !!!! */
965 if ((info->disp_info->enum_users != NULL) &&
966 (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
967 pdb_search_destroy(info->disp_info->enum_users);
968 info->disp_info->enum_users = NULL;
971 if (info->disp_info->enum_users == NULL) {
972 info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
973 info->disp_info->enum_acb_mask = r->in.acct_flags;
976 if (info->disp_info->enum_users == NULL) {
977 /* END AS ROOT !!!! */
978 unbecome_root();
979 return NT_STATUS_ACCESS_DENIED;
982 num_account = pdb_search_entries(info->disp_info->enum_users,
983 enum_context, max_entries,
984 &entries);
986 /* END AS ROOT !!!! */
988 unbecome_root();
990 if (num_account == 0) {
991 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
992 "total entries\n"));
993 *r->out.resume_handle = *r->in.resume_handle;
994 return NT_STATUS_OK;
997 status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
998 num_account, enum_context,
999 entries);
1000 if (!NT_STATUS_IS_OK(status)) {
1001 return status;
1004 if (max_entries <= num_account) {
1005 status = STATUS_MORE_ENTRIES;
1006 } else {
1007 status = NT_STATUS_OK;
1010 /* Ensure we cache this enumeration. */
1011 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1013 DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1015 samr_array->count = num_account;
1016 samr_array->entries = samr_entries;
1018 *r->out.resume_handle = *r->in.resume_handle + num_account;
1019 *r->out.sam = samr_array;
1020 *r->out.num_entries = num_account;
1022 DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1024 return status;
1027 /*******************************************************************
1028 makes a SAM_ENTRY / UNISTR2* structure from a group list.
1029 ********************************************************************/
1031 static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1032 struct samr_SamEntry **sam_pp,
1033 uint32_t num_sam_entries,
1034 struct samr_displayentry *entries)
1036 struct samr_SamEntry *sam;
1037 uint32_t i;
1039 *sam_pp = NULL;
1041 if (num_sam_entries == 0) {
1042 return;
1045 sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1046 if (sam == NULL) {
1047 return;
1050 for (i = 0; i < num_sam_entries; i++) {
1052 * JRA. I think this should include the null. TNG does not.
1054 init_lsa_String(&sam[i].name, entries[i].account_name);
1055 sam[i].idx = entries[i].rid;
1058 *sam_pp = sam;
1061 /*******************************************************************
1062 _samr_EnumDomainGroups
1063 ********************************************************************/
1065 NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1066 struct samr_EnumDomainGroups *r)
1068 NTSTATUS status;
1069 struct samr_info *info = NULL;
1070 struct samr_displayentry *groups;
1071 uint32 num_groups;
1072 struct samr_SamArray *samr_array = NULL;
1073 struct samr_SamEntry *samr_entries = NULL;
1075 /* find the policy handle. open a policy on it. */
1076 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1077 return NT_STATUS_INVALID_HANDLE;
1079 status = access_check_samr_function(info->acc_granted,
1080 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1081 "_samr_EnumDomainGroups");
1082 if (!NT_STATUS_IS_OK(status)) {
1083 return status;
1086 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1088 if (info->builtin_domain) {
1089 /* No groups in builtin. */
1090 *r->out.resume_handle = *r->in.resume_handle;
1091 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1092 return status;
1095 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1096 if (!samr_array) {
1097 return NT_STATUS_NO_MEMORY;
1100 /* the domain group array is being allocated in the function below */
1102 become_root();
1104 if (info->disp_info->groups == NULL) {
1105 info->disp_info->groups = pdb_search_groups();
1107 if (info->disp_info->groups == NULL) {
1108 unbecome_root();
1109 return NT_STATUS_ACCESS_DENIED;
1113 num_groups = pdb_search_entries(info->disp_info->groups,
1114 *r->in.resume_handle,
1115 MAX_SAM_ENTRIES, &groups);
1116 unbecome_root();
1118 /* Ensure we cache this enumeration. */
1119 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1121 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1122 num_groups, groups);
1124 samr_array->count = num_groups;
1125 samr_array->entries = samr_entries;
1127 *r->out.sam = samr_array;
1128 *r->out.num_entries = num_groups;
1129 /* this was missing, IMHO:
1130 *r->out.resume_handle = num_groups + *r->in.resume_handle;
1133 DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1135 return status;
1138 /*******************************************************************
1139 _samr_EnumDomainAliases
1140 ********************************************************************/
1142 NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1143 struct samr_EnumDomainAliases *r)
1145 NTSTATUS status;
1146 struct samr_info *info;
1147 struct samr_displayentry *aliases;
1148 uint32 num_aliases = 0;
1149 struct samr_SamArray *samr_array = NULL;
1150 struct samr_SamEntry *samr_entries = NULL;
1152 /* find the policy handle. open a policy on it. */
1153 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1154 return NT_STATUS_INVALID_HANDLE;
1156 status = access_check_samr_function(info->acc_granted,
1157 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1158 "_samr_EnumDomainAliases");
1159 if (!NT_STATUS_IS_OK(status)) {
1160 return status;
1163 DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1164 sid_string_dbg(&info->sid)));
1166 samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1167 if (!samr_array) {
1168 return NT_STATUS_NO_MEMORY;
1171 become_root();
1173 if (info->disp_info->aliases == NULL) {
1174 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1175 if (info->disp_info->aliases == NULL) {
1176 unbecome_root();
1177 return NT_STATUS_ACCESS_DENIED;
1181 num_aliases = pdb_search_entries(info->disp_info->aliases,
1182 *r->in.resume_handle,
1183 MAX_SAM_ENTRIES, &aliases);
1184 unbecome_root();
1186 /* Ensure we cache this enumeration. */
1187 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1189 make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1190 num_aliases, aliases);
1192 DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1194 samr_array->count = num_aliases;
1195 samr_array->entries = samr_entries;
1197 *r->out.sam = samr_array;
1198 *r->out.num_entries = num_aliases;
1199 *r->out.resume_handle = num_aliases + *r->in.resume_handle;
1201 return status;
1204 /*******************************************************************
1205 inits a samr_DispInfoGeneral structure.
1206 ********************************************************************/
1208 static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
1209 struct samr_DispInfoGeneral *r,
1210 uint32_t num_entries,
1211 uint32_t start_idx,
1212 struct samr_displayentry *entries)
1214 uint32 i;
1216 DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1218 if (num_entries == 0) {
1219 return NT_STATUS_OK;
1222 r->count = num_entries;
1224 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1225 if (!r->entries) {
1226 return NT_STATUS_NO_MEMORY;
1229 for (i = 0; i < num_entries ; i++) {
1231 init_lsa_String(&r->entries[i].account_name,
1232 entries[i].account_name);
1234 init_lsa_String(&r->entries[i].description,
1235 entries[i].description);
1237 init_lsa_String(&r->entries[i].full_name,
1238 entries[i].fullname);
1240 r->entries[i].rid = entries[i].rid;
1241 r->entries[i].acct_flags = entries[i].acct_flags;
1242 r->entries[i].idx = start_idx+i+1;
1245 return NT_STATUS_OK;
1248 /*******************************************************************
1249 inits a samr_DispInfoFull structure.
1250 ********************************************************************/
1252 static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
1253 struct samr_DispInfoFull *r,
1254 uint32_t num_entries,
1255 uint32_t start_idx,
1256 struct samr_displayentry *entries)
1258 uint32_t i;
1260 DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1262 if (num_entries == 0) {
1263 return NT_STATUS_OK;
1266 r->count = num_entries;
1268 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1269 if (!r->entries) {
1270 return NT_STATUS_NO_MEMORY;
1273 for (i = 0; i < num_entries ; i++) {
1275 init_lsa_String(&r->entries[i].account_name,
1276 entries[i].account_name);
1278 init_lsa_String(&r->entries[i].description,
1279 entries[i].description);
1281 r->entries[i].rid = entries[i].rid;
1282 r->entries[i].acct_flags = entries[i].acct_flags;
1283 r->entries[i].idx = start_idx+i+1;
1286 return NT_STATUS_OK;
1289 /*******************************************************************
1290 inits a samr_DispInfoFullGroups structure.
1291 ********************************************************************/
1293 static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
1294 struct samr_DispInfoFullGroups *r,
1295 uint32_t num_entries,
1296 uint32_t start_idx,
1297 struct samr_displayentry *entries)
1299 uint32_t i;
1301 DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1303 if (num_entries == 0) {
1304 return NT_STATUS_OK;
1307 r->count = num_entries;
1309 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1310 if (!r->entries) {
1311 return NT_STATUS_NO_MEMORY;
1314 for (i = 0; i < num_entries ; i++) {
1316 init_lsa_String(&r->entries[i].account_name,
1317 entries[i].account_name);
1319 init_lsa_String(&r->entries[i].description,
1320 entries[i].description);
1322 r->entries[i].rid = entries[i].rid;
1323 r->entries[i].acct_flags = entries[i].acct_flags;
1324 r->entries[i].idx = start_idx+i+1;
1327 return NT_STATUS_OK;
1330 /*******************************************************************
1331 inits a samr_DispInfoAscii structure.
1332 ********************************************************************/
1334 static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
1335 struct samr_DispInfoAscii *r,
1336 uint32_t num_entries,
1337 uint32_t start_idx,
1338 struct samr_displayentry *entries)
1340 uint32_t i;
1342 DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1344 if (num_entries == 0) {
1345 return NT_STATUS_OK;
1348 r->count = num_entries;
1350 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1351 if (!r->entries) {
1352 return NT_STATUS_NO_MEMORY;
1355 for (i = 0; i < num_entries ; i++) {
1357 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1358 entries[i].account_name);
1360 r->entries[i].idx = start_idx+i+1;
1363 return NT_STATUS_OK;
1366 /*******************************************************************
1367 inits a samr_DispInfoAscii structure.
1368 ********************************************************************/
1370 static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
1371 struct samr_DispInfoAscii *r,
1372 uint32_t num_entries,
1373 uint32_t start_idx,
1374 struct samr_displayentry *entries)
1376 uint32_t i;
1378 DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1380 if (num_entries == 0) {
1381 return NT_STATUS_OK;
1384 r->count = num_entries;
1386 r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1387 if (!r->entries) {
1388 return NT_STATUS_NO_MEMORY;
1391 for (i = 0; i < num_entries ; i++) {
1393 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1394 entries[i].account_name);
1396 r->entries[i].idx = start_idx+i+1;
1399 return NT_STATUS_OK;
1402 /*******************************************************************
1403 _samr_QueryDisplayInfo
1404 ********************************************************************/
1406 NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1407 struct samr_QueryDisplayInfo *r)
1409 NTSTATUS status;
1410 struct samr_info *info = NULL;
1411 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1413 uint32 max_entries = r->in.max_entries;
1414 uint32 enum_context = r->in.start_idx;
1415 uint32 max_size = r->in.buf_size;
1417 union samr_DispInfo *disp_info = r->out.info;
1419 uint32 temp_size=0, total_data_size=0;
1420 NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1421 uint32 num_account = 0;
1422 enum remote_arch_types ra_type = get_remote_arch();
1423 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1424 struct samr_displayentry *entries = NULL;
1426 DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1428 /* find the policy handle. open a policy on it. */
1429 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
1430 return NT_STATUS_INVALID_HANDLE;
1433 * calculate how many entries we will return.
1434 * based on
1435 * - the number of entries the client asked
1436 * - our limit on that
1437 * - the starting point (enumeration context)
1438 * - the buffer size the client will accept
1442 * We are a lot more like W2K. Instead of reading the SAM
1443 * each time to find the records we need to send back,
1444 * we read it once and link that copy to the sam handle.
1445 * For large user list (over the MAX_SAM_ENTRIES)
1446 * it's a definitive win.
1447 * second point to notice: between enumerations
1448 * our sam is now the same as it's a snapshoot.
1449 * third point: got rid of the static SAM_USER_21 struct
1450 * no more intermediate.
1451 * con: it uses much more memory, as a full copy is stored
1452 * in memory.
1454 * If you want to change it, think twice and think
1455 * of the second point , that's really important.
1457 * JFM, 12/20/2001
1460 if ((r->in.level < 1) || (r->in.level > 5)) {
1461 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1462 (unsigned int)r->in.level ));
1463 return NT_STATUS_INVALID_INFO_CLASS;
1466 /* first limit the number of entries we will return */
1467 if(max_entries > max_sam_entries) {
1468 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1469 "entries, limiting to %d\n", max_entries,
1470 max_sam_entries));
1471 max_entries = max_sam_entries;
1474 /* calculate the size and limit on the number of entries we will
1475 * return */
1477 temp_size=max_entries*struct_size;
1479 if (temp_size>max_size) {
1480 max_entries=MIN((max_size/struct_size),max_entries);;
1481 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1482 "only %d entries\n", max_entries));
1485 become_root();
1487 /* THe following done as ROOT. Don't return without unbecome_root(). */
1489 switch (r->in.level) {
1490 case 0x1:
1491 case 0x4:
1492 if (info->disp_info->users == NULL) {
1493 info->disp_info->users = pdb_search_users(ACB_NORMAL);
1494 if (info->disp_info->users == NULL) {
1495 unbecome_root();
1496 return NT_STATUS_ACCESS_DENIED;
1498 DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1499 (unsigned int)enum_context ));
1500 } else {
1501 DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1502 (unsigned int)enum_context ));
1505 num_account = pdb_search_entries(info->disp_info->users,
1506 enum_context, max_entries,
1507 &entries);
1508 break;
1509 case 0x2:
1510 if (info->disp_info->machines == NULL) {
1511 info->disp_info->machines =
1512 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1513 if (info->disp_info->machines == NULL) {
1514 unbecome_root();
1515 return NT_STATUS_ACCESS_DENIED;
1517 DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1518 (unsigned int)enum_context ));
1519 } else {
1520 DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1521 (unsigned int)enum_context ));
1524 num_account = pdb_search_entries(info->disp_info->machines,
1525 enum_context, max_entries,
1526 &entries);
1527 break;
1528 case 0x3:
1529 case 0x5:
1530 if (info->disp_info->groups == NULL) {
1531 info->disp_info->groups = pdb_search_groups();
1532 if (info->disp_info->groups == NULL) {
1533 unbecome_root();
1534 return NT_STATUS_ACCESS_DENIED;
1536 DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1537 (unsigned int)enum_context ));
1538 } else {
1539 DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1540 (unsigned int)enum_context ));
1543 num_account = pdb_search_entries(info->disp_info->groups,
1544 enum_context, max_entries,
1545 &entries);
1546 break;
1547 default:
1548 unbecome_root();
1549 smb_panic("info class changed");
1550 break;
1552 unbecome_root();
1555 /* Now create reply structure */
1556 switch (r->in.level) {
1557 case 0x1:
1558 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1559 num_account, enum_context,
1560 entries);
1561 break;
1562 case 0x2:
1563 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1564 num_account, enum_context,
1565 entries);
1566 break;
1567 case 0x3:
1568 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1569 num_account, enum_context,
1570 entries);
1571 break;
1572 case 0x4:
1573 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1574 num_account, enum_context,
1575 entries);
1576 break;
1577 case 0x5:
1578 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1579 num_account, enum_context,
1580 entries);
1581 break;
1582 default:
1583 smb_panic("info class changed");
1584 break;
1587 if (!NT_STATUS_IS_OK(disp_ret))
1588 return disp_ret;
1590 /* calculate the total size */
1591 total_data_size=num_account*struct_size;
1593 if (num_account) {
1594 status = STATUS_MORE_ENTRIES;
1595 } else {
1596 status = NT_STATUS_OK;
1599 /* Ensure we cache this enumeration. */
1600 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1602 DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1604 *r->out.total_size = total_data_size;
1605 *r->out.returned_size = temp_size;
1607 return status;
1610 /****************************************************************
1611 _samr_QueryDisplayInfo2
1612 ****************************************************************/
1614 NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1615 struct samr_QueryDisplayInfo2 *r)
1617 struct samr_QueryDisplayInfo q;
1619 q.in.domain_handle = r->in.domain_handle;
1620 q.in.level = r->in.level;
1621 q.in.start_idx = r->in.start_idx;
1622 q.in.max_entries = r->in.max_entries;
1623 q.in.buf_size = r->in.buf_size;
1625 q.out.total_size = r->out.total_size;
1626 q.out.returned_size = r->out.returned_size;
1627 q.out.info = r->out.info;
1629 return _samr_QueryDisplayInfo(p, &q);
1632 /****************************************************************
1633 _samr_QueryDisplayInfo3
1634 ****************************************************************/
1636 NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1637 struct samr_QueryDisplayInfo3 *r)
1639 struct samr_QueryDisplayInfo q;
1641 q.in.domain_handle = r->in.domain_handle;
1642 q.in.level = r->in.level;
1643 q.in.start_idx = r->in.start_idx;
1644 q.in.max_entries = r->in.max_entries;
1645 q.in.buf_size = r->in.buf_size;
1647 q.out.total_size = r->out.total_size;
1648 q.out.returned_size = r->out.returned_size;
1649 q.out.info = r->out.info;
1651 return _samr_QueryDisplayInfo(p, &q);
1654 /*******************************************************************
1655 _samr_QueryAliasInfo
1656 ********************************************************************/
1658 NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1659 struct samr_QueryAliasInfo *r)
1661 DOM_SID sid;
1662 struct acct_info info;
1663 uint32 acc_granted;
1664 NTSTATUS status;
1665 union samr_AliasInfo *alias_info = NULL;
1666 const char *alias_name = NULL;
1667 const char *alias_description = NULL;
1669 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1671 alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1672 if (!alias_info) {
1673 return NT_STATUS_NO_MEMORY;
1676 /* find the policy handle. open a policy on it. */
1677 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &sid, &acc_granted, NULL))
1678 return NT_STATUS_INVALID_HANDLE;
1680 status = access_check_samr_function(acc_granted,
1681 SA_RIGHT_ALIAS_LOOKUP_INFO,
1682 "_samr_QueryAliasInfo");
1683 if (!NT_STATUS_IS_OK(status)) {
1684 return status;
1687 become_root();
1688 status = pdb_get_aliasinfo(&sid, &info);
1689 unbecome_root();
1691 if ( !NT_STATUS_IS_OK(status))
1692 return status;
1694 /* FIXME: info contains fstrings */
1695 alias_name = talloc_strdup(r, info.acct_name);
1696 alias_description = talloc_strdup(r, info.acct_desc);
1698 switch (r->in.level) {
1699 case ALIASINFOALL:
1700 init_samr_alias_info1(&alias_info->all,
1701 alias_name,
1703 alias_description);
1704 break;
1705 case ALIASINFODESCRIPTION:
1706 init_samr_alias_info3(&alias_info->description,
1707 alias_description);
1708 break;
1709 default:
1710 return NT_STATUS_INVALID_INFO_CLASS;
1713 *r->out.info = alias_info;
1715 DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1717 return NT_STATUS_OK;
1720 #if 0
1721 /*******************************************************************
1722 samr_reply_lookup_ids
1723 ********************************************************************/
1725 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1727 uint32 rid[MAX_SAM_ENTRIES];
1728 int num_rids = q_u->num_sids1;
1730 r_u->status = NT_STATUS_OK;
1732 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1734 if (num_rids > MAX_SAM_ENTRIES) {
1735 num_rids = MAX_SAM_ENTRIES;
1736 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1739 #if 0
1740 int i;
1741 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1743 for (i = 0; i < num_rids && status == 0; i++)
1745 struct sam_passwd *sam_pass;
1746 fstring user_name;
1749 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1750 q_u->uni_user_name[i].uni_str_len));
1752 /* find the user account */
1753 become_root();
1754 sam_pass = get_smb21pwd_entry(user_name, 0);
1755 unbecome_root();
1757 if (sam_pass == NULL)
1759 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1760 rid[i] = 0;
1762 else
1764 rid[i] = sam_pass->user_rid;
1767 #endif
1769 num_rids = 1;
1770 rid[0] = BUILTIN_ALIAS_RID_USERS;
1772 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1774 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1776 return r_u->status;
1778 #endif
1780 /*******************************************************************
1781 _samr_LookupNames
1782 ********************************************************************/
1784 NTSTATUS _samr_LookupNames(pipes_struct *p,
1785 struct samr_LookupNames *r)
1787 NTSTATUS status;
1788 uint32 *rid;
1789 enum lsa_SidType *type;
1790 int i;
1791 int num_rids = r->in.num_names;
1792 DOM_SID pol_sid;
1793 uint32 acc_granted;
1794 struct samr_Ids rids, types;
1796 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1798 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
1799 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1802 status = access_check_samr_function(acc_granted,
1803 0, /* Don't know the acc_bits yet */
1804 "_samr_LookupNames");
1805 if (!NT_STATUS_IS_OK(status)) {
1806 return status;
1809 if (num_rids > MAX_SAM_ENTRIES) {
1810 num_rids = MAX_SAM_ENTRIES;
1811 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1814 rid = talloc_array(p->mem_ctx, uint32, num_rids);
1815 NT_STATUS_HAVE_NO_MEMORY(rid);
1817 type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1818 NT_STATUS_HAVE_NO_MEMORY(type);
1820 DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1821 sid_string_dbg(&pol_sid)));
1823 for (i = 0; i < num_rids; i++) {
1825 status = NT_STATUS_NONE_MAPPED;
1826 type[i] = SID_NAME_UNKNOWN;
1828 rid[i] = 0xffffffff;
1830 if (sid_check_is_builtin(&pol_sid)) {
1831 if (lookup_builtin_name(r->in.names[i].string,
1832 &rid[i]))
1834 type[i] = SID_NAME_ALIAS;
1836 } else {
1837 lookup_global_sam_name(r->in.names[i].string, 0,
1838 &rid[i], &type[i]);
1841 if (type[i] != SID_NAME_UNKNOWN) {
1842 status = NT_STATUS_OK;
1846 rids.count = num_rids;
1847 rids.ids = rid;
1849 types.count = num_rids;
1850 types.ids = type;
1852 *r->out.rids = rids;
1853 *r->out.types = types;
1855 DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1857 return status;
1860 /*******************************************************************
1861 _samr_ChangePasswordUser2
1862 ********************************************************************/
1864 NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1865 struct samr_ChangePasswordUser2 *r)
1867 NTSTATUS status;
1868 fstring user_name;
1869 fstring wks;
1871 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1873 fstrcpy(user_name, r->in.account->string);
1874 fstrcpy(wks, r->in.server->string);
1876 DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1879 * Pass the user through the NT -> unix user mapping
1880 * function.
1883 (void)map_username(user_name);
1886 * UNIX username case mangling not required, pass_oem_change
1887 * is case insensitive.
1890 status = pass_oem_change(user_name,
1891 r->in.lm_password->data,
1892 r->in.lm_verifier->hash,
1893 r->in.nt_password->data,
1894 r->in.nt_verifier->hash,
1895 NULL);
1897 DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1899 return status;
1902 /*******************************************************************
1903 _samr_ChangePasswordUser3
1904 ********************************************************************/
1906 NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
1907 struct samr_ChangePasswordUser3 *r)
1909 NTSTATUS status;
1910 fstring user_name;
1911 const char *wks = NULL;
1912 uint32 reject_reason;
1913 struct samr_DomInfo1 *dominfo = NULL;
1914 struct samr_ChangeReject *reject = NULL;
1916 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
1918 fstrcpy(user_name, r->in.account->string);
1919 if (r->in.server && r->in.server->string) {
1920 wks = r->in.server->string;
1923 DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
1926 * Pass the user through the NT -> unix user mapping
1927 * function.
1930 (void)map_username(user_name);
1933 * UNIX username case mangling not required, pass_oem_change
1934 * is case insensitive.
1937 status = pass_oem_change(user_name,
1938 r->in.lm_password->data,
1939 r->in.lm_verifier->hash,
1940 r->in.nt_password->data,
1941 r->in.nt_verifier->hash,
1942 &reject_reason);
1944 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
1945 NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1947 uint32 min_pass_len,pass_hist,password_properties;
1948 time_t u_expire, u_min_age;
1949 NTTIME nt_expire, nt_min_age;
1950 uint32 account_policy_temp;
1952 dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
1953 if (!dominfo) {
1954 return NT_STATUS_NO_MEMORY;
1957 reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
1958 if (!reject) {
1959 return NT_STATUS_NO_MEMORY;
1962 become_root();
1964 /* AS ROOT !!! */
1966 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1967 min_pass_len = account_policy_temp;
1969 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1970 pass_hist = account_policy_temp;
1972 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1973 password_properties = account_policy_temp;
1975 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1976 u_expire = account_policy_temp;
1978 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1979 u_min_age = account_policy_temp;
1981 /* !AS ROOT */
1983 unbecome_root();
1985 unix_to_nt_time_abs(&nt_expire, u_expire);
1986 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1988 if (lp_check_password_script() && *lp_check_password_script()) {
1989 password_properties |= DOMAIN_PASSWORD_COMPLEX;
1992 init_samr_DomInfo1(dominfo,
1993 min_pass_len,
1994 pass_hist,
1995 password_properties,
1996 u_expire,
1997 u_min_age);
1999 reject->reason = reject_reason;
2001 *r->out.dominfo = dominfo;
2002 *r->out.reject = reject;
2005 DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2007 return status;
2010 /*******************************************************************
2011 makes a SAMR_R_LOOKUP_RIDS structure.
2012 ********************************************************************/
2014 static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2015 const char **names,
2016 struct lsa_String **lsa_name_array_p)
2018 struct lsa_String *lsa_name_array = NULL;
2019 uint32_t i;
2021 *lsa_name_array_p = NULL;
2023 if (num_names != 0) {
2024 lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2025 if (!lsa_name_array) {
2026 return false;
2030 for (i = 0; i < num_names; i++) {
2031 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2032 init_lsa_String(&lsa_name_array[i], names[i]);
2035 *lsa_name_array_p = lsa_name_array;
2037 return true;
2040 /*******************************************************************
2041 _samr_LookupRids
2042 ********************************************************************/
2044 NTSTATUS _samr_LookupRids(pipes_struct *p,
2045 struct samr_LookupRids *r)
2047 NTSTATUS status;
2048 const char **names;
2049 enum lsa_SidType *attrs = NULL;
2050 uint32 *wire_attrs = NULL;
2051 DOM_SID pol_sid;
2052 int num_rids = (int)r->in.num_rids;
2053 uint32 acc_granted;
2054 int i;
2055 struct lsa_Strings names_array;
2056 struct samr_Ids types_array;
2057 struct lsa_String *lsa_names = NULL;
2059 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2061 /* find the policy handle. open a policy on it. */
2062 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
2063 return NT_STATUS_INVALID_HANDLE;
2065 if (num_rids > 1000) {
2066 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2067 "to samba4 idl this is not possible\n", num_rids));
2068 return NT_STATUS_UNSUCCESSFUL;
2071 if (num_rids) {
2072 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2073 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2074 wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2076 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2077 return NT_STATUS_NO_MEMORY;
2078 } else {
2079 names = NULL;
2080 attrs = NULL;
2081 wire_attrs = NULL;
2084 become_root(); /* lookup_sid can require root privs */
2085 status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
2086 names, attrs);
2087 unbecome_root();
2089 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2090 status = NT_STATUS_OK;
2093 if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2094 &lsa_names)) {
2095 return NT_STATUS_NO_MEMORY;
2098 /* Convert from enum lsa_SidType to uint32 for wire format. */
2099 for (i = 0; i < num_rids; i++) {
2100 wire_attrs[i] = (uint32)attrs[i];
2103 names_array.count = num_rids;
2104 names_array.names = lsa_names;
2106 types_array.count = num_rids;
2107 types_array.ids = wire_attrs;
2109 *r->out.names = names_array;
2110 *r->out.types = types_array;
2112 DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2114 return status;
2117 /*******************************************************************
2118 _samr_OpenUser
2119 ********************************************************************/
2121 NTSTATUS _samr_OpenUser(pipes_struct *p,
2122 struct samr_OpenUser *r)
2124 struct samu *sampass=NULL;
2125 DOM_SID sid;
2126 POLICY_HND domain_pol = *r->in.domain_handle;
2127 POLICY_HND *user_pol = r->out.user_handle;
2128 struct samr_info *info = NULL;
2129 SEC_DESC *psd = NULL;
2130 uint32 acc_granted;
2131 uint32 des_access = r->in.access_mask;
2132 size_t sd_size;
2133 bool ret;
2134 NTSTATUS nt_status;
2135 SE_PRIV se_rights;
2137 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
2139 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
2140 return NT_STATUS_INVALID_HANDLE;
2142 nt_status = access_check_samr_function(acc_granted,
2143 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
2144 "_samr_OpenUser" );
2146 if ( !NT_STATUS_IS_OK(nt_status) )
2147 return nt_status;
2149 if ( !(sampass = samu_new( p->mem_ctx )) ) {
2150 return NT_STATUS_NO_MEMORY;
2153 /* append the user's RID to it */
2155 if (!sid_append_rid(&sid, r->in.rid))
2156 return NT_STATUS_NO_SUCH_USER;
2158 /* check if access can be granted as requested by client. */
2160 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2161 se_map_generic(&des_access, &usr_generic_mapping);
2163 se_priv_copy( &se_rights, &se_machine_account );
2164 se_priv_add( &se_rights, &se_add_users );
2166 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2167 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2168 &acc_granted, "_samr_OpenUser");
2170 if ( !NT_STATUS_IS_OK(nt_status) )
2171 return nt_status;
2173 become_root();
2174 ret=pdb_getsampwsid(sampass, &sid);
2175 unbecome_root();
2177 /* check that the SID exists in our domain. */
2178 if (ret == False) {
2179 return NT_STATUS_NO_SUCH_USER;
2182 TALLOC_FREE(sampass);
2184 /* associate the user's SID and access bits with the new handle. */
2185 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2186 return NT_STATUS_NO_MEMORY;
2187 info->acc_granted = acc_granted;
2189 /* get a (unique) handle. open a policy on it. */
2190 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
2191 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2193 return NT_STATUS_OK;
2196 /*************************************************************************
2197 *************************************************************************/
2199 static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2200 DATA_BLOB *blob,
2201 struct lsa_BinaryString **_r)
2203 struct lsa_BinaryString *r;
2205 if (!blob || !_r) {
2206 return NT_STATUS_INVALID_PARAMETER;
2209 r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2210 if (!r) {
2211 return NT_STATUS_NO_MEMORY;
2214 r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2215 if (!r->array) {
2216 return NT_STATUS_NO_MEMORY;
2218 memcpy(r->array, blob->data, blob->length);
2219 r->size = blob->length;
2220 r->length = blob->length;
2222 if (!r->array) {
2223 return NT_STATUS_NO_MEMORY;
2226 *_r = r;
2228 return NT_STATUS_OK;
2231 /*************************************************************************
2232 get_user_info_7. Safe. Only gives out account_name.
2233 *************************************************************************/
2235 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2236 struct samr_UserInfo7 *r,
2237 DOM_SID *user_sid)
2239 struct samu *smbpass=NULL;
2240 bool ret;
2241 const char *account_name = NULL;
2243 ZERO_STRUCTP(r);
2245 if ( !(smbpass = samu_new( mem_ctx )) ) {
2246 return NT_STATUS_NO_MEMORY;
2249 become_root();
2250 ret = pdb_getsampwsid(smbpass, user_sid);
2251 unbecome_root();
2253 if ( !ret ) {
2254 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2255 return NT_STATUS_NO_SUCH_USER;
2258 account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2259 if (!account_name) {
2260 TALLOC_FREE(smbpass);
2261 return NT_STATUS_NO_MEMORY;
2263 TALLOC_FREE(smbpass);
2265 DEBUG(3,("User:[%s]\n", account_name));
2267 init_samr_user_info7(r, account_name);
2269 return NT_STATUS_OK;
2272 /*************************************************************************
2273 get_user_info_9. Only gives out primary group SID.
2274 *************************************************************************/
2276 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2277 struct samr_UserInfo9 *r,
2278 DOM_SID *user_sid)
2280 struct samu *smbpass=NULL;
2281 bool ret;
2283 ZERO_STRUCTP(r);
2285 if ( !(smbpass = samu_new( mem_ctx )) ) {
2286 return NT_STATUS_NO_MEMORY;
2289 become_root();
2290 ret = pdb_getsampwsid(smbpass, user_sid);
2291 unbecome_root();
2293 if (ret==False) {
2294 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2295 TALLOC_FREE(smbpass);
2296 return NT_STATUS_NO_SUCH_USER;
2299 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2301 init_samr_user_info9(r, pdb_get_group_rid(smbpass));
2303 TALLOC_FREE(smbpass);
2305 return NT_STATUS_OK;
2308 /*************************************************************************
2309 get_user_info_16. Safe. Only gives out acb bits.
2310 *************************************************************************/
2312 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2313 struct samr_UserInfo16 *r,
2314 DOM_SID *user_sid)
2316 struct samu *smbpass=NULL;
2317 bool ret;
2319 ZERO_STRUCTP(r);
2321 if ( !(smbpass = samu_new( mem_ctx )) ) {
2322 return NT_STATUS_NO_MEMORY;
2325 become_root();
2326 ret = pdb_getsampwsid(smbpass, user_sid);
2327 unbecome_root();
2329 if (ret==False) {
2330 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2331 TALLOC_FREE(smbpass);
2332 return NT_STATUS_NO_SUCH_USER;
2335 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
2337 init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
2339 TALLOC_FREE(smbpass);
2341 return NT_STATUS_OK;
2344 /*************************************************************************
2345 get_user_info_18. OK - this is the killer as it gives out password info.
2346 Ensure that this is only allowed on an encrypted connection with a root
2347 user. JRA.
2348 *************************************************************************/
2350 static NTSTATUS get_user_info_18(pipes_struct *p,
2351 TALLOC_CTX *mem_ctx,
2352 struct samr_UserInfo18 *r,
2353 DOM_SID *user_sid)
2355 struct samu *smbpass=NULL;
2356 bool ret;
2358 ZERO_STRUCTP(r);
2360 if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2361 return NT_STATUS_ACCESS_DENIED;
2364 if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
2365 return NT_STATUS_ACCESS_DENIED;
2369 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2372 if ( !(smbpass = samu_new( mem_ctx )) ) {
2373 return NT_STATUS_NO_MEMORY;
2376 ret = pdb_getsampwsid(smbpass, user_sid);
2378 if (ret == False) {
2379 DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2380 TALLOC_FREE(smbpass);
2381 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2384 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2386 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2387 TALLOC_FREE(smbpass);
2388 return NT_STATUS_ACCOUNT_DISABLED;
2391 init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass),
2392 pdb_get_nt_passwd(smbpass));
2394 TALLOC_FREE(smbpass);
2396 return NT_STATUS_OK;
2399 /*************************************************************************
2400 get_user_info_20
2401 *************************************************************************/
2403 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2404 struct samr_UserInfo20 *r,
2405 DOM_SID *user_sid)
2407 struct samu *sampass=NULL;
2408 bool ret;
2409 const char *munged_dial = NULL;
2410 DATA_BLOB blob;
2411 NTSTATUS status;
2412 struct lsa_BinaryString *parameters = NULL;
2414 ZERO_STRUCTP(r);
2416 if ( !(sampass = samu_new( mem_ctx )) ) {
2417 return NT_STATUS_NO_MEMORY;
2420 become_root();
2421 ret = pdb_getsampwsid(sampass, user_sid);
2422 unbecome_root();
2424 if (ret == False) {
2425 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2426 TALLOC_FREE(sampass);
2427 return NT_STATUS_NO_SUCH_USER;
2430 munged_dial = pdb_get_munged_dial(sampass);
2432 samr_clear_sam_passwd(sampass);
2434 DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2435 munged_dial, (int)strlen(munged_dial)));
2437 if (munged_dial) {
2438 blob = base64_decode_data_blob(munged_dial);
2439 } else {
2440 blob = data_blob_string_const_null("");
2443 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2444 data_blob_free(&blob);
2445 TALLOC_FREE(sampass);
2446 if (!NT_STATUS_IS_OK(status)) {
2447 return status;
2450 init_samr_user_info20(r, parameters);
2452 return NT_STATUS_OK;
2456 /*************************************************************************
2457 get_user_info_21
2458 *************************************************************************/
2460 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2461 struct samr_UserInfo21 *r,
2462 DOM_SID *user_sid,
2463 DOM_SID *domain_sid)
2465 NTSTATUS status;
2466 struct samu *pw = NULL;
2467 bool ret;
2468 const DOM_SID *sid_user, *sid_group;
2469 uint32_t rid, primary_gid;
2470 NTTIME last_logon, last_logoff, last_password_change,
2471 acct_expiry, allow_password_change, force_password_change;
2472 time_t must_change_time;
2473 uint8_t password_expired;
2474 const char *account_name, *full_name, *home_directory, *home_drive,
2475 *logon_script, *profile_path, *description,
2476 *workstations, *comment;
2477 struct samr_LogonHours logon_hours;
2478 struct lsa_BinaryString *parameters = NULL;
2479 const char *munged_dial = NULL;
2480 DATA_BLOB blob;
2482 ZERO_STRUCTP(r);
2484 if (!(pw = samu_new(mem_ctx))) {
2485 return NT_STATUS_NO_MEMORY;
2488 become_root();
2489 ret = pdb_getsampwsid(pw, user_sid);
2490 unbecome_root();
2492 if (ret == False) {
2493 DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
2494 TALLOC_FREE(pw);
2495 return NT_STATUS_NO_SUCH_USER;
2498 samr_clear_sam_passwd(pw);
2500 DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
2502 sid_user = pdb_get_user_sid(pw);
2504 if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2505 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2506 "the domain sid %s. Failing operation.\n",
2507 pdb_get_username(pw), sid_string_dbg(sid_user),
2508 sid_string_dbg(domain_sid)));
2509 TALLOC_FREE(pw);
2510 return NT_STATUS_UNSUCCESSFUL;
2513 become_root();
2514 sid_group = pdb_get_group_sid(pw);
2515 unbecome_root();
2517 if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2518 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2519 "which conflicts with the domain sid %s. Failing operation.\n",
2520 pdb_get_username(pw), sid_string_dbg(sid_group),
2521 sid_string_dbg(domain_sid)));
2522 TALLOC_FREE(pw);
2523 return NT_STATUS_UNSUCCESSFUL;
2526 unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
2527 unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
2528 unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
2529 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
2530 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(pw));
2532 must_change_time = pdb_get_pass_must_change_time(pw);
2533 if (must_change_time == get_time_t_max()) {
2534 unix_to_nt_time_abs(&force_password_change, must_change_time);
2535 } else {
2536 unix_to_nt_time(&force_password_change, must_change_time);
2539 if (pdb_get_pass_must_change_time(pw) == 0) {
2540 password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON;
2541 } else {
2542 password_expired = 0;
2545 munged_dial = pdb_get_munged_dial(pw);
2546 if (munged_dial) {
2547 blob = base64_decode_data_blob(munged_dial);
2548 } else {
2549 blob = data_blob_string_const_null("");
2552 status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2553 data_blob_free(&blob);
2554 if (!NT_STATUS_IS_OK(status)) {
2555 TALLOC_FREE(pw);
2556 return status;
2559 account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
2560 full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2561 home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2562 home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2563 logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2564 profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2565 description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2566 workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2567 comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
2569 logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
2570 #if 0
2573 Look at a user on a real NT4 PDC with usrmgr, press
2574 'ok'. Then you will see that fields_present is set to
2575 0x08f827fa. Look at the user immediately after that again,
2576 and you will see that 0x00fffff is returned. This solves
2577 the problem that you get access denied after having looked
2578 at the user.
2579 -- Volker
2582 #endif
2584 init_samr_user_info21(r,
2585 last_logon,
2586 last_logoff,
2587 last_password_change,
2588 acct_expiry,
2589 allow_password_change,
2590 force_password_change,
2591 account_name,
2592 full_name,
2593 home_directory,
2594 home_drive,
2595 logon_script,
2596 profile_path,
2597 description,
2598 workstations,
2599 comment,
2600 parameters,
2601 rid,
2602 primary_gid,
2603 pdb_get_acct_ctrl(pw),
2604 pdb_build_fields_present(pw),
2605 logon_hours,
2606 pdb_get_bad_password_count(pw),
2607 pdb_get_logon_count(pw),
2608 0, /* country_code */
2609 0, /* code_page */
2610 0, /* nt_password_set */
2611 0, /* lm_password_set */
2612 password_expired);
2613 TALLOC_FREE(pw);
2615 return NT_STATUS_OK;
2618 /*******************************************************************
2619 _samr_QueryUserInfo
2620 ********************************************************************/
2622 NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2623 struct samr_QueryUserInfo *r)
2625 NTSTATUS status;
2626 union samr_UserInfo *user_info = NULL;
2627 struct samr_info *info = NULL;
2628 DOM_SID domain_sid;
2629 uint32 rid;
2631 /* search for the handle */
2632 if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
2633 return NT_STATUS_INVALID_HANDLE;
2635 domain_sid = info->sid;
2637 sid_split_rid(&domain_sid, &rid);
2639 if (!sid_check_is_in_our_domain(&info->sid))
2640 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2642 DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
2643 sid_string_dbg(&info->sid)));
2645 user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
2646 if (!user_info) {
2647 return NT_STATUS_NO_MEMORY;
2650 DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
2652 switch (r->in.level) {
2653 case 7:
2654 status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
2655 if (!NT_STATUS_IS_OK(status)) {
2656 return status;
2658 break;
2659 case 9:
2660 status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
2661 if (!NT_STATUS_IS_OK(status)) {
2662 return status;
2664 break;
2665 case 16:
2666 status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
2667 if (!NT_STATUS_IS_OK(status)) {
2668 return status;
2670 break;
2672 case 18:
2673 status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
2674 if (!NT_STATUS_IS_OK(status)) {
2675 return status;
2677 break;
2679 case 20:
2680 status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
2681 if (!NT_STATUS_IS_OK(status)) {
2682 return status;
2684 break;
2686 case 21:
2687 status = get_user_info_21(p->mem_ctx, &user_info->info21,
2688 &info->sid, &domain_sid);
2689 if (!NT_STATUS_IS_OK(status)) {
2690 return status;
2692 break;
2694 default:
2695 return NT_STATUS_INVALID_INFO_CLASS;
2698 *r->out.info = user_info;
2700 DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
2702 return status;
2705 /*******************************************************************
2706 _samr_GetGroupsForUser
2707 ********************************************************************/
2709 NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
2710 struct samr_GetGroupsForUser *r)
2712 struct samu *sam_pass=NULL;
2713 DOM_SID sid;
2714 DOM_SID *sids;
2715 struct samr_RidWithAttribute dom_gid;
2716 struct samr_RidWithAttribute *gids = NULL;
2717 uint32 primary_group_rid;
2718 size_t num_groups = 0;
2719 gid_t *unix_gids;
2720 size_t i, num_gids;
2721 uint32 acc_granted;
2722 bool ret;
2723 NTSTATUS result;
2724 bool success = False;
2726 struct samr_RidWithAttributeArray *rids = NULL;
2729 * from the SID in the request:
2730 * we should send back the list of DOMAIN GROUPS
2731 * the user is a member of
2733 * and only the DOMAIN GROUPS
2734 * no ALIASES !!! neither aliases of the domain
2735 * nor aliases of the builtin SID
2737 * JFM, 12/2/2001
2740 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2742 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
2743 if (!rids) {
2744 return NT_STATUS_NO_MEMORY;
2747 /* find the policy handle. open a policy on it. */
2748 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, NULL))
2749 return NT_STATUS_INVALID_HANDLE;
2751 result = access_check_samr_function(acc_granted,
2752 SA_RIGHT_USER_GET_GROUPS,
2753 "_samr_GetGroupsForUser");
2754 if (!NT_STATUS_IS_OK(result)) {
2755 return result;
2758 if (!sid_check_is_in_our_domain(&sid))
2759 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2761 if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2762 return NT_STATUS_NO_MEMORY;
2765 become_root();
2766 ret = pdb_getsampwsid(sam_pass, &sid);
2767 unbecome_root();
2769 if (!ret) {
2770 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2771 sid_string_dbg(&sid)));
2772 return NT_STATUS_NO_SUCH_USER;
2775 sids = NULL;
2777 /* make both calls inside the root block */
2778 become_root();
2779 result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2780 &sids, &unix_gids, &num_groups);
2781 if ( NT_STATUS_IS_OK(result) ) {
2782 success = sid_peek_check_rid(get_global_sam_sid(),
2783 pdb_get_group_sid(sam_pass),
2784 &primary_group_rid);
2786 unbecome_root();
2788 if (!NT_STATUS_IS_OK(result)) {
2789 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2790 sid_string_dbg(&sid)));
2791 return result;
2794 if ( !success ) {
2795 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2796 sid_string_dbg(pdb_get_group_sid(sam_pass)),
2797 pdb_get_username(sam_pass)));
2798 TALLOC_FREE(sam_pass);
2799 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2802 gids = NULL;
2803 num_gids = 0;
2805 dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2806 SE_GROUP_ENABLED);
2807 dom_gid.rid = primary_group_rid;
2808 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2810 for (i=0; i<num_groups; i++) {
2812 if (!sid_peek_check_rid(get_global_sam_sid(),
2813 &(sids[i]), &dom_gid.rid)) {
2814 DEBUG(10, ("Found sid %s not in our domain\n",
2815 sid_string_dbg(&sids[i])));
2816 continue;
2819 if (dom_gid.rid == primary_group_rid) {
2820 /* We added the primary group directly from the
2821 * sam_account. The other SIDs are unique from
2822 * enum_group_memberships */
2823 continue;
2826 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
2829 rids->count = num_gids;
2830 rids->rids = gids;
2832 *r->out.rids = rids;
2834 DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
2836 return result;
2839 /*******************************************************************
2840 samr_QueryDomainInfo_internal
2841 ********************************************************************/
2843 static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
2844 pipes_struct *p,
2845 struct policy_handle *handle,
2846 uint32_t level,
2847 union samr_DomainInfo **dom_info_ptr)
2849 NTSTATUS status = NT_STATUS_OK;
2850 struct samr_info *info = NULL;
2851 union samr_DomainInfo *dom_info;
2852 uint32 min_pass_len,pass_hist,password_properties;
2853 time_t u_expire, u_min_age;
2854 NTTIME nt_expire, nt_min_age;
2856 time_t u_lock_duration, u_reset_time;
2857 NTTIME nt_lock_duration, nt_reset_time;
2858 uint32 lockout;
2859 time_t u_logout;
2860 NTTIME nt_logout;
2862 uint32 account_policy_temp;
2864 time_t seq_num;
2865 uint32 server_role;
2867 uint32 num_users=0, num_groups=0, num_aliases=0;
2869 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
2871 dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
2872 if (!dom_info) {
2873 return NT_STATUS_NO_MEMORY;
2876 *dom_info_ptr = dom_info;
2878 /* find the policy handle. open a policy on it. */
2879 if (!find_policy_by_hnd(p, handle, (void **)(void *)&info)) {
2880 return NT_STATUS_INVALID_HANDLE;
2883 switch (level) {
2884 case 0x01:
2886 become_root();
2888 /* AS ROOT !!! */
2890 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2891 min_pass_len = account_policy_temp;
2893 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2894 pass_hist = account_policy_temp;
2896 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2897 password_properties = account_policy_temp;
2899 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2900 u_expire = account_policy_temp;
2902 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2903 u_min_age = account_policy_temp;
2905 /* !AS ROOT */
2907 unbecome_root();
2909 unix_to_nt_time_abs(&nt_expire, u_expire);
2910 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2912 init_samr_DomInfo1(&dom_info->info1,
2913 (uint16)min_pass_len,
2914 (uint16)pass_hist,
2915 password_properties,
2916 nt_expire,
2917 nt_min_age);
2918 break;
2919 case 0x02:
2921 become_root();
2923 /* AS ROOT !!! */
2925 num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2926 num_groups = count_sam_groups(info->disp_info);
2927 num_aliases = count_sam_aliases(info->disp_info);
2929 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2930 u_logout = account_policy_temp;
2932 unix_to_nt_time_abs(&nt_logout, u_logout);
2934 if (!pdb_get_seq_num(&seq_num))
2935 seq_num = time(NULL);
2937 /* !AS ROOT */
2939 unbecome_root();
2941 server_role = ROLE_DOMAIN_PDC;
2942 if (lp_server_role() == ROLE_DOMAIN_BDC)
2943 server_role = ROLE_DOMAIN_BDC;
2945 init_samr_DomInfo2(&dom_info->info2,
2946 nt_logout,
2947 lp_serverstring(),
2948 lp_workgroup(),
2949 global_myname(),
2950 seq_num,
2952 server_role,
2954 num_users,
2955 num_groups,
2956 num_aliases);
2957 break;
2958 case 0x03:
2960 become_root();
2962 /* AS ROOT !!! */
2965 uint32 ul;
2966 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2967 u_logout = (time_t)ul;
2970 /* !AS ROOT */
2972 unbecome_root();
2974 unix_to_nt_time_abs(&nt_logout, u_logout);
2976 init_samr_DomInfo3(&dom_info->info3,
2977 nt_logout);
2979 break;
2980 case 0x04:
2981 init_samr_DomInfo4(&dom_info->info4,
2982 lp_serverstring());
2983 break;
2984 case 0x05:
2985 init_samr_DomInfo5(&dom_info->info5,
2986 get_global_sam_name());
2987 break;
2988 case 0x06:
2989 /* NT returns its own name when a PDC. win2k and later
2990 * only the name of the PDC if itself is a BDC (samba4
2991 * idl) */
2992 init_samr_DomInfo6(&dom_info->info6,
2993 global_myname());
2994 break;
2995 case 0x07:
2996 server_role = ROLE_DOMAIN_PDC;
2997 if (lp_server_role() == ROLE_DOMAIN_BDC)
2998 server_role = ROLE_DOMAIN_BDC;
3000 init_samr_DomInfo7(&dom_info->info7,
3001 server_role);
3002 break;
3003 case 0x08:
3005 become_root();
3007 /* AS ROOT !!! */
3009 if (!pdb_get_seq_num(&seq_num)) {
3010 seq_num = time(NULL);
3013 /* !AS ROOT */
3015 unbecome_root();
3017 init_samr_DomInfo8(&dom_info->info8,
3018 seq_num,
3020 break;
3021 case 0x0c:
3023 become_root();
3025 /* AS ROOT !!! */
3027 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3028 u_lock_duration = account_policy_temp;
3029 if (u_lock_duration != -1) {
3030 u_lock_duration *= 60;
3033 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
3034 u_reset_time = account_policy_temp * 60;
3036 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3037 lockout = account_policy_temp;
3039 /* !AS ROOT */
3041 unbecome_root();
3043 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
3044 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
3046 init_samr_DomInfo12(&dom_info->info12,
3047 nt_lock_duration,
3048 nt_reset_time,
3049 (uint16)lockout);
3050 break;
3051 default:
3052 return NT_STATUS_INVALID_INFO_CLASS;
3055 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
3057 return status;
3060 /*******************************************************************
3061 _samr_QueryDomainInfo
3062 ********************************************************************/
3064 NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3065 struct samr_QueryDomainInfo *r)
3067 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo",
3069 r->in.domain_handle,
3070 r->in.level,
3071 r->out.info);
3074 /* W2k3 seems to use the same check for all 3 objects that can be created via
3075 * SAMR, if you try to create for example "Dialup" as an alias it says
3076 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3077 * database. */
3079 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3081 enum lsa_SidType type;
3082 bool result;
3084 DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3086 become_root();
3087 /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3088 * whether the name already exists */
3089 result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3090 NULL, NULL, NULL, &type);
3091 unbecome_root();
3093 if (!result) {
3094 DEBUG(10, ("%s does not exist, can create it\n", new_name));
3095 return NT_STATUS_OK;
3098 DEBUG(5, ("trying to create %s, exists as %s\n",
3099 new_name, sid_type_lookup(type)));
3101 if (type == SID_NAME_DOM_GRP) {
3102 return NT_STATUS_GROUP_EXISTS;
3104 if (type == SID_NAME_ALIAS) {
3105 return NT_STATUS_ALIAS_EXISTS;
3108 /* Yes, the default is NT_STATUS_USER_EXISTS */
3109 return NT_STATUS_USER_EXISTS;
3112 /*******************************************************************
3113 _samr_CreateUser2
3114 ********************************************************************/
3116 NTSTATUS _samr_CreateUser2(pipes_struct *p,
3117 struct samr_CreateUser2 *r)
3119 const char *account = NULL;
3120 DOM_SID sid;
3121 POLICY_HND dom_pol = *r->in.domain_handle;
3122 uint32_t acb_info = r->in.acct_flags;
3123 POLICY_HND *user_pol = r->out.user_handle;
3124 struct samr_info *info = NULL;
3125 NTSTATUS nt_status;
3126 uint32 acc_granted;
3127 SEC_DESC *psd;
3128 size_t sd_size;
3129 /* check this, when giving away 'add computer to domain' privs */
3130 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3131 bool can_add_account = False;
3132 SE_PRIV se_rights;
3133 DISP_INFO *disp_info = NULL;
3135 /* Get the domain SID stored in the domain policy */
3136 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
3137 &disp_info))
3138 return NT_STATUS_INVALID_HANDLE;
3140 nt_status = access_check_samr_function(acc_granted,
3141 SA_RIGHT_DOMAIN_CREATE_USER,
3142 "_samr_CreateUser2");
3143 if (!NT_STATUS_IS_OK(nt_status)) {
3144 return nt_status;
3147 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3148 acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3149 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3150 this parameter is not an account type */
3151 return NT_STATUS_INVALID_PARAMETER;
3154 account = r->in.account_name->string;
3155 if (account == NULL) {
3156 return NT_STATUS_NO_MEMORY;
3159 nt_status = can_create(p->mem_ctx, account);
3160 if (!NT_STATUS_IS_OK(nt_status)) {
3161 return nt_status;
3164 /* determine which user right we need to check based on the acb_info */
3166 if ( acb_info & ACB_WSTRUST )
3168 se_priv_copy( &se_rights, &se_machine_account );
3169 can_add_account = user_has_privileges(
3170 p->pipe_user.nt_user_token, &se_rights );
3172 /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3173 account for domain trusts and changes the ACB flags later */
3174 else if ( acb_info & ACB_NORMAL &&
3175 (account[strlen(account)-1] != '$') )
3177 se_priv_copy( &se_rights, &se_add_users );
3178 can_add_account = user_has_privileges(
3179 p->pipe_user.nt_user_token, &se_rights );
3181 else /* implicit assumption of a BDC or domain trust account here
3182 * (we already check the flags earlier) */
3184 if ( lp_enable_privileges() ) {
3185 /* only Domain Admins can add a BDC or domain trust */
3186 se_priv_copy( &se_rights, &se_priv_none );
3187 can_add_account = nt_token_check_domain_rid(
3188 p->pipe_user.nt_user_token,
3189 DOMAIN_GROUP_RID_ADMINS );
3193 DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3194 uidtoname(p->pipe_user.ut.uid),
3195 can_add_account ? "True":"False" ));
3197 /********** BEGIN Admin BLOCK **********/
3199 if ( can_add_account )
3200 become_root();
3202 nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3203 r->out.rid);
3205 if ( can_add_account )
3206 unbecome_root();
3208 /********** END Admin BLOCK **********/
3210 /* now check for failure */
3212 if ( !NT_STATUS_IS_OK(nt_status) )
3213 return nt_status;
3215 /* Get the user's SID */
3217 sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3219 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3220 &sid, SAMR_USR_RIGHTS_WRITE_PW);
3221 se_map_generic(&des_access, &usr_generic_mapping);
3223 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3224 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3225 &acc_granted, "_samr_CreateUser2");
3227 if ( !NT_STATUS_IS_OK(nt_status) ) {
3228 return nt_status;
3231 /* associate the user's SID with the new handle. */
3232 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
3233 return NT_STATUS_NO_MEMORY;
3236 ZERO_STRUCTP(info);
3237 info->sid = sid;
3238 info->acc_granted = acc_granted;
3240 /* get a (unique) handle. open a policy on it. */
3241 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
3242 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3245 /* After a "set" ensure we have no cached display info. */
3246 force_flush_samr_cache(info->disp_info);
3248 *r->out.access_granted = acc_granted;
3250 return NT_STATUS_OK;
3253 /*******************************************************************
3254 _samr_Connect
3255 ********************************************************************/
3257 NTSTATUS _samr_Connect(pipes_struct *p,
3258 struct samr_Connect *r)
3260 struct samr_info *info = NULL;
3261 uint32 des_access = r->in.access_mask;
3263 /* Access check */
3265 if (!pipe_access_check(p)) {
3266 DEBUG(3, ("access denied to _samr_Connect\n"));
3267 return NT_STATUS_ACCESS_DENIED;
3270 /* set up the SAMR connect_anon response */
3272 /* associate the user's SID with the new handle. */
3273 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3274 return NT_STATUS_NO_MEMORY;
3276 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
3277 was observed from a win98 client trying to enumerate users (when configured
3278 user level access control on shares) --jerry */
3280 if (des_access == MAXIMUM_ALLOWED_ACCESS) {
3281 /* Map to max possible knowing we're filtered below. */
3282 des_access = GENERIC_ALL_ACCESS;
3285 se_map_generic( &des_access, &sam_generic_mapping );
3286 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
3288 /* get a (unique) handle. open a policy on it. */
3289 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3290 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3292 return NT_STATUS_OK;
3295 /*******************************************************************
3296 _samr_Connect2
3297 ********************************************************************/
3299 NTSTATUS _samr_Connect2(pipes_struct *p,
3300 struct samr_Connect2 *r)
3302 struct samr_info *info = NULL;
3303 SEC_DESC *psd = NULL;
3304 uint32 acc_granted;
3305 uint32 des_access = r->in.access_mask;
3306 NTSTATUS nt_status;
3307 size_t sd_size;
3310 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3312 /* Access check */
3314 if (!pipe_access_check(p)) {
3315 DEBUG(3, ("access denied to _samr_Connect2\n"));
3316 return NT_STATUS_ACCESS_DENIED;
3319 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3320 se_map_generic(&des_access, &sam_generic_mapping);
3322 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3323 NULL, 0, des_access, &acc_granted, "_samr_Connect2");
3325 if ( !NT_STATUS_IS_OK(nt_status) )
3326 return nt_status;
3328 /* associate the user's SID and access granted with the new handle. */
3329 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3330 return NT_STATUS_NO_MEMORY;
3332 info->acc_granted = acc_granted;
3333 info->status = r->in.access_mask; /* this looks so wrong... - gd */
3335 /* get a (unique) handle. open a policy on it. */
3336 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3337 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3339 DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
3341 return nt_status;
3344 /*******************************************************************
3345 _samr_Connect4
3346 ********************************************************************/
3348 NTSTATUS _samr_Connect4(pipes_struct *p,
3349 struct samr_Connect4 *r)
3351 struct samr_info *info = NULL;
3352 SEC_DESC *psd = NULL;
3353 uint32 acc_granted;
3354 uint32 des_access = r->in.access_mask;
3355 NTSTATUS nt_status;
3356 size_t sd_size;
3359 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3361 /* Access check */
3363 if (!pipe_access_check(p)) {
3364 DEBUG(3, ("access denied to samr_Connect4\n"));
3365 return NT_STATUS_ACCESS_DENIED;
3368 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3369 se_map_generic(&des_access, &sam_generic_mapping);
3371 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3372 NULL, 0, des_access, &acc_granted, "_samr_Connect4");
3374 if ( !NT_STATUS_IS_OK(nt_status) )
3375 return nt_status;
3377 /* associate the user's SID and access granted with the new handle. */
3378 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3379 return NT_STATUS_NO_MEMORY;
3381 info->acc_granted = acc_granted;
3382 info->status = r->in.access_mask; /* ??? */
3384 /* get a (unique) handle. open a policy on it. */
3385 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3386 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3388 DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
3390 return NT_STATUS_OK;
3393 /*******************************************************************
3394 _samr_Connect5
3395 ********************************************************************/
3397 NTSTATUS _samr_Connect5(pipes_struct *p,
3398 struct samr_Connect5 *r)
3400 struct samr_info *info = NULL;
3401 SEC_DESC *psd = NULL;
3402 uint32 acc_granted;
3403 uint32 des_access = r->in.access_mask;
3404 NTSTATUS nt_status;
3405 size_t sd_size;
3406 struct samr_ConnectInfo1 info1;
3408 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3410 /* Access check */
3412 if (!pipe_access_check(p)) {
3413 DEBUG(3, ("access denied to samr_Connect5\n"));
3414 return NT_STATUS_ACCESS_DENIED;
3417 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
3418 se_map_generic(&des_access, &sam_generic_mapping);
3420 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3421 NULL, 0, des_access, &acc_granted, "_samr_Connect5");
3423 if ( !NT_STATUS_IS_OK(nt_status) )
3424 return nt_status;
3426 /* associate the user's SID and access granted with the new handle. */
3427 if ((info = get_samr_info_by_sid(NULL)) == NULL)
3428 return NT_STATUS_NO_MEMORY;
3430 info->acc_granted = acc_granted;
3431 info->status = r->in.access_mask; /* ??? */
3433 /* get a (unique) handle. open a policy on it. */
3434 if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
3435 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3437 DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
3439 info1.client_version = SAMR_CONNECT_AFTER_W2K;
3440 info1.unknown2 = 0;
3442 *r->out.level_out = 1;
3443 r->out.info_out->info1 = info1;
3445 return NT_STATUS_OK;
3448 /**********************************************************************
3449 _samr_LookupDomain
3450 **********************************************************************/
3452 NTSTATUS _samr_LookupDomain(pipes_struct *p,
3453 struct samr_LookupDomain *r)
3455 NTSTATUS status = NT_STATUS_OK;
3456 struct samr_info *info;
3457 const char *domain_name;
3458 DOM_SID *sid = NULL;
3460 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3461 return NT_STATUS_INVALID_HANDLE;
3463 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
3464 Reverted that change so we will work with RAS servers again */
3466 status = access_check_samr_function(info->acc_granted,
3467 SA_RIGHT_SAM_OPEN_DOMAIN,
3468 "_samr_LookupDomain");
3469 if (!NT_STATUS_IS_OK(status)) {
3470 return status;
3473 domain_name = r->in.domain_name->string;
3475 sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
3476 if (!sid) {
3477 return NT_STATUS_NO_MEMORY;
3480 if (strequal(domain_name, builtin_domain_name())) {
3481 sid_copy(sid, &global_sid_Builtin);
3482 } else {
3483 if (!secrets_fetch_domain_sid(domain_name, sid)) {
3484 status = NT_STATUS_NO_SUCH_DOMAIN;
3488 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
3489 sid_string_dbg(sid)));
3491 *r->out.sid = sid;
3493 return status;
3496 /**********************************************************************
3497 _samr_EnumDomains
3498 **********************************************************************/
3500 NTSTATUS _samr_EnumDomains(pipes_struct *p,
3501 struct samr_EnumDomains *r)
3503 NTSTATUS status;
3504 struct samr_info *info;
3505 uint32_t num_entries = 2;
3506 struct samr_SamEntry *entry_array = NULL;
3507 struct samr_SamArray *sam;
3509 if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
3510 return NT_STATUS_INVALID_HANDLE;
3512 status = access_check_samr_function(info->acc_granted,
3513 SA_RIGHT_SAM_ENUM_DOMAINS,
3514 "_samr_EnumDomains");
3515 if (!NT_STATUS_IS_OK(status)) {
3516 return status;
3519 sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
3520 if (!sam) {
3521 return NT_STATUS_NO_MEMORY;
3524 entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
3525 struct samr_SamEntry,
3526 num_entries);
3527 if (!entry_array) {
3528 return NT_STATUS_NO_MEMORY;
3531 entry_array[0].idx = 0;
3532 init_lsa_String(&entry_array[0].name, get_global_sam_name());
3534 entry_array[1].idx = 1;
3535 init_lsa_String(&entry_array[1].name, "Builtin");
3537 sam->count = num_entries;
3538 sam->entries = entry_array;
3540 *r->out.sam = sam;
3541 *r->out.num_entries = num_entries;
3543 return status;
3546 /*******************************************************************
3547 _samr_OpenAlias
3548 ********************************************************************/
3550 NTSTATUS _samr_OpenAlias(pipes_struct *p,
3551 struct samr_OpenAlias *r)
3553 DOM_SID sid;
3554 POLICY_HND domain_pol = *r->in.domain_handle;
3555 uint32 alias_rid = r->in.rid;
3556 POLICY_HND *alias_pol = r->out.alias_handle;
3557 struct samr_info *info = NULL;
3558 SEC_DESC *psd = NULL;
3559 uint32 acc_granted;
3560 uint32 des_access = r->in.access_mask;
3561 size_t sd_size;
3562 NTSTATUS status;
3563 SE_PRIV se_rights;
3565 /* find the domain policy and get the SID / access bits stored in the domain policy */
3567 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3568 return NT_STATUS_INVALID_HANDLE;
3570 status = access_check_samr_function(acc_granted,
3571 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
3572 "_samr_OpenAlias");
3574 if ( !NT_STATUS_IS_OK(status) )
3575 return status;
3577 /* append the alias' RID to it */
3579 if (!sid_append_rid(&sid, alias_rid))
3580 return NT_STATUS_NO_SUCH_ALIAS;
3582 /*check if access can be granted as requested by client. */
3584 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3585 se_map_generic(&des_access,&ali_generic_mapping);
3587 se_priv_copy( &se_rights, &se_add_users );
3590 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
3591 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
3592 &acc_granted, "_samr_OpenAlias");
3594 if ( !NT_STATUS_IS_OK(status) )
3595 return status;
3598 /* Check we actually have the requested alias */
3599 enum lsa_SidType type;
3600 bool result;
3601 gid_t gid;
3603 become_root();
3604 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3605 unbecome_root();
3607 if (!result || (type != SID_NAME_ALIAS)) {
3608 return NT_STATUS_NO_SUCH_ALIAS;
3611 /* make sure there is a mapping */
3613 if ( !sid_to_gid( &sid, &gid ) ) {
3614 return NT_STATUS_NO_SUCH_ALIAS;
3619 /* associate the alias SID with the new handle. */
3620 if ((info = get_samr_info_by_sid(&sid)) == NULL)
3621 return NT_STATUS_NO_MEMORY;
3623 info->acc_granted = acc_granted;
3625 /* get a (unique) handle. open a policy on it. */
3626 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3627 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3629 return NT_STATUS_OK;
3632 /*******************************************************************
3633 set_user_info_7
3634 ********************************************************************/
3636 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3637 struct samr_UserInfo7 *id7,
3638 struct samu *pwd)
3640 NTSTATUS rc;
3642 if (id7 == NULL) {
3643 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3644 TALLOC_FREE(pwd);
3645 return NT_STATUS_ACCESS_DENIED;
3648 if (!id7->account_name.string) {
3649 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3650 TALLOC_FREE(pwd);
3651 return NT_STATUS_ACCESS_DENIED;
3654 /* check to see if the new username already exists. Note: we can't
3655 reliably lock all backends, so there is potentially the
3656 possibility that a user can be created in between this check and
3657 the rename. The rename should fail, but may not get the
3658 exact same failure status code. I think this is small enough
3659 of a window for this type of operation and the results are
3660 simply that the rename fails with a slightly different status
3661 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3663 rc = can_create(mem_ctx, id7->account_name.string);
3664 if (!NT_STATUS_IS_OK(rc)) {
3665 return rc;
3668 rc = pdb_rename_sam_account(pwd, id7->account_name.string);
3670 TALLOC_FREE(pwd);
3671 return rc;
3674 /*******************************************************************
3675 set_user_info_16
3676 ********************************************************************/
3678 static bool set_user_info_16(struct samr_UserInfo16 *id16,
3679 struct samu *pwd)
3681 if (id16 == NULL) {
3682 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3683 TALLOC_FREE(pwd);
3684 return False;
3687 /* FIX ME: check if the value is really changed --metze */
3688 if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
3689 TALLOC_FREE(pwd);
3690 return False;
3693 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3694 TALLOC_FREE(pwd);
3695 return False;
3698 TALLOC_FREE(pwd);
3700 return True;
3703 /*******************************************************************
3704 set_user_info_18
3705 ********************************************************************/
3707 static bool set_user_info_18(struct samr_UserInfo18 *id18,
3708 struct samu *pwd)
3710 if (id18 == NULL) {
3711 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3712 TALLOC_FREE(pwd);
3713 return False;
3716 if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
3717 TALLOC_FREE(pwd);
3718 return False;
3720 if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
3721 TALLOC_FREE(pwd);
3722 return False;
3724 if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3725 TALLOC_FREE(pwd);
3726 return False;
3729 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3730 TALLOC_FREE(pwd);
3731 return False;
3734 TALLOC_FREE(pwd);
3735 return True;
3738 /*******************************************************************
3739 set_user_info_20
3740 ********************************************************************/
3742 static bool set_user_info_20(struct samr_UserInfo20 *id20,
3743 struct samu *pwd)
3745 if (id20 == NULL) {
3746 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3747 return False;
3750 copy_id20_to_sam_passwd(pwd, id20);
3752 /* write the change out */
3753 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3754 TALLOC_FREE(pwd);
3755 return False;
3758 TALLOC_FREE(pwd);
3760 return True;
3763 /*******************************************************************
3764 set_user_info_21
3765 ********************************************************************/
3767 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
3768 struct samr_UserInfo21 *id21,
3769 struct samu *pwd)
3771 NTSTATUS status;
3773 if (id21 == NULL) {
3774 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3775 return NT_STATUS_INVALID_PARAMETER;
3778 /* we need to separately check for an account rename first */
3780 if (id21->account_name.string &&
3781 (!strequal(id21->account_name.string, pdb_get_username(pwd))))
3784 /* check to see if the new username already exists. Note: we can't
3785 reliably lock all backends, so there is potentially the
3786 possibility that a user can be created in between this check and
3787 the rename. The rename should fail, but may not get the
3788 exact same failure status code. I think this is small enough
3789 of a window for this type of operation and the results are
3790 simply that the rename fails with a slightly different status
3791 code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3793 status = can_create(mem_ctx, id21->account_name.string);
3794 if (!NT_STATUS_IS_OK(status)) {
3795 return status;
3798 status = pdb_rename_sam_account(pwd, id21->account_name.string);
3800 if (!NT_STATUS_IS_OK(status)) {
3801 DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
3802 nt_errstr(status)));
3803 TALLOC_FREE(pwd);
3804 return status;
3807 /* set the new username so that later
3808 functions can work on the new account */
3809 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
3812 copy_id21_to_sam_passwd("INFO_21", pwd, id21);
3815 * The funny part about the previous two calls is
3816 * that pwd still has the password hashes from the
3817 * passdb entry. These have not been updated from
3818 * id21. I don't know if they need to be set. --jerry
3821 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3822 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3823 if ( !NT_STATUS_IS_OK(status) ) {
3824 return status;
3828 /* Don't worry about writing out the user account since the
3829 primary group SID is generated solely from the user's Unix
3830 primary group. */
3832 /* write the change out */
3833 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3834 TALLOC_FREE(pwd);
3835 return status;
3838 TALLOC_FREE(pwd);
3840 return NT_STATUS_OK;
3843 /*******************************************************************
3844 set_user_info_23
3845 ********************************************************************/
3847 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
3848 struct samr_UserInfo23 *id23,
3849 struct samu *pwd)
3851 char *plaintext_buf = NULL;
3852 uint32 len = 0;
3853 uint16 acct_ctrl;
3854 NTSTATUS status;
3856 if (id23 == NULL) {
3857 DEBUG(5, ("set_user_info_23: NULL id23\n"));
3858 return NT_STATUS_INVALID_PARAMETER;
3861 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
3862 pdb_get_username(pwd)));
3864 acct_ctrl = pdb_get_acct_ctrl(pwd);
3866 if (!decode_pw_buffer(mem_ctx,
3867 id23->password.data,
3868 &plaintext_buf,
3869 &len,
3870 STR_UNICODE)) {
3871 TALLOC_FREE(pwd);
3872 return NT_STATUS_INVALID_PARAMETER;
3875 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3876 TALLOC_FREE(pwd);
3877 return NT_STATUS_ACCESS_DENIED;
3880 copy_id23_to_sam_passwd(pwd, id23);
3882 /* if it's a trust account, don't update /etc/passwd */
3883 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3884 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3885 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3886 DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
3887 } else {
3888 /* update the UNIX password */
3889 if (lp_unix_password_sync() ) {
3890 struct passwd *passwd;
3891 if (pdb_get_username(pwd) == NULL) {
3892 DEBUG(1, ("chgpasswd: User without name???\n"));
3893 TALLOC_FREE(pwd);
3894 return NT_STATUS_ACCESS_DENIED;
3897 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3898 if (passwd == NULL) {
3899 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3902 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3903 TALLOC_FREE(pwd);
3904 return NT_STATUS_ACCESS_DENIED;
3906 TALLOC_FREE(passwd);
3910 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3912 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
3913 (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
3914 pwd)))) {
3915 TALLOC_FREE(pwd);
3916 return status;
3919 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
3920 TALLOC_FREE(pwd);
3921 return status;
3924 TALLOC_FREE(pwd);
3926 return NT_STATUS_OK;
3929 /*******************************************************************
3930 set_user_info_pw
3931 ********************************************************************/
3933 static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
3934 int level)
3936 uint32 len = 0;
3937 char *plaintext_buf = NULL;
3938 uint32 acct_ctrl;
3939 time_t last_set_time;
3940 enum pdb_value_state last_set_state;
3942 DEBUG(5, ("Attempting administrator password change for user %s\n",
3943 pdb_get_username(pwd)));
3945 acct_ctrl = pdb_get_acct_ctrl(pwd);
3946 /* we need to know if it's expired, because this is an admin change, not a
3947 user change, so it's still expired when we're done */
3948 last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
3949 last_set_time = pdb_get_pass_last_set_time(pwd);
3951 if (!decode_pw_buffer(talloc_tos(),
3952 pass,
3953 &plaintext_buf,
3954 &len,
3955 STR_UNICODE)) {
3956 TALLOC_FREE(pwd);
3957 return False;
3960 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
3961 TALLOC_FREE(pwd);
3962 return False;
3965 /* if it's a trust account, don't update /etc/passwd */
3966 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3967 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3968 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3969 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3970 } else {
3971 /* update the UNIX password */
3972 if (lp_unix_password_sync()) {
3973 struct passwd *passwd;
3975 if (pdb_get_username(pwd) == NULL) {
3976 DEBUG(1, ("chgpasswd: User without name???\n"));
3977 TALLOC_FREE(pwd);
3978 return False;
3981 passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
3982 if (passwd == NULL) {
3983 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3986 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3987 TALLOC_FREE(pwd);
3988 return False;
3990 TALLOC_FREE(passwd);
3994 memset(plaintext_buf, '\0', strlen(plaintext_buf));
3997 * A level 25 change does reset the pwdlastset field, a level 24
3998 * change does not. I know this is probably not the full story, but
3999 * it is needed to make XP join LDAP correctly, without it the later
4000 * auth2 check can fail with PWD_MUST_CHANGE.
4002 if (level != 25) {
4004 * restore last set time as this is an admin change, not a
4005 * user pw change
4007 pdb_set_pass_last_set_time (pwd, last_set_time,
4008 last_set_state);
4011 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4013 /* update the SAMBA password */
4014 if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
4015 TALLOC_FREE(pwd);
4016 return False;
4019 TALLOC_FREE(pwd);
4021 return True;
4024 /*******************************************************************
4025 set_user_info_25
4026 ********************************************************************/
4028 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4029 struct samr_UserInfo25 *id25,
4030 struct samu *pwd)
4032 NTSTATUS status;
4034 if (id25 == NULL) {
4035 DEBUG(5, ("set_user_info_25: NULL id25\n"));
4036 return NT_STATUS_INVALID_PARAMETER;
4039 copy_id25_to_sam_passwd(pwd, id25);
4041 /* write the change out */
4042 if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4043 TALLOC_FREE(pwd);
4044 return status;
4048 * We need to "pdb_update_sam_account" before the unix primary group
4049 * is set, because the idealx scripts would also change the
4050 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4051 * the delete explicit / add explicit, which would then fail to find
4052 * the previous primaryGroupSid value.
4055 if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4056 status = pdb_set_unix_primary_group(mem_ctx, pwd);
4057 if ( !NT_STATUS_IS_OK(status) ) {
4058 return status;
4062 /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
4063 * hereafter! */
4065 return NT_STATUS_OK;
4068 /*******************************************************************
4069 samr_SetUserInfo_internal
4070 ********************************************************************/
4072 static NTSTATUS samr_SetUserInfo_internal(const char *fn_name,
4073 pipes_struct *p,
4074 struct policy_handle *user_handle,
4075 uint16_t level,
4076 union samr_UserInfo *info)
4078 NTSTATUS status;
4079 struct samu *pwd = NULL;
4080 DOM_SID sid;
4081 POLICY_HND *pol = user_handle;
4082 uint16_t switch_value = level;
4083 uint32_t acc_granted;
4084 uint32_t acc_required;
4085 bool ret;
4086 bool has_enough_rights = False;
4087 uint32_t acb_info;
4088 DISP_INFO *disp_info = NULL;
4090 DEBUG(5,("%s: %d\n", fn_name, __LINE__));
4092 /* find the policy handle. open a policy on it. */
4093 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
4094 return NT_STATUS_INVALID_HANDLE;
4097 /* This is tricky. A WinXP domain join sets
4098 (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
4099 The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
4100 standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
4101 This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
4102 we'll use the set from the WinXP join as the basis. */
4104 switch (switch_value) {
4105 case 18:
4106 case 24:
4107 case 25:
4108 case 26:
4109 acc_required = SA_RIGHT_USER_SET_PASSWORD;
4110 break;
4111 default:
4112 acc_required = SA_RIGHT_USER_SET_PASSWORD |
4113 SA_RIGHT_USER_SET_ATTRIBUTES |
4114 SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
4115 break;
4118 status = access_check_samr_function(acc_granted,
4119 acc_required,
4120 fn_name);
4121 if (!NT_STATUS_IS_OK(status)) {
4122 return status;
4125 DEBUG(5, ("%s: sid:%s, level:%d\n",
4126 fn_name, sid_string_dbg(&sid), switch_value));
4128 if (info == NULL) {
4129 DEBUG(5, ("%s: NULL info level\n", fn_name));
4130 return NT_STATUS_INVALID_INFO_CLASS;
4133 if (!(pwd = samu_new(NULL))) {
4134 return NT_STATUS_NO_MEMORY;
4137 become_root();
4138 ret = pdb_getsampwsid(pwd, &sid);
4139 unbecome_root();
4141 if (!ret) {
4142 TALLOC_FREE(pwd);
4143 return NT_STATUS_NO_SUCH_USER;
4146 /* deal with machine password changes differently from userinfo changes */
4147 /* check to see if we have the sufficient rights */
4149 acb_info = pdb_get_acct_ctrl(pwd);
4150 if (acb_info & ACB_WSTRUST)
4151 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4152 &se_machine_account);
4153 else if (acb_info & ACB_NORMAL)
4154 has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
4155 &se_add_users);
4156 else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
4157 if (lp_enable_privileges()) {
4158 has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
4159 DOMAIN_GROUP_RID_ADMINS);
4163 DEBUG(5, ("%s: %s does%s possess sufficient rights\n",
4164 fn_name,
4165 uidtoname(p->pipe_user.ut.uid),
4166 has_enough_rights ? "" : " not"));
4168 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
4170 if (has_enough_rights) {
4171 become_root();
4174 /* ok! user info levels (lots: see MSDEV help), off we go... */
4176 switch (switch_value) {
4178 case 7:
4179 status = set_user_info_7(p->mem_ctx,
4180 &info->info7, pwd);
4181 break;
4183 case 16:
4184 if (!set_user_info_16(&info->info16, pwd)) {
4185 status = NT_STATUS_ACCESS_DENIED;
4187 break;
4189 case 18:
4190 /* Used by AS/U JRA. */
4191 if (!set_user_info_18(&info->info18, pwd)) {
4192 status = NT_STATUS_ACCESS_DENIED;
4194 break;
4196 case 20:
4197 if (!set_user_info_20(&info->info20, pwd)) {
4198 status = NT_STATUS_ACCESS_DENIED;
4200 break;
4202 case 21:
4203 status = set_user_info_21(p->mem_ctx,
4204 &info->info21, pwd);
4205 break;
4207 case 23:
4208 if (!p->server_info->user_session_key.length) {
4209 status = NT_STATUS_NO_USER_SESSION_KEY;
4211 SamOEMhashBlob(info->info23.password.data, 516,
4212 &p->server_info->user_session_key);
4214 dump_data(100, info->info23.password.data, 516);
4216 status = set_user_info_23(p->mem_ctx,
4217 &info->info23, pwd);
4218 break;
4220 case 24:
4221 if (!p->server_info->user_session_key.length) {
4222 status = NT_STATUS_NO_USER_SESSION_KEY;
4224 SamOEMhashBlob(info->info24.password.data,
4225 516,
4226 &p->server_info->user_session_key);
4228 dump_data(100, info->info24.password.data, 516);
4230 if (!set_user_info_pw(info->info24.password.data, pwd,
4231 switch_value)) {
4232 status = NT_STATUS_ACCESS_DENIED;
4234 break;
4236 case 25:
4237 if (!p->server_info->user_session_key.length) {
4238 status = NT_STATUS_NO_USER_SESSION_KEY;
4240 encode_or_decode_arc4_passwd_buffer(
4241 info->info25.password.data,
4242 &p->server_info->user_session_key);
4244 dump_data(100, info->info25.password.data, 532);
4246 status = set_user_info_25(p->mem_ctx,
4247 &info->info25, pwd);
4248 if (!NT_STATUS_IS_OK(status)) {
4249 goto done;
4251 if (!set_user_info_pw(info->info25.password.data, pwd,
4252 switch_value)) {
4253 status = NT_STATUS_ACCESS_DENIED;
4255 break;
4257 case 26:
4258 if (!p->server_info->user_session_key.length) {
4259 status = NT_STATUS_NO_USER_SESSION_KEY;
4261 encode_or_decode_arc4_passwd_buffer(
4262 info->info26.password.data,
4263 &p->server_info->user_session_key);
4265 dump_data(100, info->info26.password.data, 516);
4267 if (!set_user_info_pw(info->info26.password.data, pwd,
4268 switch_value)) {
4269 status = NT_STATUS_ACCESS_DENIED;
4271 break;
4273 default:
4274 status = NT_STATUS_INVALID_INFO_CLASS;
4277 done:
4279 if (has_enough_rights) {
4280 unbecome_root();
4283 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
4285 if (NT_STATUS_IS_OK(status)) {
4286 force_flush_samr_cache(disp_info);
4289 return status;
4292 /*******************************************************************
4293 _samr_SetUserInfo
4294 ********************************************************************/
4296 NTSTATUS _samr_SetUserInfo(pipes_struct *p,
4297 struct samr_SetUserInfo *r)
4299 return samr_SetUserInfo_internal("_samr_SetUserInfo",
4301 r->in.user_handle,
4302 r->in.level,
4303 r->in.info);
4306 /*******************************************************************
4307 _samr_SetUserInfo2
4308 ********************************************************************/
4310 NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
4311 struct samr_SetUserInfo2 *r)
4313 return samr_SetUserInfo_internal("_samr_SetUserInfo2",
4315 r->in.user_handle,
4316 r->in.level,
4317 r->in.info);
4320 /*********************************************************************
4321 _samr_GetAliasMembership
4322 *********************************************************************/
4324 NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
4325 struct samr_GetAliasMembership *r)
4327 size_t num_alias_rids;
4328 uint32 *alias_rids;
4329 struct samr_info *info = NULL;
4330 size_t i;
4332 NTSTATUS ntstatus1;
4333 NTSTATUS ntstatus2;
4335 DOM_SID *members;
4337 DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
4339 /* find the policy handle. open a policy on it. */
4340 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
4341 return NT_STATUS_INVALID_HANDLE;
4343 ntstatus1 = access_check_samr_function(info->acc_granted,
4344 SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM,
4345 "_samr_GetAliasMembership");
4346 ntstatus2 = access_check_samr_function(info->acc_granted,
4347 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
4348 "_samr_GetAliasMembership");
4350 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
4351 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
4352 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
4353 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
4357 if (!sid_check_is_domain(&info->sid) &&
4358 !sid_check_is_builtin(&info->sid))
4359 return NT_STATUS_OBJECT_TYPE_MISMATCH;
4361 if (r->in.sids->num_sids) {
4362 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
4364 if (members == NULL)
4365 return NT_STATUS_NO_MEMORY;
4366 } else {
4367 members = NULL;
4370 for (i=0; i<r->in.sids->num_sids; i++)
4371 sid_copy(&members[i], r->in.sids->sids[i].sid);
4373 alias_rids = NULL;
4374 num_alias_rids = 0;
4376 become_root();
4377 ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
4378 r->in.sids->num_sids,
4379 &alias_rids, &num_alias_rids);
4380 unbecome_root();
4382 if (!NT_STATUS_IS_OK(ntstatus1)) {
4383 return ntstatus1;
4386 r->out.rids->count = num_alias_rids;
4387 r->out.rids->ids = alias_rids;
4389 return NT_STATUS_OK;
4392 /*********************************************************************
4393 _samr_GetMembersInAlias
4394 *********************************************************************/
4396 NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
4397 struct samr_GetMembersInAlias *r)
4399 NTSTATUS status;
4400 size_t i;
4401 size_t num_sids = 0;
4402 struct lsa_SidPtr *sids = NULL;
4403 DOM_SID *pdb_sids = NULL;
4405 DOM_SID alias_sid;
4407 uint32 acc_granted;
4409 /* find the policy handle. open a policy on it. */
4410 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, NULL))
4411 return NT_STATUS_INVALID_HANDLE;
4413 status = access_check_samr_function(acc_granted,
4414 SA_RIGHT_ALIAS_GET_MEMBERS,
4415 "_samr_GetMembersInAlias");
4416 if (!NT_STATUS_IS_OK(status)) {
4417 return status;
4420 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4422 become_root();
4423 status = pdb_enum_aliasmem(&alias_sid, &pdb_sids, &num_sids);
4424 unbecome_root();
4426 if (!NT_STATUS_IS_OK(status)) {
4427 return status;
4430 if (num_sids) {
4431 sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
4432 if (sids == NULL) {
4433 TALLOC_FREE(pdb_sids);
4434 return NT_STATUS_NO_MEMORY;
4438 for (i = 0; i < num_sids; i++) {
4439 sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
4440 if (!sids[i].sid) {
4441 TALLOC_FREE(pdb_sids);
4442 return NT_STATUS_NO_MEMORY;
4446 r->out.sids->num_sids = num_sids;
4447 r->out.sids->sids = sids;
4449 TALLOC_FREE(pdb_sids);
4451 return NT_STATUS_OK;
4454 /*********************************************************************
4455 _samr_QueryGroupMember
4456 *********************************************************************/
4458 NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
4459 struct samr_QueryGroupMember *r)
4461 DOM_SID group_sid;
4462 size_t i, num_members;
4464 uint32 *rid=NULL;
4465 uint32 *attr=NULL;
4467 uint32 acc_granted;
4469 NTSTATUS status;
4470 struct samr_RidTypeArray *rids = NULL;
4472 rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
4473 if (!rids) {
4474 return NT_STATUS_NO_MEMORY;
4477 /* find the policy handle. open a policy on it. */
4478 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
4479 return NT_STATUS_INVALID_HANDLE;
4481 status = access_check_samr_function(acc_granted,
4482 SA_RIGHT_GROUP_GET_MEMBERS,
4483 "_samr_QueryGroupMember");
4484 if (!NT_STATUS_IS_OK(status)) {
4485 return status;
4488 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4490 if (!sid_check_is_in_our_domain(&group_sid)) {
4491 DEBUG(3, ("sid %s is not in our domain\n",
4492 sid_string_dbg(&group_sid)));
4493 return NT_STATUS_NO_SUCH_GROUP;
4496 DEBUG(10, ("lookup on Domain SID\n"));
4498 become_root();
4499 status = pdb_enum_group_members(p->mem_ctx, &group_sid,
4500 &rid, &num_members);
4501 unbecome_root();
4503 if (!NT_STATUS_IS_OK(status))
4504 return status;
4506 if (num_members) {
4507 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
4508 if (attr == NULL) {
4509 return NT_STATUS_NO_MEMORY;
4511 } else {
4512 attr = NULL;
4515 for (i=0; i<num_members; i++)
4516 attr[i] = SID_NAME_USER;
4518 rids->count = num_members;
4519 rids->types = attr;
4520 rids->rids = rid;
4522 *r->out.rids = rids;
4524 return NT_STATUS_OK;
4527 /*********************************************************************
4528 _samr_AddAliasMember
4529 *********************************************************************/
4531 NTSTATUS _samr_AddAliasMember(pipes_struct *p,
4532 struct samr_AddAliasMember *r)
4534 DOM_SID alias_sid;
4535 uint32 acc_granted;
4536 SE_PRIV se_rights;
4537 bool can_add_accounts;
4538 NTSTATUS status;
4539 DISP_INFO *disp_info = NULL;
4541 /* Find the policy handle. Open a policy on it. */
4542 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4543 return NT_STATUS_INVALID_HANDLE;
4545 status = access_check_samr_function(acc_granted,
4546 SA_RIGHT_ALIAS_ADD_MEMBER,
4547 "_samr_AddAliasMember");
4548 if (!NT_STATUS_IS_OK(status)) {
4549 return status;
4552 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4554 se_priv_copy( &se_rights, &se_add_users );
4555 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4557 /******** BEGIN SeAddUsers BLOCK *********/
4559 if ( can_add_accounts )
4560 become_root();
4562 status = pdb_add_aliasmem(&alias_sid, r->in.sid);
4564 if ( can_add_accounts )
4565 unbecome_root();
4567 /******** END SeAddUsers BLOCK *********/
4569 if (NT_STATUS_IS_OK(status)) {
4570 force_flush_samr_cache(disp_info);
4573 return status;
4576 /*********************************************************************
4577 _samr_DeleteAliasMember
4578 *********************************************************************/
4580 NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
4581 struct samr_DeleteAliasMember *r)
4583 DOM_SID alias_sid;
4584 uint32 acc_granted;
4585 SE_PRIV se_rights;
4586 bool can_add_accounts;
4587 NTSTATUS status;
4588 DISP_INFO *disp_info = NULL;
4590 /* Find the policy handle. Open a policy on it. */
4591 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4592 return NT_STATUS_INVALID_HANDLE;
4594 status = access_check_samr_function(acc_granted,
4595 SA_RIGHT_ALIAS_REMOVE_MEMBER,
4596 "_samr_DeleteAliasMember");
4597 if (!NT_STATUS_IS_OK(status)) {
4598 return status;
4601 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
4602 sid_string_dbg(&alias_sid)));
4604 se_priv_copy( &se_rights, &se_add_users );
4605 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4607 /******** BEGIN SeAddUsers BLOCK *********/
4609 if ( can_add_accounts )
4610 become_root();
4612 status = pdb_del_aliasmem(&alias_sid, r->in.sid);
4614 if ( can_add_accounts )
4615 unbecome_root();
4617 /******** END SeAddUsers BLOCK *********/
4619 if (NT_STATUS_IS_OK(status)) {
4620 force_flush_samr_cache(disp_info);
4623 return status;
4626 /*********************************************************************
4627 _samr_AddGroupMember
4628 *********************************************************************/
4630 NTSTATUS _samr_AddGroupMember(pipes_struct *p,
4631 struct samr_AddGroupMember *r)
4633 NTSTATUS status;
4634 DOM_SID group_sid;
4635 uint32 group_rid;
4636 uint32 acc_granted;
4637 SE_PRIV se_rights;
4638 bool can_add_accounts;
4639 DISP_INFO *disp_info = NULL;
4641 /* Find the policy handle. Open a policy on it. */
4642 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4643 return NT_STATUS_INVALID_HANDLE;
4645 status = access_check_samr_function(acc_granted,
4646 SA_RIGHT_GROUP_ADD_MEMBER,
4647 "_samr_AddGroupMember");
4648 if (!NT_STATUS_IS_OK(status)) {
4649 return status;
4652 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4654 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4655 &group_rid)) {
4656 return NT_STATUS_INVALID_HANDLE;
4659 se_priv_copy( &se_rights, &se_add_users );
4660 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4662 /******** BEGIN SeAddUsers BLOCK *********/
4664 if ( can_add_accounts )
4665 become_root();
4667 status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
4669 if ( can_add_accounts )
4670 unbecome_root();
4672 /******** END SeAddUsers BLOCK *********/
4674 force_flush_samr_cache(disp_info);
4676 return status;
4679 /*********************************************************************
4680 _samr_DeleteGroupMember
4681 *********************************************************************/
4683 NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
4684 struct samr_DeleteGroupMember *r)
4687 NTSTATUS status;
4688 DOM_SID group_sid;
4689 uint32 group_rid;
4690 uint32 acc_granted;
4691 SE_PRIV se_rights;
4692 bool can_add_accounts;
4693 DISP_INFO *disp_info = NULL;
4696 * delete the group member named r->in.rid
4697 * who is a member of the sid associated with the handle
4698 * the rid is a user's rid as the group is a domain group.
4701 /* Find the policy handle. Open a policy on it. */
4702 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4703 return NT_STATUS_INVALID_HANDLE;
4705 status = access_check_samr_function(acc_granted,
4706 SA_RIGHT_GROUP_REMOVE_MEMBER,
4707 "_samr_DeleteGroupMember");
4708 if (!NT_STATUS_IS_OK(status)) {
4709 return status;
4712 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4713 &group_rid)) {
4714 return NT_STATUS_INVALID_HANDLE;
4717 se_priv_copy( &se_rights, &se_add_users );
4718 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4720 /******** BEGIN SeAddUsers BLOCK *********/
4722 if ( can_add_accounts )
4723 become_root();
4725 status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
4727 if ( can_add_accounts )
4728 unbecome_root();
4730 /******** END SeAddUsers BLOCK *********/
4732 force_flush_samr_cache(disp_info);
4734 return status;
4737 /*********************************************************************
4738 _samr_DeleteUser
4739 *********************************************************************/
4741 NTSTATUS _samr_DeleteUser(pipes_struct *p,
4742 struct samr_DeleteUser *r)
4744 NTSTATUS status;
4745 DOM_SID user_sid;
4746 struct samu *sam_pass=NULL;
4747 uint32 acc_granted;
4748 bool can_add_accounts;
4749 uint32 acb_info;
4750 DISP_INFO *disp_info = NULL;
4751 bool ret;
4753 DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
4755 /* Find the policy handle. Open a policy on it. */
4756 if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &user_sid, &acc_granted, &disp_info))
4757 return NT_STATUS_INVALID_HANDLE;
4759 status = access_check_samr_function(acc_granted,
4760 STD_RIGHT_DELETE_ACCESS,
4761 "_samr_DeleteUser");
4762 if (!NT_STATUS_IS_OK(status)) {
4763 return status;
4766 if (!sid_check_is_in_our_domain(&user_sid))
4767 return NT_STATUS_CANNOT_DELETE;
4769 /* check if the user exists before trying to delete */
4770 if ( !(sam_pass = samu_new( NULL )) ) {
4771 return NT_STATUS_NO_MEMORY;
4774 become_root();
4775 ret = pdb_getsampwsid(sam_pass, &user_sid);
4776 unbecome_root();
4778 if( !ret ) {
4779 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
4780 sid_string_dbg(&user_sid)));
4781 TALLOC_FREE(sam_pass);
4782 return NT_STATUS_NO_SUCH_USER;
4785 acb_info = pdb_get_acct_ctrl(sam_pass);
4787 /* For machine accounts it's the SeMachineAccountPrivilege that counts. */
4788 if ( acb_info & ACB_WSTRUST ) {
4789 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
4790 } else {
4791 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
4794 /******** BEGIN SeAddUsers BLOCK *********/
4796 if ( can_add_accounts )
4797 become_root();
4799 status = pdb_delete_user(p->mem_ctx, sam_pass);
4801 if ( can_add_accounts )
4802 unbecome_root();
4804 /******** END SeAddUsers BLOCK *********/
4806 if ( !NT_STATUS_IS_OK(status) ) {
4807 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
4808 "user %s: %s.\n", pdb_get_username(sam_pass),
4809 nt_errstr(status)));
4810 TALLOC_FREE(sam_pass);
4811 return status;
4815 TALLOC_FREE(sam_pass);
4817 if (!close_policy_hnd(p, r->in.user_handle))
4818 return NT_STATUS_OBJECT_NAME_INVALID;
4820 force_flush_samr_cache(disp_info);
4822 return NT_STATUS_OK;
4825 /*********************************************************************
4826 _samr_DeleteDomainGroup
4827 *********************************************************************/
4829 NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
4830 struct samr_DeleteDomainGroup *r)
4832 NTSTATUS status;
4833 DOM_SID group_sid;
4834 uint32 group_rid;
4835 uint32 acc_granted;
4836 SE_PRIV se_rights;
4837 bool can_add_accounts;
4838 DISP_INFO *disp_info = NULL;
4840 DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
4842 /* Find the policy handle. Open a policy on it. */
4843 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
4844 return NT_STATUS_INVALID_HANDLE;
4846 status = access_check_samr_function(acc_granted,
4847 STD_RIGHT_DELETE_ACCESS,
4848 "_samr_DeleteDomainGroup");
4849 if (!NT_STATUS_IS_OK(status)) {
4850 return status;
4853 DEBUG(10, ("sid is %s\n", sid_string_dbg(&group_sid)));
4855 if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
4856 &group_rid)) {
4857 return NT_STATUS_NO_SUCH_GROUP;
4860 se_priv_copy( &se_rights, &se_add_users );
4861 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4863 /******** BEGIN SeAddUsers BLOCK *********/
4865 if ( can_add_accounts )
4866 become_root();
4868 status = pdb_delete_dom_group(p->mem_ctx, group_rid);
4870 if ( can_add_accounts )
4871 unbecome_root();
4873 /******** END SeAddUsers BLOCK *********/
4875 if ( !NT_STATUS_IS_OK(status) ) {
4876 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
4877 "entry for group %s: %s\n",
4878 sid_string_dbg(&group_sid),
4879 nt_errstr(status)));
4880 return status;
4883 if (!close_policy_hnd(p, r->in.group_handle))
4884 return NT_STATUS_OBJECT_NAME_INVALID;
4886 force_flush_samr_cache(disp_info);
4888 return NT_STATUS_OK;
4891 /*********************************************************************
4892 _samr_DeleteDomAlias
4893 *********************************************************************/
4895 NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
4896 struct samr_DeleteDomAlias *r)
4898 DOM_SID alias_sid;
4899 uint32 acc_granted;
4900 SE_PRIV se_rights;
4901 bool can_add_accounts;
4902 NTSTATUS status;
4903 DISP_INFO *disp_info = NULL;
4905 DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
4907 /* Find the policy handle. Open a policy on it. */
4908 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &alias_sid, &acc_granted, &disp_info))
4909 return NT_STATUS_INVALID_HANDLE;
4911 /* copy the handle to the outgoing reply */
4913 memcpy(r->out.alias_handle, r->in.alias_handle, sizeof(r->out.alias_handle));
4915 status = access_check_samr_function(acc_granted,
4916 STD_RIGHT_DELETE_ACCESS,
4917 "_samr_DeleteDomAlias");
4918 if (!NT_STATUS_IS_OK(status)) {
4919 return status;
4922 DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
4924 /* Don't let Windows delete builtin groups */
4926 if ( sid_check_is_in_builtin( &alias_sid ) ) {
4927 return NT_STATUS_SPECIAL_ACCOUNT;
4930 if (!sid_check_is_in_our_domain(&alias_sid))
4931 return NT_STATUS_NO_SUCH_ALIAS;
4933 DEBUG(10, ("lookup on Local SID\n"));
4935 se_priv_copy( &se_rights, &se_add_users );
4936 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4938 /******** BEGIN SeAddUsers BLOCK *********/
4940 if ( can_add_accounts )
4941 become_root();
4943 /* Have passdb delete the alias */
4944 status = pdb_delete_alias(&alias_sid);
4946 if ( can_add_accounts )
4947 unbecome_root();
4949 /******** END SeAddUsers BLOCK *********/
4951 if ( !NT_STATUS_IS_OK(status))
4952 return status;
4954 if (!close_policy_hnd(p, r->in.alias_handle))
4955 return NT_STATUS_OBJECT_NAME_INVALID;
4957 force_flush_samr_cache(disp_info);
4959 return NT_STATUS_OK;
4962 /*********************************************************************
4963 _samr_CreateDomainGroup
4964 *********************************************************************/
4966 NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
4967 struct samr_CreateDomainGroup *r)
4970 NTSTATUS status;
4971 DOM_SID dom_sid;
4972 DOM_SID info_sid;
4973 const char *name;
4974 struct samr_info *info;
4975 uint32 acc_granted;
4976 SE_PRIV se_rights;
4977 bool can_add_accounts;
4978 DISP_INFO *disp_info = NULL;
4980 /* Find the policy handle. Open a policy on it. */
4981 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
4982 return NT_STATUS_INVALID_HANDLE;
4984 status = access_check_samr_function(acc_granted,
4985 SA_RIGHT_DOMAIN_CREATE_GROUP,
4986 "_samr_CreateDomainGroup");
4987 if (!NT_STATUS_IS_OK(status)) {
4988 return status;
4991 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4992 return NT_STATUS_ACCESS_DENIED;
4994 name = r->in.name->string;
4995 if (name == NULL) {
4996 return NT_STATUS_NO_MEMORY;
4999 status = can_create(p->mem_ctx, name);
5000 if (!NT_STATUS_IS_OK(status)) {
5001 return status;
5004 se_priv_copy( &se_rights, &se_add_users );
5005 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5007 /******** BEGIN SeAddUsers BLOCK *********/
5009 if ( can_add_accounts )
5010 become_root();
5012 /* check that we successfully create the UNIX group */
5014 status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5016 if ( can_add_accounts )
5017 unbecome_root();
5019 /******** END SeAddUsers BLOCK *********/
5021 /* check if we should bail out here */
5023 if ( !NT_STATUS_IS_OK(status) )
5024 return status;
5026 sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
5028 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5029 return NT_STATUS_NO_MEMORY;
5031 /* they created it; let the user do what he wants with it */
5033 info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
5035 /* get a (unique) handle. open a policy on it. */
5036 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5037 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5039 force_flush_samr_cache(disp_info);
5041 return NT_STATUS_OK;
5044 /*********************************************************************
5045 _samr_CreateDomAlias
5046 *********************************************************************/
5048 NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5049 struct samr_CreateDomAlias *r)
5051 DOM_SID dom_sid;
5052 DOM_SID info_sid;
5053 const char *name = NULL;
5054 struct samr_info *info;
5055 uint32 acc_granted;
5056 gid_t gid;
5057 NTSTATUS result;
5058 SE_PRIV se_rights;
5059 bool can_add_accounts;
5060 DISP_INFO *disp_info = NULL;
5062 /* Find the policy handle. Open a policy on it. */
5063 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
5064 return NT_STATUS_INVALID_HANDLE;
5066 result = access_check_samr_function(acc_granted,
5067 SA_RIGHT_DOMAIN_CREATE_ALIAS,
5068 "_samr_CreateDomAlias");
5069 if (!NT_STATUS_IS_OK(result)) {
5070 return result;
5073 if (!sid_equal(&dom_sid, get_global_sam_sid()))
5074 return NT_STATUS_ACCESS_DENIED;
5076 name = r->in.alias_name->string;
5078 se_priv_copy( &se_rights, &se_add_users );
5079 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
5081 result = can_create(p->mem_ctx, name);
5082 if (!NT_STATUS_IS_OK(result)) {
5083 return result;
5086 /******** BEGIN SeAddUsers BLOCK *********/
5088 if ( can_add_accounts )
5089 become_root();
5091 /* Have passdb create the alias */
5092 result = pdb_create_alias(name, r->out.rid);
5094 if ( can_add_accounts )
5095 unbecome_root();
5097 /******** END SeAddUsers BLOCK *********/
5099 if (!NT_STATUS_IS_OK(result)) {
5100 DEBUG(10, ("pdb_create_alias failed: %s\n",
5101 nt_errstr(result)));
5102 return result;
5105 sid_copy(&info_sid, get_global_sam_sid());
5106 sid_append_rid(&info_sid, *r->out.rid);
5108 if (!sid_to_gid(&info_sid, &gid)) {
5109 DEBUG(10, ("Could not find alias just created\n"));
5110 return NT_STATUS_ACCESS_DENIED;
5113 /* check if the group has been successfully created */
5114 if ( getgrgid(gid) == NULL ) {
5115 DEBUG(10, ("getgrgid(%d) of just created alias failed\n",
5116 gid));
5117 return NT_STATUS_ACCESS_DENIED;
5120 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5121 return NT_STATUS_NO_MEMORY;
5123 /* they created it; let the user do what he wants with it */
5125 info->acc_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
5127 /* get a (unique) handle. open a policy on it. */
5128 if (!create_policy_hnd(p, r->out.alias_handle, free_samr_info, (void *)info))
5129 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5131 force_flush_samr_cache(disp_info);
5133 return NT_STATUS_OK;
5136 /*********************************************************************
5137 _samr_QueryGroupInfo
5138 *********************************************************************/
5140 NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5141 struct samr_QueryGroupInfo *r)
5143 NTSTATUS status;
5144 DOM_SID group_sid;
5145 GROUP_MAP map;
5146 union samr_GroupInfo *info = NULL;
5147 uint32 acc_granted;
5148 bool ret;
5149 uint32_t attributes = SE_GROUP_MANDATORY |
5150 SE_GROUP_ENABLED_BY_DEFAULT |
5151 SE_GROUP_ENABLED;
5152 const char *group_name = NULL;
5153 const char *group_description = NULL;
5155 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, NULL))
5156 return NT_STATUS_INVALID_HANDLE;
5158 status = access_check_samr_function(acc_granted,
5159 SA_RIGHT_GROUP_LOOKUP_INFO,
5160 "_samr_QueryGroupInfo");
5161 if (!NT_STATUS_IS_OK(status)) {
5162 return status;
5165 become_root();
5166 ret = get_domain_group_from_sid(group_sid, &map);
5167 unbecome_root();
5168 if (!ret)
5169 return NT_STATUS_INVALID_HANDLE;
5171 /* FIXME: map contains fstrings */
5172 group_name = talloc_strdup(r, map.nt_name);
5173 group_description = talloc_strdup(r, map.comment);
5175 info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5176 if (!info) {
5177 return NT_STATUS_NO_MEMORY;
5180 switch (r->in.level) {
5181 case 1: {
5182 uint32 *members;
5183 size_t num_members;
5185 become_root();
5186 status = pdb_enum_group_members(
5187 p->mem_ctx, &group_sid, &members, &num_members);
5188 unbecome_root();
5190 if (!NT_STATUS_IS_OK(status)) {
5191 return status;
5194 init_samr_group_info1(&info->all,
5195 group_name,
5196 attributes,
5197 num_members,
5198 group_description);
5199 break;
5201 case 2:
5202 init_samr_group_info2(&info->name,
5203 group_name);
5204 break;
5205 case 3:
5206 init_samr_group_info3(&info->attributes,
5207 attributes);
5208 break;
5209 case 4:
5210 init_samr_group_info4(&info->description,
5211 group_description);
5212 break;
5213 case 5: {
5215 uint32 *members;
5216 size_t num_members;
5220 become_root();
5221 status = pdb_enum_group_members(
5222 p->mem_ctx, &group_sid, &members, &num_members);
5223 unbecome_root();
5225 if (!NT_STATUS_IS_OK(status)) {
5226 return status;
5229 init_samr_group_info5(&info->all2,
5230 group_name,
5231 attributes,
5232 0, /* num_members - in w2k3 this is always 0 */
5233 group_description);
5235 break;
5237 default:
5238 return NT_STATUS_INVALID_INFO_CLASS;
5241 *r->out.info = info;
5243 return NT_STATUS_OK;
5246 /*********************************************************************
5247 _samr_SetGroupInfo
5248 *********************************************************************/
5250 NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
5251 struct samr_SetGroupInfo *r)
5253 DOM_SID group_sid;
5254 GROUP_MAP map;
5255 uint32 acc_granted;
5256 NTSTATUS status;
5257 bool ret;
5258 bool can_mod_accounts;
5259 DISP_INFO *disp_info = NULL;
5261 if (!get_lsa_policy_samr_sid(p, r->in.group_handle, &group_sid, &acc_granted, &disp_info))
5262 return NT_STATUS_INVALID_HANDLE;
5264 status = access_check_samr_function(acc_granted,
5265 SA_RIGHT_GROUP_SET_INFO,
5266 "_samr_SetGroupInfo");
5267 if (!NT_STATUS_IS_OK(status)) {
5268 return status;
5271 become_root();
5272 ret = get_domain_group_from_sid(group_sid, &map);
5273 unbecome_root();
5274 if (!ret)
5275 return NT_STATUS_NO_SUCH_GROUP;
5277 switch (r->in.level) {
5278 case 1:
5279 fstrcpy(map.comment, r->in.info->all.description.string);
5280 break;
5281 case 4:
5282 fstrcpy(map.comment, r->in.info->description.string);
5283 break;
5284 default:
5285 return NT_STATUS_INVALID_INFO_CLASS;
5288 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5290 /******** BEGIN SeAddUsers BLOCK *********/
5292 if ( can_mod_accounts )
5293 become_root();
5295 status = pdb_update_group_mapping_entry(&map);
5297 if ( can_mod_accounts )
5298 unbecome_root();
5300 /******** End SeAddUsers BLOCK *********/
5302 if (NT_STATUS_IS_OK(status)) {
5303 force_flush_samr_cache(disp_info);
5306 return status;
5309 /*********************************************************************
5310 _samr_SetAliasInfo
5311 *********************************************************************/
5313 NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
5314 struct samr_SetAliasInfo *r)
5316 DOM_SID group_sid;
5317 struct acct_info info;
5318 uint32 acc_granted;
5319 bool can_mod_accounts;
5320 NTSTATUS status;
5321 DISP_INFO *disp_info = NULL;
5323 if (!get_lsa_policy_samr_sid(p, r->in.alias_handle, &group_sid, &acc_granted, &disp_info))
5324 return NT_STATUS_INVALID_HANDLE;
5326 status = access_check_samr_function(acc_granted,
5327 SA_RIGHT_ALIAS_SET_INFO,
5328 "_samr_SetAliasInfo");
5329 if (!NT_STATUS_IS_OK(status)) {
5330 return status;
5333 /* get the current group information */
5335 become_root();
5336 status = pdb_get_aliasinfo( &group_sid, &info );
5337 unbecome_root();
5339 if ( !NT_STATUS_IS_OK(status))
5340 return status;
5342 switch (r->in.level) {
5343 case ALIASINFONAME:
5345 fstring group_name;
5347 /* We currently do not support renaming groups in the
5348 the BUILTIN domain. Refer to util_builtin.c to understand
5349 why. The eventually needs to be fixed to be like Windows
5350 where you can rename builtin groups, just not delete them */
5352 if ( sid_check_is_in_builtin( &group_sid ) ) {
5353 return NT_STATUS_SPECIAL_ACCOUNT;
5356 /* There has to be a valid name (and it has to be different) */
5358 if ( !r->in.info->name.string )
5359 return NT_STATUS_INVALID_PARAMETER;
5361 /* If the name is the same just reply "ok". Yes this
5362 doesn't allow you to change the case of a group name. */
5364 if ( strequal( r->in.info->name.string, info.acct_name ) )
5365 return NT_STATUS_OK;
5367 fstrcpy( info.acct_name, r->in.info->name.string);
5369 /* make sure the name doesn't already exist as a user
5370 or local group */
5372 fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
5373 status = can_create( p->mem_ctx, group_name );
5374 if ( !NT_STATUS_IS_OK( status ) )
5375 return status;
5376 break;
5378 case ALIASINFODESCRIPTION:
5379 if (r->in.info->description.string) {
5380 fstrcpy(info.acct_desc,
5381 r->in.info->description.string);
5382 } else {
5383 fstrcpy( info.acct_desc, "" );
5385 break;
5386 default:
5387 return NT_STATUS_INVALID_INFO_CLASS;
5390 can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
5392 /******** BEGIN SeAddUsers BLOCK *********/
5394 if ( can_mod_accounts )
5395 become_root();
5397 status = pdb_set_aliasinfo( &group_sid, &info );
5399 if ( can_mod_accounts )
5400 unbecome_root();
5402 /******** End SeAddUsers BLOCK *********/
5404 if (NT_STATUS_IS_OK(status))
5405 force_flush_samr_cache(disp_info);
5407 return status;
5410 /****************************************************************
5411 _samr_GetDomPwInfo
5412 ****************************************************************/
5414 NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
5415 struct samr_GetDomPwInfo *r)
5417 uint32_t min_password_length = 0;
5418 uint32_t password_properties = 0;
5420 /* Perform access check. Since this rpc does not require a
5421 policy handle it will not be caught by the access checks on
5422 SAMR_CONNECT or SAMR_CONNECT_ANON. */
5424 if (!pipe_access_check(p)) {
5425 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
5426 return NT_STATUS_ACCESS_DENIED;
5429 become_root();
5430 pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
5431 &min_password_length);
5432 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
5433 &password_properties);
5434 unbecome_root();
5436 if (lp_check_password_script() && *lp_check_password_script()) {
5437 password_properties |= DOMAIN_PASSWORD_COMPLEX;
5440 r->out.info->min_password_length = min_password_length;
5441 r->out.info->password_properties = password_properties;
5443 return NT_STATUS_OK;
5446 /*********************************************************************
5447 _samr_OpenGroup
5448 *********************************************************************/
5450 NTSTATUS _samr_OpenGroup(pipes_struct *p,
5451 struct samr_OpenGroup *r)
5454 DOM_SID sid;
5455 DOM_SID info_sid;
5456 GROUP_MAP map;
5457 struct samr_info *info;
5458 SEC_DESC *psd = NULL;
5459 uint32 acc_granted;
5460 uint32 des_access = r->in.access_mask;
5461 size_t sd_size;
5462 NTSTATUS status;
5463 fstring sid_string;
5464 bool ret;
5465 SE_PRIV se_rights;
5467 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
5468 return NT_STATUS_INVALID_HANDLE;
5470 status = access_check_samr_function(acc_granted,
5471 SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
5472 "_samr_OpenGroup");
5474 if ( !NT_STATUS_IS_OK(status) )
5475 return status;
5477 /*check if access can be granted as requested by client. */
5478 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
5479 se_map_generic(&des_access,&grp_generic_mapping);
5481 se_priv_copy( &se_rights, &se_add_users );
5483 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
5484 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
5485 &acc_granted, "_samr_OpenGroup");
5487 if ( !NT_STATUS_IS_OK(status) )
5488 return status;
5490 /* this should not be hard-coded like this */
5492 if (!sid_equal(&sid, get_global_sam_sid()))
5493 return NT_STATUS_ACCESS_DENIED;
5495 sid_copy(&info_sid, get_global_sam_sid());
5496 sid_append_rid(&info_sid, r->in.rid);
5497 sid_to_fstring(sid_string, &info_sid);
5499 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
5500 return NT_STATUS_NO_MEMORY;
5502 info->acc_granted = acc_granted;
5504 DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
5506 /* check if that group really exists */
5507 become_root();
5508 ret = get_domain_group_from_sid(info->sid, &map);
5509 unbecome_root();
5510 if (!ret)
5511 return NT_STATUS_NO_SUCH_GROUP;
5513 /* get a (unique) handle. open a policy on it. */
5514 if (!create_policy_hnd(p, r->out.group_handle, free_samr_info, (void *)info))
5515 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5517 return NT_STATUS_OK;
5520 /*********************************************************************
5521 _samr_RemoveMemberFromForeignDomain
5522 *********************************************************************/
5524 NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
5525 struct samr_RemoveMemberFromForeignDomain *r)
5527 DOM_SID delete_sid, domain_sid;
5528 uint32 acc_granted;
5529 NTSTATUS result;
5530 DISP_INFO *disp_info = NULL;
5532 sid_copy( &delete_sid, r->in.sid );
5534 DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
5535 sid_string_dbg(&delete_sid)));
5537 /* Find the policy handle. Open a policy on it. */
5539 if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
5540 &acc_granted, &disp_info))
5541 return NT_STATUS_INVALID_HANDLE;
5543 result = access_check_samr_function(acc_granted,
5544 STD_RIGHT_DELETE_ACCESS,
5545 "_samr_RemoveMemberFromForeignDomain");
5547 if (!NT_STATUS_IS_OK(result))
5548 return result;
5550 DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
5551 sid_string_dbg(&domain_sid)));
5553 /* we can only delete a user from a group since we don't have
5554 nested groups anyways. So in the latter case, just say OK */
5556 /* TODO: The above comment nowadays is bogus. Since we have nested
5557 * groups now, and aliases members are never reported out of the unix
5558 * group membership, the "just say OK" makes this call a no-op. For
5559 * us. This needs fixing however. */
5561 /* I've only ever seen this in the wild when deleting a user from
5562 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
5563 * is the user about to be deleted. I very much suspect this is the
5564 * only application of this call. To verify this, let people report
5565 * other cases. */
5567 if (!sid_check_is_builtin(&domain_sid)) {
5568 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
5569 "global_sam_sid() = %s\n",
5570 sid_string_dbg(&domain_sid),
5571 sid_string_dbg(get_global_sam_sid())));
5572 DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
5573 return NT_STATUS_OK;
5576 force_flush_samr_cache(disp_info);
5578 result = NT_STATUS_OK;
5580 return result;
5583 /*******************************************************************
5584 _samr_QueryDomainInfo2
5585 ********************************************************************/
5587 NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
5588 struct samr_QueryDomainInfo2 *r)
5590 return samr_QueryDomainInfo_internal("_samr_QueryDomainInfo2",
5592 r->in.domain_handle,
5593 r->in.level,
5594 r->out.info);
5597 /*******************************************************************
5598 _samr_SetDomainInfo
5599 ********************************************************************/
5601 NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
5602 struct samr_SetDomainInfo *r)
5604 time_t u_expire, u_min_age;
5605 time_t u_logout;
5606 time_t u_lock_duration, u_reset_time;
5608 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5610 /* find the policy handle. open a policy on it. */
5611 if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
5612 return NT_STATUS_INVALID_HANDLE;
5614 DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
5616 switch (r->in.level) {
5617 case 0x01:
5618 u_expire=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.max_password_age);
5619 u_min_age=nt_time_to_unix_abs((NTTIME *)&r->in.info->info1.min_password_age);
5620 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)r->in.info->info1.min_password_length);
5621 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)r->in.info->info1.password_history_length);
5622 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)r->in.info->info1.password_properties);
5623 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
5624 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
5625 break;
5626 case 0x02:
5627 break;
5628 case 0x03:
5629 u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
5630 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
5631 break;
5632 case 0x05:
5633 break;
5634 case 0x06:
5635 break;
5636 case 0x07:
5637 break;
5638 case 0x0c:
5639 u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
5640 if (u_lock_duration != -1)
5641 u_lock_duration /= 60;
5643 u_reset_time=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_window)/60;
5645 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
5646 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
5647 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)r->in.info->info12.lockout_threshold);
5648 break;
5649 default:
5650 return NT_STATUS_INVALID_INFO_CLASS;
5653 DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
5655 return NT_STATUS_OK;
5658 /****************************************************************
5659 _samr_GetDisplayEnumerationIndex
5660 ****************************************************************/
5662 NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
5663 struct samr_GetDisplayEnumerationIndex *r)
5665 struct samr_info *info = NULL;
5666 uint32_t max_entries = (uint32_t) -1;
5667 uint32_t enum_context = 0;
5668 int i;
5669 uint32_t num_account = 0;
5670 struct samr_displayentry *entries = NULL;
5672 DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
5674 /* find the policy handle. open a policy on it. */
5675 if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
5676 return NT_STATUS_INVALID_HANDLE;
5679 if ((r->in.level < 1) || (r->in.level > 3)) {
5680 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
5681 "Unknown info level (%u)\n",
5682 r->in.level));
5683 return NT_STATUS_INVALID_INFO_CLASS;
5686 become_root();
5688 /* The following done as ROOT. Don't return without unbecome_root(). */
5690 switch (r->in.level) {
5691 case 1:
5692 if (info->disp_info->users == NULL) {
5693 info->disp_info->users = pdb_search_users(ACB_NORMAL);
5694 if (info->disp_info->users == NULL) {
5695 unbecome_root();
5696 return NT_STATUS_ACCESS_DENIED;
5698 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5699 "starting user enumeration at index %u\n",
5700 (unsigned int)enum_context));
5701 } else {
5702 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5703 "using cached user enumeration at index %u\n",
5704 (unsigned int)enum_context));
5706 num_account = pdb_search_entries(info->disp_info->users,
5707 enum_context, max_entries,
5708 &entries);
5709 break;
5710 case 2:
5711 if (info->disp_info->machines == NULL) {
5712 info->disp_info->machines =
5713 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
5714 if (info->disp_info->machines == NULL) {
5715 unbecome_root();
5716 return NT_STATUS_ACCESS_DENIED;
5718 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5719 "starting machine enumeration at index %u\n",
5720 (unsigned int)enum_context));
5721 } else {
5722 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5723 "using cached machine enumeration at index %u\n",
5724 (unsigned int)enum_context));
5726 num_account = pdb_search_entries(info->disp_info->machines,
5727 enum_context, max_entries,
5728 &entries);
5729 break;
5730 case 3:
5731 if (info->disp_info->groups == NULL) {
5732 info->disp_info->groups = pdb_search_groups();
5733 if (info->disp_info->groups == NULL) {
5734 unbecome_root();
5735 return NT_STATUS_ACCESS_DENIED;
5737 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5738 "starting group enumeration at index %u\n",
5739 (unsigned int)enum_context));
5740 } else {
5741 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5742 "using cached group enumeration at index %u\n",
5743 (unsigned int)enum_context));
5745 num_account = pdb_search_entries(info->disp_info->groups,
5746 enum_context, max_entries,
5747 &entries);
5748 break;
5749 default:
5750 unbecome_root();
5751 smb_panic("info class changed");
5752 break;
5755 unbecome_root();
5757 /* Ensure we cache this enumeration. */
5758 set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
5760 DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
5761 r->in.name->string));
5763 for (i=0; i<num_account; i++) {
5764 if (strequal(entries[i].account_name, r->in.name->string)) {
5765 DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
5766 "found %s at idx %d\n",
5767 r->in.name->string, i));
5768 *r->out.idx = i;
5769 return NT_STATUS_OK;
5773 /* assuming account_name lives at the very end */
5774 *r->out.idx = num_account;
5776 return NT_STATUS_NO_MORE_ENTRIES;
5779 /****************************************************************
5780 _samr_GetDisplayEnumerationIndex2
5781 ****************************************************************/
5783 NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
5784 struct samr_GetDisplayEnumerationIndex2 *r)
5786 struct samr_GetDisplayEnumerationIndex q;
5788 q.in.domain_handle = r->in.domain_handle;
5789 q.in.level = r->in.level;
5790 q.in.name = r->in.name;
5792 q.out.idx = r->out.idx;
5794 return _samr_GetDisplayEnumerationIndex(p, &q);
5797 /****************************************************************
5798 ****************************************************************/
5800 NTSTATUS _samr_Shutdown(pipes_struct *p,
5801 struct samr_Shutdown *r)
5803 p->rng_fault_state = true;
5804 return NT_STATUS_NOT_IMPLEMENTED;
5807 /****************************************************************
5808 ****************************************************************/
5810 NTSTATUS _samr_CreateUser(pipes_struct *p,
5811 struct samr_CreateUser *r)
5813 p->rng_fault_state = true;
5814 return NT_STATUS_NOT_IMPLEMENTED;
5817 /****************************************************************
5818 ****************************************************************/
5820 NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
5821 struct samr_SetMemberAttributesOfGroup *r)
5823 p->rng_fault_state = true;
5824 return NT_STATUS_NOT_IMPLEMENTED;
5827 /****************************************************************
5828 ****************************************************************/
5830 NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
5831 struct samr_ChangePasswordUser *r)
5833 p->rng_fault_state = true;
5834 return NT_STATUS_NOT_IMPLEMENTED;
5837 /****************************************************************
5838 ****************************************************************/
5840 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
5841 struct samr_TestPrivateFunctionsDomain *r)
5843 p->rng_fault_state = true;
5844 return NT_STATUS_NOT_IMPLEMENTED;
5847 /****************************************************************
5848 ****************************************************************/
5850 NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
5851 struct samr_TestPrivateFunctionsUser *r)
5853 p->rng_fault_state = true;
5854 return NT_STATUS_NOT_IMPLEMENTED;
5857 /****************************************************************
5858 ****************************************************************/
5860 NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
5861 struct samr_QueryUserInfo2 *r)
5863 p->rng_fault_state = true;
5864 return NT_STATUS_NOT_IMPLEMENTED;
5867 /****************************************************************
5868 ****************************************************************/
5870 NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
5871 struct samr_AddMultipleMembersToAlias *r)
5873 p->rng_fault_state = true;
5874 return NT_STATUS_NOT_IMPLEMENTED;
5877 /****************************************************************
5878 ****************************************************************/
5880 NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
5881 struct samr_RemoveMultipleMembersFromAlias *r)
5883 p->rng_fault_state = true;
5884 return NT_STATUS_NOT_IMPLEMENTED;
5887 /****************************************************************
5888 ****************************************************************/
5890 NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
5891 struct samr_OemChangePasswordUser2 *r)
5893 p->rng_fault_state = true;
5894 return NT_STATUS_NOT_IMPLEMENTED;
5897 /****************************************************************
5898 ****************************************************************/
5900 NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
5901 struct samr_SetBootKeyInformation *r)
5903 p->rng_fault_state = true;
5904 return NT_STATUS_NOT_IMPLEMENTED;
5907 /****************************************************************
5908 ****************************************************************/
5910 NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
5911 struct samr_GetBootKeyInformation *r)
5913 p->rng_fault_state = true;
5914 return NT_STATUS_NOT_IMPLEMENTED;
5917 /****************************************************************
5918 ****************************************************************/
5920 NTSTATUS _samr_Connect3(pipes_struct *p,
5921 struct samr_Connect3 *r)
5923 p->rng_fault_state = true;
5924 return NT_STATUS_NOT_IMPLEMENTED;
5927 /****************************************************************
5928 ****************************************************************/
5930 NTSTATUS _samr_RidToSid(pipes_struct *p,
5931 struct samr_RidToSid *r)
5933 p->rng_fault_state = true;
5934 return NT_STATUS_NOT_IMPLEMENTED;
5937 /****************************************************************
5938 ****************************************************************/
5940 NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
5941 struct samr_SetDsrmPassword *r)
5943 p->rng_fault_state = true;
5944 return NT_STATUS_NOT_IMPLEMENTED;
5947 /****************************************************************
5948 ****************************************************************/
5950 NTSTATUS _samr_ValidatePassword(pipes_struct *p,
5951 struct samr_ValidatePassword *r)
5953 p->rng_fault_state = true;
5954 return NT_STATUS_NOT_IMPLEMENTED;