svn rev #24149: branches/plugins/src/ lib/kadm5/srv/ lib/krb5/ plugin_core/impl/ ...
tsitkova@MIT.EDU
tsitkova at MIT.EDU
Mon Jun 28 17:32:54 EDT 2010
http://mv.ezproxy.com.ezproxyberklee.flo.org/fisheye/changelog/krb5/?cs=24149
Commit By: tsitkova
Log Message:
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.
Changed Files:
U branches/plugins/src/configure.in
U branches/plugins/src/lib/kadm5/srv/server_misc.c
U branches/plugins/src/lib/krb5/Makefile.in
U branches/plugins/src/plugin_core/impl/plugin_default_factory.c
U branches/plugins/src/plugin_core/impl/plugin_default_factory.h
U branches/plugins/src/plugin_core/impl/plugin_default_manager.c
A branches/plugins/src/plugin_dynamic/
A branches/plugins/src/plugin_dynamic/Makefile.in
A branches/plugins/src/plugin_dynamic/deps
A branches/plugins/src/plugin_dynamic/libplugin_dynamic.exports
A branches/plugins/src/plugin_dynamic/plugin_dyn_factory.c
A branches/plugins/src/plugin_dynamic/plugin_dyn_factory.h
U branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty.h
A branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/
A branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.c
A branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.h
Modified: branches/plugins/src/configure.in
===================================================================
--- branches/plugins/src/configure.in 2010-06-26 17:37:20 UTC (rev 24148)
+++ branches/plugins/src/configure.in 2010-06-28 21:32:54 UTC (rev 24149)
@@ -1123,6 +1123,7 @@
plugins/pa
plugins/pa/encrypted_challenge
plugin_core
+ plugin_dynamic
clients clients/klist clients/kinit clients/kvno
clients/kdestroy clients/kpasswd clients/ksu
Modified: branches/plugins/src/lib/kadm5/srv/server_misc.c
===================================================================
--- branches/plugins/src/lib/kadm5/srv/server_misc.c 2010-06-26 17:37:20 UTC (rev 24148)
+++ branches/plugins/src/lib/kadm5/srv/server_misc.c 2010-06-28 21:32:54 UTC (rev 24149)
@@ -65,6 +65,12 @@
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;
}
Modified: branches/plugins/src/lib/krb5/Makefile.in
===================================================================
--- branches/plugins/src/lib/krb5/Makefile.in 2010-06-26 17:37:20 UTC (rev 24148)
+++ branches/plugins/src/lib/krb5/Makefile.in 2010-06-28 21:32:54 UTC (rev 24149)
@@ -65,7 +65,7 @@
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)
Modified: branches/plugins/src/plugin_core/impl/plugin_default_factory.c
===================================================================
--- branches/plugins/src/plugin_core/impl/plugin_default_factory.c 2010-06-26 17:37:20 UTC (rev 24148)
+++ branches/plugins/src/plugin_core/impl/plugin_default_factory.c 2010-06-28 21:32:54 UTC (rev 24149)
@@ -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 @@
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 @@
factory_handle
-plugin_default_factory_get_instance()
+plugin_factory_get_instance()
{
plugin_factory* instance = _default_factory_instance;
factory_handle handle;
Modified: branches/plugins/src/plugin_core/impl/plugin_default_factory.h
===================================================================
--- branches/plugins/src/plugin_core/impl/plugin_default_factory.h 2010-06-26 17:37:20 UTC (rev 24148)
+++ branches/plugins/src/plugin_core/impl/plugin_default_factory.h 2010-06-28 21:32:54 UTC (rev 24149)
@@ -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_ */
Modified: branches/plugins/src/plugin_core/impl/plugin_default_manager.c
===================================================================
--- branches/plugins/src/plugin_core/impl/plugin_default_manager.c 2010-06-26 17:37:20 UTC (rev 24148)
+++ branches/plugins/src/plugin_core/impl/plugin_default_manager.c 2010-06-28 21:32:54 UTC (rev 24149)
@@ -5,6 +5,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+#include <dlfcn.h>
#include <plugin_manager.h>
#include <plugin_factory.h>
#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 @@
}
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
#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 @@
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) {
Added: branches/plugins/src/plugin_dynamic/Makefile.in
===================================================================
--- branches/plugins/src/plugin_dynamic/Makefile.in (rev 0)
+++ branches/plugins/src/plugin_dynamic/Makefile.in 2010-06-28 21:32:54 UTC (rev 24149)
@@ -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)
+
+ at lib_frag@
+ at libobj_frag@
+
Added: branches/plugins/src/plugin_dynamic/deps
===================================================================
--- branches/plugins/src/plugin_dynamic/deps (rev 0)
+++ branches/plugins/src/plugin_dynamic/deps 2010-06-28 21:32:54 UTC (rev 24149)
@@ -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
Added: branches/plugins/src/plugin_dynamic/libplugin_dynamic.exports
===================================================================
--- branches/plugins/src/plugin_dynamic/libplugin_dynamic.exports (rev 0)
+++ branches/plugins/src/plugin_dynamic/libplugin_dynamic.exports 2010-06-28 21:32:54 UTC (rev 24149)
@@ -0,0 +1,2 @@
+plugin_factory_get_instance
+plugin_pwd_qlty_DYN_create
Added: branches/plugins/src/plugin_dynamic/plugin_dyn_factory.c
===================================================================
--- branches/plugins/src/plugin_dynamic/plugin_dyn_factory.c (rev 0)
+++ branches/plugins/src/plugin_dynamic/plugin_dyn_factory.c 2010-06-28 21:32:54 UTC (rev 24149)
@@ -0,0 +1,67 @@
+/*
+ * plugin_dyn_factory.c
+ *
+ */
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <plugin_manager.h>
+#include <plugin_factory.h>
+#include <plugin_dyn_factory.h>
+
+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);
+}
+
Added: branches/plugins/src/plugin_dynamic/plugin_dyn_factory.h
===================================================================
--- branches/plugins/src/plugin_dynamic/plugin_dyn_factory.h (rev 0)
+++ branches/plugins/src/plugin_dynamic/plugin_dyn_factory.h 2010-06-28 21:32:54 UTC (rev 24149)
@@ -0,0 +1,16 @@
+/*
+ * plugin_dyn_factory.h
+ *
+ */
+
+#ifndef PLUGIN_DYN_FACTORY_H_
+#define PLUGIN_DYN_FACTORY_H_
+
+#include <plugin_factory.h>
+#include "plugin_pwd_qlty_DYN_impl.h"
+
+
+factory_handle plugin_factory_get_instance(void);
+
+
+#endif /* PLUGIN_DYN_FACTORY_H_ */
Modified: branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty.h
===================================================================
--- branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty.h 2010-06-26 17:37:20 UTC (rev 24148)
+++ branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty.h 2010-06-28 21:32:54 UTC (rev 24149)
@@ -13,6 +13,7 @@
#define PWD_QLTY_KRB 0
#define PWD_QLTY_X 1
+#define PWD_QLTY_DYN 33
/* PWD_QLTY API */
typedef struct {
Added: branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.c
===================================================================
--- branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.c (rev 0)
+++ branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.c 2010-06-28 21:32:54 UTC (rev 24149)
@@ -0,0 +1,53 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+
+#include "k5-int.h"
+
+#include <plugin_manager.h>
+#include <plugin_pwd_qlty.h>
+#include "plugin_pwd_qlty_DYN_impl.h"
+#include <string.h>
+#include <ctype.h>
+
+
+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;
+}
Added: branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.h
===================================================================
--- branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.h (rev 0)
+++ branches/plugins/src/plugins/pwd_qlty/plugin_pwd_qlty_DYN/plugin_pwd_qlty_DYN_impl.h 2010-06-28 21:32:54 UTC (rev 24149)
@@ -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 <plugin_manager.h>
+#include <plugin_pwd_qlty.h>
+
+plhandle plugin_pwd_qlty_DYN_create(void);
+
+#endif /* PLUGIN_PWD_QLTY_DYN_IMPL_H_ */
More information about the cvs-krb5
mailing list