Hi,

currently the KDC must be restarted if a new trust is added to make the
KDC aware of the new domain. With the attached patch the data is
reloaded automatically if a request from an unknown domain was received.
It works for me, but I'm not completely sure if this is the best
approach to avoid the restart of the KDC.

Comments are welcome.

bye
Sumit
From 5014831c66fa73bb25715725498c457777e7d796 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Fri, 5 Oct 2012 12:06:24 +0200
Subject: [PATCH] ipadb: reload trust information if domain is not know

Currently the data about trusted domains is read once at startup. If a
new trust is added the KDC must be restarted to know about the new
trust. This patch reloads the trust data if there is a request from an
unknown domain. To make DOS attacks a bit harder the data can be updated
only once in a minute.
---
 daemons/ipa-kdb/ipa_kdb_mspac.c | 44 ++++++++++++++++++++++++++++++++---------
 1 Datei geändert, 35 Zeilen hinzugefügt(+), 9 Zeilen entfernt(-)

diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 
1a03323d137a2b89a08f5b12ca00752e4e190de7..cbf74cf0b2abdf814b4254d89565399b6eeced0f
 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -40,6 +40,7 @@ struct ipadb_mspac {
 
     int num_trusts;
     struct ipadb_adtrusts *trusts;
+    time_t last_update;
 };
 
 #ifdef DEBUG
@@ -967,6 +968,8 @@ static struct ipadb_adtrusts 
*get_domain_from_realm(krb5_context context,
     struct ipadb_context *ipactx;
     struct ipadb_adtrusts *domain;
     int i;
+    krb5_error_code kerr;
+    bool updated = false;
 
     ipactx = ipadb_get_context(context);
     if (!ipactx) {
@@ -977,17 +980,28 @@ static struct ipadb_adtrusts 
*get_domain_from_realm(krb5_context context,
         return NULL;
     }
 
-    for (i = 0; i < ipactx->mspac->num_trusts; i++) {
-        domain = &ipactx->mspac->trusts[i];
-        if (strlen(domain->domain_name) != realm.length) {
-            continue;
+    do {
+        for (i = 0; i < ipactx->mspac->num_trusts; i++) {
+            domain = &ipactx->mspac->trusts[i];
+            if (strlen(domain->domain_name) != realm.length) {
+                continue;
+            }
+            if (strncasecmp(domain->domain_name, realm.data,
+                            realm.length) == 0) {
+                return domain;
+            }
         }
-        if (strncasecmp(domain->domain_name, realm.data, realm.length) == 0) {
-            return domain;
-        }
-    }
 
-    return NULL;
+        if (updated) {
+            return NULL;
+        } else {
+            kerr = ipadb_reinit_mspac(ipactx);
+            if (kerr != 0) {
+                return NULL;
+            }
+            updated = true;
+        }
+    } while(1);
 }
 
 static krb5_error_code filter_logon_info(krb5_context context,
@@ -1534,6 +1548,16 @@ krb5_error_code ipadb_reinit_mspac(struct ipadb_context 
*ipactx)
     struct dom_sid gsid;
     char *resstr;
     int ret;
+    time_t now;
+
+    /* Do not update the mspac struct more than once a minute. This would
+     * avoid heavy load on the directory server if there are lots of requests
+     * from domains which we do not trust. */
+    now = time(NULL);
+    if (ipactx->mspac != NULL && now > ipactx->mspac->last_update &&
+        (now - ipactx->mspac->last_update) < 60) {
+        return 0;
+    }
 
     /* clean up in case we had old values around */
     ipadb_mspac_struct_free(&ipactx->mspac);
@@ -1544,6 +1568,8 @@ krb5_error_code ipadb_reinit_mspac(struct ipadb_context 
*ipactx)
         goto done;
     }
 
+    ipactx->mspac->last_update = now;
+
     kerr = ipadb_simple_search(ipactx, ipactx->base, LDAP_SCOPE_SUBTREE,
                                "(objectclass=ipaNTDomainAttrs)", dom_attrs,
                                 &result);
-- 
1.7.11.4

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to