• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.5.8/source3/rpc_server/
1/*
2 *  Unix SMB/CIFS implementation.
3 *  RPC Pipe client / server routines
4 *  Copyright (C) Andrew Tridgell                   1992-1997,
5 *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6 *  Copyright (C) Paul Ashton                       1997,
7 *  Copyright (C) Marc Jacobsen			    1999,
8 *  Copyright (C) Jeremy Allison                    2001-2008,
9 *  Copyright (C) Jean François Micouleau           1998-2001,
10 *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11 *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12 *  Copyright (C) Simo Sorce                        2003.
13 *  Copyright (C) Volker Lendecke		    2005.
14 *  Copyright (C) Guenther Deschner		    2008.
15 *
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.
20 *
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.
25 *
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/>.
28 */
29
30/*
31 * This is the implementation of the SAMR code.
32 */
33
34#include "includes.h"
35#include "smbd/globals.h"
36#include "../libcli/auth/libcli_auth.h"
37#include "../librpc/gen_ndr/srv_samr.h"
38
39#undef DBGC_CLASS
40#define DBGC_CLASS DBGC_RPC_SRV
41
42#define SAMR_USR_RIGHTS_WRITE_PW \
43		( READ_CONTROL_ACCESS		| \
44		  SAMR_USER_ACCESS_CHANGE_PASSWORD	| \
45		  SAMR_USER_ACCESS_SET_LOC_COM)
46#define SAMR_USR_RIGHTS_CANT_WRITE_PW \
47		( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
48
49#define DISP_INFO_CACHE_TIMEOUT 10
50
51#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
52#define MAX_SAM_ENTRIES_W95 50
53
54struct samr_connect_info {
55	uint8_t dummy;
56};
57
58struct samr_domain_info {
59	struct dom_sid sid;
60	struct disp_info *disp_info;
61};
62
63struct samr_user_info {
64	struct dom_sid sid;
65};
66
67struct samr_group_info {
68	struct dom_sid sid;
69};
70
71struct samr_alias_info {
72	struct dom_sid sid;
73};
74
75typedef struct disp_info {
76	DOM_SID sid; /* identify which domain this is. */
77	struct pdb_search *users; /* querydispinfo 1 and 4 */
78	struct pdb_search *machines; /* querydispinfo 2 */
79	struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
80	struct pdb_search *aliases; /* enumaliases */
81
82	uint32_t enum_acb_mask;
83	struct pdb_search *enum_users; /* enumusers with a mask */
84
85	struct timed_event *cache_timeout_event; /* cache idle timeout
86						  * handler. */
87} DISP_INFO;
88
89static const struct generic_mapping sam_generic_mapping = {
90	GENERIC_RIGHTS_SAM_READ,
91	GENERIC_RIGHTS_SAM_WRITE,
92	GENERIC_RIGHTS_SAM_EXECUTE,
93	GENERIC_RIGHTS_SAM_ALL_ACCESS};
94static const struct generic_mapping dom_generic_mapping = {
95	GENERIC_RIGHTS_DOMAIN_READ,
96	GENERIC_RIGHTS_DOMAIN_WRITE,
97	GENERIC_RIGHTS_DOMAIN_EXECUTE,
98	GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
99static const struct generic_mapping usr_generic_mapping = {
100	GENERIC_RIGHTS_USER_READ,
101	GENERIC_RIGHTS_USER_WRITE,
102	GENERIC_RIGHTS_USER_EXECUTE,
103	GENERIC_RIGHTS_USER_ALL_ACCESS};
104static const struct generic_mapping usr_nopwchange_generic_mapping = {
105	GENERIC_RIGHTS_USER_READ,
106	GENERIC_RIGHTS_USER_WRITE,
107	GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
108	GENERIC_RIGHTS_USER_ALL_ACCESS};
109static const struct generic_mapping grp_generic_mapping = {
110	GENERIC_RIGHTS_GROUP_READ,
111	GENERIC_RIGHTS_GROUP_WRITE,
112	GENERIC_RIGHTS_GROUP_EXECUTE,
113	GENERIC_RIGHTS_GROUP_ALL_ACCESS};
114static const struct generic_mapping ali_generic_mapping = {
115	GENERIC_RIGHTS_ALIAS_READ,
116	GENERIC_RIGHTS_ALIAS_WRITE,
117	GENERIC_RIGHTS_ALIAS_EXECUTE,
118	GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
119
120/*******************************************************************
121*******************************************************************/
122
123static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
124                                     const struct generic_mapping *map,
125				     DOM_SID *sid, uint32 sid_access )
126{
127	DOM_SID domadmin_sid;
128	SEC_ACE ace[5];		/* at most 5 entries */
129	size_t i = 0;
130
131	SEC_ACL *psa = NULL;
132
133	/* basic access for Everyone */
134
135	init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
136			map->generic_execute | map->generic_read, 0);
137
138	/* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
139
140	init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
141			SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
142	init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
143			SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
144
145	/* Add Full Access for Domain Admins if we are a DC */
146
147	if ( IS_DC ) {
148		sid_copy( &domadmin_sid, get_global_sam_sid() );
149		sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
150		init_sec_ace(&ace[i++], &domadmin_sid,
151			SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
152	}
153
154	/* if we have a sid, give it some special access */
155
156	if ( sid ) {
157		init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
158	}
159
160	/* create the security descriptor */
161
162	if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
163		return NT_STATUS_NO_MEMORY;
164
165	if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
166				  SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
167				  psa, sd_size)) == NULL)
168		return NT_STATUS_NO_MEMORY;
169
170	return NT_STATUS_OK;
171}
172
173/*******************************************************************
174 Checks if access to an object should be granted, and returns that
175 level of access for further checks.
176********************************************************************/
177
178NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token,
179                                          SE_PRIV *rights, uint32 rights_mask,
180                                          uint32 des_access, uint32 *acc_granted,
181					  const char *debug )
182{
183	NTSTATUS status = NT_STATUS_ACCESS_DENIED;
184	uint32 saved_mask = 0;
185
186	/* check privileges; certain SAM access bits should be overridden
187	   by privileges (mostly having to do with creating/modifying/deleting
188	   users and groups) */
189
190	if (rights && !se_priv_equal(rights, &se_priv_none) &&
191			user_has_any_privilege(token, rights)) {
192
193		saved_mask = (des_access & rights_mask);
194		des_access &= ~saved_mask;
195
196		DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
197			rights_mask));
198	}
199
200
201	/* check the security descriptor first */
202
203	status = se_access_check(psd, token, des_access, acc_granted);
204	if (NT_STATUS_IS_OK(status)) {
205		goto done;
206	}
207
208	/* give root a free pass */
209
210	if ( geteuid() == sec_initial_uid() ) {
211
212		DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
213		DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
214
215		*acc_granted = des_access;
216
217		status = NT_STATUS_OK;
218		goto done;
219	}
220
221
222done:
223	/* add in any bits saved during the privilege check (only
224	   matters is status is ok) */
225
226	*acc_granted |= rights_mask;
227
228	DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
229		debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
230		des_access, *acc_granted));
231
232	return status;
233}
234
235
236/*******************************************************************
237 Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
238********************************************************************/
239
240void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
241			    const struct unix_user_token *unix_token,
242			    uint32_t *pacc_requested)
243{
244	if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
245		return;
246	}
247	*pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
248
249	/* At least try for generic read|execute - Everyone gets that. */
250	*pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
251
252	/* root gets anything. */
253	if (unix_token->uid == sec_initial_uid()) {
254		*pacc_requested |= GENERIC_ALL_ACCESS;
255		return;
256	}
257
258	/* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
259
260	if (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) ||
261			is_sid_in_token(nt_token, &global_sid_Builtin_Account_Operators)) {
262		*pacc_requested |= GENERIC_ALL_ACCESS;
263		return;
264	}
265
266	/* Full access for DOMAIN\Domain Admins. */
267	if ( IS_DC ) {
268		DOM_SID domadmin_sid;
269		sid_copy( &domadmin_sid, get_global_sam_sid() );
270		sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
271		if (is_sid_in_token(nt_token, &domadmin_sid)) {
272			*pacc_requested |= GENERIC_ALL_ACCESS;
273			return;
274		}
275	}
276	/* TODO ! Check privileges. */
277}
278
279/*******************************************************************
280 Fetch or create a dispinfo struct.
281********************************************************************/
282
283static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
284{
285	/*
286	 * We do a static cache for DISP_INFO's here. Explanation can be found
287	 * in Jeremy's checkin message to r11793:
288	 *
289	 * Fix the SAMR cache so it works across completely insane
290	 * client behaviour (ie.:
291	 * open pipe/open SAMR handle/enumerate 0 - 1024
292	 * close SAMR handle, close pipe.
293	 * open pipe/open SAMR handle/enumerate 1024 - 2048...
294	 * close SAMR handle, close pipe.
295	 * And on ad-nausium. Amazing.... probably object-oriented
296	 * client side programming in action yet again.
297	 * This change should *massively* improve performance when
298	 * enumerating users from an LDAP database.
299	 * Jeremy.
300	 *
301	 * "Our" and the builtin domain are the only ones where we ever
302	 * enumerate stuff, so just cache 2 entries.
303	 */
304
305	static struct disp_info *builtin_dispinfo;
306	static struct disp_info *domain_dispinfo;
307
308	/* There are two cases to consider here:
309	   1) The SID is a domain SID and we look for an equality match, or
310	   2) This is an account SID and so we return the DISP_INFO* for our
311	      domain */
312
313	if (psid == NULL) {
314		return NULL;
315	}
316
317	if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
318		/*
319		 * Necessary only once, but it does not really hurt.
320		 */
321		if (builtin_dispinfo == NULL) {
322			builtin_dispinfo = talloc_zero(
323				talloc_autofree_context(), struct disp_info);
324			if (builtin_dispinfo == NULL) {
325				return NULL;
326			}
327		}
328		sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
329
330		return builtin_dispinfo;
331	}
332
333	if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
334		/*
335		 * Necessary only once, but it does not really hurt.
336		 */
337		if (domain_dispinfo == NULL) {
338			domain_dispinfo = talloc_zero(
339				talloc_autofree_context(), struct disp_info);
340			if (domain_dispinfo == NULL) {
341				return NULL;
342			}
343		}
344		sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
345
346		return domain_dispinfo;
347	}
348
349	return NULL;
350}
351
352/*******************************************************************
353 Function to free the per SID data.
354 ********************************************************************/
355
356static void free_samr_cache(DISP_INFO *disp_info)
357{
358	DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
359		   sid_string_dbg(&disp_info->sid)));
360
361	/* We need to become root here because the paged search might have to
362	 * tell the LDAP server we're not interested in the rest anymore. */
363
364	become_root();
365
366	TALLOC_FREE(disp_info->users);
367	TALLOC_FREE(disp_info->machines);
368	TALLOC_FREE(disp_info->groups);
369	TALLOC_FREE(disp_info->aliases);
370	TALLOC_FREE(disp_info->enum_users);
371
372	unbecome_root();
373}
374
375/*******************************************************************
376 Idle event handler. Throw away the disp info cache.
377 ********************************************************************/
378
379static void disp_info_cache_idle_timeout_handler(struct event_context *ev_ctx,
380						 struct timed_event *te,
381						 struct timeval now,
382						 void *private_data)
383{
384	DISP_INFO *disp_info = (DISP_INFO *)private_data;
385
386	TALLOC_FREE(disp_info->cache_timeout_event);
387
388	DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
389		   "out\n"));
390	free_samr_cache(disp_info);
391}
392
393/*******************************************************************
394 Setup cache removal idle event handler.
395 ********************************************************************/
396
397static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
398{
399	/* Remove any pending timeout and update. */
400
401	TALLOC_FREE(disp_info->cache_timeout_event);
402
403	DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
404		  "SID %s for %u seconds\n", sid_string_dbg(&disp_info->sid),
405		  (unsigned int)secs_fromnow ));
406
407	disp_info->cache_timeout_event = event_add_timed(
408		smbd_event_context(), NULL,
409		timeval_current_ofs(secs_fromnow, 0),
410		disp_info_cache_idle_timeout_handler, (void *)disp_info);
411}
412
413/*******************************************************************
414 Force flush any cache. We do this on any samr_set_xxx call.
415 We must also remove the timeout handler.
416 ********************************************************************/
417
418static void force_flush_samr_cache(const struct dom_sid *sid)
419{
420	struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
421
422	if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
423		return;
424	}
425
426	DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
427	TALLOC_FREE(disp_info->cache_timeout_event);
428	free_samr_cache(disp_info);
429}
430
431/*******************************************************************
432 Ensure password info is never given out. Paranioa... JRA.
433 ********************************************************************/
434
435static void samr_clear_sam_passwd(struct samu *sam_pass)
436{
437
438	if (!sam_pass)
439		return;
440
441	/* These now zero out the old password */
442
443	pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
444	pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
445}
446
447static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
448{
449	struct samr_displayentry *entry;
450
451	if (sid_check_is_builtin(&info->sid)) {
452		/* No users in builtin. */
453		return 0;
454	}
455
456	if (info->users == NULL) {
457		info->users = pdb_search_users(info, acct_flags);
458		if (info->users == NULL) {
459			return 0;
460		}
461	}
462	/* Fetch the last possible entry, thus trigger an enumeration */
463	pdb_search_entries(info->users, 0xffffffff, 1, &entry);
464
465	/* Ensure we cache this enumeration. */
466	set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
467
468	return info->users->num_entries;
469}
470
471static uint32 count_sam_groups(struct disp_info *info)
472{
473	struct samr_displayentry *entry;
474
475	if (sid_check_is_builtin(&info->sid)) {
476		/* No groups in builtin. */
477		return 0;
478	}
479
480	if (info->groups == NULL) {
481		info->groups = pdb_search_groups(info);
482		if (info->groups == NULL) {
483			return 0;
484		}
485	}
486	/* Fetch the last possible entry, thus trigger an enumeration */
487	pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
488
489	/* Ensure we cache this enumeration. */
490	set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
491
492	return info->groups->num_entries;
493}
494
495static uint32 count_sam_aliases(struct disp_info *info)
496{
497	struct samr_displayentry *entry;
498
499	if (info->aliases == NULL) {
500		info->aliases = pdb_search_aliases(info, &info->sid);
501		if (info->aliases == NULL) {
502			return 0;
503		}
504	}
505	/* Fetch the last possible entry, thus trigger an enumeration */
506	pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
507
508	/* Ensure we cache this enumeration. */
509	set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
510
511	return info->aliases->num_entries;
512}
513
514/*******************************************************************
515 _samr_Close
516 ********************************************************************/
517
518NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
519{
520	if (!close_policy_hnd(p, r->in.handle)) {
521		return NT_STATUS_INVALID_HANDLE;
522	}
523
524	ZERO_STRUCTP(r->out.handle);
525
526	return NT_STATUS_OK;
527}
528
529/*******************************************************************
530 _samr_OpenDomain
531 ********************************************************************/
532
533NTSTATUS _samr_OpenDomain(pipes_struct *p,
534			  struct samr_OpenDomain *r)
535{
536	struct samr_connect_info *cinfo;
537	struct samr_domain_info *dinfo;
538	SEC_DESC *psd = NULL;
539	uint32    acc_granted;
540	uint32    des_access = r->in.access_mask;
541	NTSTATUS  status;
542	size_t    sd_size;
543	uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
544	SE_PRIV se_rights;
545
546	/* find the connection policy handle. */
547
548	cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
549				   struct samr_connect_info, &status);
550	if (!NT_STATUS_IS_OK(status)) {
551		return status;
552	}
553
554	/*check if access can be granted as requested by client. */
555	map_max_allowed_access(p->server_info->ptok,
556			       &p->server_info->utok,
557			       &des_access);
558
559	make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
560	se_map_generic( &des_access, &dom_generic_mapping );
561
562	/*
563	 * Users with SeMachineAccount or SeAddUser get additional
564	 * SAMR_DOMAIN_ACCESS_CREATE_USER access.
565	 */
566	se_priv_copy( &se_rights, &se_machine_account );
567	se_priv_add( &se_rights, &se_add_users );
568
569	/*
570	 * Users with SeAddUser get the ability to manipulate groups
571	 * and aliases.
572	 */
573	if (user_has_any_privilege(p->server_info->ptok, &se_add_users)) {
574		extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
575				SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
576				SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
577				SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
578				SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
579	}
580
581	status = access_check_object( psd, p->server_info->ptok,
582		&se_rights, extra_access, des_access,
583		&acc_granted, "_samr_OpenDomain" );
584
585	if ( !NT_STATUS_IS_OK(status) )
586		return status;
587
588	if (!sid_check_is_domain(r->in.sid) &&
589	    !sid_check_is_builtin(r->in.sid)) {
590		return NT_STATUS_NO_SUCH_DOMAIN;
591	}
592
593	dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
594				     struct samr_domain_info, &status);
595	if (!NT_STATUS_IS_OK(status)) {
596		return status;
597	}
598	dinfo->sid = *r->in.sid;
599	dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
600
601	DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
602
603	return NT_STATUS_OK;
604}
605
606/*******************************************************************
607 _samr_GetUserPwInfo
608 ********************************************************************/
609
610NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
611			     struct samr_GetUserPwInfo *r)
612{
613	struct samr_user_info *uinfo;
614	enum lsa_SidType sid_type;
615	uint32_t min_password_length = 0;
616	uint32_t password_properties = 0;
617	bool ret = false;
618	NTSTATUS status;
619
620	DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
621
622	uinfo = policy_handle_find(p, r->in.user_handle,
623				   SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
624				   struct samr_user_info, &status);
625	if (!NT_STATUS_IS_OK(status)) {
626		return status;
627	}
628
629	if (!sid_check_is_in_our_domain(&uinfo->sid)) {
630		return NT_STATUS_OBJECT_TYPE_MISMATCH;
631	}
632
633	become_root();
634	ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
635	unbecome_root();
636	if (ret == false) {
637		return NT_STATUS_NO_SUCH_USER;
638	}
639
640	switch (sid_type) {
641		case SID_NAME_USER:
642			become_root();
643			pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
644					       &min_password_length);
645			pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
646					       &password_properties);
647			unbecome_root();
648
649			if (lp_check_password_script() && *lp_check_password_script()) {
650				password_properties |= DOMAIN_PASSWORD_COMPLEX;
651			}
652
653			break;
654		default:
655			break;
656	}
657
658	r->out.info->min_password_length = min_password_length;
659	r->out.info->password_properties = password_properties;
660
661	DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
662
663	return NT_STATUS_OK;
664}
665
666/*******************************************************************
667 _samr_SetSecurity
668 ********************************************************************/
669
670NTSTATUS _samr_SetSecurity(pipes_struct *p,
671			   struct samr_SetSecurity *r)
672{
673	struct samr_user_info *uinfo;
674	uint32 i;
675	SEC_ACL *dacl;
676	bool ret;
677	struct samu *sampass=NULL;
678	NTSTATUS status;
679
680	uinfo = policy_handle_find(p, r->in.handle,
681				   SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
682				   struct samr_user_info, &status);
683	if (!NT_STATUS_IS_OK(status)) {
684		return status;
685	}
686
687	if (!(sampass = samu_new( p->mem_ctx))) {
688		DEBUG(0,("No memory!\n"));
689		return NT_STATUS_NO_MEMORY;
690	}
691
692	/* get the user record */
693	become_root();
694	ret = pdb_getsampwsid(sampass, &uinfo->sid);
695	unbecome_root();
696
697	if (!ret) {
698		DEBUG(4, ("User %s not found\n",
699			  sid_string_dbg(&uinfo->sid)));
700		TALLOC_FREE(sampass);
701		return NT_STATUS_INVALID_HANDLE;
702	}
703
704	dacl = r->in.sdbuf->sd->dacl;
705	for (i=0; i < dacl->num_aces; i++) {
706		if (sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
707			ret = pdb_set_pass_can_change(sampass,
708				(dacl->aces[i].access_mask &
709				 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
710						      True: False);
711			break;
712		}
713	}
714
715	if (!ret) {
716		TALLOC_FREE(sampass);
717		return NT_STATUS_ACCESS_DENIED;
718	}
719
720	become_root();
721	status = pdb_update_sam_account(sampass);
722	unbecome_root();
723
724	TALLOC_FREE(sampass);
725
726	return status;
727}
728
729/*******************************************************************
730  build correct perms based on policies and password times for _samr_query_sec_obj
731*******************************************************************/
732static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
733{
734	struct samu *sampass=NULL;
735	bool ret;
736
737	if ( !(sampass = samu_new( mem_ctx )) ) {
738		DEBUG(0,("No memory!\n"));
739		return False;
740	}
741
742	become_root();
743	ret = pdb_getsampwsid(sampass, user_sid);
744	unbecome_root();
745
746	if (ret == False) {
747		DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
748		TALLOC_FREE(sampass);
749		return False;
750	}
751
752	DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
753
754	if (pdb_get_pass_can_change(sampass)) {
755		TALLOC_FREE(sampass);
756		return True;
757	}
758	TALLOC_FREE(sampass);
759	return False;
760}
761
762
763/*******************************************************************
764 _samr_QuerySecurity
765 ********************************************************************/
766
767NTSTATUS _samr_QuerySecurity(pipes_struct *p,
768			     struct samr_QuerySecurity *r)
769{
770	struct samr_connect_info *cinfo;
771	struct samr_domain_info *dinfo;
772	struct samr_user_info *uinfo;
773	struct samr_group_info *ginfo;
774	struct samr_alias_info *ainfo;
775	NTSTATUS status;
776	SEC_DESC * psd = NULL;
777	size_t sd_size = 0;
778
779	cinfo = policy_handle_find(p, r->in.handle,
780				   STD_RIGHT_READ_CONTROL_ACCESS, NULL,
781				   struct samr_connect_info, &status);
782	if (NT_STATUS_IS_OK(status)) {
783		DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
784		status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
785					     &sam_generic_mapping, NULL, 0);
786		goto done;
787	}
788
789	dinfo = policy_handle_find(p, r->in.handle,
790				   STD_RIGHT_READ_CONTROL_ACCESS, NULL,
791				   struct samr_domain_info, &status);
792	if (NT_STATUS_IS_OK(status)) {
793		DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
794			 "with SID: %s\n", sid_string_dbg(&dinfo->sid)));
795		/*
796		 * TODO: Builtin probably needs a different SD with restricted
797		 * write access
798		 */
799		status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
800					     &dom_generic_mapping, NULL, 0);
801		goto done;
802	}
803
804	uinfo = policy_handle_find(p, r->in.handle,
805				   STD_RIGHT_READ_CONTROL_ACCESS, NULL,
806				   struct samr_user_info, &status);
807	if (NT_STATUS_IS_OK(status)) {
808		DEBUG(10,("_samr_QuerySecurity: querying security on user "
809			  "Object with SID: %s\n",
810			  sid_string_dbg(&uinfo->sid)));
811		if (check_change_pw_access(p->mem_ctx, &uinfo->sid)) {
812			status = make_samr_object_sd(
813				p->mem_ctx, &psd, &sd_size,
814				&usr_generic_mapping,
815				&uinfo->sid, SAMR_USR_RIGHTS_WRITE_PW);
816		} else {
817			status = make_samr_object_sd(
818				p->mem_ctx, &psd, &sd_size,
819				&usr_nopwchange_generic_mapping,
820				&uinfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
821		}
822		goto done;
823	}
824
825	ginfo = policy_handle_find(p, r->in.handle,
826				   STD_RIGHT_READ_CONTROL_ACCESS, NULL,
827				   struct samr_group_info, &status);
828	if (NT_STATUS_IS_OK(status)) {
829		/*
830		 * TODO: different SDs have to be generated for aliases groups
831		 * and users.  Currently all three get a default user SD
832		 */
833		DEBUG(10,("_samr_QuerySecurity: querying security on group "
834			  "Object with SID: %s\n",
835			  sid_string_dbg(&ginfo->sid)));
836		status = make_samr_object_sd(
837			p->mem_ctx, &psd, &sd_size,
838			&usr_nopwchange_generic_mapping,
839			&ginfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
840		goto done;
841	}
842
843	ainfo = policy_handle_find(p, r->in.handle,
844				   STD_RIGHT_READ_CONTROL_ACCESS, NULL,
845				   struct samr_alias_info, &status);
846	if (NT_STATUS_IS_OK(status)) {
847		/*
848		 * TODO: different SDs have to be generated for aliases groups
849		 * and users.  Currently all three get a default user SD
850		 */
851		DEBUG(10,("_samr_QuerySecurity: querying security on alias "
852			  "Object with SID: %s\n",
853			  sid_string_dbg(&ainfo->sid)));
854		status = make_samr_object_sd(
855			p->mem_ctx, &psd, &sd_size,
856			&usr_nopwchange_generic_mapping,
857			&ainfo->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
858		goto done;
859	}
860
861	return NT_STATUS_OBJECT_TYPE_MISMATCH;
862done:
863	if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
864		return NT_STATUS_NO_MEMORY;
865
866	return status;
867}
868
869/*******************************************************************
870makes a SAM_ENTRY / UNISTR2* structure from a user list.
871********************************************************************/
872
873static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
874					 struct samr_SamEntry **sam_pp,
875					 uint32_t num_entries,
876					 uint32_t start_idx,
877					 struct samr_displayentry *entries)
878{
879	uint32_t i;
880	struct samr_SamEntry *sam;
881
882	*sam_pp = NULL;
883
884	if (num_entries == 0) {
885		return NT_STATUS_OK;
886	}
887
888	sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_entries);
889	if (sam == NULL) {
890		DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
891		return NT_STATUS_NO_MEMORY;
892	}
893
894	for (i = 0; i < num_entries; i++) {
895#if 0
896		/*
897		 * usrmgr expects a non-NULL terminated string with
898		 * trust relationships
899		 */
900		if (entries[i].acct_flags & ACB_DOMTRUST) {
901			init_unistr2(&uni_temp_name, entries[i].account_name,
902				     UNI_FLAGS_NONE);
903		} else {
904			init_unistr2(&uni_temp_name, entries[i].account_name,
905				     UNI_STR_TERMINATE);
906		}
907#endif
908		init_lsa_String(&sam[i].name, entries[i].account_name);
909		sam[i].idx = entries[i].rid;
910	}
911
912	*sam_pp = sam;
913
914	return NT_STATUS_OK;
915}
916
917#define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
918
919/*******************************************************************
920 _samr_EnumDomainUsers
921 ********************************************************************/
922
923NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
924			       struct samr_EnumDomainUsers *r)
925{
926	NTSTATUS status;
927	struct samr_domain_info *dinfo;
928	int num_account;
929	uint32 enum_context = *r->in.resume_handle;
930	enum remote_arch_types ra_type = get_remote_arch();
931	int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
932	uint32 max_entries = max_sam_entries;
933	struct samr_displayentry *entries = NULL;
934	struct samr_SamArray *samr_array = NULL;
935	struct samr_SamEntry *samr_entries = NULL;
936
937	DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
938
939	dinfo = policy_handle_find(p, r->in.domain_handle,
940				   SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
941				   struct samr_domain_info, &status);
942	if (!NT_STATUS_IS_OK(status)) {
943		return status;
944	}
945
946	samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
947	if (!samr_array) {
948		return NT_STATUS_NO_MEMORY;
949	}
950	*r->out.sam = samr_array;
951
952	if (sid_check_is_builtin(&dinfo->sid)) {
953		/* No users in builtin. */
954		*r->out.resume_handle = *r->in.resume_handle;
955		DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
956		return status;
957	}
958
959	become_root();
960
961	/* AS ROOT !!!! */
962
963	if ((dinfo->disp_info->enum_users != NULL) &&
964	    (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
965		TALLOC_FREE(dinfo->disp_info->enum_users);
966	}
967
968	if (dinfo->disp_info->enum_users == NULL) {
969		dinfo->disp_info->enum_users = pdb_search_users(
970			dinfo->disp_info, r->in.acct_flags);
971		dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
972	}
973
974	if (dinfo->disp_info->enum_users == NULL) {
975		/* END AS ROOT !!!! */
976		unbecome_root();
977		return NT_STATUS_ACCESS_DENIED;
978	}
979
980	num_account = pdb_search_entries(dinfo->disp_info->enum_users,
981					 enum_context, max_entries,
982					 &entries);
983
984	/* END AS ROOT !!!! */
985
986	unbecome_root();
987
988	if (num_account == 0) {
989		DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
990			  "total entries\n"));
991		*r->out.resume_handle = *r->in.resume_handle;
992		return NT_STATUS_OK;
993	}
994
995	status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
996					  num_account, enum_context,
997					  entries);
998	if (!NT_STATUS_IS_OK(status)) {
999		return status;
1000	}
1001
1002	if (max_entries <= num_account) {
1003		status = STATUS_MORE_ENTRIES;
1004	} else {
1005		status = NT_STATUS_OK;
1006	}
1007
1008	/* Ensure we cache this enumeration. */
1009	set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1010
1011	DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
1012
1013	samr_array->count = num_account;
1014	samr_array->entries = samr_entries;
1015
1016	*r->out.resume_handle = *r->in.resume_handle + num_account;
1017	*r->out.num_entries = num_account;
1018
1019	DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
1020
1021	return status;
1022}
1023
1024/*******************************************************************
1025makes a SAM_ENTRY / UNISTR2* structure from a group list.
1026********************************************************************/
1027
1028static void make_group_sam_entry_list(TALLOC_CTX *ctx,
1029				      struct samr_SamEntry **sam_pp,
1030				      uint32_t num_sam_entries,
1031				      struct samr_displayentry *entries)
1032{
1033	struct samr_SamEntry *sam;
1034	uint32_t i;
1035
1036	*sam_pp = NULL;
1037
1038	if (num_sam_entries == 0) {
1039		return;
1040	}
1041
1042	sam = TALLOC_ZERO_ARRAY(ctx, struct samr_SamEntry, num_sam_entries);
1043	if (sam == NULL) {
1044		return;
1045	}
1046
1047	for (i = 0; i < num_sam_entries; i++) {
1048		/*
1049		 * JRA. I think this should include the null. TNG does not.
1050		 */
1051		init_lsa_String(&sam[i].name, entries[i].account_name);
1052		sam[i].idx = entries[i].rid;
1053	}
1054
1055	*sam_pp = sam;
1056}
1057
1058/*******************************************************************
1059 _samr_EnumDomainGroups
1060 ********************************************************************/
1061
1062NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
1063				struct samr_EnumDomainGroups *r)
1064{
1065	NTSTATUS status;
1066	struct samr_domain_info *dinfo;
1067	struct samr_displayentry *groups;
1068	uint32 num_groups;
1069	struct samr_SamArray *samr_array = NULL;
1070	struct samr_SamEntry *samr_entries = NULL;
1071
1072	dinfo = policy_handle_find(p, r->in.domain_handle,
1073				   SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1074				   struct samr_domain_info, &status);
1075	if (!NT_STATUS_IS_OK(status)) {
1076		return status;
1077	}
1078
1079	DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1080
1081	samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1082	if (!samr_array) {
1083		return NT_STATUS_NO_MEMORY;
1084	}
1085	*r->out.sam = samr_array;
1086
1087	if (sid_check_is_builtin(&dinfo->sid)) {
1088		/* No groups in builtin. */
1089		*r->out.resume_handle = *r->in.resume_handle;
1090		DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
1091		return status;
1092	}
1093
1094	/* the domain group array is being allocated in the function below */
1095
1096	become_root();
1097
1098	if (dinfo->disp_info->groups == NULL) {
1099		dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
1100
1101		if (dinfo->disp_info->groups == NULL) {
1102			unbecome_root();
1103			return NT_STATUS_ACCESS_DENIED;
1104		}
1105	}
1106
1107	num_groups = pdb_search_entries(dinfo->disp_info->groups,
1108					*r->in.resume_handle,
1109					MAX_SAM_ENTRIES, &groups);
1110	unbecome_root();
1111
1112	/* Ensure we cache this enumeration. */
1113	set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1114
1115	make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1116				  num_groups, groups);
1117
1118	if (MAX_SAM_ENTRIES <= num_groups) {
1119		status = STATUS_MORE_ENTRIES;
1120	} else {
1121		status = NT_STATUS_OK;
1122	}
1123
1124	samr_array->count = num_groups;
1125	samr_array->entries = samr_entries;
1126
1127	*r->out.num_entries = num_groups;
1128	*r->out.resume_handle = num_groups + *r->in.resume_handle;
1129
1130	DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
1131
1132	return status;
1133}
1134
1135/*******************************************************************
1136 _samr_EnumDomainAliases
1137 ********************************************************************/
1138
1139NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
1140				 struct samr_EnumDomainAliases *r)
1141{
1142	NTSTATUS status;
1143	struct samr_domain_info *dinfo;
1144	struct samr_displayentry *aliases;
1145	uint32 num_aliases = 0;
1146	struct samr_SamArray *samr_array = NULL;
1147	struct samr_SamEntry *samr_entries = NULL;
1148
1149	dinfo = policy_handle_find(p, r->in.domain_handle,
1150				   SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1151				   struct samr_domain_info, &status);
1152	if (!NT_STATUS_IS_OK(status)) {
1153		return status;
1154	}
1155
1156	DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
1157		 sid_string_dbg(&dinfo->sid)));
1158
1159	samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
1160	if (!samr_array) {
1161		return NT_STATUS_NO_MEMORY;
1162	}
1163
1164	become_root();
1165
1166	if (dinfo->disp_info->aliases == NULL) {
1167		dinfo->disp_info->aliases = pdb_search_aliases(
1168			dinfo->disp_info, &dinfo->sid);
1169		if (dinfo->disp_info->aliases == NULL) {
1170			unbecome_root();
1171			return NT_STATUS_ACCESS_DENIED;
1172		}
1173	}
1174
1175	num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
1176					 *r->in.resume_handle,
1177					 MAX_SAM_ENTRIES, &aliases);
1178	unbecome_root();
1179
1180	/* Ensure we cache this enumeration. */
1181	set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1182
1183	make_group_sam_entry_list(p->mem_ctx, &samr_entries,
1184				  num_aliases, aliases);
1185
1186	DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
1187
1188	if (MAX_SAM_ENTRIES <= num_aliases) {
1189		status = STATUS_MORE_ENTRIES;
1190	} else {
1191		status = NT_STATUS_OK;
1192	}
1193
1194	samr_array->count = num_aliases;
1195	samr_array->entries = samr_entries;
1196
1197	*r->out.sam = samr_array;
1198	*r->out.num_entries = num_aliases;
1199	*r->out.resume_handle = num_aliases + *r->in.resume_handle;
1200
1201	return status;
1202}
1203
1204/*******************************************************************
1205 inits a samr_DispInfoGeneral structure.
1206********************************************************************/
1207
1208static 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)
1213{
1214	uint32 i;
1215
1216	DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
1217
1218	if (num_entries == 0) {
1219		return NT_STATUS_OK;
1220	}
1221
1222	r->count = num_entries;
1223
1224	r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryGeneral, num_entries);
1225	if (!r->entries) {
1226		return NT_STATUS_NO_MEMORY;
1227	}
1228
1229	for (i = 0; i < num_entries ; i++) {
1230
1231		init_lsa_String(&r->entries[i].account_name,
1232				entries[i].account_name);
1233
1234		init_lsa_String(&r->entries[i].description,
1235				entries[i].description);
1236
1237		init_lsa_String(&r->entries[i].full_name,
1238				entries[i].fullname);
1239
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;
1243	}
1244
1245	return NT_STATUS_OK;
1246}
1247
1248/*******************************************************************
1249 inits a samr_DispInfoFull structure.
1250********************************************************************/
1251
1252static 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)
1257{
1258	uint32_t i;
1259
1260	DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
1261
1262	if (num_entries == 0) {
1263		return NT_STATUS_OK;
1264	}
1265
1266	r->count = num_entries;
1267
1268	r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFull, num_entries);
1269	if (!r->entries) {
1270		return NT_STATUS_NO_MEMORY;
1271	}
1272
1273	for (i = 0; i < num_entries ; i++) {
1274
1275		init_lsa_String(&r->entries[i].account_name,
1276				entries[i].account_name);
1277
1278		init_lsa_String(&r->entries[i].description,
1279				entries[i].description);
1280
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;
1284	}
1285
1286	return NT_STATUS_OK;
1287}
1288
1289/*******************************************************************
1290 inits a samr_DispInfoFullGroups structure.
1291********************************************************************/
1292
1293static 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)
1298{
1299	uint32_t i;
1300
1301	DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
1302
1303	if (num_entries == 0) {
1304		return NT_STATUS_OK;
1305	}
1306
1307	r->count = num_entries;
1308
1309	r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryFullGroup, num_entries);
1310	if (!r->entries) {
1311		return NT_STATUS_NO_MEMORY;
1312	}
1313
1314	for (i = 0; i < num_entries ; i++) {
1315
1316		init_lsa_String(&r->entries[i].account_name,
1317				entries[i].account_name);
1318
1319		init_lsa_String(&r->entries[i].description,
1320				entries[i].description);
1321
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;
1325	}
1326
1327	return NT_STATUS_OK;
1328}
1329
1330/*******************************************************************
1331 inits a samr_DispInfoAscii structure.
1332********************************************************************/
1333
1334static 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)
1339{
1340	uint32_t i;
1341
1342	DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
1343
1344	if (num_entries == 0) {
1345		return NT_STATUS_OK;
1346	}
1347
1348	r->count = num_entries;
1349
1350	r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1351	if (!r->entries) {
1352		return NT_STATUS_NO_MEMORY;
1353	}
1354
1355	for (i = 0; i < num_entries ; i++) {
1356
1357		init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1358					  entries[i].account_name);
1359
1360		r->entries[i].idx = start_idx+i+1;
1361	}
1362
1363	return NT_STATUS_OK;
1364}
1365
1366/*******************************************************************
1367 inits a samr_DispInfoAscii structure.
1368********************************************************************/
1369
1370static 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)
1375{
1376	uint32_t i;
1377
1378	DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
1379
1380	if (num_entries == 0) {
1381		return NT_STATUS_OK;
1382	}
1383
1384	r->count = num_entries;
1385
1386	r->entries = TALLOC_ZERO_ARRAY(ctx, struct samr_DispEntryAscii, num_entries);
1387	if (!r->entries) {
1388		return NT_STATUS_NO_MEMORY;
1389	}
1390
1391	for (i = 0; i < num_entries ; i++) {
1392
1393		init_lsa_AsciiStringLarge(&r->entries[i].account_name,
1394					  entries[i].account_name);
1395
1396		r->entries[i].idx = start_idx+i+1;
1397	}
1398
1399	return NT_STATUS_OK;
1400}
1401
1402/*******************************************************************
1403 _samr_QueryDisplayInfo
1404 ********************************************************************/
1405
1406NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
1407				struct samr_QueryDisplayInfo *r)
1408{
1409	NTSTATUS status;
1410	struct samr_domain_info *dinfo;
1411	uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1412
1413	uint32 max_entries = r->in.max_entries;
1414
1415	union samr_DispInfo *disp_info = r->out.info;
1416
1417	uint32 temp_size=0;
1418	NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1419	uint32 num_account = 0;
1420	enum remote_arch_types ra_type = get_remote_arch();
1421	int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1422	struct samr_displayentry *entries = NULL;
1423
1424	DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
1425
1426	dinfo = policy_handle_find(p, r->in.domain_handle,
1427				   SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
1428				   struct samr_domain_info, &status);
1429	if (!NT_STATUS_IS_OK(status)) {
1430		return status;
1431	}
1432
1433	if (sid_check_is_builtin(&dinfo->sid)) {
1434		DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
1435		return NT_STATUS_OK;
1436	}
1437
1438	/*
1439	 * calculate how many entries we will return.
1440	 * based on
1441	 * - the number of entries the client asked
1442	 * - our limit on that
1443	 * - the starting point (enumeration context)
1444	 * - the buffer size the client will accept
1445	 */
1446
1447	/*
1448	 * We are a lot more like W2K. Instead of reading the SAM
1449	 * each time to find the records we need to send back,
1450	 * we read it once and link that copy to the sam handle.
1451	 * For large user list (over the MAX_SAM_ENTRIES)
1452	 * it's a definitive win.
1453	 * second point to notice: between enumerations
1454	 * our sam is now the same as it's a snapshoot.
1455	 * third point: got rid of the static SAM_USER_21 struct
1456	 * no more intermediate.
1457	 * con: it uses much more memory, as a full copy is stored
1458	 * in memory.
1459	 *
1460	 * If you want to change it, think twice and think
1461	 * of the second point , that's really important.
1462	 *
1463	 * JFM, 12/20/2001
1464	 */
1465
1466	if ((r->in.level < 1) || (r->in.level > 5)) {
1467		DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
1468			 (unsigned int)r->in.level ));
1469		return NT_STATUS_INVALID_INFO_CLASS;
1470	}
1471
1472	/* first limit the number of entries we will return */
1473	if (r->in.max_entries > max_sam_entries) {
1474		DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
1475			  "entries, limiting to %d\n", r->in.max_entries,
1476			  max_sam_entries));
1477		max_entries = max_sam_entries;
1478	}
1479
1480	/* calculate the size and limit on the number of entries we will
1481	 * return */
1482
1483	temp_size=max_entries*struct_size;
1484
1485	if (temp_size > r->in.buf_size) {
1486		max_entries = MIN((r->in.buf_size / struct_size),max_entries);;
1487		DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
1488			  "only %d entries\n", max_entries));
1489	}
1490
1491	become_root();
1492
1493	/* THe following done as ROOT. Don't return without unbecome_root(). */
1494
1495	switch (r->in.level) {
1496	case 1:
1497	case 4:
1498		if (dinfo->disp_info->users == NULL) {
1499			dinfo->disp_info->users = pdb_search_users(
1500				dinfo->disp_info, ACB_NORMAL);
1501			if (dinfo->disp_info->users == NULL) {
1502				unbecome_root();
1503				return NT_STATUS_ACCESS_DENIED;
1504			}
1505			DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
1506				(unsigned  int)r->in.start_idx));
1507		} else {
1508			DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
1509				(unsigned  int)r->in.start_idx));
1510		}
1511
1512		num_account = pdb_search_entries(dinfo->disp_info->users,
1513						 r->in.start_idx, max_entries,
1514						 &entries);
1515		break;
1516	case 2:
1517		if (dinfo->disp_info->machines == NULL) {
1518			dinfo->disp_info->machines = pdb_search_users(
1519				dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
1520			if (dinfo->disp_info->machines == NULL) {
1521				unbecome_root();
1522				return NT_STATUS_ACCESS_DENIED;
1523			}
1524			DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
1525				(unsigned  int)r->in.start_idx));
1526		} else {
1527			DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
1528				(unsigned  int)r->in.start_idx));
1529		}
1530
1531		num_account = pdb_search_entries(dinfo->disp_info->machines,
1532						 r->in.start_idx, max_entries,
1533						 &entries);
1534		break;
1535	case 3:
1536	case 5:
1537		if (dinfo->disp_info->groups == NULL) {
1538			dinfo->disp_info->groups = pdb_search_groups(
1539				dinfo->disp_info);
1540			if (dinfo->disp_info->groups == NULL) {
1541				unbecome_root();
1542				return NT_STATUS_ACCESS_DENIED;
1543			}
1544			DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
1545				(unsigned  int)r->in.start_idx));
1546		} else {
1547			DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
1548				(unsigned  int)r->in.start_idx));
1549		}
1550
1551		num_account = pdb_search_entries(dinfo->disp_info->groups,
1552						 r->in.start_idx, max_entries,
1553						 &entries);
1554		break;
1555	default:
1556		unbecome_root();
1557		smb_panic("info class changed");
1558		break;
1559	}
1560	unbecome_root();
1561
1562
1563	/* Now create reply structure */
1564	switch (r->in.level) {
1565	case 1:
1566		disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
1567						num_account, r->in.start_idx,
1568						entries);
1569		break;
1570	case 2:
1571		disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
1572						num_account, r->in.start_idx,
1573						entries);
1574		break;
1575	case 3:
1576		disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
1577						num_account, r->in.start_idx,
1578						entries);
1579		break;
1580	case 4:
1581		disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
1582						num_account, r->in.start_idx,
1583						entries);
1584		break;
1585	case 5:
1586		disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
1587						num_account, r->in.start_idx,
1588						entries);
1589		break;
1590	default:
1591		smb_panic("info class changed");
1592		break;
1593	}
1594
1595	if (!NT_STATUS_IS_OK(disp_ret))
1596		return disp_ret;
1597
1598	if (max_entries <= num_account) {
1599		status = STATUS_MORE_ENTRIES;
1600	} else {
1601		status = NT_STATUS_OK;
1602	}
1603
1604	/* Ensure we cache this enumeration. */
1605	set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
1606
1607	DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
1608
1609	*r->out.total_size = num_account * struct_size;
1610	*r->out.returned_size = num_account ? temp_size : 0;
1611
1612	return status;
1613}
1614
1615/****************************************************************
1616 _samr_QueryDisplayInfo2
1617****************************************************************/
1618
1619NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
1620				 struct samr_QueryDisplayInfo2 *r)
1621{
1622	struct samr_QueryDisplayInfo q;
1623
1624	q.in.domain_handle	= r->in.domain_handle;
1625	q.in.level		= r->in.level;
1626	q.in.start_idx		= r->in.start_idx;
1627	q.in.max_entries	= r->in.max_entries;
1628	q.in.buf_size		= r->in.buf_size;
1629
1630	q.out.total_size	= r->out.total_size;
1631	q.out.returned_size	= r->out.returned_size;
1632	q.out.info		= r->out.info;
1633
1634	return _samr_QueryDisplayInfo(p, &q);
1635}
1636
1637/****************************************************************
1638 _samr_QueryDisplayInfo3
1639****************************************************************/
1640
1641NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
1642				 struct samr_QueryDisplayInfo3 *r)
1643{
1644	struct samr_QueryDisplayInfo q;
1645
1646	q.in.domain_handle	= r->in.domain_handle;
1647	q.in.level		= r->in.level;
1648	q.in.start_idx		= r->in.start_idx;
1649	q.in.max_entries	= r->in.max_entries;
1650	q.in.buf_size		= r->in.buf_size;
1651
1652	q.out.total_size	= r->out.total_size;
1653	q.out.returned_size	= r->out.returned_size;
1654	q.out.info		= r->out.info;
1655
1656	return _samr_QueryDisplayInfo(p, &q);
1657}
1658
1659/*******************************************************************
1660 _samr_QueryAliasInfo
1661 ********************************************************************/
1662
1663NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
1664			      struct samr_QueryAliasInfo *r)
1665{
1666	struct samr_alias_info *ainfo;
1667	struct acct_info info;
1668	NTSTATUS status;
1669	union samr_AliasInfo *alias_info = NULL;
1670	const char *alias_name = NULL;
1671	const char *alias_description = NULL;
1672
1673	DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1674
1675	ainfo = policy_handle_find(p, r->in.alias_handle,
1676				   SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
1677				   struct samr_alias_info, &status);
1678	if (!NT_STATUS_IS_OK(status)) {
1679		return status;
1680	}
1681
1682	alias_info = TALLOC_ZERO_P(p->mem_ctx, union samr_AliasInfo);
1683	if (!alias_info) {
1684		return NT_STATUS_NO_MEMORY;
1685	}
1686
1687	become_root();
1688	status = pdb_get_aliasinfo(&ainfo->sid, &info);
1689	unbecome_root();
1690
1691	if ( !NT_STATUS_IS_OK(status))
1692		return status;
1693
1694	/* FIXME: info contains fstrings */
1695	alias_name = talloc_strdup(r, info.acct_name);
1696	alias_description = talloc_strdup(r, info.acct_desc);
1697
1698	switch (r->in.level) {
1699	case ALIASINFOALL:
1700		alias_info->all.name.string		= alias_name;
1701		alias_info->all.num_members		= 1; /* ??? */
1702		alias_info->all.description.string	= alias_description;
1703		break;
1704	case ALIASINFONAME:
1705		alias_info->name.string			= alias_name;
1706		break;
1707	case ALIASINFODESCRIPTION:
1708		alias_info->description.string		= alias_description;
1709		break;
1710	default:
1711		return NT_STATUS_INVALID_INFO_CLASS;
1712	}
1713
1714	*r->out.info = alias_info;
1715
1716	DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
1717
1718	return NT_STATUS_OK;
1719}
1720
1721/*******************************************************************
1722 _samr_LookupNames
1723 ********************************************************************/
1724
1725NTSTATUS _samr_LookupNames(pipes_struct *p,
1726			   struct samr_LookupNames *r)
1727{
1728	struct samr_domain_info *dinfo;
1729	NTSTATUS status;
1730	uint32 *rid;
1731	enum lsa_SidType *type;
1732	int i;
1733	int num_rids = r->in.num_names;
1734	struct samr_Ids rids, types;
1735	uint32_t num_mapped = 0;
1736
1737	DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1738
1739	dinfo = policy_handle_find(p, r->in.domain_handle,
1740				   0 /* Don't know the acc_bits yet */, NULL,
1741				   struct samr_domain_info, &status);
1742	if (!NT_STATUS_IS_OK(status)) {
1743		return status;
1744	}
1745
1746	if (num_rids > MAX_SAM_ENTRIES) {
1747		num_rids = MAX_SAM_ENTRIES;
1748		DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
1749	}
1750
1751	rid = talloc_array(p->mem_ctx, uint32, num_rids);
1752	NT_STATUS_HAVE_NO_MEMORY(rid);
1753
1754	type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
1755	NT_STATUS_HAVE_NO_MEMORY(type);
1756
1757	DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
1758		 sid_string_dbg(&dinfo->sid)));
1759
1760	for (i = 0; i < num_rids; i++) {
1761
1762		status = NT_STATUS_NONE_MAPPED;
1763	        type[i] = SID_NAME_UNKNOWN;
1764
1765		rid[i] = 0xffffffff;
1766
1767		if (sid_check_is_builtin(&dinfo->sid)) {
1768			if (lookup_builtin_name(r->in.names[i].string,
1769						&rid[i]))
1770			{
1771				type[i] = SID_NAME_ALIAS;
1772			}
1773		} else {
1774			lookup_global_sam_name(r->in.names[i].string, 0,
1775					       &rid[i], &type[i]);
1776		}
1777
1778		if (type[i] != SID_NAME_UNKNOWN) {
1779			num_mapped++;
1780		}
1781	}
1782
1783	if (num_mapped == num_rids) {
1784		status = NT_STATUS_OK;
1785	} else if (num_mapped == 0) {
1786		status = NT_STATUS_NONE_MAPPED;
1787	} else {
1788		status = STATUS_SOME_UNMAPPED;
1789	}
1790
1791	rids.count = num_rids;
1792	rids.ids = rid;
1793
1794	types.count = num_rids;
1795	types.ids = type;
1796
1797	*r->out.rids = rids;
1798	*r->out.types = types;
1799
1800	DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
1801
1802	return status;
1803}
1804
1805/****************************************************************
1806 _samr_ChangePasswordUser
1807****************************************************************/
1808
1809NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
1810				  struct samr_ChangePasswordUser *r)
1811{
1812	NTSTATUS status;
1813	bool ret = false;
1814	struct samr_user_info *uinfo;
1815	struct samu *pwd;
1816	struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
1817	struct samr_Password lm_pwd, nt_pwd;
1818
1819	uinfo = policy_handle_find(p, r->in.user_handle,
1820				   SAMR_USER_ACCESS_SET_PASSWORD, NULL,
1821				   struct samr_user_info, &status);
1822	if (!NT_STATUS_IS_OK(status)) {
1823		return status;
1824	}
1825
1826	DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
1827		  sid_string_dbg(&uinfo->sid)));
1828
1829	if (!(pwd = samu_new(NULL))) {
1830		return NT_STATUS_NO_MEMORY;
1831	}
1832
1833	become_root();
1834	ret = pdb_getsampwsid(pwd, &uinfo->sid);
1835	unbecome_root();
1836
1837	if (!ret) {
1838		TALLOC_FREE(pwd);
1839		return NT_STATUS_WRONG_PASSWORD;
1840	}
1841
1842	{
1843		const uint8_t *lm_pass, *nt_pass;
1844
1845		lm_pass = pdb_get_lanman_passwd(pwd);
1846		nt_pass = pdb_get_nt_passwd(pwd);
1847
1848		if (!lm_pass || !nt_pass) {
1849			status = NT_STATUS_WRONG_PASSWORD;
1850			goto out;
1851		}
1852
1853		memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
1854		memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
1855	}
1856
1857	/* basic sanity checking on parameters.  Do this before any database ops */
1858	if (!r->in.lm_present || !r->in.nt_present ||
1859	    !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
1860	    !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
1861		/* we should really handle a change with lm not
1862		   present */
1863		status = NT_STATUS_INVALID_PARAMETER_MIX;
1864		goto out;
1865	}
1866
1867	/* decrypt and check the new lm hash */
1868	D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
1869	D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
1870	if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
1871		status = NT_STATUS_WRONG_PASSWORD;
1872		goto out;
1873	}
1874
1875	/* decrypt and check the new nt hash */
1876	D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
1877	D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
1878	if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
1879		status = NT_STATUS_WRONG_PASSWORD;
1880		goto out;
1881	}
1882
1883	/* The NT Cross is not required by Win2k3 R2, but if present
1884	   check the nt cross hash */
1885	if (r->in.cross1_present && r->in.nt_cross) {
1886		D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
1887		if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
1888			status = NT_STATUS_WRONG_PASSWORD;
1889			goto out;
1890		}
1891	}
1892
1893	/* The LM Cross is not required by Win2k3 R2, but if present
1894	   check the lm cross hash */
1895	if (r->in.cross2_present && r->in.lm_cross) {
1896		D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
1897		if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
1898			status = NT_STATUS_WRONG_PASSWORD;
1899			goto out;
1900		}
1901	}
1902
1903	if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
1904	    !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
1905		status = NT_STATUS_ACCESS_DENIED;
1906		goto out;
1907	}
1908
1909	status = pdb_update_sam_account(pwd);
1910 out:
1911	TALLOC_FREE(pwd);
1912
1913	return status;
1914}
1915
1916/*******************************************************************
1917 _samr_ChangePasswordUser2
1918 ********************************************************************/
1919
1920NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
1921				   struct samr_ChangePasswordUser2 *r)
1922{
1923	struct smbd_server_connection *sconn = smbd_server_conn;
1924	NTSTATUS status;
1925	fstring user_name;
1926	fstring wks;
1927
1928	DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1929
1930	fstrcpy(user_name, r->in.account->string);
1931	fstrcpy(wks, r->in.server->string);
1932
1933	DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1934
1935	/*
1936	 * Pass the user through the NT -> unix user mapping
1937	 * function.
1938	 */
1939
1940	(void)map_username(sconn, user_name);
1941
1942	/*
1943	 * UNIX username case mangling not required, pass_oem_change
1944	 * is case insensitive.
1945	 */
1946
1947	status = pass_oem_change(user_name,
1948				 r->in.lm_password->data,
1949				 r->in.lm_verifier->hash,
1950				 r->in.nt_password->data,
1951				 r->in.nt_verifier->hash,
1952				 NULL);
1953
1954	DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
1955
1956	if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1957		return NT_STATUS_WRONG_PASSWORD;
1958	}
1959
1960	return status;
1961}
1962
1963/****************************************************************
1964 _samr_OemChangePasswordUser2
1965****************************************************************/
1966
1967NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
1968				      struct samr_OemChangePasswordUser2 *r)
1969{
1970	struct smbd_server_connection *sconn = smbd_server_conn;
1971	NTSTATUS status;
1972	fstring user_name;
1973	const char *wks = NULL;
1974
1975	DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
1976
1977	fstrcpy(user_name, r->in.account->string);
1978	if (r->in.server && r->in.server->string) {
1979		wks = r->in.server->string;
1980	}
1981
1982	DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
1983
1984	/*
1985	 * Pass the user through the NT -> unix user mapping
1986	 * function.
1987	 */
1988
1989	(void)map_username(sconn, user_name);
1990
1991	/*
1992	 * UNIX username case mangling not required, pass_oem_change
1993	 * is case insensitive.
1994	 */
1995
1996	if (!r->in.hash || !r->in.password) {
1997		return NT_STATUS_INVALID_PARAMETER;
1998	}
1999
2000	status = pass_oem_change(user_name,
2001				 r->in.password->data,
2002				 r->in.hash->hash,
2003				 0,
2004				 0,
2005				 NULL);
2006
2007	if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2008		return NT_STATUS_WRONG_PASSWORD;
2009	}
2010
2011	DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
2012
2013	return status;
2014}
2015
2016/*******************************************************************
2017 _samr_ChangePasswordUser3
2018 ********************************************************************/
2019
2020NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
2021				   struct samr_ChangePasswordUser3 *r)
2022{
2023	struct smbd_server_connection *sconn = smbd_server_conn;
2024	NTSTATUS status;
2025	fstring user_name;
2026	const char *wks = NULL;
2027	uint32 reject_reason;
2028	struct samr_DomInfo1 *dominfo = NULL;
2029	struct samr_ChangeReject *reject = NULL;
2030	uint32_t tmp;
2031
2032	DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2033
2034	fstrcpy(user_name, r->in.account->string);
2035	if (r->in.server && r->in.server->string) {
2036		wks = r->in.server->string;
2037	}
2038
2039	DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
2040
2041	/*
2042	 * Pass the user through the NT -> unix user mapping
2043	 * function.
2044	 */
2045
2046	(void)map_username(sconn, user_name);
2047
2048	/*
2049	 * UNIX username case mangling not required, pass_oem_change
2050	 * is case insensitive.
2051	 */
2052
2053	status = pass_oem_change(user_name,
2054				 r->in.lm_password->data,
2055				 r->in.lm_verifier->hash,
2056				 r->in.nt_password->data,
2057				 r->in.nt_verifier->hash,
2058				 &reject_reason);
2059	if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2060		return NT_STATUS_WRONG_PASSWORD;
2061	}
2062
2063	if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
2064	    NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
2065
2066		time_t u_expire, u_min_age;
2067		uint32 account_policy_temp;
2068
2069		dominfo = TALLOC_ZERO_P(p->mem_ctx, struct samr_DomInfo1);
2070		if (!dominfo) {
2071			return NT_STATUS_NO_MEMORY;
2072		}
2073
2074		reject = TALLOC_ZERO_P(p->mem_ctx, struct samr_ChangeReject);
2075		if (!reject) {
2076			return NT_STATUS_NO_MEMORY;
2077		}
2078
2079		become_root();
2080
2081		/* AS ROOT !!! */
2082
2083		pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
2084		dominfo->min_password_length = tmp;
2085
2086		pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
2087		dominfo->password_history_length = tmp;
2088
2089		pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
2090				       &dominfo->password_properties);
2091
2092		pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
2093		u_expire = account_policy_temp;
2094
2095		pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
2096		u_min_age = account_policy_temp;
2097
2098		/* !AS ROOT */
2099
2100		unbecome_root();
2101
2102		unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
2103		unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
2104
2105		if (lp_check_password_script() && *lp_check_password_script()) {
2106			dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
2107		}
2108
2109		reject->reason = reject_reason;
2110
2111		*r->out.dominfo = dominfo;
2112		*r->out.reject = reject;
2113	}
2114
2115	DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
2116
2117	return status;
2118}
2119
2120/*******************************************************************
2121makes a SAMR_R_LOOKUP_RIDS structure.
2122********************************************************************/
2123
2124static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
2125				  const char **names,
2126				  struct lsa_String **lsa_name_array_p)
2127{
2128	struct lsa_String *lsa_name_array = NULL;
2129	uint32_t i;
2130
2131	*lsa_name_array_p = NULL;
2132
2133	if (num_names != 0) {
2134		lsa_name_array = TALLOC_ZERO_ARRAY(ctx, struct lsa_String, num_names);
2135		if (!lsa_name_array) {
2136			return false;
2137		}
2138	}
2139
2140	for (i = 0; i < num_names; i++) {
2141		DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
2142		init_lsa_String(&lsa_name_array[i], names[i]);
2143	}
2144
2145	*lsa_name_array_p = lsa_name_array;
2146
2147	return true;
2148}
2149
2150/*******************************************************************
2151 _samr_LookupRids
2152 ********************************************************************/
2153
2154NTSTATUS _samr_LookupRids(pipes_struct *p,
2155			  struct samr_LookupRids *r)
2156{
2157	struct samr_domain_info *dinfo;
2158	NTSTATUS status;
2159	const char **names;
2160	enum lsa_SidType *attrs = NULL;
2161	uint32 *wire_attrs = NULL;
2162	int num_rids = (int)r->in.num_rids;
2163	int i;
2164	struct lsa_Strings names_array;
2165	struct samr_Ids types_array;
2166	struct lsa_String *lsa_names = NULL;
2167
2168	DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2169
2170	dinfo = policy_handle_find(p, r->in.domain_handle,
2171				   0 /* Don't know the acc_bits yet */, NULL,
2172				   struct samr_domain_info, &status);
2173	if (!NT_STATUS_IS_OK(status)) {
2174		return status;
2175	}
2176
2177	if (num_rids > 1000) {
2178		DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
2179			  "to samba4 idl this is not possible\n", num_rids));
2180		return NT_STATUS_UNSUCCESSFUL;
2181	}
2182
2183	if (num_rids) {
2184		names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
2185		attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
2186		wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
2187
2188		if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
2189			return NT_STATUS_NO_MEMORY;
2190	} else {
2191		names = NULL;
2192		attrs = NULL;
2193		wire_attrs = NULL;
2194	}
2195
2196	become_root();  /* lookup_sid can require root privs */
2197	status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
2198				 names, attrs);
2199	unbecome_root();
2200
2201	if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
2202		status = NT_STATUS_OK;
2203	}
2204
2205	if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
2206				   &lsa_names)) {
2207		return NT_STATUS_NO_MEMORY;
2208	}
2209
2210	/* Convert from enum lsa_SidType to uint32 for wire format. */
2211	for (i = 0; i < num_rids; i++) {
2212		wire_attrs[i] = (uint32)attrs[i];
2213	}
2214
2215	names_array.count = num_rids;
2216	names_array.names = lsa_names;
2217
2218	types_array.count = num_rids;
2219	types_array.ids = wire_attrs;
2220
2221	*r->out.names = names_array;
2222	*r->out.types = types_array;
2223
2224	DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
2225
2226	return status;
2227}
2228
2229/*******************************************************************
2230 _samr_OpenUser
2231********************************************************************/
2232
2233NTSTATUS _samr_OpenUser(pipes_struct *p,
2234			struct samr_OpenUser *r)
2235{
2236	struct samu *sampass=NULL;
2237	DOM_SID sid;
2238	struct samr_domain_info *dinfo;
2239	struct samr_user_info *uinfo;
2240	SEC_DESC *psd = NULL;
2241	uint32    acc_granted;
2242	uint32    des_access = r->in.access_mask;
2243	uint32_t extra_access = 0;
2244	size_t    sd_size;
2245	bool ret;
2246	NTSTATUS nt_status;
2247	SE_PRIV se_rights;
2248	NTSTATUS status;
2249
2250	dinfo = policy_handle_find(p, r->in.domain_handle,
2251				   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
2252				   struct samr_domain_info, &status);
2253	if (!NT_STATUS_IS_OK(status)) {
2254		return status;
2255	}
2256
2257	if ( !(sampass = samu_new( p->mem_ctx )) ) {
2258		return NT_STATUS_NO_MEMORY;
2259	}
2260
2261	/* append the user's RID to it */
2262
2263	if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
2264		return NT_STATUS_NO_SUCH_USER;
2265
2266	/* check if access can be granted as requested by client. */
2267	map_max_allowed_access(p->server_info->ptok,
2268			       &p->server_info->utok,
2269			       &des_access);
2270
2271	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2272	se_map_generic(&des_access, &usr_generic_mapping);
2273
2274	/*
2275	 * Get the sampass first as we need to check privileges
2276	 * based on what kind of user object this is.
2277	 * But don't reveal info too early if it didn't exist.
2278	 */
2279
2280	become_root();
2281	ret=pdb_getsampwsid(sampass, &sid);
2282	unbecome_root();
2283
2284	se_priv_copy(&se_rights, &se_priv_none);
2285
2286	/*
2287	 * We do the override access checks on *open*, not at
2288	 * SetUserInfo time.
2289	 */
2290	if (ret) {
2291		uint32_t acb_info = pdb_get_acct_ctrl(sampass);
2292
2293		if ((acb_info & ACB_WSTRUST) &&
2294				user_has_any_privilege(p->server_info->ptok,
2295						&se_machine_account)) {
2296			/*
2297			 * SeMachineAccount is needed to add
2298			 * GENERIC_RIGHTS_USER_WRITE to a machine
2299			 * account.
2300			 */
2301			se_priv_add(&se_rights, &se_machine_account);
2302			DEBUG(10,("_samr_OpenUser: adding machine account "
2303				"rights to handle for user %s\n",
2304				pdb_get_username(sampass) ));
2305		}
2306		if ((acb_info & ACB_NORMAL) &&
2307				user_has_any_privilege(p->server_info->ptok,
2308						&se_add_users)) {
2309			/*
2310			 * SeAddUsers is needed to add
2311			 * GENERIC_RIGHTS_USER_WRITE to a normal
2312			 * account.
2313			 */
2314			se_priv_add(&se_rights, &se_add_users);
2315			DEBUG(10,("_samr_OpenUser: adding add user "
2316				"rights to handle for user %s\n",
2317				pdb_get_username(sampass) ));
2318		}
2319		/*
2320		 * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
2321		 * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not
2322		 * what Windows does but is a hack for people who haven't
2323		 * set up privileges on groups in Samba.
2324		 */
2325		if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
2326			if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
2327							DOMAIN_GROUP_RID_ADMINS)) {
2328				des_access &= ~GENERIC_RIGHTS_USER_WRITE;
2329				extra_access = GENERIC_RIGHTS_USER_WRITE;
2330				DEBUG(4,("_samr_OpenUser: Allowing "
2331					"GENERIC_RIGHTS_USER_WRITE for "
2332					"rid admins\n"));
2333			}
2334		}
2335	}
2336
2337	TALLOC_FREE(sampass);
2338
2339	nt_status = access_check_object(psd, p->server_info->ptok,
2340		&se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2341		&acc_granted, "_samr_OpenUser");
2342
2343	if ( !NT_STATUS_IS_OK(nt_status) )
2344		return nt_status;
2345
2346	/* check that the SID exists in our domain. */
2347	if (ret == False) {
2348        	return NT_STATUS_NO_SUCH_USER;
2349	}
2350
2351	/* If we did the rid admins hack above, allow access. */
2352	acc_granted |= extra_access;
2353
2354	uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
2355				     struct samr_user_info, &nt_status);
2356	if (!NT_STATUS_IS_OK(nt_status)) {
2357		return nt_status;
2358	}
2359	uinfo->sid = sid;
2360
2361	return NT_STATUS_OK;
2362}
2363
2364/*************************************************************************
2365 *************************************************************************/
2366
2367static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
2368					    DATA_BLOB *blob,
2369					    struct lsa_BinaryString **_r)
2370{
2371	struct lsa_BinaryString *r;
2372
2373	if (!blob || !_r) {
2374		return NT_STATUS_INVALID_PARAMETER;
2375	}
2376
2377	r = TALLOC_ZERO_P(mem_ctx, struct lsa_BinaryString);
2378	if (!r) {
2379		return NT_STATUS_NO_MEMORY;
2380	}
2381
2382	r->array = TALLOC_ZERO_ARRAY(mem_ctx, uint16_t, blob->length/2);
2383	if (!r->array) {
2384		return NT_STATUS_NO_MEMORY;
2385	}
2386	memcpy(r->array, blob->data, blob->length);
2387	r->size = blob->length;
2388	r->length = blob->length;
2389
2390	if (!r->array) {
2391		return NT_STATUS_NO_MEMORY;
2392	}
2393
2394	*_r = r;
2395
2396	return NT_STATUS_OK;
2397}
2398
2399/*************************************************************************
2400 get_user_info_1.
2401 *************************************************************************/
2402
2403static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
2404				struct samr_UserInfo1 *r,
2405				struct samu *pw,
2406				DOM_SID *domain_sid)
2407{
2408	const DOM_SID *sid_group;
2409	uint32_t primary_gid;
2410
2411	become_root();
2412	sid_group = pdb_get_group_sid(pw);
2413	unbecome_root();
2414
2415	if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2416		DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
2417			  "which conflicts with the domain sid %s.  Failing operation.\n",
2418			  pdb_get_username(pw), sid_string_dbg(sid_group),
2419			  sid_string_dbg(domain_sid)));
2420		return NT_STATUS_UNSUCCESSFUL;
2421	}
2422
2423	r->account_name.string		= talloc_strdup(mem_ctx, pdb_get_username(pw));
2424	r->full_name.string		= talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2425	r->primary_gid			= primary_gid;
2426	r->description.string		= talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2427	r->comment.string		= talloc_strdup(mem_ctx, pdb_get_comment(pw));
2428
2429	return NT_STATUS_OK;
2430}
2431
2432/*************************************************************************
2433 get_user_info_2.
2434 *************************************************************************/
2435
2436static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
2437				struct samr_UserInfo2 *r,
2438				struct samu *pw)
2439{
2440	r->comment.string		= talloc_strdup(mem_ctx, pdb_get_comment(pw));
2441	r->unknown.string		= NULL;
2442	r->country_code			= 0;
2443	r->code_page			= 0;
2444
2445	return NT_STATUS_OK;
2446}
2447
2448/*************************************************************************
2449 get_user_info_3.
2450 *************************************************************************/
2451
2452static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
2453				struct samr_UserInfo3 *r,
2454				struct samu *pw,
2455				DOM_SID *domain_sid)
2456{
2457	const DOM_SID *sid_user, *sid_group;
2458	uint32_t rid, primary_gid;
2459
2460	sid_user = pdb_get_user_sid(pw);
2461
2462	if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2463		DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
2464			  "the domain sid %s.  Failing operation.\n",
2465			  pdb_get_username(pw), sid_string_dbg(sid_user),
2466			  sid_string_dbg(domain_sid)));
2467		return NT_STATUS_UNSUCCESSFUL;
2468	}
2469
2470	become_root();
2471	sid_group = pdb_get_group_sid(pw);
2472	unbecome_root();
2473
2474	if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2475		DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
2476			  "which conflicts with the domain sid %s.  Failing operation.\n",
2477			  pdb_get_username(pw), sid_string_dbg(sid_group),
2478			  sid_string_dbg(domain_sid)));
2479		return NT_STATUS_UNSUCCESSFUL;
2480	}
2481
2482	unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2483	unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2484	unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2485	unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2486	unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
2487
2488	r->account_name.string	= talloc_strdup(mem_ctx, pdb_get_username(pw));
2489	r->full_name.string	= talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2490	r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2491	r->home_drive.string	= talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2492	r->logon_script.string	= talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2493	r->profile_path.string	= talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2494	r->workstations.string	= talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2495
2496	r->logon_hours		= get_logon_hours_from_pdb(mem_ctx, pw);
2497	r->rid			= rid;
2498	r->primary_gid		= primary_gid;
2499	r->acct_flags		= pdb_get_acct_ctrl(pw);
2500	r->bad_password_count	= pdb_get_bad_password_count(pw);
2501	r->logon_count		= pdb_get_logon_count(pw);
2502
2503	return NT_STATUS_OK;
2504}
2505
2506/*************************************************************************
2507 get_user_info_4.
2508 *************************************************************************/
2509
2510static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
2511				struct samr_UserInfo4 *r,
2512				struct samu *pw)
2513{
2514	r->logon_hours		= get_logon_hours_from_pdb(mem_ctx, pw);
2515
2516	return NT_STATUS_OK;
2517}
2518
2519/*************************************************************************
2520 get_user_info_5.
2521 *************************************************************************/
2522
2523static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
2524				struct samr_UserInfo5 *r,
2525				struct samu *pw,
2526				DOM_SID *domain_sid)
2527{
2528	const DOM_SID *sid_user, *sid_group;
2529	uint32_t rid, primary_gid;
2530
2531	sid_user = pdb_get_user_sid(pw);
2532
2533	if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2534		DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
2535			  "the domain sid %s.  Failing operation.\n",
2536			  pdb_get_username(pw), sid_string_dbg(sid_user),
2537			  sid_string_dbg(domain_sid)));
2538		return NT_STATUS_UNSUCCESSFUL;
2539	}
2540
2541	become_root();
2542	sid_group = pdb_get_group_sid(pw);
2543	unbecome_root();
2544
2545	if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2546		DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
2547			  "which conflicts with the domain sid %s.  Failing operation.\n",
2548			  pdb_get_username(pw), sid_string_dbg(sid_group),
2549			  sid_string_dbg(domain_sid)));
2550		return NT_STATUS_UNSUCCESSFUL;
2551	}
2552
2553	unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2554	unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2555	unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2556	unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2557
2558	r->account_name.string	= talloc_strdup(mem_ctx, pdb_get_username(pw));
2559	r->full_name.string	= talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2560	r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2561	r->home_drive.string	= talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2562	r->logon_script.string	= talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2563	r->profile_path.string	= talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2564	r->description.string	= talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2565	r->workstations.string	= talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2566
2567	r->logon_hours		= get_logon_hours_from_pdb(mem_ctx, pw);
2568	r->rid			= rid;
2569	r->primary_gid		= primary_gid;
2570	r->acct_flags		= pdb_get_acct_ctrl(pw);
2571	r->bad_password_count	= pdb_get_bad_password_count(pw);
2572	r->logon_count		= pdb_get_logon_count(pw);
2573
2574	return NT_STATUS_OK;
2575}
2576
2577/*************************************************************************
2578 get_user_info_6.
2579 *************************************************************************/
2580
2581static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
2582				struct samr_UserInfo6 *r,
2583				struct samu *pw)
2584{
2585	r->account_name.string	= talloc_strdup(mem_ctx, pdb_get_username(pw));
2586	r->full_name.string	= talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2587
2588	return NT_STATUS_OK;
2589}
2590
2591/*************************************************************************
2592 get_user_info_7. Safe. Only gives out account_name.
2593 *************************************************************************/
2594
2595static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
2596				struct samr_UserInfo7 *r,
2597				struct samu *smbpass)
2598{
2599	r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
2600	if (!r->account_name.string) {
2601		return NT_STATUS_NO_MEMORY;
2602	}
2603
2604	return NT_STATUS_OK;
2605}
2606
2607/*************************************************************************
2608 get_user_info_8.
2609 *************************************************************************/
2610
2611static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
2612				struct samr_UserInfo8 *r,
2613				struct samu *pw)
2614{
2615	r->full_name.string	= talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2616
2617	return NT_STATUS_OK;
2618}
2619
2620/*************************************************************************
2621 get_user_info_9. Only gives out primary group SID.
2622 *************************************************************************/
2623
2624static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
2625				struct samr_UserInfo9 *r,
2626				struct samu *smbpass)
2627{
2628	r->primary_gid = pdb_get_group_rid(smbpass);
2629
2630	return NT_STATUS_OK;
2631}
2632
2633/*************************************************************************
2634 get_user_info_10.
2635 *************************************************************************/
2636
2637static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
2638				 struct samr_UserInfo10 *r,
2639				 struct samu *pw)
2640{
2641	r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2642	r->home_drive.string	= talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2643
2644	return NT_STATUS_OK;
2645}
2646
2647/*************************************************************************
2648 get_user_info_11.
2649 *************************************************************************/
2650
2651static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
2652				 struct samr_UserInfo11 *r,
2653				 struct samu *pw)
2654{
2655	r->logon_script.string	= talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2656
2657	return NT_STATUS_OK;
2658}
2659
2660/*************************************************************************
2661 get_user_info_12.
2662 *************************************************************************/
2663
2664static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
2665				 struct samr_UserInfo12 *r,
2666				 struct samu *pw)
2667{
2668	r->profile_path.string	= talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2669
2670	return NT_STATUS_OK;
2671}
2672
2673/*************************************************************************
2674 get_user_info_13.
2675 *************************************************************************/
2676
2677static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
2678				 struct samr_UserInfo13 *r,
2679				 struct samu *pw)
2680{
2681	r->description.string	= talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2682
2683	return NT_STATUS_OK;
2684}
2685
2686/*************************************************************************
2687 get_user_info_14.
2688 *************************************************************************/
2689
2690static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
2691				 struct samr_UserInfo14 *r,
2692				 struct samu *pw)
2693{
2694	r->workstations.string	= talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2695
2696	return NT_STATUS_OK;
2697}
2698
2699/*************************************************************************
2700 get_user_info_16. Safe. Only gives out acb bits.
2701 *************************************************************************/
2702
2703static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
2704				 struct samr_UserInfo16 *r,
2705				 struct samu *smbpass)
2706{
2707	r->acct_flags = pdb_get_acct_ctrl(smbpass);
2708
2709	return NT_STATUS_OK;
2710}
2711
2712/*************************************************************************
2713 get_user_info_17.
2714 *************************************************************************/
2715
2716static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
2717				 struct samr_UserInfo17 *r,
2718				 struct samu *pw)
2719{
2720	unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2721
2722	return NT_STATUS_OK;
2723}
2724
2725/*************************************************************************
2726 get_user_info_18. OK - this is the killer as it gives out password info.
2727 Ensure that this is only allowed on an encrypted connection with a root
2728 user. JRA.
2729 *************************************************************************/
2730
2731static NTSTATUS get_user_info_18(pipes_struct *p,
2732				 TALLOC_CTX *mem_ctx,
2733				 struct samr_UserInfo18 *r,
2734				 DOM_SID *user_sid)
2735{
2736	struct samu *smbpass=NULL;
2737	bool ret;
2738	const uint8_t *nt_pass = NULL;
2739	const uint8_t *lm_pass = NULL;
2740
2741	ZERO_STRUCTP(r);
2742
2743	if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2744		return NT_STATUS_ACCESS_DENIED;
2745	}
2746
2747	if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
2748		return NT_STATUS_ACCESS_DENIED;
2749	}
2750
2751	/*
2752	 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
2753	 */
2754
2755	if ( !(smbpass = samu_new( mem_ctx )) ) {
2756		return NT_STATUS_NO_MEMORY;
2757	}
2758
2759	ret = pdb_getsampwsid(smbpass, user_sid);
2760
2761	if (ret == False) {
2762		DEBUG(4, ("User %s not found\n", sid_string_dbg(user_sid)));
2763		TALLOC_FREE(smbpass);
2764		return (geteuid() == sec_initial_uid()) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
2765	}
2766
2767	DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
2768
2769	if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
2770		TALLOC_FREE(smbpass);
2771		return NT_STATUS_ACCOUNT_DISABLED;
2772	}
2773
2774	lm_pass = pdb_get_lanman_passwd(smbpass);
2775	if (lm_pass != NULL) {
2776		memcpy(r->lm_pwd.hash, lm_pass, 16);
2777		r->lm_pwd_active = true;
2778	}
2779
2780	nt_pass = pdb_get_nt_passwd(smbpass);
2781	if (nt_pass != NULL) {
2782		memcpy(r->nt_pwd.hash, nt_pass, 16);
2783		r->nt_pwd_active = true;
2784	}
2785	r->password_expired = 0; /* FIXME */
2786
2787	TALLOC_FREE(smbpass);
2788
2789	return NT_STATUS_OK;
2790}
2791
2792/*************************************************************************
2793 get_user_info_20
2794 *************************************************************************/
2795
2796static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
2797				 struct samr_UserInfo20 *r,
2798				 struct samu *sampass)
2799{
2800	const char *munged_dial = NULL;
2801	DATA_BLOB blob;
2802	NTSTATUS status;
2803	struct lsa_BinaryString *parameters = NULL;
2804
2805	ZERO_STRUCTP(r);
2806
2807	munged_dial = pdb_get_munged_dial(sampass);
2808
2809	DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
2810		munged_dial, (int)strlen(munged_dial)));
2811
2812	if (munged_dial) {
2813		blob = base64_decode_data_blob(munged_dial);
2814	} else {
2815		blob = data_blob_string_const_null("");
2816	}
2817
2818	status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2819	data_blob_free(&blob);
2820	if (!NT_STATUS_IS_OK(status)) {
2821		return status;
2822	}
2823
2824	r->parameters = *parameters;
2825
2826	return NT_STATUS_OK;
2827}
2828
2829
2830/*************************************************************************
2831 get_user_info_21
2832 *************************************************************************/
2833
2834static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
2835				 struct samr_UserInfo21 *r,
2836				 struct samu *pw,
2837				 DOM_SID *domain_sid,
2838				 uint32_t acc_granted)
2839{
2840	NTSTATUS status;
2841	const DOM_SID *sid_user, *sid_group;
2842	uint32_t rid, primary_gid;
2843	NTTIME force_password_change;
2844	time_t must_change_time;
2845	struct lsa_BinaryString *parameters = NULL;
2846	const char *munged_dial = NULL;
2847	DATA_BLOB blob;
2848
2849	ZERO_STRUCTP(r);
2850
2851	sid_user = pdb_get_user_sid(pw);
2852
2853	if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
2854		DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
2855			  "the domain sid %s.  Failing operation.\n",
2856			  pdb_get_username(pw), sid_string_dbg(sid_user),
2857			  sid_string_dbg(domain_sid)));
2858		return NT_STATUS_UNSUCCESSFUL;
2859	}
2860
2861	become_root();
2862	sid_group = pdb_get_group_sid(pw);
2863	unbecome_root();
2864
2865	if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
2866		DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
2867			  "which conflicts with the domain sid %s.  Failing operation.\n",
2868			  pdb_get_username(pw), sid_string_dbg(sid_group),
2869			  sid_string_dbg(domain_sid)));
2870		return NT_STATUS_UNSUCCESSFUL;
2871	}
2872
2873	unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
2874	unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
2875	unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
2876	unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
2877	unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
2878
2879	must_change_time = pdb_get_pass_must_change_time(pw);
2880	if (must_change_time == get_time_t_max()) {
2881		unix_to_nt_time_abs(&force_password_change, must_change_time);
2882	} else {
2883		unix_to_nt_time(&force_password_change, must_change_time);
2884	}
2885
2886	munged_dial = pdb_get_munged_dial(pw);
2887	if (munged_dial) {
2888		blob = base64_decode_data_blob(munged_dial);
2889	} else {
2890		blob = data_blob_string_const_null("");
2891	}
2892
2893	status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
2894	data_blob_free(&blob);
2895	if (!NT_STATUS_IS_OK(status)) {
2896		return status;
2897	}
2898
2899	r->force_password_change	= force_password_change;
2900
2901	r->account_name.string		= talloc_strdup(mem_ctx, pdb_get_username(pw));
2902	r->full_name.string		= talloc_strdup(mem_ctx, pdb_get_fullname(pw));
2903	r->home_directory.string	= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
2904	r->home_drive.string		= talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
2905	r->logon_script.string		= talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
2906	r->profile_path.string		= talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
2907	r->description.string		= talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
2908	r->workstations.string		= talloc_strdup(mem_ctx, pdb_get_workstations(pw));
2909	r->comment.string		= talloc_strdup(mem_ctx, pdb_get_comment(pw));
2910
2911	r->logon_hours			= get_logon_hours_from_pdb(mem_ctx, pw);
2912	r->parameters			= *parameters;
2913	r->rid				= rid;
2914	r->primary_gid			= primary_gid;
2915	r->acct_flags			= pdb_get_acct_ctrl(pw);
2916	r->bad_password_count		= pdb_get_bad_password_count(pw);
2917	r->logon_count			= pdb_get_logon_count(pw);
2918	r->fields_present		= pdb_build_fields_present(pw);
2919	r->password_expired		= (pdb_get_pass_must_change_time(pw) == 0) ?
2920						PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
2921	r->country_code			= 0;
2922	r->code_page			= 0;
2923	r->lm_password_set		= 0;
2924	r->nt_password_set		= 0;
2925
2926#if 0
2927
2928	/*
2929	  Look at a user on a real NT4 PDC with usrmgr, press
2930	  'ok'. Then you will see that fields_present is set to
2931	  0x08f827fa. Look at the user immediately after that again,
2932	  and you will see that 0x00fffff is returned. This solves
2933	  the problem that you get access denied after having looked
2934	  at the user.
2935	  -- Volker
2936	*/
2937
2938#endif
2939
2940
2941	return NT_STATUS_OK;
2942}
2943
2944/*******************************************************************
2945 _samr_QueryUserInfo
2946 ********************************************************************/
2947
2948NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
2949			     struct samr_QueryUserInfo *r)
2950{
2951	NTSTATUS status;
2952	union samr_UserInfo *user_info = NULL;
2953	struct samr_user_info *uinfo;
2954	DOM_SID domain_sid;
2955	uint32 rid;
2956	bool ret = false;
2957	struct samu *pwd = NULL;
2958	uint32_t acc_required, acc_granted;
2959
2960	switch (r->in.level) {
2961	case 1: /* UserGeneralInformation */
2962		/* USER_READ_GENERAL */
2963		acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2964		break;
2965	case 2: /* UserPreferencesInformation */
2966		/* USER_READ_PREFERENCES | USER_READ_GENERAL */
2967		acc_required = SAMR_USER_ACCESS_GET_LOCALE |
2968			       SAMR_USER_ACCESS_GET_NAME_ETC;
2969		break;
2970	case 3: /* UserLogonInformation */
2971		/* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2972		acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2973			       SAMR_USER_ACCESS_GET_LOCALE |
2974			       SAMR_USER_ACCESS_GET_LOGONINFO |
2975			       SAMR_USER_ACCESS_GET_ATTRIBUTES;
2976		break;
2977	case 4: /* UserLogonHoursInformation */
2978		/* USER_READ_LOGON */
2979		acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
2980		break;
2981	case 5: /* UserAccountInformation */
2982		/* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
2983		acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
2984			       SAMR_USER_ACCESS_GET_LOCALE |
2985			       SAMR_USER_ACCESS_GET_LOGONINFO |
2986			       SAMR_USER_ACCESS_GET_ATTRIBUTES;
2987		break;
2988	case 6: /* UserNameInformation */
2989	case 7: /* UserAccountNameInformation */
2990	case 8: /* UserFullNameInformation */
2991	case 9: /* UserPrimaryGroupInformation */
2992	case 13: /* UserAdminCommentInformation */
2993		/* USER_READ_GENERAL */
2994		acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
2995		break;
2996	case 10: /* UserHomeInformation */
2997	case 11: /* UserScriptInformation */
2998	case 12: /* UserProfileInformation */
2999	case 14: /* UserWorkStationsInformation */
3000		/* USER_READ_LOGON */
3001		acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
3002		break;
3003	case 16: /* UserControlInformation */
3004	case 17: /* UserExpiresInformation */
3005	case 20: /* UserParametersInformation */
3006		/* USER_READ_ACCOUNT */
3007		acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3008		break;
3009	case 21: /* UserAllInformation */
3010		/* FIXME! - gd */
3011		acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3012		break;
3013	case 18: /* UserInternal1Information */
3014		/* FIXME! - gd */
3015		acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
3016		break;
3017	case 23: /* UserInternal4Information */
3018	case 24: /* UserInternal4InformationNew */
3019	case 25: /* UserInternal4InformationNew */
3020	case 26: /* UserInternal5InformationNew */
3021	default:
3022		return NT_STATUS_INVALID_INFO_CLASS;
3023		break;
3024	}
3025
3026	uinfo = policy_handle_find(p, r->in.user_handle,
3027				   acc_required, &acc_granted,
3028				   struct samr_user_info, &status);
3029	if (!NT_STATUS_IS_OK(status)) {
3030		return status;
3031	}
3032
3033	domain_sid = uinfo->sid;
3034
3035	sid_split_rid(&domain_sid, &rid);
3036
3037	if (!sid_check_is_in_our_domain(&uinfo->sid))
3038		return NT_STATUS_OBJECT_TYPE_MISMATCH;
3039
3040	DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
3041		 sid_string_dbg(&uinfo->sid)));
3042
3043	user_info = TALLOC_ZERO_P(p->mem_ctx, union samr_UserInfo);
3044	if (!user_info) {
3045		return NT_STATUS_NO_MEMORY;
3046	}
3047
3048	DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
3049
3050	if (!(pwd = samu_new(p->mem_ctx))) {
3051		return NT_STATUS_NO_MEMORY;
3052	}
3053
3054	become_root();
3055	ret = pdb_getsampwsid(pwd, &uinfo->sid);
3056	unbecome_root();
3057
3058	if (ret == false) {
3059		DEBUG(4,("User %s not found\n", sid_string_dbg(&uinfo->sid)));
3060		TALLOC_FREE(pwd);
3061		return NT_STATUS_NO_SUCH_USER;
3062	}
3063
3064	DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
3065
3066	samr_clear_sam_passwd(pwd);
3067
3068	switch (r->in.level) {
3069	case 1:
3070		status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
3071		break;
3072	case 2:
3073		status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
3074		break;
3075	case 3:
3076		status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
3077		break;
3078	case 4:
3079		status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
3080		break;
3081	case 5:
3082		status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
3083		break;
3084	case 6:
3085		status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
3086		break;
3087	case 7:
3088		status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
3089		break;
3090	case 8:
3091		status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
3092		break;
3093	case 9:
3094		status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
3095		break;
3096	case 10:
3097		status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
3098		break;
3099	case 11:
3100		status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
3101		break;
3102	case 12:
3103		status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
3104		break;
3105	case 13:
3106		status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
3107		break;
3108	case 14:
3109		status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
3110		break;
3111	case 16:
3112		status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
3113		break;
3114	case 17:
3115		status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
3116		break;
3117	case 18:
3118		/* level 18 is special */
3119		status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
3120					  &uinfo->sid);
3121		break;
3122	case 20:
3123		status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
3124		break;
3125	case 21:
3126		status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
3127		break;
3128	default:
3129		status = NT_STATUS_INVALID_INFO_CLASS;
3130		break;
3131	}
3132
3133	if (!NT_STATUS_IS_OK(status)) {
3134		goto done;
3135	}
3136
3137	*r->out.info = user_info;
3138
3139 done:
3140	TALLOC_FREE(pwd);
3141
3142	DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
3143
3144	return status;
3145}
3146
3147/****************************************************************
3148****************************************************************/
3149
3150NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
3151			      struct samr_QueryUserInfo2 *r)
3152{
3153	struct samr_QueryUserInfo u;
3154
3155	u.in.user_handle	= r->in.user_handle;
3156	u.in.level		= r->in.level;
3157	u.out.info		= r->out.info;
3158
3159	return _samr_QueryUserInfo(p, &u);
3160}
3161
3162/*******************************************************************
3163 _samr_GetGroupsForUser
3164 ********************************************************************/
3165
3166NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
3167				struct samr_GetGroupsForUser *r)
3168{
3169	struct samr_user_info *uinfo;
3170	struct samu *sam_pass=NULL;
3171	DOM_SID *sids;
3172	struct samr_RidWithAttribute dom_gid;
3173	struct samr_RidWithAttribute *gids = NULL;
3174	uint32 primary_group_rid;
3175	size_t num_groups = 0;
3176	gid_t *unix_gids;
3177	size_t i, num_gids;
3178	bool ret;
3179	NTSTATUS result;
3180	bool success = False;
3181
3182	struct samr_RidWithAttributeArray *rids = NULL;
3183
3184	/*
3185	 * from the SID in the request:
3186	 * we should send back the list of DOMAIN GROUPS
3187	 * the user is a member of
3188	 *
3189	 * and only the DOMAIN GROUPS
3190	 * no ALIASES !!! neither aliases of the domain
3191	 * nor aliases of the builtin SID
3192	 *
3193	 * JFM, 12/2/2001
3194	 */
3195
3196	DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3197
3198	uinfo = policy_handle_find(p, r->in.user_handle,
3199				   SAMR_USER_ACCESS_GET_GROUPS, NULL,
3200				   struct samr_user_info, &result);
3201	if (!NT_STATUS_IS_OK(result)) {
3202		return result;
3203	}
3204
3205	rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidWithAttributeArray);
3206	if (!rids) {
3207		return NT_STATUS_NO_MEMORY;
3208	}
3209
3210	if (!sid_check_is_in_our_domain(&uinfo->sid))
3211		return NT_STATUS_OBJECT_TYPE_MISMATCH;
3212
3213        if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
3214                return NT_STATUS_NO_MEMORY;
3215        }
3216
3217	become_root();
3218	ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
3219	unbecome_root();
3220
3221	if (!ret) {
3222		DEBUG(10, ("pdb_getsampwsid failed for %s\n",
3223			   sid_string_dbg(&uinfo->sid)));
3224		return NT_STATUS_NO_SUCH_USER;
3225	}
3226
3227	sids = NULL;
3228
3229	/* make both calls inside the root block */
3230	become_root();
3231	result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
3232					    &sids, &unix_gids, &num_groups);
3233	if ( NT_STATUS_IS_OK(result) ) {
3234		success = sid_peek_check_rid(get_global_sam_sid(),
3235					     pdb_get_group_sid(sam_pass),
3236					     &primary_group_rid);
3237	}
3238	unbecome_root();
3239
3240	if (!NT_STATUS_IS_OK(result)) {
3241		DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
3242			   sid_string_dbg(&uinfo->sid)));
3243		return result;
3244	}
3245
3246	if ( !success ) {
3247		DEBUG(5, ("Group sid %s for user %s not in our domain\n",
3248			  sid_string_dbg(pdb_get_group_sid(sam_pass)),
3249			  pdb_get_username(sam_pass)));
3250		TALLOC_FREE(sam_pass);
3251		return NT_STATUS_INTERNAL_DB_CORRUPTION;
3252	}
3253
3254	gids = NULL;
3255	num_gids = 0;
3256
3257	dom_gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
3258			      SE_GROUP_ENABLED);
3259	dom_gid.rid = primary_group_rid;
3260	ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3261
3262	for (i=0; i<num_groups; i++) {
3263
3264		if (!sid_peek_check_rid(get_global_sam_sid(),
3265					&(sids[i]), &dom_gid.rid)) {
3266			DEBUG(10, ("Found sid %s not in our domain\n",
3267				   sid_string_dbg(&sids[i])));
3268			continue;
3269		}
3270
3271		if (dom_gid.rid == primary_group_rid) {
3272			/* We added the primary group directly from the
3273			 * sam_account. The other SIDs are unique from
3274			 * enum_group_memberships */
3275			continue;
3276		}
3277
3278		ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
3279	}
3280
3281	rids->count = num_gids;
3282	rids->rids = gids;
3283
3284	*r->out.rids = rids;
3285
3286	DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
3287
3288	return result;
3289}
3290
3291/*******************************************************************
3292 ********************************************************************/
3293
3294static uint32_t samr_get_server_role(void)
3295{
3296	uint32_t role = ROLE_DOMAIN_PDC;
3297
3298	if (lp_server_role() == ROLE_DOMAIN_BDC) {
3299		role = ROLE_DOMAIN_BDC;
3300	}
3301
3302	return role;
3303}
3304
3305/*******************************************************************
3306 ********************************************************************/
3307
3308static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
3309				 struct samr_DomInfo1 *r)
3310{
3311	uint32_t account_policy_temp;
3312	time_t u_expire, u_min_age;
3313
3314	become_root();
3315
3316	/* AS ROOT !!! */
3317
3318	pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
3319	r->min_password_length = account_policy_temp;
3320
3321	pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
3322	r->password_history_length = account_policy_temp;
3323
3324	pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
3325			       &r->password_properties);
3326
3327	pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
3328	u_expire = account_policy_temp;
3329
3330	pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
3331	u_min_age = account_policy_temp;
3332
3333	/* !AS ROOT */
3334
3335	unbecome_root();
3336
3337	unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
3338	unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
3339
3340	if (lp_check_password_script() && *lp_check_password_script()) {
3341		r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
3342	}
3343
3344	return NT_STATUS_OK;
3345}
3346
3347/*******************************************************************
3348 ********************************************************************/
3349
3350static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
3351				 struct samr_DomGeneralInformation *r,
3352				 struct samr_domain_info *dinfo)
3353{
3354	uint32_t u_logout;
3355	time_t seq_num;
3356
3357	become_root();
3358
3359	/* AS ROOT !!! */
3360
3361	r->num_users	= count_sam_users(dinfo->disp_info, ACB_NORMAL);
3362	r->num_groups	= count_sam_groups(dinfo->disp_info);
3363	r->num_aliases	= count_sam_aliases(dinfo->disp_info);
3364
3365	pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
3366
3367	unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3368
3369	if (!pdb_get_seq_num(&seq_num)) {
3370		seq_num = time(NULL);
3371	}
3372
3373	/* !AS ROOT */
3374
3375	unbecome_root();
3376
3377	r->oem_information.string	= lp_serverstring();
3378	r->domain_name.string		= lp_workgroup();
3379	r->primary.string		= global_myname();
3380	r->sequence_num			= seq_num;
3381	r->domain_server_state		= DOMAIN_SERVER_ENABLED;
3382	r->role				= samr_get_server_role();
3383	r->unknown3			= 1;
3384
3385	return NT_STATUS_OK;
3386}
3387
3388/*******************************************************************
3389 ********************************************************************/
3390
3391static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
3392				 struct samr_DomInfo3 *r)
3393{
3394	uint32_t u_logout;
3395
3396	become_root();
3397
3398	/* AS ROOT !!! */
3399
3400	{
3401		uint32_t ul;
3402		pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
3403		u_logout = (time_t)ul;
3404	}
3405
3406	/* !AS ROOT */
3407
3408	unbecome_root();
3409
3410	unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
3411
3412	return NT_STATUS_OK;
3413}
3414
3415/*******************************************************************
3416 ********************************************************************/
3417
3418static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
3419				 struct samr_DomOEMInformation *r)
3420{
3421	r->oem_information.string = lp_serverstring();
3422
3423	return NT_STATUS_OK;
3424}
3425
3426/*******************************************************************
3427 ********************************************************************/
3428
3429static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
3430				 struct samr_DomInfo5 *r)
3431{
3432	r->domain_name.string = get_global_sam_name();
3433
3434	return NT_STATUS_OK;
3435}
3436
3437/*******************************************************************
3438 ********************************************************************/
3439
3440static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
3441				 struct samr_DomInfo6 *r)
3442{
3443	/* NT returns its own name when a PDC. win2k and later
3444	 * only the name of the PDC if itself is a BDC (samba4
3445	 * idl) */
3446	r->primary.string = global_myname();
3447
3448	return NT_STATUS_OK;
3449}
3450
3451/*******************************************************************
3452 ********************************************************************/
3453
3454static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
3455				 struct samr_DomInfo7 *r)
3456{
3457	r->role = samr_get_server_role();
3458
3459	return NT_STATUS_OK;
3460}
3461
3462/*******************************************************************
3463 ********************************************************************/
3464
3465static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
3466				 struct samr_DomInfo8 *r)
3467{
3468	time_t seq_num;
3469
3470	become_root();
3471
3472	/* AS ROOT !!! */
3473
3474	if (!pdb_get_seq_num(&seq_num)) {
3475		seq_num = time(NULL);
3476	}
3477
3478	/* !AS ROOT */
3479
3480	unbecome_root();
3481
3482	r->sequence_num = seq_num;
3483	r->domain_create_time = 0;
3484
3485	return NT_STATUS_OK;
3486}
3487
3488/*******************************************************************
3489 ********************************************************************/
3490
3491static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
3492				 struct samr_DomInfo9 *r)
3493{
3494	r->domain_server_state = DOMAIN_SERVER_ENABLED;
3495
3496	return NT_STATUS_OK;
3497}
3498
3499/*******************************************************************
3500 ********************************************************************/
3501
3502static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
3503				  struct samr_DomGeneralInformation2 *r,
3504				  struct samr_domain_info *dinfo)
3505{
3506	NTSTATUS status;
3507	uint32_t account_policy_temp;
3508	time_t u_lock_duration, u_reset_time;
3509
3510	status = query_dom_info_2(mem_ctx, &r->general, dinfo);
3511	if (!NT_STATUS_IS_OK(status)) {
3512		return status;
3513	}
3514
3515	/* AS ROOT !!! */
3516
3517	become_root();
3518
3519	pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3520	u_lock_duration = account_policy_temp;
3521	if (u_lock_duration != -1) {
3522		u_lock_duration *= 60;
3523	}
3524
3525	pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3526	u_reset_time = account_policy_temp * 60;
3527
3528	pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3529	r->lockout_threshold = account_policy_temp;
3530
3531	/* !AS ROOT */
3532
3533	unbecome_root();
3534
3535	unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3536	unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3537
3538	return NT_STATUS_OK;
3539}
3540
3541/*******************************************************************
3542 ********************************************************************/
3543
3544static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
3545				  struct samr_DomInfo12 *r)
3546{
3547	uint32_t account_policy_temp;
3548	time_t u_lock_duration, u_reset_time;
3549
3550	become_root();
3551
3552	/* AS ROOT !!! */
3553
3554	pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
3555	u_lock_duration = account_policy_temp;
3556	if (u_lock_duration != -1) {
3557		u_lock_duration *= 60;
3558	}
3559
3560	pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
3561	u_reset_time = account_policy_temp * 60;
3562
3563	pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
3564	r->lockout_threshold = account_policy_temp;
3565
3566	/* !AS ROOT */
3567
3568	unbecome_root();
3569
3570	unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
3571	unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
3572
3573	return NT_STATUS_OK;
3574}
3575
3576/*******************************************************************
3577 ********************************************************************/
3578
3579static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
3580				  struct samr_DomInfo13 *r)
3581{
3582	time_t seq_num;
3583
3584	become_root();
3585
3586	/* AS ROOT !!! */
3587
3588	if (!pdb_get_seq_num(&seq_num)) {
3589		seq_num = time(NULL);
3590	}
3591
3592	/* !AS ROOT */
3593
3594	unbecome_root();
3595
3596	r->sequence_num = seq_num;
3597	r->domain_create_time = 0;
3598	r->modified_count_at_last_promotion = 0;
3599
3600	return NT_STATUS_OK;
3601}
3602
3603/*******************************************************************
3604 _samr_QueryDomainInfo
3605 ********************************************************************/
3606
3607NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
3608			       struct samr_QueryDomainInfo *r)
3609{
3610	NTSTATUS status = NT_STATUS_OK;
3611	struct samr_domain_info *dinfo;
3612	union samr_DomainInfo *dom_info;
3613
3614	uint32_t acc_required;
3615
3616	DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3617
3618	switch (r->in.level) {
3619	case 1: /* DomainPasswordInformation */
3620	case 12: /* DomainLockoutInformation */
3621		/* DOMAIN_READ_PASSWORD_PARAMETERS */
3622		acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
3623		break;
3624	case 11: /* DomainGeneralInformation2 */
3625		/* DOMAIN_READ_PASSWORD_PARAMETERS |
3626		 * DOMAIN_READ_OTHER_PARAMETERS */
3627		acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
3628			       SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3629		break;
3630	case 2: /* DomainGeneralInformation */
3631	case 3: /* DomainLogoffInformation */
3632	case 4: /* DomainOemInformation */
3633	case 5: /* DomainReplicationInformation */
3634	case 6: /* DomainReplicationInformation */
3635	case 7: /* DomainServerRoleInformation */
3636	case 8: /* DomainModifiedInformation */
3637	case 9: /* DomainStateInformation */
3638	case 10: /* DomainUasInformation */
3639	case 13: /* DomainModifiedInformation2 */
3640		/* DOMAIN_READ_OTHER_PARAMETERS */
3641		acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
3642		break;
3643	default:
3644		return NT_STATUS_INVALID_INFO_CLASS;
3645	}
3646
3647	dinfo = policy_handle_find(p, r->in.domain_handle,
3648				   acc_required, NULL,
3649				   struct samr_domain_info, &status);
3650	if (!NT_STATUS_IS_OK(status)) {
3651		return status;
3652	}
3653
3654	dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
3655	if (!dom_info) {
3656		return NT_STATUS_NO_MEMORY;
3657	}
3658
3659	switch (r->in.level) {
3660		case 1:
3661			status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
3662			break;
3663		case 2:
3664			status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
3665			break;
3666		case 3:
3667			status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
3668			break;
3669		case 4:
3670			status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
3671			break;
3672		case 5:
3673			status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
3674			break;
3675		case 6:
3676			status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
3677			break;
3678		case 7:
3679			status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
3680			break;
3681		case 8:
3682			status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
3683			break;
3684		case 9:
3685			status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
3686			break;
3687		case 11:
3688			status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
3689			break;
3690		case 12:
3691			status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
3692			break;
3693		case 13:
3694			status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
3695			break;
3696        	default:
3697            		return NT_STATUS_INVALID_INFO_CLASS;
3698	}
3699
3700	if (!NT_STATUS_IS_OK(status)) {
3701		return status;
3702	}
3703
3704	*r->out.info = dom_info;
3705
3706	DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
3707
3708	return status;
3709}
3710
3711/* W2k3 seems to use the same check for all 3 objects that can be created via
3712 * SAMR, if you try to create for example "Dialup" as an alias it says
3713 * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
3714 * database. */
3715
3716static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
3717{
3718	enum lsa_SidType type;
3719	bool result;
3720
3721	DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
3722
3723	become_root();
3724	/* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
3725	 * whether the name already exists */
3726	result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
3727			     NULL, NULL, NULL, &type);
3728	unbecome_root();
3729
3730	if (!result) {
3731		DEBUG(10, ("%s does not exist, can create it\n", new_name));
3732		return NT_STATUS_OK;
3733	}
3734
3735	DEBUG(5, ("trying to create %s, exists as %s\n",
3736		  new_name, sid_type_lookup(type)));
3737
3738	if (type == SID_NAME_DOM_GRP) {
3739		return NT_STATUS_GROUP_EXISTS;
3740	}
3741	if (type == SID_NAME_ALIAS) {
3742		return NT_STATUS_ALIAS_EXISTS;
3743	}
3744
3745	/* Yes, the default is NT_STATUS_USER_EXISTS */
3746	return NT_STATUS_USER_EXISTS;
3747}
3748
3749/*******************************************************************
3750 _samr_CreateUser2
3751 ********************************************************************/
3752
3753NTSTATUS _samr_CreateUser2(pipes_struct *p,
3754			   struct samr_CreateUser2 *r)
3755{
3756	const char *account = NULL;
3757	DOM_SID sid;
3758	uint32_t acb_info = r->in.acct_flags;
3759	struct samr_domain_info *dinfo;
3760	struct samr_user_info *uinfo;
3761	NTSTATUS nt_status;
3762	uint32 acc_granted;
3763	SEC_DESC *psd;
3764	size_t    sd_size;
3765	/* check this, when giving away 'add computer to domain' privs */
3766	uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
3767	bool can_add_account = False;
3768	SE_PRIV se_rights;
3769
3770	dinfo = policy_handle_find(p, r->in.domain_handle,
3771				   SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
3772				   struct samr_domain_info, &nt_status);
3773	if (!NT_STATUS_IS_OK(nt_status)) {
3774		return nt_status;
3775	}
3776
3777	if (sid_check_is_builtin(&dinfo->sid)) {
3778		DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
3779		return NT_STATUS_ACCESS_DENIED;
3780	}
3781
3782	if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
3783	      acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
3784		/* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
3785		   this parameter is not an account type */
3786		return NT_STATUS_INVALID_PARAMETER;
3787	}
3788
3789	account = r->in.account_name->string;
3790	if (account == NULL) {
3791		return NT_STATUS_NO_MEMORY;
3792	}
3793
3794	nt_status = can_create(p->mem_ctx, account);
3795	if (!NT_STATUS_IS_OK(nt_status)) {
3796		return nt_status;
3797	}
3798
3799	/* determine which user right we need to check based on the acb_info */
3800
3801	if (geteuid() == sec_initial_uid()) {
3802		se_priv_copy(&se_rights, &se_priv_none);
3803		can_add_account = true;
3804	} else if (acb_info & ACB_WSTRUST) {
3805		se_priv_copy(&se_rights, &se_machine_account);
3806		can_add_account = user_has_privileges(
3807			p->server_info->ptok, &se_rights );
3808	} else if (acb_info & ACB_NORMAL &&
3809		  (account[strlen(account)-1] != '$')) {
3810		/* usrmgr.exe (and net rpc trustdom grant) creates a normal user
3811		   account for domain trusts and changes the ACB flags later */
3812		se_priv_copy(&se_rights, &se_add_users);
3813		can_add_account = user_has_privileges(
3814			p->server_info->ptok, &se_rights );
3815	} else if (lp_enable_privileges()) {
3816		/* implicit assumption of a BDC or domain trust account here
3817		 * (we already check the flags earlier) */
3818		/* only Domain Admins can add a BDC or domain trust */
3819		se_priv_copy(&se_rights, &se_priv_none);
3820		can_add_account = nt_token_check_domain_rid(
3821			p->server_info->ptok,
3822			DOMAIN_GROUP_RID_ADMINS );
3823	}
3824
3825	DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
3826		  uidtoname(p->server_info->utok.uid),
3827		  can_add_account ? "True":"False" ));
3828
3829	if (!can_add_account) {
3830		return NT_STATUS_ACCESS_DENIED;
3831	}
3832
3833	/********** BEGIN Admin BLOCK **********/
3834
3835	become_root();
3836	nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
3837				    r->out.rid);
3838	unbecome_root();
3839
3840	/********** END Admin BLOCK **********/
3841
3842	/* now check for failure */
3843
3844	if ( !NT_STATUS_IS_OK(nt_status) )
3845		return nt_status;
3846
3847	/* Get the user's SID */
3848
3849	sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
3850
3851	map_max_allowed_access(p->server_info->ptok,
3852			       &p->server_info->utok,
3853			       &des_access);
3854
3855	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
3856			    &sid, SAMR_USR_RIGHTS_WRITE_PW);
3857	se_map_generic(&des_access, &usr_generic_mapping);
3858
3859	/*
3860	 * JRA - TESTME. We just created this user so we
3861	 * had rights to create them. Do we need to check
3862	 * any further access on this object ? Can't we
3863	 * just assume we have all the rights we need ?
3864	 */
3865
3866	nt_status = access_check_object(psd, p->server_info->ptok,
3867		&se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
3868		&acc_granted, "_samr_CreateUser2");
3869
3870	if ( !NT_STATUS_IS_OK(nt_status) ) {
3871		return nt_status;
3872	}
3873
3874	uinfo = policy_handle_create(p, r->out.user_handle, acc_granted,
3875				     struct samr_user_info, &nt_status);
3876	if (!NT_STATUS_IS_OK(nt_status)) {
3877		return nt_status;
3878	}
3879	uinfo->sid = sid;
3880
3881	/* After a "set" ensure we have no cached display info. */
3882	force_flush_samr_cache(&sid);
3883
3884	*r->out.access_granted = acc_granted;
3885
3886	return NT_STATUS_OK;
3887}
3888
3889/****************************************************************
3890****************************************************************/
3891
3892NTSTATUS _samr_CreateUser(pipes_struct *p,
3893			  struct samr_CreateUser *r)
3894{
3895	struct samr_CreateUser2 c;
3896	uint32_t access_granted;
3897
3898	c.in.domain_handle	= r->in.domain_handle;
3899	c.in.account_name	= r->in.account_name;
3900	c.in.acct_flags		= ACB_NORMAL;
3901	c.in.access_mask	= r->in.access_mask;
3902	c.out.user_handle	= r->out.user_handle;
3903	c.out.access_granted	= &access_granted;
3904	c.out.rid		= r->out.rid;
3905
3906	return _samr_CreateUser2(p, &c);
3907}
3908
3909/*******************************************************************
3910 _samr_Connect
3911 ********************************************************************/
3912
3913NTSTATUS _samr_Connect(pipes_struct *p,
3914		       struct samr_Connect *r)
3915{
3916	struct samr_connect_info *info;
3917	uint32_t acc_granted;
3918	struct policy_handle hnd;
3919	uint32    des_access = r->in.access_mask;
3920	NTSTATUS status;
3921
3922	/* Access check */
3923
3924	if (!pipe_access_check(p)) {
3925		DEBUG(3, ("access denied to _samr_Connect\n"));
3926		return NT_STATUS_ACCESS_DENIED;
3927	}
3928
3929	/* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
3930	   was observed from a win98 client trying to enumerate users (when configured
3931	   user level access control on shares)   --jerry */
3932
3933	map_max_allowed_access(p->server_info->ptok,
3934			       &p->server_info->utok,
3935			       &des_access);
3936
3937	se_map_generic( &des_access, &sam_generic_mapping );
3938
3939	acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
3940				    |SAMR_ACCESS_LOOKUP_DOMAIN);
3941
3942	/* set up the SAMR connect_anon response */
3943
3944	info = policy_handle_create(p, &hnd, acc_granted,
3945				    struct samr_connect_info,
3946				    &status);
3947	if (!NT_STATUS_IS_OK(status)) {
3948		return status;
3949	}
3950
3951	*r->out.connect_handle = hnd;
3952	return NT_STATUS_OK;
3953}
3954
3955/*******************************************************************
3956 _samr_Connect2
3957 ********************************************************************/
3958
3959NTSTATUS _samr_Connect2(pipes_struct *p,
3960			struct samr_Connect2 *r)
3961{
3962	struct samr_connect_info *info = NULL;
3963	struct policy_handle hnd;
3964	SEC_DESC *psd = NULL;
3965	uint32    acc_granted;
3966	uint32    des_access = r->in.access_mask;
3967	NTSTATUS  nt_status;
3968	size_t    sd_size;
3969	const char *fn = "_samr_Connect2";
3970
3971	switch (p->hdr_req.opnum) {
3972	case NDR_SAMR_CONNECT2:
3973		fn = "_samr_Connect2";
3974		break;
3975	case NDR_SAMR_CONNECT3:
3976		fn = "_samr_Connect3";
3977		break;
3978	case NDR_SAMR_CONNECT4:
3979		fn = "_samr_Connect4";
3980		break;
3981	case NDR_SAMR_CONNECT5:
3982		fn = "_samr_Connect5";
3983		break;
3984	}
3985
3986	DEBUG(5,("%s: %d\n", fn, __LINE__));
3987
3988	/* Access check */
3989
3990	if (!pipe_access_check(p)) {
3991		DEBUG(3, ("access denied to %s\n", fn));
3992		return NT_STATUS_ACCESS_DENIED;
3993	}
3994
3995	map_max_allowed_access(p->server_info->ptok,
3996			       &p->server_info->utok,
3997			       &des_access);
3998
3999	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
4000	se_map_generic(&des_access, &sam_generic_mapping);
4001
4002	nt_status = access_check_object(psd, p->server_info->ptok,
4003		NULL, 0, des_access, &acc_granted, fn);
4004
4005	if ( !NT_STATUS_IS_OK(nt_status) )
4006		return nt_status;
4007
4008	info = policy_handle_create(p, &hnd, acc_granted,
4009				    struct samr_connect_info, &nt_status);
4010        if (!NT_STATUS_IS_OK(nt_status)) {
4011                return nt_status;
4012        }
4013
4014	DEBUG(5,("%s: %d\n", fn, __LINE__));
4015
4016	*r->out.connect_handle = hnd;
4017	return NT_STATUS_OK;
4018}
4019
4020/****************************************************************
4021 _samr_Connect3
4022****************************************************************/
4023
4024NTSTATUS _samr_Connect3(pipes_struct *p,
4025			struct samr_Connect3 *r)
4026{
4027	struct samr_Connect2 c;
4028
4029	c.in.system_name	= r->in.system_name;
4030	c.in.access_mask	= r->in.access_mask;
4031	c.out.connect_handle	= r->out.connect_handle;
4032
4033	return _samr_Connect2(p, &c);
4034}
4035
4036/*******************************************************************
4037 _samr_Connect4
4038 ********************************************************************/
4039
4040NTSTATUS _samr_Connect4(pipes_struct *p,
4041			struct samr_Connect4 *r)
4042{
4043	struct samr_Connect2 c;
4044
4045	c.in.system_name	= r->in.system_name;
4046	c.in.access_mask	= r->in.access_mask;
4047	c.out.connect_handle	= r->out.connect_handle;
4048
4049	return _samr_Connect2(p, &c);
4050}
4051
4052/*******************************************************************
4053 _samr_Connect5
4054 ********************************************************************/
4055
4056NTSTATUS _samr_Connect5(pipes_struct *p,
4057			struct samr_Connect5 *r)
4058{
4059	NTSTATUS status;
4060	struct samr_Connect2 c;
4061	struct samr_ConnectInfo1 info1;
4062
4063	info1.client_version = SAMR_CONNECT_AFTER_W2K;
4064	info1.unknown2 = 0;
4065
4066	c.in.system_name	= r->in.system_name;
4067	c.in.access_mask	= r->in.access_mask;
4068	c.out.connect_handle	= r->out.connect_handle;
4069
4070	*r->out.level_out = 1;
4071
4072	status = _samr_Connect2(p, &c);
4073	if (!NT_STATUS_IS_OK(status)) {
4074		return status;
4075	}
4076
4077	r->out.info_out->info1 = info1;
4078
4079	return NT_STATUS_OK;
4080}
4081
4082/**********************************************************************
4083 _samr_LookupDomain
4084 **********************************************************************/
4085
4086NTSTATUS _samr_LookupDomain(pipes_struct *p,
4087			    struct samr_LookupDomain *r)
4088{
4089	NTSTATUS status;
4090	struct samr_connect_info *info;
4091	const char *domain_name;
4092	DOM_SID *sid = NULL;
4093
4094	/* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
4095	   Reverted that change so we will work with RAS servers again */
4096
4097	info = policy_handle_find(p, r->in.connect_handle,
4098				  SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
4099				  struct samr_connect_info,
4100				  &status);
4101	if (!NT_STATUS_IS_OK(status)) {
4102		return status;
4103	}
4104
4105	domain_name = r->in.domain_name->string;
4106	if (!domain_name) {
4107		return NT_STATUS_INVALID_PARAMETER;
4108	}
4109
4110	sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
4111	if (!sid) {
4112		return NT_STATUS_NO_MEMORY;
4113	}
4114
4115	if (strequal(domain_name, builtin_domain_name())) {
4116		sid_copy(sid, &global_sid_Builtin);
4117	} else {
4118		if (!secrets_fetch_domain_sid(domain_name, sid)) {
4119			status = NT_STATUS_NO_SUCH_DOMAIN;
4120		}
4121	}
4122
4123	DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
4124		 sid_string_dbg(sid)));
4125
4126	*r->out.sid = sid;
4127
4128	return status;
4129}
4130
4131/**********************************************************************
4132 _samr_EnumDomains
4133 **********************************************************************/
4134
4135NTSTATUS _samr_EnumDomains(pipes_struct *p,
4136			   struct samr_EnumDomains *r)
4137{
4138	NTSTATUS status;
4139	struct samr_connect_info *info;
4140	uint32_t num_entries = 2;
4141	struct samr_SamEntry *entry_array = NULL;
4142	struct samr_SamArray *sam;
4143
4144	info = policy_handle_find(p, r->in.connect_handle,
4145				  SAMR_ACCESS_ENUM_DOMAINS, NULL,
4146				  struct samr_connect_info, &status);
4147	if (!NT_STATUS_IS_OK(status)) {
4148		return status;
4149	}
4150
4151	sam = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
4152	if (!sam) {
4153		return NT_STATUS_NO_MEMORY;
4154	}
4155
4156	entry_array = TALLOC_ZERO_ARRAY(p->mem_ctx,
4157					struct samr_SamEntry,
4158					num_entries);
4159	if (!entry_array) {
4160		return NT_STATUS_NO_MEMORY;
4161	}
4162
4163	entry_array[0].idx = 0;
4164	init_lsa_String(&entry_array[0].name, get_global_sam_name());
4165
4166	entry_array[1].idx = 1;
4167	init_lsa_String(&entry_array[1].name, "Builtin");
4168
4169	sam->count = num_entries;
4170	sam->entries = entry_array;
4171
4172	*r->out.sam = sam;
4173	*r->out.num_entries = num_entries;
4174
4175	return status;
4176}
4177
4178/*******************************************************************
4179 _samr_OpenAlias
4180 ********************************************************************/
4181
4182NTSTATUS _samr_OpenAlias(pipes_struct *p,
4183			 struct samr_OpenAlias *r)
4184{
4185	DOM_SID sid;
4186	uint32 alias_rid = r->in.rid;
4187	struct samr_alias_info *ainfo;
4188	struct samr_domain_info *dinfo;
4189	SEC_DESC *psd = NULL;
4190	uint32    acc_granted;
4191	uint32    des_access = r->in.access_mask;
4192	size_t    sd_size;
4193	NTSTATUS  status;
4194	SE_PRIV se_rights;
4195
4196	dinfo = policy_handle_find(p, r->in.domain_handle,
4197				   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
4198				   struct samr_domain_info, &status);
4199	if (!NT_STATUS_IS_OK(status)) {
4200		return status;
4201	}
4202
4203	/* append the alias' RID to it */
4204
4205	if (!sid_compose(&sid, &dinfo->sid, alias_rid))
4206		return NT_STATUS_NO_SUCH_ALIAS;
4207
4208	/*check if access can be granted as requested by client. */
4209
4210	map_max_allowed_access(p->server_info->ptok,
4211			       &p->server_info->utok,
4212			       &des_access);
4213
4214	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
4215	se_map_generic(&des_access,&ali_generic_mapping);
4216
4217	se_priv_copy( &se_rights, &se_add_users );
4218
4219	status = access_check_object(psd, p->server_info->ptok,
4220		&se_rights, GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
4221		des_access, &acc_granted, "_samr_OpenAlias");
4222
4223	if ( !NT_STATUS_IS_OK(status) )
4224		return status;
4225
4226	{
4227		/* Check we actually have the requested alias */
4228		enum lsa_SidType type;
4229		bool result;
4230		gid_t gid;
4231
4232		become_root();
4233		result = lookup_sid(NULL, &sid, NULL, NULL, &type);
4234		unbecome_root();
4235
4236		if (!result || (type != SID_NAME_ALIAS)) {
4237			return NT_STATUS_NO_SUCH_ALIAS;
4238		}
4239
4240		/* make sure there is a mapping */
4241
4242		if ( !sid_to_gid( &sid, &gid ) ) {
4243			return NT_STATUS_NO_SUCH_ALIAS;
4244		}
4245
4246	}
4247
4248	ainfo = policy_handle_create(p, r->out.alias_handle, acc_granted,
4249				     struct samr_alias_info, &status);
4250	if (!NT_STATUS_IS_OK(status)) {
4251		return status;
4252	}
4253	ainfo->sid = sid;
4254
4255	return NT_STATUS_OK;
4256}
4257
4258/*******************************************************************
4259 set_user_info_2
4260 ********************************************************************/
4261
4262static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
4263				struct samr_UserInfo2 *id2,
4264				struct samu *pwd)
4265{
4266	if (id2 == NULL) {
4267		DEBUG(5,("set_user_info_2: NULL id2\n"));
4268		return NT_STATUS_ACCESS_DENIED;
4269	}
4270
4271	copy_id2_to_sam_passwd(pwd, id2);
4272
4273	return pdb_update_sam_account(pwd);
4274}
4275
4276/*******************************************************************
4277 set_user_info_4
4278 ********************************************************************/
4279
4280static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
4281				struct samr_UserInfo4 *id4,
4282				struct samu *pwd)
4283{
4284	if (id4 == NULL) {
4285		DEBUG(5,("set_user_info_2: NULL id4\n"));
4286		return NT_STATUS_ACCESS_DENIED;
4287	}
4288
4289	copy_id4_to_sam_passwd(pwd, id4);
4290
4291	return pdb_update_sam_account(pwd);
4292}
4293
4294/*******************************************************************
4295 set_user_info_6
4296 ********************************************************************/
4297
4298static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
4299				struct samr_UserInfo6 *id6,
4300				struct samu *pwd)
4301{
4302	if (id6 == NULL) {
4303		DEBUG(5,("set_user_info_6: NULL id6\n"));
4304		return NT_STATUS_ACCESS_DENIED;
4305	}
4306
4307	copy_id6_to_sam_passwd(pwd, id6);
4308
4309	return pdb_update_sam_account(pwd);
4310}
4311
4312/*******************************************************************
4313 set_user_info_7
4314 ********************************************************************/
4315
4316static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
4317				struct samr_UserInfo7 *id7,
4318				struct samu *pwd)
4319{
4320	NTSTATUS rc;
4321
4322	if (id7 == NULL) {
4323		DEBUG(5, ("set_user_info_7: NULL id7\n"));
4324		return NT_STATUS_ACCESS_DENIED;
4325	}
4326
4327	if (!id7->account_name.string) {
4328	        DEBUG(5, ("set_user_info_7: failed to get new username\n"));
4329		return NT_STATUS_ACCESS_DENIED;
4330	}
4331
4332	/* check to see if the new username already exists.  Note: we can't
4333	   reliably lock all backends, so there is potentially the
4334	   possibility that a user can be created in between this check and
4335	   the rename.  The rename should fail, but may not get the
4336	   exact same failure status code.  I think this is small enough
4337	   of a window for this type of operation and the results are
4338	   simply that the rename fails with a slightly different status
4339	   code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4340
4341	rc = can_create(mem_ctx, id7->account_name.string);
4342
4343	/* when there is nothing to change, we're done here */
4344	if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
4345	    strequal(id7->account_name.string, pdb_get_username(pwd))) {
4346		return NT_STATUS_OK;
4347	}
4348	if (!NT_STATUS_IS_OK(rc)) {
4349		return rc;
4350	}
4351
4352	rc = pdb_rename_sam_account(pwd, id7->account_name.string);
4353
4354	return rc;
4355}
4356
4357/*******************************************************************
4358 set_user_info_8
4359 ********************************************************************/
4360
4361static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
4362				struct samr_UserInfo8 *id8,
4363				struct samu *pwd)
4364{
4365	if (id8 == NULL) {
4366		DEBUG(5,("set_user_info_8: NULL id8\n"));
4367		return NT_STATUS_ACCESS_DENIED;
4368	}
4369
4370	copy_id8_to_sam_passwd(pwd, id8);
4371
4372	return pdb_update_sam_account(pwd);
4373}
4374
4375/*******************************************************************
4376 set_user_info_10
4377 ********************************************************************/
4378
4379static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
4380				 struct samr_UserInfo10 *id10,
4381				 struct samu *pwd)
4382{
4383	if (id10 == NULL) {
4384		DEBUG(5,("set_user_info_8: NULL id10\n"));
4385		return NT_STATUS_ACCESS_DENIED;
4386	}
4387
4388	copy_id10_to_sam_passwd(pwd, id10);
4389
4390	return pdb_update_sam_account(pwd);
4391}
4392
4393/*******************************************************************
4394 set_user_info_11
4395 ********************************************************************/
4396
4397static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
4398				 struct samr_UserInfo11 *id11,
4399				 struct samu *pwd)
4400{
4401	if (id11 == NULL) {
4402		DEBUG(5,("set_user_info_11: NULL id11\n"));
4403		return NT_STATUS_ACCESS_DENIED;
4404	}
4405
4406	copy_id11_to_sam_passwd(pwd, id11);
4407
4408	return pdb_update_sam_account(pwd);
4409}
4410
4411/*******************************************************************
4412 set_user_info_12
4413 ********************************************************************/
4414
4415static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
4416				 struct samr_UserInfo12 *id12,
4417				 struct samu *pwd)
4418{
4419	if (id12 == NULL) {
4420		DEBUG(5,("set_user_info_12: NULL id12\n"));
4421		return NT_STATUS_ACCESS_DENIED;
4422	}
4423
4424	copy_id12_to_sam_passwd(pwd, id12);
4425
4426	return pdb_update_sam_account(pwd);
4427}
4428
4429/*******************************************************************
4430 set_user_info_13
4431 ********************************************************************/
4432
4433static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
4434				 struct samr_UserInfo13 *id13,
4435				 struct samu *pwd)
4436{
4437	if (id13 == NULL) {
4438		DEBUG(5,("set_user_info_13: NULL id13\n"));
4439		return NT_STATUS_ACCESS_DENIED;
4440	}
4441
4442	copy_id13_to_sam_passwd(pwd, id13);
4443
4444	return pdb_update_sam_account(pwd);
4445}
4446
4447/*******************************************************************
4448 set_user_info_14
4449 ********************************************************************/
4450
4451static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
4452				 struct samr_UserInfo14 *id14,
4453				 struct samu *pwd)
4454{
4455	if (id14 == NULL) {
4456		DEBUG(5,("set_user_info_14: NULL id14\n"));
4457		return NT_STATUS_ACCESS_DENIED;
4458	}
4459
4460	copy_id14_to_sam_passwd(pwd, id14);
4461
4462	return pdb_update_sam_account(pwd);
4463}
4464
4465/*******************************************************************
4466 set_user_info_16
4467 ********************************************************************/
4468
4469static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
4470				 struct samr_UserInfo16 *id16,
4471				 struct samu *pwd)
4472{
4473	if (id16 == NULL) {
4474		DEBUG(5,("set_user_info_16: NULL id16\n"));
4475		return NT_STATUS_ACCESS_DENIED;
4476	}
4477
4478	copy_id16_to_sam_passwd(pwd, id16);
4479
4480	return pdb_update_sam_account(pwd);
4481}
4482
4483/*******************************************************************
4484 set_user_info_17
4485 ********************************************************************/
4486
4487static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
4488				 struct samr_UserInfo17 *id17,
4489				 struct samu *pwd)
4490{
4491	if (id17 == NULL) {
4492		DEBUG(5,("set_user_info_17: NULL id17\n"));
4493		return NT_STATUS_ACCESS_DENIED;
4494	}
4495
4496	copy_id17_to_sam_passwd(pwd, id17);
4497
4498	return pdb_update_sam_account(pwd);
4499}
4500
4501/*******************************************************************
4502 set_user_info_18
4503 ********************************************************************/
4504
4505static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
4506				 TALLOC_CTX *mem_ctx,
4507				 DATA_BLOB *session_key,
4508				 struct samu *pwd)
4509{
4510	if (id18 == NULL) {
4511		DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
4512		return NT_STATUS_INVALID_PARAMETER;
4513	}
4514
4515	if (id18->nt_pwd_active || id18->lm_pwd_active) {
4516		if (!session_key->length) {
4517			return NT_STATUS_NO_USER_SESSION_KEY;
4518		}
4519	}
4520
4521	if (id18->nt_pwd_active) {
4522
4523		DATA_BLOB in, out;
4524
4525		in = data_blob_const(id18->nt_pwd.hash, 16);
4526		out = data_blob_talloc_zero(mem_ctx, 16);
4527
4528		sess_crypt_blob(&out, &in, session_key, false);
4529
4530		if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
4531			return NT_STATUS_ACCESS_DENIED;
4532		}
4533
4534		pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4535	}
4536
4537	if (id18->lm_pwd_active) {
4538
4539		DATA_BLOB in, out;
4540
4541		in = data_blob_const(id18->lm_pwd.hash, 16);
4542		out = data_blob_talloc_zero(mem_ctx, 16);
4543
4544		sess_crypt_blob(&out, &in, session_key, false);
4545
4546		if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
4547			return NT_STATUS_ACCESS_DENIED;
4548		}
4549
4550		pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4551	}
4552
4553	copy_id18_to_sam_passwd(pwd, id18);
4554
4555	return pdb_update_sam_account(pwd);
4556}
4557
4558/*******************************************************************
4559 set_user_info_20
4560 ********************************************************************/
4561
4562static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
4563				 struct samr_UserInfo20 *id20,
4564				 struct samu *pwd)
4565{
4566	if (id20 == NULL) {
4567		DEBUG(5,("set_user_info_20: NULL id20\n"));
4568		return NT_STATUS_ACCESS_DENIED;
4569	}
4570
4571	copy_id20_to_sam_passwd(pwd, id20);
4572
4573	return pdb_update_sam_account(pwd);
4574}
4575
4576/*******************************************************************
4577 set_user_info_21
4578 ********************************************************************/
4579
4580static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
4581				 TALLOC_CTX *mem_ctx,
4582				 DATA_BLOB *session_key,
4583				 struct samu *pwd)
4584{
4585	NTSTATUS status;
4586
4587	if (id21 == NULL) {
4588		DEBUG(5, ("set_user_info_21: NULL id21\n"));
4589		return NT_STATUS_INVALID_PARAMETER;
4590	}
4591
4592	if (id21->fields_present == 0) {
4593		return NT_STATUS_INVALID_PARAMETER;
4594	}
4595
4596	if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4597		return NT_STATUS_ACCESS_DENIED;
4598	}
4599
4600	if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
4601		if (id21->nt_password_set) {
4602			DATA_BLOB in, out;
4603
4604			if ((id21->nt_owf_password.length != 16) ||
4605			    (id21->nt_owf_password.size != 16)) {
4606				return NT_STATUS_INVALID_PARAMETER;
4607			}
4608
4609			if (!session_key->length) {
4610				return NT_STATUS_NO_USER_SESSION_KEY;
4611			}
4612
4613			in = data_blob_const(id21->nt_owf_password.array, 16);
4614			out = data_blob_talloc_zero(mem_ctx, 16);
4615
4616			sess_crypt_blob(&out, &in, session_key, false);
4617
4618			pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
4619			pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4620		}
4621	}
4622
4623	if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
4624		if (id21->lm_password_set) {
4625			DATA_BLOB in, out;
4626
4627			if ((id21->lm_owf_password.length != 16) ||
4628			    (id21->lm_owf_password.size != 16)) {
4629				return NT_STATUS_INVALID_PARAMETER;
4630			}
4631
4632			if (!session_key->length) {
4633				return NT_STATUS_NO_USER_SESSION_KEY;
4634			}
4635
4636			in = data_blob_const(id21->lm_owf_password.array, 16);
4637			out = data_blob_talloc_zero(mem_ctx, 16);
4638
4639			sess_crypt_blob(&out, &in, session_key, false);
4640
4641			pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
4642			pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
4643		}
4644	}
4645
4646	/* we need to separately check for an account rename first */
4647
4648	if (id21->account_name.string &&
4649	    (!strequal(id21->account_name.string, pdb_get_username(pwd))))
4650	{
4651
4652		/* check to see if the new username already exists.  Note: we can't
4653		   reliably lock all backends, so there is potentially the
4654		   possibility that a user can be created in between this check and
4655		   the rename.  The rename should fail, but may not get the
4656		   exact same failure status code.  I think this is small enough
4657		   of a window for this type of operation and the results are
4658		   simply that the rename fails with a slightly different status
4659		   code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
4660
4661		status = can_create(mem_ctx, id21->account_name.string);
4662		if (!NT_STATUS_IS_OK(status)) {
4663			return status;
4664		}
4665
4666		status = pdb_rename_sam_account(pwd, id21->account_name.string);
4667
4668		if (!NT_STATUS_IS_OK(status)) {
4669			DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
4670				nt_errstr(status)));
4671			return status;
4672		}
4673
4674		/* set the new username so that later
4675		   functions can work on the new account */
4676		pdb_set_username(pwd, id21->account_name.string, PDB_SET);
4677	}
4678
4679	copy_id21_to_sam_passwd("INFO_21", pwd, id21);
4680
4681	/*
4682	 * The funny part about the previous two calls is
4683	 * that pwd still has the password hashes from the
4684	 * passdb entry.  These have not been updated from
4685	 * id21.  I don't know if they need to be set.    --jerry
4686	 */
4687
4688	if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4689		status = pdb_set_unix_primary_group(mem_ctx, pwd);
4690		if ( !NT_STATUS_IS_OK(status) ) {
4691			return status;
4692		}
4693	}
4694
4695	/* Don't worry about writing out the user account since the
4696	   primary group SID is generated solely from the user's Unix
4697	   primary group. */
4698
4699	/* write the change out */
4700	if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4701		return status;
4702 	}
4703
4704	return NT_STATUS_OK;
4705}
4706
4707/*******************************************************************
4708 set_user_info_23
4709 ********************************************************************/
4710
4711static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
4712				 struct samr_UserInfo23 *id23,
4713				 struct samu *pwd)
4714{
4715	char *plaintext_buf = NULL;
4716	size_t len = 0;
4717	uint32_t acct_ctrl;
4718	NTSTATUS status;
4719
4720	if (id23 == NULL) {
4721		DEBUG(5, ("set_user_info_23: NULL id23\n"));
4722		return NT_STATUS_INVALID_PARAMETER;
4723	}
4724
4725	if (id23->info.fields_present == 0) {
4726		return NT_STATUS_INVALID_PARAMETER;
4727	}
4728
4729	if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4730		return NT_STATUS_ACCESS_DENIED;
4731	}
4732
4733	if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4734	    (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4735
4736		DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
4737			  pdb_get_username(pwd)));
4738
4739		if (!decode_pw_buffer(mem_ctx,
4740				      id23->password.data,
4741				      &plaintext_buf,
4742				      &len,
4743				      CH_UTF16)) {
4744			return NT_STATUS_WRONG_PASSWORD;
4745		}
4746
4747		if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4748			return NT_STATUS_ACCESS_DENIED;
4749		}
4750	}
4751
4752	copy_id23_to_sam_passwd(pwd, id23);
4753
4754	acct_ctrl = pdb_get_acct_ctrl(pwd);
4755
4756	/* if it's a trust account, don't update /etc/passwd */
4757	if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4758		( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4759		( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4760		DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
4761	} else if (plaintext_buf) {
4762		/* update the UNIX password */
4763		if (lp_unix_password_sync() ) {
4764			struct passwd *passwd;
4765			if (pdb_get_username(pwd) == NULL) {
4766				DEBUG(1, ("chgpasswd: User without name???\n"));
4767				return NT_STATUS_ACCESS_DENIED;
4768			}
4769
4770			passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4771			if (passwd == NULL) {
4772				DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4773			}
4774
4775			if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4776				return NT_STATUS_ACCESS_DENIED;
4777			}
4778			TALLOC_FREE(passwd);
4779		}
4780	}
4781
4782	if (plaintext_buf) {
4783		memset(plaintext_buf, '\0', strlen(plaintext_buf));
4784	}
4785
4786	if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
4787	    (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
4788								   pwd)))) {
4789		return status;
4790	}
4791
4792	if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4793		return status;
4794	}
4795
4796	return NT_STATUS_OK;
4797}
4798
4799/*******************************************************************
4800 set_user_info_pw
4801 ********************************************************************/
4802
4803static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
4804{
4805	size_t len = 0;
4806	char *plaintext_buf = NULL;
4807	uint32 acct_ctrl;
4808
4809	DEBUG(5, ("Attempting administrator password change for user %s\n",
4810		  pdb_get_username(pwd)));
4811
4812	acct_ctrl = pdb_get_acct_ctrl(pwd);
4813
4814	if (!decode_pw_buffer(talloc_tos(),
4815				pass,
4816				&plaintext_buf,
4817				&len,
4818				CH_UTF16)) {
4819		return False;
4820 	}
4821
4822	if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
4823		return False;
4824	}
4825
4826	/* if it's a trust account, don't update /etc/passwd */
4827	if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
4828		( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
4829		( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
4830		DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
4831	} else {
4832		/* update the UNIX password */
4833		if (lp_unix_password_sync()) {
4834			struct passwd *passwd;
4835
4836			if (pdb_get_username(pwd) == NULL) {
4837				DEBUG(1, ("chgpasswd: User without name???\n"));
4838				return False;
4839			}
4840
4841			passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
4842			if (passwd == NULL) {
4843				DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
4844			}
4845
4846			if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
4847				return False;
4848			}
4849			TALLOC_FREE(passwd);
4850		}
4851	}
4852
4853	memset(plaintext_buf, '\0', strlen(plaintext_buf));
4854
4855	DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
4856
4857	return True;
4858}
4859
4860/*******************************************************************
4861 set_user_info_24
4862 ********************************************************************/
4863
4864static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
4865				 struct samr_UserInfo24 *id24,
4866				 struct samu *pwd)
4867{
4868	NTSTATUS status;
4869
4870	if (id24 == NULL) {
4871		DEBUG(5, ("set_user_info_24: NULL id24\n"));
4872		return NT_STATUS_INVALID_PARAMETER;
4873	}
4874
4875	if (!set_user_info_pw(id24->password.data, pwd)) {
4876		return NT_STATUS_WRONG_PASSWORD;
4877	}
4878
4879	copy_id24_to_sam_passwd(pwd, id24);
4880
4881	status = pdb_update_sam_account(pwd);
4882	if (!NT_STATUS_IS_OK(status)) {
4883		return status;
4884 	}
4885
4886	return NT_STATUS_OK;
4887}
4888
4889/*******************************************************************
4890 set_user_info_25
4891 ********************************************************************/
4892
4893static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
4894				 struct samr_UserInfo25 *id25,
4895				 struct samu *pwd)
4896{
4897	NTSTATUS status;
4898
4899	if (id25 == NULL) {
4900		DEBUG(5, ("set_user_info_25: NULL id25\n"));
4901		return NT_STATUS_INVALID_PARAMETER;
4902	}
4903
4904	if (id25->info.fields_present == 0) {
4905		return NT_STATUS_INVALID_PARAMETER;
4906	}
4907
4908	if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
4909		return NT_STATUS_ACCESS_DENIED;
4910	}
4911
4912	if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
4913	    (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
4914
4915		if (!set_user_info_pw(id25->password.data, pwd)) {
4916			return NT_STATUS_WRONG_PASSWORD;
4917		}
4918	}
4919
4920	copy_id25_to_sam_passwd(pwd, id25);
4921
4922	/* write the change out */
4923	if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
4924		return status;
4925 	}
4926
4927	/*
4928	 * We need to "pdb_update_sam_account" before the unix primary group
4929	 * is set, because the idealx scripts would also change the
4930	 * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
4931	 * the delete explicit / add explicit, which would then fail to find
4932	 * the previous primaryGroupSid value.
4933	 */
4934
4935	if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
4936		status = pdb_set_unix_primary_group(mem_ctx, pwd);
4937		if ( !NT_STATUS_IS_OK(status) ) {
4938			return status;
4939		}
4940	}
4941
4942	return NT_STATUS_OK;
4943}
4944
4945/*******************************************************************
4946 set_user_info_26
4947 ********************************************************************/
4948
4949static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
4950				 struct samr_UserInfo26 *id26,
4951				 struct samu *pwd)
4952{
4953	NTSTATUS status;
4954
4955	if (id26 == NULL) {
4956		DEBUG(5, ("set_user_info_26: NULL id26\n"));
4957		return NT_STATUS_INVALID_PARAMETER;
4958	}
4959
4960	if (!set_user_info_pw(id26->password.data, pwd)) {
4961		return NT_STATUS_WRONG_PASSWORD;
4962	}
4963
4964	copy_id26_to_sam_passwd(pwd, id26);
4965
4966	status = pdb_update_sam_account(pwd);
4967	if (!NT_STATUS_IS_OK(status)) {
4968		return status;
4969	}
4970
4971	return NT_STATUS_OK;
4972}
4973
4974/*************************************************************
4975**************************************************************/
4976
4977static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
4978{
4979	uint32_t acc_required = 0;
4980
4981	/* USER_ALL_USERNAME */
4982	if (fields & SAMR_FIELD_ACCOUNT_NAME)
4983		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4984	/* USER_ALL_FULLNAME */
4985	if (fields & SAMR_FIELD_FULL_NAME)
4986		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4987	/* USER_ALL_PRIMARYGROUPID */
4988	if (fields & SAMR_FIELD_PRIMARY_GID)
4989		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4990	/* USER_ALL_HOMEDIRECTORY */
4991	if (fields & SAMR_FIELD_HOME_DIRECTORY)
4992		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4993	/* USER_ALL_HOMEDIRECTORYDRIVE */
4994	if (fields & SAMR_FIELD_HOME_DRIVE)
4995		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4996	/* USER_ALL_SCRIPTPATH */
4997	if (fields & SAMR_FIELD_LOGON_SCRIPT)
4998		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
4999	/* USER_ALL_PROFILEPATH */
5000	if (fields & SAMR_FIELD_PROFILE_PATH)
5001		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5002	/* USER_ALL_ADMINCOMMENT */
5003	if (fields & SAMR_FIELD_COMMENT)
5004		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5005	/* USER_ALL_WORKSTATIONS */
5006	if (fields & SAMR_FIELD_WORKSTATIONS)
5007		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5008	/* USER_ALL_LOGONHOURS */
5009	if (fields & SAMR_FIELD_LOGON_HOURS)
5010		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5011	/* USER_ALL_ACCOUNTEXPIRES */
5012	if (fields & SAMR_FIELD_ACCT_EXPIRY)
5013		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5014	/* USER_ALL_USERACCOUNTCONTROL */
5015	if (fields & SAMR_FIELD_ACCT_FLAGS)
5016		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5017	/* USER_ALL_PARAMETERS */
5018	if (fields & SAMR_FIELD_PARAMETERS)
5019		acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
5020	/* USER_ALL_USERCOMMENT */
5021	if (fields & SAMR_FIELD_COMMENT)
5022		acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5023	/* USER_ALL_COUNTRYCODE */
5024	if (fields & SAMR_FIELD_COUNTRY_CODE)
5025		acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5026	/* USER_ALL_CODEPAGE */
5027	if (fields & SAMR_FIELD_CODE_PAGE)
5028		acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
5029	/* USER_ALL_NTPASSWORDPRESENT */
5030	if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
5031		acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5032	/* USER_ALL_LMPASSWORDPRESENT */
5033	if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
5034		acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5035	/* USER_ALL_PASSWORDEXPIRED */
5036	if (fields & SAMR_FIELD_EXPIRED_FLAG)
5037		acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
5038
5039	return acc_required;
5040}
5041
5042/*******************************************************************
5043 samr_SetUserInfo
5044 ********************************************************************/
5045
5046NTSTATUS _samr_SetUserInfo(pipes_struct *p,
5047			   struct samr_SetUserInfo *r)
5048{
5049	struct samr_user_info *uinfo;
5050	NTSTATUS status;
5051	struct samu *pwd = NULL;
5052	union samr_UserInfo *info = r->in.info;
5053	uint32_t acc_required = 0;
5054	uint32_t fields = 0;
5055	bool ret;
5056
5057	DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
5058
5059	/* This is tricky.  A WinXP domain join sets
5060	  (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
5061	  The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
5062	  standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
5063	  This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
5064	  we'll use the set from the WinXP join as the basis. */
5065
5066	switch (r->in.level) {
5067	case 2: /* UserPreferencesInformation */
5068		/* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
5069		acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
5070		break;
5071	case 4: /* UserLogonHoursInformation */
5072	case 6: /* UserNameInformation */
5073	case 7: /* UserAccountNameInformation */
5074	case 8: /* UserFullNameInformation */
5075	case 9: /* UserPrimaryGroupInformation */
5076	case 10: /* UserHomeInformation */
5077	case 11: /* UserScriptInformation */
5078	case 12: /* UserProfileInformation */
5079	case 13: /* UserAdminCommentInformation */
5080	case 14: /* UserWorkStationsInformation */
5081	case 16: /* UserControlInformation */
5082	case 17: /* UserExpiresInformation */
5083	case 20: /* UserParametersInformation */
5084		/* USER_WRITE_ACCOUNT */
5085		acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
5086		break;
5087	case 18: /* UserInternal1Information */
5088		/* FIXME: gd, this is a guess */
5089		acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5090		break;
5091	case 21: /* UserAllInformation */
5092		fields = info->info21.fields_present;
5093		acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5094		break;
5095	case 23: /* UserInternal4Information */
5096		fields = info->info23.info.fields_present;
5097		acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5098		break;
5099	case 25: /* UserInternal4InformationNew */
5100		fields = info->info25.info.fields_present;
5101		acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
5102		break;
5103	case 24: /* UserInternal5Information */
5104	case 26: /* UserInternal5InformationNew */
5105		acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
5106		break;
5107	default:
5108		return NT_STATUS_INVALID_INFO_CLASS;
5109	}
5110
5111	uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
5112				   struct samr_user_info, &status);
5113	if (!NT_STATUS_IS_OK(status)) {
5114		return status;
5115	}
5116
5117	DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
5118		  sid_string_dbg(&uinfo->sid), r->in.level));
5119
5120	if (info == NULL) {
5121		DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
5122		return NT_STATUS_INVALID_INFO_CLASS;
5123	}
5124
5125	if (!(pwd = samu_new(NULL))) {
5126		return NT_STATUS_NO_MEMORY;
5127	}
5128
5129	become_root();
5130	ret = pdb_getsampwsid(pwd, &uinfo->sid);
5131	unbecome_root();
5132
5133	if (!ret) {
5134		TALLOC_FREE(pwd);
5135		return NT_STATUS_NO_SUCH_USER;
5136 	}
5137
5138	/* ================ BEGIN Privilege BLOCK ================ */
5139
5140	become_root();
5141
5142	/* ok!  user info levels (lots: see MSDEV help), off we go... */
5143
5144	switch (r->in.level) {
5145
5146		case 2:
5147			status = set_user_info_2(p->mem_ctx,
5148						 &info->info2, pwd);
5149			break;
5150
5151		case 4:
5152			status = set_user_info_4(p->mem_ctx,
5153						 &info->info4, pwd);
5154			break;
5155
5156		case 6:
5157			status = set_user_info_6(p->mem_ctx,
5158						 &info->info6, pwd);
5159			break;
5160
5161		case 7:
5162			status = set_user_info_7(p->mem_ctx,
5163						 &info->info7, pwd);
5164			break;
5165
5166		case 8:
5167			status = set_user_info_8(p->mem_ctx,
5168						 &info->info8, pwd);
5169			break;
5170
5171		case 10:
5172			status = set_user_info_10(p->mem_ctx,
5173						  &info->info10, pwd);
5174			break;
5175
5176		case 11:
5177			status = set_user_info_11(p->mem_ctx,
5178						  &info->info11, pwd);
5179			break;
5180
5181		case 12:
5182			status = set_user_info_12(p->mem_ctx,
5183						  &info->info12, pwd);
5184			break;
5185
5186		case 13:
5187			status = set_user_info_13(p->mem_ctx,
5188						  &info->info13, pwd);
5189			break;
5190
5191		case 14:
5192			status = set_user_info_14(p->mem_ctx,
5193						  &info->info14, pwd);
5194			break;
5195
5196		case 16:
5197			status = set_user_info_16(p->mem_ctx,
5198						  &info->info16, pwd);
5199			break;
5200
5201		case 17:
5202			status = set_user_info_17(p->mem_ctx,
5203						  &info->info17, pwd);
5204			break;
5205
5206		case 18:
5207			/* Used by AS/U JRA. */
5208			status = set_user_info_18(&info->info18,
5209						  p->mem_ctx,
5210						  &p->server_info->user_session_key,
5211						  pwd);
5212			break;
5213
5214		case 20:
5215			status = set_user_info_20(p->mem_ctx,
5216						  &info->info20, pwd);
5217			break;
5218
5219		case 21:
5220			status = set_user_info_21(&info->info21,
5221						  p->mem_ctx,
5222						  &p->server_info->user_session_key,
5223						  pwd);
5224			break;
5225
5226		case 23:
5227			if (!p->server_info->user_session_key.length) {
5228				status = NT_STATUS_NO_USER_SESSION_KEY;
5229			}
5230			arcfour_crypt_blob(info->info23.password.data, 516,
5231					   &p->server_info->user_session_key);
5232
5233			dump_data(100, info->info23.password.data, 516);
5234
5235			status = set_user_info_23(p->mem_ctx,
5236						  &info->info23, pwd);
5237			break;
5238
5239		case 24:
5240			if (!p->server_info->user_session_key.length) {
5241				status = NT_STATUS_NO_USER_SESSION_KEY;
5242			}
5243			arcfour_crypt_blob(info->info24.password.data,
5244					   516,
5245					   &p->server_info->user_session_key);
5246
5247			dump_data(100, info->info24.password.data, 516);
5248
5249			status = set_user_info_24(p->mem_ctx,
5250						  &info->info24, pwd);
5251			break;
5252
5253		case 25:
5254			if (!p->server_info->user_session_key.length) {
5255				status = NT_STATUS_NO_USER_SESSION_KEY;
5256			}
5257			encode_or_decode_arc4_passwd_buffer(
5258				info->info25.password.data,
5259				&p->server_info->user_session_key);
5260
5261			dump_data(100, info->info25.password.data, 532);
5262
5263			status = set_user_info_25(p->mem_ctx,
5264						  &info->info25, pwd);
5265			break;
5266
5267		case 26:
5268			if (!p->server_info->user_session_key.length) {
5269				status = NT_STATUS_NO_USER_SESSION_KEY;
5270			}
5271			encode_or_decode_arc4_passwd_buffer(
5272				info->info26.password.data,
5273				&p->server_info->user_session_key);
5274
5275			dump_data(100, info->info26.password.data, 516);
5276
5277			status = set_user_info_26(p->mem_ctx,
5278						  &info->info26, pwd);
5279			break;
5280
5281		default:
5282			status = NT_STATUS_INVALID_INFO_CLASS;
5283	}
5284
5285	TALLOC_FREE(pwd);
5286
5287	unbecome_root();
5288
5289	/* ================ END Privilege BLOCK ================ */
5290
5291	if (NT_STATUS_IS_OK(status)) {
5292		force_flush_samr_cache(&uinfo->sid);
5293	}
5294
5295	return status;
5296}
5297
5298/*******************************************************************
5299 _samr_SetUserInfo2
5300 ********************************************************************/
5301
5302NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
5303			    struct samr_SetUserInfo2 *r)
5304{
5305	struct samr_SetUserInfo q;
5306
5307	q.in.user_handle	= r->in.user_handle;
5308	q.in.level		= r->in.level;
5309	q.in.info		= r->in.info;
5310
5311	return _samr_SetUserInfo(p, &q);
5312}
5313
5314/*********************************************************************
5315 _samr_GetAliasMembership
5316*********************************************************************/
5317
5318NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
5319				  struct samr_GetAliasMembership *r)
5320{
5321	size_t num_alias_rids;
5322	uint32 *alias_rids;
5323	struct samr_domain_info *dinfo;
5324	size_t i;
5325
5326	NTSTATUS status;
5327
5328	DOM_SID *members;
5329
5330	DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
5331
5332	dinfo = policy_handle_find(p, r->in.domain_handle,
5333				   SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
5334				   | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
5335				   struct samr_domain_info, &status);
5336	if (!NT_STATUS_IS_OK(status)) {
5337		return status;
5338	}
5339
5340	if (!sid_check_is_domain(&dinfo->sid) &&
5341	    !sid_check_is_builtin(&dinfo->sid))
5342		return NT_STATUS_OBJECT_TYPE_MISMATCH;
5343
5344	if (r->in.sids->num_sids) {
5345		members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
5346
5347		if (members == NULL)
5348			return NT_STATUS_NO_MEMORY;
5349	} else {
5350		members = NULL;
5351	}
5352
5353	for (i=0; i<r->in.sids->num_sids; i++)
5354		sid_copy(&members[i], r->in.sids->sids[i].sid);
5355
5356	alias_rids = NULL;
5357	num_alias_rids = 0;
5358
5359	become_root();
5360	status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
5361					    r->in.sids->num_sids,
5362					    &alias_rids, &num_alias_rids);
5363	unbecome_root();
5364
5365	if (!NT_STATUS_IS_OK(status)) {
5366		return status;
5367	}
5368
5369	r->out.rids->count = num_alias_rids;
5370	r->out.rids->ids = alias_rids;
5371
5372	if (r->out.rids->ids == NULL) {
5373		/* Windows domain clients don't accept a NULL ptr here */
5374		r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
5375	}
5376	if (r->out.rids->ids == NULL) {
5377		return NT_STATUS_NO_MEMORY;
5378	}
5379
5380	return NT_STATUS_OK;
5381}
5382
5383/*********************************************************************
5384 _samr_GetMembersInAlias
5385*********************************************************************/
5386
5387NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
5388				 struct samr_GetMembersInAlias *r)
5389{
5390	struct samr_alias_info *ainfo;
5391	NTSTATUS status;
5392	size_t i;
5393	size_t num_sids = 0;
5394	struct lsa_SidPtr *sids = NULL;
5395	DOM_SID *pdb_sids = NULL;
5396
5397	ainfo = policy_handle_find(p, r->in.alias_handle,
5398				   SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
5399				   struct samr_alias_info, &status);
5400	if (!NT_STATUS_IS_OK(status)) {
5401		return status;
5402	}
5403
5404	DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5405
5406	become_root();
5407	status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
5408				   &num_sids);
5409	unbecome_root();
5410
5411	if (!NT_STATUS_IS_OK(status)) {
5412		return status;
5413	}
5414
5415	if (num_sids) {
5416		sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, num_sids);
5417		if (sids == NULL) {
5418			TALLOC_FREE(pdb_sids);
5419			return NT_STATUS_NO_MEMORY;
5420		}
5421	}
5422
5423	for (i = 0; i < num_sids; i++) {
5424		sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
5425		if (!sids[i].sid) {
5426			TALLOC_FREE(pdb_sids);
5427			return NT_STATUS_NO_MEMORY;
5428		}
5429	}
5430
5431	r->out.sids->num_sids = num_sids;
5432	r->out.sids->sids = sids;
5433
5434	TALLOC_FREE(pdb_sids);
5435
5436	return NT_STATUS_OK;
5437}
5438
5439/*********************************************************************
5440 _samr_QueryGroupMember
5441*********************************************************************/
5442
5443NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
5444				struct samr_QueryGroupMember *r)
5445{
5446	struct samr_group_info *ginfo;
5447	size_t i, num_members;
5448
5449	uint32 *rid=NULL;
5450	uint32 *attr=NULL;
5451
5452	NTSTATUS status;
5453	struct samr_RidTypeArray *rids = NULL;
5454
5455	ginfo = policy_handle_find(p, r->in.group_handle,
5456				   SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
5457				   struct samr_group_info, &status);
5458	if (!NT_STATUS_IS_OK(status)) {
5459		return status;
5460	}
5461
5462	rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
5463	if (!rids) {
5464		return NT_STATUS_NO_MEMORY;
5465	}
5466
5467	DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5468
5469	if (!sid_check_is_in_our_domain(&ginfo->sid)) {
5470		DEBUG(3, ("sid %s is not in our domain\n",
5471			  sid_string_dbg(&ginfo->sid)));
5472		return NT_STATUS_NO_SUCH_GROUP;
5473	}
5474
5475	DEBUG(10, ("lookup on Domain SID\n"));
5476
5477	become_root();
5478	status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
5479					&rid, &num_members);
5480	unbecome_root();
5481
5482	if (!NT_STATUS_IS_OK(status))
5483		return status;
5484
5485	if (num_members) {
5486		attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
5487		if (attr == NULL) {
5488			return NT_STATUS_NO_MEMORY;
5489		}
5490	} else {
5491		attr = NULL;
5492	}
5493
5494	for (i=0; i<num_members; i++)
5495		attr[i] = SID_NAME_USER;
5496
5497	rids->count = num_members;
5498	rids->types = attr;
5499	rids->rids = rid;
5500
5501	*r->out.rids = rids;
5502
5503	return NT_STATUS_OK;
5504}
5505
5506/*********************************************************************
5507 _samr_AddAliasMember
5508*********************************************************************/
5509
5510NTSTATUS _samr_AddAliasMember(pipes_struct *p,
5511			      struct samr_AddAliasMember *r)
5512{
5513	struct samr_alias_info *ainfo;
5514	NTSTATUS status;
5515
5516	ainfo = policy_handle_find(p, r->in.alias_handle,
5517				   SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
5518				   struct samr_alias_info, &status);
5519	if (!NT_STATUS_IS_OK(status)) {
5520		return status;
5521	}
5522
5523	DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5524
5525	/******** BEGIN SeAddUsers BLOCK *********/
5526
5527	become_root();
5528	status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
5529	unbecome_root();
5530
5531	/******** END SeAddUsers BLOCK *********/
5532
5533	if (NT_STATUS_IS_OK(status)) {
5534		force_flush_samr_cache(&ainfo->sid);
5535	}
5536
5537	return status;
5538}
5539
5540/*********************************************************************
5541 _samr_DeleteAliasMember
5542*********************************************************************/
5543
5544NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
5545				 struct samr_DeleteAliasMember *r)
5546{
5547	struct samr_alias_info *ainfo;
5548	NTSTATUS status;
5549
5550	ainfo = policy_handle_find(p, r->in.alias_handle,
5551				   SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
5552				   struct samr_alias_info, &status);
5553	if (!NT_STATUS_IS_OK(status)) {
5554		return status;
5555	}
5556
5557	DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
5558		   sid_string_dbg(&ainfo->sid)));
5559
5560	/******** BEGIN SeAddUsers BLOCK *********/
5561
5562	become_root();
5563	status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
5564	unbecome_root();
5565
5566	/******** END SeAddUsers BLOCK *********/
5567
5568	if (NT_STATUS_IS_OK(status)) {
5569		force_flush_samr_cache(&ainfo->sid);
5570	}
5571
5572	return status;
5573}
5574
5575/*********************************************************************
5576 _samr_AddGroupMember
5577*********************************************************************/
5578
5579NTSTATUS _samr_AddGroupMember(pipes_struct *p,
5580			      struct samr_AddGroupMember *r)
5581{
5582	struct samr_group_info *ginfo;
5583	NTSTATUS status;
5584	uint32 group_rid;
5585
5586	ginfo = policy_handle_find(p, r->in.group_handle,
5587				   SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
5588				   struct samr_group_info, &status);
5589	if (!NT_STATUS_IS_OK(status)) {
5590		return status;
5591	}
5592
5593	DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5594
5595	if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5596				&group_rid)) {
5597		return NT_STATUS_INVALID_HANDLE;
5598	}
5599
5600	/******** BEGIN SeAddUsers BLOCK *********/
5601
5602	become_root();
5603	status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
5604	unbecome_root();
5605
5606	/******** END SeAddUsers BLOCK *********/
5607
5608	force_flush_samr_cache(&ginfo->sid);
5609
5610	return status;
5611}
5612
5613/*********************************************************************
5614 _samr_DeleteGroupMember
5615*********************************************************************/
5616
5617NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
5618				 struct samr_DeleteGroupMember *r)
5619
5620{
5621	struct samr_group_info *ginfo;
5622	NTSTATUS status;
5623	uint32 group_rid;
5624
5625	/*
5626	 * delete the group member named r->in.rid
5627	 * who is a member of the sid associated with the handle
5628	 * the rid is a user's rid as the group is a domain group.
5629	 */
5630
5631	ginfo = policy_handle_find(p, r->in.group_handle,
5632				   SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
5633				   struct samr_group_info, &status);
5634	if (!NT_STATUS_IS_OK(status)) {
5635		return status;
5636	}
5637
5638	if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5639				&group_rid)) {
5640		return NT_STATUS_INVALID_HANDLE;
5641	}
5642
5643	/******** BEGIN SeAddUsers BLOCK *********/
5644
5645	become_root();
5646	status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
5647	unbecome_root();
5648
5649	/******** END SeAddUsers BLOCK *********/
5650
5651	force_flush_samr_cache(&ginfo->sid);
5652
5653	return status;
5654}
5655
5656/*********************************************************************
5657 _samr_DeleteUser
5658*********************************************************************/
5659
5660NTSTATUS _samr_DeleteUser(pipes_struct *p,
5661			  struct samr_DeleteUser *r)
5662{
5663	struct samr_user_info *uinfo;
5664	NTSTATUS status;
5665	struct samu *sam_pass=NULL;
5666	bool ret;
5667
5668	DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
5669
5670	uinfo = policy_handle_find(p, r->in.user_handle,
5671				   STD_RIGHT_DELETE_ACCESS, NULL,
5672				   struct samr_user_info, &status);
5673	if (!NT_STATUS_IS_OK(status)) {
5674		return status;
5675	}
5676
5677	if (!sid_check_is_in_our_domain(&uinfo->sid))
5678		return NT_STATUS_CANNOT_DELETE;
5679
5680	/* check if the user exists before trying to delete */
5681	if ( !(sam_pass = samu_new( NULL )) ) {
5682		return NT_STATUS_NO_MEMORY;
5683	}
5684
5685	become_root();
5686	ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
5687	unbecome_root();
5688
5689	if(!ret) {
5690		DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
5691			sid_string_dbg(&uinfo->sid)));
5692		TALLOC_FREE(sam_pass);
5693		return NT_STATUS_NO_SUCH_USER;
5694	}
5695
5696	/******** BEGIN SeAddUsers BLOCK *********/
5697
5698	become_root();
5699	status = pdb_delete_user(p->mem_ctx, sam_pass);
5700	unbecome_root();
5701
5702	/******** END SeAddUsers BLOCK *********/
5703
5704	if ( !NT_STATUS_IS_OK(status) ) {
5705		DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
5706			 "user %s: %s.\n", pdb_get_username(sam_pass),
5707			 nt_errstr(status)));
5708		TALLOC_FREE(sam_pass);
5709		return status;
5710	}
5711
5712
5713	TALLOC_FREE(sam_pass);
5714
5715	force_flush_samr_cache(&uinfo->sid);
5716
5717	if (!close_policy_hnd(p, r->in.user_handle))
5718		return NT_STATUS_OBJECT_NAME_INVALID;
5719
5720	ZERO_STRUCTP(r->out.user_handle);
5721
5722	return NT_STATUS_OK;
5723}
5724
5725/*********************************************************************
5726 _samr_DeleteDomainGroup
5727*********************************************************************/
5728
5729NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
5730				 struct samr_DeleteDomainGroup *r)
5731{
5732	struct samr_group_info *ginfo;
5733	NTSTATUS status;
5734	uint32 group_rid;
5735
5736	DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
5737
5738	ginfo = policy_handle_find(p, r->in.group_handle,
5739				   STD_RIGHT_DELETE_ACCESS, NULL,
5740				   struct samr_group_info, &status);
5741	if (!NT_STATUS_IS_OK(status)) {
5742		return status;
5743	}
5744
5745	DEBUG(10, ("sid is %s\n", sid_string_dbg(&ginfo->sid)));
5746
5747	if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
5748				&group_rid)) {
5749		return NT_STATUS_NO_SUCH_GROUP;
5750	}
5751
5752	/******** BEGIN SeAddUsers BLOCK *********/
5753
5754	become_root();
5755	status = pdb_delete_dom_group(p->mem_ctx, group_rid);
5756	unbecome_root();
5757
5758	/******** END SeAddUsers BLOCK *********/
5759
5760	if ( !NT_STATUS_IS_OK(status) ) {
5761		DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
5762			 "entry for group %s: %s\n",
5763			 sid_string_dbg(&ginfo->sid),
5764			 nt_errstr(status)));
5765		return status;
5766	}
5767
5768	force_flush_samr_cache(&ginfo->sid);
5769
5770	if (!close_policy_hnd(p, r->in.group_handle))
5771		return NT_STATUS_OBJECT_NAME_INVALID;
5772
5773	return NT_STATUS_OK;
5774}
5775
5776/*********************************************************************
5777 _samr_DeleteDomAlias
5778*********************************************************************/
5779
5780NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
5781			      struct samr_DeleteDomAlias *r)
5782{
5783	struct samr_alias_info *ainfo;
5784	NTSTATUS status;
5785
5786	DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
5787
5788	ainfo = policy_handle_find(p, r->in.alias_handle,
5789				   STD_RIGHT_DELETE_ACCESS, NULL,
5790				   struct samr_alias_info, &status);
5791	if (!NT_STATUS_IS_OK(status)) {
5792		return status;
5793	}
5794
5795	DEBUG(10, ("sid is %s\n", sid_string_dbg(&ainfo->sid)));
5796
5797	/* Don't let Windows delete builtin groups */
5798
5799	if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
5800		return NT_STATUS_SPECIAL_ACCOUNT;
5801	}
5802
5803	if (!sid_check_is_in_our_domain(&ainfo->sid))
5804		return NT_STATUS_NO_SUCH_ALIAS;
5805
5806	DEBUG(10, ("lookup on Local SID\n"));
5807
5808	/******** BEGIN SeAddUsers BLOCK *********/
5809
5810	become_root();
5811	/* Have passdb delete the alias */
5812	status = pdb_delete_alias(&ainfo->sid);
5813	unbecome_root();
5814
5815	/******** END SeAddUsers BLOCK *********/
5816
5817	if ( !NT_STATUS_IS_OK(status))
5818		return status;
5819
5820	force_flush_samr_cache(&ainfo->sid);
5821
5822	if (!close_policy_hnd(p, r->in.alias_handle))
5823		return NT_STATUS_OBJECT_NAME_INVALID;
5824
5825	return NT_STATUS_OK;
5826}
5827
5828/*********************************************************************
5829 _samr_CreateDomainGroup
5830*********************************************************************/
5831
5832NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
5833				 struct samr_CreateDomainGroup *r)
5834
5835{
5836	NTSTATUS status;
5837	const char *name;
5838	struct samr_domain_info *dinfo;
5839	struct samr_group_info *ginfo;
5840
5841	dinfo = policy_handle_find(p, r->in.domain_handle,
5842				   SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
5843				   struct samr_domain_info, &status);
5844	if (!NT_STATUS_IS_OK(status)) {
5845		return status;
5846	}
5847
5848	if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5849		return NT_STATUS_ACCESS_DENIED;
5850
5851	name = r->in.name->string;
5852	if (name == NULL) {
5853		return NT_STATUS_NO_MEMORY;
5854	}
5855
5856	status = can_create(p->mem_ctx, name);
5857	if (!NT_STATUS_IS_OK(status)) {
5858		return status;
5859	}
5860
5861	/******** BEGIN SeAddUsers BLOCK *********/
5862
5863	become_root();
5864	/* check that we successfully create the UNIX group */
5865	status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
5866	unbecome_root();
5867
5868	/******** END SeAddUsers BLOCK *********/
5869
5870	/* check if we should bail out here */
5871
5872	if ( !NT_STATUS_IS_OK(status) )
5873		return status;
5874
5875	ginfo = policy_handle_create(p, r->out.group_handle,
5876				     GENERIC_RIGHTS_GROUP_ALL_ACCESS,
5877				     struct samr_group_info, &status);
5878        if (!NT_STATUS_IS_OK(status)) {
5879                return status;
5880        }
5881	sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
5882
5883	force_flush_samr_cache(&dinfo->sid);
5884
5885	return NT_STATUS_OK;
5886}
5887
5888/*********************************************************************
5889 _samr_CreateDomAlias
5890*********************************************************************/
5891
5892NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
5893			      struct samr_CreateDomAlias *r)
5894{
5895	DOM_SID info_sid;
5896	const char *name = NULL;
5897	struct samr_domain_info *dinfo;
5898	struct samr_alias_info *ainfo;
5899	gid_t gid;
5900	NTSTATUS result;
5901
5902	dinfo = policy_handle_find(p, r->in.domain_handle,
5903				   SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
5904				   struct samr_domain_info, &result);
5905	if (!NT_STATUS_IS_OK(result)) {
5906		return result;
5907	}
5908
5909	if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
5910		return NT_STATUS_ACCESS_DENIED;
5911
5912	name = r->in.alias_name->string;
5913
5914	result = can_create(p->mem_ctx, name);
5915	if (!NT_STATUS_IS_OK(result)) {
5916		return result;
5917	}
5918
5919	/******** BEGIN SeAddUsers BLOCK *********/
5920
5921	become_root();
5922	/* Have passdb create the alias */
5923	result = pdb_create_alias(name, r->out.rid);
5924	unbecome_root();
5925
5926	/******** END SeAddUsers BLOCK *********/
5927
5928	if (!NT_STATUS_IS_OK(result)) {
5929		DEBUG(10, ("pdb_create_alias failed: %s\n",
5930			   nt_errstr(result)));
5931		return result;
5932	}
5933
5934	sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
5935
5936	if (!sid_to_gid(&info_sid, &gid)) {
5937		DEBUG(10, ("Could not find alias just created\n"));
5938		return NT_STATUS_ACCESS_DENIED;
5939	}
5940
5941	/* check if the group has been successfully created */
5942	if ( getgrgid(gid) == NULL ) {
5943		DEBUG(10, ("getgrgid(%u) of just created alias failed\n",
5944			   (unsigned int)gid));
5945		return NT_STATUS_ACCESS_DENIED;
5946	}
5947
5948	ainfo = policy_handle_create(p, r->out.alias_handle,
5949				     GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
5950				     struct samr_alias_info, &result);
5951        if (!NT_STATUS_IS_OK(result)) {
5952                return result;
5953        }
5954	ainfo->sid = info_sid;
5955
5956	force_flush_samr_cache(&info_sid);
5957
5958	return NT_STATUS_OK;
5959}
5960
5961/*********************************************************************
5962 _samr_QueryGroupInfo
5963*********************************************************************/
5964
5965NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
5966			      struct samr_QueryGroupInfo *r)
5967{
5968	struct samr_group_info *ginfo;
5969	NTSTATUS status;
5970	GROUP_MAP map;
5971	union samr_GroupInfo *info = NULL;
5972	bool ret;
5973	uint32_t attributes = SE_GROUP_MANDATORY |
5974			      SE_GROUP_ENABLED_BY_DEFAULT |
5975			      SE_GROUP_ENABLED;
5976	const char *group_name = NULL;
5977	const char *group_description = NULL;
5978
5979	ginfo = policy_handle_find(p, r->in.group_handle,
5980				   SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
5981				   struct samr_group_info, &status);
5982	if (!NT_STATUS_IS_OK(status)) {
5983		return status;
5984	}
5985
5986	become_root();
5987	ret = get_domain_group_from_sid(ginfo->sid, &map);
5988	unbecome_root();
5989	if (!ret)
5990		return NT_STATUS_INVALID_HANDLE;
5991
5992	/* FIXME: map contains fstrings */
5993	group_name = talloc_strdup(r, map.nt_name);
5994	group_description = talloc_strdup(r, map.comment);
5995
5996	info = TALLOC_ZERO_P(p->mem_ctx, union samr_GroupInfo);
5997	if (!info) {
5998		return NT_STATUS_NO_MEMORY;
5999	}
6000
6001	switch (r->in.level) {
6002		case 1: {
6003			uint32 *members;
6004			size_t num_members;
6005
6006			become_root();
6007			status = pdb_enum_group_members(
6008				p->mem_ctx, &ginfo->sid, &members,
6009				&num_members);
6010			unbecome_root();
6011
6012			if (!NT_STATUS_IS_OK(status)) {
6013				return status;
6014			}
6015
6016			info->all.name.string		= group_name;
6017			info->all.attributes		= attributes;
6018			info->all.num_members		= num_members;
6019			info->all.description.string	= group_description;
6020			break;
6021		}
6022		case 2:
6023			info->name.string = group_name;
6024			break;
6025		case 3:
6026			info->attributes.attributes = attributes;
6027			break;
6028		case 4:
6029			info->description.string = group_description;
6030			break;
6031		case 5: {
6032			/*
6033			uint32 *members;
6034			size_t num_members;
6035			*/
6036
6037			/*
6038			become_root();
6039			status = pdb_enum_group_members(
6040				p->mem_ctx, &ginfo->sid, &members,
6041				&num_members);
6042			unbecome_root();
6043
6044			if (!NT_STATUS_IS_OK(status)) {
6045				return status;
6046			}
6047			*/
6048			info->all2.name.string		= group_name;
6049			info->all2.attributes		= attributes;
6050			info->all2.num_members		= 0; /* num_members - in w2k3 this is always 0 */
6051			info->all2.description.string	= group_description;
6052
6053			break;
6054		}
6055		default:
6056			return NT_STATUS_INVALID_INFO_CLASS;
6057	}
6058
6059	*r->out.info = info;
6060
6061	return NT_STATUS_OK;
6062}
6063
6064/*********************************************************************
6065 _samr_SetGroupInfo
6066*********************************************************************/
6067
6068NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
6069			    struct samr_SetGroupInfo *r)
6070{
6071	struct samr_group_info *ginfo;
6072	GROUP_MAP map;
6073	NTSTATUS status;
6074	bool ret;
6075
6076	ginfo = policy_handle_find(p, r->in.group_handle,
6077				   SAMR_GROUP_ACCESS_SET_INFO, NULL,
6078				   struct samr_group_info, &status);
6079	if (!NT_STATUS_IS_OK(status)) {
6080		return status;
6081	}
6082
6083	become_root();
6084	ret = get_domain_group_from_sid(ginfo->sid, &map);
6085	unbecome_root();
6086	if (!ret)
6087		return NT_STATUS_NO_SUCH_GROUP;
6088
6089	switch (r->in.level) {
6090		case 2:
6091			fstrcpy(map.nt_name, r->in.info->name.string);
6092			break;
6093		case 3:
6094			break;
6095		case 4:
6096			fstrcpy(map.comment, r->in.info->description.string);
6097			break;
6098		default:
6099			return NT_STATUS_INVALID_INFO_CLASS;
6100	}
6101
6102	/******** BEGIN SeAddUsers BLOCK *********/
6103
6104	become_root();
6105	status = pdb_update_group_mapping_entry(&map);
6106	unbecome_root();
6107
6108	/******** End SeAddUsers BLOCK *********/
6109
6110	if (NT_STATUS_IS_OK(status)) {
6111		force_flush_samr_cache(&ginfo->sid);
6112	}
6113
6114	return status;
6115}
6116
6117/*********************************************************************
6118 _samr_SetAliasInfo
6119*********************************************************************/
6120
6121NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
6122			    struct samr_SetAliasInfo *r)
6123{
6124	struct samr_alias_info *ainfo;
6125	struct acct_info info;
6126	NTSTATUS status;
6127
6128	ainfo = policy_handle_find(p, r->in.alias_handle,
6129				   SAMR_ALIAS_ACCESS_SET_INFO, NULL,
6130				   struct samr_alias_info, &status);
6131	if (!NT_STATUS_IS_OK(status)) {
6132		return status;
6133	}
6134
6135	/* get the current group information */
6136
6137	become_root();
6138	status = pdb_get_aliasinfo( &ainfo->sid, &info );
6139	unbecome_root();
6140
6141	if ( !NT_STATUS_IS_OK(status))
6142		return status;
6143
6144	switch (r->in.level) {
6145		case ALIASINFONAME:
6146		{
6147			fstring group_name;
6148
6149			/* We currently do not support renaming groups in the
6150			   the BUILTIN domain.  Refer to util_builtin.c to understand
6151			   why.  The eventually needs to be fixed to be like Windows
6152			   where you can rename builtin groups, just not delete them */
6153
6154			if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
6155				return NT_STATUS_SPECIAL_ACCOUNT;
6156			}
6157
6158			/* There has to be a valid name (and it has to be different) */
6159
6160			if ( !r->in.info->name.string )
6161				return NT_STATUS_INVALID_PARAMETER;
6162
6163			/* If the name is the same just reply "ok".  Yes this
6164			   doesn't allow you to change the case of a group name. */
6165
6166			if ( strequal( r->in.info->name.string, info.acct_name ) )
6167				return NT_STATUS_OK;
6168
6169			fstrcpy( info.acct_name, r->in.info->name.string);
6170
6171			/* make sure the name doesn't already exist as a user
6172			   or local group */
6173
6174			fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
6175			status = can_create( p->mem_ctx, group_name );
6176			if ( !NT_STATUS_IS_OK( status ) )
6177				return status;
6178			break;
6179		}
6180		case ALIASINFODESCRIPTION:
6181			if (r->in.info->description.string) {
6182				fstrcpy(info.acct_desc,
6183					r->in.info->description.string);
6184			} else {
6185				fstrcpy( info.acct_desc, "" );
6186			}
6187			break;
6188		default:
6189			return NT_STATUS_INVALID_INFO_CLASS;
6190	}
6191
6192        /******** BEGIN SeAddUsers BLOCK *********/
6193
6194	become_root();
6195        status = pdb_set_aliasinfo( &ainfo->sid, &info );
6196	unbecome_root();
6197
6198        /******** End SeAddUsers BLOCK *********/
6199
6200	if (NT_STATUS_IS_OK(status))
6201		force_flush_samr_cache(&ainfo->sid);
6202
6203	return status;
6204}
6205
6206/****************************************************************
6207 _samr_GetDomPwInfo
6208****************************************************************/
6209
6210NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
6211			    struct samr_GetDomPwInfo *r)
6212{
6213	uint32_t min_password_length = 0;
6214	uint32_t password_properties = 0;
6215
6216	/* Perform access check.  Since this rpc does not require a
6217	   policy handle it will not be caught by the access checks on
6218	   SAMR_CONNECT or SAMR_CONNECT_ANON. */
6219
6220	if (!pipe_access_check(p)) {
6221		DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
6222		return NT_STATUS_ACCESS_DENIED;
6223	}
6224
6225	become_root();
6226	pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6227			       &min_password_length);
6228	pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6229			       &password_properties);
6230	unbecome_root();
6231
6232	if (lp_check_password_script() && *lp_check_password_script()) {
6233		password_properties |= DOMAIN_PASSWORD_COMPLEX;
6234	}
6235
6236	r->out.info->min_password_length = min_password_length;
6237	r->out.info->password_properties = password_properties;
6238
6239	return NT_STATUS_OK;
6240}
6241
6242/*********************************************************************
6243 _samr_OpenGroup
6244*********************************************************************/
6245
6246NTSTATUS _samr_OpenGroup(pipes_struct *p,
6247			 struct samr_OpenGroup *r)
6248
6249{
6250	DOM_SID info_sid;
6251	GROUP_MAP map;
6252	struct samr_domain_info *dinfo;
6253	struct samr_group_info *ginfo;
6254	SEC_DESC         *psd = NULL;
6255	uint32            acc_granted;
6256	uint32            des_access = r->in.access_mask;
6257	size_t            sd_size;
6258	NTSTATUS          status;
6259	bool ret;
6260	SE_PRIV se_rights;
6261
6262	dinfo = policy_handle_find(p, r->in.domain_handle,
6263				   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6264				   struct samr_domain_info, &status);
6265	if (!NT_STATUS_IS_OK(status)) {
6266		return status;
6267	}
6268
6269	/*check if access can be granted as requested by client. */
6270	map_max_allowed_access(p->server_info->ptok,
6271			       &p->server_info->utok,
6272			       &des_access);
6273
6274	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
6275	se_map_generic(&des_access,&grp_generic_mapping);
6276
6277	se_priv_copy( &se_rights, &se_add_users );
6278
6279	status = access_check_object(psd, p->server_info->ptok,
6280		&se_rights, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
6281		des_access, &acc_granted, "_samr_OpenGroup");
6282
6283	if ( !NT_STATUS_IS_OK(status) )
6284		return status;
6285
6286	/* this should not be hard-coded like this */
6287
6288	if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
6289		return NT_STATUS_ACCESS_DENIED;
6290
6291	sid_compose(&info_sid, &dinfo->sid, r->in.rid);
6292
6293	DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
6294		   sid_string_dbg(&info_sid)));
6295
6296	/* check if that group really exists */
6297	become_root();
6298	ret = get_domain_group_from_sid(info_sid, &map);
6299	unbecome_root();
6300	if (!ret)
6301		return NT_STATUS_NO_SUCH_GROUP;
6302
6303	ginfo = policy_handle_create(p, r->out.group_handle,
6304				     acc_granted,
6305				     struct samr_group_info, &status);
6306        if (!NT_STATUS_IS_OK(status)) {
6307                return status;
6308        }
6309	ginfo->sid = info_sid;
6310
6311	return NT_STATUS_OK;
6312}
6313
6314/*********************************************************************
6315 _samr_RemoveMemberFromForeignDomain
6316*********************************************************************/
6317
6318NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
6319					     struct samr_RemoveMemberFromForeignDomain *r)
6320{
6321	struct samr_domain_info *dinfo;
6322	NTSTATUS		result;
6323
6324	DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
6325		 sid_string_dbg(r->in.sid)));
6326
6327	/* Find the policy handle. Open a policy on it. */
6328
6329	dinfo = policy_handle_find(p, r->in.domain_handle,
6330				   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
6331				   struct samr_domain_info, &result);
6332	if (!NT_STATUS_IS_OK(result)) {
6333		return result;
6334	}
6335
6336	DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
6337		  sid_string_dbg(&dinfo->sid)));
6338
6339	/* we can only delete a user from a group since we don't have
6340	   nested groups anyways.  So in the latter case, just say OK */
6341
6342	/* TODO: The above comment nowadays is bogus. Since we have nested
6343	 * groups now, and aliases members are never reported out of the unix
6344	 * group membership, the "just say OK" makes this call a no-op. For
6345	 * us. This needs fixing however. */
6346
6347	/* I've only ever seen this in the wild when deleting a user from
6348	 * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
6349	 * is the user about to be deleted. I very much suspect this is the
6350	 * only application of this call. To verify this, let people report
6351	 * other cases. */
6352
6353	if (!sid_check_is_builtin(&dinfo->sid)) {
6354		DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
6355			 "global_sam_sid() = %s\n",
6356			 sid_string_dbg(&dinfo->sid),
6357			 sid_string_dbg(get_global_sam_sid())));
6358		DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
6359		return NT_STATUS_OK;
6360	}
6361
6362	force_flush_samr_cache(&dinfo->sid);
6363
6364	result = NT_STATUS_OK;
6365
6366	return result;
6367}
6368
6369/*******************************************************************
6370 _samr_QueryDomainInfo2
6371 ********************************************************************/
6372
6373NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
6374				struct samr_QueryDomainInfo2 *r)
6375{
6376	struct samr_QueryDomainInfo q;
6377
6378	q.in.domain_handle	= r->in.domain_handle;
6379	q.in.level		= r->in.level;
6380
6381	q.out.info		= r->out.info;
6382
6383	return _samr_QueryDomainInfo(p, &q);
6384}
6385
6386/*******************************************************************
6387 ********************************************************************/
6388
6389static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
6390			       struct samr_DomInfo1 *r)
6391{
6392	time_t u_expire, u_min_age;
6393
6394	u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
6395	u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
6396
6397	pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
6398			       (uint32_t)r->min_password_length);
6399	pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
6400			       (uint32_t)r->password_history_length);
6401	pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
6402			       (uint32_t)r->password_properties);
6403	pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
6404	pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
6405
6406	return NT_STATUS_OK;
6407}
6408
6409/*******************************************************************
6410 ********************************************************************/
6411
6412static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
6413			       struct samr_DomInfo3 *r)
6414{
6415	time_t u_logout;
6416
6417	u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
6418
6419	pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
6420
6421	return NT_STATUS_OK;
6422}
6423
6424/*******************************************************************
6425 ********************************************************************/
6426
6427static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
6428			        struct samr_DomInfo12 *r)
6429{
6430	time_t u_lock_duration, u_reset_time;
6431
6432	u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
6433	if (u_lock_duration != -1) {
6434		u_lock_duration /= 60;
6435	}
6436
6437	u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
6438
6439	pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
6440	pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
6441	pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
6442			       (uint32_t)r->lockout_threshold);
6443
6444	return NT_STATUS_OK;
6445}
6446
6447/*******************************************************************
6448 _samr_SetDomainInfo
6449 ********************************************************************/
6450
6451NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
6452			     struct samr_SetDomainInfo *r)
6453{
6454	struct samr_domain_info *dinfo;
6455	NTSTATUS status;
6456	uint32_t acc_required = 0;
6457
6458	DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6459
6460	switch (r->in.level) {
6461	case 1: /* DomainPasswordInformation */
6462	case 12: /* DomainLockoutInformation */
6463		/* DOMAIN_WRITE_PASSWORD_PARAMETERS */
6464		acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
6465		break;
6466	case 3: /* DomainLogoffInformation */
6467	case 4: /* DomainOemInformation */
6468		/* DOMAIN_WRITE_OTHER_PARAMETERS */
6469		acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
6470		break;
6471	case 6: /* DomainReplicationInformation */
6472	case 9: /* DomainStateInformation */
6473	case 7: /* DomainServerRoleInformation */
6474		/* DOMAIN_ADMINISTER_SERVER */
6475		acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
6476		break;
6477	default:
6478		return NT_STATUS_INVALID_INFO_CLASS;
6479	}
6480
6481	dinfo = policy_handle_find(p, r->in.domain_handle,
6482				   acc_required, NULL,
6483				   struct samr_domain_info, &status);
6484	if (!NT_STATUS_IS_OK(status)) {
6485		return status;
6486	}
6487
6488	DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
6489
6490	switch (r->in.level) {
6491		case 1:
6492			status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
6493            		break;
6494		case 3:
6495			status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
6496			break;
6497		case 4:
6498			break;
6499		case 6:
6500			break;
6501		case 7:
6502			break;
6503		case 9:
6504			break;
6505		case 12:
6506			status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
6507			break;
6508		default:
6509			return NT_STATUS_INVALID_INFO_CLASS;
6510	}
6511
6512	if (!NT_STATUS_IS_OK(status)) {
6513		return status;
6514	}
6515
6516	DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
6517
6518	return NT_STATUS_OK;
6519}
6520
6521/****************************************************************
6522 _samr_GetDisplayEnumerationIndex
6523****************************************************************/
6524
6525NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
6526					  struct samr_GetDisplayEnumerationIndex *r)
6527{
6528	struct samr_domain_info *dinfo;
6529	uint32_t max_entries = (uint32_t) -1;
6530	uint32_t enum_context = 0;
6531	int i;
6532	uint32_t num_account = 0;
6533	struct samr_displayentry *entries = NULL;
6534	NTSTATUS status;
6535
6536	DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
6537
6538	dinfo = policy_handle_find(p, r->in.domain_handle,
6539				   SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
6540				   struct samr_domain_info, &status);
6541	if (!NT_STATUS_IS_OK(status)) {
6542		return status;
6543	}
6544
6545	if ((r->in.level < 1) || (r->in.level > 3)) {
6546		DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
6547			"Unknown info level (%u)\n",
6548			r->in.level));
6549		return NT_STATUS_INVALID_INFO_CLASS;
6550	}
6551
6552	become_root();
6553
6554	/* The following done as ROOT. Don't return without unbecome_root(). */
6555
6556	switch (r->in.level) {
6557	case 1:
6558		if (dinfo->disp_info->users == NULL) {
6559			dinfo->disp_info->users = pdb_search_users(
6560				dinfo->disp_info, ACB_NORMAL);
6561			if (dinfo->disp_info->users == NULL) {
6562				unbecome_root();
6563				return NT_STATUS_ACCESS_DENIED;
6564			}
6565			DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6566				"starting user enumeration at index %u\n",
6567				(unsigned int)enum_context));
6568		} else {
6569			DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6570				"using cached user enumeration at index %u\n",
6571				(unsigned int)enum_context));
6572		}
6573		num_account = pdb_search_entries(dinfo->disp_info->users,
6574						 enum_context, max_entries,
6575						 &entries);
6576		break;
6577	case 2:
6578		if (dinfo->disp_info->machines == NULL) {
6579			dinfo->disp_info->machines = pdb_search_users(
6580				dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
6581			if (dinfo->disp_info->machines == NULL) {
6582				unbecome_root();
6583				return NT_STATUS_ACCESS_DENIED;
6584			}
6585			DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6586				"starting machine enumeration at index %u\n",
6587				(unsigned int)enum_context));
6588		} else {
6589			DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6590				"using cached machine enumeration at index %u\n",
6591				(unsigned int)enum_context));
6592		}
6593		num_account = pdb_search_entries(dinfo->disp_info->machines,
6594						 enum_context, max_entries,
6595						 &entries);
6596		break;
6597	case 3:
6598		if (dinfo->disp_info->groups == NULL) {
6599			dinfo->disp_info->groups = pdb_search_groups(
6600				dinfo->disp_info);
6601			if (dinfo->disp_info->groups == NULL) {
6602				unbecome_root();
6603				return NT_STATUS_ACCESS_DENIED;
6604			}
6605			DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6606				"starting group enumeration at index %u\n",
6607				(unsigned int)enum_context));
6608		} else {
6609			DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6610				"using cached group enumeration at index %u\n",
6611				(unsigned int)enum_context));
6612		}
6613		num_account = pdb_search_entries(dinfo->disp_info->groups,
6614						 enum_context, max_entries,
6615						 &entries);
6616		break;
6617	default:
6618		unbecome_root();
6619		smb_panic("info class changed");
6620		break;
6621	}
6622
6623	unbecome_root();
6624
6625	/* Ensure we cache this enumeration. */
6626	set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
6627
6628	DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
6629		r->in.name->string));
6630
6631	for (i=0; i<num_account; i++) {
6632		if (strequal(entries[i].account_name, r->in.name->string)) {
6633			DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
6634				"found %s at idx %d\n",
6635				r->in.name->string, i));
6636			*r->out.idx = i;
6637			return NT_STATUS_OK;
6638		}
6639	}
6640
6641	/* assuming account_name lives at the very end */
6642	*r->out.idx = num_account;
6643
6644	return NT_STATUS_NO_MORE_ENTRIES;
6645}
6646
6647/****************************************************************
6648 _samr_GetDisplayEnumerationIndex2
6649****************************************************************/
6650
6651NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
6652					   struct samr_GetDisplayEnumerationIndex2 *r)
6653{
6654	struct samr_GetDisplayEnumerationIndex q;
6655
6656	q.in.domain_handle	= r->in.domain_handle;
6657	q.in.level		= r->in.level;
6658	q.in.name		= r->in.name;
6659
6660	q.out.idx		= r->out.idx;
6661
6662	return _samr_GetDisplayEnumerationIndex(p, &q);
6663}
6664
6665/****************************************************************
6666 _samr_RidToSid
6667****************************************************************/
6668
6669NTSTATUS _samr_RidToSid(pipes_struct *p,
6670			struct samr_RidToSid *r)
6671{
6672	struct samr_domain_info *dinfo;
6673	NTSTATUS status;
6674	struct dom_sid sid;
6675
6676	dinfo = policy_handle_find(p, r->in.domain_handle,
6677				   0, NULL,
6678				   struct samr_domain_info, &status);
6679	if (!NT_STATUS_IS_OK(status)) {
6680		return status;
6681	}
6682
6683	if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
6684		return NT_STATUS_NO_MEMORY;
6685	}
6686
6687	*r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
6688	if (!*r->out.sid) {
6689		return NT_STATUS_NO_MEMORY;
6690	}
6691
6692	return NT_STATUS_OK;
6693}
6694
6695/****************************************************************
6696****************************************************************/
6697
6698NTSTATUS _samr_Shutdown(pipes_struct *p,
6699			struct samr_Shutdown *r)
6700{
6701	p->rng_fault_state = true;
6702	return NT_STATUS_NOT_IMPLEMENTED;
6703}
6704
6705/****************************************************************
6706****************************************************************/
6707
6708NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
6709					  struct samr_SetMemberAttributesOfGroup *r)
6710{
6711	p->rng_fault_state = true;
6712	return NT_STATUS_NOT_IMPLEMENTED;
6713}
6714
6715/****************************************************************
6716****************************************************************/
6717
6718NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
6719					  struct samr_TestPrivateFunctionsDomain *r)
6720{
6721	return NT_STATUS_NOT_IMPLEMENTED;
6722}
6723
6724/****************************************************************
6725****************************************************************/
6726
6727NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
6728					struct samr_TestPrivateFunctionsUser *r)
6729{
6730	return NT_STATUS_NOT_IMPLEMENTED;
6731}
6732
6733/****************************************************************
6734****************************************************************/
6735
6736NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
6737					 struct samr_AddMultipleMembersToAlias *r)
6738{
6739	p->rng_fault_state = true;
6740	return NT_STATUS_NOT_IMPLEMENTED;
6741}
6742
6743/****************************************************************
6744****************************************************************/
6745
6746NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
6747					      struct samr_RemoveMultipleMembersFromAlias *r)
6748{
6749	p->rng_fault_state = true;
6750	return NT_STATUS_NOT_IMPLEMENTED;
6751}
6752
6753/****************************************************************
6754****************************************************************/
6755
6756NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
6757				     struct samr_SetBootKeyInformation *r)
6758{
6759	p->rng_fault_state = true;
6760	return NT_STATUS_NOT_IMPLEMENTED;
6761}
6762
6763/****************************************************************
6764****************************************************************/
6765
6766NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
6767				     struct samr_GetBootKeyInformation *r)
6768{
6769	p->rng_fault_state = true;
6770	return NT_STATUS_NOT_IMPLEMENTED;
6771}
6772
6773/****************************************************************
6774****************************************************************/
6775
6776NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
6777			       struct samr_SetDsrmPassword *r)
6778{
6779	p->rng_fault_state = true;
6780	return NT_STATUS_NOT_IMPLEMENTED;
6781}
6782
6783/****************************************************************
6784****************************************************************/
6785
6786NTSTATUS _samr_ValidatePassword(pipes_struct *p,
6787				struct samr_ValidatePassword *r)
6788{
6789	p->rng_fault_state = true;
6790	return NT_STATUS_NOT_IMPLEMENTED;
6791}
6792