Hi,
this two patches add the support to display a warning to the user that the Kerberos password is about to expire. The first patch just moves some utility functions to a separate file to avoid linking the krb5_child against libdbus.
I the second patch a prompter function is introduced to catch the warning message which is generated by libkrb5. With the current API of MIT Kerberos we have to rely on this message, because the the underlying AS_REPLY data is not exposed by the library. As a consequece this message cannot be translated, but this is true for messages which are generated to indicate why a password change failed, too. The rest of the patch changes the way the response from the child is packed and unpacked to allow more than one response message.
bye, Sumit
Sorry, the first patch had dependencies to another patch, new version attached.
bye, Sumit On Tue, Apr 27, 2010 at 02:08:02PM +0200, Sumit Bose wrote:
Hi,
this two patches add the support to display a warning to the user that the Kerberos password is about to expire. The first patch just moves some utility functions to a separate file to avoid linking the krb5_child against libdbus.
I the second patch a prompter function is introduced to catch the warning message which is generated by libkrb5. With the current API of MIT Kerberos we have to rely on this message, because the the underlying AS_REPLY data is not exposed by the library. As a consequece this message cannot be translated, but this is true for messages which are generated to indicate why a password change failed, too. The rest of the patch changes the way the response from the child is packed and unpacked to allow more than one response message.
bye, Sumit
From cbf80a5f3aa12917c6c05dc264916564caf40068 Mon Sep 17 00:00:00 2001 From: Sumit Bose sbose@redhat.com Date: Fri, 23 Apr 2010 15:21:38 +0200 Subject: [PATCH 1/2] Split pam_data utilities into a separate file
src/Makefile.am | 2 + src/providers/dp_auth_util.c | 91 ----------------------------- src/providers/dp_pam_data_util.c | 116 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 91 deletions(-) create mode 100644 src/providers/dp_pam_data_util.c
diff --git a/src/Makefile.am b/src/Makefile.am index ead53f9..637a4f3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -221,6 +221,7 @@ SSSD_UTIL_OBJ = \ db/sysdb_search.c \ monitor/monitor_sbus.c \ providers/dp_auth_util.c \
- providers/dp_pam_data_util.c \ providers/dp_sbus.c \ sbus/sbus_client.c \ sbus/sssd_dbus_common.c \
@@ -824,6 +825,7 @@ krb5_child_SOURCES = \ providers/krb5/krb5_become_user.c \ providers/krb5/krb5_child.c \ providers/child_common.c \
- providers/dp_pam_data_util.c \ util/user_info_msg.c \ util/sss_krb5.c
krb5_child_CFLAGS = \ diff --git a/src/providers/dp_auth_util.c b/src/providers/dp_auth_util.c index d0ce190..e09a692 100644 --- a/src/providers/dp_auth_util.c +++ b/src/providers/dp_auth_util.c @@ -21,97 +21,6 @@
#include "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);
-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 = talloc_zero(mem_ctx, struct pam_data);
- if (pd == NULL) {
DEBUG(1, ("talloc_zero 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));
- DEBUG(l, ("domain: %s\n", pd->domain));
- DEBUG(l, ("user: %s\n", pd->user));
- DEBUG(l, ("service: %s\n", pd->service));
- DEBUG(l, ("tty: %s\n", pd->tty));
- DEBUG(l, ("ruser: %s\n", pd->ruser));
- DEBUG(l, ("rhost: %s\n", pd->rhost));
- DEBUG(l, ("authtok type: %d\n", pd->authtok_type));
- DEBUG(l, ("authtok size: %d\n", pd->authtok_size));
- DEBUG(l, ("newauthtok type: %d\n", pd->newauthtok_type));
- DEBUG(l, ("newauthtok size: %d\n", pd->newauthtok_size));
- DEBUG(l, ("priv: %d\n", pd->priv));
- DEBUG(l, ("cli_pid: %d\n", pd->cli_pid));
-}
-int pam_add_response(struct pam_data *pd, enum response_type type,
int len, const uint8_t *data)
-{
- struct response_data *new;
- new = talloc(pd, struct response_data);
- if (new == NULL) return ENOMEM;
- new->type = type;
- new->len = len;
- new->data = talloc_memdup(pd, data, len);
- if (new->data == NULL) return ENOMEM;
- new->next = pd->resp_list;
- pd->resp_list = new;
- return EOK;
-}
bool dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd) { int ret; diff --git a/src/providers/dp_pam_data_util.c b/src/providers/dp_pam_data_util.c new file mode 100644 index 0000000..f551a48 --- /dev/null +++ b/src/providers/dp_pam_data_util.c @@ -0,0 +1,116 @@ +/*
- SSSD
- Utilities to for tha pam_data structure
- Authors:
Sumit Bose <sbose@redhat.com>
- Copyright (C) 2009 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 "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);
+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 = talloc_zero(mem_ctx, struct pam_data);
- if (pd == NULL) {
DEBUG(1, ("talloc_zero 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));
- DEBUG(l, ("domain: %s\n", pd->domain));
- DEBUG(l, ("user: %s\n", pd->user));
- DEBUG(l, ("service: %s\n", pd->service));
- DEBUG(l, ("tty: %s\n", pd->tty));
- DEBUG(l, ("ruser: %s\n", pd->ruser));
- DEBUG(l, ("rhost: %s\n", pd->rhost));
- DEBUG(l, ("authtok type: %d\n", pd->authtok_type));
- DEBUG(l, ("authtok size: %d\n", pd->authtok_size));
- DEBUG(l, ("newauthtok type: %d\n", pd->newauthtok_type));
- DEBUG(l, ("newauthtok size: %d\n", pd->newauthtok_size));
- DEBUG(l, ("priv: %d\n", pd->priv));
- DEBUG(l, ("cli_pid: %d\n", pd->cli_pid));
+}
+int pam_add_response(struct pam_data *pd, enum response_type type,
int len, const uint8_t *data)
+{
- struct response_data *new;
- new = talloc(pd, struct response_data);
- if (new == NULL) return ENOMEM;
- new->type = type;
- new->len = len;
- new->data = talloc_memdup(pd, data, len);
- if (new->data == NULL) return ENOMEM;
- new->next = pd->resp_list;
- pd->resp_list = new;
- return EOK;
+}
1.6.6.1
From 37faca0409579e20f0744730d1be8f1a105b523d Mon Sep 17 00:00:00 2001 From: Sumit Bose sbose@redhat.com Date: Fri, 23 Apr 2010 13:37:22 +0200 Subject: [PATCH 2/2] Handle Krb5 password expiration warning
src/providers/krb5/krb5_auth.c | 163 +++++++++++--------------------------- src/providers/krb5/krb5_child.c | 167 ++++++++++++++++++++++++++------------- src/sss_client/pam_sss.c | 14 +++- src/sss_client/sss_cli.h | 6 +- 4 files changed, 176 insertions(+), 174 deletions(-)
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index 3b36b93..cca0132 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -6,7 +6,7 @@ Authors: Sumit Bose sbose@redhat.com
- Copyright (C) 2009 Red Hat
Copyright (C) 2009-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
@@ -45,74 +45,6 @@ #define KRB5_CHILD SSSD_LIBEXEC_PATH"/krb5_child" #endif
-static errno_t add_krb5_env(struct dp_option *opts, const char *ccname,
struct pam_data *pd)
-{
- int ret;
- const char *dummy;
- char *env;
- TALLOC_CTX *tmp_ctx = NULL;
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
DEBUG(1, ("talloc_new failed.\n"));
return ENOMEM;
- }
- if (ccname != NULL) {
env = talloc_asprintf(tmp_ctx, "%s=%s",CCACHE_ENV_NAME, ccname);
if (env == NULL) {
DEBUG(1, ("talloc_asprintf failed.\n"));
ret = ENOMEM;
goto done;
}
ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
(uint8_t *) env);
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
goto done;
}
- }
- dummy = dp_opt_get_cstring(opts, KRB5_REALM);
- if (dummy != NULL) {
env = talloc_asprintf(tmp_ctx, "%s=%s", SSSD_KRB5_REALM, dummy);
if (env == NULL) {
DEBUG(1, ("talloc_asprintf failed.\n"));
ret = ENOMEM;
goto done;
}
ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
(uint8_t *) env);
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
goto done;
}
- }
- dummy = dp_opt_get_cstring(opts, KRB5_KDC);
- if (dummy != NULL) {
env = talloc_asprintf(tmp_ctx, "%s=%s", SSSD_KRB5_KDC, dummy);
if (env == NULL) {
DEBUG(1, ("talloc_asprintf failed.\n"));
ret = ENOMEM;
goto done;
}
ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
(uint8_t *) env);
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
goto done;
}
- }
- ret = EOK;
-done:
- talloc_free(tmp_ctx);
- return ret;
-}
static errno_t check_if_ccache_file_is_used(uid_t uid, const char *ccname, bool *result) { @@ -1116,11 +1048,11 @@ static void krb5_child_done(struct tevent_req *subreq) int ret; uint8_t *buf = NULL; ssize_t len = -1;
- ssize_t pref_len;
- int p;
- int32_t *msg_status;
- int32_t *msg_type;
- int32_t *msg_len;
ssize_t pref_len = sizeof(CCACHE_ENV_NAME);
size_t p;
int32_t msg_status;
int32_t msg_type;
int32_t msg_len;
ret = handle_child_recv(subreq, pd, &buf, &len); talloc_zfree(kr->timeout_handler);
@@ -1137,71 +1069,76 @@ static void krb5_child_done(struct tevent_req *subreq) return; }
- if ((size_t) len < 3*sizeof(int32_t)) {
if ((size_t) len < sizeof(int32_t)) { DEBUG(1, ("message too short.\n")); ret = EINVAL; goto done; }
p=0;
- msg_status = ((int32_t *)(buf+p));
- p += sizeof(int32_t);
- SAFEALIGN_COPY_INT32(&msg_status, buf+p, &p);
- msg_type = ((int32_t *)(buf+p));
- p += sizeof(int32_t);
- while (p < len) {
SAFEALIGN_COPY_INT32(&msg_type, buf+p, &p);
SAFEALIGN_COPY_INT32(&msg_len, buf+p, &p);
- msg_len = ((int32_t *)(buf+p));
- p += sizeof(int32_t);
DEBUG(9, ("child response [%d][%d][%d].\n", msg_status, msg_type,
msg_len));
- DEBUG(4, ("child response [%d][%d][%d].\n", *msg_status, *msg_type,
*msg_len));
- if ((p + *msg_len) != len) {
DEBUG(1, ("message format error [%d] != [%d].\n", p+*msg_len, len));
goto done;
- }
if ((p + msg_len) > len) {
DEBUG(1, ("message format error [%d] > [%d].\n", p+msg_len, len));
ret = EINVAL;
goto done;
}
- if (*msg_status != PAM_SUCCESS && *msg_status != PAM_AUTHINFO_UNAVAIL) {
state->pam_status = *msg_status;
state->dp_err = DP_ERR_OK;
if (msg_len > pref_len &&
strncmp((const char *) &buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
kr->ccname = talloc_strndup(kr, (char *) &buf[p+pref_len],
msg_len-pref_len);
if (kr->ccname == NULL) {
DEBUG(1, ("talloc_strndup failed.\n"));
ret = ENOMEM;
goto done;
}
}
ret = pam_add_response(pd, *msg_type, *msg_len, &buf[p]);
ret = pam_add_response(pd, msg_type, msg_len, &buf[p]); if (ret != EOK) { /* This is not a fatal error */ DEBUG(1, ("pam_add_response failed.\n")); }
p += msg_len;
if ((p < len) && (p + 2*sizeof(int32_t) >= len)) {
DEBUG(1, ("The remainder of the message is too short.\n"));
ret = EINVAL;
goto done;
}
}
if (msg_status != PAM_SUCCESS && msg_status != PAM_AUTHINFO_UNAVAIL) {
state->pam_status = msg_status;
state->dp_err = DP_ERR_OK; ret = EOK; goto done;
} else {
state->pam_status = *msg_status;
}state->pam_status = msg_status;
- if (*msg_status == PAM_SUCCESS && pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
- if (msg_status == PAM_SUCCESS && pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) { state->pam_status = PAM_SUCCESS; state->dp_err = DP_ERR_OK; ret = EOK; goto done; }
- pref_len = strlen(CCACHE_ENV_NAME)+1;
- if (*msg_len > pref_len &&
strncmp((const char *) &buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
kr->ccname = talloc_strndup(kr, (char *) &buf[p+pref_len],
*msg_len-pref_len);
if (kr->ccname == NULL) {
DEBUG(1, ("talloc_strndup failed.\n"));
ret = ENOMEM;
goto done;
}
- } else {
DEBUG(1, ("Missing ccache name in child response [%.*s].\n", *msg_len,
&buf[p]));
- if (kr->ccname == NULL) {
}DEBUG(1, ("Missing ccache name in child response.\n")); ret = EINVAL; goto done;
- if (*msg_status == PAM_AUTHINFO_UNAVAIL) {
- if (msg_status == PAM_AUTHINFO_UNAVAIL) { if (kr->srv != NULL) { fo_set_port_status(kr->srv, PORT_NOT_WORKING); }
@@ -1212,7 +1149,7 @@ static void krb5_child_done(struct tevent_req *subreq) }
if (kr->kpasswd_srv != NULL) {
if (*msg_status == PAM_AUTHTOK_LOCK_BUSY) {
if (msg_status == PAM_AUTHTOK_LOCK_BUSY) { fo_set_port_status(kr->kpasswd_srv, PORT_NOT_WORKING); } else { fo_set_port_status(kr->kpasswd_srv, PORT_WORKING);
@@ -1255,14 +1192,6 @@ static void krb5_save_ccname_done(struct tevent_req *subreq) int ret; char *password = NULL;
- if (pd->cmd == SSS_PAM_AUTHENTICATE || pd->cmd == SSS_PAM_CHAUTHTOK) {
ret = add_krb5_env(krb5_ctx->opts, kr->ccname, pd);
if (ret != EOK) {
DEBUG(1, ("add_krb5_env failed.\n"));
goto done;
}
- }
- ret = sysdb_set_user_attr_recv(subreq); talloc_zfree(subreq); if (ret != EOK) {
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index 620e4d1..ac5fd75 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -6,7 +6,7 @@ Authors: Sumit Bose sbose@redhat.com
- Copyright (C) 2009 Red Hat
Copyright (C) 2009-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
@@ -103,6 +103,36 @@ static const char *__krb5_error_msg; sss_krb5_free_error_message(krb5_error_ctx, __krb5_error_msg); \ } while(0);
+static krb5_error_code sss_krb5_prompter(krb5_context context, void *data,
const char *name, const char *banner,
int num_prompts, krb5_prompt prompts[])
+{
- int ret;
- struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
- if (num_prompts != 0) {
DEBUG(1, ("Cannot handle password prompts.\n"));
return KRB5_LIBOS_CANTREADPWD;
- }
- if (banner == NULL || *banner == '\0') {
DEBUG(5, ("Prompter called with empty banner, nothing to do.\n"));
return EOK;
- }
- DEBUG(9, ("Prompter called with [%s].\n", banner));
- ret = pam_add_response(kr->pd, SSS_PAM_TEXT_MSG, strlen(banner)+1,
(const uint8_t *) banner);
- if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
- }
- return EOK;
+}
static krb5_error_code create_empty_cred(struct krb5_req *kr, krb5_creds **_cred) { krb5_error_code kerr; @@ -247,22 +277,39 @@ done: return kerr; }
-static errno_t pack_response_packet(struct response *resp, int status, int type,
size_t len, const uint8_t *data)
+static errno_t pack_response_packet(struct response *resp, int status,
struct pam_data *pd)
{
- size_t size = 0; size_t p = 0;
- struct response_data *pdr;
- size = sizeof(int32_t);
- resp->buf = talloc_array(resp, uint8_t,
3*sizeof(int32_t) + len);
pdr = pd->resp_list;
while (pdr != NULL) {
size += 2*sizeof(int32_t) + pdr->len;
pdr = pdr->next;
}
resp->buf = talloc_array(resp, uint8_t, size); if (!resp->buf) { DEBUG(1, ("Insufficient memory to create message.\n")); return ENOMEM; }
SAFEALIGN_SET_INT32(&resp->buf[p], status, &p);
- SAFEALIGN_SET_INT32(&resp->buf[p], type, &p);
- SAFEALIGN_SET_INT32(&resp->buf[p], len, &p);
- safealign_memcpy(&resp->buf[p], data, len, &p);
pdr = pd->resp_list;
while(pdr != NULL) {
SAFEALIGN_SET_INT32(&resp->buf[p], pdr->type, &p);
SAFEALIGN_SET_INT32(&resp->buf[p], pdr->len, &p);
safealign_memcpy(&resp->buf[p], pdr->data, pdr->len, &p);
pdr = pdr->next;
}
resp->size = p;
@@ -271,15 +318,12 @@ static errno_t pack_response_packet(struct response *resp, int status, int type,
static struct response *prepare_response_message(struct krb5_req *kr, krb5_error_code kerr,
char *user_error_message, int pam_status)
{ char *msg = NULL; const char *krb5_msg = NULL; int ret; struct response *resp;
size_t user_resp_len;
uint8_t *user_resp;
resp = talloc_zero(kr, struct response); if (resp == NULL) {
@@ -289,9 +333,8 @@ static struct response *prepare_response_message(struct krb5_req *kr,
if (kerr == 0) { if(kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
ret = pack_response_packet(resp, PAM_SUCCESS, SSS_PAM_SYSTEM_INFO,
strlen("success") + 1,
(const uint8_t *) "success");
pam_status = PAM_SUCCESS;
ret = EOK; } else { if (kr->ccname == NULL) { DEBUG(1, ("Error obtaining ccname.\n"));
@@ -304,44 +347,28 @@ static struct response *prepare_response_message(struct krb5_req *kr, return NULL; }
ret = pack_response_packet(resp, PAM_SUCCESS, SSS_PAM_ENV_ITEM,
strlen(msg) + 1, (uint8_t *) msg);
pam_status = PAM_SUCCESS;
ret = pam_add_response(kr->pd, SSS_PAM_ENV_ITEM, strlen(msg) + 1,
} else {(uint8_t *) msg); talloc_zfree(msg); }
if (user_error_message != NULL) {
ret = pack_user_info_chpass_error(kr, user_error_message,
&user_resp_len, &user_resp);
if (ret != EOK) {
DEBUG(1, ("pack_user_info_chpass_error failed.\n"));
talloc_zfree(user_error_message);
} else {
ret = pack_response_packet(resp, pam_status, SSS_PAM_USER_INFO,
user_resp_len, user_resp);
if (ret != EOK) {
DEBUG(1, ("pack_response_packet failed.\n"));
talloc_zfree(user_error_message);
}
}
}
if (user_error_message == NULL) {
krb5_msg = sss_krb5_get_error_message(krb5_error_ctx, kerr);
if (krb5_msg == NULL) {
DEBUG(1, ("sss_krb5_get_error_message failed.\n"));
return NULL;
}
ret = pack_response_packet(resp, pam_status, SSS_PAM_SYSTEM_INFO,
strlen(krb5_msg) + 1,
(const uint8_t *) krb5_msg);
sss_krb5_free_error_message(krb5_error_ctx, krb5_msg);
} else {
krb5_msg = sss_krb5_get_error_message(krb5_error_ctx, kerr);
if (krb5_msg == NULL) {
DEBUG(1, ("sss_krb5_get_error_message failed.\n"));
return NULL; }
ret = pam_add_response(kr->pd, SSS_PAM_SYSTEM_INFO,
strlen(krb5_msg) + 1,
(const uint8_t *) krb5_msg);
sss_krb5_free_error_message(krb5_error_ctx, krb5_msg);
}
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
ret = pack_response_packet(resp, pam_status, kr->pd); if (ret != EOK) { DEBUG(1, ("pack_response_packet failed.\n")); return NULL;
@@ -350,15 +377,14 @@ static struct response *prepare_response_message(struct krb5_req *kr, return resp; }
-static errno_t sendresponse(int fd, krb5_error_code kerr,
char *user_error_message, int pam_status,
+static errno_t sendresponse(int fd, krb5_error_code kerr, int pam_status, struct krb5_req *kr) { struct response *resp; size_t written; int ret;
- resp = prepare_response_message(kr, kerr, user_error_message, pam_status);
- resp = prepare_response_message(kr, kerr, pam_status); if (resp == NULL) { DEBUG(1, ("prepare_response_message failed.\n")); return ENOMEM;
@@ -481,8 +507,8 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr, int ret;
kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
password, NULL, NULL, 0, NULL,
kr->options);
password, sss_krb5_prompter, kr, 0,
if (kerr != 0) { KRB5_DEBUG(1, kerr); return kerr;NULL, kr->options);
@@ -533,6 +559,9 @@ static errno_t changepw_child(int fd, struct krb5_req *kr) krb5_data result_code_string; krb5_data result_string; char *user_error_message = NULL;
size_t user_resp_len;
uint8_t *user_resp;
krb5_prompter_fct prompter = sss_krb5_prompter;
pass_str = talloc_strndup(kr, (const char *) kr->pd->authtok, kr->pd->authtok_size);
@@ -542,8 +571,13 @@ static errno_t changepw_child(int fd, struct krb5_req *kr) goto sendresponse; }
- if (kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
/* We do not need a password expiration warning here. */
prompter = NULL;
- }
- kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
pass_str, NULL, NULL, 0,
if (kerr != 0) {pass_str, prompter, kr, 0, kr->krb5_ctx->changepw_principle, kr->options);
@@ -612,6 +646,20 @@ static errno_t changepw_child(int fd, struct krb5_req *kr) } }
if (user_error_message != NULL) {
ret = pack_user_info_chpass_error(kr->pd, user_error_message,
&user_resp_len, &user_resp);
if (ret != EOK) {
DEBUG(1, ("pack_user_info_chpass_error failed.\n"));
} else {
ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, user_resp_len,
user_resp);
if (ret != EOK) {
DEBUG(1, ("pack_response_packet failed.\n"));
}
}
}
}pam_status = PAM_AUTHTOK_ERR; goto sendresponse;
@@ -631,7 +679,7 @@ static errno_t changepw_child(int fd, struct krb5_req *kr) }
sendresponse:
- ret = sendresponse(fd, kerr, user_error_message, pam_status, kr);
- ret = sendresponse(fd, kerr, pam_status, kr); if (ret != EOK) { DEBUG(1, ("sendresponse failed.\n")); }
@@ -662,7 +710,7 @@ static errno_t tgt_req_child(int fd, struct krb5_req *kr) So we validate the password by trying to get a changepw ticket. */ if (kerr == KRB5KDC_ERR_KEY_EXP) { kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
pass_str, NULL, NULL, 0,
pass_str, sss_krb5_prompter, kr, 0, kr->krb5_ctx->changepw_principle, kr->options); krb5_free_cred_contents(kr->ctx, kr->creds);
@@ -693,7 +741,7 @@ static errno_t tgt_req_child(int fd, struct krb5_req *kr) }
sendresponse:
- ret = sendresponse(fd, kerr, NULL, pam_status, kr);
- ret = sendresponse(fd, kerr, pam_status, kr); if (ret != EOK) { DEBUG(1, ("sendresponse failed.\n")); }
@@ -712,7 +760,7 @@ static errno_t create_empty_ccache(int fd, struct krb5_req *kr) pam_status = PAM_SYSTEM_ERR; }
- ret = sendresponse(fd, ret, NULL, pam_status, kr);
- ret = sendresponse(fd, ret, pam_status, kr); if (ret != EOK) { DEBUG(1, ("sendresponse failed.\n")); }
@@ -878,6 +926,15 @@ static int krb5_setup(struct krb5_req *kr, uint32_t offline) goto failed; }
- /* A prompter is used to catch messages about when a password will
* expired. The library shall not use the prompter to ask for a new password
* but shall return KRB5KDC_ERR_KEY_EXP. */
- krb5_get_init_creds_opt_set_change_password_prompt(kr->options, 0);
- if (kerr != 0) {
KRB5_DEBUG(1, kerr);
goto failed;
- }
/* TODO: set options, e.g.
- krb5_get_init_creds_opt_set_tkt_life
- krb5_get_init_creds_opt_set_renew_life
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c index 31a3de8..8d6953b 100644 --- a/src/sss_client/pam_sss.c +++ b/src/sss_client/pam_sss.c @@ -888,7 +888,7 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf, switch(type) { case SSS_PAM_SYSTEM_INFO: if (buf[p + (len -1)] != '\0') {
D(("user info does not end with \\0."));
D(("system info does not end with \\0.")); break; } logger(pamh, LOG_INFO, "system info: [%s]", &buf[p]);
@@ -940,6 +940,18 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf, D(("eval_user_info_response failed")); } break;
case SSS_PAM_TEXT_MSG:
if (buf[p + (len -1)] != '\0') {
D(("system info does not end with \\0."));
break;
}
ret = do_pam_conversation(pamh, PAM_TEXT_INFO, (char *) &buf[p],
NULL, NULL);
if (ret != PAM_SUCCESS) {
D(("do_pam_conversation failed."));
}
break; default: D(("Unknown response type [%d]", type)); }
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h index f7e58fe..8712a6f 100644 --- a/src/sss_client/sss_cli.h +++ b/src/sss_client/sss_cli.h @@ -316,9 +316,13 @@ enum response_type { * @param String, zero terminated, of the form * name=value. See putenv(3) and pam_putenv(3) for * details. */
- SSS_PAM_USER_INFO /**< A message which should be displayed to the user.
- SSS_PAM_USER_INFO, /**< A message which should be displayed to the user. * @param User info message, see #user_info_type * for details. */
- SSS_PAM_TEXT_MSG, /**< A plain text message which should be displayed to
* the user.This should only be used in the case where
* it is not possile to use SSS_PAM_USER_INFO.
* @param A zero terminated string. */
};
/**
1.6.6.1
sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel
On 04/29/2010 07:27 AM, Sumit Bose wrote:
Sorry, the first patch had dependencies to another patch, new version attached.
bye, Sumit On Tue, Apr 27, 2010 at 02:08:02PM +0200, Sumit Bose wrote:
Hi,
this two patches add the support to display a warning to the user that the Kerberos password is about to expire. The first patch just moves some utility functions to a separate file to avoid linking the krb5_child against libdbus.
I the second patch a prompter function is introduced to catch the warning message which is generated by libkrb5. With the current API of MIT Kerberos we have to rely on this message, because the the underlying AS_REPLY data is not exposed by the library. As a consequece this message cannot be translated, but this is true for messages which are generated to indicate why a password change failed, too. The rest of the patch changes the way the response from the child is packed and unpacked to allow more than one response message.
bye, Sumit
Patch 0001: Ack
Patch 0002: The krb5_child_done() function is in desperate need of comments. At minimum, there needs to be a comment describing the format of the received buffer. Same for the pack_response_packet().
This is wrong: if (msg_len > pref_len && strncmp((const char *) &buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
pref_len needs to be another byte longer to account for the '='. Also, a comment here would be fantastic.
Otherwise this looks fine.
On Fri, Apr 30, 2010 at 10:18:39AM -0400, Stephen Gallagher wrote:
On 04/29/2010 07:27 AM, Sumit Bose wrote:
Sorry, the first patch had dependencies to another patch, new version attached.
bye, Sumit On Tue, Apr 27, 2010 at 02:08:02PM +0200, Sumit Bose wrote:
Hi,
this two patches add the support to display a warning to the user that the Kerberos password is about to expire. The first patch just moves some utility functions to a separate file to avoid linking the krb5_child against libdbus.
I the second patch a prompter function is introduced to catch the warning message which is generated by libkrb5. With the current API of MIT Kerberos we have to rely on this message, because the the underlying AS_REPLY data is not exposed by the library. As a consequece this message cannot be translated, but this is true for messages which are generated to indicate why a password change failed, too. The rest of the patch changes the way the response from the child is packed and unpacked to allow more than one response message.
bye, Sumit
Patch 0001: Ack
Patch 0002: The krb5_child_done() function is in desperate need of comments. At minimum, there needs to be a comment describing the format of the received buffer. Same for the pack_response_packet().
comments added
This is wrong: if (msg_len > pref_len && strncmp((const char *) &buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
pref_len needs to be another byte longer to account for the '='. Also, a comment here would be fantastic.
pref_len is already a bye longer, because I used sizeof instead of strlen. I added a comment about this, too.
New version attached.
bye, Sumit
Otherwise this looks fine.
-- 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 04/30/2010 12:10 PM, Sumit Bose wrote:
On Fri, Apr 30, 2010 at 10:18:39AM -0400, Stephen Gallagher wrote:
On 04/29/2010 07:27 AM, Sumit Bose wrote:
Sorry, the first patch had dependencies to another patch, new version attached.
bye, Sumit On Tue, Apr 27, 2010 at 02:08:02PM +0200, Sumit Bose wrote:
Hi,
this two patches add the support to display a warning to the user that the Kerberos password is about to expire. The first patch just moves some utility functions to a separate file to avoid linking the krb5_child against libdbus.
I the second patch a prompter function is introduced to catch the warning message which is generated by libkrb5. With the current API of MIT Kerberos we have to rely on this message, because the the underlying AS_REPLY data is not exposed by the library. As a consequece this message cannot be translated, but this is true for messages which are generated to indicate why a password change failed, too. The rest of the patch changes the way the response from the child is packed and unpacked to allow more than one response message.
bye, Sumit
Patch 0001: Ack
Patch 0002: The krb5_child_done() function is in desperate need of comments. At minimum, there needs to be a comment describing the format of the received buffer. Same for the pack_response_packet().
comments added
This is wrong: if (msg_len> pref_len&& strncmp((const char *)&buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
pref_len needs to be another byte longer to account for the '='. Also, a comment here would be fantastic.
pref_len is already a bye longer, because I used sizeof instead of strlen. I added a comment about this, too.
New version attached.
Sumit, these patches don't apply cleanly on sssd-1-2 at present. Would you please rebase them and resend?
On Mon, May 03, 2010 at 02:29:39PM -0400, Stephen Gallagher wrote:
On 04/30/2010 12:10 PM, Sumit Bose wrote:
On Fri, Apr 30, 2010 at 10:18:39AM -0400, Stephen Gallagher wrote:
On 04/29/2010 07:27 AM, Sumit Bose wrote:
Sorry, the first patch had dependencies to another patch, new version attached.
bye, Sumit On Tue, Apr 27, 2010 at 02:08:02PM +0200, Sumit Bose wrote:
Hi,
this two patches add the support to display a warning to the user that the Kerberos password is about to expire. The first patch just moves some utility functions to a separate file to avoid linking the krb5_child against libdbus.
I the second patch a prompter function is introduced to catch the warning message which is generated by libkrb5. With the current API of MIT Kerberos we have to rely on this message, because the the underlying AS_REPLY data is not exposed by the library. As a consequece this message cannot be translated, but this is true for messages which are generated to indicate why a password change failed, too. The rest of the patch changes the way the response from the child is packed and unpacked to allow more than one response message.
bye, Sumit
Patch 0001: Ack
Patch 0002: The krb5_child_done() function is in desperate need of comments. At minimum, there needs to be a comment describing the format of the received buffer. Same for the pack_response_packet().
comments added
This is wrong: if (msg_len> pref_len&& strncmp((const char *)&buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
pref_len needs to be another byte longer to account for the '='. Also, a comment here would be fantastic.
pref_len is already a bye longer, because I used sizeof instead of strlen. I added a comment about this, too.
New version attached.
Sumit, these patches don't apply cleanly on sssd-1-2 at present. Would you please rebase them and resend?
sure, rebased 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 Mon, May 03, 2010 at 10:39:57PM +0200, Sumit Bose wrote:
On Mon, May 03, 2010 at 02:29:39PM -0400, Stephen Gallagher wrote:
On 04/30/2010 12:10 PM, Sumit Bose wrote:
On Fri, Apr 30, 2010 at 10:18:39AM -0400, Stephen Gallagher wrote:
On 04/29/2010 07:27 AM, Sumit Bose wrote:
Sorry, the first patch had dependencies to another patch, new version attached.
bye, Sumit On Tue, Apr 27, 2010 at 02:08:02PM +0200, Sumit Bose wrote:
Hi,
this two patches add the support to display a warning to the user that the Kerberos password is about to expire. The first patch just moves some utility functions to a separate file to avoid linking the krb5_child against libdbus.
I the second patch a prompter function is introduced to catch the warning message which is generated by libkrb5. With the current API of MIT Kerberos we have to rely on this message, because the the underlying AS_REPLY data is not exposed by the library. As a consequece this message cannot be translated, but this is true for messages which are generated to indicate why a password change failed, too. The rest of the patch changes the way the response from the child is packed and unpacked to allow more than one response message.
bye, Sumit
Patch 0001: Ack
Patch 0002: The krb5_child_done() function is in desperate need of comments. At minimum, there needs to be a comment describing the format of the received buffer. Same for the pack_response_packet().
comments added
This is wrong: if (msg_len> pref_len&& strncmp((const char *)&buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
pref_len needs to be another byte longer to account for the '='. Also, a comment here would be fantastic.
pref_len is already a bye longer, because I used sizeof instead of strlen. I added a comment about this, too.
New version attached.
Sumit, these patches don't apply cleanly on sssd-1-2 at present. Would you please rebase them and resend?
sure, rebased version attached.
ah, sorry, I have attached a broken version, this one should work.
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
From c6f50758953fba24f7922dd573a234cc26761b9d Mon Sep 17 00:00:00 2001 From: Sumit Bose sbose@redhat.com Date: Fri, 23 Apr 2010 15:21:38 +0200 Subject: [PATCH 1/2] Split pam_data utilities into a separate file
src/Makefile.am | 2 + src/providers/dp_auth_util.c | 35 ---------------------- src/providers/dp_pam_data_util.c | 60 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 35 deletions(-) create mode 100644 src/providers/dp_pam_data_util.c
diff --git a/src/Makefile.am b/src/Makefile.am index 22ac358..5fb4062 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -221,6 +221,7 @@ SSSD_UTIL_OBJ = \ db/sysdb_search.c \ monitor/monitor_sbus.c \ providers/dp_auth_util.c \
- providers/dp_pam_data_util.c \ providers/dp_sbus.c \ sbus/sbus_client.c \ sbus/sssd_dbus_common.c \
@@ -825,6 +826,7 @@ krb5_child_SOURCES = \ providers/krb5/krb5_become_user.c \ providers/krb5/krb5_child.c \ providers/child_common.c \
- providers/dp_pam_data_util.c \ util/user_info_msg.c \ util/sss_krb5.c
krb5_child_CFLAGS = \ diff --git a/src/providers/dp_auth_util.c b/src/providers/dp_auth_util.c index fb10ced..e09a692 100644 --- a/src/providers/dp_auth_util.c +++ b/src/providers/dp_auth_util.c @@ -21,41 +21,6 @@
#include "data_provider.h"
-void pam_print_data(int l, struct pam_data *pd) -{
- DEBUG(l, ("command: %d\n", pd->cmd));
- DEBUG(l, ("domain: %s\n", pd->domain));
- DEBUG(l, ("user: %s\n", pd->user));
- DEBUG(l, ("service: %s\n", pd->service));
- DEBUG(l, ("tty: %s\n", pd->tty));
- DEBUG(l, ("ruser: %s\n", pd->ruser));
- DEBUG(l, ("rhost: %s\n", pd->rhost));
- DEBUG(l, ("authtok type: %d\n", pd->authtok_type));
- DEBUG(l, ("authtok size: %d\n", pd->authtok_size));
- DEBUG(l, ("newauthtok type: %d\n", pd->newauthtok_type));
- DEBUG(l, ("newauthtok size: %d\n", pd->newauthtok_size));
- DEBUG(l, ("priv: %d\n", pd->priv));
- DEBUG(l, ("cli_pid: %d\n", pd->cli_pid));
-}
-int pam_add_response(struct pam_data *pd, enum response_type type,
int len, const uint8_t *data)
-{
- struct response_data *new;
- new = talloc(pd, struct response_data);
- if (new == NULL) return ENOMEM;
- new->type = type;
- new->len = len;
- new->data = talloc_memdup(pd, data, len);
- if (new->data == NULL) return ENOMEM;
- new->next = pd->resp_list;
- pd->resp_list = new;
- return EOK;
-}
bool dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd) { int ret; diff --git a/src/providers/dp_pam_data_util.c b/src/providers/dp_pam_data_util.c new file mode 100644 index 0000000..308bd7c --- /dev/null +++ b/src/providers/dp_pam_data_util.c @@ -0,0 +1,60 @@ +/*
- SSSD
- Utilities to for tha pam_data structure
- Authors:
Sumit Bose <sbose@redhat.com>
- Copyright (C) 2009 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 "providers/data_provider.h"
+void pam_print_data(int l, struct pam_data *pd) +{
- DEBUG(l, ("command: %d\n", pd->cmd));
- DEBUG(l, ("domain: %s\n", pd->domain));
- DEBUG(l, ("user: %s\n", pd->user));
- DEBUG(l, ("service: %s\n", pd->service));
- DEBUG(l, ("tty: %s\n", pd->tty));
- DEBUG(l, ("ruser: %s\n", pd->ruser));
- DEBUG(l, ("rhost: %s\n", pd->rhost));
- DEBUG(l, ("authtok type: %d\n", pd->authtok_type));
- DEBUG(l, ("authtok size: %d\n", pd->authtok_size));
- DEBUG(l, ("newauthtok type: %d\n", pd->newauthtok_type));
- DEBUG(l, ("newauthtok size: %d\n", pd->newauthtok_size));
- DEBUG(l, ("priv: %d\n", pd->priv));
- DEBUG(l, ("cli_pid: %d\n", pd->cli_pid));
+}
+int pam_add_response(struct pam_data *pd, enum response_type type,
int len, const uint8_t *data)
+{
- struct response_data *new;
- new = talloc(pd, struct response_data);
- if (new == NULL) return ENOMEM;
- new->type = type;
- new->len = len;
- new->data = talloc_memdup(pd, data, len);
- if (new->data == NULL) return ENOMEM;
- new->next = pd->resp_list;
- pd->resp_list = new;
- return EOK;
+}
1.6.6.1
From 630caa98943b0b160dddeb74397868d062192db4 Mon Sep 17 00:00:00 2001 From: Sumit Bose sbose@redhat.com Date: Fri, 23 Apr 2010 13:37:22 +0200 Subject: [PATCH 2/2] Handle Krb5 password expiration warning
src/providers/krb5/krb5_auth.c | 185 +++++++++++++++------------------------ src/providers/krb5/krb5_child.c | 177 +++++++++++++++++++++++++------------ src/sss_client/pam_sss.c | 14 +++- src/sss_client/sss_cli.h | 6 +- 4 files changed, 210 insertions(+), 172 deletions(-)
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index f862f28..0851684 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -6,7 +6,7 @@ Authors: Sumit Bose sbose@redhat.com
- Copyright (C) 2009 Red Hat
Copyright (C) 2009-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
@@ -45,74 +45,6 @@ #define KRB5_CHILD SSSD_LIBEXEC_PATH"/krb5_child" #endif
-static errno_t add_krb5_env(struct dp_option *opts, const char *ccname,
struct pam_data *pd)
-{
- int ret;
- const char *dummy;
- char *env;
- TALLOC_CTX *tmp_ctx = NULL;
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
DEBUG(1, ("talloc_new failed.\n"));
return ENOMEM;
- }
- if (ccname != NULL) {
env = talloc_asprintf(tmp_ctx, "%s=%s",CCACHE_ENV_NAME, ccname);
if (env == NULL) {
DEBUG(1, ("talloc_asprintf failed.\n"));
ret = ENOMEM;
goto done;
}
ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
(uint8_t *) env);
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
goto done;
}
- }
- dummy = dp_opt_get_cstring(opts, KRB5_REALM);
- if (dummy != NULL) {
env = talloc_asprintf(tmp_ctx, "%s=%s", SSSD_KRB5_REALM, dummy);
if (env == NULL) {
DEBUG(1, ("talloc_asprintf failed.\n"));
ret = ENOMEM;
goto done;
}
ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
(uint8_t *) env);
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
goto done;
}
- }
- dummy = dp_opt_get_cstring(opts, KRB5_KDC);
- if (dummy != NULL) {
env = talloc_asprintf(tmp_ctx, "%s=%s", SSSD_KRB5_KDC, dummy);
if (env == NULL) {
DEBUG(1, ("talloc_asprintf failed.\n"));
ret = ENOMEM;
goto done;
}
ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
(uint8_t *) env);
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
goto done;
}
- }
- ret = EOK;
-done:
- talloc_free(tmp_ctx);
- return ret;
-}
static errno_t check_if_ccache_file_is_used(uid_t uid, const char *ccname, bool *result) { @@ -1107,10 +1039,10 @@ static void krb5_child_done(struct tevent_req *subreq) uint8_t *buf = NULL; ssize_t len = -1; ssize_t pref_len;
- int p;
- int32_t *msg_status;
- int32_t *msg_type;
- int32_t *msg_len;
size_t p;
int32_t msg_status;
int32_t msg_type;
int32_t msg_len;
ret = handle_child_recv(subreq, pd, &buf, &len); talloc_zfree(kr->timeout_handler);
@@ -1127,48 +1059,83 @@ static void krb5_child_done(struct tevent_req *subreq) return; }
- if ((size_t) len < 3*sizeof(int32_t)) {
/* A buffer with the following structure is expected.
* int32_t status of the request (required)
* message (zero or more)
*
* A message consists of:
* int32_t type of the message
* int32_t length of the following data
* uint8_t[len] data
*/
if ((size_t) len < sizeof(int32_t)) { DEBUG(1, ("message too short.\n")); ret = EINVAL; goto done; }
p=0;
- msg_status = ((int32_t *)(buf+p));
- p += sizeof(int32_t);
- SAFEALIGN_COPY_INT32(&msg_status, buf+p, &p);
- msg_type = ((int32_t *)(buf+p));
- p += sizeof(int32_t);
- while (p < len) {
SAFEALIGN_COPY_INT32(&msg_type, buf+p, &p);
SAFEALIGN_COPY_INT32(&msg_len, buf+p, &p);
- msg_len = ((int32_t *)(buf+p));
- p += sizeof(int32_t);
DEBUG(9, ("child response [%d][%d][%d].\n", msg_status, msg_type,
msg_len));
- DEBUG(4, ("child response [%d][%d][%d].\n", *msg_status, *msg_type,
*msg_len));
- if ((p + *msg_len) != len) {
DEBUG(1, ("message format error [%d] != [%d].\n", p+*msg_len, len));
goto done;
- }
if ((p + msg_len) > len) {
DEBUG(1, ("message format error [%d] > [%d].\n", p+msg_len, len));
ret = EINVAL;
goto done;
}
- if (*msg_status != PAM_SUCCESS && *msg_status != PAM_AUTHINFO_UNAVAIL &&
*msg_status != PAM_AUTHTOK_LOCK_BUSY) {
state->pam_status = *msg_status;
state->dp_err = DP_ERR_OK;
/* We need to save the name of the credential cache file. To find it
* we check if the data part of a message starts with
* CCACHE_ENV_NAME"=". pref_len also counts the trailing '=' because
* sizeof() counts the trailing '\0' of a string. */
pref_len = sizeof(CCACHE_ENV_NAME);
if (msg_len > pref_len &&
strncmp((const char *) &buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
kr->ccname = talloc_strndup(kr, (char *) &buf[p+pref_len],
msg_len-pref_len);
if (kr->ccname == NULL) {
DEBUG(1, ("talloc_strndup failed.\n"));
ret = ENOMEM;
goto done;
}
}
ret = pam_add_response(pd, *msg_type, *msg_len, &buf[p]);
ret = pam_add_response(pd, msg_type, msg_len, &buf[p]); if (ret != EOK) { /* This is not a fatal error */ DEBUG(1, ("pam_add_response failed.\n")); }
p += msg_len;
if ((p < len) && (p + 2*sizeof(int32_t) >= len)) {
DEBUG(1, ("The remainder of the message is too short.\n"));
ret = EINVAL;
goto done;
}
}
/* If the child request failed, but did not return an offline error code,
* return with the status */
if (msg_status != PAM_SUCCESS && msg_status != PAM_AUTHINFO_UNAVAIL &&
msg_status != PAM_AUTHTOK_LOCK_BUSY) {
state->pam_status = msg_status;
state->dp_err = DP_ERR_OK; ret = EOK; goto done;
} else {
state->pam_status = *msg_status;
}state->pam_status = msg_status;
- if (*msg_status == PAM_SUCCESS && pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
- /* If the child request was successful and we run the first pass of the
* change password request just return success. */
- if (msg_status == PAM_SUCCESS && pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) { state->pam_status = PAM_SUCCESS; state->dp_err = DP_ERR_OK; ret = EOK;
@@ -1206,20 +1173,16 @@ static void krb5_child_done(struct tevent_req *subreq) } else if (kr->srv != NULL) { fo_set_port_status(kr->srv, PORT_WORKING); }
- pref_len = strlen(CCACHE_ENV_NAME)+1;
- if (*msg_len > pref_len &&
strncmp((const char *) &buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
kr->ccname = talloc_strndup(kr, (char *) &buf[p+pref_len],
*msg_len-pref_len);
if (kr->ccname == NULL) {
DEBUG(1, ("talloc_strndup failed.\n"));
ret = ENOMEM;
goto done;
}
- } else {
DEBUG(1, ("Missing ccache name in child response [%.*s].\n", *msg_len, &buf[p]));
- /* The following cases are left now:
* - offline (msg_status == PAM_AUTHINFO_UNAVAIL or
* msg_status == PAM_AUTHTOK_LOCK_BUSY)
* - successful authentication or password change
*
* For all these cases we expect that one of the messages for the
* received buffer contains the name of the credential cache file. */
- if (kr->ccname == NULL) {
}DEBUG(1, ("Missing ccache name in child response.\n")); ret = EINVAL; goto done;
@@ -1323,14 +1286,6 @@ static void krb5_save_ccname_done(struct tevent_req *subreq) int ret; char *password = NULL;
- if (pd->cmd == SSS_PAM_AUTHENTICATE || pd->cmd == SSS_PAM_CHAUTHTOK) {
ret = add_krb5_env(krb5_ctx->opts, kr->ccname, pd);
if (ret != EOK) {
DEBUG(1, ("add_krb5_env failed.\n"));
goto done;
}
- }
- ret = sysdb_set_user_attr_recv(subreq); talloc_zfree(subreq); if (ret != EOK) {
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index 620e4d1..7249aeb 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -6,7 +6,7 @@ Authors: Sumit Bose sbose@redhat.com
- Copyright (C) 2009 Red Hat
Copyright (C) 2009-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
@@ -103,6 +103,36 @@ static const char *__krb5_error_msg; sss_krb5_free_error_message(krb5_error_ctx, __krb5_error_msg); \ } while(0);
+static krb5_error_code sss_krb5_prompter(krb5_context context, void *data,
const char *name, const char *banner,
int num_prompts, krb5_prompt prompts[])
+{
- int ret;
- struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
- if (num_prompts != 0) {
DEBUG(1, ("Cannot handle password prompts.\n"));
return KRB5_LIBOS_CANTREADPWD;
- }
- if (banner == NULL || *banner == '\0') {
DEBUG(5, ("Prompter called with empty banner, nothing to do.\n"));
return EOK;
- }
- DEBUG(9, ("Prompter called with [%s].\n", banner));
- ret = pam_add_response(kr->pd, SSS_PAM_TEXT_MSG, strlen(banner)+1,
(const uint8_t *) banner);
- if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
- }
- return EOK;
+}
static krb5_error_code create_empty_cred(struct krb5_req *kr, krb5_creds **_cred) { krb5_error_code kerr; @@ -247,22 +277,49 @@ done: return kerr; }
-static errno_t pack_response_packet(struct response *resp, int status, int type,
size_t len, const uint8_t *data)
+static errno_t pack_response_packet(struct response *resp, int status,
struct pam_data *pd)
{
- size_t size = 0; size_t p = 0;
- struct response_data *pdr;
- /* A buffer with the following structure must be created:
* int32_t status of the request (required)
* message (zero or more)
*
* A message consists of:
* int32_t type of the message
* int32_t length of the following data
* uint8_t[len] data
*/
- resp->buf = talloc_array(resp, uint8_t,
3*sizeof(int32_t) + len);
size = sizeof(int32_t);
pdr = pd->resp_list;
while (pdr != NULL) {
size += 2*sizeof(int32_t) + pdr->len;
pdr = pdr->next;
}
resp->buf = talloc_array(resp, uint8_t, size); if (!resp->buf) { DEBUG(1, ("Insufficient memory to create message.\n")); return ENOMEM; }
SAFEALIGN_SET_INT32(&resp->buf[p], status, &p);
- SAFEALIGN_SET_INT32(&resp->buf[p], type, &p);
- SAFEALIGN_SET_INT32(&resp->buf[p], len, &p);
- safealign_memcpy(&resp->buf[p], data, len, &p);
pdr = pd->resp_list;
while(pdr != NULL) {
SAFEALIGN_SET_INT32(&resp->buf[p], pdr->type, &p);
SAFEALIGN_SET_INT32(&resp->buf[p], pdr->len, &p);
safealign_memcpy(&resp->buf[p], pdr->data, pdr->len, &p);
pdr = pdr->next;
}
resp->size = p;
@@ -271,15 +328,12 @@ static errno_t pack_response_packet(struct response *resp, int status, int type,
static struct response *prepare_response_message(struct krb5_req *kr, krb5_error_code kerr,
char *user_error_message, int pam_status)
{ char *msg = NULL; const char *krb5_msg = NULL; int ret; struct response *resp;
size_t user_resp_len;
uint8_t *user_resp;
resp = talloc_zero(kr, struct response); if (resp == NULL) {
@@ -289,9 +343,8 @@ static struct response *prepare_response_message(struct krb5_req *kr,
if (kerr == 0) { if(kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
ret = pack_response_packet(resp, PAM_SUCCESS, SSS_PAM_SYSTEM_INFO,
strlen("success") + 1,
(const uint8_t *) "success");
pam_status = PAM_SUCCESS;
ret = EOK; } else { if (kr->ccname == NULL) { DEBUG(1, ("Error obtaining ccname.\n"));
@@ -304,44 +357,28 @@ static struct response *prepare_response_message(struct krb5_req *kr, return NULL; }
ret = pack_response_packet(resp, PAM_SUCCESS, SSS_PAM_ENV_ITEM,
strlen(msg) + 1, (uint8_t *) msg);
pam_status = PAM_SUCCESS;
ret = pam_add_response(kr->pd, SSS_PAM_ENV_ITEM, strlen(msg) + 1,
} else {(uint8_t *) msg); talloc_zfree(msg); }
if (user_error_message != NULL) {
ret = pack_user_info_chpass_error(kr, user_error_message,
&user_resp_len, &user_resp);
if (ret != EOK) {
DEBUG(1, ("pack_user_info_chpass_error failed.\n"));
talloc_zfree(user_error_message);
} else {
ret = pack_response_packet(resp, pam_status, SSS_PAM_USER_INFO,
user_resp_len, user_resp);
if (ret != EOK) {
DEBUG(1, ("pack_response_packet failed.\n"));
talloc_zfree(user_error_message);
}
}
}
if (user_error_message == NULL) {
krb5_msg = sss_krb5_get_error_message(krb5_error_ctx, kerr);
if (krb5_msg == NULL) {
DEBUG(1, ("sss_krb5_get_error_message failed.\n"));
return NULL;
}
ret = pack_response_packet(resp, pam_status, SSS_PAM_SYSTEM_INFO,
strlen(krb5_msg) + 1,
(const uint8_t *) krb5_msg);
sss_krb5_free_error_message(krb5_error_ctx, krb5_msg);
} else {
krb5_msg = sss_krb5_get_error_message(krb5_error_ctx, kerr);
if (krb5_msg == NULL) {
DEBUG(1, ("sss_krb5_get_error_message failed.\n"));
return NULL; }
ret = pam_add_response(kr->pd, SSS_PAM_SYSTEM_INFO,
strlen(krb5_msg) + 1,
(const uint8_t *) krb5_msg);
sss_krb5_free_error_message(krb5_error_ctx, krb5_msg);
}
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
ret = pack_response_packet(resp, pam_status, kr->pd); if (ret != EOK) { DEBUG(1, ("pack_response_packet failed.\n")); return NULL;
@@ -350,15 +387,14 @@ static struct response *prepare_response_message(struct krb5_req *kr, return resp; }
-static errno_t sendresponse(int fd, krb5_error_code kerr,
char *user_error_message, int pam_status,
+static errno_t sendresponse(int fd, krb5_error_code kerr, int pam_status, struct krb5_req *kr) { struct response *resp; size_t written; int ret;
- resp = prepare_response_message(kr, kerr, user_error_message, pam_status);
- resp = prepare_response_message(kr, kerr, pam_status); if (resp == NULL) { DEBUG(1, ("prepare_response_message failed.\n")); return ENOMEM;
@@ -481,8 +517,8 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr, int ret;
kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
password, NULL, NULL, 0, NULL,
kr->options);
password, sss_krb5_prompter, kr, 0,
if (kerr != 0) { KRB5_DEBUG(1, kerr); return kerr;NULL, kr->options);
@@ -533,6 +569,9 @@ static errno_t changepw_child(int fd, struct krb5_req *kr) krb5_data result_code_string; krb5_data result_string; char *user_error_message = NULL;
size_t user_resp_len;
uint8_t *user_resp;
krb5_prompter_fct prompter = sss_krb5_prompter;
pass_str = talloc_strndup(kr, (const char *) kr->pd->authtok, kr->pd->authtok_size);
@@ -542,8 +581,13 @@ static errno_t changepw_child(int fd, struct krb5_req *kr) goto sendresponse; }
- if (kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
/* We do not need a password expiration warning here. */
prompter = NULL;
- }
- kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
pass_str, NULL, NULL, 0,
if (kerr != 0) {pass_str, prompter, kr, 0, kr->krb5_ctx->changepw_principle, kr->options);
@@ -612,6 +656,20 @@ static errno_t changepw_child(int fd, struct krb5_req *kr) } }
if (user_error_message != NULL) {
ret = pack_user_info_chpass_error(kr->pd, user_error_message,
&user_resp_len, &user_resp);
if (ret != EOK) {
DEBUG(1, ("pack_user_info_chpass_error failed.\n"));
} else {
ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, user_resp_len,
user_resp);
if (ret != EOK) {
DEBUG(1, ("pack_response_packet failed.\n"));
}
}
}
}pam_status = PAM_AUTHTOK_ERR; goto sendresponse;
@@ -631,7 +689,7 @@ static errno_t changepw_child(int fd, struct krb5_req *kr) }
sendresponse:
- ret = sendresponse(fd, kerr, user_error_message, pam_status, kr);
- ret = sendresponse(fd, kerr, pam_status, kr); if (ret != EOK) { DEBUG(1, ("sendresponse failed.\n")); }
@@ -662,7 +720,7 @@ static errno_t tgt_req_child(int fd, struct krb5_req *kr) So we validate the password by trying to get a changepw ticket. */ if (kerr == KRB5KDC_ERR_KEY_EXP) { kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
pass_str, NULL, NULL, 0,
pass_str, sss_krb5_prompter, kr, 0, kr->krb5_ctx->changepw_principle, kr->options); krb5_free_cred_contents(kr->ctx, kr->creds);
@@ -693,7 +751,7 @@ static errno_t tgt_req_child(int fd, struct krb5_req *kr) }
sendresponse:
- ret = sendresponse(fd, kerr, NULL, pam_status, kr);
- ret = sendresponse(fd, kerr, pam_status, kr); if (ret != EOK) { DEBUG(1, ("sendresponse failed.\n")); }
@@ -712,7 +770,7 @@ static errno_t create_empty_ccache(int fd, struct krb5_req *kr) pam_status = PAM_SYSTEM_ERR; }
- ret = sendresponse(fd, ret, NULL, pam_status, kr);
- ret = sendresponse(fd, ret, pam_status, kr); if (ret != EOK) { DEBUG(1, ("sendresponse failed.\n")); }
@@ -878,6 +936,15 @@ static int krb5_setup(struct krb5_req *kr, uint32_t offline) goto failed; }
- /* A prompter is used to catch messages about when a password will
* expired. The library shall not use the prompter to ask for a new password
* but shall return KRB5KDC_ERR_KEY_EXP. */
- krb5_get_init_creds_opt_set_change_password_prompt(kr->options, 0);
- if (kerr != 0) {
KRB5_DEBUG(1, kerr);
goto failed;
- }
/* TODO: set options, e.g.
- krb5_get_init_creds_opt_set_tkt_life
- krb5_get_init_creds_opt_set_renew_life
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c index 8bd3c9e..d4e09da 100644 --- a/src/sss_client/pam_sss.c +++ b/src/sss_client/pam_sss.c @@ -888,7 +888,7 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf, switch(type) { case SSS_PAM_SYSTEM_INFO: if (buf[p + (len -1)] != '\0') {
D(("user info does not end with \\0."));
D(("system info does not end with \\0.")); break; } logger(pamh, LOG_INFO, "system info: [%s]", &buf[p]);
@@ -940,6 +940,18 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf, D(("eval_user_info_response failed")); } break;
case SSS_PAM_TEXT_MSG:
if (buf[p + (len -1)] != '\0') {
D(("system info does not end with \\0."));
break;
}
ret = do_pam_conversation(pamh, PAM_TEXT_INFO, (char *) &buf[p],
NULL, NULL);
if (ret != PAM_SUCCESS) {
D(("do_pam_conversation failed."));
}
break; default: D(("Unknown response type [%d]", type)); }
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h index f7e58fe..8712a6f 100644 --- a/src/sss_client/sss_cli.h +++ b/src/sss_client/sss_cli.h @@ -316,9 +316,13 @@ enum response_type { * @param String, zero terminated, of the form * name=value. See putenv(3) and pam_putenv(3) for * details. */
- SSS_PAM_USER_INFO /**< A message which should be displayed to the user.
- SSS_PAM_USER_INFO, /**< A message which should be displayed to the user. * @param User info message, see #user_info_type * for details. */
- SSS_PAM_TEXT_MSG, /**< A plain text message which should be displayed to
* the user.This should only be used in the case where
* it is not possile to use SSS_PAM_USER_INFO.
* @param A zero terminated string. */
};
/**
1.6.6.1
sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel
On 05/03/2010 04:44 PM, Sumit Bose wrote:
On Mon, May 03, 2010 at 10:39:57PM +0200, Sumit Bose wrote:
On Mon, May 03, 2010 at 02:29:39PM -0400, Stephen Gallagher wrote:
On 04/30/2010 12:10 PM, Sumit Bose wrote:
On Fri, Apr 30, 2010 at 10:18:39AM -0400, Stephen Gallagher wrote:
On 04/29/2010 07:27 AM, Sumit Bose wrote:
Sorry, the first patch had dependencies to another patch, new version attached.
bye, Sumit On Tue, Apr 27, 2010 at 02:08:02PM +0200, Sumit Bose wrote: > Hi, > > this two patches add the support to display a warning to the user that > the Kerberos password is about to expire. The first patch just moves > some utility functions to a separate file to avoid linking the > krb5_child against libdbus. > > I the second patch a prompter function is introduced to catch the > warning message which is generated by libkrb5. With the current API of > MIT Kerberos we have to rely on this message, because the the underlying > AS_REPLY data is not exposed by the library. As a consequece this message > cannot be translated, but this is true for messages which are generated > to indicate why a password change failed, too. The rest of the patch > changes the way the response from the child is packed and unpacked to > allow more than one response message. > > bye, > Sumit
Patch 0001: Ack
Patch 0002: The krb5_child_done() function is in desperate need of comments. At minimum, there needs to be a comment describing the format of the received buffer. Same for the pack_response_packet().
comments added
This is wrong: if (msg_len> pref_len&& strncmp((const char *)&buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
pref_len needs to be another byte longer to account for the '='. Also, a comment here would be fantastic.
pref_len is already a bye longer, because I used sizeof instead of strlen. I added a comment about this, too.
New version attached.
Sumit, these patches don't apply cleanly on sssd-1-2 at present. Would you please rebase them and resend?
sure, rebased version attached.
ah, sorry, I have attached a broken version, this one should work.
bye, Sumit
../../src/providers/krb5/krb5_auth.c: In function ‘krb5_save_ccname_done’: ../../src/providers/krb5/krb5_auth.c:1285: warning: unused variable ‘krb5_ctx’
Otherwise, ack. I can fix this before I push.
On Tue, May 04, 2010 at 03:16:12PM -0400, Stephen Gallagher wrote:
On 05/03/2010 04:44 PM, Sumit Bose wrote:
On Mon, May 03, 2010 at 10:39:57PM +0200, Sumit Bose wrote:
On Mon, May 03, 2010 at 02:29:39PM -0400, Stephen Gallagher wrote:
On 04/30/2010 12:10 PM, Sumit Bose wrote:
On Fri, Apr 30, 2010 at 10:18:39AM -0400, Stephen Gallagher wrote:
On 04/29/2010 07:27 AM, Sumit Bose wrote: > Sorry, the first patch had dependencies to another patch, new version > attached. > > bye, > Sumit > On Tue, Apr 27, 2010 at 02:08:02PM +0200, Sumit Bose wrote: >> Hi, >> >> this two patches add the support to display a warning to the user that >> the Kerberos password is about to expire. The first patch just moves >> some utility functions to a separate file to avoid linking the >> krb5_child against libdbus. >> >> I the second patch a prompter function is introduced to catch the >> warning message which is generated by libkrb5. With the current API of >> MIT Kerberos we have to rely on this message, because the the underlying >> AS_REPLY data is not exposed by the library. As a consequece this message >> cannot be translated, but this is true for messages which are generated >> to indicate why a password change failed, too. The rest of the patch >> changes the way the response from the child is packed and unpacked to >> allow more than one response message. >> >> bye, >> Sumit >
Patch 0001: Ack
Patch 0002: The krb5_child_done() function is in desperate need of comments. At minimum, there needs to be a comment describing the format of the received buffer. Same for the pack_response_packet().
comments added
This is wrong: if (msg_len> pref_len&& strncmp((const char *)&buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
pref_len needs to be another byte longer to account for the '='. Also, a comment here would be fantastic.
pref_len is already a bye longer, because I used sizeof instead of strlen. I added a comment about this, too.
New version attached.
Sumit, these patches don't apply cleanly on sssd-1-2 at present. Would you please rebase them and resend?
sure, rebased version attached.
ah, sorry, I have attached a broken version, this one should work.
bye, Sumit
../../src/providers/krb5/krb5_auth.c: In function ‘krb5_save_ccname_done’: ../../src/providers/krb5/krb5_auth.c:1285: warning: unused variable ‘krb5_ctx’
Otherwise, ack. I can fix this before I push.
New version attached. Please note that there is also a rebased version of 'Add support for delayed kinit if offline' that works on to top this patch.
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/05/2010 04:59 AM, Sumit Bose wrote:
New version attached. Please note that there is also a rebased version of 'Add support for delayed kinit if offline' that works on to top this patch.
bye, Sumit
Ack.
On 05/05/2010 07:23 AM, Stephen Gallagher wrote:
On 05/05/2010 04:59 AM, Sumit Bose wrote:
New version attached. Please note that there is also a rebased version of 'Add support for delayed kinit if offline' that works on to top this patch.
bye, Sumit
Ack.
Patch 0001: Pushed to master and sssd-1-2. Patch 0002: Pushed to sssd-1-2.
sssd-devel@lists.fedorahosted.org