summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2012-11-14 14:56:47 +0100
committerJakub Hrozek <jhrozek@redhat.com>2012-11-20 08:20:02 +0100
commitfe70898910c39851f0d5efa3c0a305f660f44662 (patch)
tree82490accff226f18f0ed45488d559a07d9f672a8
parentb7cb82d8d2b4c79071bb2d3e2e0c2086d4ae2ec2 (diff)
downloadsssd-fe70898910c39851f0d5efa3c0a305f660f44662.tar.gz
sssd-fe70898910c39851f0d5efa3c0a305f660f44662.tar.xz
sssd-fe70898910c39851f0d5efa3c0a305f660f44662.zip
Disable canonicalization during password changes
If canonicalization is enabled Active Directory KDCs return 'krbtgt/AD.DOMAIN' as service name instead of the expected 'kadmin/changepw' which causes a 'KDC reply did not match expectations' error. Additionally the forwardable and proxiable flags are disabled, the renewable lifetime is set to 0 and the lifetime of the ticket is set to 5 minutes as recommended in https://fedorahosted.org/sssd/ticket/1405 and also done by the kpasswd utility. Fixes: https://fedorahosted.org/sssd/ticket/1405 https://fedorahosted.org/sssd/ticket/1615
-rw-r--r--src/providers/krb5/krb5_child.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index ef46f36c4..e2125a453 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -101,6 +101,28 @@ struct krb5_req {
static krb5_context krb5_error_ctx;
#define KRB5_CHILD_DEBUG(level, error) KRB5_DEBUG(level, krb5_error_ctx, error)
+static krb5_error_code get_changepw_options(krb5_context ctx,
+ krb5_get_init_creds_opt **_options)
+{
+ krb5_get_init_creds_opt *options;
+ krb5_error_code kerr;
+
+ kerr = sss_krb5_get_init_creds_opt_alloc(ctx, &options);
+ if (kerr != 0) {
+ KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
+ return kerr;
+ }
+
+ sss_krb5_get_init_creds_opt_set_canonicalize(options, 0);
+ krb5_get_init_creds_opt_set_forwardable(options, 0);
+ krb5_get_init_creds_opt_set_proxiable(options, 0);
+ krb5_get_init_creds_opt_set_renew_life(options, 0);
+ krb5_get_init_creds_opt_set_tkt_life(options, 5*60);
+
+ *_options = options;
+
+ return 0;
+}
static errno_t sss_send_pac(krb5_authdata **pac_authdata)
{
@@ -1056,6 +1078,7 @@ static errno_t changepw_child(int fd, struct krb5_req *kr)
krb5_prompter_fct prompter = sss_krb5_prompter;
const char *realm_name;
int realm_length;
+ krb5_get_init_creds_opt *chagepw_options;
DEBUG(SSSDBG_TRACE_LIBS, ("Password change operation\n"));
@@ -1078,6 +1101,12 @@ static errno_t changepw_child(int fd, struct krb5_req *kr)
prompter = NULL;
}
+ kerr = get_changepw_options(kr->ctx, &chagepw_options);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_OP_FAILURE, ("get_changepw_options failed.\n"));
+ goto sendresponse;
+ }
+
sss_krb5_princ_realm(kr->ctx, kr->princ, &realm_name, &realm_length);
DEBUG(SSSDBG_TRACE_FUNC,
@@ -1085,7 +1114,8 @@ static errno_t changepw_child(int fd, struct krb5_req *kr)
kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
pass_str, prompter, kr, 0,
SSSD_KRB5_CHANGEPW_PRINCIPAL,
- kr->options);
+ chagepw_options);
+ sss_krb5_get_init_creds_opt_free(kr->ctx, chagepw_options);
if (kerr != 0) {
pam_status = kerr_handle_error(kerr);
goto sendresponse;
@@ -1192,6 +1222,7 @@ static errno_t tgt_req_child(int fd, struct krb5_req *kr)
krb5_error_code kerr = 0;
char *pass_str = NULL;
int pam_status = PAM_SYSTEM_ERR;
+ krb5_get_init_creds_opt *chagepw_options;
DEBUG(SSSDBG_TRACE_LIBS, ("Attempting to get a TGT\n"));
@@ -1225,10 +1256,20 @@ static errno_t tgt_req_child(int fd, struct krb5_req *kr)
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
DEBUG(1, ("Failed to unset expire callback, continue ...\n"));
}
+
+ kerr = get_changepw_options(kr->ctx, &chagepw_options);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_OP_FAILURE, ("get_changepw_options failed.\n"));
+ goto sendresponse;
+ }
+
kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
pass_str, sss_krb5_prompter, kr, 0,
SSSD_KRB5_CHANGEPW_PRINCIPAL,
- kr->options);
+ chagepw_options);
+
+ sss_krb5_get_init_creds_opt_free(kr->ctx, chagepw_options);
+
krb5_free_cred_contents(kr->ctx, kr->creds);
if (kerr == 0) {
kerr = KRB5KDC_ERR_KEY_EXP;