From c83e409297711e6012a164cc929c758a3f38e9b9 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 18 Oct 2012 12:49:38 -0400 Subject: Code can only check for cached passwords Make it clear to the API users that we can not take arbitrary auth tokens. We can only take a password for now so simplify and clarify the interface. --- src/db/sysdb.h | 3 +-- src/db/sysdb_ops.c | 12 +----------- src/providers/krb5/krb5_auth.c | 21 +++++++++++++++++---- src/responder/pam/pamsrv_cmd.c | 39 ++++++++++++++++++++++++--------------- src/tests/sysdb-tests.c | 6 ++---- 5 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index b8aafdfa..378ce488 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -740,8 +740,7 @@ errno_t check_failed_login_attempts(struct confdb_ctx *cdb, time_t *delayed_until); int sysdb_cache_auth(struct sysdb_ctx *sysdb, const char *name, - const uint8_t *authtok, - size_t authtok_size, + const char *password, struct confdb_ctx *cdb, bool just_check, time_t *_expire_date, diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index e1201f44..b9cecad5 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -2757,8 +2757,7 @@ done: int sysdb_cache_auth(struct sysdb_ctx *sysdb, const char *name, - const uint8_t *authtok, - size_t authtok_size, + const char *password, struct confdb_ctx *cdb, bool just_check, time_t *_expire_date, @@ -2773,7 +2772,6 @@ int sysdb_cache_auth(struct sysdb_ctx *sysdb, struct ldb_message *ldb_msg; const char *userhash; char *comphash; - char *password = NULL; uint64_t lastLogin = 0; int cred_expiration; uint32_t failed_login_attempts = 0; @@ -2859,13 +2857,6 @@ int sysdb_cache_auth(struct sysdb_ctx *sysdb, /* TODO: verify user account (disabled, expired ...) */ - password = talloc_strndup(tmp_ctx, (const char *)authtok, authtok_size); - if (password == NULL) { - DEBUG(1, ("talloc_strndup failed.\n")); - ret = ENOMEM; - goto done; - } - userhash = ldb_msg_find_attr_as_string(ldb_msg, SYSDB_CACHEDPWD, NULL); if (userhash == NULL || *userhash == '\0') { DEBUG(4, ("Cached credentials not available.\n")); @@ -2949,7 +2940,6 @@ done: if (_delayed_until != NULL) { *_delayed_until = delayed_until; } - if (password) for (i = 0; password[i]; i++) password[i] = 0; if (ret) { ldb_transaction_cancel(sysdb->ldb); } else { diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index 94bbe485..bd014a49 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -278,16 +278,23 @@ static void krb5_auth_cache_creds(struct krb5_ctx *krb5_ctx, struct pam_data *pd, uid_t uid, int *pam_status, int *dp_err) { + char *password = NULL; errno_t ret; - ret = sysdb_cache_auth(sysdb, pd->user, pd->authtok, - pd->authtok_size, cdb, true, NULL, - NULL); + password = talloc_strndup(state, pd->authtok, pd->authtok_size); + if (!password) { + DEBUG(0, ("Out of memory copying password\n")); + *pam_status = PAM_SYSTEM_ERR; + *dp_err = DP_ERR_OK; + return; + } + + ret = sysdb_cache_auth(sysdb, pd->user, password, cdb, true, NULL, NULL); if (ret != EOK) { DEBUG(1, ("Offline authentication failed\n")); *pam_status = cached_login_pam_status(ret); *dp_err = DP_ERR_OK; - return; + goto done; } ret = add_user_to_delayed_online_authentication(krb5_ctx, pd, uid); @@ -297,6 +304,12 @@ static void krb5_auth_cache_creds(struct krb5_ctx *krb5_ctx, } *pam_status = PAM_AUTHINFO_UNAVAIL; *dp_err = DP_ERR_OFFLINE; + +done: + if (password) { + for (i = 0; password[i]; i++) password[i] = 0; + talloc_zfree(password); + } } static errno_t krb5_auth_prepare_ccache_file(struct krb5child_req *kr, diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c index 42696422..ed7438f8 100644 --- a/src/responder/pam/pamsrv_cmd.c +++ b/src/responder/pam/pamsrv_cmd.c @@ -733,7 +733,6 @@ static void pam_reply(struct pam_auth_req *preq) struct timeval tv; struct tevent_timer *te; struct pam_data *pd; - struct sysdb_ctx *sysdb; struct pam_ctx *pctx; uint32_t user_info_type; time_t exp_date = -1; @@ -753,24 +752,34 @@ static void pam_reply(struct pam_auth_req *preq) if ((preq->domain != NULL) && (preq->domain->cache_credentials == true) && (pd->offline_auth == false)) { + const char *password = NULL; - /* do auth with offline credentials */ - pd->offline_auth = true; + /* do auth with offline credentials */ + pd->offline_auth = true; - sysdb = preq->domain->sysdb; - if (sysdb == NULL) { - DEBUG(0, ("Fatal: Sysdb CTX not found for " - "domain [%s]!\n", preq->domain->name)); - goto done; - } + if (preq->domain->sysdb == NULL) { + DEBUG(0, ("Fatal: Sysdb CTX not found for domain" + " [%s]!\n", preq->domain->name)); + goto done; + } - ret = sysdb_cache_auth(sysdb, pd->user, - pd->authtok, pd->authtok_size, - pctx->rctx->cdb, false, - &exp_date, &delay_until); + password = talloc_strndup(preq, pd->authtok, pd->authtok_size); + if (!password) { + DEBUG(0, ("Fatal: Out of memory copying password\n")); + goto done; + } - pam_handle_cached_login(preq, ret, exp_date, delay_until); - return; + ret = sysdb_cache_auth(preq->domain->sysdb, + pd->user, password, + pctx->rctx->cdb, false, + &exp_date, &delay_until); + + pam_handle_cached_login(preq, ret, exp_date, delay_until); + if (password) { + for (i = 0; password[i]; i++) password[i] = 0; + talloc_zfree(password); + } + return; } break; case SSS_PAM_CHAUTHTOK_PRELIM: diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index a79d8d6c..a5526280 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -1576,8 +1576,7 @@ static void cached_authentication_without_expiration(const char *username, return; } - ret = sysdb_cache_auth(test_ctx->sysdb, data->username, - (const uint8_t *)password, strlen(password), + ret = sysdb_cache_auth(test_ctx->sysdb, data->username, password, test_ctx->confdb, false, &expire_date, &delayed_until); fail_unless(ret == expected_result, "sysdb_cache_auth request does not " @@ -1636,8 +1635,7 @@ static void cached_authentication_with_expiration(const char *username, data->attrs, SYSDB_MOD_REP); fail_unless(ret == EOK, "Could not modify user %s", data->username); - ret = sysdb_cache_auth(test_ctx->sysdb, data->username, - (const uint8_t *) password, strlen(password), + ret = sysdb_cache_auth(test_ctx->sysdb, data->username, password, test_ctx->confdb, false, &expire_date, &delayed_until); fail_unless(ret == expected_result, -- cgit