kdc --builtin-hdb should list loadable backends
This fixes the following problems from #210: - hdb_ldap doesn't load even when installed correctly - loadable hdb backends not listed by kdc --builtin-hdb Not fixed: - hdb_ldap.so not installed in plugin dir
This commit is contained in:
		
							
								
								
									
										100
									
								
								lib/hdb/hdb.c
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								lib/hdb/hdb.c
									
									
									
									
									
								
							@@ -90,6 +90,9 @@ static struct hdb_method methods[] = {
 | 
			
		||||
#if defined(OPENLDAP) && !defined(OPENLDAP_MODULE)
 | 
			
		||||
    { HDB_INTERFACE_VERSION, NULL, NULL, "ldap:",	hdb_ldap_create},
 | 
			
		||||
    { HDB_INTERFACE_VERSION, NULL, NULL, "ldapi:",	hdb_ldapi_create},
 | 
			
		||||
#elif defined(OPENLDAP)
 | 
			
		||||
    { HDB_INTERFACE_VERSION, NULL, NULL, "ldap:",	NULL},
 | 
			
		||||
    { HDB_INTERFACE_VERSION, NULL, NULL, "ldapi:",	NULL},
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef HAVE_SQLITE3
 | 
			
		||||
    { HDB_INTERFACE_VERSION, NULL, NULL, "sqlite:", hdb_sqlite_create},
 | 
			
		||||
@@ -349,6 +352,44 @@ find_method (const char *filename, const char **rest)
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct cb_s {
 | 
			
		||||
    const char *residual;
 | 
			
		||||
    const char *filename;
 | 
			
		||||
    const struct hdb_method *h;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static krb5_error_code KRB5_LIB_CALL
 | 
			
		||||
callback(krb5_context context, const void *plug, void *plugctx, void *userctx)
 | 
			
		||||
{
 | 
			
		||||
    const struct hdb_method *h = (const struct hdb_method *)plug;
 | 
			
		||||
    struct cb_s *cb_ctx = (struct cb_s *)userctx;
 | 
			
		||||
 | 
			
		||||
    if (strncmp(cb_ctx->filename, h->prefix, strlen(h->prefix)) == 0) {
 | 
			
		||||
	cb_ctx->residual = cb_ctx->filename + strlen(h->prefix);
 | 
			
		||||
	cb_ctx->h = h;
 | 
			
		||||
	return 0;
 | 
			
		||||
    }
 | 
			
		||||
   return KRB5_PLUGIN_NO_HANDLE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
make_sym(const char *prefix)
 | 
			
		||||
{
 | 
			
		||||
    char *s, *sym;
 | 
			
		||||
 | 
			
		||||
    errno = 0;
 | 
			
		||||
    if (prefix == NULL || prefix[0] == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    if ((s = strdup(prefix)) == NULL)
 | 
			
		||||
        return NULL;
 | 
			
		||||
    if (strchr(s, ':') != NULL)
 | 
			
		||||
        *strchr(s, ':') = '\0';
 | 
			
		||||
    if (asprintf(&sym, "hdb_%s_interface", s) == -1)
 | 
			
		||||
        sym = NULL;
 | 
			
		||||
    free(s);
 | 
			
		||||
    return sym;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
krb5_error_code
 | 
			
		||||
hdb_list_builtin(krb5_context context, char **list)
 | 
			
		||||
{
 | 
			
		||||
@@ -365,12 +406,34 @@ hdb_list_builtin(krb5_context context, char **list)
 | 
			
		||||
    len += 1;
 | 
			
		||||
    buf = malloc(len);
 | 
			
		||||
    if (buf == NULL) {
 | 
			
		||||
	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
 | 
			
		||||
	return ENOMEM;
 | 
			
		||||
	return krb5_enomem(context);
 | 
			
		||||
    }
 | 
			
		||||
    buf[0] = '\0';
 | 
			
		||||
 | 
			
		||||
    for (h = methods; h->prefix != NULL; ++h) {
 | 
			
		||||
        if (h->create == NULL) {
 | 
			
		||||
            struct cb_s cb_ctx;
 | 
			
		||||
            char *f;
 | 
			
		||||
            char *sym;
 | 
			
		||||
 | 
			
		||||
            /* Try loading the plugin */
 | 
			
		||||
            if (asprintf(&f, "%sfoo", h->prefix) == -1)
 | 
			
		||||
                f = NULL;
 | 
			
		||||
            if ((sym = make_sym(h->prefix)) == NULL) {
 | 
			
		||||
                free(f);
 | 
			
		||||
                return krb5_enomem(context);
 | 
			
		||||
            }
 | 
			
		||||
            cb_ctx.filename = f;
 | 
			
		||||
            cb_ctx.residual = NULL;
 | 
			
		||||
            cb_ctx.h = NULL;
 | 
			
		||||
            (void)_krb5_plugin_run_f(context, "krb5", sym,
 | 
			
		||||
                                     HDB_INTERFACE_VERSION, 0, &cb_ctx,
 | 
			
		||||
                                     callback);
 | 
			
		||||
            free(f);
 | 
			
		||||
            free(sym);
 | 
			
		||||
            if (cb_ctx.h == NULL || cb_ctx.h->create == NULL)
 | 
			
		||||
                continue;
 | 
			
		||||
        }
 | 
			
		||||
	if (h != methods)
 | 
			
		||||
	    strlcat(buf, ", ", len);
 | 
			
		||||
	strlcat(buf, h->prefix, len);
 | 
			
		||||
@@ -408,26 +471,6 @@ _hdb_keytab2hdb_entry(krb5_context context,
 | 
			
		||||
 * use O_CREAT to tell the backend to create the file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct cb_s {
 | 
			
		||||
    const char *residual;
 | 
			
		||||
    const char *filename;
 | 
			
		||||
    const struct hdb_method *h;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static krb5_error_code KRB5_LIB_CALL
 | 
			
		||||
callback(krb5_context context, const void *plug, void *plugctx, void *userctx)
 | 
			
		||||
{
 | 
			
		||||
    const struct hdb_method *h = (const struct hdb_method *)plug;
 | 
			
		||||
    struct cb_s *cb_ctx = (struct cb_s *)userctx;
 | 
			
		||||
 | 
			
		||||
    if (strncmp(cb_ctx->filename, h->prefix, strlen(h->prefix)) == 0) {
 | 
			
		||||
	cb_ctx->residual = cb_ctx->filename + strlen(h->prefix);
 | 
			
		||||
	cb_ctx->h = h;
 | 
			
		||||
	return 0;
 | 
			
		||||
    }
 | 
			
		||||
   return KRB5_PLUGIN_NO_HANDLE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
krb5_error_code
 | 
			
		||||
hdb_create(krb5_context context, HDB **db, const char *filename)
 | 
			
		||||
{
 | 
			
		||||
@@ -438,9 +481,16 @@ hdb_create(krb5_context context, HDB **db, const char *filename)
 | 
			
		||||
    cb_ctx.h = find_method (filename, &cb_ctx.residual);
 | 
			
		||||
    cb_ctx.filename = filename;
 | 
			
		||||
 | 
			
		||||
    if (cb_ctx.h == NULL) {
 | 
			
		||||
	    (void)_krb5_plugin_run_f(context, "krb5", "hdb",
 | 
			
		||||
			     HDB_INTERFACE_VERSION, 0, &cb_ctx, callback);
 | 
			
		||||
    if (cb_ctx.h == NULL || cb_ctx.h->create == NULL) {
 | 
			
		||||
        char *sym;
 | 
			
		||||
 | 
			
		||||
        if ((sym = make_sym(filename)) == NULL)
 | 
			
		||||
            return krb5_enomem(context);
 | 
			
		||||
 | 
			
		||||
        (void)_krb5_plugin_run_f(context, "krb5", sym, HDB_INTERFACE_VERSION,
 | 
			
		||||
                                 0, &cb_ctx, callback);
 | 
			
		||||
 | 
			
		||||
        free(sym);
 | 
			
		||||
    }
 | 
			
		||||
    if (cb_ctx.h == NULL)
 | 
			
		||||
	krb5_errx(context, 1, "No database support for %s", cb_ctx.filename);
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
[libdefaults]
 | 
			
		||||
	default_realm = TEST.H5L.SE
 | 
			
		||||
	no-addresses = TRUE
 | 
			
		||||
        plugin_dir = @objdir@/../../lib/hdb @objdir@/../../lib/hdb/.libs
 | 
			
		||||
 | 
			
		||||
[realms]
 | 
			
		||||
	TEST.H5L.SE = {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user