added auto-generation of the server side boilerplate code for each
authorAndrew Tridgell <tridge@samba.org>
Sun, 14 Dec 2003 13:22:12 +0000 (13:22 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sun, 14 Dec 2003 13:22:12 +0000 (13:22 +0000)
pipe.

The server side code gets generated as librpc/gen_ndr/ndr_NAME_s.c and
gets included in the pipe module
(This used to be commit bd3dcfe5820489a838e19b244266bd9126af5eb4)

source4/build/pidl/header.pm
source4/build/pidl/pidl.pl
source4/build/pidl/server.pm [new file with mode: 0644]
source4/build/pidl/util.pm
source4/librpc/idl/echo.idl
source4/rpc_server/dcerpc_server.c
source4/rpc_server/echo/rpc_echo.c
source4/rpc_server/epmapper/rpc_epmapper.c
source4/script/build_idl.sh
source4/torture/rpc/echo.c
source4/torture/torture.c

index 32775254876985ccb3d0fcf8458df893c64a77a5..4fa5969d3f1167800523b55d2f3ecec44015ba20 100644 (file)
@@ -239,7 +239,8 @@ sub HeaderInterface($)
            $res .= "#define DCERPC_$name\_UUID \"$if_uuid\"\n";
            $res .= "#define DCERPC_$name\_VERSION $if_version\n";
            $res .= "#define DCERPC_$name\_NAME \"$interface->{NAME}\"\n\n";
-           $res .= "extern const struct dcerpc_interface_table dcerpc_table_$interface->{NAME};\n\n";
+           $res .= "extern const struct dcerpc_interface_table dcerpc_table_$interface->{NAME};\n";
+           $res .= "void rpc_$interface->{NAME}_init(void *);\n\n";
     }
 
     foreach my $d (@{$data}) {
index 30dcde929acd897ae13c8ceb5adbbf7eef3f0946..ce8250826a81c99a4705e00adb7197e81bd1c728 100755 (executable)
@@ -16,6 +16,7 @@ use File::Basename;
 use idl;
 use dump;
 use header;
+use server;
 use parser;
 use eparser;
 use validator;
@@ -26,6 +27,7 @@ my($opt_parse) = 0;
 my($opt_dump) = 0;
 my($opt_diff) = 0;
 my($opt_header) = 0;
+my($opt_server) = 0;
 my($opt_parser) = 0;
 my($opt_eparser) = 0;
 my($opt_keep) = 0;
@@ -61,6 +63,7 @@ sub ShowHelp()
              --dump                dump a pidl file back to idl
              --header              create a C header file
              --parser              create a C parser
+             --server              create server boilterplate
              --eparser             create an ethereal parser
              --diff                run diff on the idl and dumped output
              --keep                keep the .pidl file
@@ -75,6 +78,7 @@ GetOptions (
            'parse' => \$opt_parse,
            'dump' => \$opt_dump,
            'header' => \$opt_header,
+           'server' => \$opt_server,
            'parser' => \$opt_parser,
            'eparser' => \$opt_eparser,
            'diff' => \$opt_diff,
@@ -100,7 +104,7 @@ sub process_file($)
                $output = $opt_output . $basename;
        }
 
-       my($pidl_file) = util::ChangeExtension($output, "pidl");
+       my($pidl_file) = util::ChangeExtension($output, ".pidl");
 
        print "Compiling $idl_file\n";
 
@@ -120,22 +124,27 @@ sub process_file($)
        }
        
        if ($opt_header) {
-               my($header) = util::ChangeExtension($output, "h");
+               my($header) = util::ChangeExtension($output, ".h");
                util::FileSave($header, IdlHeader::Parse($pidl));
        }
+
+       if ($opt_server) {
+               my($server) = util::ChangeExtension($output, "_s.c");
+               util::FileSave($server, IdlServer::Parse($pidl));
+       }
        
        if ($opt_parser) {
-               my($parser) = util::ChangeExtension($output, "c");
+               my($parser) = util::ChangeExtension($output, ".c");
                IdlParser::Parse($pidl, $parser);
        }
        
        if ($opt_eparser) {
-               my($parser) = util::ChangeExtension($output, "c");
+               my($parser) = util::ChangeExtension($output, ".c");
                util::FileSave($parser, IdlEParser::Parse($pidl));
        }
        
        if ($opt_diff) {
-               my($tempfile) = util::ChangeExtension($output, "tmp");
+               my($tempfile) = util::ChangeExtension($output, ".tmp");
                util::FileSave($tempfile, IdlDump::Dump($pidl));
                system("diff -wu $idl_file $tempfile");
                unlink($tempfile);
diff --git a/source4/build/pidl/server.pm b/source4/build/pidl/server.pm
new file mode 100644 (file)
index 0000000..e6d996b
--- /dev/null
@@ -0,0 +1,108 @@
+
+
+###################################################
+# server boilerplate generator
+# Copyright tridge@samba.org 2003
+# released under the GNU GPL
+
+package IdlServer;
+
+use strict;
+use Data::Dumper;
+
+my($res);
+
+sub pidl($)
+{
+       $res .= shift;
+}
+
+#####################################################################
+# produce boilerplate code for a interface
+sub Boilerplate($)
+{
+       my($interface) = shift;
+       my($data) = $interface->{DATA};
+       my $count = 0;
+       my $name = $interface->{NAME};
+       my $uname = uc $name;
+
+       foreach my $d (@{$data}) {
+               if ($d->{TYPE} eq "FUNCTION") { $count++; }
+       }
+
+       if ($count == 0) {
+               return;
+       }
+
+       pidl "static const dcesrv_dispatch_fn_t dispatch_table[] = {\n";
+       foreach my $d (@{$data}) {
+               if ($d->{TYPE} eq "FUNCTION") {
+                       pidl "\t(dcesrv_dispatch_fn_t)$d->{NAME},\n";
+               }
+       }
+       pidl "\tNULL};\n\n";
+
+       pidl "
+static BOOL op_query_endpoint(const struct dcesrv_endpoint *ep)
+{
+       return dcesrv_table_query(&dcerpc_table_$name, ep);
+}
+
+static BOOL op_set_interface(struct dcesrv_state *dce, 
+                            const char *uuid, uint32 if_version)
+{
+       return dcesrv_set_interface(dce, uuid, if_version, 
+                                   &dcerpc_table_$name, dispatch_table);
+}
+
+static NTSTATUS op_connect(struct dcesrv_state *dce)
+{
+       return NT_STATUS_OK;
+}
+
+static void op_disconnect(struct dcesrv_state *dce)
+{
+       /* nothing to do */
+}
+
+static int op_lookup_endpoints(TALLOC_CTX *mem_ctx, struct dcesrv_ep_iface **e)
+{
+       return dcesrv_lookup_endpoints(&dcerpc_table_$name, mem_ctx, e);
+}
+
+static const struct dcesrv_endpoint_ops $name\_ops = {
+       op_query_endpoint,
+       op_set_interface,
+       op_connect,
+       op_disconnect,
+       op_lookup_endpoints
+};
+
+void rpc_$name\_init(void *v)
+{
+       struct dcesrv_context *dce = v;
+       if (!dcesrv_endpoint_register(dce, &$name\_ops, 
+                                     &dcerpc_table_$name)) {
+               DEBUG(1,(\"Failed to register rpcecho endpoint\\n\"));
+       }
+}
+";
+}
+
+
+#####################################################################
+# parse a parsed IDL structure back into an IDL file
+sub Parse($)
+{
+       my($idl) = shift;
+       $res = "/* dcerpc server boilerplate generated by pidl */\n\n";
+       foreach my $x (@{$idl}) {
+               ($x->{TYPE} eq "INTERFACE") && 
+                   Boilerplate($x);
+       }
+       return $res;
+}
+
+1;
+
index 57ce80253f1c68773031dabbded0e0f6fcbd8eb5..dc6fd35f0c4636b9c6d1bfddb3a083680844232a 100644 (file)
@@ -127,9 +127,9 @@ sub ChangeExtension($$)
     my($fname) = shift;
     my($ext) = shift;
     if ($fname =~ /^(.*)\.(.*?)$/) {
-       return "$1.$ext";
+       return "$1$ext";
     }
-    return "$fname.$ext";
+    return "$fname$ext";
 }
 
 #####################################################################
index d747a39f23a0c9a46a69cb5c41f87b96ef74ff1d..e62208ac98a44355dc8cb36633f229e21f945771 100644 (file)
@@ -31,7 +31,7 @@ interface rpcecho
 
 
        /* test strings */
-       void TestCall (
+       void echo_TestCall (
                [in]       unistr *s1,
                [out]      unistr *s2
                );
@@ -83,7 +83,7 @@ interface rpcecho
                [case(7)]  echo_info7 info7;
        } echo_Info;
 
-       NTSTATUS TestCall2 (
+       NTSTATUS echo_TestCall2 (
                     [in]                    uint16 level,
                     [out,switch_is(level)]  echo_Info *info
                );
index a34c00cd58804a905013335aaae3e02d06350c44..cbde3c953259bf106a4ff34f4806bb14ae39ff20 100644 (file)
@@ -792,12 +792,28 @@ int dcesrv_lookup_endpoints(const struct dcerpc_interface_table *table,
 }
 
 
+BOOL dcesrv_set_interface(struct dcesrv_state *dce, 
+                         const char *uuid, uint32 if_version,
+                         const struct dcerpc_interface_table *table,
+                         const dcesrv_dispatch_fn_t *dispatch_table)
+{
+       if (strcasecmp(table->uuid, uuid) != 0 || if_version != table->if_version) {
+               DEBUG(2,("Attempt to use unknown interface %s/%d\n", uuid, if_version));
+               return False;
+       }
+
+       dce->ndr = table;
+       dce->dispatch = dispatch_table;
+       return True;
+}
+
+
 /*
   initialise the dcerpc server subsystem
 */
 BOOL dcesrv_init(struct dcesrv_context *dce)
 {
-       rpc_echo_init(dce);
+       rpc_rpcecho_init(dce);
        rpc_epmapper_init(dce);
        return True;
 }
index d62ebc3d26014de7a82f4f04fc6c3501d5e6de72..1d3846aaffab2203f78e07a48a696d1aea83f16e 100644 (file)
@@ -55,14 +55,14 @@ static NTSTATUS echo_SourceData(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx, s
        return NT_STATUS_OK;
 }
 
-static NTSTATUS echo_TestCall(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx, struct TestCall *r)
+static NTSTATUS echo_TestCall(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx, struct echo_TestCall *r)
 {
        r->out.s2 = "this is a test string";
        
        return NT_STATUS_OK;
 }
 
-static NTSTATUS echo_TestCall2(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx, struct TestCall2 *r)
+static NTSTATUS echo_TestCall2(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx, struct echo_TestCall2 *r)
 {
        r->out.info = talloc(mem_ctx, sizeof(*r->out.info));
        if (!r->out.info) {
@@ -109,79 +109,5 @@ static NTSTATUS echo_TestCall2(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx, st
 }
 
 
-
-
-/**************************************************************************
-  all the code below this point is boilerplate that will be auto-generated
-***************************************************************************/
-
-static const dcesrv_dispatch_fn_t dispatch_table[] = {
-       (dcesrv_dispatch_fn_t)echo_AddOne,
-       (dcesrv_dispatch_fn_t)echo_EchoData,
-       (dcesrv_dispatch_fn_t)echo_SinkData,
-       (dcesrv_dispatch_fn_t)echo_SourceData,
-       (dcesrv_dispatch_fn_t)echo_TestCall,
-       (dcesrv_dispatch_fn_t)echo_TestCall2
-};
-
-
-/*
-  return True if we want to handle the given endpoint
-*/
-static BOOL op_query_endpoint(const struct dcesrv_endpoint *ep)
-{
-       return dcesrv_table_query(&dcerpc_table_rpcecho, ep);
-}
-
-/*
-  setup for a particular rpc interface
-*/
-static BOOL op_set_interface(struct dcesrv_state *dce, const char *uuid, uint32 if_version)
-{
-       if (strcasecmp(uuid, dcerpc_table_rpcecho.uuid) != 0 ||
-           if_version != dcerpc_table_rpcecho.if_version) {
-               DEBUG(2,("Attempt to use unknown interface %s/%d\n", uuid, if_version));
-               return False;
-       }
-
-       dce->ndr = &dcerpc_table_rpcecho;
-       dce->dispatch = dispatch_table;
-
-       return True;
-}
-
-
-/* op_connect is called when a connection is made to an endpoint */
-static NTSTATUS op_connect(struct dcesrv_state *dce)
-{
-       return NT_STATUS_OK;
-}
-
-static void op_disconnect(struct dcesrv_state *dce)
-{
-       /* nothing to do */
-}
-
-
-static int op_lookup_endpoints(TALLOC_CTX *mem_ctx, struct dcesrv_ep_iface **e)
-{
-       return dcesrv_lookup_endpoints(&dcerpc_table_rpcecho, mem_ctx, e);
-}
-
-static const struct dcesrv_endpoint_ops rpc_echo_ops = {
-       op_query_endpoint,
-       op_set_interface,
-       op_connect,
-       op_disconnect,
-       op_lookup_endpoints
-};
-
-/*
-  register with the dcerpc server
-*/
-void rpc_echo_init(struct dcesrv_context *dce)
-{
-       if (!dcesrv_endpoint_register(dce, &rpc_echo_ops, &dcerpc_table_rpcecho)) {
-               DEBUG(1,("Failed to register rpcecho endpoint\n"));
-       }
-}
+/* include the generated boilerplate */
+#include "librpc/gen_ndr/ndr_echo_s.c"
index 43e4d4514f8b2c9d5d0b18f7f5df719d28f86bdc..f2ecc0faa99b64889909c461d48e09295c8f1068 100644 (file)
@@ -319,79 +319,5 @@ static NTSTATUS epm_MgmtDelete(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
 }
 
 
-/**************************************************************************
-  all the code below this point is boilerplate that will be auto-generated
-***************************************************************************/
-
-static const dcesrv_dispatch_fn_t dispatch_table[] = {
-       (dcesrv_dispatch_fn_t)epm_Insert,
-       (dcesrv_dispatch_fn_t)epm_Delete,
-       (dcesrv_dispatch_fn_t)epm_Lookup,
-       (dcesrv_dispatch_fn_t)epm_Map,
-       (dcesrv_dispatch_fn_t)epm_LookupHandleFree,
-       (dcesrv_dispatch_fn_t)epm_InqObject,
-       (dcesrv_dispatch_fn_t)epm_MgmtDelete
-};
-
-
-/*
-  return True if we want to handle the given endpoint
-*/
-static BOOL op_query_endpoint(const struct dcesrv_endpoint *ep)
-{
-       return dcesrv_table_query(&dcerpc_table_epmapper, ep);
-}
-
-/*
-  setup for a particular rpc interface
-*/
-static BOOL op_set_interface(struct dcesrv_state *dce, const char *uuid, uint32 if_version)
-{
-       if (strcasecmp(uuid, dcerpc_table_epmapper.uuid) != 0 ||
-           if_version != dcerpc_table_epmapper.if_version) {
-               DEBUG(2,("Attempt to use unknown interface %s/%d\n", uuid, if_version));
-               return False;
-       }
-
-       dce->ndr = &dcerpc_table_epmapper;
-       dce->dispatch = dispatch_table;
-
-       return True;
-}
-
-
-/* op_connect is called when a connection is made to an endpoint */
-static NTSTATUS op_connect(struct dcesrv_state *dce)
-{
-       return NT_STATUS_OK;
-}
-
-static void op_disconnect(struct dcesrv_state *dce)
-{
-       /* nothing to do */
-}
-
-
-static int op_lookup_endpoints(TALLOC_CTX *mem_ctx, struct dcesrv_ep_iface **e)
-{
-       return dcesrv_lookup_endpoints(&dcerpc_table_epmapper, mem_ctx, e);
-}
-
-
-static const struct dcesrv_endpoint_ops rpc_epmapper_ops = {
-       op_query_endpoint,
-       op_set_interface,
-       op_connect,
-       op_disconnect,
-       op_lookup_endpoints
-};
-
-/*
-  register with the dcerpc server
-*/
-void rpc_epmapper_init(struct dcesrv_context *dce)
-{
-       if (!dcesrv_endpoint_register(dce, &rpc_epmapper_ops, &dcerpc_table_epmapper)) {
-               DEBUG(1,("Failed to register epmapper endpoint\n"));
-       }
-}
+/* include the generated boilerplate */
+#include "librpc/gen_ndr/ndr_epmapper_s.c"
index 6ca0063184e43c709559597f27ec900b1ba95111..f39fab3a6586645e738f0e08ef32f6c4ae78ce58 100755 (executable)
@@ -4,7 +4,7 @@ FULLBUILD=$1
 
 [ -d librpc/gen_ndr ] || mkdir -p librpc/gen_ndr || exit 1
 
-PIDL="build/pidl/pidl.pl --output librpc/gen_ndr/ndr_ --parse --header --parser"
+PIDL="build/pidl/pidl.pl --output librpc/gen_ndr/ndr_ --parse --header --parser --server"
 TABLES="build/pidl/tables.pl --output librpc/gen_ndr/tables"
 
 if [ x$FULLBUILD = xFULL ]; then
index 4ac57e7b6e186d716d18202069e926a9521c3c96..be70939de1c2fbd3e1838b7ac31f9d752b1dba3f 100644 (file)
@@ -169,12 +169,12 @@ static BOOL test_sinkdata(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
 static BOOL test_testcall(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
 {
        NTSTATUS status;
-       struct TestCall r;
+       struct echo_TestCall r;
 
        r.in.s1 = "input string";
 
        printf("\nTesting TestCall\n");
-       status = dcerpc_TestCall(p, mem_ctx, &r);
+       status = dcerpc_echo_TestCall(p, mem_ctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
                printf("TestCall failed - %s\n", nt_errstr(status));
                return False;
@@ -189,7 +189,7 @@ static BOOL test_testcall(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
 static BOOL test_testcall2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
 {
        NTSTATUS status;
-       struct TestCall2 r;
+       struct echo_TestCall2 r;
        int i;
        BOOL ret = True;
 
@@ -197,7 +197,7 @@ static BOOL test_testcall2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
                r.in.level = i;
 
                printf("\nTesting TestCall2 level %d\n", i);
-               status = dcerpc_TestCall2(p, mem_ctx, &r);
+               status = dcerpc_echo_TestCall2(p, mem_ctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
                        printf("TestCall2 failed - %s\n", nt_errstr(status));
                        ret = False;
index cc0a83fe80b79925c157f6b845867355943a2437..84734569d0b1e3e3822ddfce0942442b7d808ec6 100644 (file)
@@ -226,7 +226,18 @@ NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
        cli_tree_close(cli->tree);
 
        /* bind to the pipe, using the uuid as the key */
+#if 0
        status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+#else
+       /* enable signing on tcp connections */
+       (*p)->flags |= DCERPC_SIGN;
+
+       /* bind to the pipe, using the uuid as the key */
+       status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version,
+                                      lp_workgroup(),
+                                      lp_parm_string(-1, "torture", "username"),
+                                      lp_parm_string(-1, "torture", "password"));
+#endif
        if (!NT_STATUS_IS_OK(status)) {
                dcerpc_pipe_close(*p);
                return status;