From: Ralph Boehme Date: Sat, 24 Oct 2015 08:50:43 +0000 (+0200) Subject: s3:rpc_server: allow building RPC services as shared modules X-Git-Tag: talloc-2.1.6~243 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=593abe5f6bf3eefba35218214efb31907fa11bd7;p=thirdparty%2Fsamba.git s3:rpc_server: allow building RPC services as shared modules This is the general RPC subsystem change, existing modules must be tweaked to support being loaded as a module. The next commit shows how to do this for the Spotlight RPC service. The general syntax is: --with-shared-modules=rpc_NAME_module Signed-off-by: Ralph Boehme Reviewed-by: Guenther Deschner Reviewed-by: Andreas Schneider --- diff --git a/source3/rpc_server/rpc_modules.c b/source3/rpc_server/rpc_modules.c new file mode 100644 index 00000000000..69b5d03236b --- /dev/null +++ b/source3/rpc_server/rpc_modules.c @@ -0,0 +1,138 @@ +/* + * Unix SMB/CIFS implementation. + * + * SMBD RPC modules + * + * Copyright (c) 2015 Ralph Boehme + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" +#include "rpc_server/rpc_modules.h" + +static struct rpc_module *rpc_modules; + +struct rpc_module { + struct rpc_module *prev, *next; + char *name; + struct rpc_module_fns *fns; +}; + +static struct rpc_module *find_rpc_module(const char *name) +{ + struct rpc_module *module = NULL; + + for (module = rpc_modules; module != NULL; module = module->next) { + if (strequal(module->name, name)) { + return module; + } + } + + return NULL; +} + +NTSTATUS register_rpc_module(struct rpc_module_fns *fns, + const char *name) +{ + struct rpc_module *module = find_rpc_module(name); + + if (module != NULL) { + DBG_ERR("RPC module %s already loaded!\n", name); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + module = SMB_XMALLOC_P(struct rpc_module); + module->name = smb_xstrdup(name); + module->fns = fns; + + DLIST_ADD(rpc_modules, module); + DBG_NOTICE("Successfully added RPC module '%s'\n", name); + + return NT_STATUS_OK; +} + +bool setup_rpc_module(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, + const char *name) +{ + bool ok; + struct rpc_module *module = find_rpc_module(name); + + if (module == NULL) { + return false; + } + + ok = module->fns->setup(ev_ctx, msg_ctx); + if (!ok) { + DBG_ERR("calling setup for %s failed\n", name); + } + + return true; +} + +bool setup_rpc_modules(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx) +{ + bool ok; + struct rpc_module *module = rpc_modules; + + for (module = rpc_modules; module; module = module->next) { + ok = module->fns->setup(ev_ctx, msg_ctx); + if (!ok) { + DBG_ERR("calling setup for %s failed\n", module->name); + } + } + + return true; +} + +bool init_rpc_module(const char *name, + const struct rpc_srv_callbacks *rpc_srv_cb) +{ + struct rpc_module *module = find_rpc_module(name); + NTSTATUS status; + + if (module == NULL) { + return false; + } + + status = module->fns->init(rpc_srv_cb); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("calling init for %s failed %s\n", + name, nt_errstr(status)); + return false; + } + + return true; +} + +bool shutdown_rpc_module(const char *name) +{ + struct rpc_module *module = find_rpc_module(name); + NTSTATUS status; + + if (module == NULL) { + return false; + } + + status = module->fns->shutdown(); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("calling shutdown for %s failed %s\n", + name, nt_errstr(status)); + return false; + } + + return true; +} diff --git a/source3/rpc_server/rpc_modules.h b/source3/rpc_server/rpc_modules.h new file mode 100644 index 00000000000..afac1d911ca --- /dev/null +++ b/source3/rpc_server/rpc_modules.h @@ -0,0 +1,47 @@ +/* + * Unix SMB/CIFS implementation. + * + * SMBD RPC modules + * + * Copyright (c) 2015 Ralph Boehme + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _RPC_MODULES_H +#define _RPC_MODULES_H + +struct rpc_srv_callbacks; + +struct rpc_module_fns { + bool (*setup)(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx); + NTSTATUS (*init)(const struct rpc_srv_callbacks *rpc_srv_cb); + NTSTATUS (*shutdown)(void); +}; + +NTSTATUS register_rpc_module(struct rpc_module_fns *fns, + const char *name); + +bool setup_rpc_modules(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx); + +bool setup_rpc_module(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, + const char *name); + +bool init_rpc_module(const char *name, + const struct rpc_srv_callbacks *rpc_srv_cb); + +bool shutdown_rpc_module(const char *name); +#endif diff --git a/source3/rpc_server/rpc_service_setup.c b/source3/rpc_server/rpc_service_setup.c index ee995a805d1..3a4c0b08844 100644 --- a/source3/rpc_server/rpc_service_setup.c +++ b/source3/rpc_server/rpc_service_setup.c @@ -53,13 +53,16 @@ #include "rpc_server/rpc_ep_register.h" #include "rpc_server/rpc_server.h" #include "rpc_server/rpc_config.h" +#include "rpc_server/rpc_modules.h" #include "rpc_server/epmapper/srv_epmapper.h" +static_decl_rpc; + /* Common routine for embedded RPC servers */ -static bool rpc_setup_embedded(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - const struct ndr_interface_table *t, - const char *pipe_name) +bool rpc_setup_embedded(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, + const struct ndr_interface_table *t, + const char *pipe_name) { struct dcerpc_binding_vector *v; enum rpc_service_mode_e epm_mode = rpc_epmapper_mode(); @@ -500,6 +503,7 @@ bool dcesrv_ep_setup(struct tevent_context *ev_ctx, { TALLOC_CTX *tmp_ctx; bool ok; + init_module_fn *mod_init_fns = NULL; tmp_ctx = talloc_stackframe(); if (tmp_ctx == NULL) { @@ -585,6 +589,28 @@ bool dcesrv_ep_setup(struct tevent_context *ev_ctx, } #endif + /* Initialize static subsystems */ + static_init_rpc; + + /* Initialize shared modules */ + mod_init_fns = load_samba_modules(tmp_ctx, "rpc"); + if (mod_init_fns == NULL) { + DBG_ERR("Loading shared RPC modules failed\n"); + goto done; + } + + ok = run_init_functions(mod_init_fns); + if (!ok) { + DBG_ERR("Initializing shared RPC modules failed\n"); + goto done; + } + + ok = setup_rpc_modules(ev_ctx, msg_ctx); + if (!ok) { + DBG_ERR("Shared RPC modules setup failed\n"); + goto done; + } + done: talloc_free(tmp_ctx); return ok; diff --git a/source3/rpc_server/rpc_service_setup.h b/source3/rpc_server/rpc_service_setup.h index 2e27995261d..da89cbcbaba 100644 --- a/source3/rpc_server/rpc_service_setup.h +++ b/source3/rpc_server/rpc_service_setup.h @@ -23,6 +23,7 @@ #define _RPC_EP_SETUP_H struct ndr_interface_table; +struct rpc_srv_callbacks; /** * @brief Register an endpoint at the endpoint mapper. @@ -51,6 +52,11 @@ NTSTATUS rpc_ep_setup_register(struct tevent_context *ev_ctx, bool dcesrv_ep_setup(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx); +bool rpc_setup_embedded(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, + const struct ndr_interface_table *t, + const char *pipe_name); + #endif /* _RPC_EP_SETUP_H */ /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */ diff --git a/source3/rpc_server/wscript_build b/source3/rpc_server/wscript_build index 278e0bd924a..ae4c0613c1f 100755 --- a/source3/rpc_server/wscript_build +++ b/source3/rpc_server/wscript_build @@ -146,8 +146,9 @@ bld.SAMBA3_SUBSYSTEM('RPC_SERVER_REGISTER', deps='samba-util') bld.SAMBA3_SUBSYSTEM('RPC_SERVICE', - source='rpc_service_setup.c', + source='rpc_service_setup.c rpc_modules.c', deps=''' + rpc RPC_SERVER RPC_SERVER_REGISTER RPC_SAMR diff --git a/source3/wscript b/source3/wscript index c6fdb1bddb9..b65e3eb0cb7 100644 --- a/source3/wscript +++ b/source3/wscript @@ -1725,7 +1725,7 @@ main() { static_list = {} shared_list = {} - prefixes = ['vfs', 'pdb', 'auth', 'nss_info', 'charset', 'idmap', 'gpext', 'perfcount'] + prefixes = ['vfs', 'pdb', 'auth', 'nss_info', 'charset', 'idmap', 'gpext', 'perfcount', 'rpc'] conf.env['MODULE_PREFIXES'] = prefixes for p in prefixes: for m in final_static_modules: