Hi,
this patch should fix #305 'The kerberos provider should automatically kinit users when it goes online'.
This patch depends on: - 'Split pam_data utilities into a separate file' - 'Add callback when the ID provider switches from offline to online'
This version only applies to sssd-1-2, I will rebase/rewrite it for master later.
bye, Sumit
On Thu, Apr 29, 2010 at 06:21:20PM +0200, Sumit Bose wrote:
Hi,
this patch should fix #305 'The kerberos provider should automatically kinit users when it goes online'.
This patch depends on:
- 'Split pam_data utilities into a separate file'
- 'Add callback when the ID provider switches from offline to online'
This version only applies to sssd-1-2, I will rebase/rewrite it for master later.
bye, Sumit
Sorry, I forgot to add a fix for the unit tests.
New version attached.
bye, Sumit
On Mon, May 03, 2010 at 11:12:05AM +0200, Sumit Bose wrote:
On Thu, Apr 29, 2010 at 06:21:20PM +0200, Sumit Bose wrote:
Hi,
this patch should fix #305 'The kerberos provider should automatically kinit users when it goes online'.
This patch depends on:
- 'Split pam_data utilities into a separate file'
- 'Add callback when the ID provider switches from offline to online'
This version only applies to sssd-1-2, I will rebase/rewrite it for master later.
bye, Sumit
Sorry, I forgot to add a fix for the unit tests.
New version attached.
rebased version which should work on top of 'Handle Krb5 password expiration warning' is attached.
bye, Sumit
From a189b092198d3071682e5df4949cdefce4c3e66b Mon Sep 17 00:00:00 2001 From: Sumit Bose sbose@redhat.com Date: Mon, 19 Apr 2010 11:59:09 +0200 Subject: [PATCH] Add support for delayed kinit if offline
If the configuration option krb5_store_password_if_offline is set to true and the backend is offline the plain text user password is stored and used to request a TGT if the backend becomes online. If available the Linux kernel key retention service is used.
src/Makefile.am | 4 + src/config/SSSDConfig.py | 1 + src/config/SSSDConfigTest.py | 3 + src/config/etc/sssd.api.d/sssd-krb5.conf | 1 + src/configure.ac | 1 + src/db/sysdb.h | 3 +- src/db/sysdb_ops.c | 10 +- src/external/libkeyutils.m4 | 11 + src/man/sssd-krb5.5.xml | 14 + src/providers/data_provider.h | 11 + src/providers/dp_pam_data_util.c | 88 +++++ src/providers/ipa/ipa_common.c | 3 +- src/providers/ipa/ipa_common.h | 2 +- src/providers/ipa/ipa_init.c | 9 + src/providers/krb5/krb5_auth.c | 94 +++++- src/providers/krb5/krb5_auth.h | 10 + src/providers/krb5/krb5_common.c | 3 +- src/providers/krb5/krb5_common.h | 1 + .../krb5/krb5_delayed_online_authentication.c | 336 ++++++++++++++++++++ src/providers/krb5/krb5_init.c | 8 + src/responder/pam/pamsrv_cmd.c | 2 +- src/tests/sysdb-tests.c | 4 +- 22 files changed, 594 insertions(+), 25 deletions(-) create mode 100644 src/external/libkeyutils.m4 create mode 100644 src/providers/krb5/krb5_delayed_online_authentication.c
diff --git a/src/Makefile.am b/src/Makefile.am index 5fb4062..5ae5b2e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -767,6 +767,7 @@ libsss_krb5_la_SOURCES = \ providers/child_common.c \ providers/krb5/krb5_utils.c \ providers/krb5/krb5_become_user.c \
- providers/krb5/krb5_delayed_online_authentication.c \ providers/krb5/krb5_auth.c \ providers/krb5/krb5_common.c \ providers/krb5/krb5_init.c \
@@ -776,6 +777,7 @@ libsss_krb5_la_CFLAGS = \ $(DHASH_CFLAGS) libsss_krb5_la_LIBADD = \ $(DHASH_LIBS) \
- $(KEYUITLS_LIB) \ $(KRB5_LIBS)
libsss_krb5_la_LDFLAGS = \ -version-info 1:0:0 \ @@ -806,6 +808,7 @@ libsss_ipa_la_SOURCES = \ util/find_uid.c \ providers/krb5/krb5_utils.c \ providers/krb5/krb5_become_user.c \
- providers/krb5/krb5_delayed_online_authentication.c \ providers/krb5/krb5_common.c \ providers/krb5/krb5_auth.c
libsss_ipa_la_CFLAGS = \ @@ -816,6 +819,7 @@ libsss_ipa_la_CFLAGS = \ libsss_ipa_la_LIBADD = \ $(OPENLDAP_LIBS) \ $(DHASH_LIBS) \
- $(KEYUTILS_LIBS) \ $(KRB5_LIBS)
libsss_ipa_la_LDFLAGS = \ -version-info 1:0:0 \ diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py index 18df979..ead74c2 100644 --- a/src/config/SSSDConfig.py +++ b/src/config/SSSDConfig.py @@ -98,6 +98,7 @@ option_strings = { 'krb5_ccname_template' : _("Location of the user's credential cache"), 'krb5_keytab' : _("Location of the keytab to validate credentials"), 'krb5_validate' : _("Enable credential validation"),
'krb5_store_password_if_offline' : _("Store password if offline for later online authentication"),
# [provider/krb5/chpass] 'krb5_changepw_principal' : _('The principal of the change password service'),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py index e889965..fbe287b 100755 --- a/src/config/SSSDConfigTest.py +++ b/src/config/SSSDConfigTest.py @@ -547,6 +547,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'krb5_ccname_template', 'krb5_keytab', 'krb5_validate',
'krb5_store_password_if_offline', 'krb5_auth_timeout']) options = domain.list_options()
@@ -719,6 +720,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'krb5_ccname_template', 'krb5_keytab', 'krb5_validate',
'krb5_store_password_if_offline', 'krb5_auth_timeout'] self.assertTrue(type(options) == dict,
@@ -864,6 +866,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'krb5_ccname_template', 'krb5_keytab', 'krb5_validate',
'krb5_store_password_if_offline', 'krb5_auth_timeout']) options = domain.list_options()
diff --git a/src/config/etc/sssd.api.d/sssd-krb5.conf b/src/config/etc/sssd.api.d/sssd-krb5.conf index 7b12e08..1f8bead 100644 --- a/src/config/etc/sssd.api.d/sssd-krb5.conf +++ b/src/config/etc/sssd.api.d/sssd-krb5.conf @@ -8,6 +8,7 @@ krb5_ccachedir = str, None, false krb5_ccname_template = str, None, false krb5_keytab = str, None, false krb5_validate = bool, None, false +krb5_store_password_if_offline = bool, None, false
[provider/krb5/chpass] krb5_changepw_principal = str, None, false diff --git a/src/configure.ac b/src/configure.ac index 93debb6..5542ee4 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -94,6 +94,7 @@ m4_include([external/python.m4]) m4_include([external/selinux.m4]) m4_include([external/crypto.m4]) m4_include([external/nscd.m4]) +m4_include([external/libkeyutils.m4]) m4_include([util/signal.m4])
PKG_CHECK_MODULES([DBUS],[dbus-1]) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index cf97ed6..d6780c3 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -557,7 +557,8 @@ struct tevent_req *sysdb_cache_auth_send(TALLOC_CTX *mem_ctx, const char *name, const uint8_t *authtok, size_t authtok_size,
struct confdb_ctx *cdb);
struct confdb_ctx *cdb,
bool just_check);
int sysdb_cache_auth_recv(struct tevent_req *req, time_t *expire_date, time_t *delayed_until);
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index 618b810..6fcc95b 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -4645,6 +4645,7 @@ struct sysdb_cache_auth_state { struct sss_domain_info *domain; struct sysdb_ctx *sysdb; struct confdb_ctx *cdb;
- bool just_check; struct sysdb_attrs *update_attrs; bool authentication_successful; struct sysdb_handle *handle;
@@ -4724,7 +4725,8 @@ struct tevent_req *sysdb_cache_auth_send(TALLOC_CTX *mem_ctx, const char *name, const uint8_t *authtok, size_t authtok_size,
struct confdb_ctx *cdb)
struct confdb_ctx *cdb,
bool just_check)
{ struct tevent_req *req; struct tevent_req *subreq; @@ -4774,6 +4776,7 @@ struct tevent_req *sysdb_cache_auth_send(TALLOC_CTX *mem_ctx, state->domain = domain; state->sysdb = sysdb; state->cdb = cdb;
- state->just_check = just_check; state->update_attrs = NULL; state->authentication_successful = false; state->handle = NULL;
@@ -4888,6 +4891,11 @@ static void sysdb_cache_auth_get_attrs_done(struct tevent_req *subreq) DEBUG(4, ("Hashes do match!\n")); state->authentication_successful = true;
if (state->just_check) {
ret = EOK;
goto done;
}
ret = sysdb_attrs_add_time_t(state->update_attrs, SYSDB_LAST_LOGIN, time(NULL)); if (ret != EOK) {
diff --git a/src/external/libkeyutils.m4 b/src/external/libkeyutils.m4 new file mode 100644 index 0000000..5753d77 --- /dev/null +++ b/src/external/libkeyutils.m4 @@ -0,0 +1,11 @@ +AC_SUBST(KEYUTILS_LIBS)
+AC_CHECK_HEADERS([keyutils.h],
[AC_CHECK_LIB([keyutils], [add_key],
[AC_DEFINE(USE_KEYRING, 1, [Define if the keyring should be used])
KEYUTILS_LIBS="-lkeyutils"
],
[AC_MSG_WARN([No usable keyutils library found])]
)],
[AC_MSG_WARN([keyutils header files are not available])]
+) diff --git a/src/man/sssd-krb5.5.xml b/src/man/sssd-krb5.5.xml index c291eca..54200f6 100644 --- a/src/man/sssd-krb5.5.xml +++ b/src/man/sssd-krb5.5.xml @@ -238,6 +238,20 @@ </listitem> </varlistentry>
<varlistentry>
<term>krb5_store_password_if_offline (boolean)</term>
<listitem>
<para>
Store the password of the user if the provider is
offline and use it to request a TGT when the
provider gets online again.
</para>
<para>
Default: false
</para>
</listitem>
</varlistentry>
</variablelist> </para>
</refsect1>
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h index 747e6e8..951b47a 100644 --- a/src/providers/data_provider.h +++ b/src/providers/data_provider.h @@ -22,10 +22,16 @@ #ifndef __DATA_PROVIDER_H__ #define __DATA_PROVIDER_H__
+#include "config.h"
#include <stdint.h> #include <sys/un.h> #include <errno.h> #include <stdbool.h> +#ifdef USE_KEYRING +#include <sys/types.h> +#include <keyutils.h> +#endif #include "talloc.h" #include "tevent.h" #include "ldb.h" @@ -178,9 +184,14 @@ struct pam_data { bool offline_auth; bool last_auth_saved; int priv; +#ifdef USE_KEYRING
- key_serial_t key_serial;
+#endif };
/* from dp_auth_util.c */ +errno_t copy_pam_data(TALLOC_CTX *mem_ctx, struct pam_data *old_pd,
struct pam_data **new_pd);
void pam_print_data(int l, struct pam_data *pd); int pam_add_response(struct pam_data *pd, enum response_type type, diff --git a/src/providers/dp_pam_data_util.c b/src/providers/dp_pam_data_util.c index 308bd7c..93db7f6 100644 --- a/src/providers/dp_pam_data_util.c +++ b/src/providers/dp_pam_data_util.c @@ -24,6 +24,94 @@
#include "providers/data_provider.h"
+#define PD_STR_COPY(el) do { \
- if (old_pd->el != NULL) { \
pd->el = talloc_strdup(pd, old_pd->el); \
if (pd->el == NULL) { \
DEBUG(1, ("talloc_strdup failed.\n")); \
goto failed; \
} \
- } \
+} while(0);
+#define PD_MEM_COPY(el, size) do { \
- if (old_pd->el != NULL) { \
pd->el = talloc_memdup(pd, old_pd->el, (size)); \
if (pd->el == NULL) { \
DEBUG(1, ("talloc_memdup failed.\n")); \
goto failed; \
} \
- } \
+} while(0);
+int pam_data_destructor(void *ptr) +{
- struct pam_data *pd = talloc_get_type(ptr, struct pam_data);
- if (pd->authtok_size != 0 && pd->authtok != NULL) {
memset(pd->authtok, 0, pd->authtok_size);
pd->authtok_size = 0;
- }
- if (pd->newauthtok_size != 0 && pd->newauthtok != NULL) {
memset(pd->newauthtok, 0, pd->newauthtok_size);
pd->newauthtok_size = 0;
- }
- return EOK;
+}
+struct pam_data *create_pam_data(TALLOC_CTX *mem_ctx) +{
- struct pam_data *pd;
- pd = talloc_zero(mem_ctx, struct pam_data);
- if (pd == NULL) {
DEBUG(1, ("talloc_zero failed.\n"));
return NULL;
- }
- talloc_set_destructor((TALLOC_CTX *) pd, pam_data_destructor);
- return pd;
+}
+errno_t copy_pam_data(TALLOC_CTX *mem_ctx, struct pam_data *old_pd,
struct pam_data **new_pd)
+{
- struct pam_data *pd = NULL;
- pd = create_pam_data(mem_ctx);
- if (pd == NULL) {
DEBUG(1, ("create_pam_data failed.\n"));
return ENOMEM;
- }
- pd->cmd = old_pd->cmd;
- pd->authtok_type = old_pd->authtok_type;
- pd->authtok_size = old_pd->authtok_size;
- pd->newauthtok_type = old_pd->newauthtok_type;
- pd->newauthtok_size = old_pd->newauthtok_size;
- PD_STR_COPY(domain);
- PD_STR_COPY(user);
- PD_STR_COPY(service);
- PD_STR_COPY(tty);
- PD_STR_COPY(ruser);
- PD_STR_COPY(rhost);
- PD_MEM_COPY(authtok, old_pd->authtok_size);
- PD_MEM_COPY(newauthtok, old_pd->newauthtok_size);
- pd->cli_pid = old_pd->cli_pid;
- *new_pd = pd;
- return EOK;
+failed:
- talloc_free(pd);
- return ENOMEM;
+}
void pam_print_data(int l, struct pam_data *pd) { DEBUG(l, ("command: %d\n", pd->cmd)); diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c index bed0666..48ac56a 100644 --- a/src/providers/ipa/ipa_common.c +++ b/src/providers/ipa/ipa_common.c @@ -120,7 +120,8 @@ struct dp_option ipa_def_krb5_opts[] = { { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 15 }, NULL_NUMBER }, { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING }, { "krb5_validate", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
- { "krb5_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING }
- { "krb5_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "krb5_store_password_if_offline", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }
};
int ipa_get_options(TALLOC_CTX *memctx, diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h index 03a082e..2b93659 100644 --- a/src/providers/ipa/ipa_common.h +++ b/src/providers/ipa/ipa_common.h @@ -40,7 +40,7 @@ struct ipa_service { /* the following define is used to keep track of the options in the krb5
- module, so that if they change and ipa is not updated correspondingly
- this will trigger a runtime abort error */
-#define IPA_KRB5_OPTS_TEST 9 +#define IPA_KRB5_OPTS_TEST 10
enum ipa_basic_opt { IPA_DOMAIN = 0, diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c index 6e0688f..598c616 100644 --- a/src/providers/ipa/ipa_init.c +++ b/src/providers/ipa/ipa_init.c @@ -233,6 +233,15 @@ int sssm_ipa_auth_init(struct be_ctx *bectx, goto done; }
- if (dp_opt_get_bool(krb5_auth_ctx->opts, KRB5_STORE_PASSWORD_IF_OFFLINE)) {
ret = init_delayed_online_authentication(krb5_auth_ctx, bectx,
bectx->ev);
if (ret != EOK) {
DEBUG(1, ("init_delayed_online_authentication failed.\n"));
goto done;
}
- }
- ret = check_and_export_options(krb5_auth_ctx->opts, bectx->domain); if (ret != EOK) { DEBUG(1, ("check_and_export_opts failed.\n"));
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index 0c08fe1..822be65 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -667,6 +667,7 @@ static void krb5_find_ccache_step(struct tevent_req *req); static void krb5_save_ccname_done(struct tevent_req *req); static void krb5_child_done(struct tevent_req *req); static void krb5_pam_handler_cache_done(struct tevent_req *treq); +static void krb5_pam_handler_cache_auth_done(struct tevent_req *subreq);
struct krb5_auth_state { struct tevent_context *ev; @@ -1037,7 +1038,7 @@ static void krb5_find_ccache_step(struct tevent_req *req) kr->is_offline = true;
if (kr->valid_tgt_present) {
DEBUG(9, ("Valid TGT available, nothing to do.\n"));
DEBUG(9, ("Valid TGT available.\n")); msg = talloc_asprintf(pd, "%s=%s", CCACHE_ENV_NAME, kr->ccname); if (msg == NULL) { DEBUG(1, ("talloc_asprintf failed.\n"));
@@ -1050,29 +1051,41 @@ static void krb5_find_ccache_step(struct tevent_req *req) if (ret != EOK) { DEBUG(1, ("pam_add_response failed.\n")); }
state->pam_status = PAM_AUTHINFO_UNAVAIL;
state->dp_err = DP_ERR_OFFLINE;
ret = EOK;
goto done; }
memset(pd->authtok, 0, pd->authtok_size);
pd->authtok_size = 0;
if (kr->active_ccache_present) {
subreq = krb5_save_ccname_send(state, state->ev,
if (dp_opt_get_bool(kr->krb5_ctx->opts,KRB5_STORE_PASSWORD_IF_OFFLINE)) {
subreq = sysdb_cache_auth_send(state, state->ev, state->be_ctx->sysdb, state->be_ctx->domain, pd->user,
kr->ccname);
pd->authtok, pd->authtok_size,
state->be_ctx->cdb, true); if (subreq == NULL) {
DEBUG(1, ("krb5_save_ccname_send failed.\n"));
ret = ENOMEM;
goto done;
DEBUG(2, ("sysdb_cache_auth_send failed, "
"delayed online authentication not possible.\n"));
/* This is not a fatal error, we continue with standard
* offline authentication. */
} else {
tevent_req_set_callback(subreq,
krb5_pam_handler_cache_auth_done, req);
return; }
}
tevent_req_set_callback(subreq, krb5_save_ccname_done, req);
return;
memset(pd->authtok, 0, pd->authtok_size);
pd->authtok_size = 0;
subreq = krb5_save_ccname_send(state, state->ev,
state->be_ctx->sysdb,
state->be_ctx->domain, pd->user,
kr->ccname);
if (subreq == NULL) {
DEBUG(1, ("krb5_save_ccname_send failed.\n"));
ret = ENOMEM;
goto done; }
tevent_req_set_callback(subreq, krb5_save_ccname_done, req);
return;
}
subreq = handle_child_send(state, state->ev, kr);
@@ -1259,6 +1272,24 @@ static void krb5_save_ccname_done(struct tevent_req *subreq) }
if (kr->is_offline) {
if (dp_opt_get_bool(krb5_ctx->opts,KRB5_STORE_PASSWORD_IF_OFFLINE)) {
subreq = sysdb_cache_auth_send(state, state->ev,
state->be_ctx->sysdb,
state->be_ctx->domain, pd->user,
pd->authtok, pd->authtok_size,
state->be_ctx->cdb, true);
if (subreq == NULL) {
DEBUG(2, ("sysdb_cache_auth_send failed, "
"delayed online authentication not possible.\n"));
/* This is not a fatal error, we continue with standard
* offline authentication. */
} else {
tevent_req_set_callback(subreq,
krb5_pam_handler_cache_auth_done, req);
return;
}
}
DEBUG(4, ("Backend is marked offline, retry later!\n")); state->pam_status = PAM_AUTHINFO_UNAVAIL; state->dp_err = DP_ERR_OFFLINE;
@@ -1331,7 +1362,6 @@ static void krb5_pam_handler_cache_done(struct tevent_req *subreq) struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); int ret;
- /* password caching failures are not fatal errors */ ret = sysdb_cache_password_recv(subreq); talloc_zfree(subreq);
@@ -1345,6 +1375,36 @@ static void krb5_pam_handler_cache_done(struct tevent_req *subreq) tevent_req_done(req); }
+static void krb5_pam_handler_cache_auth_done(struct tevent_req *subreq) +{
- struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
- struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
- struct pam_data *pd = state->pd;
- struct krb5_ctx *krb5_ctx = state->kr->krb5_ctx;
- int ret;
- time_t expire_date;
- time_t delayed_until;
- ret = sysdb_cache_auth_recv(subreq, &expire_date, &delayed_until);
- talloc_zfree(subreq);
- if (ret) {
DEBUG(2, ("Offline authentication failed.\n"));
- } else {
ret = add_user_to_delayed_online_authentication(krb5_ctx, pd,
state->kr->uid);
if (ret != EOK) {
/* This error is not fatal */
DEBUG(1, ("add_user_to_delayed_online_authentication failed.\n"));
}
- }
- state->pam_status = PAM_AUTHINFO_UNAVAIL;
- state->dp_err = DP_ERR_OFFLINE;
- tevent_req_done(req);
+}
static void krb_reply(struct be_req *req, int dp_err, int result) { req->fn(req, dp_err, result, NULL); diff --git a/src/providers/krb5/krb5_auth.h b/src/providers/krb5/krb5_auth.h index e614d5c..aa2247f 100644 --- a/src/providers/krb5/krb5_auth.h +++ b/src/providers/krb5/krb5_auth.h @@ -62,6 +62,7 @@ struct krb5child_req { };
struct fo_service; +struct delayed_online_authentication;
struct krb5_ctx { /* opts taken from kinit */ @@ -94,6 +95,8 @@ struct krb5_ctx { int child_debug_fd;
pcre *illegal_path_re;
- struct delayed_online_authentication *delayed_online_authentication;
};
void krb5_pam_handler(struct be_req *be_req); @@ -104,4 +107,11 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, struct pam_data *pd, struct krb5_ctx *krb5_ctx); int krb5_auth_recv(struct tevent_req *req, int *pam_status, int *dp_err);
+errno_t add_user_to_delayed_online_authentication(struct krb5_ctx *krb5_ctx,
struct pam_data *pd,
uid_t uid);
+errno_t init_delayed_online_authentication(struct krb5_ctx *krb5_ctx,
struct be_ctx *be_ctx,
struct tevent_context *ev);
#endif /* __KRB5_AUTH_H__ */ diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c index 52cbe16..12cdb30 100644 --- a/src/providers/krb5/krb5_common.c +++ b/src/providers/krb5/krb5_common.c @@ -40,7 +40,8 @@ struct dp_option default_krb5_opts[] = { { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 15 }, NULL_NUMBER }, { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING }, { "krb5_validate", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
- { "krb5_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING }
- { "krb5_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "krb5_store_password_if_offline", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }
};
errno_t check_and_export_options(struct dp_option *opts, diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h index 0b0da31..3d01ec9 100644 --- a/src/providers/krb5/krb5_common.h +++ b/src/providers/krb5/krb5_common.h @@ -53,6 +53,7 @@ enum krb5_opts { KRB5_KEYTAB, KRB5_VALIDATE, KRB5_KPASSWD,
KRB5_STORE_PASSWORD_IF_OFFLINE,
KRB5_OPTS
}; diff --git a/src/providers/krb5/krb5_delayed_online_authentication.c b/src/providers/krb5/krb5_delayed_online_authentication.c new file mode 100644 index 0000000..b6f5a8f --- /dev/null +++ b/src/providers/krb5/krb5_delayed_online_authentication.c @@ -0,0 +1,336 @@ +/*
- SSSD
- Kerberos 5 Backend Module -- Request a TGT when the system gets online
- Authors:
Sumit Bose <sbose@redhat.com>
- Copyright (C) 2010 Red Hat
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see http://www.gnu.org/licenses/.
+*/
+#include <security/pam_modules.h> +#ifdef USE_KEYRING +#include <sys/types.h> +#include <keyutils.h> +#endif
+#include "providers/krb5/krb5_auth.h" +#include "dhash.h" +#include "util/util.h" +#include "util/find_uid.h"
+#define INITIAL_USER_TABLE_SIZE 10
+struct delayed_online_authentication {
- hash_table_t *user_table;
- struct be_ctx *be_ctx;
- struct tevent_context *ev;
- struct krb5_ctx *krb5_ctx;
+};
+struct auth_data {
- struct be_ctx *be_ctx;
- struct krb5_ctx *krb5_ctx;
- struct pam_data *pd;
+};
+static void *hash_talloc(const size_t size, void *pvt) +{
- return talloc_size(pvt, size);
+}
+static void hash_talloc_free(void *ptr, void *pvt) +{
- talloc_free(ptr);
+}
+static void authenticate_user_done(struct tevent_req *req); +static void authenticate_user(struct tevent_context *ev,
struct tevent_timer *te,
struct timeval current_time,
void *private_data)
+{
- struct auth_data *auth_data = talloc_get_type(private_data,
struct auth_data);
- struct pam_data *pd = auth_data->pd;
- struct tevent_req *req;
- DEBUG_PAM_DATA(9, pd);
- if (pd->authtok == NULL || pd->authtok_size == 0) {
DEBUG(1, ("Missing authtok for user [%s].\n", pd->user));
return;
- }
+#ifdef USE_KEYRING
- long keysize;
- long keyrevoke;
- int ret;
- keysize = keyctl_read(pd->key_serial, (char *) pd->authtok,
pd->authtok_size);
- keyrevoke = keyctl_revoke(pd->key_serial);
- if (keysize == -1) {
ret = errno;
DEBUG(1, ("keyctl_read failed [%d][%s].\n", ret, strerror(ret)));
return;
- } else if (keysize != pd->authtok_size) {
DEBUG(1, ("keyctl_read returned key with wrong size, "
"expect [%d] got [%d].\n", pd->authtok_size, keysize));
return;
- }
- if (keyrevoke == -1) {
ret = errno;
DEBUG(1, ("keyctl_revoke failed [%d][%s].\n", ret, strerror(ret)));
- }
+#endif
- req = krb5_auth_send(auth_data, ev, auth_data->be_ctx, auth_data->pd,
auth_data->krb5_ctx);
- if (req == NULL) {
DEBUG(1, ("krb5_auth_send failed.\n"));
talloc_free(auth_data);
return;
- }
- tevent_req_set_callback(req, authenticate_user_done, auth_data);
+}
+static void authenticate_user_done(struct tevent_req *req) {
- struct auth_data *auth_data = tevent_req_callback_data(req,
struct auth_data);
- int ret;
- int pam_status = PAM_SYSTEM_ERR;
- int dp_err;
- ret = krb5_auth_recv(req, &pam_status, &dp_err);
- talloc_free(req);
- if (ret) {
DEBUG(1, ("krb5_auth request failed.\n"));
- } else {
if (pam_status == PAM_SUCCESS) {
DEBUG(4, ("Successfully authenticated user [%s].\n",
auth_data->pd->user));
} else {
DEBUG(1, ("Failed to authenticate user [%s].\n",
auth_data->pd->user));
}
- }
- talloc_free(auth_data);
+}
+static errno_t authenticate_stored_users(
struct delayed_online_authentication *delayed_online_authentication)
+{
- int ret;
- hash_table_t *uid_table;
- struct hash_iter_context_t *iter;
- hash_entry_t *entry;
- hash_key_t key;
- hash_value_t value;
- struct pam_data *pd;
- struct auth_data *auth_data;
- struct tevent_timer *te;
- ret = get_uid_table(delayed_online_authentication, &uid_table);
- if (ret != HASH_SUCCESS) {
DEBUG(1, ("get_uid_table failed.\n"));
return ret;
- }
- iter = new_hash_iter_context(delayed_online_authentication->user_table);
- if (iter == NULL) {
DEBUG(1, ("new_hash_iter_context failed.\n"));
return EINVAL;
- }
- while ((entry = iter->next(iter)) != NULL) {
key.type = HASH_KEY_ULONG;
key.ul = entry->key.ul;
pd = talloc_get_type(entry->value.ptr, struct pam_data);
ret = hash_lookup(uid_table, &key, &value);
if (ret == HASH_SUCCESS) {
DEBUG(1, ("User [%s] is still logged in, "
"trying online authentication.\n", pd->user));
auth_data = talloc_zero(delayed_online_authentication->be_ctx,
struct auth_data);
if (auth_data == NULL) {
DEBUG(1, ("talloc_zero failed.\n"));
} else {
auth_data->pd = talloc_steal(auth_data, pd);
auth_data->krb5_ctx = delayed_online_authentication->krb5_ctx;
auth_data->be_ctx = delayed_online_authentication->be_ctx;
te = tevent_add_timer(delayed_online_authentication->ev,
auth_data, tevent_timeval_current(),
authenticate_user, auth_data);
if (te == NULL) {
DEBUG(1, ("tevent_add_timer failed.\n"));
}
}
} else {
DEBUG(1, ("User [%s] is not logged in anymore, "
"discarding online authentication.\n", pd->user));
talloc_free(pd);
}
ret = hash_delete(delayed_online_authentication->user_table,
&entry->key);
if (ret != HASH_SUCCESS) {
DEBUG(1, ("hash_delete failed [%s].\n",
hash_error_string(ret)));
}
- }
- talloc_free(iter);
- return EOK;
+}
+static void delayed_online_authentication_callback(void *private_data) +{
- struct delayed_online_authentication *delayed_online_authentication =
talloc_get_type(private_data, struct delayed_online_authentication);
- int ret;
- if (delayed_online_authentication->user_table == NULL) {
DEBUG(1, ("Delayed online authentication activated, "
"but user table does not exists.\n"));
return;
- }
- DEBUG(9, ("Backend is online, starting delayed online authentication.\n"));
- ret = authenticate_stored_users(delayed_online_authentication);
- if (ret != EOK) {
DEBUG(1, ("authenticate_stored_users failed.\n"));
- }
- return;
+}
+errno_t add_user_to_delayed_online_authentication(struct krb5_ctx *krb5_ctx,
struct pam_data *pd,
uid_t uid)
+{
- int ret;
- hash_key_t key;
- hash_value_t value;
- struct pam_data *new_pd;
- if (krb5_ctx->delayed_online_authentication == NULL) {
DEBUG(1, ("Missing context for delayed online authentication.\n"));
return EINVAL;
- }
- if (krb5_ctx->delayed_online_authentication->user_table == NULL) {
DEBUG(1, ("user_table not available.\n"));
return EINVAL;
- }
- if (pd->authtok_size == 0 || pd->authtok == NULL) {
DEBUG(1, ("Missing authtok for user [%s].\n", pd->user));
return EINVAL;
- }
- ret = copy_pam_data(krb5_ctx->delayed_online_authentication, pd, &new_pd);
- if (ret != EOK) {
DEBUG(1, ("copy_pam_data failed\n"));
return ENOMEM;
- }
+#ifdef USE_KEYRING
- new_pd->key_serial = add_key("user", new_pd->user, new_pd->authtok,
new_pd->authtok_size, KEY_SPEC_THREAD_KEYRING);
- if (new_pd->key_serial == -1) {
ret = errno;
DEBUG(1, ("add_key fialed [%d][%s].\n", ret, strerror(ret)));
talloc_free(new_pd);
return ret;
- }
- DEBUG(9, ("Saved authtok of user [%s] with serial [%ld].\n",
new_pd->user, new_pd->key_serial));
- memset(new_pd->authtok, 0, new_pd->authtok_size);
+#endif
- key.type = HASH_KEY_ULONG;
- key.ul = uid;
- value.type = HASH_VALUE_PTR;
- value.ptr = new_pd;
- ret = hash_enter(krb5_ctx->delayed_online_authentication->user_table,
&key, &value);
- if (ret != HASH_SUCCESS) {
DEBUG(1, ("Cannot add user [%s] to table [%s], "
"delayed online authentication not possible.\n",
pd->user, hash_error_string(ret)));
talloc_free(new_pd);
return ENOMEM;
- }
- DEBUG(9, ("Added user [%s] successfully to "
"delayed online authentication.\n", pd->user));
- return EOK;
+}
+errno_t init_delayed_online_authentication(struct krb5_ctx *krb5_ctx,
struct be_ctx *be_ctx,
struct tevent_context *ev)
+{
- int ret;
- krb5_ctx->delayed_online_authentication = talloc_zero(krb5_ctx,
struct delayed_online_authentication);
- if (krb5_ctx->delayed_online_authentication == NULL) {
DEBUG(1, ("talloc_zero failed.\n"));
return ENOMEM;
- }
- ret = hash_create_ex(INITIAL_USER_TABLE_SIZE,
&krb5_ctx->delayed_online_authentication->user_table,
0, 0, 0, 0, hash_talloc, hash_talloc_free,
krb5_ctx->delayed_online_authentication,
NULL, NULL);
- if (ret != HASH_SUCCESS) {
DEBUG(1, ("hash_create_ex failed [%s]\n", hash_error_string(ret)));
ret = ENOMEM;
goto fail;
- }
- krb5_ctx->delayed_online_authentication->be_ctx = be_ctx;
- krb5_ctx->delayed_online_authentication->krb5_ctx = krb5_ctx;
- krb5_ctx->delayed_online_authentication->ev = ev;
- ret = be_add_online_cb(krb5_ctx, be_ctx,
delayed_online_authentication_callback,
krb5_ctx->delayed_online_authentication, NULL);
- if (ret != EOK) {
DEBUG(1, ("be_add_online_cb failed.\n"));
goto fail;
- }
- /* TODO: add destructor */
- return EOK;
+fail:
- talloc_zfree(krb5_ctx->delayed_online_authentication);
- return ret;
+} diff --git a/src/providers/krb5/krb5_init.c b/src/providers/krb5/krb5_init.c index 83129d9..fb5560d 100644 --- a/src/providers/krb5/krb5_init.c +++ b/src/providers/krb5/krb5_init.c @@ -120,6 +120,14 @@ int sssm_krb5_auth_init(struct be_ctx *bectx, } }
- if (dp_opt_get_bool(ctx->opts, KRB5_STORE_PASSWORD_IF_OFFLINE)) {
ret = init_delayed_online_authentication(ctx, bectx, bectx->ev);
if (ret != EOK) {
DEBUG(1, ("init_delayed_online_authentication failed.\n"));
goto fail;
}
- }
- ret = check_and_export_options(ctx->opts, bectx->domain); if (ret != EOK) { DEBUG(1, ("check_and_export_options failed.\n"));
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c index 8d67da1..182e849 100644 --- a/src/responder/pam/pamsrv_cmd.c +++ b/src/responder/pam/pamsrv_cmd.c @@ -520,7 +520,7 @@ static void pam_reply(struct pam_auth_req *preq) req = sysdb_cache_auth_send(preq, preq->cctx->ev, sysdb, preq->domain, pd->user, pd->authtok, pd->authtok_size,
pctx->rctx->cdb);
pctx->rctx->cdb, false); if (req == NULL) { DEBUG(1, ("Failed to setup offline auth.\n")); /* this error is not fatal, continue */
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index c6661ae..8557be5 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -2313,7 +2313,7 @@ static void cached_authentication_without_expiration(const char *username, 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);
test_ctx->confdb, false);
fail_unless(req != NULL, "sysdb_cache_password_send failed.");
tevent_req_set_callback(req, test_search_done, data);
@@ -2388,7 +2388,7 @@ static void cached_authentication_with_expiration(const char *username, 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);
test_ctx->confdb, false);
fail_unless(req != NULL, "sysdb_cache_password_send failed.");
tevent_req_set_callback(req, test_search_done, data);
-- 1.6.6.1
sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel
On 05/05/2010 05:02 AM, Sumit Bose wrote
rebased version which should work on top of 'Handle Krb5 password expiration warning' is attached.
Nack: please update the sssd.spec to BuildRequires: keyutils-libs-devel and Requires: keyutils-libs
Please reduce krb5_ctx->delayed_online_authentication to krb5_ctx->deferred_auth. It's much too long and will be difficult to keep within our 79-character limit.
Simmilarly, 'struct delayed_online_authentication' should probably be 'struct deferred_auth_ctx' (naming it a context makes it less confusing. My first impression of the line: ret = get_uid_table(delayed_online_authentication, &uid_table); was that you were passing in a function pointer here.
In delayed_online_authentication_callback(), reduce the DEBUG message to level 5.
authenticate_stored_users() depends on get_uid_table() returning True, which will only happen on Linux. We should do a get_uid_table() call in init_delayed_online_authentication() and skip setting up the online callback if this feature is unavailable. (With a 0-level DEBUG message saying that delayed online auth was requested on an unsupported system) The manpage should also mention that this feature is available only on Linux.
authenticate_user(): Do we want to revoke the key here? I think we might want to hold onto it until authenticate_user_done(). That way if it fails (the KDC may be offline, even though the LDAP provider is online) we can hang onto the creds and try again the next time we go online.
On Wed, May 05, 2010 at 09:41:10AM -0400, Stephen Gallagher wrote:
On 05/05/2010 05:02 AM, Sumit Bose wrote
rebased version which should work on top of 'Handle Krb5 password expiration warning' is attached.
Nack: please update the sssd.spec to BuildRequires: keyutils-libs-devel and Requires: keyutils-libs
done
Please reduce krb5_ctx->delayed_online_authentication to krb5_ctx->deferred_auth. It's much too long and will be difficult to keep within our 79-character limit.
Simmilarly, 'struct delayed_online_authentication' should probably be 'struct deferred_auth_ctx' (naming it a context makes it less confusing. My first impression of the line: ret = get_uid_table(delayed_online_authentication, &uid_table); was that you were passing in a function pointer here.
done
In delayed_online_authentication_callback(), reduce the DEBUG message to level 5.
done
authenticate_stored_users() depends on get_uid_table() returning True, which will only happen on Linux. We should do a get_uid_table() call in init_delayed_online_authentication() and skip setting up the online callback if this feature is unavailable. (With a 0-level DEBUG message saying that delayed online auth was requested on an unsupported system) The manpage should also mention that this feature is available only on Linux.
done
authenticate_user(): Do we want to revoke the key here? I think we might want to hold onto it until authenticate_user_done(). That way if it fails (the KDC may be offline, even though the LDAP provider is online) we can hang onto the creds and try again the next time we go online.
This is not necessary because the delayed request is handled like an ordinary auth request. If the KDC is offline the request is added to the list of delayed requests again.
New version attached.
bye, Sumit
-- Stephen Gallagher RHCE 804006346421761
Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ _______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel
On 05/06/2010 09:25 AM, Sumit Bose wrote:
On Wed, May 05, 2010 at 09:41:10AM -0400, Stephen Gallagher wrote:
On 05/05/2010 05:02 AM, Sumit Bose wrote
rebased version which should work on top of 'Handle Krb5 password expiration warning' is attached.
Nack: please update the sssd.spec to BuildRequires: keyutils-libs-devel and Requires: keyutils-libs
done
Please reduce krb5_ctx->delayed_online_authentication to krb5_ctx->deferred_auth. It's much too long and will be difficult to keep within our 79-character limit.
Simmilarly, 'struct delayed_online_authentication' should probably be 'struct deferred_auth_ctx' (naming it a context makes it less confusing. My first impression of the line: ret = get_uid_table(delayed_online_authentication,&uid_table); was that you were passing in a function pointer here.
done
In delayed_online_authentication_callback(), reduce the DEBUG message to level 5.
done
authenticate_stored_users() depends on get_uid_table() returning True, which will only happen on Linux. We should do a get_uid_table() call in init_delayed_online_authentication() and skip setting up the online callback if this feature is unavailable. (With a 0-level DEBUG message saying that delayed online auth was requested on an unsupported system) The manpage should also mention that this feature is available only on Linux.
done
authenticate_user(): Do we want to revoke the key here? I think we might want to hold onto it until authenticate_user_done(). That way if it fails (the KDC may be offline, even though the LDAP provider is online) we can hang onto the creds and try again the next time we go online.
This is not necessary because the delayed request is handled like an ordinary auth request. If the KDC is offline the request is added to the list of delayed requests again.
New version attached.
bye, Sumit
Nack
This feature is not working properly. I'll describe my testing steps below. (I used IPA for this)
As root on the client, I added krb5_store_password_if_offline = true to the sssd.conf.
I then made sure there were no users logged in but root and removed /tmp/krb5cc*
I turned off my IPA server and sshed into the machine with a user that had cached credentials. Offline auth happened as expected.
I then turned my IPA server back on, waited 60s and then performed a getent request to get the machine to go online.
I saw in the logs that it went online and performed the deferred kinit. However, klist on the logged-in user did not show a tgt. Checking in /tmp, I saw two krb5cc* files for the same userid.
It looks like the auto-kinit code is not recognizing an existing ccache.
On Thu, May 06, 2010 at 02:10:08PM -0400, Stephen Gallagher wrote:
On 05/06/2010 09:25 AM, Sumit Bose wrote:
On Wed, May 05, 2010 at 09:41:10AM -0400, Stephen Gallagher wrote:
On 05/05/2010 05:02 AM, Sumit Bose wrote
rebased version which should work on top of 'Handle Krb5 password expiration warning' is attached.
Nack: please update the sssd.spec to BuildRequires: keyutils-libs-devel and Requires: keyutils-libs
done
Please reduce krb5_ctx->delayed_online_authentication to krb5_ctx->deferred_auth. It's much too long and will be difficult to keep within our 79-character limit.
Simmilarly, 'struct delayed_online_authentication' should probably be 'struct deferred_auth_ctx' (naming it a context makes it less confusing. My first impression of the line: ret = get_uid_table(delayed_online_authentication,&uid_table); was that you were passing in a function pointer here.
done
In delayed_online_authentication_callback(), reduce the DEBUG message to level 5.
done
authenticate_stored_users() depends on get_uid_table() returning True, which will only happen on Linux. We should do a get_uid_table() call in init_delayed_online_authentication() and skip setting up the online callback if this feature is unavailable. (With a 0-level DEBUG message saying that delayed online auth was requested on an unsupported system) The manpage should also mention that this feature is available only on Linux.
done
authenticate_user(): Do we want to revoke the key here? I think we might want to hold onto it until authenticate_user_done(). That way if it fails (the KDC may be offline, even though the LDAP provider is online) we can hang onto the creds and try again the next time we go online.
This is not necessary because the delayed request is handled like an ordinary auth request. If the KDC is offline the request is added to the list of delayed requests again.
New version attached.
bye, Sumit
Nack
This feature is not working properly. I'll describe my testing steps below. (I used IPA for this)
As root on the client, I added krb5_store_password_if_offline = true to the sssd.conf.
I then made sure there were no users logged in but root and removed /tmp/krb5cc*
I turned off my IPA server and sshed into the machine with a user that had cached credentials. Offline auth happened as expected.
I then turned my IPA server back on, waited 60s and then performed a getent request to get the machine to go online.
I saw in the logs that it went online and performed the deferred kinit. However, klist on the logged-in user did not show a tgt. Checking in /tmp, I saw two krb5cc* files for the same userid.
It looks like the auto-kinit code is not recognizing an existing ccache.
Thanks for catching this, it looks that there was always a ccache available during my testing. New version attached.
bye, Sumit
-- Stephen Gallagher RHCE 804006346421761
Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ _______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel
On 05/07/2010 07:08 AM, Sumit Bose wrote:
On Thu, May 06, 2010 at 02:10:08PM -0400, Stephen Gallagher wrote:
On 05/06/2010 09:25 AM, Sumit Bose wrote:
On Wed, May 05, 2010 at 09:41:10AM -0400, Stephen Gallagher wrote:
On 05/05/2010 05:02 AM, Sumit Bose wrote
rebased version which should work on top of 'Handle Krb5 password expiration warning' is attached.
Nack: please update the sssd.spec to BuildRequires: keyutils-libs-devel and Requires: keyutils-libs
done
Please reduce krb5_ctx->delayed_online_authentication to krb5_ctx->deferred_auth. It's much too long and will be difficult to keep within our 79-character limit.
Simmilarly, 'struct delayed_online_authentication' should probably be 'struct deferred_auth_ctx' (naming it a context makes it less confusing. My first impression of the line: ret = get_uid_table(delayed_online_authentication,&uid_table); was that you were passing in a function pointer here.
done
In delayed_online_authentication_callback(), reduce the DEBUG message to level 5.
done
authenticate_stored_users() depends on get_uid_table() returning True, which will only happen on Linux. We should do a get_uid_table() call in init_delayed_online_authentication() and skip setting up the online callback if this feature is unavailable. (With a 0-level DEBUG message saying that delayed online auth was requested on an unsupported system) The manpage should also mention that this feature is available only on Linux.
done
authenticate_user(): Do we want to revoke the key here? I think we might want to hold onto it until authenticate_user_done(). That way if it fails (the KDC may be offline, even though the LDAP provider is online) we can hang onto the creds and try again the next time we go online.
This is not necessary because the delayed request is handled like an ordinary auth request. If the KDC is offline the request is added to the list of delayed requests again.
New version attached.
bye, Sumit
Nack
This feature is not working properly. I'll describe my testing steps below. (I used IPA for this)
As root on the client, I added krb5_store_password_if_offline = true to the sssd.conf.
I then made sure there were no users logged in but root and removed /tmp/krb5cc*
I turned off my IPA server and sshed into the machine with a user that had cached credentials. Offline auth happened as expected.
I then turned my IPA server back on, waited 60s and then performed a getent request to get the machine to go online.
I saw in the logs that it went online and performed the deferred kinit. However, klist on the logged-in user did not show a tgt. Checking in /tmp, I saw two krb5cc* files for the same userid.
It looks like the auto-kinit code is not recognizing an existing ccache.
Thanks for catching this, it looks that there was always a ccache available during my testing. New version attached.
bye, Sumit
At last, the long-awaited Ack!
This is a great feature.
On 05/07/2010 08:45 AM, Stephen Gallagher wrote:
At last, the long-awaited Ack!
This is a great feature.
Pushed to sssd-1-2.
sssd-devel@lists.fedorahosted.org