summaryrefslogtreecommitdiff
path: root/source3/sam/gums.c
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2003-10-13 21:26:10 +0000
committerSimo Sorce <idra@samba.org>2003-10-13 21:26:10 +0000
commit5733f731a911478492315af288c1a674ec038452 (patch)
treeb42248f3a4780ae663ee37d465cb5e9fa89bb224 /source3/sam/gums.c
parent0bb70fe0b43fa9e9615e405b12c2adbb4ff04594 (diff)
downloadsamba-5733f731a911478492315af288c1a674ec038452.tar.gz
samba-5733f731a911478492315af288c1a674ec038452.tar.bz2
samba-5733f731a911478492315af288c1a674ec038452.zip
So here it is a non-intrusive patch with my latest work on gums (the
laternative to the current passdb). Currently it is run through a comatibility module in the passdb layer, with a subset of the functionality it may provide. It is still work in progress, but as someone asked me about it, and as it should make no difference to the normal code, I tought it was a good idea to put it into. It adds a dependency on perl. I know it is not very nice, but I'm sure we will work out a solution for that. As always blame me if I break something, but try to fix yourself, as I am busy-busy-busy :-) Simo. (This used to be commit 7b3c94b5cfc1a9ceb430613353a937345f2eda74)
Diffstat (limited to 'source3/sam/gums.c')
-rw-r--r--source3/sam/gums.c171
1 files changed, 122 insertions, 49 deletions
diff --git a/source3/sam/gums.c b/source3/sam/gums.c
index a118740637..ab374b9342 100644
--- a/source3/sam/gums.c
+++ b/source3/sam/gums.c
@@ -20,8 +20,8 @@
#include "includes.h"
-/*#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_GUMS*/
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_SAM
#define GMV_MAJOR 0
#define GMV_MINOR 1
@@ -56,8 +56,7 @@
#define PRIV_ALL 255
-GUMS_FUNCTIONS *gums_storage;
-static void *dl_handle;
+static GUMS_FUNCTIONS *gums_backend = NULL;
static PRIVS gums_privs[] = {
{PRIV_NONE, "no_privs", "No privilege"}, /* this one MUST be first */
@@ -90,72 +89,146 @@ static PRIVS gums_privs[] = {
{PRIV_ALL, "SaAllPrivs", "All Privileges"}
};
-NTSTATUS gums_init(const char *module_name)
+static struct gums_init_function_entry *backends = NULL;
+
+static void lazy_initialize_gums(void)
{
- int (*module_version)(int);
- NTSTATUS (*module_init)();
-/* gums_module_init module_init;*/
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ static BOOL initialized = False;
+
+ if (initialized)
+ return;
- DEBUG(5, ("Opening gums module %s\n", module_name));
- dl_handle = sys_dlopen(module_name, RTLD_NOW);
- if (!dl_handle) {
- DEBUG(0, ("ERROR: Failed to load gums module %s, error: %s\n", module_name, sys_dlerror()));
- return NT_STATUS_UNSUCCESSFUL;
- }
+ static_init_gums;
+ initialized = True;
+}
- module_version = sys_dlsym(dl_handle, "gumm_version");
- if (!module_version) {
- DEBUG(0, ("ERROR: Failed to find gums module version!\n"));
- goto error;
- }
+static struct gums_init_function_entry *gums_find_backend_entry(const char *name);
+
+NTSTATUS gums_register_module(int version, const char *name, gums_init_function init_fn)
+{
+ struct gums_init_function_entry *entry = backends;
+
+ if (version != GUMS_INTERFACE_VERSION) {
+ DEBUG(0,("Can't register gums backend!\n"
+ "You tried to register a gums module with"
+ "GUMS_INTERFACE_VERSION %d, while this version"
+ "of samba uses version %d\n", version,
+ GUMS_INTERFACE_VERSION));
- if (module_version(GMV_MAJOR) != GUMS_VERSION_MAJOR) {
- DEBUG(0, ("ERROR: Module's major version does not match gums version!\n"));
- goto error;
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
}
- if (module_version(GMV_MINOR) != GUMS_VERSION_MINOR) {
- DEBUG(1, ("WARNING: Module's minor version does not match gums version!\n"));
+ if (!name || !init_fn) {
+ return NT_STATUS_INVALID_PARAMETER;
}
- module_init = sys_dlsym(dl_handle, "gumm_init");
- if (!module_init) {
- DEBUG(0, ("ERROR: Failed to find gums module's init function!\n"));
- goto error;
+ DEBUG(5,("Attempting to register gums backend %s\n", name));
+
+ /* Check for duplicates */
+ if (gums_find_backend_entry(name)) {
+ DEBUG(0,("There already is a gums backend registered"
+ "with the name %s!\n", name));
+ return NT_STATUS_OBJECT_NAME_COLLISION;
}
- DEBUG(5, ("Initializing module %s\n", module_name));
+ entry = smb_xmalloc(sizeof(struct gums_init_function_entry));
+ entry->name = smb_xstrdup(name);
+ entry->init_fn = init_fn;
- ret = module_init(&gums_storage);
- goto done;
+ DLIST_ADD(backends, entry);
+ DEBUG(5,("Successfully added gums backend '%s'\n", name));
+ return NT_STATUS_OK;
+}
-error:
- ret = NT_STATUS_UNSUCCESSFUL;
- sys_dlclose(dl_handle);
+static struct gums_init_function_entry *gums_find_backend_entry(const char *name)
+{
+ struct gums_init_function_entry *entry = backends;
-done:
- return ret;
+ while (entry) {
+ if (strcmp(entry->name, name) == 0)
+ return entry;
+ entry = entry->next;
+ }
+
+ return NULL;
}
-NTSTATUS gums_unload(void)
+NTSTATUS gums_setup_backend(const char *backend)
{
- NTSTATUS ret;
- NTSTATUS (*module_finalize)();
- if (!dl_handle)
- return NT_STATUS_UNSUCCESSFUL;
+ TALLOC_CTX *mem_ctx;
+ char *module_name = smb_xstrdup(backend);
+ char *p, *module_data = NULL;
+ struct gums_init_function_entry *entry;
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+ lazy_initialize_gums();
+
+ p = strchr(module_name, ':');
+ if (p) {
+ *p = 0;
+ module_data = p+1;
+ trim_string(module_data, " ", " ");
+ }
+
+ trim_string(module_name, " ", " ");
- module_finalize = sys_dlsym(dl_handle, "gumm_finalize");
- if (!module_finalize) {
- DEBUG(0, ("ERROR: Failed to find gums module's init function!\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ DEBUG(5,("Attempting to find a gums backend to match %s (%s)\n", backend, module_name));
+
+ entry = gums_find_backend_entry(module_name);
+
+ /* Try to find a module that contains this module */
+ if (!entry) {
+ DEBUG(2,("No builtin backend found, trying to load plugin\n"));
+ if(NT_STATUS_IS_OK(smb_probe_module("gums", module_name)) && !(entry = gums_find_backend_entry(module_name))) {
+ DEBUG(0,("Plugin is available, but doesn't register gums backend %s\n", module_name));
+ SAFE_FREE(module_name);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
}
- DEBUG(5, ("Finalizing module"));
+ /* No such backend found */
+ if(!entry) {
+ DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name));
+ SAFE_FREE(module_name);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- ret = module_finalize();
- sys_dlclose(dl_handle);
+ DEBUG(5,("Found gums backend %s\n", module_name));
+ /* free current functions structure if any */
+ if (gums_backend) {
+ gums_backend->free_private_data(gums_backend->private_data);
+ talloc_destroy(gums_backend->mem_ctx);
+ gums_backend = NULL;
+ }
+
+ /* allocate a new GUMS_FUNCTIONS structure and memory context */
+ mem_ctx = talloc_init("gums_backend (%s)", module_name);
+ if (!mem_ctx)
+ return NT_STATUS_NO_MEMORY;
+ gums_backend = talloc(mem_ctx, sizeof(GUMS_FUNCTIONS));
+ if (!gums_backend)
+ return NT_STATUS_NO_MEMORY;
+ gums_backend->mem_ctx = mem_ctx;
+
+ /* init the requested backend module */
+ if (NT_STATUS_IS_OK(ret = entry->init_fn(gums_backend, module_data))) {
+ DEBUG(5,("gums backend %s has a valid init\n", backend));
+ } else {
+ DEBUG(0,("gums backend %s did not correctly init (error was %s)\n", backend, nt_errstr(ret)));
+ }
+ SAFE_FREE(module_name);
return ret;
}
+
+NTSTATUS get_gums_fns(GUMS_FUNCTIONS **fns)
+{
+ if (gums_backend != NULL) {
+ *fns = gums_backend;
+ return NT_STATUS_OK;
+ }
+
+ DEBUG(2, ("get_gums_fns: unable to get gums functions! backend uninitialized?\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+}