[SSSD] [PATCH] Fix kinit after password change

Sumit Bose sbose at redhat.com
Tue Mar 23 14:36:43 UTC 2010


Hi,

this patch should fix #433 'Changing password with Kerberos succeeds,
but still returns an error message'

bye,
Sumit
-------------- next part --------------
From bcdb6851f7c01010c6c45cf81a816f6d0be96067 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 23 Mar 2010 15:26:33 +0100
Subject: [PATCH] Fix kinit after password change

In an environment with slave KDCs and a central server where password
changes are allowed the request for a new TGT immediately after the
password change should be made against this server, because the slave
server might not know the new password.
---
 src/krb5_plugin/sssd_krb5_locator_plugin.c |   28 +++++++++++++++++-----------
 src/providers/krb5/krb5_child.c            |   13 +++++++++++++
 src/providers/krb5/krb5_common.h           |    1 +
 3 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/src/krb5_plugin/sssd_krb5_locator_plugin.c b/src/krb5_plugin/sssd_krb5_locator_plugin.c
index 626960a..983b971 100644
--- a/src/krb5_plugin/sssd_krb5_locator_plugin.c
+++ b/src/krb5_plugin/sssd_krb5_locator_plugin.c
@@ -271,6 +271,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
     uint16_t port = 0;
     const char *addr = NULL;
     char port_str[PORT_STR_SIZE];
+    const char *use_kpasswd_as_kdc = NULL;
 
     if (private_data == NULL) return KRB5_PLUGIN_NO_HANDLE;
     ctx = (struct sssd_ctx *) private_data;
@@ -289,15 +290,13 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
             return KRB5_PLUGIN_NO_HANDLE;
         }
 
-        if (svc == locate_service_kadmin || svc == locate_service_kpasswd) {
-            ret = get_krb5info(realm, ctx, locate_service_kpasswd);
-            if (ret != EOK) {
-                PLUGIN_DEBUG(("reading kpasswd address failed, "
-                              "using kdc address.\n"));
-                free(ctx->kpasswd_addr);
-                ctx->kpasswd_addr = strdup(ctx->kdc_addr);
-                ctx->kpasswd_port = 0;
-            }
+        ret = get_krb5info(realm, ctx, locate_service_kpasswd);
+        if (ret != EOK) {
+            PLUGIN_DEBUG(("reading kpasswd address failed, "
+                          "using kdc address.\n"));
+            free(ctx->kpasswd_addr);
+            ctx->kpasswd_addr = strdup(ctx->kdc_addr);
+            ctx->kpasswd_port = 0;
         }
     }
 
@@ -305,11 +304,18 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
                   "locate_service[%d]\n", ctx->sssd_realm, realm, family,
                                           socktype, svc));
 
+    use_kpasswd_as_kdc = getenv(SSSD_KRB5_USE_KPASSWD_AS_KDC);
+
     switch (svc) {
         case locate_service_kdc:
         case locate_service_master_kdc:
-            addr = ctx->kdc_addr;
-            port = ctx->kdc_port ? ctx->kdc_port : DEFAULT_KERBEROS_PORT;
+            if (use_kpasswd_as_kdc == NULL) {
+                addr = ctx->kdc_addr;
+                port = ctx->kdc_port ? ctx->kdc_port : DEFAULT_KERBEROS_PORT;
+            } else {
+                addr = ctx->kpasswd_addr;
+                port = DEFAULT_KERBEROS_PORT;
+            }
             break;
         case locate_service_kadmin:
             addr = ctx->kpasswd_addr;
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 86242ef..a04083c 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -631,7 +631,15 @@ static errno_t changepw_child(int fd, struct krb5_req *kr)
 
     krb5_free_cred_contents(kr->ctx, kr->creds);
 
+    ret = setenv(SSSD_KRB5_USE_KPASSWD_AS_KDC, "1", 1);
+    if (ret != EOK) {
+        DEBUG(2, ("setenv %s failed.\n", SSSD_KRB5_USE_KPASSWD_AS_KDC));
+    }
     kerr = get_and_save_tgt(kr, newpass_str);
+    ret = unsetenv(SSSD_KRB5_USE_KPASSWD_AS_KDC);
+    if (ret != EOK) {
+        DEBUG(2, ("unsetenv %s failed.\n", SSSD_KRB5_USE_KPASSWD_AS_KDC));
+    }
     memset(newpass_str, 0, kr->pd->newauthtok_size);
     talloc_zfree(newpass_str);
     memset(kr->pd->newauthtok, 0, kr->pd->newauthtok_size);
@@ -1012,6 +1020,11 @@ int main(int argc, const char *argv[])
         goto fail;
     }
 
+    ret = unsetenv(SSSD_KRB5_USE_KPASSWD_AS_KDC);
+    if (ret != EOK) {
+        DEBUG(2, ("unsetenv %s failed.\n", SSSD_KRB5_USE_KPASSWD_AS_KDC));
+    }
+
     ret = kr->child_req(STDOUT_FILENO, kr);
     if (ret != EOK) {
         DEBUG(1, ("Child request failed.\n"));
diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
index 0b0da31..503c742 100644
--- a/src/providers/krb5/krb5_common.h
+++ b/src/providers/krb5/krb5_common.h
@@ -36,6 +36,7 @@
 #define SSSD_KRB5_KDC "SSSD_KRB5_KDC"
 #define SSSD_KRB5_REALM "SSSD_KRB5_REALM"
 #define SSSD_KRB5_CHANGEPW_PRINCIPLE "SSSD_KRB5_CHANGEPW_PRINCIPLE"
+#define SSSD_KRB5_USE_KPASSWD_AS_KDC "SSSD_KRB5_USE_KPASSWD_AS_KDC"
 
 #define KDCINFO_TMPL PUBCONF_PATH"/kdcinfo.%s"
 #define KPASSWDINFO_TMPL PUBCONF_PATH"/kpasswdinfo.%s"
-- 
1.6.6.1



More information about the sssd-devel mailing list