From: Zhanna Tsitkov Date: Mon, 28 Jun 2010 21:32:54 +0000 (+0000) Subject: Added facilities to handle dynamic plugins X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=224ec4ec57cb3e3df197e8fcfd0eea572d049d34;p=thirdparty%2Fkrb5.git Added facilities to handle dynamic plugins For the purpose of demonstration, a new plugin pwd_qlty_DYN was created. The new section in krb5.conf for dynamic plugins looks as follows plugin_list = PQ_DYN PQ_DYN = { plugin_api = plugin_pwd_qlty plugin_factory_name = plugin_dyn_factory plugin_factory_type = dynamic plugin_name = plugin_pwd_qlty_DYN plugin_factory_path = /var/tsitkova/Sources/pl/src/plugin_dynamic/libplugin_dynamic.so plugin_id = 33 } The test appl is server_misc.c. git-svn-id: svn://anonsvn.mit.edu/krb5/branches/plugins@24149 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/configure.in b/src/configure.in index 9c1c6543e4..f67740798a 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1123,6 +1123,7 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test plugins/pa plugins/pa/encrypted_challenge plugin_core + plugin_dynamic clients clients/klist clients/kinit clients/kvno clients/kdestroy clients/kpasswd clients/ksu diff --git a/src/lib/kadm5/srv/server_misc.c b/src/lib/kadm5/srv/server_misc.c index 8e5dac311e..c748ee3a29 100644 --- a/src/lib/kadm5/srv/server_misc.c +++ b/src/lib/kadm5/srv/server_misc.c @@ -65,6 +65,12 @@ passwd_check(kadm5_server_handle_t srv_handle, ret = plugin_pwd_qlty_check(plugin_handle, srv_handle, password, use_policy, pol, principal); + + plugin_handle = plugin_manager_get_service(srv_handle->context->pl_handle, + "plugin_pwd_qlty", PWD_QLTY_DYN); + + ret = plugin_pwd_qlty_check(plugin_handle, + srv_handle, password, use_policy, pol, principal); } return ret; } diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in index 49df43ceea..cfeae321af 100644 --- a/src/lib/krb5/Makefile.in +++ b/src/lib/krb5/Makefile.in @@ -65,7 +65,7 @@ RELDIR=krb5 SHLIB_EXPDEPS = \ $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB) -SHLIB_EXPLIBS=-lk5crypto -lcom_err $(SUPPORT_LIB) @GEN_LIB@ $(LIBS) $(PLUGINS_LIBS) +SHLIB_EXPLIBS=-lk5crypto -lcom_err $(SUPPORT_LIB) @GEN_LIB@ $(LIBS) $(PLUGINS_LIBS) -ldl SHLIB_DIRS=-L$(TOPLIBD) SHLIB_RDIRS=$(KRB5_LIBDIR) diff --git a/src/plugin_core/impl/plugin_default_factory.c b/src/plugin_core/impl/plugin_default_factory.c index 893b69b717..40fa6ecbf0 100644 --- a/src/plugin_core/impl/plugin_default_factory.c +++ b/src/plugin_core/impl/plugin_default_factory.c @@ -13,6 +13,7 @@ static plugin_factory* _default_factory_instance = NULL; +/* built-in plugins */ static plugin_descr plugin_default_factory_table[] = { {"plugin_pwd_qlty_X", plugin_pwd_qlty_X_create}, {"plugin_pwd_qlty_krb", plugin_pwd_qlty_krb_create}, @@ -37,11 +38,14 @@ _create_api (const char* plugin_name) plhandle handle; plugin_descr *ptr = NULL; - handle.api = NULL; - for( ptr = plugin_default_factory_table; ptr->plugin_name != NULL; ptr++) { - if (strcmp(ptr->plugin_name, plugin_name) == 0) { - handle = ptr->plugin_creator(); - break; + memset(&handle, 0, sizeof(handle)); + if(plugin_name){ + handle.api = NULL; + for( ptr = plugin_default_factory_table; ptr->plugin_name != NULL; ptr++) { + if (strcmp(ptr->plugin_name, plugin_name) == 0) { + handle = ptr->plugin_creator(); + break; + } } } return handle; @@ -49,7 +53,7 @@ _create_api (const char* plugin_name) factory_handle -plugin_default_factory_get_instance() +plugin_factory_get_instance() { plugin_factory* instance = _default_factory_instance; factory_handle handle; diff --git a/src/plugin_core/impl/plugin_default_factory.h b/src/plugin_core/impl/plugin_default_factory.h index 25760ef76c..5373ac5ae0 100644 --- a/src/plugin_core/impl/plugin_default_factory.h +++ b/src/plugin_core/impl/plugin_default_factory.h @@ -11,7 +11,7 @@ #include "plugin_pwd_qlty_X_impl.h" -factory_handle plugin_default_factory_get_instance(void); +factory_handle plugin_factory_get_instance(void); #endif /* PLUGIN_DEFAULT_FACTORY_H_ */ diff --git a/src/plugin_core/impl/plugin_default_manager.c b/src/plugin_core/impl/plugin_default_manager.c index c93f9705d6..05702955d3 100644 --- a/src/plugin_core/impl/plugin_default_manager.c +++ b/src/plugin_core/impl/plugin_default_manager.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include "plugin_default_manager.h" @@ -16,17 +17,34 @@ #endif static plugin_factory_descr _table[] = { - {"plugin_default_factory", plugin_default_factory_get_instance}, + {"plugin_default_factory", plugin_factory_get_instance}, {NULL, NULL} }; static factory_handle -_load_factory (const char* factory_name, const char* factory_type) +_load_dynamic_factory (const char* factory_name, const char* path) +{ + factory_handle handle; + void *h_dl = dlopen(path, RTLD_LAZY); + factory_handle (*plugin_d_factory_get_instance)() = NULL; +#ifdef DEBUG_PLUGINS + printf("plugins: _load_dynamic_factory %s\n", factory_name); +#endif + if(h_dl){ + plugin_d_factory_get_instance = dlsym(h_dl, "plugin_factory_get_instance"); + handle = plugin_d_factory_get_instance(); + } + + return handle; +} + +static factory_handle +_load_static_factory (const char* factory_name) { factory_handle handle; plugin_factory_descr *ptr = NULL; #ifdef DEBUG_PLUGINS - printf("plugins: _load_factory\n"); + printf("plugins: _load_static_factory %s\n", factory_name); #endif handle.api = NULL; @@ -38,7 +56,28 @@ _load_factory (const char* factory_name, const char* factory_type) } return handle; } +#define BUILTIN_TYPE "builtin" +#define DYNAMIC_TYPE "dynamic" +#define EMPTY_STR "" +static factory_handle +_load_factory(const char* factory_name, const char* factory_type, const char* factory_path) +{ + factory_handle handle; + if(strncmp(factory_type, BUILTIN_TYPE, strlen(BUILTIN_TYPE)) == 0){ + handle = _load_static_factory(factory_name); + } else if(strncmp(factory_type, DYNAMIC_TYPE, strlen(DYNAMIC_TYPE)) == 0){ + handle = _load_dynamic_factory(factory_name, factory_path); + } else { + if (factory_type) + printf("plugins: unknown factory_type %s\n", factory_type); + else { + printf("plugins: no factory_type found. Defaulting to built-in\n"); + handle = _load_static_factory(factory_name); + } + } + return handle; +} static registry_data* _create_registry() { @@ -83,11 +122,12 @@ _search_registry (registry_data* data, const char* api_name) } static plhandle -_create_api(const char* plugin_name, const char* factory_name, - const char* factory_type, const char* plugin_id /*, config_node* properties*/) +_create_api(const char* plugin_name, const char* plugin_id, + const char* factory_name, const char* factory_type, const char* factory_path + /*, config_node* properties*/) { plhandle p_handle; - factory_handle f_handle = _load_factory(factory_name, factory_type); + factory_handle f_handle = _load_factory(factory_name, factory_type, factory_path); #ifdef DEBUG_PLUGINS printf("plugins: _create_api\n"); #endif @@ -164,6 +204,7 @@ _configure_plugin_yaml(manager_data* mdata, config_node* plugin_node) const char* plugin_api = NULL; const char* factory_name = NULL; const char* factory_type = NULL; + const char* factory_path = NULL; const char* plugin_name = NULL; const char* plugin_type = NULL; const char* plugin_id = NULL; @@ -182,6 +223,8 @@ _configure_plugin_yaml(manager_data* mdata, config_node* plugin_node) factory_name = q->node_value.str_value; } else if(strcmp(q->node_name, "factory_type") == 0) { factory_type = q->node_value.str_value; + } else if(strcmp(q->node_name, "factory_path") == 0) { + factory_path = q->node_value.str_value; } else if(strcmp(q->node_name, "plugin_name") == 0) { plugin_name = q->node_value.str_value; } else if(strcmp(q->node_name, "plugin_id") == 0) { @@ -200,11 +243,13 @@ _configure_plugin_yaml(manager_data* mdata, config_node* plugin_node) printf("factory_type=%s\n", factory_type); printf("plugin_name=%s\n", plugin_name); printf("plugin_type=%s\n", plugin_type); + printf("plugin_path=%s\n", plugin_path); printf("plugin_id=%s\n", plugin_id); printf("**End**\n"); #endif - handle = _create_api(plugin_name, factory_name, factory_type/*, plugin_id*//*, properties*/); + handle = _create_api(plugin_name, plugin_id, + factory_name, factory_type, factory_path /*, properties*/); if(handle.api != NULL) { ret = _register_api(mdata->registry,plugin_api, plugin_type, handle); if (ret != API_REGISTER_OK) { @@ -263,13 +308,13 @@ _configure_krb5(manager_data* data, const char* path) profile_filespec_t *files = NULL; profile_t profile; const char *hierarchy[4]; - char **factory_name, **factory_type, **plugin_name, **plugin_type; + char **factory_name, **factory_type, **factory_path, **plugin_name, **plugin_type; char** plugin_id; char** plugin_api; + char *f_path = NULL; plhandle handle; char **pl_list, *pl_l; - retval = krb5_get_default_config_files(&files); #if 0 if (files) @@ -310,7 +355,7 @@ _configure_krb5(manager_data* data, const char* path) #endif i=0; - while (pl_l = pl_list[i++]){ + while ((pl_l = pl_list[i++])){ #ifdef DEBUG_PLUGINS printf("plugins: nickname in conf file: '%s'\n", pl_l); @@ -349,18 +394,30 @@ _configure_krb5(manager_data* data, const char* path) hierarchy[3] = 0; retval = profile_get_values(profile, hierarchy, &factory_type); + /* factory_path */ + hierarchy[2] = "plugin_factory_path"; + hierarchy[3] = 0; + retval = profile_get_values(profile, hierarchy, &factory_path); + if(!retval) + f_path = *factory_path; + else + f_path = NULL; + + #ifdef DEBUG_PLUGINS - printf("plugins: >>>\n"); + printf("ZH plugins: >>>\n"); printf("api=%s\n", *plugin_api); printf("factory=%s\n", *factory_name); printf("factory_type=%s\n", *factory_type); + if (f_path) printf("factory_path=%s\n", f_path); printf("plugin_name=%s\n", *plugin_name); printf("plugin_type=%s\n",*plugin_type); printf("plugin_id=%s\n", *plugin_id); printf("<<< plugins\n"); #endif - handle = _create_api(*plugin_name, *factory_name, *factory_type ,*plugin_id/*, properties*/); + handle = _create_api(*plugin_name, *plugin_id, + *factory_name, *factory_type, f_path /*, properties*/); if(handle.api != NULL) { retval = _register_api(mdata->registry,*plugin_api, *plugin_type, handle); if(retval != API_REGISTER_OK) { diff --git a/src/plugin_dynamic/Makefile.in b/src/plugin_dynamic/Makefile.in new file mode 100644 index 0000000000..2aeed12e8c --- /dev/null +++ b/src/plugin_dynamic/Makefile.in @@ -0,0 +1,42 @@ +mydir=plugin_dynamic +BUILDTOP=$(REL).. +RELDIR=../plugin_dynamic +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) +DEFS= + +LOCALINCLUDES = -I$(srcdir)/../include/krb5 -I$(srcdir)/. \ + -I$(srcdir)/../plugin_core \ + -I$(srcdir)/../plugins/pwd_qlty -I$(srcdir)/../plugins/pwd_qlty/plugin_pwd_qlty_DYN \ + -I$(srcdir)/../util/profile -I./../lib/kadm5/ + +LIBBASE= plugin_dynamic +LIBMAJOR=0 +LIBMINOR=0 +SO_EXT=.so + +# LIBS_UTILS = -lyaml +# LIBS_UTILS = -lprofile +LIBS_UTILS = +# $(BUILDTOP)/util/profile/libprofile.so + +SHLIB_DIRS=-L$(TOPLIBD) +SHLIB_RDIRS=$(KRB5_LIBDIR) +STOBJLISTS=OBJS.ST + +SHLIB_EXPLIBS= $(LIBS_UTILS) + +STLIBOBJS= plugin_dyn_factory.o $(srcdir)/../plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.o + +SRCS= plugin_dyn_factory.c $(srcdir)/../plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.c + +all-unix:: all-liblinks +install-unix:: install-libs +clean-unix:: clean-libs clean-libobjs clean-liblinks + +clean:: + $(RM) lib$(LIBBASE)$(SO_EXT) + +@lib_frag@ +@libobj_frag@ + diff --git a/src/plugin_dynamic/deps b/src/plugin_dynamic/deps new file mode 100644 index 0000000000..bf5a74b32b --- /dev/null +++ b/src/plugin_dynamic/deps @@ -0,0 +1,11 @@ +plugin_dyn_factory.so plugin_dyn_factory.po $(OUTPRE)plugin_dyn_factory.$(OBJEXT): \ + $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/plugin_core/plugin_factory.h \ + $(top_srcdir)/plugin_core/plugin_manager.h \ + $(top_srcdir)/plugin_dynamic/plugin_dyn_factory.h \ + plugin_dyn_factory.c +plugin_pwd_qlty_DYN_impl.so plugin_pwd_qlty_DYN_impl.po $(OUTPRE)plugin_pwd_qlty_DYN_impl.$(OBJEXT): \ + $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) \ + $(top_srcdir)/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.h \ + $(top_srcdir)/plugin_core/plugin_manager.h \ + $(top_srcdir)/plugin_core/plugin_factory.h \ + plugin_pwd_qlty_DYN_impl.c diff --git a/src/plugin_dynamic/libplugin_dynamic.exports b/src/plugin_dynamic/libplugin_dynamic.exports new file mode 100644 index 0000000000..00440c75e2 --- /dev/null +++ b/src/plugin_dynamic/libplugin_dynamic.exports @@ -0,0 +1,2 @@ +plugin_factory_get_instance +plugin_pwd_qlty_DYN_create diff --git a/src/plugin_dynamic/plugin_dyn_factory.c b/src/plugin_dynamic/plugin_dyn_factory.c new file mode 100644 index 0000000000..6342245628 --- /dev/null +++ b/src/plugin_dynamic/plugin_dyn_factory.c @@ -0,0 +1,67 @@ +/* + * plugin_dyn_factory.c + * + */ +#include +#include +#include + +#include +#include +#include + +static plugin_factory* _dyn_factory_instance = NULL; + +/* dynamic plugins */ +static plugin_descr plugin_dyn_factory_table[] = { + {"plugin_pwd_qlty_DYN", plugin_pwd_qlty_DYN_create}, + {NULL,NULL} +}; + +/* Factory API implementation */ +static void +_get_factory_content (const char* container[]) { + plugin_descr *ptr = NULL; + int i = 0; + for( ptr = plugin_dyn_factory_table; ptr->plugin_name != NULL; ptr++,i++) { + container[i] = ptr->plugin_name; + } +} + +static plhandle +_create_api (const char* plugin_name) +{ + plhandle handle; + plugin_descr *ptr = NULL; + + memset(&handle, 0, sizeof(handle)); + if(plugin_name){ + handle.api = NULL; + for( ptr = plugin_dyn_factory_table; ptr->plugin_name != NULL; ptr++) { + if (strcmp(ptr->plugin_name, plugin_name) == 0) { + handle = ptr->plugin_creator(); + break; + } + } + } + return handle; +} + + +factory_handle +plugin_factory_get_instance() +{ + plugin_factory* instance = _dyn_factory_instance; + factory_handle handle; + + if(_dyn_factory_instance == NULL) { + instance = (plugin_factory*) malloc(sizeof(plugin_factory)); + memset(instance, 0, sizeof(plugin_factory)); + instance->get_factory_content = _get_factory_content; + instance->create_api = _create_api; + _dyn_factory_instance = instance; + } + handle.api = instance; + return (handle); +} + diff --git a/src/plugin_dynamic/plugin_dyn_factory.h b/src/plugin_dynamic/plugin_dyn_factory.h new file mode 100644 index 0000000000..dc34258a56 --- /dev/null +++ b/src/plugin_dynamic/plugin_dyn_factory.h @@ -0,0 +1,16 @@ +/* + * plugin_dyn_factory.h + * + */ + +#ifndef PLUGIN_DYN_FACTORY_H_ +#define PLUGIN_DYN_FACTORY_H_ + +#include +#include "plugin_pwd_qlty_DYN_impl.h" + + +factory_handle plugin_factory_get_instance(void); + + +#endif /* PLUGIN_DYN_FACTORY_H_ */ diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty.h b/src/plugins/pwd_qlty/plugin_pwd_qlty.h index 83be080cd8..51c79c7018 100644 --- a/src/plugins/pwd_qlty/plugin_pwd_qlty.h +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty.h @@ -13,6 +13,7 @@ #define PWD_QLTY_KRB 0 #define PWD_QLTY_X 1 +#define PWD_QLTY_DYN 33 /* PWD_QLTY API */ typedef struct { diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.c b/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.c new file mode 100644 index 0000000000..632693df0c --- /dev/null +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.c @@ -0,0 +1,53 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +#include "k5-int.h" + +#include +#include +#include "plugin_pwd_qlty_DYN_impl.h" +#include +#include + + +static kadm5_ret_t +_plugin_pwd_qlty_check(kadm5_server_handle_t srv_handle, + char *password, int use_policy, kadm5_policy_ent_t pol, + krb5_principal principal) +{ + + +#ifdef DEBUG_PLUGINS + printf("Plugin pwd qlty DYNAMIC >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); +#endif + return 0; + +} + +static kadm5_ret_t +_plugin_pwd_qlty_init(kadm5_server_handle_t handle) +{ + return 0; +} + +static void +_plugin_pwd_qlty_clean() +{ + return; +} + +plhandle +plugin_pwd_qlty_DYN_create() +{ + plhandle handle; + plugin_pwd_qlty* api = malloc(sizeof(plugin_pwd_qlty)); + + memset(api, 0, sizeof(plugin_pwd_qlty)); + api->version = 1; + api->plugin_id = PWD_QLTY_DYN; + api->pwd_qlty_init = _plugin_pwd_qlty_init; + api->pwd_qlty_check = _plugin_pwd_qlty_check; + api->pwd_qlty_cleanup = _plugin_pwd_qlty_clean; + handle.api = api; + + return handle; +} diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.h b/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.h new file mode 100644 index 0000000000..022328a5bf --- /dev/null +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.h @@ -0,0 +1,14 @@ +/* + * plugin_pwd_qlty_DYN_impl.h + * + */ + +#ifndef PLUGIN_PWD_QLTY_DYN_IMPL_H_ +#define PLUGIN_PWD_QLTY_DYN_IMPL_H_ + +#include +#include + +plhandle plugin_pwd_qlty_DYN_create(void); + +#endif /* PLUGIN_PWD_QLTY_DYN_IMPL_H_ */