Line data Source code
1 : /* s3 compat server functions auto-generated by pidl */
2 : #include "bin/default/librpc/gen_ndr/ndr_mdssvc.h"
3 : #include "bin/default/librpc/gen_ndr/ndr_mdssvc_scompat.h"
4 : #include <librpc/rpc/dcesrv_core.h>
5 : #include <rpc_server/rpc_config.h>
6 : #include <rpc_server/rpc_server.h>
7 : #include <util/debug.h>
8 :
9 : enum s3compat_rpc_dispatch {
10 : S3COMPAT_RPC_DISPATCH_EXTERNAL = 0x00000001,
11 : S3COMPAT_RPC_DISPATCH_INTERNAL = 0x00000002,
12 : };
13 :
14 : /* mdssvc - dcerpc server boilerplate generated by pidl */
15 12 : static NTSTATUS mdssvc__op_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
16 : {
17 : #ifdef DCESRV_INTERFACE_MDSSVC_BIND
18 : return DCESRV_INTERFACE_MDSSVC_BIND(context,iface);
19 : #else
20 12 : return NT_STATUS_OK;
21 : #endif
22 : }
23 :
24 12 : static void mdssvc__op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
25 : {
26 : #ifdef DCESRV_INTERFACE_MDSSVC_UNBIND
27 : DCESRV_INTERFACE_MDSSVC_UNBIND(context, iface);
28 : #else
29 12 : return;
30 : #endif
31 : }
32 :
33 62 : NTSTATUS mdssvc__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r)
34 : {
35 : enum ndr_err_code ndr_err;
36 62 : uint16_t opnum = dce_call->pkt.u.request.opnum;
37 :
38 62 : dce_call->fault_code = 0;
39 :
40 62 : if (opnum >= ndr_table_mdssvc.num_calls) {
41 0 : dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
42 0 : return NT_STATUS_NET_WRITE_FAULT;
43 : }
44 :
45 62 : *r = talloc_named(mem_ctx, ndr_table_mdssvc.calls[opnum].struct_size, "struct %s", ndr_table_mdssvc.calls[opnum].name);
46 62 : NT_STATUS_HAVE_NO_MEMORY(*r);
47 :
48 : /* unravel the NDR for the packet */
49 62 : ndr_err = ndr_table_mdssvc.calls[opnum].ndr_pull(pull, NDR_IN, *r);
50 62 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
51 0 : dce_call->fault_code = DCERPC_FAULT_NDR;
52 0 : return NT_STATUS_NET_WRITE_FAULT;
53 : }
54 :
55 62 : return NT_STATUS_OK;
56 : }
57 :
58 62 : static NTSTATUS mdssvc__op_dispatch_internal(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, enum s3compat_rpc_dispatch dispatch)
59 : {
60 62 : uint16_t opnum = dce_call->pkt.u.request.opnum;
61 62 : struct pipes_struct *p = NULL;
62 62 : NTSTATUS status = NT_STATUS_OK;
63 62 : bool impersonated = false;
64 :
65 : /* Retrieve pipes struct */
66 62 : p = dcesrv_get_pipes_struct(dce_call->conn);
67 62 : p->dce_call = dce_call;
68 62 : p->mem_ctx = mem_ctx;
69 : /* Reset pipes struct fault state */
70 62 : p->fault_state = 0;
71 :
72 : /* Impersonate */
73 62 : if (dispatch == S3COMPAT_RPC_DISPATCH_EXTERNAL) {
74 62 : impersonated = become_authenticated_pipe_user(dce_call->auth_state->session_info);
75 62 : if (!impersonated) {
76 0 : dce_call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
77 0 : status = NT_STATUS_NET_WRITE_FAULT;
78 0 : goto fail;
79 : }
80 : }
81 :
82 62 : switch (opnum) {
83 16 : case 0: { /* mdssvc_open */
84 16 : struct mdssvc_open *r2 = (struct mdssvc_open *)r;
85 16 : if (DEBUGLEVEL >= 10) {
86 0 : NDR_PRINT_FUNCTION_DEBUG(mdssvc_open, NDR_IN, r2);
87 : }
88 16 : NDR_ZERO_STRUCT(r2->out);
89 16 : r2->out.device_id = r2->in.device_id;
90 16 : r2->out.unkn2 = r2->in.unkn2;
91 16 : r2->out.unkn3 = r2->in.unkn3;
92 16 : r2->out.share_path = talloc_zero_array(r2, const char, 1025);
93 16 : if (r2->out.share_path == NULL) {
94 0 : status = NT_STATUS_NO_MEMORY;
95 0 : p->fault_state = DCERPC_FAULT_CANT_PERFORM;
96 0 : goto fail;
97 : }
98 :
99 16 : r2->out.handle = talloc_zero(r2, struct policy_handle);
100 16 : if (r2->out.handle == NULL) {
101 0 : status = NT_STATUS_NO_MEMORY;
102 0 : p->fault_state = DCERPC_FAULT_CANT_PERFORM;
103 0 : goto fail;
104 : }
105 :
106 16 : _mdssvc_open(p, r2);
107 16 : break;
108 : }
109 14 : case 1: { /* mdssvc_unknown1 */
110 14 : struct mdssvc_unknown1 *r2 = (struct mdssvc_unknown1 *)r;
111 14 : if (DEBUGLEVEL >= 10) {
112 0 : NDR_PRINT_FUNCTION_DEBUG(mdssvc_unknown1, NDR_IN, r2);
113 : }
114 14 : NDR_ZERO_STRUCT(r2->out);
115 14 : r2->out.status = talloc_zero(r2, uint32_t);
116 14 : if (r2->out.status == NULL) {
117 0 : status = NT_STATUS_NO_MEMORY;
118 0 : p->fault_state = DCERPC_FAULT_CANT_PERFORM;
119 0 : goto fail;
120 : }
121 :
122 14 : r2->out.flags = talloc_zero(r2, uint32_t);
123 14 : if (r2->out.flags == NULL) {
124 0 : status = NT_STATUS_NO_MEMORY;
125 0 : p->fault_state = DCERPC_FAULT_CANT_PERFORM;
126 0 : goto fail;
127 : }
128 :
129 14 : r2->out.unkn7 = talloc_zero(r2, uint32_t);
130 14 : if (r2->out.unkn7 == NULL) {
131 0 : status = NT_STATUS_NO_MEMORY;
132 0 : p->fault_state = DCERPC_FAULT_CANT_PERFORM;
133 0 : goto fail;
134 : }
135 :
136 14 : _mdssvc_unknown1(p, r2);
137 14 : break;
138 : }
139 22 : case 2: { /* mdssvc_cmd */
140 22 : struct mdssvc_cmd *r2 = (struct mdssvc_cmd *)r;
141 22 : if (DEBUGLEVEL >= 10) {
142 0 : NDR_PRINT_FUNCTION_DEBUG(mdssvc_cmd, NDR_IN, r2);
143 : }
144 22 : NDR_ZERO_STRUCT(r2->out);
145 22 : r2->out.fragment = talloc_zero(r2, uint32_t);
146 22 : if (r2->out.fragment == NULL) {
147 0 : status = NT_STATUS_NO_MEMORY;
148 0 : p->fault_state = DCERPC_FAULT_CANT_PERFORM;
149 0 : goto fail;
150 : }
151 :
152 22 : r2->out.response_blob = talloc_zero(r2, struct mdssvc_blob);
153 22 : if (r2->out.response_blob == NULL) {
154 0 : status = NT_STATUS_NO_MEMORY;
155 0 : p->fault_state = DCERPC_FAULT_CANT_PERFORM;
156 0 : goto fail;
157 : }
158 :
159 22 : r2->out.unkn9 = talloc_zero(r2, uint32_t);
160 22 : if (r2->out.unkn9 == NULL) {
161 0 : status = NT_STATUS_NO_MEMORY;
162 0 : p->fault_state = DCERPC_FAULT_CANT_PERFORM;
163 0 : goto fail;
164 : }
165 :
166 22 : _mdssvc_cmd(p, r2);
167 22 : break;
168 : }
169 10 : case 3: { /* mdssvc_close */
170 10 : struct mdssvc_close *r2 = (struct mdssvc_close *)r;
171 10 : if (DEBUGLEVEL >= 10) {
172 0 : NDR_PRINT_FUNCTION_DEBUG(mdssvc_close, NDR_IN, r2);
173 : }
174 10 : NDR_ZERO_STRUCT(r2->out);
175 10 : r2->out.out_handle = talloc_zero(r2, struct policy_handle);
176 10 : if (r2->out.out_handle == NULL) {
177 0 : status = NT_STATUS_NO_MEMORY;
178 0 : p->fault_state = DCERPC_FAULT_CANT_PERFORM;
179 0 : goto fail;
180 : }
181 :
182 10 : r2->out.status = talloc_zero(r2, uint32_t);
183 10 : if (r2->out.status == NULL) {
184 0 : status = NT_STATUS_NO_MEMORY;
185 0 : p->fault_state = DCERPC_FAULT_CANT_PERFORM;
186 0 : goto fail;
187 : }
188 :
189 10 : _mdssvc_close(p, r2);
190 10 : break;
191 : }
192 0 : default:
193 0 : dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
194 0 : break;
195 : }
196 :
197 62 : fail:
198 : /* Unimpersonate */
199 62 : if (impersonated) {
200 62 : unbecome_authenticated_pipe_user();
201 : }
202 :
203 62 : p->dce_call = NULL;
204 62 : p->mem_ctx = NULL;
205 : /* Check pipes struct fault state */
206 62 : if (p->fault_state != 0) {
207 6 : dce_call->fault_code = p->fault_state;
208 : }
209 62 : if (dce_call->fault_code != 0) {
210 6 : status = NT_STATUS_NET_WRITE_FAULT;
211 : }
212 :
213 62 : return status;
214 : }
215 :
216 62 : NTSTATUS mdssvc__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
217 : {
218 62 : return mdssvc__op_dispatch_internal(dce_call, mem_ctx, r, S3COMPAT_RPC_DISPATCH_EXTERNAL);
219 : }
220 :
221 56 : NTSTATUS mdssvc__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
222 : {
223 56 : uint16_t opnum = dce_call->pkt.u.request.opnum;
224 :
225 56 : switch (opnum) {
226 16 : case 0: { /* mdssvc_open */
227 16 : struct mdssvc_open *r2 = (struct mdssvc_open *)r;
228 16 : if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
229 0 : DEBUG(5,("function mdssvc_open replied async\n"));
230 : }
231 16 : if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
232 0 : NDR_PRINT_FUNCTION_DEBUG(mdssvc_open, NDR_OUT | NDR_SET_VALUES, r2);
233 : }
234 16 : if (dce_call->fault_code != 0) {
235 0 : DBG_WARNING("dcerpc_fault %s in mdssvc_open\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
236 : }
237 16 : break;
238 : }
239 12 : case 1: { /* mdssvc_unknown1 */
240 12 : struct mdssvc_unknown1 *r2 = (struct mdssvc_unknown1 *)r;
241 12 : if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
242 0 : DEBUG(5,("function mdssvc_unknown1 replied async\n"));
243 : }
244 12 : if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
245 0 : NDR_PRINT_FUNCTION_DEBUG(mdssvc_unknown1, NDR_OUT | NDR_SET_VALUES, r2);
246 : }
247 12 : if (dce_call->fault_code != 0) {
248 0 : DBG_WARNING("dcerpc_fault %s in mdssvc_unknown1\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
249 : }
250 12 : break;
251 : }
252 20 : case 2: { /* mdssvc_cmd */
253 20 : struct mdssvc_cmd *r2 = (struct mdssvc_cmd *)r;
254 20 : if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
255 0 : DEBUG(5,("function mdssvc_cmd replied async\n"));
256 : }
257 20 : if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
258 0 : NDR_PRINT_FUNCTION_DEBUG(mdssvc_cmd, NDR_OUT | NDR_SET_VALUES, r2);
259 : }
260 20 : if (dce_call->fault_code != 0) {
261 0 : DBG_WARNING("dcerpc_fault %s in mdssvc_cmd\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
262 : }
263 20 : break;
264 : }
265 8 : case 3: { /* mdssvc_close */
266 8 : struct mdssvc_close *r2 = (struct mdssvc_close *)r;
267 8 : if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
268 0 : DEBUG(5,("function mdssvc_close replied async\n"));
269 : }
270 8 : if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {
271 0 : NDR_PRINT_FUNCTION_DEBUG(mdssvc_close, NDR_OUT | NDR_SET_VALUES, r2);
272 : }
273 8 : if (dce_call->fault_code != 0) {
274 0 : DBG_WARNING("dcerpc_fault %s in mdssvc_close\n", dcerpc_errstr(mem_ctx, dce_call->fault_code));
275 : }
276 8 : break;
277 : }
278 0 : default:
279 0 : dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
280 0 : break;
281 : }
282 :
283 56 : if (dce_call->fault_code != 0) {
284 0 : return NT_STATUS_NET_WRITE_FAULT;
285 : }
286 :
287 56 : return NT_STATUS_OK;
288 : }
289 :
290 56 : NTSTATUS mdssvc__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, const void *r)
291 : {
292 : enum ndr_err_code ndr_err;
293 56 : uint16_t opnum = dce_call->pkt.u.request.opnum;
294 :
295 56 : ndr_err = ndr_table_mdssvc.calls[opnum].ndr_push(push, NDR_OUT, r);
296 56 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
297 0 : dce_call->fault_code = DCERPC_FAULT_NDR;
298 0 : return NT_STATUS_NET_WRITE_FAULT;
299 : }
300 :
301 56 : return NT_STATUS_OK;
302 : }
303 :
304 0 : NTSTATUS mdssvc__op_local(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
305 : {
306 0 : return mdssvc__op_dispatch_internal(dce_call, mem_ctx, r, S3COMPAT_RPC_DISPATCH_INTERNAL);
307 : }
308 :
309 : static const struct dcesrv_interface dcesrv_mdssvc_interface = {
310 : .name = "mdssvc",
311 : .syntax_id = {{0x885d85fb,0xc754,0x4062,{0xa0,0xe7},{0x68,0x72,0xce,0x00,0x64,0xf4}},2.0},
312 : .bind = mdssvc__op_bind,
313 : .unbind = mdssvc__op_unbind,
314 : .ndr_pull = mdssvc__op_ndr_pull,
315 : .dispatch = mdssvc__op_dispatch,
316 : .reply = mdssvc__op_reply,
317 : .ndr_push = mdssvc__op_ndr_push,
318 : .local = mdssvc__op_local,
319 : #ifdef DCESRV_INTERFACE_MDSSVC_FLAGS
320 : .flags = DCESRV_INTERFACE_MDSSVC_FLAGS
321 : #else
322 : .flags = 0
323 : #endif
324 : };
325 :
326 8 : static NTSTATUS mdssvc__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
327 : {
328 : uint32_t i;
329 : NTSTATUS ret;
330 :
331 : #ifdef DCESRV_INTERFACE_MDSSVC_NCACN_NP_SECONDARY_ENDPOINT
332 : const char *ncacn_np_secondary_endpoint = DCESRV_INTERFACE_MDSSVC_NCACN_NP_SECONDARY_ENDPOINT;
333 : #else
334 8 : const char *ncacn_np_secondary_endpoint = NULL;
335 : #endif
336 :
337 24 : for (i=0;i<ndr_table_mdssvc.endpoints->count;i++) {
338 16 : const char *name = ndr_table_mdssvc.endpoints->names[i];
339 :
340 16 : ret = dcesrv_interface_register(dce_ctx, name, ncacn_np_secondary_endpoint, &dcesrv_mdssvc_interface, NULL);
341 16 : if (!NT_STATUS_IS_OK(ret)) {
342 0 : DBG_ERR("Failed to register endpoint '%s'\n",name);
343 0 : return ret;
344 : }
345 : }
346 :
347 8 : return NT_STATUS_OK;
348 : }
349 :
350 8 : static NTSTATUS mdssvc__op_shutdown_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
351 : {
352 8 : return NT_STATUS_OK;
353 : }
354 :
355 0 : static bool mdssvc__op_interface_by_uuid(struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version)
356 : {
357 0 : if (dcesrv_mdssvc_interface.syntax_id.if_version == if_version && GUID_equal(&dcesrv_mdssvc_interface.syntax_id.uuid, uuid)) {
358 0 : memcpy(iface,&dcesrv_mdssvc_interface, sizeof(*iface));
359 0 : return true;
360 : }
361 :
362 0 : return false;
363 : }
364 :
365 0 : static bool mdssvc__op_interface_by_name(struct dcesrv_interface *iface, const char *name)
366 : {
367 0 : if (strcmp(dcesrv_mdssvc_interface.name, name)==0) {
368 0 : memcpy(iface, &dcesrv_mdssvc_interface, sizeof(*iface));
369 0 : return true;
370 : }
371 :
372 0 : return false;
373 : }
374 :
375 : static const struct dcesrv_endpoint_server mdssvc_ep_server = {
376 : /* fill in our name */
377 : .name = "mdssvc",
378 :
379 : /* Initialization flag */
380 : .initialized = false,
381 :
382 : /* fill in all the operations */
383 : #ifdef DCESRV_INTERFACE_MDSSVC_INIT_SERVER
384 : .init_server = DCESRV_INTERFACE_MDSSVC_INIT_SERVER,
385 : #else
386 : .init_server = mdssvc__op_init_server,
387 : #endif
388 : #ifdef DCESRV_INTERFACE_MDSSVC_SHUTDOWN_SERVER
389 : .shutdown_server = DCESRV_INTERFACE_MDSSVC_SHUTDOWN_SERVER,
390 : #else
391 : .shutdown_server = mdssvc__op_shutdown_server,
392 : #endif
393 : .interface_by_uuid = mdssvc__op_interface_by_uuid,
394 : .interface_by_name = mdssvc__op_interface_by_name
395 : };
396 :
397 8 : const struct dcesrv_endpoint_server *mdssvc_get_ep_server(void)
398 : {
399 8 : return &mdssvc_ep_server;
400 : }
|