mirror of
https://github.com/samba-team/samba.git
synced 2025-02-24 13:57:43 +03:00
added auto-generation of the server side boilerplate code for each
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)
This commit is contained in:
parent
4cd6b8a64b
commit
f6eb8342cb
@ -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}) {
|
||||
|
@ -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);
|
||||
|
108
source4/build/pidl/server.pm
Normal file
108
source4/build/pidl/server.pm
Normal file
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
|
@ -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
|
||||
);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user