auth_winbind: Allow badPwdCount to be set to 0 with this auth method
authorGarming Sam <garming@catalyst.net.nz>
Mon, 3 Apr 2017 03:26:12 +0000 (15:26 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 30 May 2017 06:06:06 +0000 (08:06 +0200)
We rely on the other SAM modules to increment the badPwdCount locally,
but we must reset to 0 if the remote sends a success (to override our
failure).

Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/auth/ntlm/auth_sam.c
source4/auth/ntlm/auth_winbind.c
source4/auth/sam.c

index 54cc64375954139515069513afe7a7df6be06a64..cfe7455501be8be566cad27fc9d57c7954b94d9a 100644 (file)
@@ -41,35 +41,6 @@ NTSTATUS auth_sam_init(void);
 extern const char *user_attrs[];
 extern const char *domain_ref_attrs[];
 
-/****************************************************************************
- Look for the specified user in the sam, return ldb result structures
-****************************************************************************/
-
-static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
-                                      const char *account_name,
-                                      struct ldb_dn *domain_dn,
-                                      struct ldb_message **ret_msg)
-{
-       int ret;
-
-       /* pull the user attributes */
-       ret = dsdb_search_one(sam_ctx, mem_ctx, ret_msg, domain_dn, LDB_SCOPE_SUBTREE,
-                             user_attrs,
-                             DSDB_SEARCH_SHOW_EXTENDED_DN,
-                             "(&(sAMAccountName=%s)(objectclass=user))",
-                             ldb_binary_encode_string(mem_ctx, account_name));
-       if (ret == LDB_ERR_NO_SUCH_OBJECT) {
-               DEBUG(3,("sam_search_user: Couldn't find user [%s] in samdb, under %s\n", 
-                        account_name, ldb_dn_get_linearized(domain_dn)));
-               return NT_STATUS_NO_SUCH_USER;          
-       }
-       if (ret != LDB_SUCCESS) {
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       }
-       
-       return NT_STATUS_OK;
-}
-
 /****************************************************************************
  Do a specific test for an smb password being correct, given a smb_password and
  the lanman and NT responses.
index 7c815fc020e2c7a77c9597d47ab76529cf2fc6a7..41819dca60527fcd7df89b0e851286d19c76a5c9 100644 (file)
@@ -31,6 +31,7 @@
 #include "auth/auth_sam_reply.h"
 #include "libcli/security/security.h"
 #include "dsdb/samdb/samdb.h"
+#include "auth/auth_sam.h"
 
 _PUBLIC_ NTSTATUS auth4_winbind_init(TALLOC_CTX *);
 
@@ -107,6 +108,9 @@ static NTSTATUS winbind_check_password(struct auth_method_context *ctx,
        struct winbind_check_password_state *s;
        const struct auth_usersupplied_info *user_info_new;
        struct netr_IdentityInfo *identity_info;
+       struct ldb_dn *domain_dn;
+       struct ldb_message *msg;
+
 
        if (!ctx->auth_ctx->msg_ctx) {
                DEBUG(0,("winbind_check_password: auth_context_create was called with out messaging context\n"));
@@ -190,6 +194,42 @@ static NTSTATUS winbind_check_password(struct auth_method_context *ctx,
                return NT_STATUS_NOT_IMPLEMENTED;
        }
 
+       /*
+        * At best, reset the badPwdCount to 0 if the account exists.
+        * This means that lockouts happen at a badPwdCount earlier than
+        * normal, but makes it more fault tolerant.
+        */
+       if (NT_STATUS_IS_OK(s->req.out.result)) {
+               const char *account_name = user_info->mapped.account_name;
+               const char *p = NULL;
+               p = strchr_m(account_name, '@');
+               if (p != NULL) {
+                       const char *nt4_domain = NULL;
+                       const char *nt4_account = NULL;
+
+                       status = crack_name_to_nt4_name(mem_ctx,
+                                                       ctx->auth_ctx->event_ctx,
+                                                       ctx->auth_ctx->lp_ctx,
+                                                       DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
+                                                       account_name,
+                                                       &nt4_domain, &nt4_account);
+                       if (NT_STATUS_IS_OK(status) &&
+                           lpcfg_is_mydomain(ctx->auth_ctx->lp_ctx, nt4_domain)) {
+                               account_name = nt4_account;
+                       }
+               }
+
+               domain_dn = ldb_get_default_basedn(ctx->auth_ctx->sam_ctx);
+               if (domain_dn != NULL) {
+                       status = authsam_search_account(mem_ctx, ctx->auth_ctx->sam_ctx, account_name, domain_dn, &msg);
+                       if (NT_STATUS_IS_OK(status)) {
+                           authsam_logon_success_accounting(ctx->auth_ctx->sam_ctx, msg,
+                                                            domain_dn,
+                                                            user_info->flags & USER_INFO_INTERACTIVE_LOGON);
+                       }
+               }
+       }
+
        status = make_user_info_dc_netlogon_validation(mem_ctx,
                                                      user_info->client.account_name,
                                                      s->req.in.validation_level,
index 9b0f0618bae258a7c11babe15fb6dea8e081519c..9119ef54f439b11cbdb94c07eb9aa9e18527da2a 100644 (file)
@@ -837,6 +837,34 @@ static NTSTATUS authsam_update_lastlogon_timestamp(struct ldb_context *sam_ctx,
        return NT_STATUS_OK;
 }
 
+/****************************************************************************
+ Look for the specified user in the sam, return ldb result structures
+****************************************************************************/
+
+NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
+                                        const char *account_name,
+                                        struct ldb_dn *domain_dn,
+                                        struct ldb_message **ret_msg)
+{
+       int ret;
+
+       /* pull the user attributes */
+       ret = dsdb_search_one(sam_ctx, mem_ctx, ret_msg, domain_dn, LDB_SCOPE_SUBTREE,
+                             user_attrs,
+                             DSDB_SEARCH_SHOW_EXTENDED_DN,
+                             "(&(sAMAccountName=%s)(objectclass=user))",
+                             ldb_binary_encode_string(mem_ctx, account_name));
+       if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+               DEBUG(3,("sam_search_user: Couldn't find user [%s] in samdb, under %s\n",
+                        account_name, ldb_dn_get_linearized(domain_dn)));
+               return NT_STATUS_NO_SUCH_USER;
+       }
+       if (ret != LDB_SUCCESS) {
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
+
+       return NT_STATUS_OK;
+}
 
 
 /* Reset the badPwdCount to zero and update the lastLogon time. */