implementing password lockout
Aurélien Degrémont
aurelien.degremont at idealx.com
Mon Jan 26 15:08:58 GMT 2004
I'll try to clarify the bad password count system..
First, it's sure a field is missing in our sam_account struct, we must
store the lockout time, as my patch did it, it is necessary to unlock it
when lock period is elapsed.
Concerning this, note that the "lockout time" is never provided in SAMR
packets, even if NT do store it, it is only used internaly or during
replication. We (with Richard) only see this once inside a NETLOGON
struct, working on NT replication (Richard really need to post a patch
only concerning all the breakthroughts on netlogon :)).
Second, note that the previously known unknow_3 field only apply to SAMR
protocol, and as far as i know, netlogon doesn't implement something
like this. So, i suppose each deltas sent during a replication are
always totally filled. I cannot test this now. But the microsoft
documentation you sent, explain this.
(http://support.microsoft.com/default.aspx?scid=kb;en-us;297157).
We need, at least, to add 2 fields to sam accounts : a bad password
count, and a lockout time.
I've attached my patch concerning this. It's 2-month old and doesn't
manage ldap replication issues, but the other mecanisms are correct.
Look at it.
Each DC maintains the number of bad password count. So, if the PDC is
down, the BDC will look to the count and acct flags stored in their SAM db.
Aurélien
Jim McDonough wrote:
> Simo, thanks for clarifying that...but I still have a few issues to
> clear up, since we don't (yet) have real windows replication:
>
> When the bad password count isn't replicated, if we're using LDAP
> replication, we're going to replicate it, so we'll have to store a
> time for the last bad password, no? We can't choose to selectively
> replicate attributes sometimes, but not others. This is what Jianliang
> has in his patch, and it makes sense to me.
>
> I still think we need a local version, though, because if we don't,
> then if the PDC is down what happens when a user enters a bad
> password? A correct password should be OK, but a bad password attempt...?
>
> ----------------------------
> Jim McDonough
> IBM Linux Technology Center
> Samba Team
> 6 Minuteman Drive
> Scarborough, ME 04074
> USA
>
> jmcd at us.ibm.com
> jmcd at samba.org
>
> Phone: (207) 885-5565
> IBM tie-line: 776-9984
>
-------------- next part --------------
diff -ruN samba-3.0.1pre1/examples/pdb/mysql/mysql.dump samba-badpwdcount-3.0.1pre1/examples/pdb/mysql/mysql.dump
--- samba-3.0.1pre1/examples/pdb/mysql/mysql.dump 2003-06-07 19:57:30.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/examples/pdb/mysql/mysql.dump 2003-11-17 10:11:10.000000000 +0100
@@ -31,5 +31,6 @@
logon_divs int(9),
hours_len int(9),
unknown_5 int(9),
- unknown_6 int(9)
+ unknown_6 int(9),
+ lockout_time int(9)
);
diff -ruN samba-3.0.1pre1/examples/pdb/mysql/smb.conf samba-badpwdcount-3.0.1pre1/examples/pdb/mysql/smb.conf
--- samba-3.0.1pre1/examples/pdb/mysql/smb.conf 2003-06-07 19:57:30.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/examples/pdb/mysql/smb.conf 2003-11-17 10:15:35.000000000 +0100
@@ -4,7 +4,7 @@
security = domain
domain logons = yes
domain master = yes
-passdb backend = plugin:/usr/local/samba/lib/pdb_mysql.so:mysql
+passdb backend = mysql:samba1
mysql:mysql host = rhonwyn
mysql:mysql user = samba
mysql:mysql password = ambas
diff -ruN samba-3.0.1pre1/source/auth/auth_sam.c samba-badpwdcount-3.0.1pre1/source/auth/auth_sam.c
--- samba-3.0.1pre1/source/auth/auth_sam.c 2003-10-10 20:08:34.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/source/auth/auth_sam.c 2003-11-17 10:57:40.000000000 +0100
@@ -407,6 +407,9 @@
NTSTATUS nt_status;
uint8 user_sess_key[16];
const uint8* lm_hash;
+ uint32 account_policy_lockout, account_policy_lockout_duration;
+ uint16 badpwdcount;
+ time_t lockout_time;
if (!user_info || !auth_context) {
return NT_STATUS_UNSUCCESSFUL;
@@ -429,13 +432,67 @@
pdb_free_sam(&sampass);
return NT_STATUS_NO_SUCH_USER;
}
-
+
+
+ /* if the account is locked, unlock it if lockout duration is expired */
+ if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) {
+ lockout_time = 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();
+ }
+ }
+
+
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 = pdb_get_bad_password_count(sampass) + 1;
+ if (!pdb_set_bad_password_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;
}
+
+ /* reset badpwdcount if account is normal*/
+ if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
+ if (!pdb_set_bad_password_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);
diff -ruN samba-3.0.1pre1/source/include/passdb.h samba-badpwdcount-3.0.1pre1/source/include/passdb.h
--- samba-3.0.1pre1/source/include/passdb.h 2003-10-10 20:08:34.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/source/include/passdb.h 2003-11-17 12:05:25.000000000 +0100
@@ -36,6 +36,7 @@
PDB_LOGONSCRIPT,
PDB_LOGONTIME,
PDB_LOGOFFTIME,
+ PDB_LOCKOUTTIME,
PDB_KICKOFFTIME,
PDB_CANCHANGETIME,
PDB_MUSTCHANGETIME,
@@ -105,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;
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 */
diff -ruN samba-3.0.1pre1/source/lib/smbldap.c samba-badpwdcount-3.0.1pre1/source/lib/smbldap.c
--- samba-3.0.1pre1/source/lib/smbldap.c 2003-09-11 20:05:44.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/source/lib/smbldap.c 2003-11-17 10:11:10.000000000 +0100
@@ -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 }
};
diff -ruN samba-3.0.1pre1/source/passdb/passdb.c samba-badpwdcount-3.0.1pre1/source/passdb/passdb.c
--- samba-3.0.1pre1/source/passdb/passdb.c 2003-10-10 20:08:36.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/source/passdb/passdb.c 2003-11-17 14:49:42.000000000 +0100
@@ -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 */
@@ -1303,6 +1304,7 @@
uint32 logon_time,
logoff_time,
kickoff_time,
+ lockout_time,
pass_last_set_time,
pass_can_change_time,
pass_must_change_time;
@@ -1342,6 +1344,7 @@
&logon_time,
&logoff_time,
&kickoff_time,
+ &lockout_time,
&pass_last_set_time,
&pass_can_change_time,
&pass_must_change_time,
@@ -1378,6 +1381,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);
@@ -1482,11 +1486,13 @@
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;
+ uint16 bad_pwd_count;
const char *username;
const char *domain;
@@ -1522,6 +1528,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);
@@ -1627,6 +1634,7 @@
logon_time,
logoff_time,
kickoff_time,
+ lockout_time,
pass_last_set_time,
pass_can_change_time,
pass_must_change_time,
@@ -1670,6 +1678,7 @@
logon_time,
logoff_time,
kickoff_time,
+ lockout_time,
pass_last_set_time,
pass_can_change_time,
pass_must_change_time,
diff -ruN samba-3.0.1pre1/source/passdb/pdb_get_set.c samba-badpwdcount-3.0.1pre1/source/passdb/pdb_get_set.c
--- samba-3.0.1pre1/source/passdb/pdb_get_set.c 2003-10-10 20:08:36.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/source/passdb/pdb_get_set.c 2003-11-17 10:11:11.000000000 +0100
@@ -347,6 +347,17 @@
}
/*********************************************************************
+ 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.
********************************************************************/
@@ -1141,3 +1152,16 @@
return True;
}
+
+/********************************************************************
+ 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);
+}
diff -ruN samba-3.0.1pre1/source/passdb/pdb_ldap.c samba-badpwdcount-3.0.1pre1/source/passdb/pdb_ldap.c
--- samba-3.0.1pre1/source/passdb/pdb_ldap.c 2003-10-10 20:08:36.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/source/passdb/pdb_ldap.c 2003-11-17 14:52:05.000000000 +0100
@@ -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,
@@ -420,9 +421,9 @@
uint32 user_rid;
uint8 smblmpwd[LM_HASH_LEN],
smbntpwd[NT_HASH_LEN];
- uint16 acct_ctrl = 0,
+ uint16 acct_ctrl = 0,
logon_divs;
- uint16 bad_password_count = 0,
+ uint16 bad_password_count = 0,
logon_count = 0;
uint32 hours_len;
uint8 hours[MAX_HOURS_LEN];
@@ -587,6 +588,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_password_count(sampass, bad_pasword_count, 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
@@ -897,6 +914,17 @@
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_password_count(sampass));
+ if (need_update(sampass, PDB_BAD_PASSWORD_COUNT))
+ 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)) {
diff -ruN samba-3.0.1pre1/source/passdb/pdb_mysql.c samba-badpwdcount-3.0.1pre1/source/passdb/pdb_mysql.c
--- samba-3.0.1pre1/source/passdb/pdb_mysql.c 2003-10-10 20:08:36.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/source/passdb/pdb_mysql.c 2003-11-17 14:44:21.000000000 +0100
@@ -25,6 +25,7 @@
#define CONFIG_LOGON_TIME_DEFAULT "logon_time"
#define CONFIG_LOGOFF_TIME_DEFAULT "logoff_time"
#define CONFIG_KICKOFF_TIME_DEFAULT "kickoff_time"
+#define CONFIG_LOCKOUT_TIME_DEFAULT "lockout_time"
#define CONFIG_PASS_LAST_SET_TIME_DEFAULT "pass_last_set_time"
#define CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT "pass_can_change_time"
#define CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT "pass_must_change_time"
@@ -269,6 +270,7 @@
pdb_set_bad_password_count(u, xatol(row[27]), PDB_SET);
pdb_set_logon_count(u, xatol(row[28]), PDB_SET);
pdb_set_unknown_6(u, xatol(row[29]), PDB_SET);
+ pdb_set_lockout_time(u, xatol(row[30]), PDB_SET);
return NT_STATUS_OK;
}
@@ -286,7 +288,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,%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,%s FROM %s",
config_value_read(data, "logon time column",
CONFIG_LOGON_TIME_DEFAULT),
config_value_read(data, "logoff time column",
@@ -347,6 +349,8 @@
CONFIG_LOGON_COUNT_DEFAULT),
config_value_read(data, "unknown 6 column",
CONFIG_UNKNOWN_6_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));
@@ -452,7 +456,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,%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,%s FROM %s WHERE %s = '%s'",
config_value_read(data, "logon time column",
CONFIG_LOGON_TIME_DEFAULT),
config_value_read(data, "logoff time column",
@@ -513,6 +517,8 @@
CONFIG_LOGON_COUNT_DEFAULT),
config_value_read(data, "unknown 6 column",
CONFIG_UNKNOWN_6_DEFAULT),
+ config_value_read(data, "lockout time column",
+ CONFIG_LOCKOUT_TIME_DEFAULT),
config_value(data, "table", CONFIG_TABLE_DEFAULT), field,
esc_sname);
@@ -761,6 +767,13 @@
pdb_get_logon_divs(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),
diff -ruN samba-3.0.1pre1/source/passdb/pdb_xml.c samba-badpwdcount-3.0.1pre1/source/passdb/pdb_xml.c
--- samba-3.0.1pre1/source/passdb/pdb_xml.c 2003-10-10 20:08:36.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/source/passdb/pdb_xml.c 2003-11-17 14:35:35.000000000 +0100
@@ -174,6 +174,11 @@
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,
@@ -426,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));
diff -ruN samba-3.0.1pre1/source/rpc_server/srv_samr_util.c samba-badpwdcount-3.0.1pre1/source/rpc_server/srv_samr_util.c
--- samba-3.0.1pre1/source/rpc_server/srv_samr_util.c 2003-10-10 20:08:36.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/source/rpc_server/srv_samr_util.c 2003-11-17 14:52:51.000000000 +0100
@@ -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_password_count(to, 0, PDB_CHANGED);
pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
}
@@ -395,7 +397,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 && (from->acb_info != pdb_get_acct_ctrl(to))) {
+
pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
}
diff -ruN samba-3.0.1pre1/source/utils/pdbedit.c samba-badpwdcount-3.0.1pre1/source/utils/pdbedit.c
--- samba-3.0.1pre1/source/utils/pdbedit.c 2003-09-24 19:16:13.000000000 +0200
+++ samba-badpwdcount-3.0.1pre1/source/utils/pdbedit.c 2003-11-17 11:26:03.000000000 +0100
@@ -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_password_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_password_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