summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2010-07-16 14:52:42 +0200
committerAndreas Schneider <asn@samba.org>2010-07-19 12:59:18 +0200
commit5cefbfef26bf2d5f470f1d8c52d75e9756c0f738 (patch)
treee68e42882b0dd51a29240ff936097ff0e6a54981
parentb91e5cf17d09e4e8bf73e78b96f69831a7cb0d0b (diff)
downloadsamba-5cefbfef26bf2d5f470f1d8c52d75e9756c0f738.tar.gz
samba-5cefbfef26bf2d5f470f1d8c52d75e9756c0f738.tar.bz2
samba-5cefbfef26bf2d5f470f1d8c52d75e9756c0f738.zip
s3-rpc_server: Added callbacks for init and shutdown of a rpc service.
This adds two callback function for each rpc service. One is for initialisation and the other for shutdown. rpc_<service>_unregister() needs to be called to execute the shutdown function.
-rw-r--r--pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm15
-rw-r--r--source3/include/proto.h20
-rw-r--r--source3/m4/aclocal.m410
-rw-r--r--source3/rpc_server/srv_pipe_register.c45
-rw-r--r--source3/winbindd/winbindd.c4
-rw-r--r--source3/wscript20
6 files changed, 97 insertions, 17 deletions
diff --git a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
index 0ea43e48ad..04475d26c9 100644
--- a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
+++ b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
@@ -257,10 +257,19 @@ sub ParseInterface($)
pidl "";
if (not has_property($if, "no_srv_register")) {
- pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(void);";
- pidl "NTSTATUS rpc_$if->{NAME}_init(void)";
+ pidl_hdr "struct rpc_srv_callbacks;";
+ pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(const struct rpc_srv_callbacks *rpc_srv_cb);";
+ pidl "NTSTATUS rpc_$if->{NAME}_init(const struct rpc_srv_callbacks *rpc_srv_cb)";
pidl "{";
- pidl "\treturn rpc_srv_register(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", \&ndr_table_$if->{NAME}, api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct));";
+ pidl "\treturn rpc_srv_register(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", \&ndr_table_$if->{NAME}, api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct), rpc_srv_cb);";
+ pidl "}";
+
+ pidl "";
+
+ pidl_hdr "NTSTATUS rpc_$if->{NAME}_shutdown(void);";
+ pidl "NTSTATUS rpc_$if->{NAME}_shutdown(void)";
+ pidl "{";
+ pidl "\treturn rpc_srv_unregister(\&ndr_table_$if->{NAME});";
pidl "}";
}
pidl_hdr "#endif /* __SRV_$uif\__ */";
diff --git a/source3/include/proto.h b/source3/include/proto.h
index a5b98cdc4d..d9f9ab96d4 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -5047,6 +5047,22 @@ void *_policy_handle_find(struct pipes_struct *p,
(_access_granted), #_type, __location__, (_pstatus))
+/* The following definitions come from rpc_server/srv_rpc_register.c */
+
+struct rpc_srv_callbacks {
+ bool (*init)(void *private_data);
+ bool (*shutdown)(void *private_data);
+ void *private_data;
+};
+
+NTSTATUS rpc_srv_register(int version, const char *clnt,
+ const char *srv,
+ const struct ndr_interface_table *iface,
+ const struct api_struct *cmds, int size,
+ const struct rpc_srv_callbacks *rpc_srv_cb);
+
+NTSTATUS rpc_srv_unregister(const struct ndr_interface_table *iface);
+
/* The following definitions come from rpc_server/srv_pipe.c */
bool create_next_pdu(pipes_struct *p);
@@ -5056,10 +5072,6 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt,
const char *srv,
const struct ndr_syntax_id *interface,
const struct api_struct *cmds, int size);
-NTSTATUS rpc_srv_register(int version, const char *clnt,
- const char *srv,
- const struct ndr_interface_table *iface,
- const struct api_struct *cmds, int size);
bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax);
bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt);
bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt);
diff --git a/source3/m4/aclocal.m4 b/source3/m4/aclocal.m4
index f7f3497a23..3ca44bd496 100644
--- a/source3/m4/aclocal.m4
+++ b/source3/m4/aclocal.m4
@@ -30,9 +30,17 @@ AC_DEFUN(SMB_MODULE,
AC_MSG_RESULT([shared])
[$6]
string_shared_modules="$string_shared_modules $1"
+ elif test x"$DEST" = xSTATIC && test x"$4" = xRPC; then
+ [init_static_modules_]translit([$4], [A-Z], [a-z])="$[init_static_modules_]translit([$4], [A-Z], [a-z]) $1_init(NULL);"
+ [decl_static_modules_]translit([$4], [A-Z], [a-z])="$[decl_static_modules_]translit([$4], [A-Z], [a-z]) extern NTSTATUS $1_init(const struct rpc_srv_callbacks *rpc_srv_cb);"
+ string_static_modules="$string_static_modules $1"
+ $4_STATIC="$$4_STATIC $2"
+ AC_SUBST($4_STATIC)
+ [$5]
+ AC_MSG_RESULT([static])
elif test x"$DEST" = xSTATIC; then
[init_static_modules_]translit([$4], [A-Z], [a-z])="$[init_static_modules_]translit([$4], [A-Z], [a-z]) $1_init();"
- [decl_static_modules_]translit([$4], [A-Z], [a-z])="$[decl_static_modules_]translit([$4], [A-Z], [a-z]) extern NTSTATUS $1_init(void);"
+ [decl_static_modules_]translit([$4], [A-Z], [a-z])="$[decl_static_modules_]translit([$4], [A-Z], [a-z]) extern NTSTATUS $1_init(void);"
string_static_modules="$string_static_modules $1"
$4_STATIC="$$4_STATIC $2"
AC_SUBST($4_STATIC)
diff --git a/source3/rpc_server/srv_pipe_register.c b/source3/rpc_server/srv_pipe_register.c
index c97edb15b5..3753596a2b 100644
--- a/source3/rpc_server/srv_pipe_register.c
+++ b/source3/rpc_server/srv_pipe_register.c
@@ -31,11 +31,26 @@ struct rpc_table {
struct ndr_syntax_id rpc_interface;
const struct api_struct *cmds;
uint32_t n_cmds;
+ bool (*shutdown_fn)(void *private_data);
+ void *shutdown_data;
};
static struct rpc_table *rpc_lookup;
static uint32_t rpc_lookup_size;
+static struct rpc_table *rpc_srv_get_pipe_by_id(const struct ndr_syntax_id *id)
+{
+ uint32_t i;
+
+ for (i = 0; i < rpc_lookup_size; i++) {
+ if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
+ return &rpc_lookup[i];
+ }
+ }
+
+ return NULL;
+}
+
bool rpc_srv_pipe_exists_by_id(const struct ndr_syntax_id *id)
{
uint32_t i;
@@ -150,7 +165,8 @@ bool rpc_srv_get_pipe_interface_by_cli_name(const char *cli_name,
NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv,
const struct ndr_interface_table *iface,
- const struct api_struct *cmds, int size)
+ const struct api_struct *cmds, int size,
+ const struct rpc_srv_callbacks *rpc_srv_cb)
{
struct rpc_table *rpc_entry;
@@ -194,5 +210,32 @@ NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv,
rpc_entry->cmds = cmds;
rpc_entry->n_cmds = size;
+ if (rpc_srv_cb != NULL) {
+ rpc_entry->shutdown_fn = rpc_srv_cb->shutdown;
+ rpc_entry->shutdown_data = rpc_srv_cb->private_data;
+
+ if (rpc_srv_cb->init != NULL &&
+ !rpc_srv_cb->init(rpc_srv_cb->private_data)) {
+ DEBUG(0, ("rpc_srv_register: Failed to call the %s "
+ "init function!\n", srv));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS rpc_srv_unregister(const struct ndr_interface_table *iface)
+{
+ struct rpc_table *rpc_entry = rpc_srv_get_pipe_by_id(&iface->syntax_id);
+
+ if (rpc_entry != NULL && rpc_entry->shutdown_fn != NULL) {
+ if (!rpc_entry->shutdown_fn(rpc_entry->shutdown_data)) {
+ DEBUG(0, ("rpc_srv_unregister: Failed to call the %s "
+ "init function!\n", rpc_entry->pipe.srv));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
return NT_STATUS_OK;
}
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 7e1eb3e714..9efa8ed984 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -1291,8 +1291,8 @@ int main(int argc, char **argv, char **envp)
winbindd_register_handlers();
- rpc_lsarpc_init();
- rpc_samr_init();
+ rpc_lsarpc_init(NULL);
+ rpc_samr_init(NULL);
if (!init_system_info()) {
DEBUG(0,("ERROR: failed to setup system user info.\n"));
diff --git a/source3/wscript b/source3/wscript
index 0b31563343..66bddcf858 100644
--- a/source3/wscript
+++ b/source3/wscript
@@ -321,12 +321,20 @@ utimensat vsyslog _write __write __xstat
conf.env[shared_env] = []
if p in static_list:
decl_list=""
- for entry in static_list[p]:
- decl_list += "extern NTSTATUS %s_init(void); " % entry
- conf.env[static_env].append('%s' % entry.upper())
- decl_list = decl_list.rstrip()
- conf.DEFINE('static_decl_%s' % p, decl_list)
- conf.DEFINE('static_init_%s' % p, '{ %s_init(); }' % '_init(); '.join(static_list[p]))
+ if p == "rpc":
+ for entry in static_list[p]:
+ decl_list += "extern NTSTATUS %s_init(const struct rpc_srv_callbacks *rpc_srv_cb); " % entry
+ conf.env[static_env].append('%s' % entry.upper())
+ decl_list = decl_list.rstrip()
+ conf.DEFINE('static_decl_%s' % p, decl_list)
+ conf.DEFINE('static_init_%s' % p, '{ %s_init(NULL); }' % '_init(NULL); '.join(static_list[p]))
+ else:
+ for entry in static_list[p]:
+ decl_list += "extern NTSTATUS %s_init(void); " % entry
+ conf.env[static_env].append('%s' % entry.upper())
+ decl_list = decl_list.rstrip()
+ conf.DEFINE('static_decl_%s' % p, decl_list)
+ conf.DEFINE('static_init_%s' % p, '{ %s_init(); }' % '_init(); '.join(static_list[p]))
else:
conf.DEFINE('static_decl_%s' % p, '')
conf.DEFINE('static_init_%s' % p, '{}')