1#!/usr/bin/perl 2# (C) 2007 Jelmer Vernooij <jelmer@samba.org> 3# Published under the GNU General Public License 4use strict; 5use warnings; 6 7use Test::More tests => 8; 8use FindBin qw($RealBin); 9use lib "$RealBin"; 10use Util; 11use Parse::Pidl::Util qw(MyDumper); 12use Parse::Pidl::Samba3::ClientNDR qw(ParseFunction); 13use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv); 14 15# Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work 16my $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] }; 17is_deeply({ "foo" => "r.in.foo" }, GenerateFunctionInEnv($fn, "r.")); 18is_deeply({ "foo" => "r.in.foo" }, GenerateFunctionOutEnv($fn, "r.")); 19 20$fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] }; 21is_deeply({ "foo" => "r.in.foo" }, GenerateFunctionInEnv($fn, "r.")); 22is_deeply({ "foo" => "r.out.foo" }, GenerateFunctionOutEnv($fn, "r.")); 23 24$fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] }; 25is_deeply({ }, GenerateFunctionInEnv($fn, "r.")); 26is_deeply({ "foo" => "r.out.foo" }, GenerateFunctionOutEnv($fn, "r.")); 27 28my $x = new Parse::Pidl::Samba3::ClientNDR(); 29 30$fn = { NAME => "bar", ELEMENTS => [ ] }; 31$x->ParseFunction("foo", $fn); 32is($x->{res}, 33"struct rpccli_bar_state { 34 TALLOC_CTX *out_mem_ctx; 35}; 36 37static void rpccli_bar_done(struct tevent_req *subreq); 38 39struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx, 40 struct tevent_context *ev, 41 struct rpc_pipe_client *cli) 42{ 43 struct tevent_req *req; 44 struct rpccli_bar_state *state; 45 struct tevent_req *subreq; 46 47 req = tevent_req_create(mem_ctx, &state, 48 struct rpccli_bar_state); 49 if (req == NULL) { 50 return NULL; 51 } 52 state->out_mem_ctx = NULL; 53 54 subreq = dcerpc_bar_send(state, 55 ev, 56 cli->binding_handle); 57 if (tevent_req_nomem(subreq, req)) { 58 return tevent_req_post(req, ev); 59 } 60 tevent_req_set_callback(subreq, rpccli_bar_done, req); 61 return req; 62} 63 64static void rpccli_bar_done(struct tevent_req *subreq) 65{ 66 struct tevent_req *req = tevent_req_callback_data( 67 subreq, struct tevent_req); 68 struct rpccli_bar_state *state = tevent_req_data( 69 req, struct rpccli_bar_state); 70 NTSTATUS status; 71 TALLOC_CTX *mem_ctx; 72 73 if (state->out_mem_ctx) { 74 mem_ctx = state->out_mem_ctx; 75 } else { 76 mem_ctx = state; 77 } 78 79 status = dcerpc_bar_recv(subreq, 80 mem_ctx); 81 TALLOC_FREE(subreq); 82 if (!NT_STATUS_IS_OK(status)) { 83 tevent_req_nterror(req, status); 84 return; 85 } 86 87 tevent_req_done(req); 88} 89 90NTSTATUS rpccli_bar_recv(struct tevent_req *req, 91 TALLOC_CTX *mem_ctx) 92{ 93 struct rpccli_bar_state *state = tevent_req_data( 94 req, struct rpccli_bar_state); 95 NTSTATUS status; 96 97 if (tevent_req_is_nterror(req, &status)) { 98 tevent_req_received(req); 99 return status; 100 } 101 102 /* Steal possible out parameters to the callers context */ 103 talloc_steal(mem_ctx, state->out_mem_ctx); 104 105 tevent_req_received(req); 106 return NT_STATUS_OK; 107} 108 109NTSTATUS rpccli_bar(struct rpc_pipe_client *cli, 110 TALLOC_CTX *mem_ctx) 111{ 112 NTSTATUS status; 113 114 status = dcerpc_bar(cli->binding_handle, 115 mem_ctx); 116 if (!NT_STATUS_IS_OK(status)) { 117 return status; 118 } 119 120 /* Return result */ 121 return NT_STATUS_OK; 122} 123 124"); 125 126$x = new Parse::Pidl::Samba3::ClientNDR(); 127 128$fn = { NAME => "bar", ELEMENTS => [ ], RETURN_TYPE => "WERROR" }; 129$x->ParseFunction("foo", $fn); 130is($x->{res}, 131"struct rpccli_bar_state { 132 TALLOC_CTX *out_mem_ctx; 133 WERROR result; 134}; 135 136static void rpccli_bar_done(struct tevent_req *subreq); 137 138struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx, 139 struct tevent_context *ev, 140 struct rpc_pipe_client *cli) 141{ 142 struct tevent_req *req; 143 struct rpccli_bar_state *state; 144 struct tevent_req *subreq; 145 146 req = tevent_req_create(mem_ctx, &state, 147 struct rpccli_bar_state); 148 if (req == NULL) { 149 return NULL; 150 } 151 state->out_mem_ctx = NULL; 152 153 subreq = dcerpc_bar_send(state, 154 ev, 155 cli->binding_handle); 156 if (tevent_req_nomem(subreq, req)) { 157 return tevent_req_post(req, ev); 158 } 159 tevent_req_set_callback(subreq, rpccli_bar_done, req); 160 return req; 161} 162 163static void rpccli_bar_done(struct tevent_req *subreq) 164{ 165 struct tevent_req *req = tevent_req_callback_data( 166 subreq, struct tevent_req); 167 struct rpccli_bar_state *state = tevent_req_data( 168 req, struct rpccli_bar_state); 169 NTSTATUS status; 170 TALLOC_CTX *mem_ctx; 171 172 if (state->out_mem_ctx) { 173 mem_ctx = state->out_mem_ctx; 174 } else { 175 mem_ctx = state; 176 } 177 178 status = dcerpc_bar_recv(subreq, 179 mem_ctx, 180 &state->result); 181 TALLOC_FREE(subreq); 182 if (!NT_STATUS_IS_OK(status)) { 183 tevent_req_nterror(req, status); 184 return; 185 } 186 187 tevent_req_done(req); 188} 189 190NTSTATUS rpccli_bar_recv(struct tevent_req *req, 191 TALLOC_CTX *mem_ctx, 192 WERROR *result) 193{ 194 struct rpccli_bar_state *state = tevent_req_data( 195 req, struct rpccli_bar_state); 196 NTSTATUS status; 197 198 if (tevent_req_is_nterror(req, &status)) { 199 tevent_req_received(req); 200 return status; 201 } 202 203 /* Steal possible out parameters to the callers context */ 204 talloc_steal(mem_ctx, state->out_mem_ctx); 205 206 /* Return result */ 207 *result = state->result; 208 209 tevent_req_received(req); 210 return NT_STATUS_OK; 211} 212 213NTSTATUS rpccli_bar(struct rpc_pipe_client *cli, 214 TALLOC_CTX *mem_ctx, 215 WERROR *werror) 216{ 217 WERROR result; 218 NTSTATUS status; 219 220 status = dcerpc_bar(cli->binding_handle, 221 mem_ctx, 222 &result); 223 if (!NT_STATUS_IS_OK(status)) { 224 return status; 225 } 226 227 /* Return result */ 228 if (werror) { 229 *werror = result; 230 } 231 232 return werror_to_ntstatus(result); 233} 234 235"); 236 237