From: Zhanna Tsitkov Date: Mon, 14 Jun 2010 19:26:20 +0000 (+0000) Subject: Added facilities to handle multiple impls of the same static plugins. It is based... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d75ad1259c4edccc7c4127e9ed01a12dfa191730;p=thirdparty%2Fkrb5.git Added facilities to handle multiple impls of the same static plugins. It is based on plugin_id As a proof of the concept, the password quality validation plugins were considered. So, the following happens: In the krb5.conf we indicate that we potentially want two pwd quality plugins: plugin_pwd_qlty_krb (native MIT kerb code extracted from server_mics.c) and plugin_pwd_qlty_X (bogus,as a matter of fact, almost identical to plugin_pwd_qlty_krb impl). In the caller, i.e. in passwd_check of lib/kadm5/srv/server_misc.c, we call KRB and X impl's and verify the pwd against both of the policies: plugin_manager_get_service(srv_handle->context->pl_handle, "plugin_pwd_qlty", PWD_QLTY_KRB); plugin_manager_get_service(srv_handle->context->pl_handle, "plugin_pwd_qlty", PWD_QLTY_X); (It is proof of the concept.) git-svn-id: svn://anonsvn.mit.edu/krb5/branches/plugins@24135 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/Makefile.in b/src/Makefile.in index 2540836ce0..417270105c 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -10,6 +10,7 @@ mydir=. SUBDIRS=util include plugin_core plugin_core/impl \ plugins/pa plugins/pa/encrypted_challenge \ plugins/pwd_qlty plugins/pwd_qlty/plugin_pwd_qlty_krb \ + plugins/pwd_qlty/plugin_pwd_qlty_X \ lib \ @ldap_plugin_dir@ \ plugins/kdb/db2 \ diff --git a/src/config-files/krb5.conf b/src/config-files/krb5.conf index 09387983df..dfd2cd9d49 100644 --- a/src/config-files/krb5.conf +++ b/src/config-files/krb5.conf @@ -26,22 +26,24 @@ # kdc = CONSOLE [plugins] - plugin_prng = { - plugin_factory_name = plugin_default_factory - plugin_factory_type = static - plugin_name = plugin_yarrow_prng - plugin_type = service - } - plugin_pa = { + plugin_list = PQ1 + plugin_list = PQ2 + + PQ1 = { + plugin_api = plugin_pwd_qlty plugin_factory_name = plugin_default_factory plugin_factory_type = static - plugin_name = plugin_encrypted_challenge_pa + plugin_name = plugin_pwd_qlty_X plugin_type = service + plugin_id = 1 } - plugin_pwd_qlty = { + + PQ2 = { + plugin_api = plugin_pwd_qlty plugin_factory_name = plugin_default_factory plugin_factory_type = static plugin_name = plugin_pwd_qlty_krb plugin_type = service + plugin_id = 0 } diff --git a/src/configure.in b/src/configure.in index 6d1ddad60a..9c1c6543e4 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1118,6 +1118,7 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test plugins/pwd_qlty plugins/pwd_qlty/plugin_pwd_qlty_krb + plugins/pwd_qlty/plugin_pwd_qlty_X plugin_core/impl plugins/pa plugins/pa/encrypted_challenge diff --git a/src/include/k5-int.h b/src/include/k5-int.h index f6ef41a10b..6b320242ac 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -1433,6 +1433,7 @@ struct _kdb_log_context; /* Plugin API ---- PLUGIN HANDLE */ typedef struct _plhandle{ + int plugin_id; void *api; struct _plhandle *next; } plhandle; @@ -1459,7 +1460,7 @@ typedef struct { void (*configure)(manager_data * data, const char*); void (*start)(manager_data * data); void (*stop)(manager_data * data); - plhandle (*getService)(manager_data * data, const char*); + plhandle (*getService)(manager_data * data, const char*, const int pl_id); } plugin_manager; /* Plugin API ---- PLUGIN HANDLE ----- END*/ @@ -1513,7 +1514,7 @@ struct _krb5_context { krb5_boolean allow_weak_crypto; - /* PLUGIN HANDLE */ + /* PLUGIN manager HANDLE */ plugin_manager *pl_handle; }; diff --git a/src/kdc/enc_challenge.c b/src/kdc/enc_challenge.c index df17ad0990..8c6f409b53 100644 --- a/src/kdc/enc_challenge.c +++ b/src/kdc/enc_challenge.c @@ -10,7 +10,7 @@ int preauth_flags(krb5_context context, krb5_preauthtype pa_type) { int flags = 0; - plhandle handle = plugin_manager_get_service(context->pl_handle, "plugin_pa"); + plhandle handle = plugin_manager_get_service(context->pl_handle, "plugin_pa", 0); flags = plugin_preauth_flags(handle, context, pa_type); return flags; @@ -30,7 +30,7 @@ process_preauth(krb5_context context, void *plugin_context, krb5_pa_data ***out_padata) { krb5_error_code ret = 0; - plhandle handle = plugin_manager_get_service(context->pl_handle, "plugin_pa"); + plhandle handle = plugin_manager_get_service(context->pl_handle, "plugin_pa", 0); ret = plugin_process_preauth(handle, context, plugin_context, request_context, opt, @@ -52,7 +52,7 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request, void *pa_module_context, krb5_pa_data *data) { krb5_error_code retval = 0; - plhandle handle = plugin_manager_get_service(context->pl_handle, "plugin_pa"); + plhandle handle = plugin_manager_get_service(context->pl_handle, "plugin_pa", 0); retval = plugin_kdc_include_padata(handle, context, request, client, server, @@ -69,7 +69,7 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client, krb5_data **e_data, krb5_authdata ***authz_data) { krb5_error_code retval = 0; - plhandle handle = plugin_manager_get_service(context->pl_handle, "plugin_pa"); + plhandle handle = plugin_manager_get_service(context->pl_handle, "plugin_pa", 0); retval = plugin_kdc_verify_preauth(handle, context, client, req_pkt, request, enc_tkt_reply, data, @@ -89,7 +89,7 @@ kdc_return_preauth(krb5_context context, krb5_pa_data *padata, void *pa_module_context, void **pa_request_context) { krb5_error_code retval = 0; - plhandle handle = plugin_manager_get_service(context->pl_handle, "plugin_pa"); + plhandle handle = plugin_manager_get_service(context->pl_handle, "plugin_pa", 0); retval = plugin_kdc_return_preauth(handle, context, padata, client, req_pkt, request, reply, @@ -106,7 +106,7 @@ server_free_reqctx(krb5_context kcontext, void **pa_request_context) { krb5_error_code retval = 0; - plhandle handle = plugin_manager_get_service(kcontext->pl_handle, "plugin_pa"); + plhandle handle = plugin_manager_get_service(kcontext->pl_handle, "plugin_pa", 0); retval = plugin_server_free_reqctx(handle, kcontext, pa_module_context, pa_request_context); @@ -116,14 +116,14 @@ krb5_error_code server_init(krb5_context kcontext, void **module_context, const char **realmnames) { krb5_error_code retval = 0; - plhandle handle = plugin_manager_get_service(kcontext->pl_handle, "plugin_pa"); + plhandle handle = plugin_manager_get_service(kcontext->pl_handle, "plugin_pa", 0); retval = plugin_server_init(handle, kcontext, module_context, realmnames); return retval; } void server_fini(krb5_context kcontext, void *module_context) { - plhandle handle = plugin_manager_get_service(kcontext->pl_handle, "plugin_pa"); + plhandle handle = plugin_manager_get_service(kcontext->pl_handle, "plugin_pa", 0); plugin_server_fini(handle, kcontext, module_context); return; } diff --git a/src/lib/kadm5/srv/server_misc.c b/src/lib/kadm5/srv/server_misc.c index d89699a17c..8e5dac311e 100644 --- a/src/lib/kadm5/srv/server_misc.c +++ b/src/lib/kadm5/srv/server_misc.c @@ -55,7 +55,13 @@ passwd_check(kadm5_server_handle_t srv_handle, srv_handle->context->pl_handle != NULL ){ plugin_handle = plugin_manager_get_service(srv_handle->context->pl_handle, - "plugin_pwd_qlty"); + "plugin_pwd_qlty", PWD_QLTY_KRB); + + 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_X); ret = plugin_pwd_qlty_check(plugin_handle, srv_handle, password, use_policy, pol, principal); diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in index 0e3a047a8d..49df43ceea 100644 --- a/src/lib/krb5/Makefile.in +++ b/src/lib/krb5/Makefile.in @@ -10,7 +10,8 @@ DEFS= PLUGINS_LIBS = \ ../../plugin_core/impl/libplugin_impl.a $(PLUGIN_CORE_DEPLIB) \ ../../plugins/pa/encrypted_challenge/libencrypted_challenge.a \ - ../../plugins/pwd_qlty/plugin_pwd_qlty_krb/libplugin_pwd_qlty_krb.a + ../../plugins/pwd_qlty/plugin_pwd_qlty_krb/libplugin_pwd_qlty_krb.a \ + ../../plugins/pwd_qlty/plugin_pwd_qlty_X/libplugin_pwd_qlty_X.a ##DOSBUILDTOP = ..\.. diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c index dff54d06cc..91d17ea31a 100644 --- a/src/lib/krb5/krb/init_ctx.c +++ b/src/lib/krb5/krb/init_ctx.c @@ -177,7 +177,7 @@ init_common (krb5_context *context, krb5_boolean secure, krb5_boolean kdc) ctx->allow_weak_crypto = tmp; - /* Plugin initialization */ // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>... + /* Plugin initialization */ plugin_default_manager_get_instance(&plugin_mngr_instance); set_plugin_manager_instance(&ctx->pl_handle, plugin_mngr_instance); plugin_manager_configure(ctx->pl_handle, conf_path); diff --git a/src/plugin_core/impl/Makefile.in b/src/plugin_core/impl/Makefile.in index 2d292d86dd..bc9e630c04 100644 --- a/src/plugin_core/impl/Makefile.in +++ b/src/plugin_core/impl/Makefile.in @@ -6,7 +6,9 @@ PROG_RPATH=$(KRB5_LIBDIR) DEFS= LOCALINCLUDES = -I$(srcdir)/../../include/krb5 -I$(srcdir)/. \ - -I$(srcdir)/../../plugins/pwd_qlty -I$(srcdir)/../../plugins/pwd_qlty/plugin_pwd_qlty_krb \ + -I$(srcdir)/../../plugins/pwd_qlty \ + -I$(srcdir)/../../plugins/pwd_qlty/plugin_pwd_qlty_krb \ + -I$(srcdir)/../../plugins/pwd_qlty/plugin_pwd_qlty_X \ -I$(srcdir)/../../plugins/pa -I$(srcdir)/../../plugins/pa/encrypted_challenge \ -I$(srcdir)/.. -I$(srcdir)/../../lib/kadm5 @@ -19,7 +21,8 @@ SRCS= plugin_default_factory.c plugin_default_manager.c STOBJLISTS=OBJS.ST LIBS_UTILS = ../plugin_core$(SO_EXT) \ - ../../plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_impl$(SO_EXT) + ../../plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_krb_impl$(SO_EXT) \ + ../../plugins/pwd_qlty/plugin_pwd_qlty_X/plugin_pwd_qlty_X_impl$(SO_EXT) SHLIB_EXPLIBS= $(LIBS_UTILS) $(CRYPTO_DEPLIB) $(SUPPORT_DEPLIB) diff --git a/src/plugin_core/impl/plugin_default_factory.c b/src/plugin_core/impl/plugin_default_factory.c index 1711240d52..893b69b717 100644 --- a/src/plugin_core/impl/plugin_default_factory.c +++ b/src/plugin_core/impl/plugin_default_factory.c @@ -9,12 +9,12 @@ #include "plugin_manager.h" #include "plugin_factory.h" #include "plugin_pa_impl.h" -#include "plugin_pwd_qlty_impl.h" #include "plugin_default_factory.h" static plugin_factory* _default_factory_instance = NULL; 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}, {"plugin_encrypted_challenge_pa", plugin_encrypted_challenge_pa_create}, {"plugin_ldap_audit", NULL}, diff --git a/src/plugin_core/impl/plugin_default_factory.h b/src/plugin_core/impl/plugin_default_factory.h index 04e8e318ab..25760ef76c 100644 --- a/src/plugin_core/impl/plugin_default_factory.h +++ b/src/plugin_core/impl/plugin_default_factory.h @@ -7,7 +7,8 @@ #define PLUGIN_DEFAULT_FACTORY_H_ #include -#include "plugin_pwd_qlty_impl.h" +#include "plugin_pwd_qlty_krb_impl.h" +#include "plugin_pwd_qlty_X_impl.h" factory_handle plugin_default_factory_get_instance(void); diff --git a/src/plugin_core/impl/plugin_default_manager.c b/src/plugin_core/impl/plugin_default_manager.c index 7bddeb2c05..c93f9705d6 100644 --- a/src/plugin_core/impl/plugin_default_manager.c +++ b/src/plugin_core/impl/plugin_default_manager.c @@ -25,6 +25,9 @@ _load_factory (const char* factory_name, const char* factory_type) { factory_handle handle; plugin_factory_descr *ptr = NULL; +#ifdef DEBUG_PLUGINS + printf("plugins: _load_factory\n"); +#endif handle.api = NULL; for( ptr = _table; ptr->factory_name != NULL; ptr++) { @@ -40,6 +43,9 @@ static registry_data* _create_registry() { registry_data* registry = (registry_data*) malloc(sizeof(registry_data)); +#ifdef DEBUG_PLUGINS + printf("plugins: _create_registry\n"); +#endif memset(registry, 0, sizeof(registry_data)); return registry; @@ -48,6 +54,9 @@ _create_registry() static void _extend_registry (registry_data* data, int ext_n) { +#ifdef DEBUG_PLUGINS + printf("plugins: _extend_registry\n"); +#endif if(data->registry_max_size == 0) { data->table = NULL; } @@ -62,6 +71,9 @@ _search_registry (registry_data* data, const char* api_name) int i = 0; reg_entry* ptr = data->table; +#ifdef DEBUG_PLUGINS + printf("plugins: _search_registry\n"); +#endif for(i = 0; i < data->registry_size; i++,ptr++) { if(strcmp(api_name, ptr->api_name) == 0) { return ptr; @@ -72,11 +84,15 @@ _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/*, config_node* properties*/) + const char* factory_type, const char* plugin_id /*, config_node* properties*/) { plhandle p_handle; factory_handle f_handle = _load_factory(factory_name, factory_type); +#ifdef DEBUG_PLUGINS + printf("plugins: _create_api\n"); +#endif p_handle = create_api(f_handle, plugin_name); + p_handle.plugin_id = atoi(plugin_id); return(p_handle); } @@ -101,21 +117,31 @@ _register_api(registry_data* data, const char* api_name, if(data->registry_size == data->registry_max_size) { _extend_registry(data, extension_size); } + +#ifdef DEBUG_PLUGINS + printf ("plugins: _register_api %s\n", api_name); +#endif + entry = _search_registry(data, api_name); if(entry == NULL) { + /* Do this in case of a new id only */ entry = data->table + data->registry_size; data->registry_size++; } +#if 0 if(entry->size && strcmp(plugin_type, "service") == 0) { #ifdef DEBUG_PLUGINS printf("%s is already registered, only one plugin is allowed per service\n", api_name); #endif ret = API_ALREADY_REGISTERED; - } else { + } else +#endif + { strcpy(entry->api_name, api_name); next = (plhandle*) malloc(sizeof(plhandle)); memset(next, 0, sizeof(plhandle)); next->api = handle.api; + next->plugin_id = handle.plugin_id; if(entry->first == NULL) { entry->first = next; entry->last = next; @@ -140,6 +166,7 @@ _configure_plugin_yaml(manager_data* mdata, config_node* plugin_node) const char* factory_type = NULL; const char* plugin_name = NULL; const char* plugin_type = NULL; + const char* plugin_id = NULL; plhandle handle; int ret = API_REGISTER_FAILED; @@ -157,7 +184,10 @@ _configure_plugin_yaml(manager_data* mdata, config_node* plugin_node) factory_type = 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) { + plugin_id = q->node_value.str_value; } + } } else if(strcmp(p->node_name, "properties") == 0) { properties = p; @@ -170,10 +200,11 @@ _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_id=%s\n", plugin_id); printf("**End**\n"); #endif - handle = _create_api(plugin_name, factory_name, factory_type/*, properties*/); + handle = _create_api(plugin_name, factory_name, factory_type/*, plugin_id*//*, properties*/); if(handle.api != NULL) { ret = _register_api(mdata->registry,plugin_api, plugin_type, handle); if (ret != API_REGISTER_OK) { @@ -182,6 +213,9 @@ _configure_plugin_yaml(manager_data* mdata, config_node* plugin_node) plugin_name, plugin_api, factory_name, plugin_type); #endif } + else + printf("SUCCESS to register %s for %s(factory=%s,plugin_type=%s)\n", + plugin_name, plugin_api, factory_name, plugin_type); } else { #ifdef DEBUG_PLUGINS printf("Failed to configure plugin: api=%s, plugin_name=%s,factory=%s\n", @@ -225,11 +259,16 @@ _configure_krb5(manager_data* data, const char* path) krb5_error_code retval; char *plugin; void *iter; + int i = 0; profile_filespec_t *files = NULL; profile_t profile; - const char *realm_srv_names[4]; + const char *hierarchy[4]; char **factory_name, **factory_type, **plugin_name, **plugin_type; + char** plugin_id; + char** plugin_api; plhandle handle; + char **pl_list, *pl_l; + retval = krb5_get_default_config_files(&files); #if 0 @@ -250,61 +289,98 @@ _configure_krb5(manager_data* data, const char* path) com_err("krb5_PLUGIN_iterator_create", retval, 0); return; } - while (iter) { + /* Get the list of the plugins that may be used during run time */ + hierarchy[0] = "plugins"; + hierarchy[1] = "plugin_list"; + hierarchy[2] = 0; + retval = profile_get_values(profile, hierarchy, &pl_list); + if (retval){ + com_err("krb5_PLUGIN no plugins listed to configure/register", retval, 0); + return; + } + +#if 0 + while (iter && pl_list[i]) { if ((retval = krb5_plugin_iterator(profile, &iter, &plugin))) { com_err("krb5_PLUGIN_iterator", retval, 0); krb5_plugin_iterator_free(profile, &iter); return; } if (plugin) { -#ifdef DEBUG_PLUGINS - printf("PLUGIN: '%s'\n", plugin); #endif - realm_srv_names[0] = "plugins"; - realm_srv_names[1] = plugin; - - /* plugin_name */ - realm_srv_names[2] = "plugin_name"; - realm_srv_names[3] = 0; - retval = profile_get_values(profile, realm_srv_names, &plugin_name); + i=0; + while (pl_l = pl_list[i++]){ - /* plugin_type */ - realm_srv_names[2] = "plugin_type"; - realm_srv_names[3] = 0; - - retval = profile_get_values(profile, realm_srv_names, &plugin_type); - - /* factory_name */ - realm_srv_names[2] = "plugin_factory_name"; - realm_srv_names[3] = 0; - - retval = profile_get_values(profile, realm_srv_names, &factory_name); - - /* factory_type */ - realm_srv_names[2] = "plugin_factory_type"; - realm_srv_names[3] = 0; +#ifdef DEBUG_PLUGINS + printf("plugins: nickname in conf file: '%s'\n", pl_l); +#endif + hierarchy[0] = "plugins"; + hierarchy[1] = pl_l; + //hierarchy[1] = plugin; + + /* plugin_name */ + hierarchy[2] = "plugin_api"; + hierarchy[3] = 0; + retval = profile_get_values(profile, hierarchy, &plugin_api); + + /* plugin_name */ + hierarchy[2] = "plugin_name"; + hierarchy[3] = 0; + retval = profile_get_values(profile, hierarchy, &plugin_name); + + /* plugin_type */ + hierarchy[2] = "plugin_type"; + hierarchy[3] = 0; + retval = profile_get_values(profile, hierarchy, &plugin_type); + + /* plugin_id */ + hierarchy[2] = "plugin_id"; + hierarchy[3] = 0; + retval = profile_get_values(profile, hierarchy, &plugin_id); + + /* factory_name */ + hierarchy[2] = "plugin_factory_name"; + hierarchy[3] = 0; + retval = profile_get_values(profile, hierarchy, &factory_name); + + /* factory_type */ + hierarchy[2] = "plugin_factory_type"; + hierarchy[3] = 0; + retval = profile_get_values(profile, hierarchy, &factory_type); - retval = profile_get_values(profile, realm_srv_names, &factory_type); +#ifdef DEBUG_PLUGINS + printf("plugins: >>>\n"); + printf("api=%s\n", *plugin_api); + printf("factory=%s\n", *factory_name); + printf("factory_type=%s\n", *factory_type); + 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/*, properties*/); - if(handle.api != NULL) { - retval = _register_api(mdata->registry,plugin, *plugin_type, handle); - if( retval != API_REGISTER_OK) { + handle = _create_api(*plugin_name, *factory_name, *factory_type ,*plugin_id/*, properties*/); + if(handle.api != NULL) { + retval = _register_api(mdata->registry,*plugin_api, *plugin_type, handle); + if(retval != API_REGISTER_OK) { #ifdef DEBUG_PLUGINS - printf("Failed to register %s for %s(factory=%s,plugin_type=%s)\n", - *plugin_name, plugin, *factory_name, *plugin_type); + printf("plugins: Failed to register %s for %s(factory=%s,plugin_type=%s) ret=%i\n", + *plugin_name, *plugin_api, *factory_name, *plugin_type, retval); #endif - } } else { #ifdef DEBUG_PLUGINS - printf("Failed to configure plugin: api=%s, plugin_name=%s,factory=%s\n", - plugin, *plugin_name, *factory_name); + printf("plugins: registered OK\n"); #endif } - - krb5_free_plugin_string(profile, plugin); + } else { +#ifdef DEBUG_PLUGINS + printf("plugins: Failed to configure plugin: api=%s, plugin_name=%s,factory=%s\n", + *plugin_api, *plugin_name, *factory_name); +#endif } + + // Need to cleanup ~ krb5_free_plugin_string(profile, plugin); } } @@ -323,22 +399,31 @@ _stop(manager_data* data) } static plhandle -_getService(manager_data* data, const char* service_name) +_getService(manager_data* data, const char* service_name, int plugin_id) { - plhandle handle; + plhandle *handle; manager_data* mdata = (manager_data*) data; reg_entry* entry = _search_registry(mdata->registry, service_name); memset(&handle, 0, sizeof handle); if(entry) { - handle = *(entry->first); + for(handle = entry->first; handle != NULL; handle = handle->next) { + if (handle->plugin_id == plugin_id) + break; + } + if (handle == NULL) { +#ifdef DEBUG_PLUGINS + printf("service %s:%d is not registered \n", service_name, plugin_id); +#endif + } + } else { #ifdef DEBUG_PLUGINS printf("service %s is not available\n", service_name); #endif } - return handle; + return *handle; } static manager_data* @@ -354,11 +439,18 @@ _init_data() plugin_manager* plugin_default_manager_get_instance(plugin_manager** plugin_mngr_instance) { - plugin_manager* instance = NULL; // = plugin_mngr_instance; + plugin_manager* instance = NULL; +#ifdef DEBUG_PLUGINS + printf("plugins: plugin_default_manager_get_instanc \n"); +#endif if(*plugin_mngr_instance == NULL) { + instance = (plugin_manager*) malloc(sizeof(plugin_manager)); + if (!instance) + return NULL; memset(instance, 0, sizeof(plugin_manager)); + instance->data = _init_data(); #ifdef CONFIG_IN_YAML instance->configure = _configure_yaml; @@ -372,4 +464,3 @@ plugin_default_manager_get_instance(plugin_manager** plugin_mngr_instance) } return (*plugin_mngr_instance); } - diff --git a/src/plugin_core/plugin_manager.c b/src/plugin_core/plugin_manager.c index 2ce0c1a305..647044d173 100644 --- a/src/plugin_core/plugin_manager.c +++ b/src/plugin_core/plugin_manager.c @@ -17,6 +17,7 @@ plugin_manager_configure(plugin_manager* _instance,const char* path) if (_instance != NULL) { _instance->configure(_instance->data, path); } + return 0; } void plugin_manager_start(plugin_manager* _instance) @@ -34,16 +35,13 @@ void plugin_manager_stop(plugin_manager* _instance) } plhandle -plugin_manager_get_service(plugin_manager* _instance, const char* service_name) +plugin_manager_get_service(plugin_manager* _instance, const char* service_name, const int pl_id) { plhandle handle; if (_instance != NULL) { - handle = _instance->getService(_instance->data, service_name); + handle = _instance->getService(_instance->data, service_name, pl_id); } else { handle.api = NULL; } return handle; } - - - diff --git a/src/plugin_core/plugin_manager.h b/src/plugin_core/plugin_manager.h index 4f1afe2b10..b2311864b0 100644 --- a/src/plugin_core/plugin_manager.h +++ b/src/plugin_core/plugin_manager.h @@ -14,6 +14,6 @@ void set_plugin_manager_instance(plugin_manager** _instance,plugin_manager*); int plugin_manager_configure(plugin_manager* _instance,const char*); void plugin_manager_start(plugin_manager* _instance); void plugin_manager_stop(plugin_manager* _instance); -plhandle plugin_manager_get_service(plugin_manager* _instance,const char*); +plhandle plugin_manager_get_service(plugin_manager* _instance,const char*, const int); #endif /* PLUGIN_MANAGER_H_ */ diff --git a/src/plugins/pwd_qlty/deps b/src/plugins/pwd_qlty/deps index 7b7a8790bf..cada08652a 100644 --- a/src/plugins/pwd_qlty/deps +++ b/src/plugins/pwd_qlty/deps @@ -7,9 +7,3 @@ plugin_pwd_qlty.so plugin_pwd_qlty.po $(OUTPRE)plugin_pwd_qlty.$(OBJEXT): \ $(top_srcdir)/plugin_core/plugin_factory.h \ $(top_srcdir)/lib/kadm5/admin.h \ plugin_pwd_qlty.c -plugin_pwd_qlty_impl.so plugin_pwd_qlty_impl.po $(OUTPRE)plugin_pwd_qlty_impl.$(OBJEXT): \ - $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/plugins/pwd_qlty/plugin_pwd_qlty_impl.h \ - $(top_srcdir)/plugin_core/plugin_manager.h \ - $(top_srcdir)/plugin_core/plugin_factory.h \ - $(top_srcdir)/lib/kadm5/admin.h \ - plugin_pwd_qlty_impl.c diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty.h b/src/plugins/pwd_qlty/plugin_pwd_qlty.h index 4921be8161..83be080cd8 100644 --- a/src/plugins/pwd_qlty/plugin_pwd_qlty.h +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty.h @@ -11,9 +11,13 @@ #include #include +#define PWD_QLTY_KRB 0 +#define PWD_QLTY_X 1 + /* PWD_QLTY API */ typedef struct { int version; + int plugin_id; kadm5_ret_t (*pwd_qlty_init)(kadm5_server_handle_t); void (*pwd_qlty_cleanup)(); kadm5_ret_t (*pwd_qlty_check)(kadm5_server_handle_t, char*, diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty_X/Makefile.in b/src/plugins/pwd_qlty/plugin_pwd_qlty_X/Makefile.in new file mode 100644 index 0000000000..b6a50b7202 --- /dev/null +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty_X/Makefile.in @@ -0,0 +1,25 @@ +mydir=plugins/pwd_qlty/plugin_pwd_qlty_X +BUILDTOP=$(REL)../../.. +RELDIR=../plugins/pwd_qlty/plugin_pwd_qlty_X +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) +DEFS= + +LOCALINCLUDES = -I../../../include/krb5 -I. -I../../../plugin_core -I.. -I$(srcdir)/.. \ + -I../../../lib/kadm5 + +LIBBASE=plugin_pwd_qlty_X + +STLIBOBJS= plugin_pwd_qlty_X_impl.o server_dict.o +SRCS= $(srcdir)/plugin_pwd_qlty_X_impl.c $(srcdir)/server_dict.c + +STOBJLISTS=OBJS.ST + +all-unix:: all-liblinks +clean-unix:: clean-liblinks clean-libs clean-libobjs +install-unix:: install-libs + + +@libpriv_frag@ +@lib_frag@ +@libobj_frag@ diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty_X/deps b/src/plugins/pwd_qlty/plugin_pwd_qlty_X/deps new file mode 100644 index 0000000000..4690d7600e --- /dev/null +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty_X/deps @@ -0,0 +1,11 @@ +# +# Generated makefile dependencies follow. +# +plugin_pwd_qlty_X_impl.so plugin_pwd_qlty_X_impl.po $(OUTPRE)plugin_pwd_qlty_X_impl.$(OBJEXT): \ + $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) \ + $(top_srcdir)/plugins/pwd_qlty/plugin_pwd_qlty_X/plugin_pwd_qlty_X_impl.h \ + $(top_srcdir)/lib/kadm5/admin.h \ + $(top_srcdir)/plugin_core/plugin_manager.h \ + $(top_srcdir)/plugin_core/plugin_factory.h \ + plugin_pwd_qlty_X_impl.c + diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty_X/plugin_pwd_qlty_X_impl.c b/src/plugins/pwd_qlty/plugin_pwd_qlty_X/plugin_pwd_qlty_X_impl.c new file mode 100644 index 0000000000..cd99926f54 --- /dev/null +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty_X/plugin_pwd_qlty_X_impl.c @@ -0,0 +1,172 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +#include "k5-int.h" + +#include +#include +#include "plugin_pwd_qlty_X_impl.h" +#include +#include + + +#ifdef HESIOD +/* stolen from v4sever/kadm_funcs.c */ +static char * +reverse(str) + char *str; +{ + static char newstr[80]; + char *p, *q; + int i; + + i = strlen(str); + if (i >= sizeof(newstr)) + i = sizeof(newstr)-1; + p = str+i-1; + q = newstr; + q[i]='\0'; + for(; i > 0; i--) + *q++ = *p--; + + return(newstr); +} + +static int +str_check_gecos(gecos, pwstr) + char *gecos; + char *pwstr; +{ + char *cp, *ncp, *tcp; + + for (cp = gecos; *cp; ) { + /* Skip past punctuation */ + for (; *cp; cp++) + if (isalnum(*cp)) + break; + /* Skip to the end of the word */ + for (ncp = cp; *ncp; ncp++) + if (!isalnum(*ncp) && *ncp != '\'') + break; + /* Delimit end of word */ + if (*ncp) + *ncp++ = '\0'; + /* Check word to see if it's the password */ + if (*cp) { + if (!strcasecmp(pwstr, cp)) + return 1; + tcp = reverse(cp); + if (!strcasecmp(pwstr, tcp)) + return 1; + cp = ncp; + } else + break; + } + return 0; +} +#endif /* HESIOD */ + + +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) +{ + int nupper = 0, + nlower = 0, + ndigit = 0, + npunct = 0, + nspec = 0; + char c, *s, *cp; + +#ifdef HESIOD + extern struct passwd *hes_getpwnam(); + struct passwd *ent; +#endif + +#ifdef DEBUG_PLUGINS + printf("Plugin pwd qlty X\n"); +#endif + + if(use_policy) { + if(strlen(password) < (unsigned int)pol->pw_min_length) + return KADM5_PASS_Q_TOOSHORT; + s = password; + while ((c = *s++)) { + if (islower((unsigned char) c)) { + nlower = 1; + continue; + } + else if (isupper((unsigned char) c)) { + nupper = 1; + continue; + } else if (isdigit((unsigned char) c)) { + ndigit = 1; + continue; + } else if (ispunct((unsigned char) c)) { + npunct = 1; + continue; + } else { + nspec = 1; + continue; + } + } + if ((nupper + nlower + ndigit + npunct + nspec) < pol->pw_min_classes || nlower < 1) // Zh X-policy + return KADM5_PASS_Q_CLASS; + if((find_word(password) == KADM5_OK)) + return KADM5_PASS_Q_DICT; + else { + int i, n = krb5_princ_size(handle->context, principal); + cp = krb5_princ_realm(handle->context, principal)->data; + if (strcasecmp(cp, password) == 0) + return KADM5_PASS_Q_DICT; + for (i = 0; i < n ; i++) { + cp = krb5_princ_component(handle->context, principal, i)->data; + if (strcasecmp(cp, password) == 0) + return KADM5_PASS_Q_DICT; +#ifdef HESIOD + ent = hes_getpwnam(cp); + if (ent && ent->pw_gecos) + if (str_check_gecos(ent->pw_gecos, password)) + return KADM5_PASS_Q_DICT; /* XXX new error code? */ +#endif + } + return KADM5_OK; + } + } else { + if (strlen(password) < 1) + return KADM5_PASS_Q_TOOSHORT; + } + return KADM5_OK; + +} + +static kadm5_ret_t +_plugin_pwd_qlty_init(kadm5_server_handle_t handle) +{ + init_dict(&handle->params); + return 0; +} + +static void +_plugin_pwd_qlty_clean() +{ + destroy_dict(); + return; +} + +plhandle +plugin_pwd_qlty_X_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_X; + 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_X/plugin_pwd_qlty_X_impl.h b/src/plugins/pwd_qlty/plugin_pwd_qlty_X/plugin_pwd_qlty_X_impl.h new file mode 100644 index 0000000000..165a2438b9 --- /dev/null +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty_X/plugin_pwd_qlty_X_impl.h @@ -0,0 +1,14 @@ +/* + * plugin_pwd_qlty_X_impl.h + * + */ + +#ifndef PLUGIN_PWD_QLTY_X_IMPL_H_ +#define PLUGIN_PWD_QLTY_X_IMPL_H_ + +#include +#include + +plhandle plugin_pwd_qlty_X_create(void); + +#endif /* PLUGIN_PWD_QLTY_X_IMPL_H_ */ diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty_X/server_dict.c b/src/plugins/pwd_qlty/plugin_pwd_qlty_X/server_dict.c new file mode 100644 index 0000000000..46a30f1b6b --- /dev/null +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty_X/server_dict.c @@ -0,0 +1,203 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved + * + * $Header$ + */ + +#if !defined(lint) && !defined(__CODECENTER__) +static char *rcsid = "$Header$"; +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_MEMORY_H +#include +#endif +#include "adm_proto.h" +#include +#include "server_internal.h" +#include "k5-platform.h" + +static char **word_list = NULL; /* list of word pointers */ +static char *word_block = NULL; /* actual word data */ +static unsigned int word_count = 0; /* number of words */ + + +/* + * Function: word_compare + * + * Purpose: compare two words in the dictionary. + * + * Arguments: + * w1 (input) pointer to first word + * w2 (input) pointer to second word + * result of strcmp + * + * Requires: + * w1 and w2 to point to valid memory + * + */ + +static int +word_compare(const void *s1, const void *s2) +{ + return (strcasecmp(*(const char **)s1, *(const char **)s2)); +} + +/* + * Function: init-dict + * + * Purpose: Initialize in memory word dictionary + * + * Arguments: + * none + * KADM5_OK on success errno on failure; + * (but success on ENOENT) + * + * Requires: + * If WORDFILE exists, it must contain a list of words, + * one word per-line. + * + * Effects: + * If WORDFILE exists, it is read into memory sorted for future + * use. If it does not exist, it syslogs an error message and returns + * success. + * + * Modifies: + * word_list to point to a chunck of allocated memory containing + * pointers to words + * word_block to contain the dictionary. + * + */ + +int init_dict(kadm5_config_params *params) +{ + int fd, + len, + i; + char *p, + *t; + struct stat sb; + + if(word_list != NULL && word_block != NULL) + return KADM5_OK; + if (! (params->mask & KADM5_CONFIG_DICT_FILE)) { + return KADM5_OK; + } + if ((fd = open(params->dict_file, O_RDONLY)) == -1) { + if (errno == ENOENT) { + return KADM5_OK; + } else + return errno; + } + set_cloexec_fd(fd); + if (fstat(fd, &sb) == -1) { + close(fd); + return errno; + } + if ((word_block = (char *) malloc(sb.st_size + 1)) == NULL) + return ENOMEM; + if (read(fd, word_block, sb.st_size) != sb.st_size) + return errno; + (void) close(fd); + word_block[sb.st_size] = '\0'; + + p = word_block; + len = sb.st_size; + while(len > 0 && (t = memchr(p, '\n', len)) != NULL) { + *t = '\0'; + len -= t - p + 1; + p = t + 1; + word_count++; + } + if ((word_list = (char **) malloc(word_count * sizeof(char *))) == NULL) + return ENOMEM; + p = word_block; + for (i = 0; i < word_count; i++) { + word_list[i] = p; + p += strlen(p) + 1; + } + qsort(word_list, word_count, sizeof(char *), word_compare); + return KADM5_OK; +} + +/* + * Function: find_word + * + * Purpose: See if the specified word exists in the in-core dictionary + * + * Arguments: + * word (input) word to search for. + * WORD_NOT_FOUND if not in dictionary, + * KADM5_OK if if found word + * errno if init needs to be called and returns an + * error + * + * Requires: + * word to be a null terminated string. + * That word_list and word_block besetup + * + * Effects: + * finds word in dictionary. + * Modifies: + * nothing. + * + */ + +int +find_word(const char *word) +{ + char **value; + + if(word_list == NULL || word_block == NULL) + return WORD_NOT_FOUND; + if ((value = (char **) bsearch(&word, word_list, word_count, sizeof(char *), + word_compare)) == NULL) + return WORD_NOT_FOUND; + else + return KADM5_OK; +} + +/* + * Function: destroy_dict + * + * Purpose: destroy in-core copy of dictionary. + * + * Arguments: + * none + * none + * Requires: + * nothing + * Effects: + * frees up memory occupied by word_list and word_block + * sets count back to 0, and resets the pointers to NULL + * + * Modifies: + * word_list, word_block, and word_count. + * + */ + +void +destroy_dict(void) +{ + if(word_list) { + free(word_list); + word_list = NULL; + } + if(word_block) { + free(word_block); + word_block = NULL; + } + if(word_count) + word_count = 0; + return; +} diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/Makefile.in b/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/Makefile.in index f00cf9edc7..9c70c1bde8 100644 --- a/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/Makefile.in +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/Makefile.in @@ -10,8 +10,8 @@ LOCALINCLUDES = -I../../../include/krb5 -I. -I../../../plugin_core -I.. -I$(src LIBBASE=plugin_pwd_qlty_krb -STLIBOBJS= plugin_pwd_qlty_impl.o server_dict.o -SRCS= $(srcdir)/plugin_pwd_qlty_impl.c $(srcdir)/server_dict.c +STLIBOBJS= plugin_pwd_qlty_krb_impl.o server_dict.o +SRCS= $(srcdir)/plugin_pwd_qlty_krb_impl.c $(srcdir)/server_dict.c STOBJLISTS=OBJS.ST diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/deps b/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/deps index d2990c7347..1359c2d98e 100644 --- a/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/deps +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/deps @@ -1,11 +1,11 @@ # # Generated makefile dependencies follow. # -plugin_pwd_qlty_impl.so plugin_pwd_qlty_impl.po $(OUTPRE)plugin_pwd_qlty_impl.$(OBJEXT): \ +plugin_pwd_qlty_krb_impl.so plugin_pwd_qlty_krb_impl.po $(OUTPRE)plugin_pwd_qlty_krb_impl.$(OBJEXT): \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) \ - $(top_srcdir)/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_impl.h \ + $(top_srcdir)/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_krb_impl.h \ $(top_srcdir)/lib/kadm5/admin.h \ $(top_srcdir)/plugin_core/plugin_manager.h \ $(top_srcdir)/plugin_core/plugin_factory.h \ - plugin_pwd_qlty_impl.c + plugin_pwd_qlty_krb_impl.c diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_impl.h b/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_impl.h deleted file mode 100644 index b8bf2060a7..0000000000 --- a/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_impl.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * plugin_pwd_qlty_impl.h - * - */ - -#ifndef PLUGIN_PWD_QLTY_IMPL_H_ -#define PLUGIN_PWD_QLTY_IMPL_H_ - -#include -#include - -plhandle plugin_pwd_qlty_krb_create(void); - -#endif /* PLUGIN_PWD_QLTY_IMPL_H_ */ diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_impl.c b/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_krb_impl.c similarity index 95% rename from src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_impl.c rename to src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_krb_impl.c index 941a165280..f75e33783f 100644 --- a/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_impl.c +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_krb_impl.c @@ -4,7 +4,7 @@ #include #include -#include "plugin_pwd_qlty_impl.h" +#include "plugin_pwd_qlty_krb_impl.h" #include #include @@ -71,17 +71,22 @@ _plugin_pwd_qlty_check(kadm5_server_handle_t srv_handle, char *password, int use_policy, kadm5_policy_ent_t pol, krb5_principal principal) { - int nupper = 0, + int nupper = 0, nlower = 0, ndigit = 0, npunct = 0, - nspec = 0; + nspec = 0; char c, *s, *cp; #ifdef HESIOD extern struct passwd *hes_getpwnam(); struct passwd *ent; #endif + +#ifdef DEBUG_PLUGINS + printf("Plugin pwd qlty KRB\n"); +#endif + if(use_policy) { if(strlen(password) < (unsigned int)pol->pw_min_length) return KADM5_PASS_Q_TOOSHORT; @@ -157,6 +162,7 @@ plugin_pwd_qlty_krb_create() memset(api, 0, sizeof(plugin_pwd_qlty)); api->version = 1; + api->plugin_id = PWD_QLTY_KRB; api->pwd_qlty_init = _plugin_pwd_qlty_init; api->pwd_qlty_check = _plugin_pwd_qlty_check; api->pwd_qlty_cleanup = _plugin_pwd_qlty_clean; diff --git a/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_krb_impl.h b/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_krb_impl.h new file mode 100644 index 0000000000..89fc6b3228 --- /dev/null +++ b/src/plugins/pwd_qlty/plugin_pwd_qlty_krb/plugin_pwd_qlty_krb_impl.h @@ -0,0 +1,14 @@ +/* + * plugin_pwd_qlty_krb_impl.h + * + */ + +#ifndef PLUGIN_PWD_QLTY_KRB_IMPL_H_ +#define PLUGIN_PWD_QLTY_KRB_IMPL_H_ + +#include +#include + +plhandle plugin_pwd_qlty_krb_create(void); + +#endif /* PLUGIN_PWD_QLTY_KRB_IMPL_H_ */