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-2002,
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 *
13 *  This program is free software; you can redistribute it and/or modify
14 *  it under the terms of the GNU General Public License as published by
15 *  the Free Software Foundation; either version 2 of the License, or
16 *  (at your option) any later version.
17 *
18 *  This program is distributed in the hope that it will be useful,
19 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 *  GNU General Public License for more details.
22 *
23 *  You should have received a copy of the GNU General Public License
24 *  along with this program; if not, write to the Free Software
25 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28/*
29 * This is the implementation of the SAMR code.
30 */
31
32#include "includes.h"
33
34#undef DBGC_CLASS
35#define DBGC_CLASS DBGC_RPC_SRV
36
37#define SAMR_USR_RIGHTS_WRITE_PW \
38		( READ_CONTROL_ACCESS		| \
39		  SA_RIGHT_USER_CHANGE_PASSWORD	| \
40		  SA_RIGHT_USER_SET_LOC_COM )
41
42extern DOM_SID global_sid_Builtin;
43
44extern rid_name domain_group_rids[];
45extern rid_name domain_alias_rids[];
46extern rid_name builtin_alias_rids[];
47
48
49typedef struct _disp_info {
50	BOOL user_dbloaded;
51	uint32 num_user_account;
52	SAM_ACCOUNT *disp_user_info;
53	BOOL group_dbloaded;
54	uint32 num_group_account;
55	DOMAIN_GRP *disp_group_info;
56} DISP_INFO;
57
58struct samr_info {
59	/* for use by the \PIPE\samr policy */
60	DOM_SID sid;
61	uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
62	uint32 acc_granted;
63	uint16 acb_mask;
64	BOOL only_machines;
65	DISP_INFO disp_info;
66
67	TALLOC_CTX *mem_ctx;
68};
69
70struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
71struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
72struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
73struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
74struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
75
76/*******************************************************************
77*******************************************************************/
78
79static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
80                                     struct generic_mapping *map,
81				     DOM_SID *sid, uint32 sid_access )
82{
83	extern DOM_SID global_sid_World;
84	DOM_SID adm_sid, act_sid, domadmin_sid;
85	SEC_ACE ace[5];		/* at most 5 entries */
86	SEC_ACCESS mask;
87	size_t i = 0;
88
89	SEC_ACL *psa = NULL;
90
91	/* basic access for Everyone */
92
93	init_sec_access(&mask, map->generic_execute | map->generic_read );
94	init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
95
96	/* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
97
98	sid_copy(&adm_sid, &global_sid_Builtin);
99	sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
100
101	sid_copy(&act_sid, &global_sid_Builtin);
102	sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
103
104	init_sec_access(&mask, map->generic_all);
105
106	init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
107	init_sec_ace(&ace[i++], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
108
109	/* Add Full Access for Domain Admins if we are a DC */
110
111	if ( IS_DC ) {
112		sid_copy( &domadmin_sid, get_global_sam_sid() );
113		sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
114		init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
115	}
116
117	/* if we have a sid, give it some special access */
118
119	if ( sid ) {
120		init_sec_access( &mask, sid_access );
121		init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
122	}
123
124	/* create the security descriptor */
125
126	if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
127		return NT_STATUS_NO_MEMORY;
128
129	if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
130		return NT_STATUS_NO_MEMORY;
131
132	return NT_STATUS_OK;
133}
134
135/*******************************************************************
136 Checks if access to an object should be granted, and returns that
137 level of access for further checks.
138********************************************************************/
139
140static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
141                                          SE_PRIV *rights, uint32 rights_mask,
142                                          uint32 des_access, uint32 *acc_granted,
143					  const char *debug )
144{
145	NTSTATUS status = NT_STATUS_ACCESS_DENIED;
146	uint32 saved_mask = 0;
147
148	/* check privileges; certain SAM access bits should be overridden
149	   by privileges (mostly having to do with creating/modifying/deleting
150	   users and groups) */
151
152	if ( rights && user_has_any_privilege( token, rights ) ) {
153
154		saved_mask = (des_access & rights_mask);
155		des_access &= ~saved_mask;
156
157		DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
158			rights_mask));
159	}
160
161
162	/* check the security descriptor first */
163
164	if ( se_access_check(psd, token, des_access, acc_granted, &status) )
165		goto done;
166
167	/* give root a free pass */
168
169	if ( geteuid() == sec_initial_uid() ) {
170
171		DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
172		DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
173
174		*acc_granted = des_access;
175
176		status = NT_STATUS_OK;
177		goto done;
178	}
179
180
181done:
182	/* add in any bits saved during the privilege check (only
183	   matters is status is ok) */
184
185	*acc_granted |= rights_mask;
186
187	DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
188		debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
189		des_access, *acc_granted));
190
191	return status;
192}
193
194/*******************************************************************
195 Checks if access to a function can be granted
196********************************************************************/
197
198static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
199{
200	DEBUG(5,("%s: access check ((granted: %#010x;  required: %#010x)\n",
201		debug, acc_granted, acc_required));
202
203	/* check the security descriptor first */
204
205	if ( (acc_granted&acc_required) == acc_required )
206		return NT_STATUS_OK;
207
208	/* give root a free pass */
209
210	if (geteuid() == sec_initial_uid()) {
211
212		DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
213			debug, acc_granted, acc_required));
214		DEBUGADD(4,("but overwritten by euid == 0\n"));
215
216		return NT_STATUS_OK;
217	}
218
219	DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n",
220		debug, acc_granted, acc_required));
221
222	return NT_STATUS_ACCESS_DENIED;
223}
224
225
226/*******************************************************************
227 Create a samr_info struct.
228********************************************************************/
229
230static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
231{
232	struct samr_info *info;
233	fstring sid_str;
234	TALLOC_CTX *mem_ctx;
235
236	if (psid) {
237		sid_to_string(sid_str, psid);
238	} else {
239		fstrcpy(sid_str,"(NULL)");
240	}
241
242	mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
243
244	if ((info = TALLOC_P(mem_ctx, struct samr_info)) == NULL)
245		return NULL;
246
247	ZERO_STRUCTP(info);
248	DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
249	if (psid) {
250		sid_copy( &info->sid, psid);
251	} else {
252		DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
253	}
254	info->mem_ctx = mem_ctx;
255	return info;
256}
257
258/*******************************************************************
259 Function to free the per handle data.
260 ********************************************************************/
261
262static void free_samr_users(struct samr_info *info)
263{
264	int i;
265
266	if (info->disp_info.user_dbloaded){
267		for (i=0; i<info->disp_info.num_user_account; i++) {
268			SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
269			/* Not really a free, actually a 'clear' */
270			pdb_free_sam(&sam);
271		}
272	}
273	info->disp_info.user_dbloaded=False;
274	info->disp_info.num_user_account=0;
275}
276
277/*******************************************************************
278 Function to free the per handle data.
279 ********************************************************************/
280
281static void free_samr_db(struct samr_info *info)
282{
283	/* Groups are talloced */
284
285	free_samr_users(info);
286
287	info->disp_info.group_dbloaded=False;
288	info->disp_info.num_group_account=0;
289}
290
291static void free_samr_info(void *ptr)
292{
293	struct samr_info *info=(struct samr_info *) ptr;
294
295	free_samr_db(info);
296	talloc_destroy(info->mem_ctx);
297}
298
299/*******************************************************************
300 Ensure password info is never given out. Paranioa... JRA.
301 ********************************************************************/
302
303static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
304{
305
306	if (!sam_pass)
307		return;
308
309	/* These now zero out the old password */
310
311	pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
312	pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
313}
314
315
316static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL only_machines)
317{
318	SAM_ACCOUNT *pwd = NULL;
319	SAM_ACCOUNT *pwd_array = NULL;
320	NTSTATUS nt_status = NT_STATUS_OK;
321	TALLOC_CTX *mem_ctx = info->mem_ctx;
322	uint16 query_acb_mask = acb_mask;
323
324	DEBUG(10,("load_sampwd_entries\n"));
325
326	/* if the snapshoot is already loaded, return */
327	if ((info->disp_info.user_dbloaded==True)
328	    && (info->acb_mask == acb_mask)
329	    && (info->only_machines == only_machines)) {
330		DEBUG(10,("load_sampwd_entries: already in memory\n"));
331		return NT_STATUS_OK;
332	}
333
334	free_samr_users(info);
335
336	if (only_machines) {
337		query_acb_mask |= ACB_WSTRUST;
338		query_acb_mask |= ACB_SVRTRUST;
339	}
340
341	if (!pdb_setsampwent(False, query_acb_mask)) {
342		DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
343		return NT_STATUS_ACCESS_DENIED;
344	}
345
346	for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
347		     && pdb_getsampwent(pwd) == True; pwd=NULL) {
348
349		if (only_machines) {
350			if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
351			      || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
352				DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
353				pdb_free_sam(&pwd);
354				continue;
355			}
356		} else {
357			if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
358				pdb_free_sam(&pwd);
359				DEBUG(5,(" acb_mask %x reject\n", acb_mask));
360				continue;
361			}
362		}
363
364		/* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
365		if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
366
367			DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
368			pwd_array=TALLOC_REALLOC_ARRAY(mem_ctx, info->disp_info.disp_user_info, SAM_ACCOUNT,
369			                  info->disp_info.num_user_account+MAX_SAM_ENTRIES);
370
371			if (pwd_array==NULL)
372				return NT_STATUS_NO_MEMORY;
373
374			info->disp_info.disp_user_info=pwd_array;
375		}
376
377		/* Copy the SAM_ACCOUNT into the array */
378		info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
379
380		DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
381
382		info->disp_info.num_user_account++;
383	}
384
385	pdb_endsampwent();
386
387	/* the snapshoot is in memory, we're ready to enumerate fast */
388
389	info->acb_mask = acb_mask;
390	info->only_machines = only_machines;
391	info->disp_info.user_dbloaded=True;
392
393	DEBUG(10,("load_sampwd_entries: done\n"));
394
395	return nt_status;
396}
397
398static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
399{
400	GROUP_MAP *map=NULL;
401	DOMAIN_GRP *grp_array = NULL;
402	uint32 group_entries = 0;
403	uint32 i;
404	TALLOC_CTX *mem_ctx = info->mem_ctx;
405	BOOL ret;
406
407	DEBUG(10,("load_group_domain_entries\n"));
408
409	/* if the snapshoot is already loaded, return */
410	if (info->disp_info.group_dbloaded==True) {
411		DEBUG(10,("load_group_domain_entries: already in memory\n"));
412		return NT_STATUS_OK;
413	}
414
415	if (sid_equal(sid, &global_sid_Builtin)) {
416		/* No domain groups for now in the BUILTIN domain */
417		info->disp_info.num_group_account=0;
418		info->disp_info.disp_group_info=NULL;
419		info->disp_info.group_dbloaded=True;
420		return NT_STATUS_OK;
421	}
422
423	become_root();
424	ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
425	unbecome_root();
426
427	if ( !ret ) {
428		DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
429		return NT_STATUS_NO_MEMORY;
430	}
431
432
433	info->disp_info.num_group_account=group_entries;
434
435	grp_array=TALLOC_ARRAY(mem_ctx, DOMAIN_GRP, info->disp_info.num_group_account);
436	if (group_entries!=0 && grp_array==NULL) {
437		DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
438		SAFE_FREE(map);
439		return NT_STATUS_NO_MEMORY;
440	}
441
442	info->disp_info.disp_group_info=grp_array;
443
444	for (i=0; i<group_entries; i++) {
445		fstrcpy(grp_array[i].name, map[i].nt_name);
446		fstrcpy(grp_array[i].comment, map[i].comment);
447		sid_split_rid(&map[i].sid, &grp_array[i].rid);
448		grp_array[i].attr=SID_NAME_DOM_GRP;
449	}
450
451	SAFE_FREE(map);
452
453	/* the snapshoot is in memory, we're ready to enumerate fast */
454
455	info->disp_info.group_dbloaded=True;
456
457	DEBUG(10,("load_group_domain_entries: done\n"));
458
459	return NT_STATUS_OK;
460}
461
462
463/*******************************************************************
464 _samr_close_hnd
465 ********************************************************************/
466
467NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
468{
469	r_u->status = NT_STATUS_OK;
470
471	/* close the policy handle */
472	if (!close_policy_hnd(p, &q_u->pol))
473		return NT_STATUS_OBJECT_NAME_INVALID;
474
475	DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
476
477	return r_u->status;
478}
479
480/*******************************************************************
481 samr_reply_open_domain
482 ********************************************************************/
483
484NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
485{
486	struct    samr_info *info;
487	SEC_DESC *psd = NULL;
488	uint32    acc_granted;
489	uint32    des_access = q_u->flags;
490	NTSTATUS  status;
491	size_t sd_size;
492	SE_PRIV se_rights;
493
494	r_u->status = NT_STATUS_OK;
495
496	/* find the connection policy handle. */
497
498	if ( !find_policy_by_hnd(p, &q_u->pol, (void**)&info) )
499		return NT_STATUS_INVALID_HANDLE;
500
501	status = access_check_samr_function( info->acc_granted,
502		SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_open_domain" );
503
504	if ( !NT_STATUS_IS_OK(status) )
505		return status;
506
507	/*check if access can be granted as requested by client. */
508
509	make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
510	se_map_generic( &des_access, &dom_generic_mapping );
511
512	se_priv_copy( &se_rights, &se_machine_account );
513	se_priv_add( &se_rights, &se_add_users );
514
515	status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
516		&se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
517		&acc_granted, "_samr_open_domain" );
518
519	if ( !NT_STATUS_IS_OK(status) )
520		return status;
521
522	/* associate the domain SID with the (unique) handle. */
523	if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
524		return NT_STATUS_NO_MEMORY;
525	info->acc_granted = acc_granted;
526
527	/* get a (unique) handle.  open a policy on it. */
528	if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
529		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
530
531	DEBUG(5,("samr_open_domain: %d\n", __LINE__));
532
533	return r_u->status;
534}
535
536/*******************************************************************
537 _samr_get_usrdom_pwinfo
538 ********************************************************************/
539
540NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
541{
542	struct samr_info *info = NULL;
543
544	r_u->status = NT_STATUS_OK;
545
546	/* find the policy handle.  open a policy on it. */
547	if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
548		return NT_STATUS_INVALID_HANDLE;
549
550	if (!sid_check_is_in_our_domain(&info->sid))
551		return NT_STATUS_OBJECT_TYPE_MISMATCH;
552
553	init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
554
555	DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
556
557	/*
558	 * NT sometimes return NT_STATUS_ACCESS_DENIED
559	 * I don't know yet why.
560	 */
561
562	return r_u->status;
563}
564
565
566/*******************************************************************
567 _samr_set_sec_obj
568 ********************************************************************/
569
570NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
571{
572	DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
573	return NT_STATUS_NOT_IMPLEMENTED;
574}
575
576
577/*******************************************************************
578********************************************************************/
579
580static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
581                                     DOM_SID *sid, uint32 *acc_granted)
582{
583	struct samr_info *info = NULL;
584
585	/* find the policy handle.  open a policy on it. */
586	if (!find_policy_by_hnd(p, pol, (void **)&info))
587		return False;
588
589	if (!info)
590		return False;
591
592	*sid = info->sid;
593	*acc_granted = info->acc_granted;
594	return True;
595}
596
597/*******************************************************************
598 _samr_query_sec_obj
599 ********************************************************************/
600
601NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
602{
603	DOM_SID pol_sid;
604	fstring str_sid;
605	SEC_DESC * psd = NULL;
606	uint32 acc_granted;
607	size_t sd_size;
608
609	r_u->status = NT_STATUS_OK;
610
611	/* Get the SID. */
612	if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
613		return NT_STATUS_INVALID_HANDLE;
614
615
616
617	DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
618
619	/* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
620
621	/* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
622	if (pol_sid.sid_rev_num == 0)
623	{
624		DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
625		r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
626	}
627	else if (sid_equal(&pol_sid,get_global_sam_sid()))  /* check if it is our domain SID */
628
629	{
630		DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
631		r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
632	}
633	else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin  Domain */
634	{
635		/* TODO: Builtin probably needs a different SD with restricted write access*/
636		DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
637		r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
638	}
639	else if (sid_check_is_in_our_domain(&pol_sid) ||
640	    	 sid_check_is_in_builtin(&pol_sid))
641	{
642		/* TODO: different SDs have to be generated for aliases groups and users.
643		         Currently all three get a default user SD  */
644		DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
645		r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
646	}
647	else return NT_STATUS_OBJECT_TYPE_MISMATCH;
648
649	if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
650		return NT_STATUS_NO_MEMORY;
651
652	if (NT_STATUS_IS_OK(r_u->status))
653		r_u->ptr = 1;
654
655	return r_u->status;
656}
657
658/*******************************************************************
659makes a SAM_ENTRY / UNISTR2* structure from a user list.
660********************************************************************/
661
662static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
663					 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
664					 DOM_SID *domain_sid)
665{
666	uint32 i;
667	SAM_ENTRY *sam;
668	UNISTR2 *uni_name;
669	SAM_ACCOUNT *pwd = NULL;
670	UNISTR2 uni_temp_name;
671	const char *temp_name;
672	const DOM_SID *user_sid;
673	uint32 user_rid;
674	fstring user_sid_string;
675	fstring domain_sid_string;
676
677	*sam_pp = NULL;
678	*uni_name_pp = NULL;
679
680	if (num_entries == 0)
681		return NT_STATUS_OK;
682
683	sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries);
684
685	uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_entries);
686
687	if (sam == NULL || uni_name == NULL) {
688		DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
689		return NT_STATUS_NO_MEMORY;
690	}
691
692	for (i = 0; i < num_entries; i++) {
693		pwd = &disp_user_info[i+start_idx];
694		temp_name = pdb_get_username(pwd);
695
696		/*
697		 * usrmgr expects a non-NULL terminated string with
698		 * trust relationships
699		 */
700		if (pdb_get_acct_ctrl(pwd) & ACB_DOMTRUST) {
701			init_unistr2(&uni_temp_name, temp_name, UNI_FLAGS_NONE);
702		} else {
703			init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
704		}
705
706		user_sid = pdb_get_user_sid(pwd);
707
708		if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
709			DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
710				  "the domain sid %s.  Failing operation.\n",
711				  temp_name,
712				  sid_to_string(user_sid_string, user_sid),
713				  sid_to_string(domain_sid_string, domain_sid)));
714			return NT_STATUS_UNSUCCESSFUL;
715		}
716
717		init_sam_entry(&sam[i], &uni_temp_name, user_rid);
718		copy_unistr2(&uni_name[i], &uni_temp_name);
719	}
720
721	*sam_pp = sam;
722	*uni_name_pp = uni_name;
723	return NT_STATUS_OK;
724}
725
726/*******************************************************************
727 samr_reply_enum_dom_users
728 ********************************************************************/
729
730NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
731			      SAMR_R_ENUM_DOM_USERS *r_u)
732{
733	struct samr_info *info = NULL;
734	uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
735	int num_account;
736	uint32 enum_context=q_u->start_idx;
737	uint32 max_size=q_u->max_size;
738	uint32 temp_size;
739	enum remote_arch_types ra_type = get_remote_arch();
740	int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
741	uint32 max_entries = max_sam_entries;
742	DOM_SID domain_sid;
743
744	r_u->status = NT_STATUS_OK;
745
746	/* find the policy handle.  open a policy on it. */
747	if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
748		return NT_STATUS_INVALID_HANDLE;
749
750	domain_sid = info->sid;
751
752 	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
753					SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
754					"_samr_enum_dom_users"))) {
755 		return r_u->status;
756	}
757
758	DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
759
760	become_root();
761	r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
762	unbecome_root();
763
764	if (!NT_STATUS_IS_OK(r_u->status))
765		return r_u->status;
766
767	num_account = info->disp_info.num_user_account;
768
769	if (enum_context > num_account) {
770		DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
771		return NT_STATUS_OK;
772	}
773
774	/* verify we won't overflow */
775	if (max_entries > num_account-enum_context) {
776		max_entries = num_account-enum_context;
777		DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
778	}
779
780	/* calculate the size and limit on the number of entries we will return */
781	temp_size=max_entries*struct_size;
782
783	if (temp_size>max_size) {
784		max_entries=MIN((max_size/struct_size),max_entries);;
785		DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
786	}
787
788	/*
789	 * Note from JRA. total_entries is not being used here. Currently if there is a
790	 * large user base then it looks like NT will enumerate until get_sampwd_entries
791	 * returns False due to num_entries being zero. This will cause an access denied
792	 * return. I don't think this is right and needs further investigation. Note that
793	 * this is also the same in the TNG code (I don't think that has been tested with
794	 * a very large user list as MAX_SAM_ENTRIES is set to 600).
795	 *
796	 * I also think that one of the 'num_entries' return parameters is probably
797	 * the "max entries" parameter - but in the TNG code they're all currently set to the same
798	 * value (again I think this is wrong).
799	 */
800
801	r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
802					       max_entries, enum_context,
803					       info->disp_info.disp_user_info,
804					       &domain_sid);
805
806	if (!NT_STATUS_IS_OK(r_u->status))
807		return r_u->status;
808
809	if (enum_context+max_entries < num_account)
810		r_u->status = STATUS_MORE_ENTRIES;
811
812	DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
813
814	init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
815
816	DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
817
818	return r_u->status;
819}
820
821/*******************************************************************
822makes a SAM_ENTRY / UNISTR2* structure from a group list.
823********************************************************************/
824
825static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
826                uint32 num_sam_entries, DOMAIN_GRP *grp)
827{
828	uint32 i;
829	SAM_ENTRY *sam;
830	UNISTR2 *uni_name;
831
832	*sam_pp = NULL;
833	*uni_name_pp = NULL;
834
835	if (num_sam_entries == 0)
836		return;
837
838	sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
839	uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
840
841	if (sam == NULL || uni_name == NULL) {
842		DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
843		return;
844	}
845
846	for (i = 0; i < num_sam_entries; i++) {
847		/*
848		 * JRA. I think this should include the null. TNG does not.
849		 */
850		init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
851		init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
852	}
853
854	*sam_pp = sam;
855	*uni_name_pp = uni_name;
856}
857
858/*******************************************************************
859 Get the group entries - similar to get_sampwd_entries().
860 ******************************************************************/
861
862static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
863                                   DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
864                                   uint32 *p_num_entries, uint32 max_entries )
865{
866	GROUP_MAP *map=NULL;
867	int i;
868	uint32 group_entries = 0;
869	uint32 num_entries = 0;
870
871	*p_num_entries = 0;
872
873	/* access checks for the users were performed higher up.  become/unbecome_root()
874	   needed for some passdb backends to enumerate groups */
875
876	become_root();
877	pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
878			       ENUM_ONLY_MAPPED);
879	unbecome_root();
880
881	num_entries=group_entries-start_idx;
882
883	/* limit the number of entries */
884	if (num_entries>max_entries) {
885		DEBUG(5,("Limiting to %d entries\n", max_entries));
886		num_entries=max_entries;
887	}
888
889	*d_grp=TALLOC_ZERO_ARRAY(ctx, DOMAIN_GRP, num_entries);
890	if (num_entries!=0 && *d_grp==NULL){
891		SAFE_FREE(map);
892		return NT_STATUS_NO_MEMORY;
893	}
894
895	for (i=0; i<num_entries; i++) {
896		fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
897		fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
898		sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
899		(*d_grp)[i].attr=SID_NAME_DOM_GRP;
900	}
901
902	SAFE_FREE(map);
903
904	*p_num_entries = num_entries;
905
906	DEBUG(10,("get_group_domain_entries: returning %d entries\n",
907		  *p_num_entries));
908
909	return NT_STATUS_OK;
910}
911
912/*******************************************************************
913 Wrapper for enumerating local groups
914 ******************************************************************/
915
916static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
917				   const DOM_SID *sid, uint32 start_idx,
918                                   uint32 *p_num_entries, uint32 max_entries )
919{
920	struct acct_info *info;
921	int i;
922	BOOL res;
923
924	become_root();
925	res = pdb_enum_aliases(sid, start_idx, max_entries,
926			       p_num_entries, &info);
927	unbecome_root();
928
929	if (!res)
930		return NT_STATUS_ACCESS_DENIED;
931
932	if (*p_num_entries == 0)
933		return NT_STATUS_OK;
934
935	*d_grp = TALLOC_ARRAY(ctx, DOMAIN_GRP, *p_num_entries);
936
937	if (*d_grp == NULL) {
938		SAFE_FREE(info);
939		return NT_STATUS_NO_MEMORY;
940	}
941
942	for (i=0; i<*p_num_entries; i++) {
943		fstrcpy((*d_grp)[i].name, info[i].acct_name);
944		fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
945		(*d_grp)[i].rid = info[i].rid;
946		(*d_grp)[i].attr = SID_NAME_ALIAS;
947	}
948
949	SAFE_FREE(info);
950	return NT_STATUS_OK;
951}
952
953/*******************************************************************
954 samr_reply_enum_dom_groups
955 ********************************************************************/
956
957NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
958{
959	DOMAIN_GRP *grp=NULL;
960	uint32 num_entries;
961	DOM_SID sid;
962	uint32 acc_granted;
963
964	r_u->status = NT_STATUS_OK;
965
966	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
967		return NT_STATUS_INVALID_HANDLE;
968
969	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
970		return r_u->status;
971	}
972
973	DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
974
975	/* the domain group array is being allocated in the function below */
976	if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
977		return r_u->status;
978	}
979
980	make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
981
982	init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
983
984	DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
985
986	return r_u->status;
987}
988
989
990/*******************************************************************
991 samr_reply_enum_dom_aliases
992 ********************************************************************/
993
994NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
995{
996	DOMAIN_GRP *grp=NULL;
997	uint32 num_entries = 0;
998	fstring sid_str;
999	DOM_SID sid;
1000	NTSTATUS status;
1001	uint32  acc_granted;
1002
1003	r_u->status = NT_STATUS_OK;
1004
1005	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1006		return NT_STATUS_INVALID_HANDLE;
1007
1008	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1009		return r_u->status;
1010	}
1011
1012	sid_to_string(sid_str, &sid);
1013	DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1014
1015	status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1016				   &num_entries, MAX_SAM_ENTRIES);
1017	if (!NT_STATUS_IS_OK(status)) return status;
1018
1019	make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1020
1021	/*safe_free(grp);*/
1022
1023	init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1024
1025	DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1026
1027	return r_u->status;
1028}
1029
1030/*******************************************************************
1031 samr_reply_query_dispinfo
1032 ********************************************************************/
1033
1034NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1035			      SAMR_R_QUERY_DISPINFO *r_u)
1036{
1037	struct samr_info *info = NULL;
1038	uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1039
1040	uint32 max_entries=q_u->max_entries;
1041	uint32 enum_context=q_u->start_idx;
1042	uint32 max_size=q_u->max_size;
1043
1044	SAM_DISPINFO_CTR *ctr;
1045	uint32 temp_size=0, total_data_size=0;
1046	NTSTATUS disp_ret;
1047	uint32 num_account = 0;
1048	enum remote_arch_types ra_type = get_remote_arch();
1049	int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1050	DOM_SID domain_sid;
1051
1052	DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1053	r_u->status = NT_STATUS_OK;
1054
1055	/* find the policy handle.  open a policy on it. */
1056	if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1057		return NT_STATUS_INVALID_HANDLE;
1058
1059	domain_sid = info->sid;
1060
1061	/*
1062	 * calculate how many entries we will return.
1063	 * based on
1064	 * - the number of entries the client asked
1065	 * - our limit on that
1066	 * - the starting point (enumeration context)
1067	 * - the buffer size the client will accept
1068	 */
1069
1070	/*
1071	 * We are a lot more like W2K. Instead of reading the SAM
1072	 * each time to find the records we need to send back,
1073	 * we read it once and link that copy to the sam handle.
1074	 * For large user list (over the MAX_SAM_ENTRIES)
1075	 * it's a definitive win.
1076	 * second point to notice: between enumerations
1077	 * our sam is now the same as it's a snapshoot.
1078	 * third point: got rid of the static SAM_USER_21 struct
1079	 * no more intermediate.
1080	 * con: it uses much more memory, as a full copy is stored
1081	 * in memory.
1082	 *
1083	 * If you want to change it, think twice and think
1084	 * of the second point , that's really important.
1085	 *
1086	 * JFM, 12/20/2001
1087	 */
1088
1089	/* Get what we need from the password database */
1090	switch (q_u->switch_level) {
1091		case 0x1:
1092			/* When playing with usrmgr, this is necessary
1093                           if you want immediate refresh after editing
1094                           a user. I would like to do this after the
1095                           setuserinfo2, but we do not have access to
1096                           the domain handle in that call, only to the
1097                           user handle. Where else does this hurt?
1098			   -- Volker
1099			*/
1100#if 0
1101			/* We cannot do this here - it kills performace. JRA. */
1102			free_samr_users(info);
1103#endif
1104		case 0x2:
1105		case 0x4:
1106			become_root();
1107			/* Level 2 is for all machines, otherwise only 'normal' users */
1108			r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1109			unbecome_root();
1110			if (!NT_STATUS_IS_OK(r_u->status)) {
1111				DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1112				return r_u->status;
1113			}
1114			num_account = info->disp_info.num_user_account;
1115			break;
1116		case 0x3:
1117		case 0x5:
1118			r_u->status = load_group_domain_entries(info, &info->sid);
1119			if (!NT_STATUS_IS_OK(r_u->status))
1120				return r_u->status;
1121			num_account = info->disp_info.num_group_account;
1122			break;
1123		default:
1124			DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1125			return NT_STATUS_INVALID_INFO_CLASS;
1126	}
1127
1128	/* first limit the number of entries we will return */
1129	if(max_entries > max_sam_entries) {
1130		DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1131		max_entries = max_sam_entries;
1132	}
1133
1134	if (enum_context > num_account) {
1135		DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1136		return NT_STATUS_NO_MORE_ENTRIES;
1137	}
1138
1139	/* verify we won't overflow */
1140	if (max_entries > num_account-enum_context) {
1141		max_entries = num_account-enum_context;
1142		DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1143	}
1144
1145	/* calculate the size and limit on the number of entries we will return */
1146	temp_size=max_entries*struct_size;
1147
1148	if (temp_size>max_size) {
1149		max_entries=MIN((max_size/struct_size),max_entries);;
1150		DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1151	}
1152
1153	if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
1154		return NT_STATUS_NO_MEMORY;
1155
1156	ZERO_STRUCTP(ctr);
1157
1158	/* Now create reply structure */
1159	switch (q_u->switch_level) {
1160	case 0x1:
1161		if (max_entries) {
1162			if (!(ctr->sam.info1 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_1,max_entries)))
1163				return NT_STATUS_NO_MEMORY;
1164		}
1165		disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1166					       info->disp_info.disp_user_info, &domain_sid);
1167		if (!NT_STATUS_IS_OK(disp_ret))
1168			return disp_ret;
1169		break;
1170	case 0x2:
1171		if (max_entries) {
1172			if (!(ctr->sam.info2 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_2,max_entries)))
1173				return NT_STATUS_NO_MEMORY;
1174		}
1175		disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1176					       info->disp_info.disp_user_info, &domain_sid);
1177		if (!NT_STATUS_IS_OK(disp_ret))
1178			return disp_ret;
1179		break;
1180	case 0x3:
1181		if (max_entries) {
1182			if (!(ctr->sam.info3 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_3,max_entries)))
1183				return NT_STATUS_NO_MEMORY;
1184		}
1185		disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1186		if (!NT_STATUS_IS_OK(disp_ret))
1187			return disp_ret;
1188		break;
1189	case 0x4:
1190		if (max_entries) {
1191			if (!(ctr->sam.info4 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_4,max_entries)))
1192				return NT_STATUS_NO_MEMORY;
1193		}
1194		disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1195		if (!NT_STATUS_IS_OK(disp_ret))
1196			return disp_ret;
1197		break;
1198	case 0x5:
1199		if (max_entries) {
1200			if (!(ctr->sam.info5 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_5,max_entries)))
1201				return NT_STATUS_NO_MEMORY;
1202		}
1203		disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1204		if (!NT_STATUS_IS_OK(disp_ret))
1205			return disp_ret;
1206		break;
1207
1208	default:
1209		ctr->sam.info = NULL;
1210		return NT_STATUS_INVALID_INFO_CLASS;
1211	}
1212
1213	/* calculate the total size */
1214	total_data_size=num_account*struct_size;
1215
1216	if (enum_context+max_entries < num_account)
1217		r_u->status = STATUS_MORE_ENTRIES;
1218
1219	DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1220
1221	init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1222
1223	return r_u->status;
1224
1225}
1226
1227/*******************************************************************
1228 samr_reply_query_aliasinfo
1229 ********************************************************************/
1230
1231NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1232{
1233	DOM_SID   sid;
1234	struct acct_info info;
1235	uint32    acc_granted;
1236	BOOL ret;
1237
1238	r_u->status = NT_STATUS_OK;
1239
1240	DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1241
1242	/* find the policy handle.  open a policy on it. */
1243	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1244		return NT_STATUS_INVALID_HANDLE;
1245	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1246		return r_u->status;
1247	}
1248
1249	become_root();
1250	ret = pdb_get_aliasinfo(&sid, &info);
1251	unbecome_root();
1252
1253	if ( !ret )
1254		return NT_STATUS_NO_SUCH_ALIAS;
1255
1256	switch (q_u->switch_level) {
1257	case 1:
1258		r_u->ptr = 1;
1259		r_u->ctr.switch_value1 = 1;
1260		init_samr_alias_info1(&r_u->ctr.alias.info1,
1261				      info.acct_name, 1, info.acct_desc);
1262		break;
1263	case 3:
1264		r_u->ptr = 1;
1265		r_u->ctr.switch_value1 = 3;
1266		init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1267		break;
1268	default:
1269		return NT_STATUS_INVALID_INFO_CLASS;
1270	}
1271
1272	DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1273
1274	return r_u->status;
1275}
1276
1277#if 0
1278/*******************************************************************
1279 samr_reply_lookup_ids
1280 ********************************************************************/
1281
1282 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1283{
1284    uint32 rid[MAX_SAM_ENTRIES];
1285    int num_rids = q_u->num_sids1;
1286
1287    r_u->status = NT_STATUS_OK;
1288
1289    DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1290
1291    if (num_rids > MAX_SAM_ENTRIES) {
1292        num_rids = MAX_SAM_ENTRIES;
1293        DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1294    }
1295
1296#if 0
1297    int i;
1298    SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1299
1300    for (i = 0; i < num_rids && status == 0; i++)
1301    {
1302        struct sam_passwd *sam_pass;
1303        fstring user_name;
1304
1305
1306        fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1307                                    q_u->uni_user_name[i].uni_str_len));
1308
1309        /* find the user account */
1310        become_root();
1311        sam_pass = get_smb21pwd_entry(user_name, 0);
1312        unbecome_root();
1313
1314        if (sam_pass == NULL)
1315        {
1316            status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1317            rid[i] = 0;
1318        }
1319        else
1320        {
1321            rid[i] = sam_pass->user_rid;
1322        }
1323    }
1324#endif
1325
1326    num_rids = 1;
1327    rid[0] = BUILTIN_ALIAS_RID_USERS;
1328
1329    init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1330
1331    DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1332
1333    return r_u->status;
1334}
1335#endif
1336
1337/*******************************************************************
1338 _samr_lookup_names
1339 ********************************************************************/
1340
1341NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1342{
1343	uint32 rid[MAX_SAM_ENTRIES];
1344	uint32 local_rid;
1345	enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1346	enum SID_NAME_USE local_type;
1347	int i;
1348	int num_rids = q_u->num_names2;
1349	DOM_SID pol_sid;
1350	fstring sid_str;
1351	uint32  acc_granted;
1352
1353	r_u->status = NT_STATUS_OK;
1354
1355	DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1356
1357	ZERO_ARRAY(rid);
1358	ZERO_ARRAY(type);
1359
1360	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1361		init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1362		return r_u->status;
1363	}
1364
1365	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1366		return r_u->status;
1367	}
1368
1369	if (num_rids > MAX_SAM_ENTRIES) {
1370		num_rids = MAX_SAM_ENTRIES;
1371		DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1372	}
1373
1374	DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1375
1376	for (i = 0; i < num_rids; i++) {
1377		fstring name;
1378            	DOM_SID sid;
1379            	int ret;
1380
1381	        r_u->status = NT_STATUS_NONE_MAPPED;
1382
1383	        rid [i] = 0xffffffff;
1384	        type[i] = SID_NAME_UNKNOWN;
1385
1386		ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1387
1388 		/*
1389		 * we are only looking for a name
1390		 * the SID we get back can be outside
1391		 * the scope of the pol_sid
1392		 *
1393		 * in clear: it prevents to reply to domain\group: yes
1394		 * when only builtin\group exists.
1395		 *
1396		 * a cleaner code is to add the sid of the domain we're looking in
1397		 * to the local_lookup_name function.
1398		 */
1399
1400            	if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1401                	sid_split_rid(&sid, &local_rid);
1402
1403			if (sid_equal(&sid, &pol_sid)) {
1404				rid[i]=local_rid;
1405
1406				/* Windows does not return WKN_GRP here, even
1407				 * on lookups in builtin */
1408				type[i] = (local_type == SID_NAME_WKN_GRP) ?
1409					SID_NAME_ALIAS : local_type;
1410
1411                		r_u->status = NT_STATUS_OK;
1412			}
1413            	}
1414	}
1415
1416	init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1417
1418	DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1419
1420	return r_u->status;
1421}
1422
1423/*******************************************************************
1424 _samr_chgpasswd_user
1425 ********************************************************************/
1426
1427NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1428{
1429	fstring user_name;
1430	fstring wks;
1431
1432	DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1433
1434	r_u->status = NT_STATUS_OK;
1435
1436	rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1437	rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1438
1439	DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1440
1441	/*
1442	 * Pass the user through the NT -> unix user mapping
1443	 * function.
1444	 */
1445
1446	(void)map_username(user_name);
1447
1448	/*
1449	 * UNIX username case mangling not required, pass_oem_change
1450	 * is case insensitive.
1451	 */
1452
1453	r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1454				q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1455
1456	init_samr_r_chgpasswd_user(r_u, r_u->status);
1457
1458	DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1459
1460	return r_u->status;
1461}
1462
1463/*******************************************************************
1464makes a SAMR_R_LOOKUP_RIDS structure.
1465********************************************************************/
1466
1467static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1468	    UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1469{
1470	uint32 i;
1471	UNIHDR *hdr_name=NULL;
1472	UNISTR2 *uni_name=NULL;
1473
1474	*pp_uni_name = NULL;
1475	*pp_hdr_name = NULL;
1476
1477	if (num_names != 0) {
1478		hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1479		if (hdr_name == NULL)
1480			return False;
1481
1482		uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1483		if (uni_name == NULL)
1484			return False;
1485	}
1486
1487	for (i = 0; i < num_names; i++) {
1488		DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1489		init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1490		init_uni_hdr(&hdr_name[i], &uni_name[i]);
1491	}
1492
1493	*pp_uni_name = uni_name;
1494	*pp_hdr_name = hdr_name;
1495
1496	return True;
1497}
1498
1499/*******************************************************************
1500 _samr_lookup_rids
1501 ********************************************************************/
1502
1503NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1504{
1505	fstring group_names[MAX_SAM_ENTRIES];
1506	uint32 *group_attrs = NULL;
1507	UNIHDR *hdr_name = NULL;
1508	UNISTR2 *uni_name = NULL;
1509	DOM_SID pol_sid;
1510	int num_rids = q_u->num_rids1;
1511	int i;
1512	uint32 acc_granted;
1513	BOOL have_mapped = False;
1514	BOOL have_unmapped = False;
1515
1516	r_u->status = NT_STATUS_OK;
1517
1518	DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1519
1520	/* find the policy handle.  open a policy on it. */
1521	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1522		return NT_STATUS_INVALID_HANDLE;
1523
1524	if (num_rids > 1000) {
1525		DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
1526			  "to samba4 idl this is not possible\n", num_rids));
1527		return NT_STATUS_UNSUCCESSFUL;
1528	}
1529
1530	if (num_rids) {
1531		if ((group_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids )) == NULL)
1532			return NT_STATUS_NO_MEMORY;
1533 	}
1534
1535	if (!sid_equal(&pol_sid, get_global_sam_sid())) {
1536		/* TODO: Sooner or later we need to look up BUILTIN rids as
1537		 * well. -- vl */
1538		goto done;
1539	}
1540
1541	become_root();  /* lookup_sid can require root privs */
1542
1543	for (i = 0; i < num_rids; i++) {
1544		fstring tmpname;
1545		fstring domname;
1546		DOM_SID sid;
1547   		enum SID_NAME_USE type;
1548
1549		group_attrs[i] = SID_NAME_UNKNOWN;
1550		*group_names[i] = '\0';
1551
1552		sid_copy(&sid, &pol_sid);
1553		sid_append_rid(&sid, q_u->rid[i]);
1554
1555		if (lookup_sid(&sid, domname, tmpname, &type)) {
1556			group_attrs[i] = (uint32)type;
1557			fstrcpy(group_names[i],tmpname);
1558			DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i],
1559				 group_attrs[i]));
1560			have_mapped = True;
1561		} else {
1562			have_unmapped = True;
1563		}
1564	}
1565
1566	unbecome_root();
1567
1568 done:
1569
1570	r_u->status = NT_STATUS_NONE_MAPPED;
1571
1572	if (have_mapped)
1573		r_u->status =
1574			have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
1575
1576	if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1577		return NT_STATUS_NO_MEMORY;
1578
1579	init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1580
1581	DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1582
1583	return r_u->status;
1584}
1585
1586/*******************************************************************
1587 _samr_open_user. Safe - gives out no passwd info.
1588 ********************************************************************/
1589
1590NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1591{
1592	SAM_ACCOUNT *sampass=NULL;
1593	DOM_SID sid;
1594	POLICY_HND domain_pol = q_u->domain_pol;
1595	POLICY_HND *user_pol = &r_u->user_pol;
1596	struct samr_info *info = NULL;
1597	SEC_DESC *psd = NULL;
1598	uint32    acc_granted;
1599	uint32    des_access = q_u->access_mask;
1600	size_t    sd_size;
1601	BOOL ret;
1602	NTSTATUS nt_status;
1603	SE_PRIV se_rights;
1604
1605	r_u->status = NT_STATUS_OK;
1606
1607	/* find the domain policy handle and get domain SID / access bits in the domain policy. */
1608
1609	if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
1610		return NT_STATUS_INVALID_HANDLE;
1611
1612	nt_status = access_check_samr_function( acc_granted,
1613		SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user" );
1614
1615	if ( !NT_STATUS_IS_OK(nt_status) )
1616		return nt_status;
1617
1618	nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1619
1620	if (!NT_STATUS_IS_OK(nt_status))
1621		return nt_status;
1622
1623	/* append the user's RID to it */
1624
1625	if (!sid_append_rid(&sid, q_u->user_rid))
1626		return NT_STATUS_NO_SUCH_USER;
1627
1628	/* check if access can be granted as requested by client. */
1629
1630	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
1631	se_map_generic(&des_access, &usr_generic_mapping);
1632
1633	se_priv_copy( &se_rights, &se_machine_account );
1634	se_priv_add( &se_rights, &se_add_users );
1635
1636	nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
1637		&se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
1638		&acc_granted, "_samr_open_user");
1639
1640	if ( !NT_STATUS_IS_OK(nt_status) )
1641		return nt_status;
1642
1643	become_root();
1644	ret=pdb_getsampwsid(sampass, &sid);
1645	unbecome_root();
1646
1647	/* check that the SID exists in our domain. */
1648	if (ret == False) {
1649        	return NT_STATUS_NO_SUCH_USER;
1650	}
1651
1652	pdb_free_sam(&sampass);
1653
1654	/* associate the user's SID and access bits with the new handle. */
1655	if ((info = get_samr_info_by_sid(&sid)) == NULL)
1656		return NT_STATUS_NO_MEMORY;
1657	info->acc_granted = acc_granted;
1658
1659	/* get a (unique) handle.  open a policy on it. */
1660	if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1661		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1662
1663	return r_u->status;
1664}
1665
1666/*************************************************************************
1667 get_user_info_7. Safe. Only gives out account_name.
1668 *************************************************************************/
1669
1670static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, SAM_USER_INFO_7 *id7, DOM_SID *user_sid)
1671{
1672	SAM_ACCOUNT *smbpass=NULL;
1673	BOOL ret;
1674	NTSTATUS nt_status;
1675
1676	nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1677
1678	if (!NT_STATUS_IS_OK(nt_status)) {
1679		return nt_status;
1680	}
1681
1682	become_root();
1683	ret = pdb_getsampwsid(smbpass, user_sid);
1684	unbecome_root();
1685
1686	if (ret==False) {
1687		DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1688		return NT_STATUS_NO_SUCH_USER;
1689	}
1690
1691	DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1692
1693	ZERO_STRUCTP(id7);
1694	init_sam_user_info7(id7, pdb_get_username(smbpass) );
1695
1696	pdb_free_sam(&smbpass);
1697
1698	return NT_STATUS_OK;
1699}
1700/*************************************************************************
1701 get_user_info_10. Safe. Only gives out acb bits.
1702 *************************************************************************/
1703
1704static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1705{
1706	SAM_ACCOUNT *smbpass=NULL;
1707	BOOL ret;
1708	NTSTATUS nt_status;
1709
1710	nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1711
1712	if (!NT_STATUS_IS_OK(nt_status)) {
1713		return nt_status;
1714	}
1715
1716	become_root();
1717	ret = pdb_getsampwsid(smbpass, user_sid);
1718	unbecome_root();
1719
1720	if (ret==False) {
1721		DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1722		return NT_STATUS_NO_SUCH_USER;
1723	}
1724
1725	DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1726
1727	ZERO_STRUCTP(id10);
1728	init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1729
1730	pdb_free_sam(&smbpass);
1731
1732	return NT_STATUS_OK;
1733}
1734
1735/*************************************************************************
1736 get_user_info_12. OK - this is the killer as it gives out password info.
1737 Ensure that this is only allowed on an encrypted connection with a root
1738 user. JRA.
1739 *************************************************************************/
1740
1741static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1742{
1743	SAM_ACCOUNT *smbpass=NULL;
1744	BOOL ret;
1745	NTSTATUS nt_status;
1746
1747	if (!p->ntlmssp_auth_validated)
1748		return NT_STATUS_ACCESS_DENIED;
1749
1750	if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1751		return NT_STATUS_ACCESS_DENIED;
1752
1753	/*
1754	 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1755	 */
1756
1757	nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1758
1759	if (!NT_STATUS_IS_OK(nt_status)) {
1760		return nt_status;
1761	}
1762
1763	ret = pdb_getsampwsid(smbpass, user_sid);
1764
1765	if (ret == False) {
1766		DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1767		pdb_free_sam(&smbpass);
1768		return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1769	}
1770
1771	DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1772
1773	if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1774		pdb_free_sam(&smbpass);
1775		return NT_STATUS_ACCOUNT_DISABLED;
1776	}
1777
1778	ZERO_STRUCTP(id12);
1779	init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1780
1781	pdb_free_sam(&smbpass);
1782
1783	return NT_STATUS_OK;
1784}
1785
1786/*************************************************************************
1787 get_user_info_20
1788 *************************************************************************/
1789
1790static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1791{
1792	SAM_ACCOUNT *sampass=NULL;
1793	BOOL ret;
1794
1795	pdb_init_sam_talloc(mem_ctx, &sampass);
1796
1797	become_root();
1798	ret = pdb_getsampwsid(sampass, user_sid);
1799	unbecome_root();
1800
1801	if (ret == False) {
1802		DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1803		return NT_STATUS_NO_SUCH_USER;
1804	}
1805
1806	samr_clear_sam_passwd(sampass);
1807
1808	DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1809
1810	ZERO_STRUCTP(id20);
1811	init_sam_user_info20A(id20, sampass);
1812
1813	pdb_free_sam(&sampass);
1814
1815	return NT_STATUS_OK;
1816}
1817
1818/*************************************************************************
1819 get_user_info_21
1820 *************************************************************************/
1821
1822static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1823				 DOM_SID *user_sid, DOM_SID *domain_sid)
1824{
1825	SAM_ACCOUNT *sampass=NULL;
1826	BOOL ret;
1827	NTSTATUS nt_status;
1828
1829	nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1830	if (!NT_STATUS_IS_OK(nt_status)) {
1831		return nt_status;
1832	}
1833
1834	become_root();
1835	ret = pdb_getsampwsid(sampass, user_sid);
1836	unbecome_root();
1837
1838	if (ret == False) {
1839		DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1840		return NT_STATUS_NO_SUCH_USER;
1841	}
1842
1843	samr_clear_sam_passwd(sampass);
1844
1845	DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1846
1847	ZERO_STRUCTP(id21);
1848	nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1849
1850	pdb_free_sam(&sampass);
1851
1852	return NT_STATUS_OK;
1853}
1854
1855/*******************************************************************
1856 _samr_query_userinfo
1857 ********************************************************************/
1858
1859NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1860{
1861	SAM_USERINFO_CTR *ctr;
1862	struct samr_info *info = NULL;
1863	DOM_SID domain_sid;
1864	uint32 rid;
1865
1866	r_u->status=NT_STATUS_OK;
1867
1868	/* search for the handle */
1869	if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1870		return NT_STATUS_INVALID_HANDLE;
1871
1872	domain_sid = info->sid;
1873
1874	sid_split_rid(&domain_sid, &rid);
1875
1876	if (!sid_check_is_in_our_domain(&info->sid))
1877		return NT_STATUS_OBJECT_TYPE_MISMATCH;
1878
1879	DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1880
1881	ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
1882	if (!ctr)
1883		return NT_STATUS_NO_MEMORY;
1884
1885	ZERO_STRUCTP(ctr);
1886
1887	/* ok!  user info levels (lots: see MSDEV help), off we go... */
1888	ctr->switch_value = q_u->switch_value;
1889
1890	switch (q_u->switch_value) {
1891	case 0x07:
1892		ctr->info.id7 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_7);
1893		if (ctr->info.id7 == NULL)
1894			return NT_STATUS_NO_MEMORY;
1895
1896		if (!NT_STATUS_IS_OK(r_u->status = get_user_info_7(p->mem_ctx, ctr->info.id7, &info->sid)))
1897			return r_u->status;
1898		break;
1899	case 0x10:
1900		ctr->info.id10 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_10);
1901		if (ctr->info.id10 == NULL)
1902			return NT_STATUS_NO_MEMORY;
1903
1904		if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1905			return r_u->status;
1906		break;
1907
1908#if 0
1909/* whoops - got this wrong.  i think.  or don't understand what's happening. */
1910        case 0x11:
1911        {
1912            NTTIME expire;
1913            info = (void *)&id11;
1914
1915            expire.low = 0xffffffff;
1916            expire.high = 0x7fffffff;
1917
1918            ctr->info.id = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_11));
1919	    ZERO_STRUCTP(ctr->info.id11);
1920            init_sam_user_info11(ctr->info.id11, &expire,
1921                         "BROOKFIELDS$",    /* name */
1922                         0x03ef,    /* user rid */
1923                         0x201, /* group rid */
1924                         0x0080);   /* acb info */
1925
1926            break;
1927        }
1928#endif
1929
1930	case 0x12:
1931		ctr->info.id12 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_12);
1932		if (ctr->info.id12 == NULL)
1933			return NT_STATUS_NO_MEMORY;
1934
1935		if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1936			return r_u->status;
1937		break;
1938
1939	case 20:
1940		ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
1941		if (ctr->info.id20 == NULL)
1942			return NT_STATUS_NO_MEMORY;
1943		if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1944			return r_u->status;
1945		break;
1946
1947	case 21:
1948		ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
1949		if (ctr->info.id21 == NULL)
1950			return NT_STATUS_NO_MEMORY;
1951		if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1952								    &info->sid, &domain_sid)))
1953			return r_u->status;
1954		break;
1955
1956	default:
1957		return NT_STATUS_INVALID_INFO_CLASS;
1958	}
1959
1960	init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1961
1962	DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1963
1964	return r_u->status;
1965}
1966
1967/*******************************************************************
1968 samr_reply_query_usergroups
1969 ********************************************************************/
1970
1971NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1972{
1973	SAM_ACCOUNT *sam_pass=NULL;
1974	struct passwd *passwd;
1975	DOM_SID  sid;
1976	DOM_SID *sids;
1977	DOM_GID *gids = NULL;
1978	int num_groups = 0;
1979	gid_t *unix_gids;
1980	int i, num_gids, num_sids;
1981	uint32 acc_granted;
1982	BOOL ret;
1983	NTSTATUS result;
1984
1985	/*
1986	 * from the SID in the request:
1987	 * we should send back the list of DOMAIN GROUPS
1988	 * the user is a member of
1989	 *
1990	 * and only the DOMAIN GROUPS
1991	 * no ALIASES !!! neither aliases of the domain
1992	 * nor aliases of the builtin SID
1993	 *
1994	 * JFM, 12/2/2001
1995	 */
1996
1997	r_u->status = NT_STATUS_OK;
1998
1999	DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2000
2001	/* find the policy handle.  open a policy on it. */
2002	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2003		return NT_STATUS_INVALID_HANDLE;
2004
2005	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2006		return r_u->status;
2007	}
2008
2009	if (!sid_check_is_in_our_domain(&sid))
2010		return NT_STATUS_OBJECT_TYPE_MISMATCH;
2011
2012	pdb_init_sam(&sam_pass);
2013
2014	become_root();
2015	ret = pdb_getsampwsid(sam_pass, &sid);
2016	unbecome_root();
2017
2018	if (ret == False) {
2019		pdb_free_sam(&sam_pass);
2020		return NT_STATUS_NO_SUCH_USER;
2021	}
2022
2023	passwd = getpwnam_alloc(pdb_get_username(sam_pass));
2024	if (passwd == NULL) {
2025		pdb_free_sam(&sam_pass);
2026		return NT_STATUS_NO_SUCH_USER;
2027	}
2028
2029	sids = NULL;
2030	num_sids = 0;
2031
2032	become_root();
2033	result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
2034					    passwd->pw_gid,
2035					    &sids, &unix_gids, &num_groups);
2036	unbecome_root();
2037
2038	pdb_free_sam(&sam_pass);
2039	passwd_free(&passwd);
2040
2041	if (!NT_STATUS_IS_OK(result))
2042		return result;
2043
2044	SAFE_FREE(unix_gids);
2045
2046	gids = NULL;
2047	num_gids = 0;
2048
2049	for (i=0; i<num_groups; i++) {
2050		uint32 rid;
2051
2052		if (!sid_peek_check_rid(get_global_sam_sid(),
2053					&(sids[i]), &rid))
2054			continue;
2055
2056		gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1);
2057		gids[num_gids].attr=7;
2058		gids[num_gids].g_rid = rid;
2059		num_gids += 1;
2060	}
2061	SAFE_FREE(sids);
2062
2063	/* construct the response.  lkclXXXX: gids are not copied! */
2064	init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2065
2066	DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2067
2068	return r_u->status;
2069}
2070
2071/*******************************************************************
2072 _samr_query_dom_info
2073 ********************************************************************/
2074
2075NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2076{
2077	struct samr_info *info = NULL;
2078	SAM_UNK_CTR *ctr;
2079	uint32 min_pass_len,pass_hist,flag;
2080	time_t u_expire, u_min_age;
2081	NTTIME nt_expire, nt_min_age;
2082
2083	time_t u_lock_duration, u_reset_time;
2084	NTTIME nt_lock_duration, nt_reset_time;
2085	uint32 lockout;
2086
2087	time_t u_logout;
2088	NTTIME nt_logout;
2089
2090	uint32 account_policy_temp;
2091	uint32 server_role;
2092
2093	uint32 num_users=0, num_groups=0, num_aliases=0;
2094
2095	if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2096		return NT_STATUS_NO_MEMORY;
2097
2098	ZERO_STRUCTP(ctr);
2099
2100	r_u->status = NT_STATUS_OK;
2101
2102	DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2103
2104	/* find the policy handle.  open a policy on it. */
2105	if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2106		return NT_STATUS_INVALID_HANDLE;
2107
2108	switch (q_u->switch_value) {
2109		case 0x01:
2110
2111			account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2112			min_pass_len = account_policy_temp;
2113
2114			account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2115			pass_hist = account_policy_temp;
2116
2117			account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2118			flag = account_policy_temp;
2119
2120			account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2121			u_expire = account_policy_temp;
2122
2123			account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2124			u_min_age = account_policy_temp;
2125
2126			unix_to_nt_time_abs(&nt_expire, u_expire);
2127			unix_to_nt_time_abs(&nt_min_age, u_min_age);
2128
2129			init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2130			               flag, nt_expire, nt_min_age);
2131			break;
2132		case 0x02:
2133			become_root();
2134			r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2135			unbecome_root();
2136			if (!NT_STATUS_IS_OK(r_u->status)) {
2137				DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2138				return r_u->status;
2139			}
2140			num_users=info->disp_info.num_user_account;
2141			free_samr_db(info);
2142
2143			r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2144			if (!NT_STATUS_IS_OK(r_u->status)) {
2145				DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2146				return r_u->status;
2147			}
2148			num_groups=info->disp_info.num_group_account;
2149			free_samr_db(info);
2150
2151			account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
2152			u_logout = account_policy_temp;
2153
2154			unix_to_nt_time_abs(&nt_logout, u_logout);
2155
2156			server_role = ROLE_DOMAIN_PDC;
2157			if (lp_server_role() == ROLE_DOMAIN_BDC)
2158				server_role = ROLE_DOMAIN_BDC;
2159
2160			/* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2161			init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL),
2162				       num_users, num_groups, num_aliases, nt_logout, server_role);
2163			break;
2164		case 0x03:
2165			account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2166			unix_to_nt_time_abs(&nt_logout, u_logout);
2167
2168			init_unk_info3(&ctr->info.inf3, nt_logout);
2169			break;
2170		case 0x05:
2171			init_unk_info5(&ctr->info.inf5, global_myname());
2172			break;
2173		case 0x06:
2174			init_unk_info6(&ctr->info.inf6);
2175			break;
2176		case 0x07:
2177			server_role = ROLE_DOMAIN_PDC;
2178			if (lp_server_role() == ROLE_DOMAIN_BDC)
2179				server_role = ROLE_DOMAIN_BDC;
2180
2181			init_unk_info7(&ctr->info.inf7, server_role);
2182			break;
2183		case 0x08:
2184			init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
2185			break;
2186		case 0x0c:
2187			account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2188			u_lock_duration = account_policy_temp;
2189			if (u_lock_duration != -1)
2190				u_lock_duration *= 60;
2191
2192			account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2193			u_reset_time = account_policy_temp * 60;
2194
2195			account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2196			lockout = account_policy_temp;
2197
2198			unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2199			unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2200
2201            		init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2202            		break;
2203        	default:
2204            		return NT_STATUS_INVALID_INFO_CLASS;
2205		}
2206
2207	init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2208
2209	DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2210
2211	return r_u->status;
2212}
2213
2214/*******************************************************************
2215 _samr_create_user
2216 Create an account, can be either a normal user or a machine.
2217 This funcion will need to be updated for bdc/domain trusts.
2218 ********************************************************************/
2219
2220NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2221{
2222	SAM_ACCOUNT *sam_pass=NULL;
2223	fstring account;
2224	DOM_SID sid;
2225	pstring add_script;
2226	POLICY_HND dom_pol = q_u->domain_pol;
2227	UNISTR2 user_account = q_u->uni_name;
2228	uint16 acb_info = q_u->acb_info;
2229	POLICY_HND *user_pol = &r_u->user_pol;
2230	struct samr_info *info = NULL;
2231	BOOL ret;
2232	NTSTATUS nt_status;
2233	struct passwd *pw;
2234	uint32 acc_granted;
2235	SEC_DESC *psd;
2236	size_t    sd_size;
2237	uint32 new_rid = 0;
2238	/* check this, when giving away 'add computer to domain' privs */
2239	uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2240	BOOL can_add_account = False;
2241	SE_PRIV se_rights;
2242
2243	/* Get the domain SID stored in the domain policy */
2244	if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2245		return NT_STATUS_INVALID_HANDLE;
2246
2247	if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2248		return nt_status;
2249	}
2250
2251	if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2252		/* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2253		   this parameter is not an account type */
2254		return NT_STATUS_INVALID_PARAMETER;
2255	}
2256
2257	rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2258	strlower_m(account);
2259
2260	pdb_init_sam(&sam_pass);
2261
2262	become_root();
2263	ret = pdb_getsampwnam(sam_pass, account);
2264	unbecome_root();
2265	if (ret == True) {
2266		/* this account exists: say so */
2267		pdb_free_sam(&sam_pass);
2268		return NT_STATUS_USER_EXISTS;
2269	}
2270
2271	pdb_free_sam(&sam_pass);
2272
2273	/*********************************************************************
2274	 * HEADS UP!  If we have to create a new user account, we have to get
2275	 * a new RID from somewhere.  This used to be done by the passdb
2276	 * backend. It has been moved into idmap now.  Since idmap is now
2277	 * wrapped up behind winbind, this means you have to run winbindd if you
2278	 * want new accounts to get a new RID when "enable rid algorithm = no".
2279	 * Tough.  We now have a uniform way of allocating RIDs regardless
2280	 * of what ever passdb backend people may use.
2281	 *                                             --jerry (2003-07-10)
2282	 *********************************************************************/
2283
2284	pw = Get_Pwnam(account);
2285
2286	/* determine which user right we need to check based on the acb_info */
2287
2288	if ( acb_info & ACB_WSTRUST )
2289	{
2290		pstrcpy(add_script, lp_addmachine_script());
2291		se_priv_copy( &se_rights, &se_machine_account );
2292		can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2293	}
2294	else if ( acb_info & ACB_NORMAL )
2295	{
2296		pstrcpy(add_script, lp_adduser_script());
2297		se_priv_copy( &se_rights, &se_add_users );
2298		can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2299	}
2300	else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) )
2301	{
2302		pstrcpy(add_script, lp_addmachine_script());
2303		if ( lp_enable_privileges() ) {
2304			/* only Domain Admins can add a BDC or domain trust */
2305			se_priv_copy( &se_rights, &se_priv_none );
2306			can_add_account = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
2307		}
2308	}
2309
2310	DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2311		p->pipe_user_name, can_add_account ? "True":"False" ));
2312
2313	/********** BEGIN Admin BLOCK **********/
2314
2315	if ( can_add_account )
2316		become_root();
2317
2318	if ( !pw ) {
2319		if (*add_script) {
2320  			int add_ret;
2321
2322  			all_string_sub(add_script, "%u", account, sizeof(add_script));
2323  			add_ret = smbrun(add_script,NULL);
2324 			DEBUG(add_ret ? 0 : 3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2325  		}
2326		else	/* no add user script -- ask winbindd to do it */
2327		{
2328			if ( !winbind_create_user( account, &new_rid ) ) {
2329				DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2330					account));
2331			}
2332		}
2333
2334	}
2335
2336	/* implicit call to getpwnam() next.  we have a valid SID coming out of this call */
2337
2338	flush_pwnam_cache();
2339	nt_status = pdb_init_sam_new(&sam_pass, account, new_rid);
2340
2341	/* this code is order such that we have no unnecessary retuns
2342	   out of the admin block of code */
2343
2344	if ( NT_STATUS_IS_OK(nt_status) ) {
2345	 	pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2346
2347		if ( !(ret = pdb_add_sam_account(sam_pass)) ) {
2348	 		pdb_free_sam(&sam_pass);
2349 			DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n",
2350				account));
2351			nt_status = NT_STATUS_ACCESS_DENIED;
2352		}
2353	}
2354
2355	if ( can_add_account )
2356		unbecome_root();
2357
2358	/********** END Admin BLOCK **********/
2359
2360	/* now check for failure */
2361
2362	if ( !NT_STATUS_IS_OK(nt_status) )
2363		return nt_status;
2364
2365	/* Get the user's SID */
2366
2367	sid_copy(&sid, pdb_get_user_sid(sam_pass));
2368
2369	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2370	se_map_generic(&des_access, &usr_generic_mapping);
2371
2372	nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2373		&se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2374		&acc_granted, "_samr_create_user");
2375
2376	if ( !NT_STATUS_IS_OK(nt_status) ) {
2377		return nt_status;
2378	}
2379
2380	/* associate the user's SID with the new handle. */
2381	if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2382		pdb_free_sam(&sam_pass);
2383		return NT_STATUS_NO_MEMORY;
2384	}
2385
2386	ZERO_STRUCTP(info);
2387	info->sid = sid;
2388	info->acc_granted = acc_granted;
2389
2390	/* get a (unique) handle.  open a policy on it. */
2391	if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2392		pdb_free_sam(&sam_pass);
2393		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2394	}
2395
2396	r_u->user_rid=pdb_get_user_rid(sam_pass);
2397
2398	r_u->access_granted = acc_granted;
2399
2400	pdb_free_sam(&sam_pass);
2401
2402	return NT_STATUS_OK;
2403}
2404
2405/*******************************************************************
2406 samr_reply_connect_anon
2407 ********************************************************************/
2408
2409NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2410{
2411	struct samr_info *info = NULL;
2412	uint32    des_access = q_u->access_mask;
2413
2414	/* Access check */
2415
2416	if (!pipe_access_check(p)) {
2417		DEBUG(3, ("access denied to samr_connect_anon\n"));
2418		r_u->status = NT_STATUS_ACCESS_DENIED;
2419		return r_u->status;
2420	}
2421
2422	/* set up the SAMR connect_anon response */
2423
2424	r_u->status = NT_STATUS_OK;
2425
2426	/* associate the user's SID with the new handle. */
2427	if ((info = get_samr_info_by_sid(NULL)) == NULL)
2428		return NT_STATUS_NO_MEMORY;
2429
2430	/* don't give away the farm but this is probably ok.  The SA_RIGHT_SAM_ENUM_DOMAINS
2431	   was observed from a win98 client trying to enumerate users (when configured
2432	   user level access control on shares)   --jerry */
2433
2434	se_map_generic( &des_access, &sam_generic_mapping );
2435	info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2436
2437	info->status = q_u->unknown_0;
2438
2439	/* get a (unique) handle.  open a policy on it. */
2440	if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2441		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2442
2443	return r_u->status;
2444}
2445
2446/*******************************************************************
2447 samr_reply_connect
2448 ********************************************************************/
2449
2450NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2451{
2452	struct samr_info *info = NULL;
2453	SEC_DESC *psd = NULL;
2454	uint32    acc_granted;
2455	uint32    des_access = q_u->access_mask;
2456	NTSTATUS  nt_status;
2457	size_t sd_size;
2458
2459
2460	DEBUG(5,("_samr_connect: %d\n", __LINE__));
2461
2462	/* Access check */
2463
2464	if (!pipe_access_check(p)) {
2465		DEBUG(3, ("access denied to samr_connect\n"));
2466		r_u->status = NT_STATUS_ACCESS_DENIED;
2467		return r_u->status;
2468	}
2469
2470	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2471	se_map_generic(&des_access, &sam_generic_mapping);
2472
2473	nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2474		NULL, 0, des_access, &acc_granted, "_samr_connect");
2475
2476	if ( !NT_STATUS_IS_OK(nt_status) )
2477		return nt_status;
2478
2479	r_u->status = NT_STATUS_OK;
2480
2481	/* associate the user's SID and access granted with the new handle. */
2482	if ((info = get_samr_info_by_sid(NULL)) == NULL)
2483		return NT_STATUS_NO_MEMORY;
2484
2485	info->acc_granted = acc_granted;
2486	info->status = q_u->access_mask;
2487
2488	/* get a (unique) handle.  open a policy on it. */
2489	if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2490		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2491
2492	DEBUG(5,("_samr_connect: %d\n", __LINE__));
2493
2494	return r_u->status;
2495}
2496
2497/*******************************************************************
2498 samr_connect4
2499 ********************************************************************/
2500
2501NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2502{
2503	struct samr_info *info = NULL;
2504	SEC_DESC *psd = NULL;
2505	uint32    acc_granted;
2506	uint32    des_access = q_u->access_mask;
2507	NTSTATUS  nt_status;
2508	size_t sd_size;
2509
2510
2511	DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2512
2513	/* Access check */
2514
2515	if (!pipe_access_check(p)) {
2516		DEBUG(3, ("access denied to samr_connect4\n"));
2517		r_u->status = NT_STATUS_ACCESS_DENIED;
2518		return r_u->status;
2519	}
2520
2521	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2522	se_map_generic(&des_access, &sam_generic_mapping);
2523
2524	nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2525		NULL, 0, des_access, &acc_granted, "_samr_connect4");
2526
2527	if ( !NT_STATUS_IS_OK(nt_status) )
2528		return nt_status;
2529
2530	r_u->status = NT_STATUS_OK;
2531
2532	/* associate the user's SID and access granted with the new handle. */
2533	if ((info = get_samr_info_by_sid(NULL)) == NULL)
2534		return NT_STATUS_NO_MEMORY;
2535
2536	info->acc_granted = acc_granted;
2537	info->status = q_u->access_mask;
2538
2539	/* get a (unique) handle.  open a policy on it. */
2540	if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2541		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2542
2543	DEBUG(5,("_samr_connect: %d\n", __LINE__));
2544
2545	return r_u->status;
2546}
2547
2548/**********************************************************************
2549 api_samr_lookup_domain
2550 **********************************************************************/
2551
2552NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2553{
2554	struct samr_info *info;
2555	fstring domain_name;
2556	DOM_SID sid;
2557
2558	r_u->status = NT_STATUS_OK;
2559
2560	if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2561		return NT_STATUS_INVALID_HANDLE;
2562
2563	/* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
2564	   Reverted that change so we will work with RAS servers again */
2565
2566	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2567		SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain")))
2568	{
2569		return r_u->status;
2570	}
2571
2572	rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2573
2574	ZERO_STRUCT(sid);
2575
2576	if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2577		r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2578	}
2579
2580	DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2581
2582	init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2583
2584	return r_u->status;
2585}
2586
2587/******************************************************************
2588makes a SAMR_R_ENUM_DOMAINS structure.
2589********************************************************************/
2590
2591static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2592			UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2593{
2594	uint32 i;
2595	SAM_ENTRY *sam;
2596	UNISTR2 *uni_name;
2597
2598	DEBUG(5, ("make_enum_domains\n"));
2599
2600	*pp_sam = NULL;
2601	*pp_uni_name = NULL;
2602
2603	if (num_sam_entries == 0)
2604		return True;
2605
2606	sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2607	uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2608
2609	if (sam == NULL || uni_name == NULL)
2610		return False;
2611
2612	for (i = 0; i < num_sam_entries; i++) {
2613		init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2614		init_sam_entry(&sam[i], &uni_name[i], 0);
2615	}
2616
2617	*pp_sam = sam;
2618	*pp_uni_name = uni_name;
2619
2620	return True;
2621}
2622
2623/**********************************************************************
2624 api_samr_enum_domains
2625 **********************************************************************/
2626
2627NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2628{
2629	struct samr_info *info;
2630	uint32 num_entries = 2;
2631	fstring dom[2];
2632	const char *name;
2633
2634	r_u->status = NT_STATUS_OK;
2635
2636	if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2637		return NT_STATUS_INVALID_HANDLE;
2638
2639	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2640		return r_u->status;
2641	}
2642
2643	name = get_global_sam_name();
2644
2645	fstrcpy(dom[0],name);
2646	strupper_m(dom[0]);
2647	fstrcpy(dom[1],"Builtin");
2648
2649	if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2650		return NT_STATUS_NO_MEMORY;
2651
2652	init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2653
2654	return r_u->status;
2655}
2656
2657/*******************************************************************
2658 api_samr_open_alias
2659 ********************************************************************/
2660
2661NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2662{
2663	DOM_SID sid;
2664	POLICY_HND domain_pol = q_u->dom_pol;
2665	uint32 alias_rid = q_u->rid_alias;
2666	POLICY_HND *alias_pol = &r_u->pol;
2667	struct    samr_info *info = NULL;
2668	SEC_DESC *psd = NULL;
2669	uint32    acc_granted;
2670	uint32    des_access = q_u->access_mask;
2671	size_t    sd_size;
2672	NTSTATUS  status;
2673	SE_PRIV se_rights;
2674
2675	r_u->status = NT_STATUS_OK;
2676
2677	/* find the domain policy and get the SID / access bits stored in the domain policy */
2678
2679	if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
2680		return NT_STATUS_INVALID_HANDLE;
2681
2682	status = access_check_samr_function(acc_granted,
2683		SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias");
2684
2685	if ( !NT_STATUS_IS_OK(status) )
2686		return status;
2687
2688	/* append the alias' RID to it */
2689
2690	if (!sid_append_rid(&sid, alias_rid))
2691		return NT_STATUS_NO_SUCH_USER;
2692
2693	/*check if access can be granted as requested by client. */
2694
2695	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
2696	se_map_generic(&des_access,&ali_generic_mapping);
2697
2698	se_priv_add( &se_rights, &se_add_users );
2699
2700
2701	status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2702		&se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
2703		&acc_granted, "_samr_open_alias");
2704
2705	if ( !NT_STATUS_IS_OK(status) )
2706		return status;
2707
2708	/*
2709	 * we should check if the rid really exist !!!
2710	 * JFM.
2711	 */
2712
2713	/* associate the user's SID with the new handle. */
2714	if ((info = get_samr_info_by_sid(&sid)) == NULL)
2715		return NT_STATUS_NO_MEMORY;
2716
2717	info->acc_granted = acc_granted;
2718
2719	/* get a (unique) handle.  open a policy on it. */
2720	if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2721		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2722
2723	return r_u->status;
2724}
2725
2726/*******************************************************************
2727 set_user_info_10
2728 ********************************************************************/
2729
2730static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, SAM_ACCOUNT *pwd)
2731{
2732	if (id10 == NULL) {
2733		DEBUG(5, ("set_user_info_10: NULL id10\n"));
2734		pdb_free_sam(&pwd);
2735		return False;
2736	}
2737
2738	/* FIX ME: check if the value is really changed --metze */
2739	if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2740		pdb_free_sam(&pwd);
2741		return False;
2742	}
2743
2744	if(!pdb_update_sam_account(pwd)) {
2745		pdb_free_sam(&pwd);
2746		return False;
2747	}
2748
2749	pdb_free_sam(&pwd);
2750
2751	return True;
2752}
2753
2754/*******************************************************************
2755 set_user_info_12
2756 ********************************************************************/
2757
2758static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, SAM_ACCOUNT *pwd)
2759{
2760
2761	if (id12 == NULL) {
2762		DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2763		pdb_free_sam(&pwd);
2764		return False;
2765	}
2766
2767	if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2768		pdb_free_sam(&pwd);
2769		return False;
2770	}
2771	if (!pdb_set_nt_passwd     (pwd, id12->nt_pwd, PDB_CHANGED)) {
2772		pdb_free_sam(&pwd);
2773		return False;
2774	}
2775 	if (!pdb_set_pass_changed_now (pwd)) {
2776		pdb_free_sam(&pwd);
2777		return False;
2778	}
2779
2780	if(!pdb_update_sam_account(pwd)) {
2781		pdb_free_sam(&pwd);
2782		return False;
2783 	}
2784
2785	pdb_free_sam(&pwd);
2786	return True;
2787}
2788
2789/*******************************************************************
2790 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2791 ********************************************************************/
2792static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2793{
2794	struct group *grp;
2795	gid_t gid;
2796
2797	if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2798					&gid))) {
2799		DEBUG(2,("Could not get gid for primary group of "
2800			 "user %s\n", pdb_get_username(sampass)));
2801		return False;
2802	}
2803
2804	grp = getgrgid(gid);
2805
2806	if (grp == NULL) {
2807		DEBUG(2,("Could not find primary group %lu for "
2808			 "user %s\n", (unsigned long)gid,
2809			 pdb_get_username(sampass)));
2810		return False;
2811	}
2812
2813	if (smb_set_primary_group(grp->gr_name,
2814				  pdb_get_username(sampass)) != 0) {
2815		DEBUG(2,("Could not set primary group for user %s to "
2816			 "%s\n",
2817			 pdb_get_username(sampass), grp->gr_name));
2818		return False;
2819	}
2820
2821	return True;
2822}
2823
2824
2825/*******************************************************************
2826 set_user_info_20
2827 ********************************************************************/
2828
2829static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, SAM_ACCOUNT *pwd)
2830{
2831	if (id20 == NULL) {
2832		DEBUG(5, ("set_user_info_20: NULL id20\n"));
2833		return False;
2834	}
2835
2836	copy_id20_to_sam_passwd(pwd, id20);
2837
2838	/* write the change out */
2839	if(!pdb_update_sam_account(pwd)) {
2840		pdb_free_sam(&pwd);
2841		return False;
2842 	}
2843
2844	pdb_free_sam(&pwd);
2845
2846	return True;
2847}
2848/*******************************************************************
2849 set_user_info_21
2850 ********************************************************************/
2851
2852static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, SAM_ACCOUNT *pwd)
2853{
2854
2855	if (id21 == NULL) {
2856		DEBUG(5, ("set_user_info_21: NULL id21\n"));
2857		return False;
2858	}
2859
2860	copy_id21_to_sam_passwd(pwd, id21);
2861
2862	/*
2863	 * The funny part about the previous two calls is
2864	 * that pwd still has the password hashes from the
2865	 * passdb entry.  These have not been updated from
2866	 * id21.  I don't know if they need to be set.    --jerry
2867	 */
2868
2869	if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2870		set_unix_primary_group(pwd);
2871
2872	/* write the change out */
2873	if(!pdb_update_sam_account(pwd)) {
2874		pdb_free_sam(&pwd);
2875		return False;
2876 	}
2877
2878	pdb_free_sam(&pwd);
2879
2880	return True;
2881}
2882
2883/*******************************************************************
2884 set_user_info_23
2885 ********************************************************************/
2886
2887static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
2888{
2889	pstring plaintext_buf;
2890	uint32 len;
2891	uint16 acct_ctrl;
2892
2893	if (id23 == NULL) {
2894		DEBUG(5, ("set_user_info_23: NULL id23\n"));
2895		return False;
2896	}
2897
2898	DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2899		  pdb_get_username(pwd)));
2900
2901	acct_ctrl = pdb_get_acct_ctrl(pwd);
2902
2903	if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2904		pdb_free_sam(&pwd);
2905		return False;
2906 	}
2907
2908	if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2909		pdb_free_sam(&pwd);
2910		return False;
2911	}
2912
2913	copy_id23_to_sam_passwd(pwd, id23);
2914
2915	/* if it's a trust account, don't update /etc/passwd */
2916	if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2917		( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2918		( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2919		DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2920	} else  {
2921		/* update the UNIX password */
2922		if (lp_unix_password_sync() ) {
2923			struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2924			if (!passwd) {
2925				DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2926			}
2927
2928			if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2929				pdb_free_sam(&pwd);
2930				return False;
2931			}
2932		}
2933	}
2934
2935	ZERO_STRUCT(plaintext_buf);
2936
2937	if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2938		set_unix_primary_group(pwd);
2939
2940	if(!pdb_update_sam_account(pwd)) {
2941		pdb_free_sam(&pwd);
2942		return False;
2943	}
2944
2945	pdb_free_sam(&pwd);
2946
2947	return True;
2948}
2949
2950/*******************************************************************
2951 set_user_info_pw
2952 ********************************************************************/
2953
2954static BOOL set_user_info_pw(char *pass, SAM_ACCOUNT *pwd)
2955{
2956	uint32 len;
2957	pstring plaintext_buf;
2958	uint16 acct_ctrl;
2959
2960	DEBUG(5, ("Attempting administrator password change for user %s\n",
2961		  pdb_get_username(pwd)));
2962
2963	acct_ctrl = pdb_get_acct_ctrl(pwd);
2964
2965	ZERO_STRUCT(plaintext_buf);
2966
2967	if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2968		pdb_free_sam(&pwd);
2969		return False;
2970 	}
2971
2972	if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2973		pdb_free_sam(&pwd);
2974		return False;
2975	}
2976
2977	/* if it's a trust account, don't update /etc/passwd */
2978	if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2979		( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2980		( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2981		DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2982	} else {
2983		/* update the UNIX password */
2984		if (lp_unix_password_sync()) {
2985			struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2986			if (!passwd) {
2987				DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2988			}
2989
2990			if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2991				pdb_free_sam(&pwd);
2992				return False;
2993			}
2994		}
2995	}
2996
2997	ZERO_STRUCT(plaintext_buf);
2998
2999	DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3000
3001	/* update the SAMBA password */
3002	if(!pdb_update_sam_account(pwd)) {
3003		pdb_free_sam(&pwd);
3004		return False;
3005 	}
3006
3007	pdb_free_sam(&pwd);
3008
3009	return True;
3010}
3011
3012/*******************************************************************
3013 samr_reply_set_userinfo
3014 ********************************************************************/
3015
3016NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3017{
3018	SAM_ACCOUNT *pwd = NULL;
3019	DOM_SID sid;
3020	POLICY_HND *pol = &q_u->pol;
3021	uint16 switch_value = q_u->switch_value;
3022	SAM_USERINFO_CTR *ctr = q_u->ctr;
3023	uint32 acc_granted;
3024	uint32 acc_required;
3025	BOOL ret;
3026	BOOL has_enough_rights = False;
3027	uint32 acb_info;
3028
3029	DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3030
3031	r_u->status = NT_STATUS_OK;
3032
3033	/* find the policy handle.  open a policy on it. */
3034	if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3035		return NT_STATUS_INVALID_HANDLE;
3036
3037	/* observed when joining an XP client to a Samba domain */
3038
3039	acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3040
3041	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3042		return r_u->status;
3043	}
3044
3045	DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3046
3047	if (ctr == NULL) {
3048		DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3049		return NT_STATUS_INVALID_INFO_CLASS;
3050	}
3051
3052 	pdb_init_sam(&pwd);
3053
3054	become_root();
3055	ret = pdb_getsampwsid(pwd, &sid);
3056	unbecome_root();
3057
3058	if ( !ret ) {
3059		pdb_free_sam(&pwd);
3060		return NT_STATUS_NO_SUCH_USER;
3061 	}
3062
3063	/* deal with machine password changes differently from userinfo changes */
3064	/* check to see if we have the sufficient rights */
3065
3066	acb_info = pdb_get_acct_ctrl(pwd);
3067	if ( acb_info & ACB_WSTRUST )
3068		has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3069	else if ( acb_info & ACB_NORMAL )
3070		has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3071	else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3072		if ( lp_enable_privileges() )
3073			has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3074	}
3075
3076	DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3077		p->pipe_user_name, has_enough_rights ? "" : " not"));
3078
3079	/* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3080
3081	if ( has_enough_rights )
3082		become_root();
3083
3084	/* ok!  user info levels (lots: see MSDEV help), off we go... */
3085
3086	switch (switch_value) {
3087		case 18:
3088			if (!set_user_info_12(ctr->info.id12, pwd))
3089				r_u->status = NT_STATUS_ACCESS_DENIED;
3090			break;
3091
3092		case 24:
3093			if (!p->session_key.length) {
3094				r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3095			}
3096			SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3097
3098			dump_data(100, (char *)ctr->info.id24->pass, 516);
3099
3100			if (!set_user_info_pw((char *)ctr->info.id24->pass, pwd))
3101				r_u->status = NT_STATUS_ACCESS_DENIED;
3102			break;
3103
3104		case 25:
3105#if 0
3106			/*
3107			 * Currently we don't really know how to unmarshall
3108			 * the level 25 struct, and the password encryption
3109			 * is different. This is a placeholder for when we
3110			 * do understand it. In the meantime just return INVALID
3111			 * info level and W2K SP2 drops down to level 23... JRA.
3112			 */
3113
3114			if (!p->session_key.length) {
3115				r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3116			}
3117			SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3118
3119			dump_data(100, (char *)ctr->info.id25->pass, 532);
3120
3121			if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3122				r_u->status = NT_STATUS_ACCESS_DENIED;
3123			break;
3124#endif
3125			r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3126			break;
3127
3128		case 23:
3129			if (!p->session_key.length) {
3130				r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3131			}
3132			SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3133
3134			dump_data(100, (char *)ctr->info.id23->pass, 516);
3135
3136			if (!set_user_info_23(ctr->info.id23, pwd))
3137				r_u->status = NT_STATUS_ACCESS_DENIED;
3138			break;
3139
3140		default:
3141			r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3142	}
3143
3144
3145	if ( has_enough_rights )
3146		unbecome_root();
3147
3148	/* ================ END SeMachineAccountPrivilege BLOCK ================ */
3149
3150	return r_u->status;
3151}
3152
3153/*******************************************************************
3154 samr_reply_set_userinfo2
3155 ********************************************************************/
3156
3157NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3158{
3159	SAM_ACCOUNT *pwd = NULL;
3160	DOM_SID sid;
3161	SAM_USERINFO_CTR *ctr = q_u->ctr;
3162	POLICY_HND *pol = &q_u->pol;
3163	uint16 switch_value = q_u->switch_value;
3164	uint32 acc_granted;
3165	uint32 acc_required;
3166	BOOL ret;
3167	BOOL has_enough_rights = False;
3168	uint32 acb_info;
3169
3170	DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3171
3172	r_u->status = NT_STATUS_OK;
3173
3174	/* find the policy handle.  open a policy on it. */
3175	if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3176		return NT_STATUS_INVALID_HANDLE;
3177
3178	/* observed when joining XP client to Samba domain */
3179
3180	acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3181
3182	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3183		return r_u->status;
3184	}
3185
3186	DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3187
3188	if (ctr == NULL) {
3189		DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3190		return NT_STATUS_INVALID_INFO_CLASS;
3191	}
3192
3193	switch_value=ctr->switch_value;
3194
3195 	pdb_init_sam(&pwd);
3196
3197	become_root();
3198	ret = pdb_getsampwsid(pwd, &sid);
3199	unbecome_root();
3200
3201	if ( !ret ) {
3202		pdb_free_sam(&pwd);
3203		return NT_STATUS_NO_SUCH_USER;
3204 	}
3205
3206	acb_info = pdb_get_acct_ctrl(pwd);
3207	if ( acb_info & ACB_WSTRUST )
3208		has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3209	else if ( acb_info & ACB_NORMAL )
3210		has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3211	else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3212		if ( lp_enable_privileges() )
3213			has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3214	}
3215
3216	DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3217		p->pipe_user_name, has_enough_rights ? "" : " not"));
3218
3219	/* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3220
3221	if ( has_enough_rights )
3222		become_root();
3223
3224	/* ok!  user info levels (lots: see MSDEV help), off we go... */
3225
3226	switch (switch_value) {
3227		case 16:
3228			if (!set_user_info_10(ctr->info.id10, pwd))
3229				r_u->status = NT_STATUS_ACCESS_DENIED;
3230			break;
3231		case 18:
3232			/* Used by AS/U JRA. */
3233			if (!set_user_info_12(ctr->info.id12, pwd))
3234				r_u->status = NT_STATUS_ACCESS_DENIED;
3235			break;
3236		case 20:
3237			if (!set_user_info_20(ctr->info.id20, pwd))
3238				r_u->status = NT_STATUS_ACCESS_DENIED;
3239			break;
3240		case 21:
3241			if (!set_user_info_21(ctr->info.id21, pwd))
3242				return NT_STATUS_ACCESS_DENIED;
3243			break;
3244		default:
3245			r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3246	}
3247
3248	if ( has_enough_rights )
3249		unbecome_root();
3250
3251	/* ================ END SeMachineAccountPrivilege BLOCK ================ */
3252
3253	return r_u->status;
3254}
3255
3256/*********************************************************************
3257 _samr_query_aliasmem
3258*********************************************************************/
3259
3260NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3261{
3262	int num_groups = 0;
3263	uint32 *rids=NULL;
3264	struct samr_info *info = NULL;
3265	int i;
3266
3267	NTSTATUS ntstatus1;
3268	NTSTATUS ntstatus2;
3269
3270	DOM_SID *members;
3271	DOM_SID *aliases;
3272	int num_aliases;
3273	BOOL res;
3274
3275	r_u->status = NT_STATUS_OK;
3276
3277	DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3278
3279	/* find the policy handle.  open a policy on it. */
3280	if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3281		return NT_STATUS_INVALID_HANDLE;
3282
3283	ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3284	ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3285
3286	if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3287		if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3288		    !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3289			return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3290		}
3291	}
3292
3293	if (!sid_check_is_domain(&info->sid) &&
3294	    !sid_check_is_builtin(&info->sid))
3295		return NT_STATUS_OBJECT_TYPE_MISMATCH;
3296
3297	members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3298
3299	if (members == NULL)
3300		return NT_STATUS_NO_MEMORY;
3301
3302	for (i=0; i<q_u->num_sids1; i++)
3303		sid_copy(&members[i], &q_u->sid[i].sid);
3304
3305	become_root();
3306	res = pdb_enum_alias_memberships(members,
3307					 q_u->num_sids1, &aliases,
3308					 &num_aliases);
3309	unbecome_root();
3310
3311	if (!res)
3312		return NT_STATUS_UNSUCCESSFUL;
3313
3314	rids = NULL;
3315	num_groups = 0;
3316
3317	for (i=0; i<num_aliases; i++) {
3318		uint32 rid;
3319
3320		if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
3321			continue;
3322
3323		rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
3324
3325		if (rids == NULL)
3326			return NT_STATUS_NO_MEMORY;
3327
3328		rids[num_groups] = rid;
3329		num_groups += 1;
3330	}
3331	SAFE_FREE(aliases);
3332
3333	init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3334	return NT_STATUS_OK;
3335}
3336
3337/*********************************************************************
3338 _samr_query_aliasmem
3339*********************************************************************/
3340
3341NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3342{
3343	int i;
3344
3345	int num_sids = 0;
3346	DOM_SID2 *sid;
3347	DOM_SID *sids=NULL;
3348
3349	DOM_SID alias_sid;
3350
3351	uint32 acc_granted;
3352
3353	/* find the policy handle.  open a policy on it. */
3354	if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3355		return NT_STATUS_INVALID_HANDLE;
3356
3357	if (!NT_STATUS_IS_OK(r_u->status =
3358		access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3359		return r_u->status;
3360	}
3361
3362	DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3363
3364	if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3365		return NT_STATUS_NO_SUCH_ALIAS;
3366
3367	sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);
3368	if (num_sids!=0 && sid == NULL) {
3369		SAFE_FREE(sids);
3370		return NT_STATUS_NO_MEMORY;
3371	}
3372
3373	for (i = 0; i < num_sids; i++) {
3374		init_dom_sid2(&sid[i], &sids[i]);
3375	}
3376
3377	init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3378
3379	SAFE_FREE(sids);
3380
3381	return NT_STATUS_OK;
3382}
3383
3384static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3385{
3386	int i;
3387
3388	for (i=0; i<*num; i++) {
3389		if ((*uids)[i] == uid)
3390			return;
3391	}
3392
3393	*uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3394
3395	if (*uids == NULL)
3396		return;
3397
3398	(*uids)[*num] = uid;
3399	*num += 1;
3400}
3401
3402
3403static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3404{
3405	struct group *grp;
3406	char **gr;
3407	struct sys_pwent *userlist, *user;
3408
3409	*uids = NULL;
3410	*num = 0;
3411
3412	/* We only look at our own sam, so don't care about imported stuff */
3413
3414	winbind_off();
3415
3416	if ((grp = getgrgid(gid)) == NULL) {
3417		winbind_on();
3418		return False;
3419	}
3420
3421	/* Primary group members */
3422
3423	userlist = getpwent_list();
3424
3425	for (user = userlist; user != NULL; user = user->next) {
3426		if (user->pw_gid != gid)
3427			continue;
3428		add_uid_to_array_unique(user->pw_uid, uids, num);
3429	}
3430
3431	pwent_free(userlist);
3432
3433	/* Secondary group members */
3434
3435	for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3436		struct passwd *pw = getpwnam(*gr);
3437
3438		if (pw == NULL)
3439			continue;
3440		add_uid_to_array_unique(pw->pw_uid, uids, num);
3441	}
3442
3443	winbind_on();
3444
3445	return True;
3446}
3447
3448/*********************************************************************
3449 _samr_query_groupmem
3450*********************************************************************/
3451
3452NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3453{
3454	DOM_SID group_sid;
3455	fstring group_sid_str;
3456	int i, num_members;
3457
3458	uint32 *rid=NULL;
3459	uint32 *attr=NULL;
3460
3461	uint32 acc_granted;
3462
3463	NTSTATUS result;
3464
3465	/* find the policy handle.  open a policy on it. */
3466	if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3467		return NT_STATUS_INVALID_HANDLE;
3468
3469	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3470		return r_u->status;
3471	}
3472
3473	sid_to_string(group_sid_str, &group_sid);
3474	DEBUG(10, ("sid is %s\n", group_sid_str));
3475
3476	if (!sid_check_is_in_our_domain(&group_sid)) {
3477		DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3478		return NT_STATUS_NO_SUCH_GROUP;
3479	}
3480
3481	DEBUG(10, ("lookup on Domain SID\n"));
3482
3483	become_root();
3484	result = pdb_enum_group_members(p->mem_ctx, &group_sid,
3485					&rid, &num_members);
3486	unbecome_root();
3487
3488	if (!NT_STATUS_IS_OK(result))
3489		return result;
3490
3491	attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
3492
3493	if ((num_members!=0) && (rid==NULL))
3494		return NT_STATUS_NO_MEMORY;
3495
3496	for (i=0; i<num_members; i++)
3497		attr[i] = SID_NAME_USER;
3498
3499	init_samr_r_query_groupmem(r_u, num_members, rid, attr, NT_STATUS_OK);
3500
3501	return NT_STATUS_OK;
3502}
3503
3504/*********************************************************************
3505 _samr_add_aliasmem
3506*********************************************************************/
3507
3508NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3509{
3510	DOM_SID alias_sid;
3511	uint32 acc_granted;
3512	SE_PRIV se_rights;
3513	BOOL can_add_accounts;
3514	BOOL ret;
3515
3516
3517	/* Find the policy handle. Open a policy on it. */
3518	if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3519		return NT_STATUS_INVALID_HANDLE;
3520
3521	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3522		return r_u->status;
3523	}
3524
3525	DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3526
3527	se_priv_copy( &se_rights, &se_add_users );
3528	can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3529
3530	/******** BEGIN SeAddUsers BLOCK *********/
3531
3532	if ( can_add_accounts )
3533		become_root();
3534
3535	ret = pdb_add_aliasmem(&alias_sid, &q_u->sid.sid);
3536
3537	if ( can_add_accounts )
3538		unbecome_root();
3539
3540	/******** END SeAddUsers BLOCK *********/
3541
3542	return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3543}
3544
3545/*********************************************************************
3546 _samr_del_aliasmem
3547*********************************************************************/
3548
3549NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3550{
3551	DOM_SID alias_sid;
3552	uint32 acc_granted;
3553	SE_PRIV se_rights;
3554	BOOL can_add_accounts;
3555	BOOL ret;
3556
3557	/* Find the policy handle. Open a policy on it. */
3558	if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3559		return NT_STATUS_INVALID_HANDLE;
3560
3561	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3562		return r_u->status;
3563	}
3564
3565	DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3566		   sid_string_static(&alias_sid)));
3567
3568	se_priv_copy( &se_rights, &se_add_users );
3569	can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3570
3571	/******** BEGIN SeAddUsers BLOCK *********/
3572
3573	if ( can_add_accounts )
3574		become_root();
3575
3576	ret = pdb_del_aliasmem(&alias_sid, &q_u->sid.sid);
3577
3578	if ( can_add_accounts )
3579		unbecome_root();
3580
3581	/******** END SeAddUsers BLOCK *********/
3582
3583	return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3584}
3585
3586/*********************************************************************
3587 _samr_add_groupmem
3588*********************************************************************/
3589
3590NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3591{
3592	DOM_SID group_sid;
3593	DOM_SID user_sid;
3594	fstring group_sid_str;
3595	uid_t uid;
3596	struct passwd *pwd;
3597	struct group *grp;
3598	fstring grp_name;
3599	GROUP_MAP map;
3600	NTSTATUS ret;
3601	SAM_ACCOUNT *sam_user=NULL;
3602	BOOL check;
3603	uint32 acc_granted;
3604	SE_PRIV se_rights;
3605	BOOL can_add_accounts;
3606
3607	/* Find the policy handle. Open a policy on it. */
3608	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3609		return NT_STATUS_INVALID_HANDLE;
3610
3611	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3612		return r_u->status;
3613	}
3614
3615	sid_to_string(group_sid_str, &group_sid);
3616	DEBUG(10, ("sid is %s\n", group_sid_str));
3617
3618	if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3619		return NT_STATUS_NO_SUCH_GROUP;
3620
3621	DEBUG(10, ("lookup on Domain SID\n"));
3622
3623	if(!get_domain_group_from_sid(group_sid, &map))
3624		return NT_STATUS_NO_SUCH_GROUP;
3625
3626	sid_copy(&user_sid, get_global_sam_sid());
3627	sid_append_rid(&user_sid, q_u->rid);
3628
3629	ret = pdb_init_sam(&sam_user);
3630	if (!NT_STATUS_IS_OK(ret))
3631		return ret;
3632
3633	check = pdb_getsampwsid(sam_user, &user_sid);
3634
3635	if (check != True) {
3636		pdb_free_sam(&sam_user);
3637		return NT_STATUS_NO_SUCH_USER;
3638	}
3639
3640	/* check a real user exist before we run the script to add a user to a group */
3641	if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3642		pdb_free_sam(&sam_user);
3643		return NT_STATUS_NO_SUCH_USER;
3644	}
3645
3646	pdb_free_sam(&sam_user);
3647
3648	if ((pwd=getpwuid_alloc(uid)) == NULL) {
3649		return NT_STATUS_NO_SUCH_USER;
3650	}
3651
3652	if ((grp=getgrgid(map.gid)) == NULL) {
3653		passwd_free(&pwd);
3654		return NT_STATUS_NO_SUCH_GROUP;
3655	}
3656
3657	/* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3658	fstrcpy(grp_name, grp->gr_name);
3659
3660	/* if the user is already in the group */
3661	if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3662		passwd_free(&pwd);
3663		return NT_STATUS_MEMBER_IN_GROUP;
3664	}
3665
3666	se_priv_copy( &se_rights, &se_add_users );
3667	can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3668
3669	/******** BEGIN SeAddUsers BLOCK *********/
3670
3671	if ( can_add_accounts )
3672		become_root();
3673
3674	/*
3675	 * ok, the group exist, the user exist, the user is not in the group,
3676	 *
3677	 * we can (finally) add it to the group !
3678	 */
3679
3680	smb_add_user_group(grp_name, pwd->pw_name);
3681
3682	if ( can_add_accounts )
3683		unbecome_root();
3684
3685	/******** END SeAddUsers BLOCK *********/
3686
3687	/* check if the user has been added then ... */
3688	if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3689		passwd_free(&pwd);
3690		return NT_STATUS_MEMBER_NOT_IN_GROUP;		/* don't know what to reply else */
3691	}
3692
3693	passwd_free(&pwd);
3694	return NT_STATUS_OK;
3695}
3696
3697/*********************************************************************
3698 _samr_del_groupmem
3699*********************************************************************/
3700
3701NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3702{
3703	DOM_SID group_sid;
3704	DOM_SID user_sid;
3705	SAM_ACCOUNT *sam_pass=NULL;
3706	GROUP_MAP map;
3707	fstring grp_name;
3708	struct group *grp;
3709	uint32 acc_granted;
3710	SE_PRIV se_rights;
3711	BOOL can_add_accounts;
3712
3713	/*
3714	 * delete the group member named q_u->rid
3715	 * who is a member of the sid associated with the handle
3716	 * the rid is a user's rid as the group is a domain group.
3717	 */
3718
3719	/* Find the policy handle. Open a policy on it. */
3720	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3721		return NT_STATUS_INVALID_HANDLE;
3722
3723	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3724		return r_u->status;
3725	}
3726
3727	if (!sid_check_is_in_our_domain(&group_sid))
3728		return NT_STATUS_NO_SUCH_GROUP;
3729
3730	sid_copy(&user_sid, get_global_sam_sid());
3731	sid_append_rid(&user_sid, q_u->rid);
3732
3733	if (!get_domain_group_from_sid(group_sid, &map))
3734		return NT_STATUS_NO_SUCH_GROUP;
3735
3736	if ((grp=getgrgid(map.gid)) == NULL)
3737		return NT_STATUS_NO_SUCH_GROUP;
3738
3739	/* we need to copy the name otherwise it's overloaded in user_in_group_list */
3740	fstrcpy(grp_name, grp->gr_name);
3741
3742	/* check if the user exists before trying to remove it from the group */
3743	pdb_init_sam(&sam_pass);
3744	if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3745		DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3746		pdb_free_sam(&sam_pass);
3747		return NT_STATUS_NO_SUCH_USER;
3748	}
3749
3750	/* if the user is not in the group */
3751	if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3752		pdb_free_sam(&sam_pass);
3753		return NT_STATUS_MEMBER_NOT_IN_GROUP;
3754	}
3755
3756
3757	se_priv_copy( &se_rights, &se_add_users );
3758	can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3759
3760	/******** BEGIN SeAddUsers BLOCK *********/
3761
3762	if ( can_add_accounts )
3763		become_root();
3764
3765	smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3766
3767	if ( can_add_accounts )
3768		unbecome_root();
3769
3770	/******** END SeAddUsers BLOCK *********/
3771
3772	/* check if the user has been removed then ... */
3773	if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3774		pdb_free_sam(&sam_pass);
3775		return NT_STATUS_ACCESS_DENIED;		/* don't know what to reply else */
3776	}
3777
3778	pdb_free_sam(&sam_pass);
3779	return NT_STATUS_OK;
3780
3781}
3782
3783/****************************************************************************
3784 Delete a UNIX user on demand.
3785****************************************************************************/
3786
3787static int smb_delete_user(const char *unix_user)
3788{
3789	pstring del_script;
3790	int ret;
3791
3792	/* try winbindd first since it is impossible to determine where
3793	   a user came from via NSS.  Try the delete user script if this fails
3794	   meaning the user did not exist in winbindd's list of accounts */
3795
3796	if ( winbind_delete_user( unix_user ) ) {
3797		DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3798		return 0;
3799	}
3800
3801
3802	/* fall back to 'delete user script' */
3803
3804	pstrcpy(del_script, lp_deluser_script());
3805	if (! *del_script)
3806		return -1;
3807	all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3808	ret = smbrun(del_script,NULL);
3809	flush_pwnam_cache();
3810	DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3811
3812	return ret;
3813}
3814
3815/*********************************************************************
3816 _samr_delete_dom_user
3817*********************************************************************/
3818
3819NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3820{
3821	DOM_SID user_sid;
3822	SAM_ACCOUNT *sam_pass=NULL;
3823	uint32 acc_granted;
3824	SE_PRIV se_rights;
3825	BOOL can_add_accounts;
3826	BOOL ret;
3827
3828	DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3829
3830	/* Find the policy handle. Open a policy on it. */
3831	if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3832		return NT_STATUS_INVALID_HANDLE;
3833
3834	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3835		return r_u->status;
3836	}
3837
3838	if (!sid_check_is_in_our_domain(&user_sid))
3839		return NT_STATUS_CANNOT_DELETE;
3840
3841	/* check if the user exists before trying to delete */
3842	pdb_init_sam(&sam_pass);
3843	if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3844		DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3845			sid_string_static(&user_sid)));
3846		pdb_free_sam(&sam_pass);
3847		return NT_STATUS_NO_SUCH_USER;
3848	}
3849
3850	se_priv_copy( &se_rights, &se_add_users );
3851	can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3852
3853	/******** BEGIN SeAddUsers BLOCK *********/
3854
3855	if ( can_add_accounts )
3856		become_root();
3857
3858	/* First delete the samba side....
3859	   code is order to prevent unnecessary returns out of the admin
3860	   block of code */
3861
3862	if ( (ret = pdb_delete_sam_account(sam_pass)) == True ) {
3863		/*
3864		 * Now delete the unix side ....
3865		 * note: we don't check if the delete really happened
3866		 * as the script is not necessary present
3867		 * and maybe the sysadmin doesn't want to delete the unix side
3868		 */
3869		smb_delete_user( pdb_get_username(sam_pass) );
3870	}
3871
3872	if ( can_add_accounts )
3873		unbecome_root();
3874
3875	/******** END SeAddUsers BLOCK *********/
3876
3877	if ( !ret ) {
3878		DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3879		pdb_free_sam(&sam_pass);
3880		return NT_STATUS_CANNOT_DELETE;
3881	}
3882
3883
3884	pdb_free_sam(&sam_pass);
3885
3886	if (!close_policy_hnd(p, &q_u->user_pol))
3887		return NT_STATUS_OBJECT_NAME_INVALID;
3888
3889	return NT_STATUS_OK;
3890}
3891
3892/*********************************************************************
3893 _samr_delete_dom_group
3894*********************************************************************/
3895
3896NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3897{
3898	DOM_SID group_sid;
3899	DOM_SID dom_sid;
3900	uint32 group_rid;
3901	fstring group_sid_str;
3902	gid_t gid;
3903	struct group *grp;
3904	GROUP_MAP map;
3905	uint32 acc_granted;
3906	SE_PRIV se_rights;
3907	BOOL can_add_accounts;
3908	BOOL ret;
3909
3910	DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3911
3912	/* Find the policy handle. Open a policy on it. */
3913	if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3914		return NT_STATUS_INVALID_HANDLE;
3915
3916	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3917		return r_u->status;
3918	}
3919
3920	sid_copy(&dom_sid, &group_sid);
3921	sid_to_string(group_sid_str, &dom_sid);
3922	sid_split_rid(&dom_sid, &group_rid);
3923
3924	DEBUG(10, ("sid is %s\n", group_sid_str));
3925
3926	/* we check if it's our SID before deleting */
3927	if (!sid_equal(&dom_sid, get_global_sam_sid()))
3928		return NT_STATUS_NO_SUCH_GROUP;
3929
3930	DEBUG(10, ("lookup on Domain SID\n"));
3931
3932	if(!get_domain_group_from_sid(group_sid, &map))
3933		return NT_STATUS_NO_SUCH_GROUP;
3934
3935	gid=map.gid;
3936
3937	/* check if group really exists */
3938	if ( (grp=getgrgid(gid)) == NULL)
3939		return NT_STATUS_NO_SUCH_GROUP;
3940
3941	se_priv_copy( &se_rights, &se_add_users );
3942	can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3943
3944	/******** BEGIN SeAddUsers BLOCK *********/
3945
3946	if ( can_add_accounts )
3947		become_root();
3948
3949	/* delete mapping first */
3950
3951	if ( (ret = pdb_delete_group_mapping_entry(group_sid)) == True ) {
3952		smb_delete_group( grp->gr_name );
3953	}
3954
3955	if ( can_add_accounts )
3956		unbecome_root();
3957
3958	/******** END SeAddUsers BLOCK *********/
3959
3960	if ( !ret ) {
3961		DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n",
3962			group_sid_str));
3963		return NT_STATUS_ACCESS_DENIED;
3964	}
3965
3966	/* don't check that the unix group has been deleted.  Work like
3967	   _samr_delet_dom_user() */
3968
3969	if (!close_policy_hnd(p, &q_u->group_pol))
3970		return NT_STATUS_OBJECT_NAME_INVALID;
3971
3972	return NT_STATUS_OK;
3973}
3974
3975/*********************************************************************
3976 _samr_delete_dom_alias
3977*********************************************************************/
3978
3979NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3980{
3981	DOM_SID alias_sid;
3982	uint32 acc_granted;
3983	SE_PRIV se_rights;
3984	BOOL can_add_accounts;
3985	BOOL ret;
3986
3987	DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3988
3989	/* Find the policy handle. Open a policy on it. */
3990	if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3991		return NT_STATUS_INVALID_HANDLE;
3992
3993	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3994		return r_u->status;
3995	}
3996
3997	DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3998
3999	if (!sid_check_is_in_our_domain(&alias_sid))
4000		return NT_STATUS_NO_SUCH_ALIAS;
4001
4002	DEBUG(10, ("lookup on Local SID\n"));
4003
4004	se_priv_copy( &se_rights, &se_add_users );
4005	can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4006
4007	/******** BEGIN SeAddUsers BLOCK *********/
4008
4009	if ( can_add_accounts )
4010		become_root();
4011
4012	/* Have passdb delete the alias */
4013	ret = pdb_delete_alias(&alias_sid);
4014
4015	if ( can_add_accounts )
4016		unbecome_root();
4017
4018	/******** END SeAddUsers BLOCK *********/
4019
4020	if ( !ret )
4021		return NT_STATUS_ACCESS_DENIED;
4022
4023	if (!close_policy_hnd(p, &q_u->alias_pol))
4024		return NT_STATUS_OBJECT_NAME_INVALID;
4025
4026	return NT_STATUS_OK;
4027}
4028
4029/*********************************************************************
4030 _samr_create_dom_group
4031*********************************************************************/
4032
4033NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
4034{
4035	DOM_SID dom_sid;
4036	DOM_SID info_sid;
4037	fstring name;
4038	fstring sid_string;
4039	struct group *grp;
4040	struct samr_info *info;
4041	uint32 acc_granted;
4042	gid_t gid;
4043	SE_PRIV se_rights;
4044	BOOL can_add_accounts;
4045	NTSTATUS result;
4046
4047	/* Find the policy handle. Open a policy on it. */
4048	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
4049		return NT_STATUS_INVALID_HANDLE;
4050
4051	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
4052		return r_u->status;
4053	}
4054
4055	if (!sid_equal(&dom_sid, get_global_sam_sid()))
4056		return NT_STATUS_ACCESS_DENIED;
4057
4058	unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4059
4060	/* check if group already exist */
4061	if ((grp=getgrnam(name)) != NULL)
4062		return NT_STATUS_GROUP_EXISTS;
4063
4064	se_priv_copy( &se_rights, &se_add_users );
4065	can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4066
4067	/******** BEGIN SeAddUsers BLOCK *********/
4068
4069	if ( can_add_accounts )
4070		become_root();
4071
4072	/* check that we successfully create the UNIX group */
4073
4074	result = NT_STATUS_ACCESS_DENIED;
4075	if ( (smb_create_group(name, &gid) == 0) && ((grp=getgrgid(gid)) != NULL) ) {
4076
4077		/* so far, so good */
4078
4079		result = NT_STATUS_OK;
4080
4081		r_u->rid = pdb_gid_to_group_rid( grp->gr_gid );
4082
4083		/* add the group to the mapping table */
4084
4085		sid_copy( &info_sid, get_global_sam_sid() );
4086		sid_append_rid( &info_sid, r_u->rid );
4087		sid_to_string( sid_string, &info_sid );
4088
4089		/* reset the error code if we fail to add the mapping entry */
4090
4091		if ( !add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL) )
4092			result = NT_STATUS_ACCESS_DENIED;
4093	}
4094
4095	if ( can_add_accounts )
4096		unbecome_root();
4097
4098	/******** END SeAddUsers BLOCK *********/
4099
4100	/* check if we should bail out here */
4101
4102	if ( !NT_STATUS_IS_OK(result) )
4103		return result;
4104
4105	if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4106		return NT_STATUS_NO_MEMORY;
4107
4108	/* get a (unique) handle.  open a policy on it. */
4109	if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4110		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4111
4112	return NT_STATUS_OK;
4113}
4114
4115/*********************************************************************
4116 _samr_create_dom_alias
4117*********************************************************************/
4118
4119NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4120{
4121	DOM_SID dom_sid;
4122	DOM_SID info_sid;
4123	fstring name;
4124	struct group *grp;
4125	struct samr_info *info;
4126	uint32 acc_granted;
4127	gid_t gid;
4128	NTSTATUS result;
4129	SE_PRIV se_rights;
4130	BOOL can_add_accounts;
4131
4132	/* Find the policy handle. Open a policy on it. */
4133	if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4134		return NT_STATUS_INVALID_HANDLE;
4135
4136	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4137		return r_u->status;
4138	}
4139
4140	if (!sid_equal(&dom_sid, get_global_sam_sid()))
4141		return NT_STATUS_ACCESS_DENIED;
4142
4143	unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4144
4145	se_priv_copy( &se_rights, &se_add_users );
4146	can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4147
4148	/******** BEGIN SeAddUsers BLOCK *********/
4149
4150	if ( can_add_accounts )
4151		become_root();
4152
4153	/* Have passdb create the alias */
4154	result = pdb_create_alias(name, &r_u->rid);
4155
4156	if ( can_add_accounts )
4157		unbecome_root();
4158
4159	/******** END SeAddUsers BLOCK *********/
4160
4161	if (!NT_STATUS_IS_OK(result))
4162		return result;
4163
4164	sid_copy(&info_sid, get_global_sam_sid());
4165	sid_append_rid(&info_sid, r_u->rid);
4166
4167	if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
4168		return NT_STATUS_ACCESS_DENIED;
4169
4170	/* check if the group has been successfully created */
4171	if ((grp=getgrgid(gid)) == NULL)
4172		return NT_STATUS_ACCESS_DENIED;
4173
4174	if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4175		return NT_STATUS_NO_MEMORY;
4176
4177	/* get a (unique) handle.  open a policy on it. */
4178	if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4179		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4180
4181	return NT_STATUS_OK;
4182}
4183
4184/*********************************************************************
4185 _samr_query_groupinfo
4186
4187sends the name/comment pair of a domain group
4188level 1 send also the number of users of that group
4189*********************************************************************/
4190
4191NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4192{
4193	DOM_SID group_sid;
4194	GROUP_MAP map;
4195	DOM_SID *sids=NULL;
4196	uid_t *uids;
4197	int num=0;
4198	GROUP_INFO_CTR *ctr;
4199	uint32 acc_granted;
4200	BOOL ret;
4201
4202	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4203		return NT_STATUS_INVALID_HANDLE;
4204
4205	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4206		return r_u->status;
4207	}
4208
4209	become_root();
4210	ret = get_domain_group_from_sid(group_sid, &map);
4211	unbecome_root();
4212	if (!ret)
4213		return NT_STATUS_INVALID_HANDLE;
4214
4215	ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
4216	if (ctr==NULL)
4217		return NT_STATUS_NO_MEMORY;
4218
4219	switch (q_u->switch_level) {
4220		case 1:
4221			ctr->switch_value1 = 1;
4222			if(!get_memberuids(map.gid, &uids, &num))
4223				return NT_STATUS_NO_SUCH_GROUP;
4224			SAFE_FREE(uids);
4225			init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
4226			SAFE_FREE(sids);
4227			break;
4228		case 3:
4229			ctr->switch_value1 = 3;
4230			init_samr_group_info3(&ctr->group.info3);
4231			break;
4232		case 4:
4233			ctr->switch_value1 = 4;
4234			init_samr_group_info4(&ctr->group.info4, map.comment);
4235			break;
4236		default:
4237			return NT_STATUS_INVALID_INFO_CLASS;
4238	}
4239
4240	init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4241
4242	return NT_STATUS_OK;
4243}
4244
4245/*********************************************************************
4246 _samr_set_groupinfo
4247
4248 update a domain group's comment.
4249*********************************************************************/
4250
4251NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4252{
4253	DOM_SID group_sid;
4254	GROUP_MAP map;
4255	GROUP_INFO_CTR *ctr;
4256	uint32 acc_granted;
4257
4258	if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4259		return NT_STATUS_INVALID_HANDLE;
4260
4261	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4262		return r_u->status;
4263	}
4264
4265	if (!get_domain_group_from_sid(group_sid, &map))
4266		return NT_STATUS_NO_SUCH_GROUP;
4267
4268	ctr=q_u->ctr;
4269
4270	switch (ctr->switch_value1) {
4271		case 1:
4272			unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4273			break;
4274		case 4:
4275			unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4276			break;
4277		default:
4278			return NT_STATUS_INVALID_INFO_CLASS;
4279	}
4280
4281	if(!pdb_update_group_mapping_entry(&map)) {
4282		return NT_STATUS_NO_SUCH_GROUP;
4283	}
4284
4285	return NT_STATUS_OK;
4286}
4287
4288/*********************************************************************
4289 _samr_set_aliasinfo
4290
4291 update an alias's comment.
4292*********************************************************************/
4293
4294NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4295{
4296	DOM_SID group_sid;
4297	struct acct_info info;
4298	ALIAS_INFO_CTR *ctr;
4299	uint32 acc_granted;
4300
4301	if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4302		return NT_STATUS_INVALID_HANDLE;
4303
4304	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4305		return r_u->status;
4306	}
4307
4308	ctr=&q_u->ctr;
4309
4310	switch (ctr->switch_value1) {
4311		case 3:
4312			unistr2_to_ascii(info.acct_desc,
4313					 &(ctr->alias.info3.uni_acct_desc),
4314					 sizeof(info.acct_desc)-1);
4315			break;
4316		default:
4317			return NT_STATUS_INVALID_INFO_CLASS;
4318	}
4319
4320	if(!pdb_set_aliasinfo(&group_sid, &info)) {
4321		return NT_STATUS_ACCESS_DENIED;
4322	}
4323
4324	return NT_STATUS_OK;
4325}
4326
4327/*********************************************************************
4328 _samr_get_dom_pwinfo
4329*********************************************************************/
4330
4331NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4332{
4333	/* Perform access check.  Since this rpc does not require a
4334	   policy handle it will not be caught by the access checks on
4335	   SAMR_CONNECT or SAMR_CONNECT_ANON. */
4336
4337	if (!pipe_access_check(p)) {
4338		DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4339		r_u->status = NT_STATUS_ACCESS_DENIED;
4340		return r_u->status;
4341	}
4342
4343	/* Actually, returning zeros here works quite well :-). */
4344
4345	return NT_STATUS_OK;
4346}
4347
4348/*********************************************************************
4349 _samr_open_group
4350*********************************************************************/
4351
4352NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4353{
4354	DOM_SID sid;
4355	DOM_SID info_sid;
4356	GROUP_MAP map;
4357	struct samr_info *info;
4358	SEC_DESC         *psd = NULL;
4359	uint32            acc_granted;
4360	uint32            des_access = q_u->access_mask;
4361	size_t            sd_size;
4362	NTSTATUS          status;
4363	fstring sid_string;
4364	BOOL ret;
4365	SE_PRIV se_rights;
4366
4367	if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4368		return NT_STATUS_INVALID_HANDLE;
4369
4370	status = access_check_samr_function(acc_granted,
4371		SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group");
4372
4373	if ( !NT_STATUS_IS_OK(status) )
4374		return status;
4375
4376	/*check if access can be granted as requested by client. */
4377	make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
4378	se_map_generic(&des_access,&grp_generic_mapping);
4379
4380	se_priv_copy( &se_rights, &se_add_users );
4381
4382	status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
4383		&se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
4384		&acc_granted, "_samr_open_group");
4385
4386	if ( !NT_STATUS_IS_OK(status) )
4387		return status;
4388
4389	/* this should not be hard-coded like this */
4390
4391	if (!sid_equal(&sid, get_global_sam_sid()))
4392		return NT_STATUS_ACCESS_DENIED;
4393
4394	sid_copy(&info_sid, get_global_sam_sid());
4395	sid_append_rid(&info_sid, q_u->rid_group);
4396	sid_to_string(sid_string, &info_sid);
4397
4398	if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4399		return NT_STATUS_NO_MEMORY;
4400
4401	info->acc_granted = acc_granted;
4402
4403	DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4404
4405	/* check if that group really exists */
4406	become_root();
4407	ret = get_domain_group_from_sid(info->sid, &map);
4408	unbecome_root();
4409	if (!ret)
4410		return NT_STATUS_NO_SUCH_GROUP;
4411
4412	/* get a (unique) handle.  open a policy on it. */
4413	if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4414		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4415
4416	return NT_STATUS_OK;
4417}
4418
4419/*********************************************************************
4420 _samr_remove_sid_foreign_domain
4421*********************************************************************/
4422
4423NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4424                                          SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4425                                          SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4426{
4427	DOM_SID			delete_sid, alias_sid;
4428	SAM_ACCOUNT 		*sam_pass=NULL;
4429	uint32 			acc_granted;
4430	GROUP_MAP 		map;
4431	BOOL			is_user = False;
4432	NTSTATUS		result;
4433	enum SID_NAME_USE	type = SID_NAME_UNKNOWN;
4434
4435	sid_copy( &delete_sid, &q_u->sid.sid );
4436
4437	DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4438		sid_string_static(&delete_sid)));
4439
4440	/* Find the policy handle. Open a policy on it. */
4441
4442	if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4443		return NT_STATUS_INVALID_HANDLE;
4444
4445	result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4446		"_samr_remove_sid_foreign_domain");
4447
4448	if (!NT_STATUS_IS_OK(result))
4449		return result;
4450
4451	DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4452		sid_string_static(&alias_sid)));
4453
4454	/* make sure we can handle this */
4455
4456	if ( sid_check_is_domain(&alias_sid) )
4457		type = SID_NAME_DOM_GRP;
4458	else if ( sid_check_is_builtin(&alias_sid) )
4459		type = SID_NAME_ALIAS;
4460
4461	if ( type == SID_NAME_UNKNOWN ) {
4462		DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4463		return NT_STATUS_OK;
4464	}
4465
4466	/* check if the user exists before trying to delete */
4467
4468	pdb_init_sam(&sam_pass);
4469
4470	if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4471		is_user = True;
4472	} else {
4473		/* maybe it is a group */
4474		if( !pdb_getgrsid(&map, delete_sid) ) {
4475			DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4476				sid_string_static(&delete_sid)));
4477			result = NT_STATUS_INVALID_SID;
4478			goto done;
4479		}
4480	}
4481
4482	/* we can only delete a user from a group since we don't have
4483	   nested groups anyways.  So in the latter case, just say OK */
4484
4485	if ( is_user ) {
4486		GROUP_MAP	*mappings = NULL;
4487		int		num_groups, i;
4488		struct group	*grp2;
4489
4490		if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4491
4492			/* interate over the groups */
4493			for ( i=0; i<num_groups; i++ ) {
4494
4495				grp2 = getgrgid(mappings[i].gid);
4496
4497				if ( !grp2 ) {
4498					DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4499					continue;
4500				}
4501
4502				if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4503					continue;
4504
4505				smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4506
4507				if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4508					/* should we fail here ? */
4509					DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4510						pdb_get_username(sam_pass), grp2->gr_name ));
4511					continue;
4512				}
4513
4514				DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4515					pdb_get_username(sam_pass), grp2->gr_name ));
4516			}
4517
4518			SAFE_FREE(mappings);
4519		}
4520	}
4521
4522	result = NT_STATUS_OK;
4523done:
4524
4525	pdb_free_sam(&sam_pass);
4526
4527	return result;
4528}
4529
4530/*******************************************************************
4531 _samr_unknown_2e
4532 ********************************************************************/
4533
4534NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4535{
4536	struct samr_info *info = NULL;
4537	SAM_UNK_CTR *ctr;
4538	uint32 min_pass_len,pass_hist,flag;
4539	time_t u_expire, u_min_age;
4540	NTTIME nt_expire, nt_min_age;
4541
4542	time_t u_lock_duration, u_reset_time;
4543	NTTIME nt_lock_duration, nt_reset_time;
4544	uint32 lockout;
4545
4546	time_t u_logout;
4547	NTTIME nt_logout;
4548
4549	uint32 num_users=0, num_groups=0, num_aliases=0;
4550
4551	uint32 account_policy_temp;
4552	uint32 server_role;
4553
4554	if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4555		return NT_STATUS_NO_MEMORY;
4556
4557	ZERO_STRUCTP(ctr);
4558
4559	r_u->status = NT_STATUS_OK;
4560
4561	DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4562
4563	/* find the policy handle.  open a policy on it. */
4564	if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4565		return NT_STATUS_INVALID_HANDLE;
4566
4567	switch (q_u->switch_value) {
4568		case 0x01:
4569			account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4570			min_pass_len = account_policy_temp;
4571
4572			account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4573			pass_hist = account_policy_temp;
4574
4575			account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4576			flag = account_policy_temp;
4577
4578			account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4579			u_expire = account_policy_temp;
4580
4581			account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4582			u_min_age = account_policy_temp;
4583
4584			unix_to_nt_time_abs(&nt_expire, u_expire);
4585			unix_to_nt_time_abs(&nt_min_age, u_min_age);
4586
4587			init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4588			               flag, nt_expire, nt_min_age);
4589			break;
4590		case 0x02:
4591			become_root();
4592			r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4593			unbecome_root();
4594			if (!NT_STATUS_IS_OK(r_u->status)) {
4595				DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4596				return r_u->status;
4597			}
4598			num_users=info->disp_info.num_user_account;
4599			free_samr_db(info);
4600
4601			r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4602			if (NT_STATUS_IS_ERR(r_u->status)) {
4603				DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4604				return r_u->status;
4605			}
4606			num_groups=info->disp_info.num_group_account;
4607			free_samr_db(info);
4608
4609			account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4610			u_logout = account_policy_temp;
4611
4612			unix_to_nt_time_abs(&nt_logout, u_logout);
4613
4614			server_role = ROLE_DOMAIN_PDC;
4615			if (lp_server_role() == ROLE_DOMAIN_BDC)
4616				server_role = ROLE_DOMAIN_BDC;
4617
4618			/* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4619			init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL),
4620				       num_users, num_groups, num_aliases, nt_logout, server_role);
4621			break;
4622		case 0x03:
4623			account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4624			u_logout = account_policy_temp;
4625
4626			unix_to_nt_time_abs(&nt_logout, u_logout);
4627
4628			init_unk_info3(&ctr->info.inf3, nt_logout);
4629			break;
4630		case 0x05:
4631			init_unk_info5(&ctr->info.inf5, global_myname());
4632			break;
4633		case 0x06:
4634			init_unk_info6(&ctr->info.inf6);
4635			break;
4636		case 0x07:
4637			server_role = ROLE_DOMAIN_PDC;
4638			if (lp_server_role() == ROLE_DOMAIN_BDC)
4639				server_role = ROLE_DOMAIN_BDC;
4640			init_unk_info7(&ctr->info.inf7, server_role);
4641			break;
4642		case 0x08:
4643			init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
4644			break;
4645		case 0x0c:
4646			account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4647			u_lock_duration = account_policy_temp;
4648			if (u_lock_duration != -1)
4649				u_lock_duration *= 60;
4650
4651			account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4652			u_reset_time = account_policy_temp * 60;
4653
4654			account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4655			lockout = account_policy_temp;
4656
4657			unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4658			unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4659
4660            		init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4661			break;
4662		default:
4663			return NT_STATUS_INVALID_INFO_CLASS;
4664	}
4665
4666	init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4667
4668	DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4669
4670	return r_u->status;
4671}
4672
4673/*******************************************************************
4674 _samr_
4675 ********************************************************************/
4676
4677NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4678{
4679	time_t u_expire, u_min_age;
4680	time_t u_logout;
4681	time_t u_lock_duration, u_reset_time;
4682
4683	r_u->status = NT_STATUS_OK;
4684
4685	DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4686
4687	/* find the policy handle.  open a policy on it. */
4688	if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4689		return NT_STATUS_INVALID_HANDLE;
4690
4691	DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4692
4693	switch (q_u->switch_value) {
4694        	case 0x01:
4695			u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4696			u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4697
4698			account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4699			account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4700			account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4701			account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4702			account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4703            		break;
4704        	case 0x02:
4705			break;
4706		case 0x03:
4707			u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4708			account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4709			break;
4710		case 0x05:
4711			break;
4712		case 0x06:
4713			break;
4714		case 0x07:
4715			break;
4716		case 0x0c:
4717			u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4718			if (u_lock_duration != -1)
4719				u_lock_duration /= 60;
4720
4721			u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4722
4723			account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4724			account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4725			account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4726			break;
4727		default:
4728			return NT_STATUS_INVALID_INFO_CLASS;
4729	}
4730
4731	init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4732
4733	DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4734
4735	return r_u->status;
4736}
4737