[PATCH] bad password lock
Aurélien Degrémont
adegremont at idealx.com
Tue Sep 16 12:33:45 GMT 2003
Hi,
Here is the new version of the Richard Renard's patch, which enables the
bad password count and lockout duration functionnalities.
I note that Jeremy Allison was already working on it, and that some
people were waiting for it :). I hope this patch will be useful.
This patch is based on Jianliang Lu patch
(http://lists.samba.org/pipermail/samba-technical/2003-May/044645.html)
but was mainly rewritten.
This new version enables theses new functionnalities on all the
available backends of Samba (tdbsam, xml, mysql, ldap).
This patch adds 2 fields in the ldap schema
- sambaBadPwdCount
- sambaLockoutDuration
And in the MySQL table :
- bad_pwd_count
- lockout_time
Obviously, due to smbpasswd limitations, these features are not
available on it.
An option ( -z ) to reset the bad password count was added in pdbedit.
This patch needs tests and i'm waiting for your comments.
Best regards,
Aurélien Degrémont
-------------- next part --------------
Index: examples/LDAP/samba.schema
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/examples/LDAP/samba.schema,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -r1.1.1.1 -r1.1.1.1.2.1
--- examples/LDAP/samba.schema 11 Sep 2003 15:45:29 -0000 1.1.1.1
+++ examples/LDAP/samba.schema 11 Sep 2003 15:58:25 -0000 1.1.1.1.2.1
@@ -202,6 +202,15 @@
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+attributetype ( 1.3.6.1.4.1.7165.2.1.50 NAME 'sambaBadPwdCount'
+ DESC 'Bad Password Attempt'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.51 NAME 'sambaLockoutTime'
+ DESC 'Timestamp of when the user was locked out'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
##
## string settings
@@ -304,8 +313,8 @@
DESC 'Samba 3.0 Auxilary SAM Account'
MUST ( uid $ sambaSID )
MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $
- sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $
- sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $
+ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ sambaLockoutTime $
+ sambaBadPwdCount $ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $
displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $
sambaProfilePath $ description $ sambaUserWorkstations $
sambaPrimaryGroupSID $ sambaDomainName ))
Index: source/auth/auth_sam.c
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/source/auth/auth_sam.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -r1.1.1.1 -r1.1.1.1.2.1
--- source/auth/auth_sam.c 11 Sep 2003 15:45:30 -0000 1.1.1.1
+++ source/auth/auth_sam.c 11 Sep 2003 15:58:26 -0000 1.1.1.1.2.1
@@ -156,8 +156,15 @@
uint16 acct_ctrl;
const uint8 *nt_pw, *lm_pw;
uint32 auth_flags;
-
+
acct_ctrl = pdb_get_acct_ctrl(sampass);
+
+ /* Quit if the account was locked out. */
+ if (acct_ctrl & ACB_AUTOLOCK) {
+ DEBUG(1,("Account for user %s was locked out.\n", pdb_get_username(sampass)));
+ return NT_STATUS_ACCOUNT_LOCKED_OUT;
+ }
+
if (acct_ctrl & ACB_PWNOTREQ)
{
if (lp_null_passwords())
@@ -404,6 +411,8 @@
check if a username/password is OK assuming the password is a 24 byte
SMB hash supplied in the user_info structure
return an NT_STATUS constant.
+
+hacked by Richard Renard for IDEALX
****************************************************************************/
static NTSTATUS check_sam_security(const struct auth_context *auth_context,
@@ -417,6 +426,9 @@
NTSTATUS nt_status;
uint8 user_sess_key[16];
const uint8* lm_hash;
+ uint32 account_policy_lockout, badpwdcount,
+ account_policy_lockout_duration;
+ time_t lockout_time;
if (!user_info || !auth_context) {
return NT_STATUS_UNSUCCESSFUL;
@@ -443,9 +455,61 @@
nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, user_sess_key);
+ /* if WRONG_PASSWORD set badpwdcount and lock the account if needed */
if (!NT_STATUS_IS_OK(nt_status)) {
+ if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) && pdb_get_acct_ctrl(sampass) &ACB_NORMAL) {
+ badpwdcount = (uint32)pdb_get_bad_pwd_count(sampass) + 1 ;
+ if (!pdb_set_bad_pwd_count(sampass, badpwdcount, PDB_CHANGED))
+ DEBUG(1,("Failed to set 'badPwdCount' for user %s. \n", user_info->internal_username.str));
+ account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
+ if (account_policy_lockout && (badpwdcount > account_policy_lockout)) {
+ nt_status = NT_STATUS_ACCOUNT_LOCKED_OUT;
+ lockout_time = time(NULL);
+ if(!pdb_set_acct_ctrl (sampass, pdb_get_acct_ctrl(sampass)|ACB_AUTOLOCK, PDB_CHANGED))
+ DEBUG(1, ("Failed to set 'lockout' flag for user %s. \n", user_info->internal_username.str));
+ if(!pdb_set_lockout_time(sampass, lockout_time, PDB_CHANGED))
+ DEBUG(1, ("Failed to set 'lockout_time' for user %s \n", user_info->internal_username.str));
+ }
+
+ become_root();
+ if (!pdb_update_sam_account(sampass))
+ DEBUG(1, ("Failed to modify entry for user %s. \n", user_info->internal_username.str));
+ unbecome_root();
+
+ }
pdb_free_sam(&sampass);
return nt_status;
+ }
+
+ /* if the account is locked, unlock it if lockout duration is expired */
+ if (pdb_get_acct_ctrl(sampass) &ACB_AUTOLOCK) {
+ lockout_time = (time_t)pdb_get_lockout_time(sampass);
+ account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_lockout_duration);
+ if ( ((time_t)lockout_time + (time_t)account_policy_lockout_duration) < time(NULL) &&
+ ((time_t)lockout_time + (time_t)account_policy_lockout_duration) > (time_t)lockout_time) {
+ if(!pdb_set_acct_ctrl (sampass, pdb_get_acct_ctrl(sampass) ^ACB_AUTOLOCK, PDB_CHANGED))
+ DEBUG(1, ("Failed to remove 'lockout' flag for user %s. \n", user_info->internal_username.str));
+ if(!pdb_set_lockout_time(sampass, (time_t)0, PDB_CHANGED))
+ DEBUG(1, ("Failed to remove 'lockout_time' for user %s \n", user_info->internal_username.str));
+
+ become_root();
+ if (!pdb_update_sam_account(sampass))
+ DEBUG(1, ("Failed to modify entry for user %s. \n", user_info->internal_username.str));
+ unbecome_root();
+ }
+ }
+
+ /* reset badpwdcount if account is normal*/
+ if (pdb_get_acct_ctrl(sampass) &ACB_NORMAL) {
+ if (!pdb_set_bad_pwd_count(sampass, 0, PDB_CHANGED))
+ DEBUG(1, ("Failed to reset 'BadPwdCount' for user %s. \n", user_info->internal_username.str));
+ if (!pdb_set_logon_time(sampass, time(NULL), PDB_CHANGED))
+ DEBUG(1, ("auth_sam.c : pdb_set_logon_time failed! \n"));
+
+ become_root();
+ if (!pdb_update_sam_account(sampass))
+ DEBUG(1, ("Failed to modify entry for user %s. \n", user_info->internal_username.str));
+ unbecome_root();
}
nt_status = sam_account_ok(mem_ctx, sampass, user_info);
Index: source/include/passdb.h
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/source/include/passdb.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -r1.1.1.1 -r1.1.1.1.2.1
--- source/include/passdb.h 11 Sep 2003 15:45:31 -0000 1.1.1.1
+++ source/include/passdb.h 11 Sep 2003 15:58:27 -0000 1.1.1.1.2.1
@@ -62,6 +62,8 @@
PDB_LMPASSWD,
PDB_NTPASSWD,
PDB_BACKEND_PRIVATE_DATA,
+ PDB_BADPWDCOUNT,
+ PDB_LOCKOUTTIME,
/* this must be the last element */
PDB_COUNT
@@ -104,6 +106,7 @@
time_t logon_time; /* logon time */
time_t logoff_time; /* logoff time */
time_t kickoff_time; /* kickoff time */
+ time_t lockout_time; /* lockout time */
time_t pass_last_set_time; /* password last set time */
time_t pass_can_change_time; /* password can change time */
time_t pass_must_change_time; /* password must change time */
@@ -138,6 +141,7 @@
uint32 unknown_5; /* 0x0002 0000 */
uint32 unknown_6; /* 0x0000 04ec */
+ uint32 bad_pwd_count; /* count of bad password attempts */
/* a tag for who added the private methods */
const struct pdb_methods *backend_private_methods;
void *backend_private_data;
Index: source/include/smbldap.h
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/source/include/smbldap.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -r1.1.1.1 -r1.1.1.1.2.1
--- source/include/smbldap.h 11 Sep 2003 15:45:31 -0000 1.1.1.1
+++ source/include/smbldap.h 11 Sep 2003 15:58:27 -0000 1.1.1.1.2.1
@@ -88,6 +88,8 @@
#define LDAP_ATTR_SID 32
#define LDAP_ATTR_ALGORITHMIC_RID_BASE 33
#define LDAP_ATTR_NEXT_RID 34
+#define LDAP_ATTR_BAD_PWD_COUNT 35
+#define LDAP_ATTR_LOCKOUT_TIME 36
typedef struct _attrib_map_entry {
int attrib;
Index: source/lib/smbldap.c
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/source/lib/smbldap.c,v
retrieving revision 1.1.1.1.4.1
retrieving revision 1.1.1.1.2.2
diff -u -r1.1.1.1.4.1 -r1.1.1.1.2.2
--- source/lib/smbldap.c 15 Sep 2003 09:59:15 -0000 1.1.1.1.4.1
+++ source/lib/smbldap.c 15 Sep 2003 14:24:03 -0000 1.1.1.1.2.2
@@ -97,6 +97,8 @@
{ LDAP_ATTR_DOMAIN, "sambaDomainName" },
{ LDAP_ATTR_OBJCLASS, "objectClass" },
{ LDAP_ATTR_ACB_INFO, "sambaAcctFlags" },
+ { LDAP_ATTR_BAD_PWD_COUNT, "sambaBadPwdCount" },
+ { LDAP_ATTR_LOCKOUT_TIME, "sambaLockoutTime" },
{ LDAP_ATTR_LIST_END, NULL }
};
Index: source/passdb/passdb.c
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/source/passdb/passdb.c,v
retrieving revision 1.1.1.1.4.1
retrieving revision 1.1.1.1.2.6
diff -u -r1.1.1.1.4.1 -r1.1.1.1.2.6
--- source/passdb/passdb.c 15 Sep 2003 09:59:16 -0000 1.1.1.1.4.1
+++ source/passdb/passdb.c 15 Sep 2003 14:24:04 -0000 1.1.1.1.2.6
@@ -78,6 +78,7 @@
user->private.pass_can_change_time = (time_t)0;
user->private.logoff_time =
user->private.kickoff_time =
+ user->private.lockout_time = (time_t)0;
user->private.pass_must_change_time = get_time_t_max();
user->private.unknown_3 = 0x00ffffff; /* don't know */
user->private.logon_divs = 168; /* hours per week */
@@ -85,6 +86,7 @@
memset(user->private.hours, 0xff, user->private.hours_len); /* available at all hours */
user->private.unknown_5 = 0x00000000; /* don't know */
user->private.unknown_6 = 0x000004ec; /* don't know */
+ user->private.bad_pwd_count = 0;
/* Some parts of samba strlen their pdb_get...() returns,
so this keeps the interface unchanged for now. */
@@ -1269,7 +1271,7 @@
Marshall/unmarshall SAM_ACCOUNT structs.
*********************************************************************/
-#define TDB_FORMAT_STRING "ddddddBBBBBBBBBBBBddBBwdwdBdd"
+#define TDB_FORMAT_STRING "dddddddBBBBBBBBBBBBddBBwdwdBddd"
/**********************************************************************
Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
@@ -1284,6 +1286,7 @@
uint32 logon_time,
logoff_time,
kickoff_time,
+ lockout_time,
pass_last_set_time,
pass_can_change_time,
pass_must_change_time;
@@ -1304,7 +1307,7 @@
fullname_len, homedir_len, logon_script_len,
profile_path_len, acct_desc_len, workstations_len;
- uint32 user_rid, group_rid, unknown_3, hours_len, unknown_5, unknown_6;
+ uint32 user_rid, group_rid, unknown_3, hours_len, unknown_5, unknown_6, bad_pwd_count;
uint16 acct_ctrl, logon_divs;
uint8 *hours;
static uint8 *lm_pw_ptr, *nt_pw_ptr;
@@ -1322,6 +1325,7 @@
&logon_time,
&logoff_time,
&kickoff_time,
+ &lockout_time,
&pass_last_set_time,
&pass_can_change_time,
&pass_must_change_time,
@@ -1347,7 +1351,8 @@
&hours_len,
&hourslen, &hours,
&unknown_5,
- &unknown_6);
+ &unknown_6,
+ &bad_pwd_count);
if (len == -1) {
ret = False;
@@ -1357,6 +1362,7 @@
pdb_set_logon_time(sampass, logon_time, PDB_SET);
pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
+ pdb_set_lockout_time(sampass, lockout_time, PDB_SET);
pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
@@ -1426,6 +1432,7 @@
pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
pdb_set_hours(sampass, hours, PDB_SET);
+ pdb_set_bad_pwd_count(sampass, bad_pwd_count, PDB_SET);
done:
@@ -1460,11 +1467,12 @@
uint32 logon_time,
logoff_time,
kickoff_time,
+ lockout_time,
pass_last_set_time,
pass_can_change_time,
pass_must_change_time;
- uint32 user_rid, group_rid;
+ uint32 user_rid, group_rid, bad_pwd_count;
const char *username;
const char *domain;
@@ -1500,6 +1508,7 @@
logon_time = (uint32)pdb_get_logon_time(sampass);
logoff_time = (uint32)pdb_get_logoff_time(sampass);
kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
+ lockout_time = (uint32)pdb_get_lockout_time(sampass);
pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
@@ -1598,13 +1607,15 @@
if (munged_dial)
munged_dial_len = strlen(munged_dial) +1;
else
- munged_dial_len = 0;
-
+ munged_dial_len = 0;
+
+
/* one time to get the size needed */
len = tdb_pack(NULL, 0, TDB_FORMAT_STRING,
logon_time,
logoff_time,
kickoff_time,
+ lockout_time,
pass_last_set_time,
pass_can_change_time,
pass_must_change_time,
@@ -1630,7 +1641,8 @@
pdb_get_hours_len(sampass),
MAX_HOURS_LEN, pdb_get_hours(sampass),
pdb_get_unknown_5(sampass),
- pdb_get_unknown_6(sampass));
+ pdb_get_unknown_6(sampass),
+ pdb_get_bad_pwd_count(sampass));
if (size_only)
@@ -1647,6 +1659,7 @@
logon_time,
logoff_time,
kickoff_time,
+ lockout_time,
pass_last_set_time,
pass_can_change_time,
pass_must_change_time,
@@ -1672,7 +1685,8 @@
pdb_get_hours_len(sampass),
MAX_HOURS_LEN, pdb_get_hours(sampass),
pdb_get_unknown_5(sampass),
- pdb_get_unknown_6(sampass));
+ pdb_get_unknown_6(sampass),
+ pdb_get_bad_pwd_count(sampass));
/* check to make sure we got it correct */
Index: source/passdb/pdb_get_set.c
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/source/passdb/pdb_get_set.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -r1.1.1.1 -r1.1.1.1.2.1
--- source/passdb/pdb_get_set.c 11 Sep 2003 15:45:32 -0000 1.1.1.1
+++ source/passdb/pdb_get_set.c 11 Sep 2003 15:58:28 -0000 1.1.1.1.2.1
@@ -339,6 +339,28 @@
}
/*********************************************************************
+ Get the user's bad password count.
+ ********************************************************************/
+uint32 pdb_get_bad_pwd_count (const SAM_ACCOUNT *sampass)
+{
+ if(sampass)
+ return (sampass->private.bad_pwd_count);
+ else
+ return (-1);
+}
+
+/*********************************************************************
+ Get the user's lockout_time.
+ ********************************************************************/
+time_t pdb_get_lockout_time (const SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->private.lockout_time);
+ else
+ return (-1);
+}
+
+/*********************************************************************
Collection of set...() functions for SAM_ACCOUNT.
********************************************************************/
@@ -1122,4 +1144,30 @@
return False;
return True;
+}
+
+/*********************************************************************
+ Set the user's bad_pwd_count
+ ********************************************************************/
+BOOL pdb_set_bad_pwd_count (SAM_ACCOUNT *sampass, uint32 badpwdcount, enum pdb_value_state flag)
+{
+ if (!sampass)
+ return False;
+
+ sampass->private.bad_pwd_count = badpwdcount;
+
+ return pdb_set_init_flags(sampass, PDB_BADPWDCOUNT, flag);
+}
+
+/********************************************************************
+ Set the user's lockout time
+ *******************************************************************/
+BOOL pdb_set_lockout_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
+{
+ if (!sampass)
+ return False;
+
+ sampass->private.lockout_time = mytime;
+
+ return pdb_set_init_flags(sampass, PDB_LOCKOUTTIME, flag);
}
Index: source/passdb/pdb_ldap.c
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/source/passdb/pdb_ldap.c,v
retrieving revision 1.1.1.1.4.1
retrieving revision 1.1.1.1.2.3
diff -u -r1.1.1.1.4.1 -r1.1.1.1.2.3
--- source/passdb/pdb_ldap.c 15 Sep 2003 09:59:16 -0000 1.1.1.1.4.1
+++ source/passdb/pdb_ldap.c 15 Sep 2003 14:34:56 -0000 1.1.1.1.2.3
@@ -405,7 +405,8 @@
kickoff_time,
pass_last_set_time,
pass_can_change_time,
- pass_must_change_time;
+ pass_must_change_time,
+ lockout_time;
pstring username,
domain,
nt_username,
@@ -417,7 +418,8 @@
acct_desc,
munged_dial,
workstations;
- uint32 user_rid;
+ uint32 user_rid,
+ badpwdcount;
uint8 smblmpwd[LM_HASH_LEN],
smbntpwd[NT_HASH_LEN];
uint16 acct_ctrl = 0,
@@ -585,6 +587,22 @@
pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
}
+ if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
+ get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PWD_COUNT), temp)) {
+ /* leave as default */
+ } else {
+ badpwdcount = (uint32) atol(temp);
+ pdb_set_bad_pwd_count(sampass, badpwdcount, PDB_SET);
+ }
+
+ if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
+ get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOCKOUT_TIME), temp)) {
+ /* leave as default */
+ } else {
+ lockout_time = (time_t) atol(temp);
+ pdb_set_lockout_time(sampass, lockout_time, PDB_SET);
+ }
+
/* recommend that 'gecos' and 'displayName' should refer to the same
* attribute OID. userFullName depreciated, only used by Samba
* primary rules of LDAP: don't make a new attribute when one is already defined
@@ -878,6 +896,17 @@
if (need_update(sampass, PDB_MUSTCHANGETIME))
smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
+
+ slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_bad_pwd_count(sampass));
+ if (need_update(sampass, PDB_BADPWDCOUNT))
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
+ get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PWD_COUNT), temp);
+
+ slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_lockout_time(sampass));
+ if (need_update(sampass, PDB_LOCKOUTTIME))
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
+ get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOCKOUT_TIME), temp);
+
if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
|| (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
Index: source/passdb/pdb_mysql.c
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/source/passdb/pdb_mysql.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -r1.1.1.1 -r1.1.1.1.2.1
--- source/passdb/pdb_mysql.c 11 Sep 2003 15:45:32 -0000 1.1.1.1
+++ source/passdb/pdb_mysql.c 11 Sep 2003 15:58:28 -0000 1.1.1.1.2.1
@@ -22,6 +22,10 @@
#include <mysql/mysql.h>
#define CONFIG_TABLE_DEFAULT "user"
+
+#define CONFIG_BAD_PWD_COUNT_DEFAULT "bad_pwd_count"
+#define CONFIG_LOCKOUT_TIME_DEFAULT "lockout_time"
+
#define CONFIG_LOGON_TIME_DEFAULT "logon_time"
#define CONFIG_LOGOFF_TIME_DEFAULT "logoff_time"
#define CONFIG_KICKOFF_TIME_DEFAULT "kickoff_time"
@@ -262,6 +266,9 @@
pdb_set_unknown_5(u, xatol(row[27]), PDB_SET);
pdb_set_unknown_6(u, xatol(row[28]), PDB_SET);
+ pdb_set_bad_pwd_count(u, xatol(row[29]), PDB_SET);
+ pdb_set_lockout_time(u, xatol(row[30]), PDB_SET);
+
return NT_STATUS_OK;
}
@@ -278,7 +285,7 @@
}
asprintf(&query,
- "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s",
+ "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s",
config_value_read(data, "logon time column",
CONFIG_LOGON_TIME_DEFAULT),
config_value_read(data, "logoff time column",
@@ -337,6 +344,10 @@
CONFIG_UNKNOWN_5_DEFAULT),
config_value_read(data, "unknown 6 column",
CONFIG_UNKNOWN_6_DEFAULT),
+ config_value_read(data, "bad pwd count column",
+ CONFIG_BAD_PWD_COUNT_DEFAULT),
+ config_value_read(data, "lockout time column",
+ CONFIG_LOCKOUT_TIME_DEFAULT),
config_value(data, "table", CONFIG_TABLE_DEFAULT)
);
DEBUG(5, ("Executing query %s\n", query));
@@ -442,7 +453,7 @@
}
asprintf(&query,
- "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s WHERE %s = '%s'",
+ "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s WHERE %s = '%s'",
config_value_read(data, "logon time column",
CONFIG_LOGON_TIME_DEFAULT),
config_value_read(data, "logoff time column",
@@ -501,6 +512,10 @@
CONFIG_UNKNOWN_5_DEFAULT),
config_value_read(data, "unknown 6 column",
CONFIG_UNKNOWN_6_DEFAULT),
+ config_value_read(data, "bad pwd count column",
+ CONFIG_BAD_PWD_COUNT_DEFAULT),
+ config_value_read(data, "lockout time column",
+ CONFIG_LOCKOUT_TIME_DEFAULT),
config_value(data, "table", CONFIG_TABLE_DEFAULT), field,
esc_sname);
@@ -747,6 +762,18 @@
pdb_get_logon_divs(newpwd));
}
+
+ pdb_mysql_int_field(methods, &query,
+ config_value_write(data, "bad pwd count column",
+ CONFIG_BAD_PWD_COUNT_DEFAULT),
+ pdb_get_bad_pwd_count(newpwd));
+
+ pdb_mysql_int_field(methods, &query,
+ config_value_write(data, "lockout time column",
+ CONFIG_LOCKOUT_TIME_DEFAULT),
+ pdb_get_lockout_time(newpwd));
+
+
pdb_mysql_string_field(methods, &query,
config_value_write(data, "user sid column",
CONFIG_USER_SID_DEFAULT),
Index: source/passdb/pdb_xml.c
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/source/passdb/pdb_xml.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.2
diff -u -r1.1.1.1 -r1.1.1.1.2.2
--- source/passdb/pdb_xml.c 11 Sep 2003 15:45:32 -0000 1.1.1.1
+++ source/passdb/pdb_xml.c 16 Sep 2003 10:03:56 -0000 1.1.1.1.2.2
@@ -169,6 +169,16 @@
atol(xmlNodeListGetString
(doc, cur->xmlChildrenNode, 1)), PDB_SET);
+ else if (!strcmp(cur->name, "bad_pwd_count") && cur->ns == ns)
+ pdb_set_bad_pwd_count(u,
+ atol(xmlNodeListGetString
+ (doc, cur->xmlChildrenNode, 1)), PDB_SET);
+
+ else if (!strcmp(cur->name, "lockout_time") && cur->ns == ns)
+ pdb_set_lockout_time(u,
+ atol(xmlNodeListGetString
+ (doc, cur->xmlChildrenNode, 1)), PDB_SET);
+
else if (!strcmp(cur->name, "homedir") && cur->ns == ns)
pdb_set_homedir(u,
xmlNodeListGetString(doc, cur->xmlChildrenNode,
@@ -410,7 +420,7 @@
sid_to_string(sid_str, pdb_get_group_sid(u)));
if (pdb_get_init_flags(u, PDB_LOGONTIME) != PDB_DEFAULT)
- xmlNewChild(user, data->ns, "login_time",
+ xmlNewChild(user, data->ns, "logon_time",
iota(pdb_get_logon_time(u)));
if (pdb_get_init_flags(u, PDB_LOGOFFTIME) != PDB_DEFAULT)
@@ -421,6 +431,10 @@
xmlNewChild(user, data->ns, "kickoff_time",
iota(pdb_get_kickoff_time(u)));
+ if (pdb_get_init_flags(u, PDB_LOCKOUTTIME) != PDB_DEFAULT)
+ xmlNewChild(user, data->ns, "lockout_time",
+ iota(pdb_get_lockout_time(u)));
+
if (pdb_get_domain(u) && strcmp(pdb_get_domain(u), ""))
xmlNewChild(user, data->ns, "domain", pdb_get_domain(u));
@@ -497,6 +511,9 @@
xmlNewChild(user, data->ns, "unknown_5", iota(pdb_get_unknown_5(u)));
xmlNewChild(user, data->ns, "unknown_6", iota(pdb_get_unknown_6(u)));
+ xmlNewChild(user, data->ns, "bad_pwd_count", iota(pdb_get_bad_pwd_count(u)));
+
+
xmlSaveFile(data->location, data->doc);
return NT_STATUS_OK;
Index: source/rpc_server/srv_samr_util.c
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/source/rpc_server/srv_samr_util.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -r1.1.1.1 -r1.1.1.1.2.1
--- source/rpc_server/srv_samr_util.c 11 Sep 2003 15:45:32 -0000 1.1.1.1
+++ source/rpc_server/srv_samr_util.c 11 Sep 2003 15:58:28 -0000 1.1.1.1.2.1
@@ -186,6 +186,8 @@
DEBUG(10,("INFO_21 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info));
if (from->acb_info != pdb_get_acct_ctrl(to)) {
+ if ((pdb_get_acct_ctrl(to) & ACB_AUTOLOCK) && !(from->acb_info & ACB_AUTOLOCK))
+ pdb_set_bad_pwd_count(to, 0, PDB_CHANGED);
pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
}
@@ -390,7 +392,8 @@
}
DEBUG(10,("INFO_23 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info));
- if (from->acb_info != pdb_get_acct_ctrl(to)) {
+ if ((from->acb_info != pdb_get_acct_ctrl(to)) && (from->acb_info)) {
+
pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
}
Index: source/utils/pdbedit.c
===================================================================
RCS file: /opt/cvs/prj/infra/serveur_proximite/samba/source/source/utils/pdbedit.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.2
diff -u -r1.1.1.1 -r1.1.1.1.2.2
--- source/utils/pdbedit.c 11 Sep 2003 15:45:33 -0000 1.1.1.1
+++ source/utils/pdbedit.c 15 Sep 2003 14:34:56 -0000 1.1.1.1.2.2
@@ -47,6 +47,7 @@
#define BIT_RESERV_7 0x00800000
#define BIT_IMPORT 0x01000000
#define BIT_EXPORT 0x02000000
+#define BIT_BADPWDRESET 0x04000000
#define MASK_ALWAYS_GOOD 0x0000001F
#define MASK_USER_GOOD 0x00401F00
@@ -144,6 +145,9 @@
tmp = pdb_get_kickoff_time(sam_pwent);
printf ("Kickoff time: %s\n", tmp ? http_timestring(tmp) : "0");
+ tmp = pdb_get_lockout_time(sam_pwent);
+ printf ("Lockout time: %s\n", tmp ? http_timestring(tmp) : "0");
+
tmp = pdb_get_pass_last_set_time(sam_pwent);
printf ("Password last set: %s\n", tmp ? http_timestring(tmp) : "0");
@@ -153,6 +157,8 @@
tmp = pdb_get_pass_must_change_time(sam_pwent);
printf ("Password must change: %s\n", tmp ? http_timestring(tmp) : "0");
+ printf ("Bad password attempts: %d\n", pdb_get_bad_pwd_count(sam_pwent));
+
} else if (smbpwdstyle) {
char lm_passwd[33];
char nt_passwd[33];
@@ -241,6 +247,7 @@
const char *fullname, const char *homedir,
const char *drive, const char *script,
const char *profile, const char *account_control,
+ const BOOL badpwd,
const char *user_sid, const char *group_sid)
{
SAM_ACCOUNT *sam_pwent=NULL;
@@ -282,6 +289,10 @@
(pdb_get_acct_ctrl(sam_pwent) & not_settable) | newflag,
PDB_CHANGED);
}
+
+ if (badpwd)
+ pdb_set_bad_pwd_count(sam_pwent, 0, PDB_CHANGED);
+
if (user_sid) {
DOM_SID u_sid;
if (!string_to_sid(&u_sid, user_sid)) {
@@ -548,6 +559,7 @@
static char *user_sid = NULL;
static char *group_sid = NULL;
static long int account_policy_value = 0;
+ static BOOL badpwd_reset = False;
BOOL account_policy_value_set = False;
struct pdb_context *bin;
@@ -578,6 +590,7 @@
{"account-policy", 'P', POPT_ARG_STRING, &account_policy, 0,"value of an account policy (like maximum password age)",NULL},
{"value", 'C', POPT_ARG_LONG, &account_policy_value, 'C',"set the account policy to this value", NULL},
{"account-control", 'c', POPT_ARG_STRING, &account_control, 0, "Values of account control", NULL},
+ {"badpwdcount-reset", 'z', POPT_ARG_NONE, &badpwd_reset, 0, "reset bad password count", NULL},
POPT_COMMON_SAMBA
POPT_TABLEEND
};
@@ -629,7 +642,8 @@
(account_policy ? BIT_ACCPOLICY : 0) +
(account_policy_value_set ? BIT_ACCPOLVAL : 0) +
(backend_in ? BIT_IMPORT : 0) +
- (backend_out ? BIT_EXPORT : 0);
+ (backend_out ? BIT_EXPORT : 0) +
+ (badpwd_reset ? BIT_BADPWDRESET : 0);
if (setparms & BIT_BACKEND) {
if (!NT_STATUS_IS_OK(make_pdb_context_string(&bdef, backend))) {
@@ -722,7 +736,12 @@
/* mask out users options */
checkparms &= ~MASK_USER_GOOD;
-
+
+ if (checkparms & BIT_BADPWDRESET) {
+ checkparms |= BIT_MODIFY;
+ checkparms &= ~BIT_BADPWDRESET;
+ }
+
/* account operation */
if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) {
/* check use of -u option */
@@ -758,6 +777,7 @@
home_drive,
logon_script,
profile_path, account_control,
+ badpwd_reset,
user_sid, group_sid);
}
}
More information about the samba-technical
mailing list