[SSSD] [PATCH] use stored upn if available

Sumit Bose sbose at redhat.com
Mon Aug 24 13:21:45 UTC 2009


On Mon, Aug 24, 2009 at 11:19:01AM +0200, Sumit Bose wrote:
> On Sun, Aug 23, 2009 at 05:40:16PM -0400, Simo Sorce wrote:
> > On Fri, 2009-08-21 at 12:17 +0200, Sumit Bose wrote:
> > > Hi,
> > > 
> > > this is the last patch in the series to add the basic support for AD as
> > > a server. With this patch the kerberos backend will use the user
> > > principal name provided by the server to get the TGT. To make the client
> > > side kerberos libraries happy the realm part is always made upper case.
> > 
> > Unfortunately this patch has already been acked an committed, but I do
> > not agree with the way it has been implemented.
> > 
> > The upper case hack is an AD specific hack, and should *not* be
> > implemented in the kerberos backend.
> > Rather it should be implemented as an hack in the ldap driver.
> 
> ok, you are right, the current version would force the restriction of
> upper case only realm names, which might not always be what we want.
> 
> > 
> > Note that Windows servers are fine with the lower case because they do
> > some quite aggressive canonicalization at the server side.
> > Moreover the UPN can easily be != username+ at +upper(REALM), so the hack
> > should be activate only through an option, so that it can be disabled if
> > kerberos libraries become able to cope with the UPN as provided via LDAP
> > by AD.
> > 
> 
> ok, I'll provide a patch for both after 0.5.0 is released.
> 

ok, here is the patch

bye,
Sumit
-------------- next part --------------
>From 803fb55df74a84a1dc61918b1cf14fe4d76d4a4c Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Mon, 24 Aug 2009 15:17:37 +0200
Subject: [PATCH] some UPN handling fixes

- making the realm part upper case is now optional and done in the
  LDAP backend
- using a username at realm UPN is now optional
---
 server/man/sssd-krb5.5.xml         |   14 ++++++++++++++
 server/man/sssd-ldap.5.xml         |   16 ++++++++++++++++
 server/providers/krb5/krb5_auth.c  |   34 +++++++++++-----------------------
 server/providers/krb5/krb5_auth.h  |    1 +
 server/providers/ldap/sdap.c       |    3 ++-
 server/providers/ldap/sdap.h       |    3 ++-
 server/providers/ldap/sdap_async.c |   23 +++++++++++++++++++++++
 7 files changed, 69 insertions(+), 25 deletions(-)

diff --git a/server/man/sssd-krb5.5.xml b/server/man/sssd-krb5.5.xml
index d2b631a..3a22afc 100644
--- a/server/man/sssd-krb5.5.xml
+++ b/server/man/sssd-krb5.5.xml
@@ -62,6 +62,20 @@
                         </para>
                     </listitem>
                 </varlistentry>
+
+                <varlistentry>
+                    <term>krb5try_simple_upn (boolean)</term>
+                    <listitem>
+                        <para>
+                            Set this option to 'true'
+                            if an User Principle Name (UPN) cannot be found in sysdb
+                            and you want to use an UPN like 'username at realm'.
+                        </para>
+                        <para>
+                            Default: false
+                        </para>
+                    </listitem>
+                </varlistentry>
             </variablelist>
         </para>
     </refsect1>
diff --git a/server/man/sssd-ldap.5.xml b/server/man/sssd-ldap.5.xml
index 948b3e2..28ad3ee 100644
--- a/server/man/sssd-ldap.5.xml
+++ b/server/man/sssd-ldap.5.xml
@@ -219,6 +219,22 @@
                 </varlistentry>
 
                 <varlistentry>
+                    <term>force_upper_case_realm (string)</term>
+                    <listitem>
+                        <para>
+                            Some directory servers, for example Active Directory,
+                            might deliver the realm part of the UPN lower case
+                            which may cause the authentication to fail. Set this
+                            option to a non-zero value, if you want to use an
+                            upper case realm.
+                        </para>
+                        <para>
+                            Default: 0 
+                        </para>
+                    </listitem>
+                </varlistentry>
+
+                <varlistentry>
                     <term>userFullname (string)</term>
                     <listitem>
                         <para>
diff --git a/server/providers/krb5/krb5_auth.c b/server/providers/krb5/krb5_auth.c
index 45bbe4c..39bc170 100644
--- a/server/providers/krb5/krb5_auth.c
+++ b/server/providers/krb5/krb5_auth.c
@@ -31,7 +31,6 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <pwd.h>
-#include <ctype.h>
 
 #include <security/pam_modules.h>
 
@@ -41,25 +40,6 @@
 #include "krb5_plugin/sssd_krb5_locator_plugin.h"
 #include "providers/krb5/krb5_auth.h"
 
-#define REALM_SEPARATOR '@'
-
-static void make_realm_upper_case(const char *upn)
-{
-    char *c;
-
-    c = strchr(upn, REALM_SEPARATOR);
-    if (c == NULL) {
-        DEBUG(9, ("No realm delimiter found in upn [%s].\n", upn));
-        return;
-    }
-
-    while(*(++c) != '\0') {
-        c[0] = toupper(*c);
-    }
-
-    return;
-}
-
 static void fd_nonblocking(int fd) {
     int flags;
 
@@ -452,11 +432,15 @@ static void get_user_upn_done(void *pvt, int err, struct ldb_result *res)
 
     case 1:
         upn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_UPN, NULL);
-        if (upn == NULL) {
+        if (upn == NULL && krb5_ctx->try_simple_upn) {
             /* NOTE: this is a hack, works only in some environments */
             if (krb5_ctx->realm != NULL) {
                 upn = talloc_asprintf(be_req, "%s@%s", pd->user,
                                       krb5_ctx->realm);
+                if (upn == NULL) {
+                    DEBUG(1, ("failed to build simple upn.\n"));
+                }
+                DEBUG(9, ("Using simple UPN [%s].\n", upn));
             }
         }
         break;
@@ -472,8 +456,6 @@ static void get_user_upn_done(void *pvt, int err, struct ldb_result *res)
         goto failed;
     }
 
-    make_realm_upper_case(upn);
-
     ret = krb5_setup(be_req, upn, &kr);
     if (ret != EOK) {
         DEBUG(1, ("krb5_setup failed.\n"));
@@ -612,6 +594,7 @@ int sssm_krb5_auth_init(struct be_ctx *bectx, struct bet_ops **ops,
 {
     struct krb5_ctx *ctx = NULL;
     char *value = NULL;
+    bool bool_value;
     int ret;
     struct tevent_signal *sige;
 
@@ -651,6 +634,11 @@ int sssm_krb5_auth_init(struct be_ctx *bectx, struct bet_ops **ops,
     }
     ctx->realm = value;
 
+    ret = confdb_get_bool(bectx->cdb, ctx, bectx->conf_path,
+                          "krb5try_simple_upn", false, &bool_value);
+    if (ret != EOK) goto fail;
+    ctx->try_simple_upn = bool_value;
+
 /* TODO: set options */
 
     sige = tevent_add_signal(bectx->ev, ctx, SIGCHLD, SA_SIGINFO,
diff --git a/server/providers/krb5/krb5_auth.h b/server/providers/krb5/krb5_auth.h
index d1c5c7c..540f65f 100644
--- a/server/providers/krb5/krb5_auth.h
+++ b/server/providers/krb5/krb5_auth.h
@@ -61,6 +61,7 @@ struct krb5_ctx {
 
     char *kdcip;
     char *realm;
+    bool try_simple_upn;
 };
 
 struct krb5_req {
diff --git a/server/providers/ldap/sdap.c b/server/providers/ldap/sdap.c
index 0b16db4..e11e10a 100644
--- a/server/providers/ldap/sdap.c
+++ b/server/providers/ldap/sdap.c
@@ -40,7 +40,8 @@ struct sdap_gen_opts default_basic_opts[] = {
     { "groupSearchScope", "sub", NULL },
     { "groupSearchFilter", NULL, NULL },
     { "ldapSchema", "rfc2307", NULL },
-    { "offline_timeout", "5", NULL }
+    { "offline_timeout", "5", NULL },
+    { "force_upper_case_realm", "0", NULL }
 };
 
 struct sdap_id_map default_user_map[] = {
diff --git a/server/providers/ldap/sdap.h b/server/providers/ldap/sdap.h
index 5afbcfc..9c0dc1e 100644
--- a/server/providers/ldap/sdap.h
+++ b/server/providers/ldap/sdap.h
@@ -84,8 +84,9 @@ enum sdap_result {
 #define SDAP_GROUP_SEARCH_FILTER 12
 #define SDAP_SCHEMA 13
 #define SDAP_OFFLINE_TIMEOUT 14
+#define SDAP_FORCE_UPPER_CASE_REALM 15
 
-#define SDAP_OPTS_BASIC 15 /* opts counter */
+#define SDAP_OPTS_BASIC 16 /* opts counter */
 
 /* the objectclass must be the first attribute.
  * Functions depend on this */
diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
index 7c6cd2c..f3632ba 100644
--- a/server/providers/ldap/sdap_async.c
+++ b/server/providers/ldap/sdap_async.c
@@ -18,11 +18,31 @@
     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 <ctype.h>
 
 #include "db/sysdb.h"
 #include "providers/ldap/sdap_async.h"
 #include "util/util.h"
 
+#define REALM_SEPARATOR '@'
+
+static void make_realm_upper_case(const char *upn)
+{
+    char *c;
+
+    c = strchr(upn, REALM_SEPARATOR);
+    if (c == NULL) {
+        DEBUG(9, ("No realm delimiter found in upn [%s].\n", upn));
+        return;
+    }
+
+    while(*(++c) != '\0') {
+        c[0] = toupper(*c);
+    }
+
+    return;
+}
+
 /* ==LDAP-Memory-Handling================================================= */
 
 static int lmsg_destructor(void *mem)
@@ -952,6 +972,9 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
     if (el->num_values == 0) {
         DEBUG(7, ("User principle is not available for user [%s].\n", name));
     } else {
+        if (strcmp(opts->basic[SDAP_FORCE_UPPER_CASE_REALM].value,"0") != 0) {
+            make_realm_upper_case((const char*) el->values[0].data);
+        }
         DEBUG(7, ("Adding user principle [%s] to attributes of user [%s].\n",
                   el->values[0].data, name));
         ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN,
-- 
1.6.2.5



More information about the sssd-devel mailing list