1/*
2   Unix SMB/CIFS implementation.
3   Password and authentication handling
4   Copyright (C) Jeremy Allison 		1996-2001
5   Copyright (C) Luke Kenneth Casson Leighton 	1996-1998
6   Copyright (C) Gerald (Jerry) Carter		2000-2001
7   Copyright (C) Andrew Bartlett		2001-2002
8   Copyright (C) Simo Sorce			2003
9
10   This program is free software; you can redistribute it and/or modify
11   it under the terms of the GNU General Public License as published by
12   the Free Software Foundation; either version 2 of the License, or
13   (at your option) any later version.
14
15   This program is distributed in the hope that it will be useful,
16   but WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   GNU General Public License for more details.
19
20   You should have received a copy of the GNU General Public License
21   along with this program; if not, write to the Free Software
22   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23*/
24
25#include "includes.h"
26
27#undef DBGC_CLASS
28#define DBGC_CLASS DBGC_PASSDB
29
30/******************************************************************
31 get the default domain/netbios name to be used when
32 testing authentication.  For example, if you connect
33 to a Windows member server using a bogus domain name, the
34 Windows box will map the BOGUS\user to DOMAIN\user.  A
35 standalone box will map to WKS\user.
36******************************************************************/
37
38const char *get_default_sam_name(void)
39{
40	/* standalone servers can only use the local netbios name */
41	if ( lp_server_role() == ROLE_STANDALONE )
42		return global_myname();
43
44	/* Windows domain members default to the DOMAIN
45	   name when not specified */
46	return lp_workgroup();
47}
48
49/************************************************************
50 Fill the SAM_ACCOUNT with default values.
51 ***********************************************************/
52
53void pdb_fill_default_sam(SAM_ACCOUNT *user)
54{
55	ZERO_STRUCT(user->private); /* Don't touch the talloc context */
56
57	/* no initial methods */
58	user->methods = NULL;
59
60        /* Don't change these timestamp settings without a good reason.
61           They are important for NT member server compatibility. */
62
63	user->private.logon_time            = (time_t)0;
64	user->private.pass_last_set_time    = (time_t)0;
65	user->private.pass_can_change_time  = (time_t)0;
66	user->private.logoff_time           =
67	user->private.kickoff_time          =
68	user->private.pass_must_change_time = get_time_t_max();
69	user->private.fields_present        = 0x00ffffff;
70	user->private.logon_divs = 168; 	/* hours per week */
71	user->private.hours_len = 21; 		/* 21 times 8 bits = 168 */
72	memset(user->private.hours, 0xff, user->private.hours_len); /* available at all hours */
73	user->private.bad_password_count = 0;
74	user->private.logon_count = 0;
75	user->private.unknown_6 = 0x000004ec; /* don't know */
76
77	/* Some parts of samba strlen their pdb_get...() returns,
78	   so this keeps the interface unchanged for now. */
79
80	user->private.username = "";
81	user->private.domain = "";
82	user->private.nt_username = "";
83	user->private.full_name = "";
84	user->private.home_dir = "";
85	user->private.logon_script = "";
86	user->private.profile_path = "";
87	user->private.acct_desc = "";
88	user->private.workstations = "";
89	user->private.unknown_str = "";
90	user->private.munged_dial = "";
91
92	user->private.plaintext_pw = NULL;
93
94	/*
95	   Unless we know otherwise have a Account Control Bit
96	   value of 'normal user'.  This helps User Manager, which
97	   asks for a filtered list of users.
98	*/
99
100	user->private.acct_ctrl = ACB_NORMAL;
101}
102
103static void destroy_pdb_talloc(SAM_ACCOUNT **user)
104{
105	if (*user) {
106		data_blob_clear_free(&((*user)->private.lm_pw));
107		data_blob_clear_free(&((*user)->private.nt_pw));
108
109		if((*user)->private.plaintext_pw!=NULL)
110			memset((*user)->private.plaintext_pw,'\0',strlen((*user)->private.plaintext_pw));
111		talloc_destroy((*user)->mem_ctx);
112		*user = NULL;
113	}
114}
115
116
117/**********************************************************************
118 Allocates memory and initialises a struct sam_passwd on supplied mem_ctx.
119***********************************************************************/
120
121NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user)
122{
123	if (*user != NULL) {
124		DEBUG(0,("pdb_init_sam_talloc: SAM_ACCOUNT was non NULL\n"));
125#if 0
126		smb_panic("non-NULL pointer passed to pdb_init_sam\n");
127#endif
128		return NT_STATUS_UNSUCCESSFUL;
129	}
130
131	if (!mem_ctx) {
132		DEBUG(0,("pdb_init_sam_talloc: mem_ctx was NULL!\n"));
133		return NT_STATUS_UNSUCCESSFUL;
134	}
135
136	*user=TALLOC_P(mem_ctx, SAM_ACCOUNT);
137
138	if (*user==NULL) {
139		DEBUG(0,("pdb_init_sam_talloc: error while allocating memory\n"));
140		return NT_STATUS_NO_MEMORY;
141	}
142
143	(*user)->mem_ctx = mem_ctx;
144
145	(*user)->free_fn = NULL;
146
147	pdb_fill_default_sam(*user);
148
149	return NT_STATUS_OK;
150}
151
152
153/*************************************************************
154 Allocates memory and initialises a struct sam_passwd.
155 ************************************************************/
156
157NTSTATUS pdb_init_sam(SAM_ACCOUNT **user)
158{
159	TALLOC_CTX *mem_ctx;
160	NTSTATUS nt_status;
161
162	mem_ctx = talloc_init("passdb internal SAM_ACCOUNT allocation");
163
164	if (!mem_ctx) {
165		DEBUG(0,("pdb_init_sam: error while doing talloc_init()\n"));
166		return NT_STATUS_NO_MEMORY;
167	}
168
169	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, user))) {
170		talloc_destroy(mem_ctx);
171		return nt_status;
172	}
173
174	(*user)->free_fn = destroy_pdb_talloc;
175
176	return NT_STATUS_OK;
177}
178
179/**************************************************************************
180 * This function will take care of all the steps needed to correctly
181 * allocate and set the user SID, please do use this function to create new
182 * users, messing with SIDs is not good.
183 *
184 * account_data must be provided initialized, pwd may be null.
185 * 									SSS
186 ***************************************************************************/
187
188static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd)
189{
190	const char *guest_account = lp_guestaccount();
191	GROUP_MAP map;
192	BOOL ret;
193
194	if (!account_data || !pwd) {
195		return NT_STATUS_INVALID_PARAMETER;
196	}
197
198	/* this is a hack this thing should not be set
199	   this way --SSS */
200	if (!(guest_account && *guest_account)) {
201		DEBUG(1, ("NULL guest account!?!?\n"));
202		return NT_STATUS_UNSUCCESSFUL;
203	} else {
204		/* Ensure this *must* be set right */
205		if (strcmp(pwd->pw_name, guest_account) == 0) {
206			if (!pdb_set_user_sid_from_rid(account_data, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
207				return NT_STATUS_UNSUCCESSFUL;
208			}
209			if (!pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) {
210				return NT_STATUS_UNSUCCESSFUL;
211			}
212			return NT_STATUS_OK;
213		}
214	}
215
216	if (!pdb_set_user_sid_from_rid(account_data, algorithmic_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) {
217		DEBUG(0,("Can't set User SID from RID!\n"));
218		return NT_STATUS_INVALID_PARAMETER;
219	}
220
221	/* call the mapping code here */
222	become_root();
223	ret = pdb_getgrgid(&map, pwd->pw_gid);
224	unbecome_root();
225
226	if( ret ) {
227		if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){
228			DEBUG(0,("Can't set Group SID!\n"));
229			return NT_STATUS_INVALID_PARAMETER;
230		}
231	}
232	else {
233		if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) {
234			DEBUG(0,("Can't set Group SID\n"));
235			return NT_STATUS_INVALID_PARAMETER;
236		}
237	}
238
239	return NT_STATUS_OK;
240}
241
242/*************************************************************
243 Initialises a struct sam_passwd with sane values.
244 ************************************************************/
245
246NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
247{
248	NTSTATUS ret;
249
250	if (!pwd) {
251		return NT_STATUS_UNSUCCESSFUL;
252	}
253
254	pdb_fill_default_sam(sam_account);
255
256	pdb_set_username(sam_account, pwd->pw_name, PDB_SET);
257	pdb_set_fullname(sam_account, pwd->pw_gecos, PDB_SET);
258
259	pdb_set_unix_homedir(sam_account, pwd->pw_dir, PDB_SET);
260
261	pdb_set_domain (sam_account, get_global_sam_name(), PDB_DEFAULT);
262
263	/* When we get a proper uid -> SID and SID -> uid allocation
264	   mechinism, we should call it here.
265
266	   We can't just set this to 0 or allow it only to be filled
267	   in when added to the backend, because the user's SID
268	   may already be in security descriptors etc.
269
270	   -- abartlet 11-May-02
271	*/
272
273	ret = pdb_set_sam_sids(sam_account, pwd);
274	if (!NT_STATUS_IS_OK(ret)) return ret;
275
276	/* check if this is a user account or a machine account */
277	if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')
278	{
279		pdb_set_profile_path(sam_account,
280				     talloc_sub_specified((sam_account)->mem_ctx,
281							    lp_logon_path(),
282							    pwd->pw_name, global_myname(),
283							    pwd->pw_uid, pwd->pw_gid),
284				     PDB_DEFAULT);
285
286		pdb_set_homedir(sam_account,
287				talloc_sub_specified((sam_account)->mem_ctx,
288						       lp_logon_home(),
289						       pwd->pw_name, global_myname(),
290						       pwd->pw_uid, pwd->pw_gid),
291				PDB_DEFAULT);
292
293		pdb_set_dir_drive(sam_account,
294				  talloc_sub_specified((sam_account)->mem_ctx,
295							 lp_logon_drive(),
296							 pwd->pw_name, global_myname(),
297							 pwd->pw_uid, pwd->pw_gid),
298				  PDB_DEFAULT);
299
300		pdb_set_logon_script(sam_account,
301				     talloc_sub_specified((sam_account)->mem_ctx,
302							    lp_logon_script(),
303							    pwd->pw_name, global_myname(),
304							    pwd->pw_uid, pwd->pw_gid),
305				     PDB_DEFAULT);
306		if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT)) {
307			DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", pwd->pw_name));
308			return NT_STATUS_UNSUCCESSFUL;
309		}
310	} else {
311		if (!pdb_set_acct_ctrl(sam_account, ACB_WSTRUST, PDB_DEFAULT)) {
312			DEBUG(1, ("Failed to set 'trusted workstation account' flags for user %s.\n", pwd->pw_name));
313			return NT_STATUS_UNSUCCESSFUL;
314		}
315	}
316	return NT_STATUS_OK;
317}
318
319
320/*************************************************************
321 Initialises a struct sam_passwd with sane values.
322 ************************************************************/
323
324NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
325{
326	NTSTATUS nt_status;
327
328	if (!pwd) {
329		new_sam_acct = NULL;
330		return NT_STATUS_INVALID_PARAMETER;
331	}
332
333	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
334		new_sam_acct = NULL;
335		return nt_status;
336	}
337
338	if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) {
339		pdb_free_sam(new_sam_acct);
340		new_sam_acct = NULL;
341		return nt_status;
342	}
343
344	return NT_STATUS_OK;
345}
346
347
348/*************************************************************
349 Initialises a SAM_ACCOUNT ready to add a new account, based
350 on the UNIX user.  Pass in a RID if you have one
351 ************************************************************/
352
353NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username,
354                          uint32 rid)
355{
356	NTSTATUS 	nt_status = NT_STATUS_NO_MEMORY;
357	struct passwd 	*pwd;
358	BOOL		ret;
359
360	pwd = Get_Pwnam(username);
361
362	if (!pwd)
363		return NT_STATUS_NO_SUCH_USER;
364
365	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(new_sam_acct, pwd))) {
366		*new_sam_acct = NULL;
367		return nt_status;
368	}
369
370	/* see if we need to generate a new rid using the 2.2 algorithm */
371	if ( rid == 0 && lp_enable_rid_algorithm() ) {
372		DEBUG(10,("pdb_init_sam_new: no RID specified.  Generating one via old algorithm\n"));
373		rid = algorithmic_pdb_uid_to_user_rid(pwd->pw_uid);
374	}
375
376	/* set the new SID */
377
378	ret = pdb_set_user_sid_from_rid( *new_sam_acct, rid, PDB_SET );
379
380	return (ret ? NT_STATUS_OK : NT_STATUS_NO_SUCH_USER);
381}
382
383
384/**
385 * Free the contets of the SAM_ACCOUNT, but not the structure.
386 *
387 * Also wipes the LM and NT hashes and plaintext password from
388 * memory.
389 *
390 * @param user SAM_ACCOUNT to free members of.
391 **/
392
393static void pdb_free_sam_contents(SAM_ACCOUNT *user)
394{
395
396	/* Kill off sensitive data.  Free()ed by the
397	   talloc mechinism */
398
399	data_blob_clear_free(&(user->private.lm_pw));
400	data_blob_clear_free(&(user->private.nt_pw));
401	if (user->private.plaintext_pw!=NULL)
402		memset(user->private.plaintext_pw,'\0',strlen(user->private.plaintext_pw));
403
404	if (user->private.backend_private_data && user->private.backend_private_data_free_fn) {
405		user->private.backend_private_data_free_fn(&user->private.backend_private_data);
406	}
407}
408
409
410/************************************************************
411 Reset the SAM_ACCOUNT and free the NT/LM hashes.
412 ***********************************************************/
413
414NTSTATUS pdb_reset_sam(SAM_ACCOUNT *user)
415{
416	if (user == NULL) {
417		DEBUG(0,("pdb_reset_sam: SAM_ACCOUNT was NULL\n"));
418#if 0
419		smb_panic("NULL pointer passed to pdb_free_sam\n");
420#endif
421		return NT_STATUS_UNSUCCESSFUL;
422	}
423
424	pdb_free_sam_contents(user);
425
426	pdb_fill_default_sam(user);
427
428	return NT_STATUS_OK;
429}
430
431
432/************************************************************
433 Free the SAM_ACCOUNT and the member pointers.
434 ***********************************************************/
435
436NTSTATUS pdb_free_sam(SAM_ACCOUNT **user)
437{
438	if (*user == NULL) {
439		DEBUG(0,("pdb_free_sam: SAM_ACCOUNT was NULL\n"));
440#if 0
441		smb_panic("NULL pointer passed to pdb_free_sam\n");
442#endif
443		return NT_STATUS_UNSUCCESSFUL;
444	}
445
446	pdb_free_sam_contents(*user);
447
448	if ((*user)->free_fn) {
449		(*user)->free_fn(user);
450	}
451
452	return NT_STATUS_OK;
453}
454
455/**********************************************************
456 Encode the account control bits into a string.
457 length = length of string to encode into (including terminating
458 null). length *MUST BE MORE THAN 2* !
459 **********************************************************/
460
461char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
462{
463	static fstring acct_str;
464
465	size_t i = 0;
466
467	SMB_ASSERT(length <= sizeof(acct_str));
468
469	acct_str[i++] = '[';
470
471	if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
472	if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
473	if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
474	if (acct_ctrl & ACB_TEMPDUP  ) acct_str[i++] = 'T';
475	if (acct_ctrl & ACB_NORMAL   ) acct_str[i++] = 'U';
476	if (acct_ctrl & ACB_MNS      ) acct_str[i++] = 'M';
477	if (acct_ctrl & ACB_WSTRUST  ) acct_str[i++] = 'W';
478	if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
479	if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
480	if (acct_ctrl & ACB_PWNOEXP  ) acct_str[i++] = 'X';
481	if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
482
483	for ( ; i < length - 2 ; i++ )
484		acct_str[i] = ' ';
485
486	i = length - 2;
487	acct_str[i++] = ']';
488	acct_str[i++] = '\0';
489
490	return acct_str;
491}
492
493/**********************************************************
494 Decode the account control bits from a string.
495 **********************************************************/
496
497uint16 pdb_decode_acct_ctrl(const char *p)
498{
499	uint16 acct_ctrl = 0;
500	BOOL finished = False;
501
502	/*
503	 * Check if the account type bits have been encoded after the
504	 * NT password (in the form [NDHTUWSLXI]).
505	 */
506
507	if (*p != '[')
508		return 0;
509
510	for (p++; *p && !finished; p++) {
511		switch (*p) {
512			case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
513			case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
514			case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
515			case 'T': { acct_ctrl |= ACB_TEMPDUP  ; break; /* 'T'emp account. */ }
516			case 'U': { acct_ctrl |= ACB_NORMAL   ; break; /* 'U'ser account (normal). */ }
517			case 'M': { acct_ctrl |= ACB_MNS      ; break; /* 'M'NS logon user account. What is this ? */ }
518			case 'W': { acct_ctrl |= ACB_WSTRUST  ; break; /* 'W'orkstation account. */ }
519			case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
520			case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
521			case 'X': { acct_ctrl |= ACB_PWNOEXP  ; break; /* No 'X'piry on password */ }
522			case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
523            case ' ': { break; }
524			case ':':
525			case '\n':
526			case '\0':
527			case ']':
528			default:  { finished = True; }
529		}
530	}
531
532	return acct_ctrl;
533}
534
535/*************************************************************
536 Routine to set 32 hex password characters from a 16 byte array.
537**************************************************************/
538
539void pdb_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl)
540{
541	if (pwd != NULL) {
542		int i;
543		for (i = 0; i < 16; i++)
544			slprintf(&p[i*2], 3, "%02X", pwd[i]);
545	} else {
546		if (acct_ctrl & ACB_PWNOTREQ)
547			safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
548		else
549			safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
550	}
551}
552
553/*************************************************************
554 Routine to get the 32 hex characters and turn them
555 into a 16 byte array.
556**************************************************************/
557
558BOOL pdb_gethexpwd(const char *p, unsigned char *pwd)
559{
560	int i;
561	unsigned char   lonybble, hinybble;
562	const char      *hexchars = "0123456789ABCDEF";
563	char           *p1, *p2;
564
565	if (!p)
566		return (False);
567
568	for (i = 0; i < 32; i += 2) {
569		hinybble = toupper(p[i]);
570		lonybble = toupper(p[i + 1]);
571
572		p1 = strchr(hexchars, hinybble);
573		p2 = strchr(hexchars, lonybble);
574
575		if (!p1 || !p2)
576			return (False);
577
578		hinybble = PTR_DIFF(p1, hexchars);
579		lonybble = PTR_DIFF(p2, hexchars);
580
581		pwd[i / 2] = (hinybble << 4) | lonybble;
582	}
583	return (True);
584}
585
586/*************************************************************
587 Routine to set 42 hex hours characters from a 21 byte array.
588**************************************************************/
589
590void pdb_sethexhours(char *p, const unsigned char *hours)
591{
592	if (hours != NULL) {
593		int i;
594		for (i = 0; i < 21; i++) {
595			slprintf(&p[i*2], 3, "%02X", hours[i]);
596		}
597	} else {
598		safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
599	}
600}
601
602/*************************************************************
603 Routine to get the 42 hex characters and turn them
604 into a 21 byte array.
605**************************************************************/
606
607BOOL pdb_gethexhours(const char *p, unsigned char *hours)
608{
609	int i;
610	unsigned char   lonybble, hinybble;
611	const char      *hexchars = "0123456789ABCDEF";
612	char           *p1, *p2;
613
614	if (!p) {
615		return (False);
616	}
617
618	for (i = 0; i < 42; i += 2) {
619		hinybble = toupper(p[i]);
620		lonybble = toupper(p[i + 1]);
621
622		p1 = strchr(hexchars, hinybble);
623		p2 = strchr(hexchars, lonybble);
624
625		if (!p1 || !p2) {
626			return (False);
627		}
628
629		hinybble = PTR_DIFF(p1, hexchars);
630		lonybble = PTR_DIFF(p2, hexchars);
631
632		hours[i / 2] = (hinybble << 4) | lonybble;
633	}
634	return (True);
635}
636
637int algorithmic_rid_base(void)
638{
639	static int rid_offset = 0;
640
641	if (rid_offset != 0)
642		return rid_offset;
643
644	rid_offset = lp_algorithmic_rid_base();
645
646	if (rid_offset < BASE_RID) {
647		/* Try to prevent admin foot-shooting, we can't put algorithmic
648		   rids below 1000, that's the 'well known RIDs' on NT */
649		DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
650		rid_offset = BASE_RID;
651	}
652	if (rid_offset & 1) {
653		DEBUG(0, ("algorithmic rid base must be even\n"));
654		rid_offset += 1;
655	}
656	return rid_offset;
657}
658
659/*******************************************************************
660 Converts NT user RID to a UNIX uid.
661 ********************************************************************/
662
663uid_t algorithmic_pdb_user_rid_to_uid(uint32 user_rid)
664{
665	int rid_offset = algorithmic_rid_base();
666	return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
667}
668
669/*******************************************************************
670 converts UNIX uid to an NT User RID.
671 ********************************************************************/
672
673uint32 algorithmic_pdb_uid_to_user_rid(uid_t uid)
674{
675	int rid_offset = algorithmic_rid_base();
676	return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
677}
678
679/*******************************************************************
680 Converts NT group RID to a UNIX gid.
681 ********************************************************************/
682
683gid_t pdb_group_rid_to_gid(uint32 group_rid)
684{
685	int rid_offset = algorithmic_rid_base();
686	return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
687}
688
689/*******************************************************************
690 converts NT Group RID to a UNIX uid.
691
692 warning: you must not call that function only
693 you must do a call to the group mapping first.
694 there is not anymore a direct link between the gid and the rid.
695 ********************************************************************/
696
697uint32 pdb_gid_to_group_rid(gid_t gid)
698{
699	int rid_offset = algorithmic_rid_base();
700	return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
701}
702
703/*******************************************************************
704 Decides if a RID is a well known RID.
705 ********************************************************************/
706
707static BOOL pdb_rid_is_well_known(uint32 rid)
708{
709	/* Not using rid_offset here, because this is the actual
710	   NT fixed value (1000) */
711
712	return (rid < BASE_RID);
713}
714
715/*******************************************************************
716 Decides if a RID is a user or group RID.
717 ********************************************************************/
718
719BOOL algorithmic_pdb_rid_is_user(uint32 rid)
720{
721	if(pdb_rid_is_well_known(rid)) {
722		/*
723		 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
724		 * and DOMAIN_USER_RID_GUEST.
725		 */
726		if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
727			return True;
728	} else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
729		return True;
730	}
731	return False;
732}
733
734/*******************************************************************
735 Convert a rid into a name. Used in the lookup SID rpc.
736 ********************************************************************/
737
738BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use)
739{
740	uint32 rid;
741	SAM_ACCOUNT *sam_account = NULL;
742	GROUP_MAP map;
743	BOOL ret;
744
745	if (sid_equal(get_global_sam_sid(), sid)) {
746		*psid_name_use = SID_NAME_DOMAIN;
747		fstrcpy(name, "");
748		DEBUG(5,("local_lookup_sid: SID is our own domain-sid: %s.\n",
749			sid_string_static(sid)));
750		return True;
751	}
752
753	if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){
754		DEBUG(0,("local_lookup_sid: sid_peek_check_rid return False! SID: %s\n",
755			sid_string_static(&map.sid)));
756		return False;
757	}
758	*psid_name_use = SID_NAME_UNKNOWN;
759
760	DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid));
761
762
763	/* see if the passdb can help us with the name of the user */
764	if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
765		return False;
766	}
767
768	/* BEING ROOT BLLOCK */
769	become_root();
770	if (pdb_getsampwsid(sam_account, sid)) {
771		unbecome_root();			/* -----> EXIT BECOME_ROOT() */
772		fstrcpy(name, pdb_get_username(sam_account));
773		*psid_name_use = SID_NAME_USER;
774
775		pdb_free_sam(&sam_account);
776
777		return True;
778	}
779	pdb_free_sam(&sam_account);
780
781	ret = pdb_getgrsid(&map, *sid);
782	unbecome_root();
783	/* END BECOME_ROOT BLOCK */
784
785	if ( ret ) {
786		if (map.gid!=(gid_t)-1) {
787			DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid));
788		} else {
789			DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid.  Returning name.\n", map.nt_name));
790		}
791
792		fstrcpy(name, map.nt_name);
793		*psid_name_use = map.sid_name_use;
794		return True;
795	}
796
797	if (rid == DOMAIN_USER_RID_ADMIN) {
798		*psid_name_use = SID_NAME_USER;
799		fstrcpy(name, "Administrator");
800		return True;
801	}
802
803	if (algorithmic_pdb_rid_is_user(rid)) {
804		uid_t uid;
805		struct passwd *pw = NULL;
806
807		DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
808
809       		uid = algorithmic_pdb_user_rid_to_uid(rid);
810		pw = sys_getpwuid( uid );
811
812		DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid,
813			 pw ? "succeeded" : "failed" ));
814
815		if ( !pw )
816			fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
817		else
818			fstrcpy( name, pw->pw_name );
819
820		DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name,
821			 (unsigned int)rid ));
822
823		*psid_name_use = SID_NAME_USER;
824
825		return ( pw != NULL );
826	} else {
827		gid_t gid;
828		struct group *gr;
829
830		DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid));
831
832		gid = pdb_group_rid_to_gid(rid);
833		gr = getgrgid(gid);
834
835		*psid_name_use = SID_NAME_ALIAS;
836
837		DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid,
838			 gr ? "succeeded" : "failed" ));
839
840		if( !gr )
841			fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
842		else
843			fstrcpy( name, gr->gr_name);
844
845		DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
846			 (unsigned int)rid ));
847
848		/* assume algorithmic groups are domain global groups */
849
850		*psid_name_use = SID_NAME_DOM_GRP;
851
852		return ( gr != NULL );
853	}
854}
855
856/*******************************************************************
857 Convert a name into a SID. Used in the lookup name rpc.
858 ********************************************************************/
859
860BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
861{
862	DOM_SID local_sid;
863	DOM_SID sid;
864	fstring user;
865	SAM_ACCOUNT *sam_account = NULL;
866	struct group *grp;
867	GROUP_MAP map;
868
869	*psid_name_use = SID_NAME_UNKNOWN;
870
871	/*
872	 * user may be quoted a const string, and map_username and
873	 * friends can modify it. Make a modifiable copy. JRA.
874	 */
875
876	fstrcpy(user, c_user);
877
878	sid_copy(&local_sid, get_global_sam_sid());
879
880	if (map_name_to_wellknown_sid(&sid, psid_name_use, user)){
881		fstring sid_str;
882		sid_copy( psid, &sid);
883		sid_to_string(sid_str, &sid);
884		DEBUG(10,("lookup_name: name %s = SID %s, type = %u\n", user, sid_str,
885			(unsigned int)*psid_name_use ));
886		return True;
887	}
888
889	(void)map_username(user);
890
891	if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
892		return False;
893	}
894
895	/* BEGIN ROOT BLOCK */
896
897	become_root();
898	if (pdb_getsampwnam(sam_account, user)) {
899		unbecome_root();
900		sid_copy(psid, pdb_get_user_sid(sam_account));
901		*psid_name_use = SID_NAME_USER;
902
903		pdb_free_sam(&sam_account);
904		return True;
905	}
906
907	pdb_free_sam(&sam_account);
908
909	/*
910	 * Maybe it was a group ?
911	 */
912
913	/* check if it's a mapped group */
914	if (pdb_getgrnam(&map, user)) {
915		/* yes it's a mapped group */
916		sid_copy(&local_sid, &map.sid);
917		*psid_name_use = map.sid_name_use;
918	} else {
919		/* it's not a mapped group */
920		grp = getgrnam(user);
921		if(!grp) {
922			unbecome_root();		/* ---> exit form block */
923			return False;
924		}
925
926		/*
927		 *check if it's mapped, if it is reply it doesn't exist
928		 *
929		 * that's to prevent this case:
930		 *
931		 * unix group ug is mapped to nt group ng
932		 * someone does a lookup on ug
933		 * we must not reply as it doesn't "exist" anymore
934		 * for NT. For NT only ng exists.
935		 * JFM, 30/11/2001
936		 */
937
938		if (pdb_getgrgid(&map, grp->gr_gid)){
939			unbecome_root();		/* ---> exit form block */
940			return False;
941		}
942
943		sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
944		*psid_name_use = SID_NAME_ALIAS;
945	}
946	unbecome_root();
947	/* END ROOT BLOCK */
948
949	sid_copy( psid, &local_sid);
950
951	return True;
952}
953
954/*************************************************************
955 Change a password entry in the local smbpasswd file.
956 *************************************************************/
957
958BOOL local_password_change(const char *user_name, int local_flags,
959			   const char *new_passwd,
960			   char *err_str, size_t err_str_len,
961			   char *msg_str, size_t msg_str_len)
962{
963	SAM_ACCOUNT 	*sam_pass=NULL;
964	uint16 other_acb;
965
966	*err_str = '\0';
967	*msg_str = '\0';
968
969	/* Get the smb passwd entry for this user */
970	pdb_init_sam(&sam_pass);
971
972	become_root();
973	if(!pdb_getsampwnam(sam_pass, user_name)) {
974		unbecome_root();
975		pdb_free_sam(&sam_pass);
976
977		if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
978			/* Might not exist in /etc/passwd.  Use rid algorithm here */
979			if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) {
980				slprintf(err_str, err_str_len-1, "Failed to initialise SAM_ACCOUNT for user %s. Does this user exist in the UNIX password database ?\n", user_name);
981				return False;
982			}
983		} else {
984			slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
985			return False;
986		}
987	} else {
988		unbecome_root();
989		/* the entry already existed */
990		local_flags &= ~LOCAL_ADD_USER;
991	}
992
993	/* the 'other' acb bits not being changed here */
994	other_acb =  (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
995	if (local_flags & LOCAL_TRUST_ACCOUNT) {
996		if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
997			slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
998			pdb_free_sam(&sam_pass);
999			return False;
1000		}
1001	} else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
1002		if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
1003			slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
1004			pdb_free_sam(&sam_pass);
1005			return False;
1006		}
1007	} else {
1008		if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
1009			slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
1010			pdb_free_sam(&sam_pass);
1011			return False;
1012		}
1013	}
1014
1015	/*
1016	 * We are root - just write the new password
1017	 * and the valid last change time.
1018	 */
1019
1020	if (local_flags & LOCAL_DISABLE_USER) {
1021		if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
1022			slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
1023			pdb_free_sam(&sam_pass);
1024			return False;
1025		}
1026	} else if (local_flags & LOCAL_ENABLE_USER) {
1027		if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1028			slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1029			pdb_free_sam(&sam_pass);
1030			return False;
1031		}
1032	}
1033
1034	if (local_flags & LOCAL_SET_NO_PASSWORD) {
1035		if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
1036			slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
1037			pdb_free_sam(&sam_pass);
1038			return False;
1039		}
1040	} else if (local_flags & LOCAL_SET_PASSWORD) {
1041		/*
1042		 * If we're dealing with setting a completely empty user account
1043		 * ie. One with a password of 'XXXX', but not set disabled (like
1044		 * an account created from scratch) then if the old password was
1045		 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
1046		 * We remove that as we're giving this user their first password
1047		 * and the decision hasn't really been made to disable them (ie.
1048		 * don't create them disabled). JRA.
1049		 */
1050		if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
1051			if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1052				slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1053				pdb_free_sam(&sam_pass);
1054				return False;
1055			}
1056		}
1057		if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
1058			slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
1059			pdb_free_sam(&sam_pass);
1060			return False;
1061		}
1062
1063		if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
1064			slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
1065			pdb_free_sam(&sam_pass);
1066			return False;
1067		}
1068	}
1069
1070	if (local_flags & LOCAL_ADD_USER) {
1071		if (pdb_add_sam_account(sam_pass)) {
1072			slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
1073			pdb_free_sam(&sam_pass);
1074			return True;
1075		} else {
1076			slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
1077			pdb_free_sam(&sam_pass);
1078			return False;
1079		}
1080	} else if (local_flags & LOCAL_DELETE_USER) {
1081		if (!pdb_delete_sam_account(sam_pass)) {
1082			slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
1083			pdb_free_sam(&sam_pass);
1084			return False;
1085		}
1086		slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
1087	} else {
1088		if(!pdb_update_sam_account(sam_pass)) {
1089			slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
1090			pdb_free_sam(&sam_pass);
1091			return False;
1092		}
1093		if(local_flags & LOCAL_DISABLE_USER)
1094			slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
1095		else if (local_flags & LOCAL_ENABLE_USER)
1096			slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
1097		else if (local_flags & LOCAL_SET_NO_PASSWORD)
1098			slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
1099	}
1100
1101	pdb_free_sam(&sam_pass);
1102	return True;
1103}
1104
1105/****************************************************************************
1106 Convert a uid to SID - algorithmic.
1107****************************************************************************/
1108
1109DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid)
1110{
1111	if ( !lp_enable_rid_algorithm() )
1112		return NULL;
1113
1114	DEBUG(8,("algorithmic_uid_to_sid: falling back to RID algorithm\n"));
1115	sid_copy( psid, get_global_sam_sid() );
1116	sid_append_rid( psid, algorithmic_pdb_uid_to_user_rid(uid) );
1117	DEBUG(10,("algorithmic_uid_to_sid:  uid (%d) -> SID %s.\n",
1118		(unsigned int)uid, sid_string_static(psid) ));
1119
1120	return psid;
1121}
1122
1123/****************************************************************************
1124 Convert a uid to SID - locally.
1125****************************************************************************/
1126
1127DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
1128{
1129	SAM_ACCOUNT *sampw = NULL;
1130	struct passwd *unix_pw;
1131	BOOL ret;
1132
1133	unix_pw = sys_getpwuid( uid );
1134
1135	if ( !unix_pw ) {
1136		DEBUG(4,("local_uid_to_sid: host has no idea of uid %lu\n", (unsigned long)uid));
1137		return algorithmic_uid_to_sid( psid, uid);
1138	}
1139
1140	if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1141		DEBUG(0,("local_uid_to_sid: failed to allocate SAM_ACCOUNT object\n"));
1142		return NULL;
1143	}
1144
1145	become_root();
1146	ret = pdb_getsampwnam( sampw, unix_pw->pw_name );
1147	unbecome_root();
1148
1149	if ( ret )
1150		sid_copy( psid, pdb_get_user_sid(sampw) );
1151	else {
1152		DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n",
1153			unix_pw->pw_name, (unsigned long)uid));
1154
1155		algorithmic_uid_to_sid( psid, uid);
1156	}
1157
1158	pdb_free_sam(&sampw);
1159
1160	DEBUG(10,("local_uid_to_sid:  uid (%d) -> SID %s (%s).\n",
1161		(unsigned int)uid, sid_string_static(psid), unix_pw->pw_name));
1162
1163	return psid;
1164}
1165
1166/****************************************************************************
1167 Convert a SID to uid - locally.
1168****************************************************************************/
1169
1170BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1171{
1172	SAM_ACCOUNT *sampw = NULL;
1173	struct passwd *unix_pw;
1174	const char *user_name;
1175
1176	*name_type = SID_NAME_UNKNOWN;
1177
1178	/*
1179	 * We can only convert to a uid if this is our local
1180	 * Domain SID (ie. we are the controling authority).
1181	 */
1182	if (!sid_check_is_in_our_domain(psid) ) {
1183		DEBUG(5,("local_sid_to_uid: this SID (%s) is not from our domain\n", sid_string_static(psid)));
1184		return False;
1185	}
1186
1187	/* lookup the user account */
1188
1189	if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1190		DEBUG(0,("local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object\n"));
1191		return False;
1192	}
1193
1194	become_root();
1195	if ( !pdb_getsampwsid(sampw, psid) ) {
1196		unbecome_root();
1197		DEBUG(8,("local_sid_to_uid: Could not find SID %s in passdb\n",
1198			sid_string_static(psid)));
1199		return False;
1200	}
1201	unbecome_root();
1202
1203	user_name = pdb_get_username(sampw);
1204
1205	unix_pw = sys_getpwnam( user_name );
1206
1207	if ( !unix_pw ) {
1208		DEBUG(0,("local_sid_to_uid: %s found in passdb but getpwnam() return NULL!\n",
1209			user_name));
1210		pdb_free_sam( &sampw );
1211		return False;
1212	}
1213
1214	*puid = unix_pw->pw_uid;
1215
1216	DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_string_static(psid),
1217		(unsigned int)*puid, user_name ));
1218
1219	*name_type = SID_NAME_USER;
1220
1221	return True;
1222}
1223
1224/****************************************************************************
1225 Convert a gid to SID - algorithmic.
1226****************************************************************************/
1227
1228DOM_SID *algorithmic_gid_to_sid(DOM_SID *psid, uid_t gid)
1229{
1230	if ( !lp_enable_rid_algorithm() )
1231		return NULL;
1232
1233	DEBUG(8,("algorithmic_gid_to_sid: falling back to RID algorithm\n"));
1234	sid_copy( psid, get_global_sam_sid() );
1235	sid_append_rid( psid, pdb_gid_to_group_rid(gid) );
1236	DEBUG(10,("algorithmic_gid_to_sid:  gid (%d) -> SID %s.\n",
1237		(unsigned int)gid, sid_string_static(psid) ));
1238
1239	return psid;
1240}
1241
1242/****************************************************************************
1243 Convert a gid to SID - locally.
1244****************************************************************************/
1245
1246DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
1247{
1248	GROUP_MAP group;
1249	BOOL ret;
1250
1251	/* we don't need to disable winbindd since the gid is stored in
1252	   the GROUP_MAP object */
1253
1254	/* done as root since ldap backend requires root to open a connection */
1255
1256	become_root();
1257	ret = pdb_getgrgid( &group, gid );
1258	unbecome_root();
1259
1260	if ( !ret ) {
1261
1262		/* algorithmic to rid mapping if enabled */
1263
1264		if ( lp_enable_rid_algorithm() ) {
1265
1266			DEBUG(10,("local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n",
1267				(unsigned int)gid, sid_string_static(psid)));
1268
1269			return algorithmic_gid_to_sid(psid, gid);
1270		}
1271		else
1272			return NULL;
1273	}
1274
1275	sid_copy( psid, &group.sid );
1276
1277	DEBUG(10,("local_gid_to_sid:  gid (%d) -> SID %s.\n",
1278		(unsigned int)gid, sid_string_static(psid)));
1279
1280	return psid;
1281}
1282
1283/****************************************************************************
1284 Convert a SID to gid - locally.
1285****************************************************************************/
1286
1287BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1288{
1289	uint32 rid;
1290	GROUP_MAP group;
1291	BOOL ret;
1292
1293	*name_type = SID_NAME_UNKNOWN;
1294
1295	/* This call can enumerate group mappings for foreign sids as well.
1296	   So don't check for a match against our domain SID */
1297
1298	/* we don't need to disable winbindd since the gid is stored in
1299	   the GROUP_MAP object */
1300
1301	become_root();
1302	ret = pdb_getgrsid(&group, *psid);
1303	unbecome_root();
1304
1305	if ( !ret ) {
1306
1307		/* Fallback to algorithmic rid mapping if enabled */
1308
1309		if ( lp_enable_rid_algorithm() ) {
1310
1311			if (!sid_check_is_in_our_domain(psid) ) {
1312				DEBUG(5,("local_sid_to_gid: RID algorithm only supported for our domain (%s is not)\n", sid_string_static(psid)));
1313				return False;
1314			}
1315
1316			if (!sid_peek_rid(psid, &rid)) {
1317				DEBUG(10,("local_sid_to_gid: invalid SID!\n"));
1318					return False;
1319			}
1320
1321			DEBUG(10,("local_sid_to_gid: Fall back to algorithmic mapping\n"));
1322
1323			if (algorithmic_pdb_rid_is_user(rid)) {
1324				DEBUG(3, ("local_sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(psid)));
1325				return False;
1326			} else {
1327				*pgid = pdb_group_rid_to_gid(rid);
1328				DEBUG(10,("local_sid_to_gid: mapping: %s -> %u\n", sid_string_static(psid), (unsigned int)(*pgid)));
1329				return True;
1330			}
1331		}
1332
1333		return False;
1334	}
1335
1336	*pgid = group.gid;
1337	*name_type = group.sid_name_use;
1338
1339	DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u)\n", sid_string_static(psid),
1340		(unsigned int)*pgid));
1341
1342	return True;
1343}
1344
1345/**********************************************************************
1346 Marshall/unmarshall SAM_ACCOUNT structs.
1347 *********************************************************************/
1348
1349#define TDB_FORMAT_STRING_V0       "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
1350#define TDB_FORMAT_STRING_V1       "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
1351#define TDB_FORMAT_STRING_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
1352
1353/**********************************************************************
1354 Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
1355 *********************************************************************/
1356
1357BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1358{
1359	return(init_sam_from_buffer_v2(sampass, buf, buflen));
1360}
1361
1362/**********************************************************************
1363 Intialize a BYTE buffer from a SAM_ACCOUNT struct
1364 *********************************************************************/
1365
1366uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1367{
1368	return(init_buffer_from_sam_v2(buf, sampass, size_only));
1369}
1370
1371
1372BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1373{
1374
1375	/* times are stored as 32bit integer
1376	   take care on system with 64bit wide time_t
1377	   --SSS */
1378	uint32	logon_time,
1379		logoff_time,
1380		kickoff_time,
1381		pass_last_set_time,
1382		pass_can_change_time,
1383		pass_must_change_time;
1384	char *username = NULL;
1385	char *domain = NULL;
1386	char *nt_username = NULL;
1387	char *dir_drive = NULL;
1388	char *unknown_str = NULL;
1389	char *munged_dial = NULL;
1390	char *fullname = NULL;
1391	char *homedir = NULL;
1392	char *logon_script = NULL;
1393	char *profile_path = NULL;
1394	char *acct_desc = NULL;
1395	char *workstations = NULL;
1396	uint32	username_len, domain_len, nt_username_len,
1397		dir_drive_len, unknown_str_len, munged_dial_len,
1398		fullname_len, homedir_len, logon_script_len,
1399		profile_path_len, acct_desc_len, workstations_len;
1400
1401	uint32	user_rid, group_rid, remove_me, hours_len, unknown_6;
1402	uint16	acct_ctrl, logon_divs;
1403	uint16	bad_password_count, logon_count;
1404	uint8	*hours = NULL;
1405	uint8	*lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1406	uint32		len = 0;
1407	uint32		lm_pw_len, nt_pw_len, hourslen;
1408	BOOL ret = True;
1409
1410	if(sampass == NULL || buf == NULL) {
1411		DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
1412		return False;
1413	}
1414
1415/* TDB_FORMAT_STRING_V0       "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1416
1417	/* unpack the buffer into variables */
1418	len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
1419		&logon_time,						/* d */
1420		&logoff_time,						/* d */
1421		&kickoff_time,						/* d */
1422		&pass_last_set_time,					/* d */
1423		&pass_can_change_time,					/* d */
1424		&pass_must_change_time,					/* d */
1425		&username_len, &username,				/* B */
1426		&domain_len, &domain,					/* B */
1427		&nt_username_len, &nt_username,				/* B */
1428		&fullname_len, &fullname,				/* B */
1429		&homedir_len, &homedir,					/* B */
1430		&dir_drive_len, &dir_drive,				/* B */
1431		&logon_script_len, &logon_script,			/* B */
1432		&profile_path_len, &profile_path,			/* B */
1433		&acct_desc_len, &acct_desc,				/* B */
1434		&workstations_len, &workstations,			/* B */
1435		&unknown_str_len, &unknown_str,				/* B */
1436		&munged_dial_len, &munged_dial,				/* B */
1437		&user_rid,						/* d */
1438		&group_rid,						/* d */
1439		&lm_pw_len, &lm_pw_ptr,					/* B */
1440		&nt_pw_len, &nt_pw_ptr,					/* B */
1441		&acct_ctrl,						/* w */
1442		&remove_me, /* remove on the next TDB_FORMAT upgarde */	/* d */
1443		&logon_divs,						/* w */
1444		&hours_len,						/* d */
1445		&hourslen, &hours,					/* B */
1446		&bad_password_count,					/* w */
1447		&logon_count,						/* w */
1448		&unknown_6);						/* d */
1449
1450	if (len == (uint32) -1)  {
1451		ret = False;
1452		goto done;
1453	}
1454
1455	pdb_set_logon_time(sampass, logon_time, PDB_SET);
1456	pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1457	pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1458	pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1459	pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1460	pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1461
1462	pdb_set_username(sampass, username, PDB_SET);
1463	pdb_set_domain(sampass, domain, PDB_SET);
1464	pdb_set_nt_username(sampass, nt_username, PDB_SET);
1465	pdb_set_fullname(sampass, fullname, PDB_SET);
1466
1467	if (homedir) {
1468		pdb_set_homedir(sampass, homedir, PDB_SET);
1469	}
1470	else {
1471		pdb_set_homedir(sampass,
1472			talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1473			PDB_DEFAULT);
1474	}
1475
1476	if (dir_drive)
1477		pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1478	else {
1479		pdb_set_dir_drive(sampass,
1480			talloc_sub_basic(sampass->mem_ctx,  username, lp_logon_drive()),
1481			PDB_DEFAULT);
1482	}
1483
1484	if (logon_script)
1485		pdb_set_logon_script(sampass, logon_script, PDB_SET);
1486	else {
1487		pdb_set_logon_script(sampass,
1488			talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1489			PDB_DEFAULT);
1490	}
1491
1492	if (profile_path) {
1493		pdb_set_profile_path(sampass, profile_path, PDB_SET);
1494	} else {
1495		pdb_set_profile_path(sampass,
1496			talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1497			PDB_DEFAULT);
1498	}
1499
1500	pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1501	pdb_set_workstations(sampass, workstations, PDB_SET);
1502	pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1503
1504	if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1505		if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1506			ret = False;
1507			goto done;
1508		}
1509	}
1510
1511	if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1512		if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1513			ret = False;
1514			goto done;
1515		}
1516	}
1517
1518	pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1519	pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1520	pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1521	pdb_set_hours_len(sampass, hours_len, PDB_SET);
1522	pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1523	pdb_set_logon_count(sampass, logon_count, PDB_SET);
1524	pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1525	pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1526	pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1527	pdb_set_hours(sampass, hours, PDB_SET);
1528
1529done:
1530
1531	SAFE_FREE(username);
1532	SAFE_FREE(domain);
1533	SAFE_FREE(nt_username);
1534	SAFE_FREE(fullname);
1535	SAFE_FREE(homedir);
1536	SAFE_FREE(dir_drive);
1537	SAFE_FREE(logon_script);
1538	SAFE_FREE(profile_path);
1539	SAFE_FREE(acct_desc);
1540	SAFE_FREE(workstations);
1541	SAFE_FREE(munged_dial);
1542	SAFE_FREE(unknown_str);
1543	SAFE_FREE(lm_pw_ptr);
1544	SAFE_FREE(nt_pw_ptr);
1545	SAFE_FREE(hours);
1546
1547	return ret;
1548}
1549
1550BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1551{
1552
1553	/* times are stored as 32bit integer
1554	   take care on system with 64bit wide time_t
1555	   --SSS */
1556	uint32	logon_time,
1557		logoff_time,
1558		kickoff_time,
1559		bad_password_time,
1560		pass_last_set_time,
1561		pass_can_change_time,
1562		pass_must_change_time;
1563	char *username = NULL;
1564	char *domain = NULL;
1565	char *nt_username = NULL;
1566	char *dir_drive = NULL;
1567	char *unknown_str = NULL;
1568	char *munged_dial = NULL;
1569	char *fullname = NULL;
1570	char *homedir = NULL;
1571	char *logon_script = NULL;
1572	char *profile_path = NULL;
1573	char *acct_desc = NULL;
1574	char *workstations = NULL;
1575	uint32	username_len, domain_len, nt_username_len,
1576		dir_drive_len, unknown_str_len, munged_dial_len,
1577		fullname_len, homedir_len, logon_script_len,
1578		profile_path_len, acct_desc_len, workstations_len;
1579
1580	uint32	user_rid, group_rid, remove_me, hours_len, unknown_6;
1581	uint16	acct_ctrl, logon_divs;
1582	uint16	bad_password_count, logon_count;
1583	uint8	*hours = NULL;
1584	uint8	*lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1585	uint32		len = 0;
1586	uint32		lm_pw_len, nt_pw_len, hourslen;
1587	BOOL ret = True;
1588
1589	if(sampass == NULL || buf == NULL) {
1590		DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
1591		return False;
1592	}
1593
1594/* TDB_FORMAT_STRING_V1       "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1595
1596	/* unpack the buffer into variables */
1597	len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
1598		&logon_time,						/* d */
1599		&logoff_time,						/* d */
1600		&kickoff_time,						/* d */
1601		/* Change from V0 is addition of bad_password_time field. */
1602		&bad_password_time,					/* d */
1603		&pass_last_set_time,					/* d */
1604		&pass_can_change_time,					/* d */
1605		&pass_must_change_time,					/* d */
1606		&username_len, &username,				/* B */
1607		&domain_len, &domain,					/* B */
1608		&nt_username_len, &nt_username,				/* B */
1609		&fullname_len, &fullname,				/* B */
1610		&homedir_len, &homedir,					/* B */
1611		&dir_drive_len, &dir_drive,				/* B */
1612		&logon_script_len, &logon_script,			/* B */
1613		&profile_path_len, &profile_path,			/* B */
1614		&acct_desc_len, &acct_desc,				/* B */
1615		&workstations_len, &workstations,			/* B */
1616		&unknown_str_len, &unknown_str,				/* B */
1617		&munged_dial_len, &munged_dial,				/* B */
1618		&user_rid,						/* d */
1619		&group_rid,						/* d */
1620		&lm_pw_len, &lm_pw_ptr,					/* B */
1621		&nt_pw_len, &nt_pw_ptr,					/* B */
1622		&acct_ctrl,						/* w */
1623		&remove_me,						/* d */
1624		&logon_divs,						/* w */
1625		&hours_len,						/* d */
1626		&hourslen, &hours,					/* B */
1627		&bad_password_count,					/* w */
1628		&logon_count,						/* w */
1629		&unknown_6);						/* d */
1630
1631	if (len == (uint32) -1)  {
1632		ret = False;
1633		goto done;
1634	}
1635
1636	pdb_set_logon_time(sampass, logon_time, PDB_SET);
1637	pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1638	pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1639
1640	/* Change from V0 is addition of bad_password_time field. */
1641	pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1642	pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1643	pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1644	pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1645
1646	pdb_set_username(sampass, username, PDB_SET);
1647	pdb_set_domain(sampass, domain, PDB_SET);
1648	pdb_set_nt_username(sampass, nt_username, PDB_SET);
1649	pdb_set_fullname(sampass, fullname, PDB_SET);
1650
1651	if (homedir) {
1652		pdb_set_homedir(sampass, homedir, PDB_SET);
1653	}
1654	else {
1655		pdb_set_homedir(sampass,
1656			talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1657			PDB_DEFAULT);
1658	}
1659
1660	if (dir_drive)
1661		pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1662	else {
1663		pdb_set_dir_drive(sampass,
1664			talloc_sub_basic(sampass->mem_ctx,  username, lp_logon_drive()),
1665			PDB_DEFAULT);
1666	}
1667
1668	if (logon_script)
1669		pdb_set_logon_script(sampass, logon_script, PDB_SET);
1670	else {
1671		pdb_set_logon_script(sampass,
1672			talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1673			PDB_DEFAULT);
1674	}
1675
1676	if (profile_path) {
1677		pdb_set_profile_path(sampass, profile_path, PDB_SET);
1678	} else {
1679		pdb_set_profile_path(sampass,
1680			talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1681			PDB_DEFAULT);
1682	}
1683
1684	pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1685	pdb_set_workstations(sampass, workstations, PDB_SET);
1686	pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1687
1688	if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1689		if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1690			ret = False;
1691			goto done;
1692		}
1693	}
1694
1695	if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1696		if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1697			ret = False;
1698			goto done;
1699		}
1700	}
1701
1702	pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1703
1704	pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1705	pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1706	pdb_set_hours_len(sampass, hours_len, PDB_SET);
1707	pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1708	pdb_set_logon_count(sampass, logon_count, PDB_SET);
1709	pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1710	pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1711	pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1712	pdb_set_hours(sampass, hours, PDB_SET);
1713
1714done:
1715
1716	SAFE_FREE(username);
1717	SAFE_FREE(domain);
1718	SAFE_FREE(nt_username);
1719	SAFE_FREE(fullname);
1720	SAFE_FREE(homedir);
1721	SAFE_FREE(dir_drive);
1722	SAFE_FREE(logon_script);
1723	SAFE_FREE(profile_path);
1724	SAFE_FREE(acct_desc);
1725	SAFE_FREE(workstations);
1726	SAFE_FREE(munged_dial);
1727	SAFE_FREE(unknown_str);
1728	SAFE_FREE(lm_pw_ptr);
1729	SAFE_FREE(nt_pw_ptr);
1730	SAFE_FREE(hours);
1731
1732	return ret;
1733}
1734
1735
1736BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1737{
1738
1739	/* times are stored as 32bit integer
1740	   take care on system with 64bit wide time_t
1741	   --SSS */
1742	uint32	logon_time,
1743		logoff_time,
1744		kickoff_time,
1745		bad_password_time,
1746		pass_last_set_time,
1747		pass_can_change_time,
1748		pass_must_change_time;
1749	char *username = NULL;
1750	char *domain = NULL;
1751	char *nt_username = NULL;
1752	char *dir_drive = NULL;
1753	char *unknown_str = NULL;
1754	char *munged_dial = NULL;
1755	char *fullname = NULL;
1756	char *homedir = NULL;
1757	char *logon_script = NULL;
1758	char *profile_path = NULL;
1759	char *acct_desc = NULL;
1760	char *workstations = NULL;
1761	uint32	username_len, domain_len, nt_username_len,
1762		dir_drive_len, unknown_str_len, munged_dial_len,
1763		fullname_len, homedir_len, logon_script_len,
1764		profile_path_len, acct_desc_len, workstations_len;
1765
1766	uint32	user_rid, group_rid, hours_len, unknown_6;
1767	uint16	acct_ctrl, logon_divs;
1768	uint16	bad_password_count, logon_count;
1769	uint8	*hours = NULL;
1770	uint8	*lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1771	uint32		len = 0;
1772	uint32		lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1773	uint32 pwHistLen = 0;
1774	BOOL ret = True;
1775	fstring tmpstring;
1776
1777	if(sampass == NULL || buf == NULL) {
1778		DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
1779		return False;
1780	}
1781
1782/* TDB_FORMAT_STRING_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1783
1784	/* unpack the buffer into variables */
1785	len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
1786		&logon_time,						/* d */
1787		&logoff_time,						/* d */
1788		&kickoff_time,						/* d */
1789		&bad_password_time,					/* d */
1790		&pass_last_set_time,					/* d */
1791		&pass_can_change_time,					/* d */
1792		&pass_must_change_time,					/* d */
1793		&username_len, &username,				/* B */
1794		&domain_len, &domain,					/* B */
1795		&nt_username_len, &nt_username,				/* B */
1796		&fullname_len, &fullname,				/* B */
1797		&homedir_len, &homedir,					/* B */
1798		&dir_drive_len, &dir_drive,				/* B */
1799		&logon_script_len, &logon_script,			/* B */
1800		&profile_path_len, &profile_path,			/* B */
1801		&acct_desc_len, &acct_desc,				/* B */
1802		&workstations_len, &workstations,			/* B */
1803		&unknown_str_len, &unknown_str,				/* B */
1804		&munged_dial_len, &munged_dial,				/* B */
1805		&user_rid,						/* d */
1806		&group_rid,						/* d */
1807		&lm_pw_len, &lm_pw_ptr,					/* B */
1808		&nt_pw_len, &nt_pw_ptr,					/* B */
1809		/* Change from V1 is addition of password history field. */
1810		&nt_pw_hist_len, &nt_pw_hist_ptr,			/* B */
1811		&acct_ctrl,						/* w */
1812		/* Also "remove_me" field was removed. */
1813		&logon_divs,						/* w */
1814		&hours_len,						/* d */
1815		&hourslen, &hours,					/* B */
1816		&bad_password_count,					/* w */
1817		&logon_count,						/* w */
1818		&unknown_6);						/* d */
1819
1820	if (len == (uint32) -1)  {
1821		ret = False;
1822		goto done;
1823	}
1824
1825	pdb_set_logon_time(sampass, logon_time, PDB_SET);
1826	pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1827	pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1828	pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1829	pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1830	pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1831	pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1832
1833	pdb_set_username(sampass, username, PDB_SET);
1834	pdb_set_domain(sampass, domain, PDB_SET);
1835	pdb_set_nt_username(sampass, nt_username, PDB_SET);
1836	pdb_set_fullname(sampass, fullname, PDB_SET);
1837
1838	if (homedir) {
1839		fstrcpy( tmpstring, homedir );
1840		standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1841		pdb_set_homedir(sampass, tmpstring, PDB_SET);
1842	}
1843	else {
1844		pdb_set_homedir(sampass,
1845			talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1846			PDB_DEFAULT);
1847	}
1848
1849	if (dir_drive)
1850		pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1851	else
1852		pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1853
1854	if (logon_script) {
1855		fstrcpy( tmpstring, logon_script );
1856		standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1857		pdb_set_logon_script(sampass, tmpstring, PDB_SET);
1858	}
1859	else {
1860		pdb_set_logon_script(sampass,
1861			talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1862			PDB_DEFAULT);
1863	}
1864
1865	if (profile_path) {
1866		fstrcpy( tmpstring, profile_path );
1867		standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1868		pdb_set_profile_path(sampass, tmpstring, PDB_SET);
1869	}
1870	else {
1871		pdb_set_profile_path(sampass,
1872			talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1873			PDB_DEFAULT);
1874	}
1875
1876	pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1877	pdb_set_workstations(sampass, workstations, PDB_SET);
1878	pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1879
1880	if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1881		if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1882			ret = False;
1883			goto done;
1884		}
1885	}
1886
1887	if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1888		if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1889			ret = False;
1890			goto done;
1891		}
1892	}
1893
1894	/* Change from V1 is addition of password history field. */
1895	account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
1896	if (pwHistLen) {
1897		char *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1898		if (!pw_hist) {
1899			ret = False;
1900			goto done;
1901		}
1902		memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1903		if (nt_pw_hist_ptr && nt_pw_hist_len) {
1904			int i;
1905			SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1906			nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1907			for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1908				memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1909					&nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1910					PW_HISTORY_ENTRY_LEN);
1911			}
1912		}
1913		if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1914			SAFE_FREE(pw_hist);
1915			ret = False;
1916			goto done;
1917		}
1918		SAFE_FREE(pw_hist);
1919	} else {
1920		pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1921	}
1922
1923	pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1924	pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1925	pdb_set_hours_len(sampass, hours_len, PDB_SET);
1926	pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1927	pdb_set_logon_count(sampass, logon_count, PDB_SET);
1928	pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1929	pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1930	pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1931	pdb_set_hours(sampass, hours, PDB_SET);
1932
1933done:
1934
1935	SAFE_FREE(username);
1936	SAFE_FREE(domain);
1937	SAFE_FREE(nt_username);
1938	SAFE_FREE(fullname);
1939	SAFE_FREE(homedir);
1940	SAFE_FREE(dir_drive);
1941	SAFE_FREE(logon_script);
1942	SAFE_FREE(profile_path);
1943	SAFE_FREE(acct_desc);
1944	SAFE_FREE(workstations);
1945	SAFE_FREE(munged_dial);
1946	SAFE_FREE(unknown_str);
1947	SAFE_FREE(lm_pw_ptr);
1948	SAFE_FREE(nt_pw_ptr);
1949	SAFE_FREE(nt_pw_hist_ptr);
1950	SAFE_FREE(hours);
1951
1952	return ret;
1953}
1954
1955uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1956{
1957	size_t len, buflen;
1958
1959	/* times are stored as 32bit integer
1960	   take care on system with 64bit wide time_t
1961	   --SSS */
1962	uint32	logon_time,
1963		logoff_time,
1964		kickoff_time,
1965		bad_password_time,
1966		pass_last_set_time,
1967		pass_can_change_time,
1968		pass_must_change_time;
1969
1970	uint32  user_rid, group_rid;
1971
1972	const char *username;
1973	const char *domain;
1974	const char *nt_username;
1975	const char *dir_drive;
1976	const char *unknown_str;
1977	const char *munged_dial;
1978	const char *fullname;
1979	const char *homedir;
1980	const char *logon_script;
1981	const char *profile_path;
1982	const char *acct_desc;
1983	const char *workstations;
1984	uint32	username_len, domain_len, nt_username_len,
1985		dir_drive_len, unknown_str_len, munged_dial_len,
1986		fullname_len, homedir_len, logon_script_len,
1987		profile_path_len, acct_desc_len, workstations_len;
1988
1989	const uint8 *lm_pw;
1990	const uint8 *nt_pw;
1991	const uint8 *nt_pw_hist;
1992	uint32	lm_pw_len = 16;
1993	uint32	nt_pw_len = 16;
1994	uint32  nt_pw_hist_len;
1995	uint32 pwHistLen = 0;
1996
1997	/* do we have a valid SAM_ACCOUNT pointer? */
1998	if (sampass == NULL) {
1999		DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
2000		return -1;
2001	}
2002
2003	*buf = NULL;
2004	buflen = 0;
2005
2006	logon_time = (uint32)pdb_get_logon_time(sampass);
2007	logoff_time = (uint32)pdb_get_logoff_time(sampass);
2008	kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
2009	bad_password_time = (uint32)pdb_get_bad_password_time(sampass);
2010	pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
2011	pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
2012	pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
2013
2014	user_rid = pdb_get_user_rid(sampass);
2015	group_rid = pdb_get_group_rid(sampass);
2016
2017	username = pdb_get_username(sampass);
2018	if (username) {
2019		username_len = strlen(username) +1;
2020	} else {
2021		username_len = 0;
2022	}
2023
2024	domain = pdb_get_domain(sampass);
2025	if (domain) {
2026		domain_len = strlen(domain) +1;
2027	} else {
2028		domain_len = 0;
2029	}
2030
2031	nt_username = pdb_get_nt_username(sampass);
2032	if (nt_username) {
2033		nt_username_len = strlen(nt_username) +1;
2034	} else {
2035		nt_username_len = 0;
2036	}
2037
2038	fullname = pdb_get_fullname(sampass);
2039	if (fullname) {
2040		fullname_len = strlen(fullname) +1;
2041	} else {
2042		fullname_len = 0;
2043	}
2044
2045	/*
2046	 * Only updates fields which have been set (not defaults from smb.conf)
2047	 */
2048
2049	if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
2050		dir_drive = pdb_get_dir_drive(sampass);
2051	} else {
2052		dir_drive = NULL;
2053	}
2054	if (dir_drive) {
2055		dir_drive_len = strlen(dir_drive) +1;
2056	} else {
2057		dir_drive_len = 0;
2058	}
2059
2060	if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
2061		homedir = pdb_get_homedir(sampass);
2062	} else {
2063		homedir = NULL;
2064	}
2065	if (homedir) {
2066		homedir_len = strlen(homedir) +1;
2067	} else {
2068		homedir_len = 0;
2069	}
2070
2071	if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
2072		logon_script = pdb_get_logon_script(sampass);
2073	} else {
2074		logon_script = NULL;
2075	}
2076	if (logon_script) {
2077		logon_script_len = strlen(logon_script) +1;
2078	} else {
2079		logon_script_len = 0;
2080	}
2081
2082	if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
2083		profile_path = pdb_get_profile_path(sampass);
2084	} else {
2085		profile_path = NULL;
2086	}
2087	if (profile_path) {
2088		profile_path_len = strlen(profile_path) +1;
2089	} else {
2090		profile_path_len = 0;
2091	}
2092
2093	lm_pw = pdb_get_lanman_passwd(sampass);
2094	if (!lm_pw) {
2095		lm_pw_len = 0;
2096	}
2097
2098	nt_pw = pdb_get_nt_passwd(sampass);
2099	if (!nt_pw) {
2100		nt_pw_len = 0;
2101	}
2102
2103	account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
2104	nt_pw_hist =  pdb_get_pw_history(sampass, &nt_pw_hist_len);
2105	if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
2106		nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
2107	} else {
2108		nt_pw_hist_len = 0;
2109	}
2110
2111	acct_desc = pdb_get_acct_desc(sampass);
2112	if (acct_desc) {
2113		acct_desc_len = strlen(acct_desc) +1;
2114	} else {
2115		acct_desc_len = 0;
2116	}
2117
2118	workstations = pdb_get_workstations(sampass);
2119	if (workstations) {
2120		workstations_len = strlen(workstations) +1;
2121	} else {
2122		workstations_len = 0;
2123	}
2124
2125	unknown_str = NULL;
2126	unknown_str_len = 0;
2127
2128	munged_dial = pdb_get_munged_dial(sampass);
2129	if (munged_dial) {
2130		munged_dial_len = strlen(munged_dial) +1;
2131	} else {
2132		munged_dial_len = 0;
2133	}
2134
2135/* TDB_FORMAT_STRING_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
2136
2137	/* one time to get the size needed */
2138	len = tdb_pack(NULL, 0,  TDB_FORMAT_STRING_V2,
2139		logon_time,				/* d */
2140		logoff_time,				/* d */
2141		kickoff_time,				/* d */
2142		bad_password_time,			/* d */
2143		pass_last_set_time,			/* d */
2144		pass_can_change_time,			/* d */
2145		pass_must_change_time,			/* d */
2146		username_len, username,			/* B */
2147		domain_len, domain,			/* B */
2148		nt_username_len, nt_username,		/* B */
2149		fullname_len, fullname,			/* B */
2150		homedir_len, homedir,			/* B */
2151		dir_drive_len, dir_drive,		/* B */
2152		logon_script_len, logon_script,		/* B */
2153		profile_path_len, profile_path,		/* B */
2154		acct_desc_len, acct_desc,		/* B */
2155		workstations_len, workstations,		/* B */
2156		unknown_str_len, unknown_str,		/* B */
2157		munged_dial_len, munged_dial,		/* B */
2158		user_rid,				/* d */
2159		group_rid,				/* d */
2160		lm_pw_len, lm_pw,			/* B */
2161		nt_pw_len, nt_pw,			/* B */
2162		nt_pw_hist_len, nt_pw_hist,		/* B */
2163		pdb_get_acct_ctrl(sampass),		/* w */
2164		pdb_get_logon_divs(sampass),		/* w */
2165		pdb_get_hours_len(sampass),		/* d */
2166		MAX_HOURS_LEN, pdb_get_hours(sampass),	/* B */
2167		pdb_get_bad_password_count(sampass),	/* w */
2168		pdb_get_logon_count(sampass),		/* w */
2169		pdb_get_unknown_6(sampass));		/* d */
2170
2171	if (size_only) {
2172		return buflen;
2173	}
2174
2175	/* malloc the space needed */
2176	if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
2177		DEBUG(0,("init_buffer_from_sam_v2: Unable to malloc() memory for buffer!\n"));
2178		return (-1);
2179	}
2180
2181	/* now for the real call to tdb_pack() */
2182	buflen = tdb_pack((char *)*buf, len,  TDB_FORMAT_STRING_V2,
2183		logon_time,				/* d */
2184		logoff_time,				/* d */
2185		kickoff_time,				/* d */
2186		bad_password_time,			/* d */
2187		pass_last_set_time,			/* d */
2188		pass_can_change_time,			/* d */
2189		pass_must_change_time,			/* d */
2190		username_len, username,			/* B */
2191		domain_len, domain,			/* B */
2192		nt_username_len, nt_username,		/* B */
2193		fullname_len, fullname,			/* B */
2194		homedir_len, homedir,			/* B */
2195		dir_drive_len, dir_drive,		/* B */
2196		logon_script_len, logon_script,		/* B */
2197		profile_path_len, profile_path,		/* B */
2198		acct_desc_len, acct_desc,		/* B */
2199		workstations_len, workstations,		/* B */
2200		unknown_str_len, unknown_str,		/* B */
2201		munged_dial_len, munged_dial,		/* B */
2202		user_rid,				/* d */
2203		group_rid,				/* d */
2204		lm_pw_len, lm_pw,			/* B */
2205		nt_pw_len, nt_pw,			/* B */
2206		nt_pw_hist_len, nt_pw_hist,		/* B */
2207		pdb_get_acct_ctrl(sampass),		/* w */
2208		pdb_get_logon_divs(sampass),		/* w */
2209		pdb_get_hours_len(sampass),		/* d */
2210		MAX_HOURS_LEN, pdb_get_hours(sampass),	/* B */
2211		pdb_get_bad_password_count(sampass),	/* w */
2212		pdb_get_logon_count(sampass),		/* w */
2213		pdb_get_unknown_6(sampass));		/* d */
2214
2215	/* check to make sure we got it correct */
2216	if (buflen != len) {
2217		DEBUG(0, ("init_buffer_from_sam_v2: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2218			  (unsigned long)buflen, (unsigned long)len));
2219		/* error */
2220		SAFE_FREE (*buf);
2221		return (-1);
2222	}
2223
2224	return (buflen);
2225}
2226
2227BOOL pdb_copy_sam_account(const SAM_ACCOUNT *src, SAM_ACCOUNT **dst)
2228{
2229	BOOL result;
2230	uint8 *buf;
2231	int len;
2232
2233	if ((*dst == NULL) && (!NT_STATUS_IS_OK(pdb_init_sam(dst))))
2234		return False;
2235
2236	len = init_buffer_from_sam_v2(&buf, src, False);
2237
2238	if (len == -1)
2239		return False;
2240
2241	result = init_sam_from_buffer_v2(*dst, buf, len);
2242	(*dst)->methods = src->methods;
2243
2244	free(buf);
2245
2246	return result;
2247}
2248
2249/**********************************************************************
2250**********************************************************************/
2251
2252static BOOL get_free_ugid_range(uint32 *low, uint32 *high)
2253{
2254	uid_t u_low, u_high;
2255	gid_t g_low, g_high;
2256
2257	if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
2258		return False;
2259	}
2260
2261	*low  = (u_low < g_low)   ? u_low  : g_low;
2262	*high = (u_high < g_high) ? u_high : g_high;
2263
2264	return True;
2265}
2266
2267/******************************************************************
2268 Get the the non-algorithmic RID range if idmap range are defined
2269******************************************************************/
2270
2271BOOL get_free_rid_range(uint32 *low, uint32 *high)
2272{
2273	uint32 id_low, id_high;
2274
2275	if (!lp_enable_rid_algorithm()) {
2276		*low = BASE_RID;
2277		*high = (uint32)-1;
2278	}
2279
2280	if (!get_free_ugid_range(&id_low, &id_high)) {
2281		return False;
2282	}
2283
2284	*low = algorithmic_pdb_uid_to_user_rid(id_low);
2285	if (algorithmic_pdb_user_rid_to_uid((uint32)-1) < id_high) {
2286		*high = (uint32)-1;
2287	} else {
2288		*high = algorithmic_pdb_uid_to_user_rid(id_high);
2289	}
2290
2291	return True;
2292}
2293
2294/*********************************************************************
2295 Update the bad password count checking the AP_RESET_COUNT_TIME
2296*********************************************************************/
2297
2298BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
2299{
2300	time_t LastBadPassword;
2301	uint16 BadPasswordCount;
2302	uint32 resettime;
2303
2304	if (!sampass) return False;
2305
2306	BadPasswordCount = pdb_get_bad_password_count(sampass);
2307	if (!BadPasswordCount) {
2308		DEBUG(9, ("No bad password attempts.\n"));
2309		return True;
2310	}
2311
2312	if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) {
2313		DEBUG(0, ("pdb_update_bad_password_count: account_policy_get failed.\n"));
2314		return False;
2315	}
2316
2317	/* First, check if there is a reset time to compare */
2318	if ((resettime == (uint32) -1) || (resettime == 0)) {
2319		DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2320		return True;
2321	}
2322
2323	LastBadPassword = pdb_get_bad_password_time(sampass);
2324	DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2325		   (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
2326	if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
2327		pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2328		pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2329		if (updated) {
2330			*updated = True;
2331		}
2332	}
2333
2334	return True;
2335}
2336
2337/*********************************************************************
2338 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
2339*********************************************************************/
2340
2341BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
2342{
2343	uint32 duration;
2344	time_t LastBadPassword;
2345
2346	if (!sampass) return False;
2347
2348	if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2349		DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2350			pdb_get_username(sampass)));
2351		return True;
2352	}
2353
2354	if (!account_policy_get(AP_LOCK_ACCOUNT_DURATION, &duration)) {
2355		DEBUG(0, ("pdb_update_autolock_flag: account_policy_get failed.\n"));
2356		return False;
2357	}
2358
2359	/* First, check if there is a duration to compare */
2360	if ((duration == (uint32) -1)  || (duration == 0)) {
2361		DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2362		return True;
2363	}
2364
2365	LastBadPassword = pdb_get_bad_password_time(sampass);
2366	DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2367		  pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
2368
2369	if (LastBadPassword == (time_t)0) {
2370		DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
2371bad password time. Leaving locked out.\n",
2372			pdb_get_username(sampass) ));
2373			return True;
2374	}
2375
2376	if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
2377		pdb_set_acct_ctrl(sampass,
2378				  pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2379				  PDB_CHANGED);
2380		pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2381		pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2382		if (updated) {
2383			*updated = True;
2384		}
2385	}
2386
2387	return True;
2388}
2389
2390/*********************************************************************
2391 Increment the bad_password_count
2392*********************************************************************/
2393
2394BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
2395{
2396	uint32 account_policy_lockout;
2397	BOOL autolock_updated = False, badpw_updated = False;
2398
2399	if (!sampass)
2400		return False;
2401
2402	/* Retrieve the account lockout policy */
2403	if (!account_policy_get(AP_BAD_ATTEMPT_LOCKOUT,
2404				&account_policy_lockout)) {
2405		DEBUG(0, ("pdb_increment_bad_password_count: account_policy_get failed.\n"));
2406		return False;
2407	}
2408
2409	/* If there is no policy, we don't need to continue checking */
2410	if (!account_policy_lockout) {
2411		DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2412		return True;
2413	}
2414
2415	/* Check if the autolock needs to be cleared */
2416	if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2417		return False;
2418
2419	/* Check if the badpw count needs to be reset */
2420	if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2421		return False;
2422
2423	/*
2424	  Ok, now we can assume that any resetting that needs to be
2425	  done has been done, and just get on with incrementing
2426	  and autolocking if necessary
2427	*/
2428
2429	pdb_set_bad_password_count(sampass,
2430				   pdb_get_bad_password_count(sampass)+1,
2431				   PDB_CHANGED);
2432	pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2433
2434
2435	if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2436		return True;
2437
2438	if (!pdb_set_acct_ctrl(sampass,
2439			       pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2440			       PDB_CHANGED)) {
2441		DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2442		return False;
2443	}
2444
2445	return True;
2446}
2447