From 5f3b21e0821a63ad5fca3c2e576725539122d3c6 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Mon, 21 Feb 2011 11:29:37 -0500
Subject: [PATCH] Allow krb5_realm to override ipa_domain

It is possible to set up FreeIPA servers where the Kerberos realm
differs from the IPA domain name. We need to allow setting the
krb5_realm explicitly to handle this.
---
 src/providers/ipa/ipa_common.c |   43 +++++++++++++++++++++++++++++++--------
 src/providers/ipa/ipa_common.h |    3 +-
 src/providers/ipa/ipa_init.c   |    9 +-------
 3 files changed, 37 insertions(+), 18 deletions(-)

diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index c146735c71ff90160ba042864e96b496fa139969..b748289bc578e61e57f31a92cdec7a8832cf1e9d 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -589,13 +589,15 @@ static void ipa_resolve_callback(void *private_data, struct fo_server *server)
 }
 
 int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
-                     const char *servers, const char *domain,
+                     const char *servers,
+                     struct ipa_options *options,
                      struct ipa_service **_service)
 {
     TALLOC_CTX *tmp_ctx;
     struct ipa_service *service;
     char **list = NULL;
     char *realm;
+    const char *domain;
     int ret;
     int i;
 
@@ -639,15 +641,38 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
     }
     service->sdap->kinit_service_name = service->krb5_service->name;
 
-    realm = talloc_strdup(service, domain);
-    if (!realm) {
-        ret = ENOMEM;
-        goto done;
+    /* First check whether the realm has been manually specified */
+    realm = dp_opt_get_string(options->id->basic, SDAP_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]);
+        }
     }
-    for (i = 0; realm[i]; i++) {
-        realm[i] = toupper(realm[i]);
-    }
-    service->krb5_service->realm = realm;
 
     if (!servers) {
         servers = BE_SRV_IDENTIFIER;
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index ed67a2c7b994e731b7eb270c6d4db1ecc5e27934..85f22e8df7f5329b61d456039ae269050856426c 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -93,7 +93,8 @@ int ipa_get_auth_options(struct ipa_options *ipa_opts,
                          struct dp_option **_opts);
 
 int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
-                     const char *servers, const char *domain,
+                     const char *servers,
+                     struct ipa_options *options,
                      struct ipa_service **_service);
 
 #endif /* _IPA_COMMON_H_ */
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index 27e0a11feef1a76194616075d06a436bc4c14a02..8f7d4d61fec0fb27ad711d66c62fc93054a989bf 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -61,7 +61,6 @@ struct bet_ops ipa_access_ops = {
 int common_ipa_init(struct be_ctx *bectx)
 {
     const char *ipa_servers;
-    const char *ipa_domain;
     int ret;
 
     ret = ipa_get_options(bectx, bectx->cdb,
@@ -76,13 +75,7 @@ int common_ipa_init(struct be_ctx *bectx)
         DEBUG(1, ("Missing ipa_server option - using service discovery!\n"));
     }
 
-    ipa_domain = dp_opt_get_string(ipa_options->basic, IPA_DOMAIN);
-    if (!ipa_domain) {
-        DEBUG(0, ("Missing ipa_domain option!\n"));
-        return EINVAL;
-    }
-
-    ret = ipa_service_init(ipa_options, bectx, ipa_servers, ipa_domain,
+    ret = ipa_service_init(ipa_options, bectx, ipa_servers, ipa_options,
                            &ipa_options->service);
     if (ret != EOK) {
         DEBUG(0, ("Failed to init IPA failover service!\n"));
-- 
1.7.4

