2001-12-03 17:14:23 +00:00
/*
2002-01-30 06:08:46 +00:00
* Unix SMB / CIFS implementation .
2001-12-03 17:14:23 +00:00
* account policy storage
* Copyright ( C ) Jean Fran <EFBFBD> ois Micouleau 1998 - 2001.
2002-08-17 17:00:51 +00:00
* Copyright ( C ) Andrew Bartlett 2002
2005-09-30 17:13:37 +00:00
* Copyright ( C ) Guenther Deschner 2004 - 2005
2001-12-03 17:14:23 +00:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2007-07-09 19:25:36 +00:00
* the Free Software Foundation ; either version 3 of the License , or
2001-12-03 17:14:23 +00:00
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2007-07-10 05:23:25 +00:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2001-12-03 17:14:23 +00:00
*/
# include "includes.h"
2005-01-13 18:20:37 +00:00
static TDB_CONTEXT * tdb ;
2001-12-03 17:14:23 +00:00
2005-09-30 17:13:37 +00:00
/* cache all entries for 60 seconds for to save ldap-queries (cache is updated
* after this period if admins do not use pdbedit or usermanager but manipulate
* ldap directly ) - gd */
2005-01-10 18:29:52 +00:00
2005-09-30 17:13:37 +00:00
# define DATABASE_VERSION 3
# define AP_TTL 60
2005-02-12 00:51:31 +00:00
2005-09-30 17:13:37 +00:00
struct ap_table {
int field ;
const char * string ;
uint32 default_val ;
const char * description ;
const char * ldap_attr ;
} ;
2005-02-12 00:51:31 +00:00
2005-09-30 17:13:37 +00:00
static const struct ap_table account_policy_names [ ] = {
{ AP_MIN_PASSWORD_LEN , " min password length " , MINPASSWDLENGTH ,
" Minimal password length (default: 5) " ,
" sambaMinPwdLength " } ,
2005-02-12 00:51:31 +00:00
2005-09-30 17:13:37 +00:00
{ AP_PASSWORD_HISTORY , " password history " , 0 ,
" Length of Password History Entries (default: 0 => off) " ,
" sambaPwdHistoryLength " } ,
2005-02-12 00:51:31 +00:00
2005-09-30 17:13:37 +00:00
{ AP_USER_MUST_LOGON_TO_CHG_PASS , " user must logon to change password " , 0 ,
" Force Users to logon for password change (default: 0 => off, 2 => on) " ,
" sambaLogonToChgPwd " } ,
2005-02-12 00:51:31 +00:00
2005-09-30 17:13:37 +00:00
{ AP_MAX_PASSWORD_AGE , " maximum password age " , ( uint32 ) - 1 ,
" Maximum password age, in seconds (default: -1 => never expire passwords) " ,
" sambaMaxPwdAge " } ,
{ AP_MIN_PASSWORD_AGE , " minimum password age " , 0 ,
" Minimal password age, in seconds (default: 0 => allow immediate password change) " ,
" sambaMinPwdAge " } ,
{ AP_LOCK_ACCOUNT_DURATION , " lockout duration " , 30 ,
" Lockout duration in minutes (default: 30, -1 => forever) " ,
" sambaLockoutDuration " } ,
{ AP_RESET_COUNT_TIME , " reset count minutes " , 30 ,
" Reset time after lockout in minutes (default: 30) " ,
" sambaLockoutObservationWindow " } ,
{ AP_BAD_ATTEMPT_LOCKOUT , " bad lockout attempt " , 0 ,
" Lockout users after bad logon attempts (default: 0 => off) " ,
" sambaLockoutThreshold " } ,
2005-12-20 15:10:41 +00:00
{ AP_TIME_TO_LOGOUT , " disconnect time " , ( uint32 ) - 1 ,
2005-09-30 17:13:37 +00:00
" Disconnect Users outside logon hours (default: -1 => off, 0 => on) " ,
" sambaForceLogoff " } ,
{ AP_REFUSE_MACHINE_PW_CHANGE , " refuse machine password change " , 0 ,
" Allow Machine Password changes (default: 0 => off) " ,
" sambaRefuseMachinePwdChange " } ,
{ 0 , NULL , 0 , " " , NULL }
2002-08-17 17:00:51 +00:00
} ;
2006-12-01 14:54:31 +00:00
void account_policy_names_list ( const char * * * names , int * num_names )
{
const char * * nl ;
int i , count ;
2004-07-08 21:01:30 +00:00
2006-12-01 14:54:31 +00:00
for ( count = 0 ; account_policy_names [ count ] . string ; count + + ) {
2004-07-08 21:01:30 +00:00
}
2006-12-01 14:54:31 +00:00
nl = SMB_MALLOC_ARRAY ( const char * , count ) ;
2004-07-08 21:01:30 +00:00
if ( ! nl ) {
2006-12-01 14:54:31 +00:00
* num_names = 0 ;
return ;
2004-07-08 21:01:30 +00:00
}
for ( i = 0 ; account_policy_names [ i ] . string ; i + + ) {
2006-12-01 14:54:31 +00:00
nl [ i ] = account_policy_names [ i ] . string ;
2004-07-08 21:01:30 +00:00
}
2006-12-01 14:54:31 +00:00
* num_names = count ;
* names = nl ;
return ;
2004-07-08 21:01:30 +00:00
}
2002-08-17 17:00:51 +00:00
/****************************************************************************
Get the account policy name as a string from its # define ' ed number
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 17:13:37 +00:00
const char * decode_account_policy_name ( int field )
2002-08-17 17:00:51 +00:00
{
int i ;
for ( i = 0 ; account_policy_names [ i ] . string ; i + + ) {
2005-12-20 15:10:41 +00:00
if ( field = = account_policy_names [ i ] . field ) {
2002-08-17 17:00:51 +00:00
return account_policy_names [ i ] . string ;
2005-12-20 15:10:41 +00:00
}
2002-08-17 17:00:51 +00:00
}
return NULL ;
2005-09-30 17:13:37 +00:00
}
/****************************************************************************
Get the account policy LDAP attribute as a string from its # define ' ed number
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-08-17 17:00:51 +00:00
2005-09-30 17:13:37 +00:00
const char * get_account_policy_attr ( int field )
{
int i ;
for ( i = 0 ; account_policy_names [ i ] . field ; i + + ) {
2005-12-20 15:10:41 +00:00
if ( field = = account_policy_names [ i ] . field ) {
2005-09-30 17:13:37 +00:00
return account_policy_names [ i ] . ldap_attr ;
2005-12-20 15:10:41 +00:00
}
2005-09-30 17:13:37 +00:00
}
return NULL ;
}
/****************************************************************************
Get the account policy description as a string from its # define ' ed number
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
const char * account_policy_get_desc ( int field )
{
int i ;
for ( i = 0 ; account_policy_names [ i ] . string ; i + + ) {
2005-12-20 15:10:41 +00:00
if ( field = = account_policy_names [ i ] . field ) {
2005-09-30 17:13:37 +00:00
return account_policy_names [ i ] . description ;
2005-12-20 15:10:41 +00:00
}
2005-09-30 17:13:37 +00:00
}
return NULL ;
2002-08-17 17:00:51 +00:00
}
2001-12-03 17:14:23 +00:00
/****************************************************************************
2002-08-17 17:00:51 +00:00
Get the account policy name as a string from its # define ' ed number
2001-12-03 17:14:23 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-08-17 17:00:51 +00:00
int account_policy_name_to_fieldnum ( const char * name )
2001-12-03 17:14:23 +00:00
{
2002-08-17 17:00:51 +00:00
int i ;
for ( i = 0 ; account_policy_names [ i ] . string ; i + + ) {
2005-12-20 15:10:41 +00:00
if ( strcmp ( name , account_policy_names [ i ] . string ) = = 0 ) {
2002-08-17 17:00:51 +00:00
return account_policy_names [ i ] . field ;
2005-12-20 15:10:41 +00:00
}
2001-12-03 17:14:23 +00:00
}
2002-08-17 17:00:51 +00:00
return 0 ;
2005-09-30 17:13:37 +00:00
}
/*****************************************************************************
Get default value for account policy
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL account_policy_get_default ( int account_policy , uint32 * val )
{
int i ;
for ( i = 0 ; account_policy_names [ i ] . field ; i + + ) {
if ( account_policy_names [ i ] . field = = account_policy ) {
* val = account_policy_names [ i ] . default_val ;
return True ;
}
}
DEBUG ( 0 , ( " no default for account_policy index %d found. This should never happen \n " ,
account_policy ) ) ;
return False ;
}
/*****************************************************************************
Set default for a field if it is empty
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL account_policy_set_default_on_empty ( int account_policy )
{
uint32 value ;
if ( ! account_policy_get ( account_policy , & value ) & &
! account_policy_get_default ( account_policy , & value ) ) {
return False ;
}
return account_policy_set ( account_policy , value ) ;
}
/*****************************************************************************
Open the account policy tdb .
* * * ` * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL init_account_policy ( void )
{
const char * vstring = " INFO/version " ;
uint32 version ;
int i ;
2005-12-20 15:10:41 +00:00
if ( tdb ) {
2005-09-30 17:13:37 +00:00
return True ;
2005-12-20 15:10:41 +00:00
}
2005-09-30 17:13:37 +00:00
2006-07-11 18:01:26 +00:00
tdb = tdb_open_log ( lock_path ( " account_policy.tdb " ) , 0 , TDB_DEFAULT , O_RDWR , 0600 ) ;
if ( ! tdb ) { /* the account policies files does not exist or open failed, try to create a new one */
tdb = tdb_open_log ( lock_path ( " account_policy.tdb " ) , 0 , TDB_DEFAULT , O_RDWR | O_CREAT , 0600 ) ;
if ( ! tdb ) {
DEBUG ( 0 , ( " Failed to open account policy database \n " ) ) ;
return False ;
}
2005-09-30 17:13:37 +00:00
}
/* handle a Samba upgrade */
2006-04-17 11:49:06 +00:00
tdb_lock_bystring ( tdb , vstring ) ;
2005-09-30 17:13:37 +00:00
if ( ! tdb_fetch_uint32 ( tdb , vstring , & version ) | | version ! = DATABASE_VERSION ) {
tdb_store_uint32 ( tdb , vstring , DATABASE_VERSION ) ;
for ( i = 0 ; account_policy_names [ i ] . field ; i + + ) {
if ( ! account_policy_set_default_on_empty ( account_policy_names [ i ] . field ) ) {
DEBUG ( 0 , ( " failed to set default value in account policy tdb \n " ) ) ;
return False ;
}
}
}
tdb_unlock_bystring ( tdb , vstring ) ;
/* These exist by default on NT4 in [HKLM\SECURITY\Policy\Accounts] */
privilege_create_account ( & global_sid_World ) ;
privilege_create_account ( & global_sid_Builtin_Account_Operators ) ;
privilege_create_account ( & global_sid_Builtin_Server_Operators ) ;
privilege_create_account ( & global_sid_Builtin_Print_Operators ) ;
privilege_create_account ( & global_sid_Builtin_Backup_Operators ) ;
2006-03-15 05:50:52 +00:00
/* BUILTIN\Administrators get everything -- *always* */
2006-09-06 15:17:25 +00:00
if ( lp_enable_privileges ( ) ) {
if ( ! grant_all_privileges ( & global_sid_Builtin_Administrators ) ) {
DEBUG ( 1 , ( " init_account_policy: Failed to grant privileges "
" to BUILTIN \\ Administrators! \n " ) ) ;
}
2006-03-15 05:50:52 +00:00
}
2005-09-30 17:13:37 +00:00
return True ;
}
/*****************************************************************************
Get an account policy ( from tdb )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-07-08 21:01:30 +00:00
2001-12-31 13:46:26 +00:00
BOOL account_policy_get ( int field , uint32 * value )
2001-12-03 17:14:23 +00:00
{
2006-09-09 22:27:06 +00:00
const char * name ;
2005-01-10 18:29:52 +00:00
uint32 regval ;
2001-12-03 17:14:23 +00:00
2005-12-20 15:10:41 +00:00
if ( ! init_account_policy ( ) ) {
2005-09-30 17:13:37 +00:00
return False ;
2005-12-20 15:10:41 +00:00
}
2001-12-04 06:20:39 +00:00
2005-12-20 15:10:41 +00:00
if ( value ) {
2005-01-10 18:29:52 +00:00
* value = 0 ;
2005-12-20 15:10:41 +00:00
}
2002-08-17 17:00:51 +00:00
2006-09-09 22:27:06 +00:00
name = decode_account_policy_name ( field ) ;
if ( name = = NULL ) {
2002-08-17 17:00:51 +00:00
DEBUG ( 1 , ( " account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0. \n " , field ) ) ;
return False ;
}
2005-12-20 15:10:41 +00:00
2005-01-10 18:29:52 +00:00
if ( ! tdb_fetch_uint32 ( tdb , name , & regval ) ) {
2004-11-24 09:44:57 +00:00
DEBUG ( 1 , ( " account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0 \n " , field , name ) ) ;
2002-08-17 17:00:51 +00:00
return False ;
}
2005-12-20 15:10:41 +00:00
if ( value ) {
2005-01-10 18:29:52 +00:00
* value = regval ;
2005-12-20 15:10:41 +00:00
}
2005-01-10 18:29:52 +00:00
2005-09-30 17:13:37 +00:00
DEBUG ( 10 , ( " account_policy_get: name: %s, val: %d \n " , name , regval ) ) ;
2001-12-03 17:14:23 +00:00
return True ;
}
/****************************************************************************
2005-09-30 17:13:37 +00:00
Set an account policy ( in tdb )
2001-12-03 17:14:23 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 17:13:37 +00:00
2001-12-31 13:46:26 +00:00
BOOL account_policy_set ( int field , uint32 value )
2001-12-03 17:14:23 +00:00
{
2006-09-09 22:27:06 +00:00
const char * name ;
2001-12-03 17:14:23 +00:00
2005-12-20 15:10:41 +00:00
if ( ! init_account_policy ( ) ) {
2005-09-30 17:13:37 +00:00
return False ;
2005-12-20 15:10:41 +00:00
}
2001-12-04 06:20:39 +00:00
2006-09-09 22:27:06 +00:00
name = decode_account_policy_name ( field ) ;
if ( name = = NULL ) {
2002-08-17 17:00:51 +00:00
DEBUG ( 1 , ( " Field %d is not a valid account policy type! Cannot set. \n " , field ) ) ;
2001-12-03 17:14:23 +00:00
return False ;
2002-08-17 17:00:51 +00:00
}
if ( ! tdb_store_uint32 ( tdb , name , value ) ) {
2005-09-30 17:13:37 +00:00
DEBUG ( 1 , ( " tdb_store_uint32 failed for field %d (%s) on value %u \n " , field , name , value ) ) ;
2002-08-17 17:00:51 +00:00
return False ;
}
2005-09-30 17:13:37 +00:00
DEBUG ( 10 , ( " account_policy_set: name: %s, value: %d \n " , name , value ) ) ;
2001-12-03 17:14:23 +00:00
return True ;
}
2005-01-13 18:20:37 +00:00
2005-09-30 17:13:37 +00:00
/****************************************************************************
Set an account policy in the cache
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cache_account_policy_set ( int field , uint32 value )
{
const char * policy_name = NULL ;
2006-09-09 22:27:06 +00:00
char * cache_key = NULL ;
char * cache_value = NULL ;
BOOL ret = False ;
2005-09-30 17:13:37 +00:00
policy_name = decode_account_policy_name ( field ) ;
if ( policy_name = = NULL ) {
DEBUG ( 0 , ( " cache_account_policy_set: no policy found \n " ) ) ;
return False ;
}
2006-09-09 22:27:06 +00:00
if ( asprintf ( & cache_key , " ACCT_POL/%s " , policy_name ) < 0 ) {
DEBUG ( 0 , ( " asprintf failed \n " ) ) ;
goto done ;
2005-12-20 15:10:41 +00:00
}
2006-09-09 22:27:06 +00:00
if ( asprintf ( & cache_value , " %lu \n " , ( unsigned long ) value ) < 0 ) {
DEBUG ( 0 , ( " asprintf failed \n " ) ) ;
goto done ;
2005-12-20 15:10:41 +00:00
}
2006-09-09 22:27:06 +00:00
DEBUG ( 10 , ( " cache_account_policy_set: updating account pol cache \n " ) ) ;
2005-12-20 15:10:41 +00:00
2006-09-09 22:27:06 +00:00
ret = gencache_set ( cache_key , cache_value , time ( NULL ) + AP_TTL ) ;
2005-12-20 15:10:41 +00:00
2006-09-09 22:27:06 +00:00
done :
SAFE_FREE ( cache_key ) ;
SAFE_FREE ( cache_value ) ;
return ret ;
2005-12-20 15:10:41 +00:00
}
2005-09-30 17:13:37 +00:00
/*****************************************************************************
Get an account policy from the cache
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cache_account_policy_get ( int field , uint32 * value )
{
2006-09-09 22:27:06 +00:00
const char * policy_name = NULL ;
char * cache_key = NULL ;
char * cache_value = NULL ;
BOOL ret = False ;
2005-09-30 17:13:37 +00:00
2006-09-09 22:27:06 +00:00
policy_name = decode_account_policy_name ( field ) ;
if ( policy_name = = NULL ) {
DEBUG ( 0 , ( " cache_account_policy_set: no policy found \n " ) ) ;
2005-09-30 17:13:37 +00:00
return False ;
}
2006-09-09 22:27:06 +00:00
if ( asprintf ( & cache_key , " ACCT_POL/%s " , policy_name ) < 0 ) {
DEBUG ( 0 , ( " asprintf failed \n " ) ) ;
goto done ;
}
2005-09-30 17:13:37 +00:00
2006-09-09 22:27:06 +00:00
if ( gencache_get ( cache_key , & cache_value , NULL ) ) {
uint32 tmp = strtoul ( cache_value , NULL , 10 ) ;
* value = tmp ;
ret = True ;
}
2005-09-30 17:13:37 +00:00
2006-09-09 22:27:06 +00:00
done :
SAFE_FREE ( cache_key ) ;
SAFE_FREE ( cache_value ) ;
return ret ;
}
2005-09-30 17:13:37 +00:00
2005-01-13 18:20:37 +00:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
TDB_CONTEXT * get_account_pol_tdb ( void )
{
if ( ! tdb ) {
2005-12-20 15:10:41 +00:00
if ( ! init_account_policy ( ) ) {
2005-01-13 18:20:37 +00:00
return NULL ;
2005-12-20 15:10:41 +00:00
}
2005-01-13 18:20:37 +00:00
}
return tdb ;
}