diff options
Diffstat (limited to 'source3/rpc_server/srv_pipe.c')
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 101 |
1 files changed, 94 insertions, 7 deletions
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 5d8b7d39e9..588d6644b1 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -454,6 +454,41 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); The switch table for the pipe names and the functions to handle them. *******************************************************************/ +struct api_cmd +{ + const char *name; + int (*init)(void); +}; + +static struct api_cmd api_fd_commands[] = +{ +#ifndef RPC_LSA_DYNAMIC + { "lsarpc", rpc_lsa_init }, +#endif +#ifndef RPC_SAMR_DYNAMIC + { "samr", rpc_samr_init }, +#endif +#ifndef RPC_SVC_DYNAMIC + { "srvsvc", rpc_srv_init }, +#endif +#ifndef RPC_WKS_DYNAMIC + { "wkssvc", rpc_wks_init }, +#endif +#ifndef RPC_NETLOG_DYNAMIC + { "NETLOGON", rpc_net_init }, +#endif +#ifndef RPC_REG_DYNAMIC + { "winreg", rpc_reg_init }, +#endif +#ifndef RPC_SPOOLSS_DYNAMIC + { "spoolss", rpc_spoolss_init }, +#endif +#ifndef RPC_DFS_DYNAMIC + { "netdfs", rpc_dfs_init }, +#endif + { NULL, NULL } +}; + struct rpc_table { struct @@ -757,6 +792,47 @@ int rpc_pipe_register_commands(const char *clnt, const char *srv, const struct a } /******************************************************************* + Register commands to an RPC pipe +*******************************************************************/ +int rpc_load_module(const char *module) +{ +#ifdef HAVE_DLOPEN + void *handle; + int (*module_init)(void); + pstring full_path; + const char *error; + + pstrcpy(full_path, lib_path("rpc")); + pstrcat(full_path, "/librpc_"); + pstrcat(full_path, module); + pstrcat(full_path, "."); + pstrcat(full_path, shlib_ext()); + + handle = sys_dlopen(full_path, RTLD_LAZY); + if (!handle) { + DEBUG(0, ("Could not load requested pipe %s as %s\n", + module, full_path)); + DEBUG(0, (" Error: %s\n", dlerror())); + return 0; + } + + DEBUG(3, ("Module '%s' loaded\n", full_path)); + + module_init = sys_dlsym(handle, "rpc_pipe_init"); + if ((error = sys_dlerror()) != NULL) { + DEBUG(0, ("Error trying to resolve symbol 'rpc_pipe_init' in %s: %s\n", + full_path, error)); + return 0; + } + + return module_init(); +#else + DEBUG(0,("Attempting to load a dynamic RPC pipe when dlopen isn't available\n")); + return 0; +#endif +} + +/******************************************************************* Respond to a pipe bind request. *******************************************************************/ @@ -794,7 +870,14 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) } if (i == rpc_lookup_size) { - if (!smb_probe_module("rpc", p->name)) { + for (i = 0; api_fd_commands[i].name; i++) { + if (strequal(api_fd_commands[i].name, p->name)) { + api_fd_commands[i].init(); + break; + } + } + + if (!api_fd_commands[i].name && !rpc_load_module(p->name)) { DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", p->name )); if(!setup_bind_nak(p)) @@ -810,11 +893,6 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) break; } } - - if (i == rpc_lookup_size) { - DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name)); - return False; - } } /* decode the bind request */ @@ -1214,7 +1292,16 @@ BOOL api_pipe_request(pipes_struct *p) if (i == rpc_lookup_size) { - smb_probe_module("rpc", p->name); + for (i = 0; api_fd_commands[i].name; i++) { + if (strequal(api_fd_commands[i].name, p->name)) { + api_fd_commands[i].init(); + break; + } + } + + if (!api_fd_commands[i].name) { + rpc_load_module(p->name); + } for (i = 0; i < rpc_lookup_size; i++) { if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { |