s3-rpc_server: Added callbacks for init and shutdown of a rpc service.
authorAndreas Schneider <asn@samba.org>
Fri, 16 Jul 2010 12:52:42 +0000 (14:52 +0200)
committerAndreas Schneider <asn@samba.org>
Mon, 19 Jul 2010 10:59:18 +0000 (12:59 +0200)
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.

pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
source3/include/proto.h
source3/m4/aclocal.m4
source3/rpc_server/srv_pipe_register.c
source3/winbindd/winbindd.c
source3/wscript

index 0ea43e48ad5f802dbb738eb963dc0a48e76569ea..04475d26c9c53e4e2eff8d6c7162185575d44678 100644 (file)
@@ -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\__ */";
index a5b98cdc4de629d14c0449993a4f4d7a749fce29..d9f9ab96d46cb5d9e18f2fd79106f9f0e07128f9 100644 (file)
@@ -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);
index f7f3497a236130b78c48e3a783daa9abd461d7d0..3ca44bd496d27f042e3197689f8d3d6c9c982676 100644 (file)
@@ -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)
index c97edb15b54322cbe8b55d33b9c3e1710caa3674..3753596a2b135502d28f6fbee412ab8b7a999e74 100644 (file)
@@ -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;
 }
index 7e1eb3e71400cea8eaff9850a29f31ed983141d3..9efa8ed98453e17a94265ffe83f357905d7b014b 100644 (file)
@@ -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"));
index 0b31563343d62af3133f45f93638af1bfd74f3e3..66bddcf858068104bd95eea11e19e63cf666f686 100644 (file)
@@ -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, '{}')