From 9eac4bd18db06a4c27d8509709c528076d4328dc Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Wed, 23 Feb 2011 17:40:44 +0100
Subject: [PATCH] Use realm for basedn instead of IPA domain

https://fedorahosted.org/sssd/ticket/807
---
 src/man/sssd-ipa.5.xml         |   15 ++++++++
 src/providers/ipa/ipa_access.c |    2 +-
 src/providers/ipa/ipa_auth.c   |   12 +++---
 src/providers/ipa/ipa_common.c |   78 +++++++++++++++++++---------------------
 src/providers/ipa/ipa_utils.c  |    6 +++
 src/tests/ipa_ldap_opt-tests.c |    1 +
 6 files changed, 66 insertions(+), 48 deletions(-)

diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml
index 606581d..4604c55 100644
--- a/src/man/sssd-ipa.5.xml
+++ b/src/man/sssd-ipa.5.xml
@@ -161,6 +161,21 @@
                     </listitem>
                 </varlistentry>
 
+                <varlistentry>
+                    <term>krb5_realm (string)</term>
+                    <listitem>
+                        <para>
+                            The name of the Kerberos realm. This is optional and
+                            defaults to the value of <quote>ipa_domain</quote>.
+                        </para>
+                        <para>
+                            The name of the Kerberos realm has a special
+                            meaning in IPA - it is converted into the base
+                            DN to use for performing LDAP operations.
+                        </para>
+                    </listitem>
+                </varlistentry>
+
             </variablelist>
         </para>
     </refsect1>
diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c
index 02b0a77..f07eb7b 100644
--- a/src/providers/ipa/ipa_access.c
+++ b/src/providers/ipa/ipa_access.c
@@ -74,7 +74,7 @@ static char *get_hbac_search_base(TALLOC_CTX *mem_ctx,
     DEBUG(9, ("ipa_hbac_search_base not available, trying base DN.\n"));
 
     ret = domain_to_basedn(mem_ctx,
-                           dp_opt_get_string(ipa_options, IPA_DOMAIN),
+                           dp_opt_get_string(ipa_options, IPA_KRB5_REALM),
                            &base);
     if (ret != EOK) {
         DEBUG(1, ("domain_to_basedn failed.\n"));
diff --git a/src/providers/ipa/ipa_auth.c b/src/providers/ipa/ipa_auth.c
index eb7f291..d8d8ad5 100644
--- a/src/providers/ipa/ipa_auth.c
+++ b/src/providers/ipa/ipa_auth.c
@@ -46,7 +46,7 @@ struct get_password_migration_flag_state {
     struct sdap_handle *sh;
     enum sdap_result result;
     struct fo_server *srv;
-    char *ipa_domain;
+    char *ipa_realm;
     bool password_migration;
 };
 
@@ -56,13 +56,13 @@ static void get_password_migration_flag_done(struct tevent_req *subreq);
 static struct tevent_req *get_password_migration_flag_send(TALLOC_CTX *memctx,
                                             struct tevent_context *ev,
                                             struct sdap_auth_ctx *sdap_auth_ctx,
-                                            char *ipa_domain)
+                                            char *ipa_realm)
 {
     int ret;
     struct tevent_req *req, *subreq;
     struct get_password_migration_flag_state *state;
 
-    if (sdap_auth_ctx == NULL || ipa_domain == NULL) {
+    if (sdap_auth_ctx == NULL || ipa_realm == NULL) {
         DEBUG(1, ("Missing parameter.\n"));
         return NULL;
     }
@@ -80,7 +80,7 @@ static struct tevent_req *get_password_migration_flag_send(TALLOC_CTX *memctx,
     state->result = SDAP_ERROR;
     state->srv = NULL;
     state->password_migration = false;
-    state->ipa_domain = ipa_domain;
+    state->ipa_realm = ipa_realm;
 
     /* We request to use StartTLS here, because if password migration is
      * enabled we will use this connection for authentication, too. */
@@ -126,7 +126,7 @@ static void get_password_migration_flag_auth_done(struct tevent_req *subreq)
         return;
     }
 
-    ret = domain_to_basedn(state, state->ipa_domain, &ldap_basedn);
+    ret = domain_to_basedn(state, state->ipa_realm, &ldap_basedn);
     if (ret != EOK) {
         DEBUG(1, ("domain_to_basedn failed.\n"));
         tevent_req_error(req, ret);
@@ -311,7 +311,7 @@ static void ipa_auth_handler_done(struct tevent_req *req)
                                              state->ipa_auth_ctx->sdap_auth_ctx,
                                              dp_opt_get_string(
                                                state->ipa_auth_ctx->ipa_options,
-                                               IPA_DOMAIN));
+                                               IPA_KRB5_REALM));
         if (req == NULL) {
             DEBUG(1, ("get_password_migration_flag failed.\n"));
             goto done;
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index 397e418..579b8b6 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -175,8 +175,10 @@ int ipa_get_options(TALLOC_CTX *memctx,
     struct ipa_options *opts;
     char *domain;
     char *server;
+    char *realm;
     char *ipa_hostname;
     int ret;
+    int i;
     char hostname[HOST_NAME_MAX + 1];
 
     opts = talloc_zero(memctx, struct ipa_options);
@@ -196,6 +198,7 @@ int ipa_get_options(TALLOC_CTX *memctx,
         if (ret != EOK) {
             goto done;
         }
+        domain = dom->name;
     }
 
     server = dp_opt_get_string(opts->basic, IPA_SERVER);
@@ -220,6 +223,27 @@ int ipa_get_options(TALLOC_CTX *memctx,
         }
     }
 
+    /* First check whether the realm has been manually specified */
+    realm = dp_opt_get_string(opts->basic, IPA_KRB5_REALM);
+    if (!realm) {
+        /* No explicit krb5_realm, use the IPA domain */
+        realm = talloc_strdup(opts, domain);
+        if (!realm) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        /* Use the upper-case IPA domain for the kerberos realm */
+        for (i = 0; realm[i]; i++) {
+            realm[i] = toupper(realm[i]);
+        }
+
+        ret = dp_opt_set_string(opts->basic, IPA_KRB5_REALM,
+                                realm);
+        if (ret != EOK) {
+            goto done;
+        }
+    }
 
     ret = EOK;
     *_opts = opts;
@@ -273,7 +297,7 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
     }
 
     ret = domain_to_basedn(tmpctx,
-                           dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN),
+                           dp_opt_get_string(ipa_opts->basic, IPA_KRB5_REALM),
                            &basedn);
     if (ret != EOK) {
         goto done;
@@ -319,16 +343,13 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
 
     /* set krb realm */
     if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_KRB5_REALM)) {
-        realm = dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN);
+        realm = dp_opt_get_string(ipa_opts->basic, IPA_KRB5_REALM);
         value = talloc_strdup(tmpctx, realm);
         if (value == NULL) {
             DEBUG(1, ("talloc_strdup failed.\n"));
             ret = ENOMEM;
             goto done;
         }
-        for (i = 0; value[i]; i++) {
-            value[i] = toupper(value[i]);
-        }
         ret = dp_opt_set_string(ipa_opts->id->basic,
                                 SDAP_KRB5_REALM, value);
         if (ret != EOK) {
@@ -467,7 +488,6 @@ int ipa_get_auth_options(struct ipa_options *ipa_opts,
     char *value;
     char *copy = NULL;
     int ret;
-    int i;
 
     /* self check test, this should never fail, unless someone forgot
      * to properly update the code after new ldap options have been added */
@@ -501,7 +521,7 @@ int ipa_get_auth_options(struct ipa_options *ipa_opts,
 
     /* set krb realm */
     if (NULL == dp_opt_get_string(ipa_opts->auth, KRB5_REALM)) {
-        value = dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN);
+        value = dp_opt_get_string(ipa_opts->basic, IPA_KRB5_REALM);
         if (!value) {
             ret = ENOMEM;
             goto done;
@@ -512,9 +532,6 @@ int ipa_get_auth_options(struct ipa_options *ipa_opts,
             ret = ENOMEM;
             goto done;
         }
-        for (i = 0; copy[i]; i++) {
-            copy[i] = toupper(copy[i]);
-        }
         ret = dp_opt_set_string(ipa_opts->auth, KRB5_REALM, copy);
         if (ret != EOK) {
             goto done;
@@ -598,7 +615,6 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
     struct ipa_service *service;
     char **list = NULL;
     char *realm;
-    const char *domain;
     int ret;
     int i;
 
@@ -642,37 +658,17 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
     }
     service->sdap->kinit_service_name = service->krb5_service->name;
 
-    /* First check whether the realm has been manually specified */
     realm = dp_opt_get_string(options->basic, IPA_KRB5_REALM);
-    if (realm) {
-        /* krb5_realm exists in the configuration, use it */
-        service->krb5_service->realm =
-                talloc_strdup(service->krb5_service, realm);
-        if (!service->krb5_service->realm) {
-            ret = ENOMEM;
-            goto done;
-        }
-    } else {
-        /* No explicit krb5_realm, use the IPA domain */
-        domain = dp_opt_get_string(options->basic, IPA_DOMAIN);
-        if (!domain) {
-            DEBUG(0, ("Missing ipa_domain option!\n"));
-            ret = EINVAL;
-            goto done;
-        }
-
-        service->krb5_service->realm =
-                talloc_strdup(service->krb5_service, domain);
-        if (!service->krb5_service->realm) {
-            ret = ENOMEM;
-            goto done;
-        }
-
-        /* Use the upper-case IPA domain for the kerberos realm */
-        for (i = 0; service->krb5_service->realm[i]; i++) {
-            service->krb5_service->realm[i] =
-                    toupper(service->krb5_service->realm[i]);
-        }
+    if (!realm) {
+        DEBUG(1, ("No Kerberos realm set\n"));
+        ret = EINVAL;
+        goto done;
+    }
+    service->krb5_service->realm =
+        talloc_strdup(service->krb5_service, realm);
+    if (!service->krb5_service->realm) {
+        ret = ENOMEM;
+        goto done;
     }
 
     if (!servers) {
diff --git a/src/providers/ipa/ipa_utils.c b/src/providers/ipa/ipa_utils.c
index 504a877..a1e48f2 100644
--- a/src/providers/ipa/ipa_utils.c
+++ b/src/providers/ipa/ipa_utils.c
@@ -23,6 +23,8 @@
 */
 
 
+#include <ctype.h>
+
 #include "providers/ipa/ipa_common.h"
 
 int domain_to_basedn(TALLOC_CTX *memctx, const char *domain, char **basedn)
@@ -52,6 +54,10 @@ int domain_to_basedn(TALLOC_CTX *memctx, const char *domain, char **basedn)
         return ENOMEM;
     }
 
+    for (p=dn; *p; ++p) {
+        *p = tolower(*p);
+    }
+
     *basedn = dn;
     return EOK;
 }
diff --git a/src/tests/ipa_ldap_opt-tests.c b/src/tests/ipa_ldap_opt-tests.c
index f0c0d40..574aa09 100644
--- a/src/tests/ipa_ldap_opt-tests.c
+++ b/src/tests/ipa_ldap_opt-tests.c
@@ -39,6 +39,7 @@ struct test_domain {
 struct test_domain test_domains[] = {
     { "abc", "dc=abc"},
     { "a.b.c", "dc=a,dc=b,dc=c"},
+    { "A.B.C", "dc=a,dc=b,dc=c"},
     { NULL, NULL}
 };
 
-- 
1.7.4

