diff options
author | Volker Lendecke <vl@samba.org> | 2009-11-01 12:05:14 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2009-11-07 09:14:16 +0100 |
commit | cd16e38e32013c8abb872c179c7f8bf33c92ed25 (patch) | |
tree | d06b3673c0d7a9e4a9baca946b0a6c9a173c16bc | |
parent | 268df12ab6b60052d4f5e8ff723f2528ace0dbfb (diff) | |
download | samba-cd16e38e32013c8abb872c179c7f8bf33c92ed25.tar.gz samba-cd16e38e32013c8abb872c179c7f8bf33c92ed25.tar.bz2 samba-cd16e38e32013c8abb872c179c7f8bf33c92ed25.zip |
s3: Register the ndr_interfaces dynamically
-rw-r--r-- | source3/include/proto.h | 5 | ||||
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 147 |
2 files changed, 114 insertions, 38 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 9328c927ee..e57ffdd571 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5703,8 +5703,11 @@ bool prs_data_blob(prs_struct *prs, DATA_BLOB *blob, TALLOC_CTX *mem_ctx); /* The following definitions come from rpc_parse/parse_rpc.c */ +bool smb_register_ndr_interface(const struct ndr_interface_table *interface); +const struct ndr_interface_table *get_iface_from_syntax( + const struct ndr_syntax_id *syntax); const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx, - const struct ndr_syntax_id *interface); + const struct ndr_syntax_id *syntax); void init_rpc_hdr(RPC_HDR *hdr, enum dcerpc_pkt_type pkt_type, uint8 flags, uint32 call_id, int data_len, int auth_len); bool smb_io_rpc_hdr(const char *desc, RPC_HDR *rpc, prs_struct *ps, int depth); diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7a05c9b5fb..9ff84f8b6d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -28,31 +28,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_CLI -/* - * IMPORTANT!! If you update this structure, make sure to - * update the index #defines in smb.h. - */ - -static const struct ndr_interface_table *pipe_names[] = -{ - &ndr_table_lsarpc, - &ndr_table_dssetup, - &ndr_table_samr, - &ndr_table_netlogon, - &ndr_table_srvsvc, - &ndr_table_wkssvc, - &ndr_table_winreg, - &ndr_table_spoolss, - &ndr_table_netdfs, - &ndr_table_rpcecho, - &ndr_table_initshutdown, - &ndr_table_svcctl, - &ndr_table_eventlog, - &ndr_table_ntsvcs, - &ndr_table_epmapper, - &ndr_table_drsuapi, -}; - static const char *get_pipe_name_from_iface( TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface) { @@ -80,25 +55,123 @@ static const char *get_pipe_name_from_iface( return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15); } +static const struct ndr_interface_table **interfaces; + +bool smb_register_ndr_interface(const struct ndr_interface_table *interface) +{ + int num_interfaces = talloc_array_length(interfaces); + const struct ndr_interface_table **tmp; + int i; + + for (i=0; i<num_interfaces; i++) { + if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, + &interface->syntax_id)) { + return true; + } + } + + tmp = talloc_realloc(NULL, interfaces, + const struct ndr_interface_table *, + num_interfaces + 1); + if (tmp == NULL) { + DEBUG(1, ("smb_register_ndr_interface: talloc failed\n")); + return false; + } + interfaces = tmp; + interfaces[num_interfaces] = interface; + return true; +} + +static bool initialize_interfaces(void) +{ + if (!smb_register_ndr_interface(&ndr_table_lsarpc)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_dssetup)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_samr)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_netlogon)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_srvsvc)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_wkssvc)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_winreg)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_spoolss)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_netdfs)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_rpcecho)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_initshutdown)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_svcctl)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_eventlog)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_epmapper)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_drsuapi)) { + return false; + } + return true; +} + +const struct ndr_interface_table *get_iface_from_syntax( + const struct ndr_syntax_id *syntax) +{ + int num_interfaces; + int i; + + if (interfaces == NULL) { + if (!initialize_interfaces()) { + return NULL; + } + } + num_interfaces = talloc_array_length(interfaces); + + for (i=0; i<num_interfaces; i++) { + if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) { + return interfaces[i]; + } + } + + return NULL; +} + /**************************************************************************** Return the pipe name from the interface. ****************************************************************************/ const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx, - const struct ndr_syntax_id *interface) + const struct ndr_syntax_id *syntax) { + const struct ndr_interface_table *interface; char *guid_str; const char *result; - int i; - for (i = 0; i<ARRAY_SIZE(pipe_names); i++) { - if (ndr_syntax_id_equal(&pipe_names[i]->syntax_id, - interface)) { - result = get_pipe_name_from_iface( - mem_ctx, pipe_names[i]); - if (result == NULL) { - break; - } + interface = get_iface_from_syntax(syntax); + if (interface != NULL) { + result = get_pipe_name_from_iface(mem_ctx, interface); + if (result != NULL) { return result; } } @@ -108,12 +181,12 @@ const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx, * interested in the known pipes mentioned in pipe_names[] */ - guid_str = GUID_string(talloc_tos(), &interface->uuid); + guid_str = GUID_string(talloc_tos(), &syntax->uuid); if (guid_str == NULL) { return NULL; } result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str, - (int)interface->if_version); + (int)syntax->if_version); TALLOC_FREE(guid_str); if (result == NULL) { |