[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