diff options
author | Jim McDonough <jmcd@samba.org> | 2004-03-18 20:05:00 +0000 |
---|---|---|
committer | Jim McDonough <jmcd@samba.org> | 2004-03-18 20:05:00 +0000 |
commit | 2332bebd9fabc32dbc2756347338dbecc06e527b (patch) | |
tree | 08d49649a4e52c75765b6e915e7c204d3bd69469 /source3/passdb/pdb_ldap.c | |
parent | 4b9423fc2205b6f37300e134f425d0aef3022a6e (diff) | |
download | samba-2332bebd9fabc32dbc2756347338dbecc06e527b.tar.gz samba-2332bebd9fabc32dbc2756347338dbecc06e527b.tar.bz2 samba-2332bebd9fabc32dbc2756347338dbecc06e527b.zip |
merge from 3.0...LDAP password lockout support
(This used to be commit b627cee3848d73e35181c9e6fdd9931452b28e48)
Diffstat (limited to 'source3/passdb/pdb_ldap.c')
-rw-r--r-- | source3/passdb/pdb_ldap.c | 121 |
1 files changed, 120 insertions, 1 deletions
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 0ebb63b3fb..b7e28a9e99 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -391,6 +391,25 @@ static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state, #endif +static time_t ldapsam_get_entry_timestamp( + struct ldapsam_privates *ldap_state, + LDAPMessage * entry) +{ + pstring temp; + struct tm tm; + + if (!smbldap_get_single_pstring( + ldap_state->smbldap_state->ldap_struct, entry, + get_userattr_key2string(ldap_state->schema_ver, + LDAP_ATTR_MOD_TIMESTAMP), + temp)) + return (time_t) 0; + + strptime(temp, "%Y%m%d%H%M%SZ", &tm); + tzset(); + return (mktime(&tm) - timezone); +} + /********************************************************************** Initialize SAM_ACCOUNT from an LDAP query. (Based on init_sam_from_buffer in pdb_tdb.c) @@ -405,7 +424,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, kickoff_time, pass_last_set_time, pass_can_change_time, - pass_must_change_time; + pass_must_change_time, + ldap_entry_time, + bad_password_time; pstring username, domain, nt_username, @@ -427,6 +448,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, uint32 hours_len; uint8 hours[MAX_HOURS_LEN]; pstring temp; + LOGIN_CACHE *cache_entry = NULL; /* * do a little initialization @@ -720,6 +742,15 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); } + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, + get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_TIME), temp)) { + /* leave as default */ + } else { + bad_password_time = (time_t) atol(temp); + pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET); + } + + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_COUNT), temp)) { /* leave as default */ @@ -732,6 +763,43 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_hours(sampass, hours, PDB_SET); + /* check the timestamp of the cache vs ldap entry */ + if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state, + entry))) + return True; + + /* see if we have newer updates */ + if (!(cache_entry = login_cache_read(sampass))) { + DEBUG (9, ("No cache entry, bad count = %d, bad time = %d\n", + pdb_get_bad_password_count(sampass), + pdb_get_bad_password_time(sampass))); + return True; + } + + DEBUG(7, ("ldap time is %d, cache time is %d, bad time = %d\n", + ldap_entry_time, cache_entry->entry_timestamp, + cache_entry->bad_password_time)); + + if (ldap_entry_time > cache_entry->entry_timestamp) { + /* cache is older than directory , so + we need to delete the entry but allow the + fields to be written out */ + login_cache_delentry(sampass); + } else { + /* read cache in */ + pdb_set_acct_ctrl(sampass, + pdb_get_acct_ctrl(sampass) | + (cache_entry->acct_ctrl & ACB_AUTOLOCK), + PDB_SET); + pdb_set_bad_password_count(sampass, + cache_entry->bad_password_count, + PDB_SET); + pdb_set_bad_password_time(sampass, + cache_entry->bad_password_time, + PDB_SET); + } + + SAFE_FREE(cache_entry); return True; } @@ -907,6 +975,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp); + if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) { @@ -954,6 +1023,56 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN)); + /* password lockout cache: + - If we are now autolocking or clearing, we write to ldap + - If we are clearing, we delete the cache entry + - If the count is > 0, we update the cache + + This even means when autolocking, we cache, just in case the + update doesn't work, and we have to cache the autolock flag */ + + if (need_update(sampass, PDB_BAD_PASSWORD_COUNT)) /* && + need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ { + uint16 badcount = pdb_get_bad_password_count(sampass); + time_t badtime = pdb_get_bad_password_time(sampass); + uint32 pol; + account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &pol); + + DEBUG(3, ("updating bad password fields, policy=%d, count=%d, time=%d\n", pol, badcount, badtime)); + + if ((badcount >= pol) || (badcount == 0)) { + DEBUG(7, ("making mods to update ldap, count=%d, time=%d\n", badcount, badtime)); + slprintf (temp, sizeof (temp) - 1, "%li", badcount); + smbldap_make_mod( + ldap_state->smbldap_state->ldap_struct, + existing, mods, + get_userattr_key2string( + ldap_state->schema_ver, + LDAP_ATTR_BAD_PASSWORD_COUNT), + temp); + + slprintf (temp, sizeof (temp) - 1, "%li", badtime); + smbldap_make_mod( + ldap_state->smbldap_state->ldap_struct, + existing, mods, + get_userattr_key2string( + ldap_state->schema_ver, + LDAP_ATTR_BAD_PASSWORD_TIME), + temp); + } + if (badcount == 0) { + DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass))); + login_cache_delentry(sampass); + } else { + LOGIN_CACHE cache_entry ={time(NULL), + pdb_get_acct_ctrl(sampass), + badcount, badtime}; + DEBUG(7, ("Updating bad password count and time in login cache\n")); + login_cache_write(sampass, cache_entry); + } + + } + return True; } |