From: Garming Sam Date: Mon, 3 Apr 2017 03:26:12 +0000 (+1200) Subject: auth_winbind: Allow badPwdCount to be set to 0 with this auth method X-Git-Tag: ldb-1.1.30~44 X-Git-Url: http://git.samba.org/samba.git/?p=sfrench%2Fsamba-autobuild%2F.git;a=commitdiff_plain;h=b50a147a7e40e17d0e280b4c705ac25cea78c869 auth_winbind: Allow badPwdCount to be set to 0 with this auth method 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 Reviewed-by: Andrew Bartlett --- diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c index 54cc6437595..cfe7455501b 100644 --- a/source4/auth/ntlm/auth_sam.c +++ b/source4/auth/ntlm/auth_sam.c @@ -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. diff --git a/source4/auth/ntlm/auth_winbind.c b/source4/auth/ntlm/auth_winbind.c index 7c815fc020e..41819dca605 100644 --- a/source4/auth/ntlm/auth_winbind.c +++ b/source4/auth/ntlm/auth_winbind.c @@ -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, diff --git a/source4/auth/sam.c b/source4/auth/sam.c index 9b0f0618bae..9119ef54f43 100644 --- a/source4/auth/sam.c +++ b/source4/auth/sam.c @@ -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. */