I have implemented the "bad password attempt lockout" policy. If an user 
attempt with the bad password more than the count setted in the policy, then 
his account will be auto-locked, like what did NT. The implementation is only 
for LDAP passdb backend.
To do this, I have to introduce a new integer attribute in 
samba.schema, "badPwAttempt".
Folllowing are the patches, any comments?



Jianliang Lu
TieSse s.p.a.
Via Jervis, 60.  10015 Ivrea (To) - Italy
[EMAIL PROTECTED]
[EMAIL PROTECTED]
--- samba-3.0alpha22-orig/source/auth/auth_sam.c        Mon Feb 17 16:31:06 2003
+++ samba-3.0alpha22-orig/source/auth/auth_sam.c.fix    Thu Mar 27 12:40:10 2003
@@ -326,6 +326,12 @@
                return NT_STATUS_ACCOUNT_DISABLED;
        }
 
+       /* 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;
+       }
+
        /* Test account expire time */
        
        kickoff_time = pdb_get_kickoff_time(sampass);
@@ -414,6 +420,7 @@
        NTSTATUS nt_status;
        uint8 user_sess_key[16];
        const uint8* lm_hash;
+       uint32 account_policy_lockout, badpwattempt;
 
        if (!user_info || !auth_context) {
                return NT_STATUS_UNSUCCESSFUL;
@@ -448,10 +455,43 @@
        nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, 
user_sess_key);
 
        if (!NT_STATUS_IS_OK(nt_status)) {
+               if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD)) {      
+                       badpwattempt = (uint32)pdb_get_bad_pw_attempt(sampass) + 1;
+                       if (!pdb_set_bad_pw_attempt(sampass, badpwattempt, 
PDB_CHANGED))
+                                       DEBUG(1, ("Failed to set 'badPwAttempt' for 
user % s. \n", 
+                                                                
user_info->internal_username.str));
+                       account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, 
&account_policy_lockout);
+                       if (badpwattempt >= account_policy_lockout)
+                               if (!pdb_set_acct_ctrl (sampass, 
+                                                                               
pdb_get_acct_ctrl(sampass) |ACB_AUTOLOCK, 
+                                                                               
PDB_CHANGED)) {
+                                       DEBUG(1, ("Failed to set 'disabled' flag 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 (!pdb_set_bad_pw_attempt(sampass, 0, PDB_CHANGED))
+                       DEBUG(1, ("Failed to set 'badPwAttempt' 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 fialed!\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();
+
        if (!NT_STATUS_IS_OK(nt_status = make_server_info_sam(server_info, sampass))) 
{         
                DEBUG(0,("check_sam_security: make_server_info_sam() failed with 
'%s'\n", nt_errstr(nt_status)));
                return nt_status;
--- samba-3.0alpha22-orig/source/passdb/passdb.c        Mon Feb 24 16:12:31 2003
+++ samba-3.0alpha22-orig/source/passdb/passdb.c.fix    Thu Mar 27 12:40:10 2003
@@ -60,6 +60,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_pw_attempt = 0; /* bad password attemp count */
 
        /* Some parts of samba strlen their pdb_get...() returns, 
           so this keeps the interface unchanged for now. */
--- samba-3.0alpha22-orig/source/passdb/pdb_get_set.c   Thu Jan  9 20:05:59 2003
+++ samba-3.0alpha22-orig/source/passdb/pdb_get_set.c.fix       Thu Mar 27 12:40:10 
2003
@@ -172,6 +172,14 @@
                return (NULL);
 }      
 
+uint32 pdb_get_bad_pw_attempt (const SAM_ACCOUNT *sampass)
+{
+       if (sampass)
+               return (sampass->private.bad_pw_attempt);
+       else
+               return (-1);
+}
+
 /**
  * Get flags showing what is initalised in the SAM_ACCOUNT
  * @param sampass the SAM_ACCOUNT in question
@@ -1038,6 +1046,16 @@
        return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
 }
 
+BOOL pdb_set_bad_pw_attempt (SAM_ACCOUNT *sampass, uint32 badpwattempt, enum 
pdb_value_state flag)
+{
+       if (!sampass)
+               return False;
+
+       sampass->private.bad_pw_attempt = badpwattempt;
+
+       return pdb_set_init_flags(sampass, PDB_BADPWATTEMPT, flag);
+}
+
 BOOL pdb_set_hours (SAM_ACCOUNT *sampass, const uint8 *hours, enum pdb_value_state 
flag)
 {
        if (!sampass)
@@ -1064,6 +1082,7 @@
 BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
 {
        uint32 expire;
+       uint32 min_age;
 
        if (!sampass)
                return False;
@@ -1082,6 +1101,16 @@
                        return False;
        }
        
+       if (!account_policy_get(AP_MIN_PASSWORD_AGE, &min_age) 
+           || (min_age==(uint32)-1)) {
+               if (!pdb_set_pass_can_change_time (sampass, 0, PDB_CHANGED))
+                       return False;
+       } else {
+               if (!pdb_set_pass_can_change_time (sampass, 
+                                                   pdb_get_pass_last_set_time(sampass)
+                                                   + min_age, PDB_CHANGED))
+                       return False;
+       }
        return True;
 }
 
--- samba-3.0alpha22-orig/source/passdb/pdb_ldap.c      Thu Mar 13 12:27:01 2003
+++ samba-3.0alpha22-orig/source/passdb/pdb_ldap.c.fix  Thu Mar 27 12:40:10 2003
@@ -149,7 +149,7 @@
                             "logoffTime", "kickoffTime", "cn",
                             "pwdCanChange", "pwdMustChange",
                             "displayName", "homeDrive",
-                            "smbHome", "scriptPath",
+                            "smbHome", "scriptPath", "badPwAttempt",
                             "profilePath", "description",
                             "userWorkstations", "rid",
                             "primaryGroupID", "lmPassword",
@@ -927,7 +927,8 @@
                        workstations;
        struct passwd   *pw;
        uint32          user_rid, 
-                       group_rid;
+                       group_rid,
+                       badpwattempt;
        uint8           smblmpwd[LM_HASH_LEN],
                        smbntpwd[NT_HASH_LEN];
        uint16          acct_ctrl = 0, 
@@ -980,6 +981,7 @@
        get_single_attribute(ldap_state->ldap_struct, entry, "rid", temp);
        user_rid = (uint32)atol(temp);
 
+
        pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
 
        if (!get_single_attribute(ldap_state->ldap_struct, entry, "primaryGroupID", 
temp)) {
@@ -1037,6 +1039,12 @@
                pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
        }
 
+       if (!get_single_attribute(ldap_state->ldap_struct, entry, "badPwAttempt", 
temp)) {
+               /* leave as default */
+       } else {
+               badpwattempt = (uint32)atol(temp);
+               pdb_set_bad_pw_attempt(sampass, badpwattempt, PDB_SET);
+       }
        if (!get_single_attribute(ldap_state->ldap_struct, entry, "logonTime", temp)) {
                /* leave as default */
        } else {
@@ -1309,6 +1317,11 @@
                make_a_mod(mods, ldap_op, "logonTime", temp);
        }
 
+       if (need_ldap_mod(pdb_add, sampass, PDB_BADPWATTEMPT)) {
+               slprintf(temp, sizeof(temp) - 1, "%li", 
pdb_get_bad_pw_attempt(sampass));
+               make_a_mod(mods, ldap_op, "badPwAttempt", temp);
+       }
+
        if (need_ldap_mod(pdb_add, sampass, PDB_LOGOFFTIME)) {
                slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
                make_a_mod(mods, ldap_op, "logoffTime", temp);
--- samba-3.0alpha22-orig/source/utils/pdbedit.c        Fri Feb 14 23:34:38 2003
+++ samba-3.0alpha22-orig/source/utils/pdbedit.c.fix    Thu Mar 27 12:40:10 2003
@@ -136,6 +136,7 @@
                tmp = pdb_get_pass_must_change_time(sam_pwent);
                printf ("Password must change: %s\n", tmp ? http_timestring(tmp) : 
"0");
                
+               printf ("Bad Password Attempt: %d\n", 
pdb_get_bad_pw_attempt(sam_pwent));
        } else if (smbpwdstyle) {
                if (IS_SAM_UNIX_USER(sam_pwent)) {
                        char lm_passwd[33];
--- ./samba-3.0alpha22-orig/examples/LDAP/samba.schema  Mon Jan  6 17:39:40 2003
+++ ./samba-3.0alpha22-orig/examples/LDAP/samba.schema.fix      Thu Mar 27 12:40:10 
2003
@@ -64,6 +64,11 @@
        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.19 NAME 'badPwAttempt'
+       DESC 'NT badPwAttempt'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
 ##
 ## string settings
 ##
@@ -134,7 +139,7 @@
 objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY
        DESC 'Samba Auxilary Account'
        MUST ( uid $ rid ) 
-       MAY  ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+       MAY  ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $ badPwAttempt $
                logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $ 
                displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
                description $ userWorkstations $ primaryGroupID $ domain ))
 
--- samba-3.0alpha22-orig/source/include/smb.h  Thu Feb 27 22:21:08 2003
+++ samba-3.0alpha22-orig/source/include/smb.h.fix      Thu Mar 27 12:40:10 2003
@@ -611,6 +611,7 @@
        PDB_UNKNOWN3,
        PDB_UNKNOWN5,
        PDB_UNKNOWN6,
+       PDB_BADPWATTEMPT,
        PDB_LMPASSWD,
        PDB_NTPASSWD,
 
@@ -684,6 +685,7 @@
                
                uint32 unknown_5; /* 0x0002 0000 */
                uint32 unknown_6; /* 0x0000 04ec */
+               uint32 bad_pw_attempt; /* count of bad password attempt */
        } private;
 
        /* Lets see if the remaining code can get the hint that you

Reply via email to