diff options
-rw-r--r-- | source4/librpc/idl/echo.idl | 55 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_echo.c | 299 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_echo.h | 58 | ||||
-rw-r--r-- | source4/librpc/rpc/rpc_echo.c | 21 | ||||
-rw-r--r-- | source4/torture/rpc/echo.c | 35 |
5 files changed, 440 insertions, 28 deletions
diff --git a/source4/librpc/idl/echo.idl b/source4/librpc/idl/echo.idl index f68bcf38c3..2ef7026826 100644 --- a/source4/librpc/idl/echo.idl +++ b/source4/librpc/idl/echo.idl @@ -25,7 +25,58 @@ interface rpcecho [out,ref,size_is(len)] uint8 *data ); - void TestCall ( - [in] unistr *s + + /* test strings */ + void TestCall ( + [in] unistr *s1, + [out] unistr *s2 + ); + + + /* test some alignment issues */ + typedef struct { + uint8 v; + } echo_info1; + + typedef struct { + uint16 v; + } echo_info2; + + typedef struct { + uint32 v; + } echo_info3; + + typedef struct { + HYPER_T v; + } echo_info4; + + typedef struct { + uint8 v1; + HYPER_T v2; + } echo_info5; + + typedef struct { + uint8 v1; + echo_info1 info1; + } echo_info6; + + typedef struct { + uint8 v1; + echo_info4 info4; + } echo_info7; + + typedef union { + [case(1)] echo_info1 info1; + [case(2)] echo_info2 info2; + [case(3)] echo_info3 info3; + [case(4)] echo_info4 info4; + [case(5)] echo_info5 info5; + [case(6)] echo_info6 info6; + [case(7)] echo_info7 info7; + } echo_Info; + + NTSTATUS TestCall2 ( + [in] uint16 level, + [out,switch_is(level)] echo_Info *info ); } diff --git a/source4/librpc/ndr/ndr_echo.c b/source4/librpc/ndr/ndr_echo.c index 7377f845c8..8e4690de52 100644 --- a/source4/librpc/ndr/ndr_echo.c +++ b/source4/librpc/ndr/ndr_echo.c @@ -40,6 +40,16 @@ NTSTATUS ndr_push_echo_SourceData(struct ndr_push *ndr, struct echo_SourceData * NTSTATUS ndr_push_TestCall(struct ndr_push *ndr, struct TestCall *r) { + NDR_CHECK(ndr_push_ptr(ndr, r->in.s1)); + if (r->in.s1) { + NDR_CHECK(ndr_push_unistr(ndr, r->in.s1)); + } + + return NT_STATUS_OK; +} + +NTSTATUS ndr_push_TestCall2(struct ndr_push *ndr, struct TestCall2 *r) +{ NDR_CHECK(ndr_push_uint16(ndr, r->in.level)); return NT_STATUS_OK; @@ -91,12 +101,41 @@ NTSTATUS ndr_pull_echo_SourceData(struct ndr_pull *ndr, struct echo_SourceData * return NT_STATUS_OK; } -NTSTATUS ndr_pull_echo_ServerRole(struct ndr_pull *ndr, int ndr_flags, struct echo_ServerRole *r) +NTSTATUS ndr_pull_TestCall(struct ndr_pull *ndr, struct TestCall *r) +{ + uint32 _ptr_s2; + NDR_CHECK(ndr_pull_uint32(ndr, &_ptr_s2)); + if (_ptr_s2) { + NDR_ALLOC(ndr, r->out.s2); + } else { + r->out.s2 = NULL; + } + if (r->out.s2) { + NDR_CHECK(ndr_pull_unistr(ndr, &r->out.s2)); + } + + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_echo_info1(struct ndr_pull *ndr, int ndr_flags, struct echo_info1 *r) +{ + NDR_CHECK(ndr_pull_struct_start(ndr)); + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_align(ndr, 1)); + NDR_CHECK(ndr_pull_uint8(ndr, &r->v)); + ndr_pull_struct_end(ndr); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; +done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_echo_info2(struct ndr_pull *ndr, int ndr_flags, struct echo_info2 *r) { NDR_CHECK(ndr_pull_struct_start(ndr)); if (!(ndr_flags & NDR_SCALARS)) goto buffers; NDR_CHECK(ndr_pull_align(ndr, 2)); - NDR_CHECK(ndr_pull_uint16(ndr, &r->role)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->v)); ndr_pull_struct_end(ndr); buffers: if (!(ndr_flags & NDR_BUFFERS)) goto done; @@ -104,14 +143,108 @@ done: return NT_STATUS_OK; } -NTSTATUS ndr_pull_echo_PolicyInformation(struct ndr_pull *ndr, int ndr_flags, uint16 *level, union echo_PolicyInformation *r) +NTSTATUS ndr_pull_echo_info3(struct ndr_pull *ndr, int ndr_flags, struct echo_info3 *r) +{ + NDR_CHECK(ndr_pull_struct_start(ndr)); + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->v)); + ndr_pull_struct_end(ndr); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; +done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_echo_info4(struct ndr_pull *ndr, int ndr_flags, struct echo_info4 *r) +{ + NDR_CHECK(ndr_pull_struct_start(ndr)); + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_align(ndr, 8)); + NDR_CHECK(ndr_pull_HYPER_T(ndr, &r->v)); + ndr_pull_struct_end(ndr); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; +done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_echo_info5(struct ndr_pull *ndr, int ndr_flags, struct echo_info5 *r) +{ + NDR_CHECK(ndr_pull_struct_start(ndr)); + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_align(ndr, 8)); + NDR_CHECK(ndr_pull_uint8(ndr, &r->v1)); + NDR_CHECK(ndr_pull_HYPER_T(ndr, &r->v2)); + ndr_pull_struct_end(ndr); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; +done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_echo_info6(struct ndr_pull *ndr, int ndr_flags, struct echo_info6 *r) +{ + NDR_CHECK(ndr_pull_struct_start(ndr)); + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint8(ndr, &r->v1)); + NDR_CHECK(ndr_pull_echo_info1(ndr, NDR_SCALARS, &r->info1)); + ndr_pull_struct_end(ndr); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; + NDR_CHECK(ndr_pull_echo_info1(ndr, NDR_BUFFERS, &r->info1)); +done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_echo_info7(struct ndr_pull *ndr, int ndr_flags, struct echo_info7 *r) +{ + NDR_CHECK(ndr_pull_struct_start(ndr)); + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint8(ndr, &r->v1)); + NDR_CHECK(ndr_pull_echo_info4(ndr, NDR_SCALARS, &r->info4)); + ndr_pull_struct_end(ndr); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; + NDR_CHECK(ndr_pull_echo_info4(ndr, NDR_BUFFERS, &r->info4)); +done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_echo_Info(struct ndr_pull *ndr, int ndr_flags, uint16 *level, union echo_Info *r) { if (!(ndr_flags & NDR_SCALARS)) goto buffers; NDR_CHECK(ndr_pull_struct_start(ndr)); NDR_CHECK(ndr_pull_uint16(ndr, level)); switch (*level) { + case 1: { + NDR_CHECK(ndr_pull_echo_info1(ndr, NDR_SCALARS, &r->info1)); + break; } + + case 2: { + NDR_CHECK(ndr_pull_echo_info2(ndr, NDR_SCALARS, &r->info2)); + break; } + + case 3: { + NDR_CHECK(ndr_pull_echo_info3(ndr, NDR_SCALARS, &r->info3)); + break; } + + case 4: { + NDR_CHECK(ndr_pull_echo_info4(ndr, NDR_SCALARS, &r->info4)); + break; } + + case 5: { + NDR_CHECK(ndr_pull_echo_info5(ndr, NDR_SCALARS, &r->info5)); + break; } + case 6: { - NDR_CHECK(ndr_pull_echo_ServerRole(ndr, NDR_SCALARS, &r->role)); + NDR_CHECK(ndr_pull_echo_info6(ndr, NDR_SCALARS, &r->info6)); + break; } + + case 7: { + NDR_CHECK(ndr_pull_echo_info7(ndr, NDR_SCALARS, &r->info7)); break; } default: @@ -121,8 +254,32 @@ NTSTATUS ndr_pull_echo_PolicyInformation(struct ndr_pull *ndr, int ndr_flags, ui buffers: if (!(ndr_flags & NDR_BUFFERS)) goto done; switch (*level) { + case 1: + NDR_CHECK(ndr_pull_echo_info1(ndr, NDR_BUFFERS, &r->info1)); + break; + + case 2: + NDR_CHECK(ndr_pull_echo_info2(ndr, NDR_BUFFERS, &r->info2)); + break; + + case 3: + NDR_CHECK(ndr_pull_echo_info3(ndr, NDR_BUFFERS, &r->info3)); + break; + + case 4: + NDR_CHECK(ndr_pull_echo_info4(ndr, NDR_BUFFERS, &r->info4)); + break; + + case 5: + NDR_CHECK(ndr_pull_echo_info5(ndr, NDR_BUFFERS, &r->info5)); + break; + case 6: - NDR_CHECK(ndr_pull_echo_ServerRole(ndr, NDR_BUFFERS, &r->role)); + NDR_CHECK(ndr_pull_echo_info6(ndr, NDR_BUFFERS, &r->info6)); + break; + + case 7: + NDR_CHECK(ndr_pull_echo_info7(ndr, NDR_BUFFERS, &r->info7)); break; default: @@ -132,7 +289,7 @@ done: return NT_STATUS_OK; } -NTSTATUS ndr_pull_TestCall(struct ndr_pull *ndr, struct TestCall *r) +NTSTATUS ndr_pull_TestCall2(struct ndr_pull *ndr, struct TestCall2 *r) { uint32 _ptr_info; NDR_CHECK(ndr_pull_uint32(ndr, &_ptr_info)); @@ -143,10 +300,11 @@ NTSTATUS ndr_pull_TestCall(struct ndr_pull *ndr, struct TestCall *r) } if (r->out.info) { { uint16 _level = r->in.level; - NDR_CHECK(ndr_pull_echo_PolicyInformation(ndr, NDR_SCALARS|NDR_BUFFERS, &_level, r->out.info)); + NDR_CHECK(ndr_pull_echo_Info(ndr, NDR_SCALARS|NDR_BUFFERS, &_level, r->out.info)); if (((NDR_SCALARS|NDR_BUFFERS) & NDR_SCALARS) && (_level != r->in.level)) return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u in info"); } } + NDR_CHECK(ndr_pull_NTSTATUS(ndr, &r->out.result)); return NT_STATUS_OK; } @@ -246,20 +404,124 @@ void ndr_print_echo_SourceData(struct ndr_print *ndr, const char *name, int flag ndr->depth--; } -void ndr_print_echo_ServerRole(struct ndr_print *ndr, const char *name, struct echo_ServerRole *r) +void ndr_print_TestCall(struct ndr_print *ndr, const char *name, int flags, struct TestCall *r) +{ + ndr_print_struct(ndr, name, "TestCall"); + ndr->depth++; + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "TestCall"); + ndr->depth++; + ndr_print_ptr(ndr, "s1", r->in.s1); + ndr->depth++; + if (r->in.s1) { + ndr_print_unistr(ndr, "s1", r->in.s1); + } + ndr->depth--; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "TestCall"); + ndr->depth++; + ndr_print_ptr(ndr, "s2", r->out.s2); + ndr->depth++; + if (r->out.s2) { + ndr_print_unistr(ndr, "s2", r->out.s2); + } + ndr->depth--; + ndr->depth--; + } + ndr->depth--; +} + +void ndr_print_echo_info1(struct ndr_print *ndr, const char *name, struct echo_info1 *r) +{ + ndr_print_struct(ndr, name, "echo_info1"); + ndr->depth++; + ndr_print_uint8(ndr, "v", r->v); + ndr->depth--; +} + +void ndr_print_echo_info2(struct ndr_print *ndr, const char *name, struct echo_info2 *r) +{ + ndr_print_struct(ndr, name, "echo_info2"); + ndr->depth++; + ndr_print_uint16(ndr, "v", r->v); + ndr->depth--; +} + +void ndr_print_echo_info3(struct ndr_print *ndr, const char *name, struct echo_info3 *r) +{ + ndr_print_struct(ndr, name, "echo_info3"); + ndr->depth++; + ndr_print_uint32(ndr, "v", r->v); + ndr->depth--; +} + +void ndr_print_echo_info4(struct ndr_print *ndr, const char *name, struct echo_info4 *r) +{ + ndr_print_struct(ndr, name, "echo_info4"); + ndr->depth++; + ndr_print_HYPER_T(ndr, "v", r->v); + ndr->depth--; +} + +void ndr_print_echo_info5(struct ndr_print *ndr, const char *name, struct echo_info5 *r) +{ + ndr_print_struct(ndr, name, "echo_info5"); + ndr->depth++; + ndr_print_uint8(ndr, "v1", r->v1); + ndr_print_HYPER_T(ndr, "v2", r->v2); + ndr->depth--; +} + +void ndr_print_echo_info6(struct ndr_print *ndr, const char *name, struct echo_info6 *r) { - ndr_print_struct(ndr, name, "echo_ServerRole"); + ndr_print_struct(ndr, name, "echo_info6"); ndr->depth++; - ndr_print_uint16(ndr, "role", r->role); + ndr_print_uint8(ndr, "v1", r->v1); + ndr_print_echo_info1(ndr, "info1", &r->info1); ndr->depth--; } -void ndr_print_echo_PolicyInformation(struct ndr_print *ndr, const char *name, uint16 level, union echo_PolicyInformation *r) +void ndr_print_echo_info7(struct ndr_print *ndr, const char *name, struct echo_info7 *r) { - ndr_print_union(ndr, name, level, "echo_PolicyInformation"); + ndr_print_struct(ndr, name, "echo_info7"); + ndr->depth++; + ndr_print_uint8(ndr, "v1", r->v1); + ndr_print_echo_info4(ndr, "info4", &r->info4); + ndr->depth--; +} + +void ndr_print_echo_Info(struct ndr_print *ndr, const char *name, uint16 level, union echo_Info *r) +{ + ndr_print_union(ndr, name, level, "echo_Info"); switch (level) { + case 1: + ndr_print_echo_info1(ndr, "info1", &r->info1); + break; + + case 2: + ndr_print_echo_info2(ndr, "info2", &r->info2); + break; + + case 3: + ndr_print_echo_info3(ndr, "info3", &r->info3); + break; + + case 4: + ndr_print_echo_info4(ndr, "info4", &r->info4); + break; + + case 5: + ndr_print_echo_info5(ndr, "info5", &r->info5); + break; + case 6: - ndr_print_echo_ServerRole(ndr, "role", &r->role); + ndr_print_echo_info6(ndr, "info6", &r->info6); + break; + + case 7: + ndr_print_echo_info7(ndr, "info7", &r->info7); break; default: @@ -267,25 +529,26 @@ void ndr_print_echo_PolicyInformation(struct ndr_print *ndr, const char *name, u } } -void ndr_print_TestCall(struct ndr_print *ndr, const char *name, int flags, struct TestCall *r) +void ndr_print_TestCall2(struct ndr_print *ndr, const char *name, int flags, struct TestCall2 *r) { - ndr_print_struct(ndr, name, "TestCall"); + ndr_print_struct(ndr, name, "TestCall2"); ndr->depth++; if (flags & NDR_IN) { - ndr_print_struct(ndr, "in", "TestCall"); + ndr_print_struct(ndr, "in", "TestCall2"); ndr->depth++; ndr_print_uint16(ndr, "level", r->in.level); ndr->depth--; } if (flags & NDR_OUT) { - ndr_print_struct(ndr, "out", "TestCall"); + ndr_print_struct(ndr, "out", "TestCall2"); ndr->depth++; ndr_print_ptr(ndr, "info", r->out.info); ndr->depth++; if (r->out.info) { - ndr_print_echo_PolicyInformation(ndr, "info", r->in.level, r->out.info); + ndr_print_echo_Info(ndr, "info", r->in.level, r->out.info); } ndr->depth--; + ndr_print_NTSTATUS(ndr, "result", &r->out.result); ndr->depth--; } ndr->depth--; diff --git a/source4/librpc/ndr/ndr_echo.h b/source4/librpc/ndr/ndr_echo.h index a5f6a2998e..5b5d118e19 100644 --- a/source4/librpc/ndr/ndr_echo.h +++ b/source4/librpc/ndr/ndr_echo.h @@ -9,6 +9,7 @@ #define DCERPC_ECHO_SINKDATA 2 #define DCERPC_ECHO_SOURCEDATA 3 #define DCERPC_TESTCALL 4 +#define DCERPC_TESTCALL2 5 struct echo_AddOne { @@ -56,21 +57,66 @@ struct echo_SourceData { }; -struct echo_ServerRole { - uint16 role; +struct TestCall { + struct { + const char *s1; + } in; + + struct { + const char *s2; + } out; + }; -union echo_PolicyInformation { -/* [case(6)] */ struct echo_ServerRole role; +struct echo_info1 { + uint8 v; }; -struct TestCall { +struct echo_info2 { + uint16 v; +}; + +struct echo_info3 { + uint32 v; +}; + +struct echo_info4 { + HYPER_T v; +}; + +struct echo_info5 { + uint8 v1; + HYPER_T v2; +}; + +struct echo_info6 { + uint8 v1; + struct echo_info1 info1; +}; + +struct echo_info7 { + uint8 v1; + struct echo_info4 info4; +}; + +union echo_Info { +/* [case(1)] */ struct echo_info1 info1; +/* [case(2)] */ struct echo_info2 info2; +/* [case(3)] */ struct echo_info3 info3; +/* [case(4)] */ struct echo_info4 info4; +/* [case(5)] */ struct echo_info5 info5; +/* [case(6)] */ struct echo_info6 info6; +/* [case(7)] */ struct echo_info7 info7; +}; + +struct TestCall2 { struct { uint16 level; } in; struct { - union echo_PolicyInformation *info; + union echo_Info *info; + NTSTATUS result; } out; }; diff --git a/source4/librpc/rpc/rpc_echo.c b/source4/librpc/rpc/rpc_echo.c index 38b394dbf6..c774dbb36e 100644 --- a/source4/librpc/rpc/rpc_echo.c +++ b/source4/librpc/rpc/rpc_echo.c @@ -102,3 +102,24 @@ NTSTATUS dcerpc_TestCall(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct Test return status; } + +NTSTATUS dcerpc_TestCall2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct TestCall2 *r) +{ + NTSTATUS status; + + if (p->flags & DCERPC_DEBUG_PRINT_IN) { + NDR_PRINT_IN_DEBUG(TestCall2, r); + } + + status = dcerpc_ndr_request(p, DCERPC_TESTCALL2, mem_ctx, + (ndr_push_fn_t) ndr_push_TestCall2, + (ndr_pull_fn_t) ndr_pull_TestCall2, + r); + + if (NT_STATUS_IS_OK(status) && (p->flags & DCERPC_DEBUG_PRINT_OUT)) { + NDR_PRINT_OUT_DEBUG(TestCall2, r); + } + if (NT_STATUS_IS_OK(status)) status = r->out.result; + + return status; +} diff --git a/source4/torture/rpc/echo.c b/source4/torture/rpc/echo.c index fe044fbc6c..8d8a3d7c0c 100644 --- a/source4/torture/rpc/echo.c +++ b/source4/torture/rpc/echo.c @@ -170,9 +170,8 @@ static BOOL test_testcall(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { NTSTATUS status; struct TestCall r; - char *s = "foo!"; - r.in.s = s; + r.in.s1 = "input string"; printf("\nTesting TestCall\n"); status = dcerpc_TestCall(p, mem_ctx, &r); @@ -184,6 +183,30 @@ static BOOL test_testcall(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) return True; } +/* + test the testcall interface +*/ +static BOOL test_testcall2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + struct TestCall2 r; + int i; + BOOL ret = True; + + for (i=1;i<=7;i++) { + r.in.level = i; + + printf("\nTesting TestCall2 level %d\n", i); + status = dcerpc_TestCall2(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + printf("TestCall2 failed - %s\n", nt_errstr(status)); + ret = False; + } + } + + return ret; +} + BOOL torture_rpc_echo(int dummy) { NTSTATUS status; @@ -201,6 +224,7 @@ BOOL torture_rpc_echo(int dummy) return False; } +#if 1 if (!test_addone(p, mem_ctx)) { ret = False; } @@ -216,11 +240,18 @@ BOOL torture_rpc_echo(int dummy) if (!test_sinkdata(p, mem_ctx)) { ret = False; } +#endif + + p->flags |= DCERPC_DEBUG_PRINT_BOTH; if (!test_testcall(p, mem_ctx)) { ret = False; } + if (!test_testcall2(p, mem_ctx)) { + ret = False; + } + printf("\n"); torture_rpc_close(p); |