diff options
author | Sumit Bose <sbose@redhat.com> | 2010-01-28 17:19:03 +0100 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2010-02-02 14:41:41 -0500 |
commit | 5136873b1fd56e34172e5fb325ac2b5508c85f31 (patch) | |
tree | aa43b4f705d1c3593f76c80ae0d028f09186df9c /server | |
parent | 7ea48433b3bab77813b11c60e1ea82cb9793dc33 (diff) | |
download | sssd-5136873b1fd56e34172e5fb325ac2b5508c85f31.tar.gz sssd-5136873b1fd56e34172e5fb325ac2b5508c85f31.tar.bz2 sssd-5136873b1fd56e34172e5fb325ac2b5508c85f31.zip |
Warn the user if authentication happens offline
Diffstat (limited to 'server')
-rw-r--r-- | server/db/sysdb.h | 2 | ||||
-rw-r--r-- | server/db/sysdb_ops.c | 20 | ||||
-rw-r--r-- | server/responder/pam/pamsrv_cmd.c | 20 | ||||
-rw-r--r-- | server/tests/sysdb-tests.c | 103 |
4 files changed, 132 insertions, 13 deletions
diff --git a/server/db/sysdb.h b/server/db/sysdb.h index 9b77edfa..a6d9e69e 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -557,7 +557,7 @@ struct tevent_req *sysdb_cache_auth_send(TALLOC_CTX *mem_ctx, const uint8_t *authtok, size_t authtok_size, struct confdb_ctx *cdb); -int sysdb_cache_auth_recv(struct tevent_req *req); +int sysdb_cache_auth_recv(struct tevent_req *req, time_t *expire_date); struct tevent_req *sysdb_store_custom_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c index c1d996d5..8dd81b3c 100644 --- a/server/db/sysdb_ops.c +++ b/server/db/sysdb_ops.c @@ -4648,6 +4648,7 @@ struct sysdb_cache_auth_state { struct sysdb_attrs *update_attrs; bool authentication_successful; struct sysdb_handle *handle; + time_t expire_date; }; errno_t check_failed_login_attempts(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, @@ -4766,6 +4767,7 @@ struct tevent_req *sysdb_cache_auth_send(TALLOC_CTX *mem_ctx, state->update_attrs = NULL; state->authentication_successful = false; state->handle = NULL; + state->expire_date = -1; subreq = sysdb_search_user_by_name_send(state, ev, sysdb, NULL, domain, name, attrs); @@ -4821,10 +4823,16 @@ static void sysdb_cache_auth_get_attrs_done(struct tevent_req *subreq) DEBUG(9, ("Offline credentials expiration is [%d] days.\n", cred_expiration)); - if (cred_expiration && lastLogin + (cred_expiration * 86400) < time(NULL)) { - DEBUG(4, ("Cached user entry is too old.\n")); - ret = EACCES; - goto done; + if (cred_expiration) { + state->expire_date = lastLogin + (cred_expiration * 86400); + if (state->expire_date < time(NULL)) { + DEBUG(4, ("Cached user entry is too old.\n")); + state->expire_date = 0; + ret = EACCES; + goto done; + } + } else { + state->expire_date = 0; } ret = check_failed_login_attempts(state, state->cdb, ldb_msg, @@ -5026,9 +5034,11 @@ static void sysdb_cache_auth_done(struct tevent_req *subreq) return; } -int sysdb_cache_auth_recv(struct tevent_req *req) { +int sysdb_cache_auth_recv(struct tevent_req *req, time_t *expire_date) { struct sysdb_cache_auth_state *state = tevent_req_data(req, struct sysdb_cache_auth_state); + *expire_date = state->expire_date; + TEVENT_REQ_RETURN_ON_ERROR(req); return (state->authentication_successful ? EOK : EINVAL); diff --git a/server/responder/pam/pamsrv_cmd.c b/server/responder/pam/pamsrv_cmd.c index f89e73c8..a4573e60 100644 --- a/server/responder/pam/pamsrv_cmd.c +++ b/server/responder/pam/pamsrv_cmd.c @@ -626,13 +626,31 @@ static void pam_cache_auth_done(struct tevent_req *req) int ret; struct pam_auth_req *preq = tevent_req_callback_data(req, struct pam_auth_req); + const uint32_t resp_type = SSS_PAM_USER_INFO_OFFLINE_AUTH; + const size_t resp_len = sizeof(uint32_t) + sizeof(long long); + uint8_t *resp; + time_t expire_date = 0; + long long dummy; - ret = sysdb_cache_auth_recv(req); + ret = sysdb_cache_auth_recv(req, &expire_date); talloc_zfree(req); switch (ret) { case EOK: preq->pd->pam_status = PAM_SUCCESS; + resp = talloc_size(preq->pd, resp_len); + if (resp == NULL) { + DEBUG(1, ("talloc_size failed, cannot prepare user info.\n")); + } else { + memcpy(resp, &resp_type, sizeof(uint32_t)); + dummy = (long long) expire_date; + memcpy(resp+sizeof(uint32_t), &dummy, sizeof(long long)); + ret = pam_add_response(preq->pd, SSS_PAM_USER_INFO, resp_len, + (const uint8_t *) resp); + if (ret != EOK) { + DEBUG(1, ("pam_add_response failed.\n")); + } + } break; case ENOENT: preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL; diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c index 3cd5e7dc..97876448 100644 --- a/server/tests/sysdb-tests.c +++ b/server/tests/sysdb-tests.c @@ -2278,13 +2278,17 @@ START_TEST (test_sysdb_cache_password) } END_TEST -static void cached_authentication(const char *username, const char *password, - int expected_result) +static void cached_authentication_without_expiration(const char *username, + const char *password, + int expected_result) { struct sysdb_test_ctx *test_ctx; struct test_data *data; struct tevent_req *req; int ret; + time_t expire_date; + const char *val[2]; + val[1] = NULL; /* Setup */ ret = setup_sysdb_tests(&test_ctx); @@ -2295,6 +2299,15 @@ static void cached_authentication(const char *username, const char *password, data->ev = test_ctx->ev; data->username = username; + val[0] = "0"; + ret = confdb_add_param(test_ctx->confdb, true, CONFDB_PAM_CONF_ENTRY, + CONFDB_PAM_CRED_TIMEOUT, val); + if (ret != EOK) { + fail("Could not initialize provider"); + talloc_free(test_ctx); + return; + } + req = sysdb_cache_auth_send(data, test_ctx->ev, test_ctx->sysdb, test_ctx->domain, data->username, (const uint8_t *) password, strlen(password), @@ -2306,11 +2319,86 @@ static void cached_authentication(const char *username, const char *password, ret = test_loop(data); fail_unless(ret == EOK, "test_loop failed."); - ret = sysdb_cache_auth_recv(req); + ret = sysdb_cache_auth_recv(req, &expire_date); fail_unless(ret == expected_result, "sysdb_cache_auth request does not " "return expected result [%d].", expected_result); + fail_unless(expire_date == 0, "Wrong expire date, expected [%d], got [%d]", + 0, expire_date); + + talloc_free(test_ctx); +} + +static void cached_authentication_with_expiration(const char *username, + const char *password, + int expected_result) +{ + struct sysdb_test_ctx *test_ctx; + struct test_data *data; + struct tevent_req *req; + int ret; + time_t expire_date; + const char *val[2]; + val[1] = NULL; + time_t now; + time_t expected_expire_date; + + /* Setup */ + ret = setup_sysdb_tests(&test_ctx); + fail_unless(ret == EOK, "Could not set up the test"); + + data = talloc_zero(test_ctx, struct test_data); + data->ctx = test_ctx; + data->ev = test_ctx->ev; + data->username = username; + + val[0] = "1"; + ret = confdb_add_param(test_ctx->confdb, true, CONFDB_PAM_CONF_ENTRY, + CONFDB_PAM_CRED_TIMEOUT, val); + if (ret != EOK) { + fail("Could not initialize provider"); + talloc_free(test_ctx); + return; + } + + now = time(NULL); + expected_expire_date = now + (24 * 60 * 60); + DEBUG(9, ("Setting SYSDB_LAST_ONLINE_AUTH to [%lld].\n", (long long) now)); + + data->attrs = sysdb_new_attrs(data); + ret = sysdb_attrs_add_time_t(data->attrs, SYSDB_LAST_ONLINE_AUTH, now); + + req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb); + fail_unless(req != NULL, "sysdb_transaction_send failed."); + + tevent_req_set_callback(req, test_set_user_attr, data); + + ret = test_loop(data); + fail_unless(ret == EOK, "Could not modify user %s", data->username); + talloc_zfree(req); + + data->finished = false; + req = sysdb_cache_auth_send(data, test_ctx->ev, test_ctx->sysdb, + test_ctx->domain, data->username, + (const uint8_t *) password, strlen(password), + test_ctx->confdb); + fail_unless(req != NULL, "sysdb_cache_password_send failed."); + + tevent_req_set_callback(req, test_search_done, data); + + ret = test_loop(data); + fail_unless(ret == EOK, "test_loop failed."); + + ret = sysdb_cache_auth_recv(req, &expire_date); + fail_unless(ret == expected_result, "sysdb_cache_auth request does not " + "return expected result [%d], got [%d].", + expected_result, ret); + + fail_unless(expire_date == expected_expire_date, + "Wrong expire date, expected [%d], got [%d]", + expected_expire_date, expire_date); + talloc_free(test_ctx); } @@ -2325,7 +2413,8 @@ START_TEST (test_sysdb_cached_authentication_missing_password) username = talloc_asprintf(tmp_ctx, "testuser%d", _i); fail_unless(username != NULL, "talloc_asprintf failed."); - cached_authentication(username, "abc", ENOENT); + cached_authentication_without_expiration(username, "abc", ENOENT); + cached_authentication_with_expiration(username, "abc", ENOENT); talloc_free(tmp_ctx); @@ -2343,7 +2432,8 @@ START_TEST (test_sysdb_cached_authentication_wrong_password) username = talloc_asprintf(tmp_ctx, "testuser%d", _i); fail_unless(username != NULL, "talloc_asprintf failed."); - cached_authentication(username, "abc", EINVAL); + cached_authentication_without_expiration(username, "abc", EINVAL); + cached_authentication_with_expiration(username, "abc", EINVAL); talloc_free(tmp_ctx); @@ -2361,7 +2451,8 @@ START_TEST (test_sysdb_cached_authentication) username = talloc_asprintf(tmp_ctx, "testuser%d", _i); fail_unless(username != NULL, "talloc_asprintf failed."); - cached_authentication(username, username, EOK); + cached_authentication_without_expiration(username, username, EOK); + cached_authentication_with_expiration(username, username, EOK); talloc_free(tmp_ctx); |