Rename hdb_ldb to hdb_samba4 and load as a plugin into the kdc.
authorAndrew Bartlett <abartlet@samba.org>
Wed, 24 Sep 2008 19:53:10 +0000 (12:53 -0700)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 30 Sep 2008 05:34:35 +0000 (22:34 -0700)
This avoids one more custom patch to the Heimdal code, and provides a
more standard way to produce hdb plugins in future.

I've renamed from hdb_ldb to hdb_samba4 as it really is not generic
ldb.

Andrew Bartlett

source4/heimdal/lib/hdb/hdb.c
source4/heimdal/lib/hdb/hdb.h
source4/kdc/config.mk
source4/kdc/hdb-samba4.c [moved from source4/kdc/hdb-ldb.c with 96% similarity]
source4/kdc/kdc.c

index 3fddabb2d08dad3d3bd715b4ee1f5d871bcb87ca..19c170767dfab78e99ad80697985c892b4fab9ef 100644 (file)
  * SUCH DAMAGE. 
  */
 
+#include "krb5.h"
+#include "krb5_locl.h"
 #include "hdb_locl.h"
-
 RCSID("$Id$");
 
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
 
-struct hdb_method {
-    const char *prefix;
-    krb5_error_code (*create)(krb5_context, HDB **, const char *filename);
-};
-
 static struct hdb_method methods[] = {
 #if HAVE_DB1 || HAVE_DB3
-    {"db:",    hdb_db_create},
+    {HDB_INTERFACE_VERSION, "db:",     hdb_db_create},
 #endif
 #if HAVE_NDBM
-    {"ndbm:",  hdb_ndbm_create},
+    {HDB_INTERFACE_VERSION, "ndbm:",   hdb_ndbm_create},
 #endif
 #if defined(OPENLDAP) && !defined(OPENLDAP_MODULE)
-    {"ldap:",  hdb_ldap_create},
-    {"ldapi:", hdb_ldapi_create},
-#endif
-#ifdef HAVE_LDB /* Used for integrated samba build */
-    {"ldb:",   hdb_ldb_create},
+    {HDB_INTERFACE_VERSION, "ldap:",   hdb_ldap_create},
+    {HDB_INTERFACE_VERSION, "ldapi:",  hdb_ldapi_create},
 #endif
-    {NULL,     NULL}
+    {0, NULL,  NULL}
 };
 
 #if HAVE_DB1 || HAVE_DB3
@@ -398,11 +391,32 @@ hdb_create(krb5_context context, HDB **db, const char *filename)
 {
     const struct hdb_method *h;
     const char *residual;
+    krb5_error_code ret;
+    struct krb5_plugin *list = NULL, *e;
 
     if(filename == NULL)
        filename = HDB_DEFAULT_DB;
     krb5_add_et_list(context, initialize_hdb_error_table_r);
     h = find_method (filename, &residual);
+
+    if (h == NULL) {
+           ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, "hdb", &list);
+           if(ret == 0 && list != NULL) {
+                   for (e = list; e != NULL; e = _krb5_plugin_get_next(e)) {
+                           h = _krb5_plugin_get_symbol(e);
+                           if (strncmp (filename, h->prefix, strlen(h->prefix)) == 0
+                               && h->interface_version == HDB_INTERFACE_VERSION) {
+                                   residual = filename + strlen(h->prefix);
+                                   break;
+                           }
+                   }
+                   if (e == NULL) {
+                           h = NULL;
+                           _krb5_plugin_free(list);
+                   }
+           }
+    }
+
 #ifdef HAVE_DLOPEN
     if (h == NULL)
        h = find_dynamic_method (context, filename, &residual);
index bc1b744015cbb5776b6a1a5a9203c59d7136404b..5c2097ea59c436e4b53a1ad1f688bd85533e565e 100644 (file)
@@ -139,6 +139,12 @@ typedef krb5_error_code (*hdb_foreach_func_t)(krb5_context, HDB*,
                                              hdb_entry_ex*, void*);
 extern krb5_kt_ops hdb_kt_ops;
 
+struct hdb_method {
+    int        interface_version;
+    const char *prefix;
+    krb5_error_code (*create)(krb5_context, HDB **, const char *filename);
+};
+
 #include <hdb-protos.h>
 
 #endif /* __HDB_H__ */
index b3e5bfdb92f102b1fd4a5348eb06adb477de7956..dfd2879bd600b61dc79d4e0aa979b72d562d0046 100644 (file)
@@ -6,7 +6,7 @@
 INIT_FUNCTION = server_service_kdc_init
 SUBSYSTEM = samba
 PRIVATE_DEPENDENCIES = \
-               HEIMDAL_KDC HDB_LDB
+               HEIMDAL_KDC HDB_SAMBA4
 # End SUBSYSTEM KDC
 #######################
 
@@ -14,7 +14,7 @@ KDC_OBJ_FILES = $(addprefix $(kdcsrcdir)/, kdc.o kpasswdd.o)
 
 #######################
 # Start SUBSYSTEM KDC
-[SUBSYSTEM::HDB_LDB]
+[SUBSYSTEM::HDB_SAMBA4]
 CFLAGS = -Iheimdal/kdc -Iheimdal/lib/hdb
 PRIVATE_DEPENDENCIES = \
                LIBLDB auth_sam auth_sam_reply CREDENTIALS \
@@ -22,5 +22,5 @@ PRIVATE_DEPENDENCIES = \
 # End SUBSYSTEM KDC
 #######################
 
-HDB_LDB_OBJ_FILES = $(addprefix $(kdcsrcdir)/, hdb-ldb.o pac-glue.o)
-$(eval $(call proto_header_template,$(kdcsrcdir)/pac_glue.h,$(HDB_LDB_OBJ_FILES:.o=.c)))
+HDB_SAMBA4_OBJ_FILES = $(addprefix $(kdcsrcdir)/, hdb-samba4.o pac-glue.o)
+$(eval $(call proto_header_template,$(kdcsrcdir)/pac_glue.h,$(HDB_SAMBA4_OBJ_FILES:.o=.c)))
similarity index 96%
rename from source4/kdc/hdb-ldb.c
rename to source4/kdc/hdb-samba4.c
index 4fde75cf707ca6775cc258af8db78611c52761a1..d7317f17d4f3f49ecd641482ca3140eaf431e9c0 100644 (file)
@@ -53,8 +53,8 @@
 #include "../lib/crypto/md4.h"
 
 enum hdb_ldb_ent_type 
-{ HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER, 
-  HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_TRUST, HDB_LDB_ENT_TYPE_ANY };
+{ HDB_SAMBA4_ENT_TYPE_CLIENT, HDB_SAMBA4_ENT_TYPE_SERVER, 
+  HDB_SAMBA4_ENT_TYPE_KRBTGT, HDB_SAMBA4_ENT_TYPE_TRUST, HDB_SAMBA4_ENT_TYPE_ANY };
 
 enum trust_direction {
        UNKNOWN = 0,
@@ -115,26 +115,26 @@ static HDBFlags uf2HDBFlags(krb5_context context, int userAccountControl, enum h
 
        /* Account types - clear the invalid bit if it turns out to be valid */
        if (userAccountControl & UF_NORMAL_ACCOUNT) {
-               if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) {
+               if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) {
                        flags.client = 1;
                }
                flags.invalid = 0;
        }
        
        if (userAccountControl & UF_INTERDOMAIN_TRUST_ACCOUNT) {
-               if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) {
+               if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) {
                        flags.client = 1;
                }
                flags.invalid = 0;
        }
        if (userAccountControl & UF_WORKSTATION_TRUST_ACCOUNT) {
-               if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) {
+               if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) {
                        flags.client = 1;
                }
                flags.invalid = 0;
        }
        if (userAccountControl & UF_SERVER_TRUST_ACCOUNT) {
-               if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) {
+               if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) {
                        flags.client = 1;
                }
                flags.invalid = 0;
@@ -551,7 +551,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
 
        
        entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal)));
-       if (ent_type == HDB_LDB_ENT_TYPE_ANY && principal == NULL) {
+       if (ent_type == HDB_SAMBA4_ENT_TYPE_ANY && principal == NULL) {
                const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
                if (!samAccountName) {
                        krb5_set_error_string(context, "LDB_message2entry: no samAccountName present");
@@ -587,7 +587,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
 
        entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type);
 
-       if (ent_type == HDB_LDB_ENT_TYPE_KRBTGT) {
+       if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT) {
                entry_ex->entry.flags.invalid = 0;
                entry_ex->entry.flags.server = 1;
                entry_ex->entry.flags.forwardable = 1;
@@ -631,7 +631,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
                *entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry);
        }
 
-       if (ent_type != HDB_LDB_ENT_TYPE_KRBTGT) {
+       if (ent_type != HDB_SAMBA4_ENT_TYPE_KRBTGT) {
                NTTIME must_change_time
                        = samdb_result_force_password_change((struct ldb_context *)db->hdb_db, mem_ctx, 
                                                             domain_dn, msg);
@@ -909,16 +909,16 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con
        }
 
        switch (ent_type) {
-       case HDB_LDB_ENT_TYPE_CLIENT:
-       case HDB_LDB_ENT_TYPE_TRUST:
-       case HDB_LDB_ENT_TYPE_ANY:
+       case HDB_SAMBA4_ENT_TYPE_CLIENT:
+       case HDB_SAMBA4_ENT_TYPE_TRUST:
+       case HDB_SAMBA4_ENT_TYPE_ANY:
                /* Can't happen */
                return EINVAL;
-       case HDB_LDB_ENT_TYPE_KRBTGT:
+       case HDB_SAMBA4_ENT_TYPE_KRBTGT:
                filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))", 
                                         KRB5_TGS_NAME);
                break;
-       case HDB_LDB_ENT_TYPE_SERVER:
+       case HDB_SAMBA4_ENT_TYPE_SERVER:
                filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))", 
                                         short_princ_talloc);
                break;
@@ -1075,7 +1075,7 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
        }
        
        ret = LDB_message2entry(context, db, mem_ctx, 
-                               principal, HDB_LDB_ENT_TYPE_CLIENT,
+                               principal, HDB_SAMBA4_ENT_TYPE_CLIENT,
                                msg[0], realm_ref_msg[0], entry_ex);
        return ret;
 }
@@ -1136,7 +1136,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
                
                ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, 
                                           mem_ctx, 
-                                          principal, HDB_LDB_ENT_TYPE_KRBTGT, realm_dn, &msg);
+                                          principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, realm_dn, &msg);
                
                if (ret != 0) {
                        krb5_warnx(context, "LDB_fetch: could not find principal in DB");
@@ -1145,7 +1145,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
                }
                
                ret = LDB_message2entry(context, db, mem_ctx, 
-                                       principal, HDB_LDB_ENT_TYPE_KRBTGT, 
+                                       principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, 
                                        msg[0], realm_ref_msg_1[0], entry_ex);
                if (ret != 0) {
                        krb5_warnx(context, "LDB_fetch: message2entry failed"); 
@@ -1265,7 +1265,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
                
                ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, 
                                           mem_ctx, 
-                                          principal, HDB_LDB_ENT_TYPE_SERVER, realm_dn, &msg);
+                                          principal, HDB_SAMBA4_ENT_TYPE_SERVER, realm_dn, &msg);
                
                if (ret != 0) {
                        return ret;
@@ -1273,7 +1273,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
        }
 
        ret = LDB_message2entry(context, db, mem_ctx, 
-                               principal, HDB_LDB_ENT_TYPE_SERVER,
+                               principal, HDB_SAMBA4_ENT_TYPE_SERVER,
                                msg[0], realm_ref_msg[0], entry_ex);
        if (ret != 0) {
                krb5_warnx(context, "LDB_fetch: message2entry failed"); 
@@ -1358,7 +1358,7 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd
 
        if (priv->index < priv->count) {
                ret = LDB_message2entry(context, db, mem_ctx, 
-                                       NULL, HDB_LDB_ENT_TYPE_ANY, 
+                                       NULL, HDB_SAMBA4_ENT_TYPE_ANY, 
                                        priv->msgs[priv->index++], 
                                        priv->realm_ref_msgs[0], entry);
        } else {
@@ -1476,7 +1476,7 @@ static krb5_error_code LDB_destroy(krb5_context context, HDB *db)
  * (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb
  * code */
 
-NTSTATUS kdc_hdb_ldb_create(TALLOC_CTX *mem_ctx, 
+NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx, 
                            struct event_context *ev_ctx, 
                            struct loadparm_context *lp_ctx,
                            krb5_context context, struct HDB **db, const char *arg)
@@ -1536,12 +1536,12 @@ NTSTATUS kdc_hdb_ldb_create(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
-krb5_error_code hdb_ldb_create(krb5_context context, struct HDB **db, const char *arg)
+krb5_error_code hdb_samba4_create(krb5_context context, struct HDB **db, const char *arg)
 {
        NTSTATUS nt_status;
        /* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */
-       nt_status = kdc_hdb_ldb_create(kdc_mem_ctx, event_context_find(kdc_mem_ctx), kdc_lp_ctx, 
-                                      context, db, arg);
+       nt_status = kdc_hdb_samba4_create(kdc_mem_ctx, event_context_find(kdc_mem_ctx), kdc_lp_ctx, 
+                                         context, db, arg);
 
        if (NT_STATUS_IS_OK(nt_status)) {
                return 0;
index 030eb23c10d8d8f33775a679fc8356e7c001d2c1..83c6f1c2ee15dc93a408c52bcfb2a7abb5ddb216 100644 (file)
@@ -667,6 +667,11 @@ static void kdc_task_init(struct task_server *task)
        NTSTATUS status;
        krb5_error_code ret;
        struct interface *ifaces;
+       struct hdb_method hdb_samba4 = {
+               .interface_version = HDB_INTERFACE_VERSION,
+               .prefix = "samba4:",
+               .create = hdb_samba4_create
+       };
 
        switch (lp_server_role(task->lp_ctx)) {
        case ROLE_STANDALONE:
@@ -724,7 +729,7 @@ static void kdc_task_init(struct task_server *task)
        }
        kdc->config->num_db = 1;
                
-       status = kdc_hdb_ldb_create(kdc, task->event_ctx, task->lp_ctx, 
+       status = kdc_hdb_samba4_create(kdc, task->event_ctx, task->lp_ctx, 
                                    kdc->smb_krb5_context->krb5_context, 
                                    &kdc->config->db[0], NULL);
        if (!NT_STATUS_IS_OK(status)) {
@@ -732,6 +737,16 @@ static void kdc_task_init(struct task_server *task)
                return; 
        }
 
+
+       /* Register hdb-samba4 hooks */
+       ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, 
+                                  PLUGIN_TYPE_DATA, "hdb",
+                                  &hdb_samba4);
+       if(ret) {
+               task_server_terminate(task, "kdc: failed to register hdb keytab");
+               return;
+       }
+
        ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops);
        if(ret) {
                task_server_terminate(task, "kdc: failed to register hdb keytab");