• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source3/lib/
1/*
2 *  Unix SMB/CIFS implementation.
3 *  account policy storage
4 *  Copyright (C) Jean Fran�ois Micouleau      1998-2001.
5 *  Copyright (C) Andrew Bartlett              2002
6 *  Copyright (C) Guenther Deschner            2004-2005
7 *
8 *  This program is free software; you can redistribute it and/or modify
9 *  it under the terms of the GNU General Public License as published by
10 *  the Free Software Foundation; either version 3 of the License, or
11 *  (at your option) any later version.
12 *
13 *  This program is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *  GNU General Public License for more details.
17 *
18 *  You should have received a copy of the GNU General Public License
19 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "includes.h"
23static struct db_context *db;
24
25/* cache all entries for 60 seconds for to save ldap-queries (cache is updated
26 * after this period if admins do not use pdbedit or usermanager but manipulate
27 * ldap directly) - gd */
28
29#define DATABASE_VERSION 	3
30#define AP_TTL			60
31
32
33struct ap_table {
34	enum pdb_policy_type type;
35	const char *string;
36	uint32 default_val;
37	const char *description;
38	const char *ldap_attr;
39};
40
41static const struct ap_table account_policy_names[] = {
42	{PDB_POLICY_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH,
43		"Minimal password length (default: 5)",
44		"sambaMinPwdLength" },
45
46	{PDB_POLICY_PASSWORD_HISTORY, "password history", 0,
47		"Length of Password History Entries (default: 0 => off)",
48		"sambaPwdHistoryLength" },
49
50	{PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0,
51		"Force Users to logon for password change (default: 0 => off, 2 => on)",
52		"sambaLogonToChgPwd" },
53
54	{PDB_POLICY_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1,
55		"Maximum password age, in seconds (default: -1 => never expire passwords)",
56		"sambaMaxPwdAge" },
57
58	{PDB_POLICY_MIN_PASSWORD_AGE,"minimum password age", 0,
59		"Minimal password age, in seconds (default: 0 => allow immediate password change)",
60		"sambaMinPwdAge" },
61
62	{PDB_POLICY_LOCK_ACCOUNT_DURATION, "lockout duration", 30,
63		"Lockout duration in minutes (default: 30, -1 => forever)",
64		"sambaLockoutDuration" },
65
66	{PDB_POLICY_RESET_COUNT_TIME, "reset count minutes", 30,
67		"Reset time after lockout in minutes (default: 30)",
68		"sambaLockoutObservationWindow" },
69
70	{PDB_POLICY_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0,
71		"Lockout users after bad logon attempts (default: 0 => off)",
72		"sambaLockoutThreshold" },
73
74	{PDB_POLICY_TIME_TO_LOGOUT, "disconnect time", (uint32) -1,
75		"Disconnect Users outside logon hours (default: -1 => off, 0 => on)",
76		"sambaForceLogoff" },
77
78	{PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0,
79		"Allow Machine Password changes (default: 0 => off)",
80		"sambaRefuseMachinePwdChange" },
81
82	{0, NULL, 0, "", NULL}
83};
84
85void account_policy_names_list(const char ***names, int *num_names)
86{
87	const char **nl;
88	int i, count;
89
90	for (count=0; account_policy_names[count].string; count++) {
91	}
92	nl = SMB_MALLOC_ARRAY(const char *, count);
93	if (!nl) {
94		*num_names = 0;
95		return;
96	}
97	for (i=0; account_policy_names[i].string; i++) {
98		nl[i] = account_policy_names[i].string;
99	}
100	*num_names = count;
101	*names = nl;
102	return;
103}
104
105/****************************************************************************
106Get the account policy name as a string from its #define'ed number
107****************************************************************************/
108
109const char *decode_account_policy_name(enum pdb_policy_type type)
110{
111	int i;
112	for (i=0; account_policy_names[i].string; i++) {
113		if (type == account_policy_names[i].type) {
114			return account_policy_names[i].string;
115		}
116	}
117	return NULL;
118}
119
120/****************************************************************************
121Get the account policy LDAP attribute as a string from its #define'ed number
122****************************************************************************/
123
124const char *get_account_policy_attr(enum pdb_policy_type type)
125{
126	int i;
127	for (i=0; account_policy_names[i].type; i++) {
128		if (type == account_policy_names[i].type) {
129			return account_policy_names[i].ldap_attr;
130		}
131	}
132	return NULL;
133}
134
135/****************************************************************************
136Get the account policy description as a string from its #define'ed number
137****************************************************************************/
138
139const char *account_policy_get_desc(enum pdb_policy_type type)
140{
141	int i;
142	for (i=0; account_policy_names[i].string; i++) {
143		if (type == account_policy_names[i].type) {
144			return account_policy_names[i].description;
145		}
146	}
147	return NULL;
148}
149
150/****************************************************************************
151Get the account policy name as a string from its #define'ed number
152****************************************************************************/
153
154enum pdb_policy_type account_policy_name_to_typenum(const char *name)
155{
156	int i;
157	for (i=0; account_policy_names[i].string; i++) {
158		if (strcmp(name, account_policy_names[i].string) == 0) {
159			return account_policy_names[i].type;
160		}
161	}
162	return 0;
163}
164
165/*****************************************************************************
166Get default value for account policy
167*****************************************************************************/
168
169bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val)
170{
171	int i;
172	for (i=0; account_policy_names[i].type; i++) {
173		if (account_policy_names[i].type == type) {
174			*val = account_policy_names[i].default_val;
175			return True;
176		}
177	}
178	DEBUG(0,("no default for account_policy index %d found. This should never happen\n",
179		type));
180	return False;
181}
182
183/*****************************************************************************
184 Set default for a type if it is empty
185*****************************************************************************/
186
187static bool account_policy_set_default_on_empty(enum pdb_policy_type type)
188{
189
190	uint32 value;
191
192	if (!account_policy_get(type, &value) &&
193	    !account_policy_get_default(type, &value)) {
194		return False;
195	}
196
197	return account_policy_set(type, value);
198}
199
200/*****************************************************************************
201 Open the account policy tdb.
202***`*************************************************************************/
203
204bool init_account_policy(void)
205{
206
207	const char *vstring = "INFO/version";
208	uint32 version;
209	int i;
210
211	if (db != NULL) {
212		return True;
213	}
214
215	db = db_open(NULL, state_path("account_policy.tdb"), 0, TDB_DEFAULT,
216		     O_RDWR, 0600);
217
218	if (db == NULL) { /* the account policies files does not exist or open
219			   * failed, try to create a new one */
220		db = db_open(NULL, state_path("account_policy.tdb"), 0,
221			     TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
222		if (db == NULL) {
223			DEBUG(0,("Failed to open account policy database\n"));
224			return False;
225		}
226	}
227
228	version = dbwrap_fetch_int32(db, vstring);
229	if (version == DATABASE_VERSION) {
230		return true;
231	}
232
233	/* handle a Samba upgrade */
234
235	if (db->transaction_start(db) != 0) {
236		DEBUG(0, ("transaction_start failed\n"));
237		TALLOC_FREE(db);
238		return false;
239	}
240
241	version = dbwrap_fetch_int32(db, vstring);
242	if (version == DATABASE_VERSION) {
243		/*
244		 * Race condition
245		 */
246		if (db->transaction_cancel(db)) {
247			smb_panic("transaction_cancel failed");
248		}
249		return true;
250	}
251
252	if (version != DATABASE_VERSION) {
253		if (dbwrap_store_uint32(db, vstring, DATABASE_VERSION) != 0) {
254			DEBUG(0, ("dbwrap_store_uint32 failed\n"));
255			goto cancel;
256		}
257
258		for (i=0; account_policy_names[i].type; i++) {
259
260			if (!account_policy_set_default_on_empty(account_policy_names[i].type)) {
261				DEBUG(0,("failed to set default value in account policy tdb\n"));
262				goto cancel;
263			}
264		}
265	}
266
267	/* These exist by default on NT4 in [HKLM\SECURITY\Policy\Accounts] */
268
269	privilege_create_account( &global_sid_World );
270	privilege_create_account( &global_sid_Builtin_Account_Operators );
271	privilege_create_account( &global_sid_Builtin_Server_Operators );
272	privilege_create_account( &global_sid_Builtin_Print_Operators );
273	privilege_create_account( &global_sid_Builtin_Backup_Operators );
274
275	/* BUILTIN\Administrators get everything -- *always* */
276
277	if ( lp_enable_privileges() ) {
278		if ( !grant_all_privileges( &global_sid_Builtin_Administrators ) ) {
279			DEBUG(1,("init_account_policy: Failed to grant privileges "
280				"to BUILTIN\\Administrators!\n"));
281		}
282	}
283
284	if (db->transaction_commit(db) != 0) {
285		DEBUG(0, ("transaction_commit failed\n"));
286		TALLOC_FREE(db);
287		return false;
288	}
289
290	return True;
291
292 cancel:
293	if (db->transaction_cancel(db)) {
294		smb_panic("transaction_cancel failed");
295	}
296	TALLOC_FREE(db);
297
298	return false;
299}
300
301/*****************************************************************************
302Get an account policy (from tdb)
303*****************************************************************************/
304
305bool account_policy_get(enum pdb_policy_type type, uint32_t *value)
306{
307	const char *name;
308	uint32 regval;
309
310	if (!init_account_policy()) {
311		return False;
312	}
313
314	if (value) {
315		*value = 0;
316	}
317
318	name = decode_account_policy_name(type);
319	if (name == NULL) {
320		DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type!  Cannot get, returning 0.\n", type));
321		return False;
322	}
323
324	if (!dbwrap_fetch_uint32(db, name, &regval)) {
325		DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for type %d (%s), returning 0\n", type, name));
326		return False;
327	}
328
329	if (value) {
330		*value = regval;
331	}
332
333	DEBUG(10,("account_policy_get: name: %s, val: %d\n", name, regval));
334	return True;
335}
336
337
338/****************************************************************************
339Set an account policy (in tdb)
340****************************************************************************/
341
342bool account_policy_set(enum pdb_policy_type type, uint32_t value)
343{
344	const char *name;
345	NTSTATUS status;
346
347	if (!init_account_policy()) {
348		return False;
349	}
350
351	name = decode_account_policy_name(type);
352	if (name == NULL) {
353		DEBUG(1, ("Field %d is not a valid account policy type!  Cannot set.\n", type));
354		return False;
355	}
356
357	status = dbwrap_trans_store_uint32(db, name, value);
358	if (!NT_STATUS_IS_OK(status)) {
359		DEBUG(1, ("store_uint32 failed for type %d (%s) on value "
360			  "%u: %s\n", type, name, value, nt_errstr(status)));
361		return False;
362	}
363
364	DEBUG(10,("account_policy_set: name: %s, value: %d\n", name, value));
365
366	return True;
367}
368
369/****************************************************************************
370Set an account policy in the cache
371****************************************************************************/
372
373bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value)
374{
375	const char *policy_name = NULL;
376	char *cache_key = NULL;
377	char *cache_value = NULL;
378	bool ret = False;
379
380	policy_name = decode_account_policy_name(type);
381	if (policy_name == NULL) {
382		DEBUG(0,("cache_account_policy_set: no policy found\n"));
383		return False;
384	}
385
386	if (asprintf(&cache_key, "ACCT_POL/%s", policy_name) < 0) {
387		DEBUG(0, ("asprintf failed\n"));
388		goto done;
389	}
390
391	if (asprintf(&cache_value, "%lu\n", (unsigned long)value) < 0) {
392		DEBUG(0, ("asprintf failed\n"));
393		goto done;
394	}
395
396	DEBUG(10,("cache_account_policy_set: updating account pol cache\n"));
397
398	ret = gencache_set(cache_key, cache_value, time(NULL)+AP_TTL);
399
400 done:
401	SAFE_FREE(cache_key);
402	SAFE_FREE(cache_value);
403	return ret;
404}
405
406/*****************************************************************************
407Get an account policy from the cache
408*****************************************************************************/
409
410bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value)
411{
412	const char *policy_name = NULL;
413	char *cache_key = NULL;
414	char *cache_value = NULL;
415	bool ret = False;
416
417	policy_name = decode_account_policy_name(type);
418	if (policy_name == NULL) {
419		DEBUG(0,("cache_account_policy_set: no policy found\n"));
420		return False;
421	}
422
423	if (asprintf(&cache_key, "ACCT_POL/%s", policy_name) < 0) {
424		DEBUG(0, ("asprintf failed\n"));
425		goto done;
426	}
427
428	if (gencache_get(cache_key, &cache_value, NULL)) {
429		uint32 tmp = strtoul(cache_value, NULL, 10);
430		*value = tmp;
431		ret = True;
432	}
433
434 done:
435	SAFE_FREE(cache_key);
436	SAFE_FREE(cache_value);
437	return ret;
438}
439
440/****************************************************************************
441****************************************************************************/
442
443struct db_context *get_account_pol_db( void )
444{
445
446	if ( db == NULL ) {
447		if ( !init_account_policy() ) {
448			return NULL;
449		}
450	}
451
452	return db;
453}
454
455