summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2010-01-28 17:19:03 +0100
committerStephen Gallagher <sgallagh@redhat.com>2010-02-02 14:41:41 -0500
commit5136873b1fd56e34172e5fb325ac2b5508c85f31 (patch)
treeaa43b4f705d1c3593f76c80ae0d028f09186df9c /server
parent7ea48433b3bab77813b11c60e1ea82cb9793dc33 (diff)
downloadsssd-5136873b1fd56e34172e5fb325ac2b5508c85f31.tar.gz
sssd-5136873b1fd56e34172e5fb325ac2b5508c85f31.tar.xz
sssd-5136873b1fd56e34172e5fb325ac2b5508c85f31.zip
Warn the user if authentication happens offline
Diffstat (limited to 'server')
-rw-r--r--server/db/sysdb.h2
-rw-r--r--server/db/sysdb_ops.c20
-rw-r--r--server/responder/pam/pamsrv_cmd.c20
-rw-r--r--server/tests/sysdb-tests.c103
4 files changed, 132 insertions, 13 deletions
diff --git a/server/db/sysdb.h b/server/db/sysdb.h
index 9b77edfa3..a6d9e69e4 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 c1d996d52..8dd81b3c0 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 f89e73c8c..a4573e60d 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 3cd5e7dcc..978764480 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);