summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-11-01 12:05:14 +0100
committerVolker Lendecke <vl@samba.org>2009-11-07 09:14:16 +0100
commitcd16e38e32013c8abb872c179c7f8bf33c92ed25 (patch)
treed06b3673c0d7a9e4a9baca946b0a6c9a173c16bc
parent268df12ab6b60052d4f5e8ff723f2528ace0dbfb (diff)
downloadsamba-cd16e38e32013c8abb872c179c7f8bf33c92ed25.tar.gz
samba-cd16e38e32013c8abb872c179c7f8bf33c92ed25.tar.bz2
samba-cd16e38e32013c8abb872c179c7f8bf33c92ed25.zip
s3: Register the ndr_interfaces dynamically
-rw-r--r--source3/include/proto.h5
-rw-r--r--source3/rpc_client/cli_pipe.c147
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) {