First round of merging various UUID structures.
[Samba/gebeck_regimport.git] / source / rpc_parse / parse_epmapper.c
blob89dc0994c613e39cfe8c668fb1456bddb113a25e
1 /*
2 Unix SMB/CIFS implementation.
3 Samba end point mapper functions
4 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "includes.h"
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_RPC_PARSE
26 static uint32 internal_referent_id = 0;
29 /*******************************************************************
30 Reads or writes a handle.
31 ********************************************************************/
32 BOOL epm_io_handle(const char *desc, EPM_HANDLE *handle, prs_struct *ps,
33 int depth)
35 if (!prs_align(ps))
36 return False;
38 if (!prs_uint8s(False, "data", ps, depth, handle->data,
39 sizeof(handle->data)))
40 return False;
42 return True;
45 /*******************************************************************
46 inits an EPM_FLOOR structure.
47 ********************************************************************/
48 NTSTATUS init_epm_floor(EPM_FLOOR *floor, uint8 protocol)
50 /* handle lhs */
51 floor->lhs.protocol = protocol;
52 floor->lhs.length = sizeof(floor->lhs.protocol);
54 switch(floor->lhs.protocol) {
55 case EPM_FLOOR_UUID:
56 floor->lhs.length += sizeof(floor->lhs.uuid.uuid);
57 floor->lhs.length += sizeof(floor->lhs.uuid.version);
58 break;
59 default:
60 break;
63 /* handle rhs */
64 switch(floor->lhs.protocol) {
65 case EPM_FLOOR_RPC:
66 case EPM_FLOOR_UUID:
67 floor->rhs.length = sizeof(floor->rhs.unknown);
68 break;
69 case EPM_FLOOR_TCP:
70 floor->rhs.length = sizeof(floor->rhs.tcp.port);
71 break;
72 case EPM_FLOOR_IP:
73 floor->rhs.length = sizeof(floor->rhs.ip.addr);
74 break;
75 case EPM_FLOOR_NMPIPES:
76 case EPM_FLOOR_LRPC:
77 case EPM_FLOOR_NETBIOS:
78 floor->rhs.length = strlen(floor->rhs.string) + 1;
79 break;
80 default:
81 break;
84 return NT_STATUS_OK;
87 /*******************************************************************
88 inits an EPM_FLOOR structure with a UUID
89 ********************************************************************/
90 NTSTATUS init_epm_floor_uuid(EPM_FLOOR *floor,
91 const struct uuid uuid, uint16 version)
93 memcpy(&floor->lhs.uuid.uuid, &uuid, sizeof(uuid));
94 floor->lhs.uuid.version = version;
95 floor->rhs.unknown = 0;
96 return init_epm_floor(floor, EPM_FLOOR_UUID);
99 /*******************************************************************
100 inits an EPM_FLOOR structure for RPC
101 ********************************************************************/
102 NTSTATUS init_epm_floor_rpc(EPM_FLOOR *floor)
104 floor->rhs.unknown = 0;
105 return init_epm_floor(floor, EPM_FLOOR_RPC);
108 /*******************************************************************
109 inits an EPM_FLOOR structure for TCP
110 ********************************************************************/
111 NTSTATUS init_epm_floor_tcp(EPM_FLOOR *floor, uint16 port)
113 floor->rhs.tcp.port = htons(port);
114 return init_epm_floor(floor, EPM_FLOOR_TCP);
117 /*******************************************************************
118 inits an EPM_FLOOR structure for IP
119 ********************************************************************/
120 NTSTATUS init_epm_floor_ip(EPM_FLOOR *floor, uint8 addr[4])
122 memcpy(&floor->rhs.ip.addr, addr, sizeof(addr));
123 return init_epm_floor(floor, EPM_FLOOR_IP);
126 /*******************************************************************
127 inits an EPM_FLOOR structure for named pipe
128 ********************************************************************/
129 NTSTATUS init_epm_floor_np(EPM_FLOOR *floor, const char *pipe_name)
131 safe_strcpy(floor->rhs.string, pipe_name, sizeof(floor->rhs.string)-1);
132 return init_epm_floor(floor, EPM_FLOOR_NMPIPES);
135 /*******************************************************************
136 inits an EPM_FLOOR structure for named pipe
137 ********************************************************************/
138 NTSTATUS init_epm_floor_lrpc(EPM_FLOOR *floor, const char *pipe_name)
140 safe_strcpy(floor->rhs.string, pipe_name, sizeof(floor->rhs.string)-1);
141 return init_epm_floor(floor, EPM_FLOOR_LRPC);
144 /*******************************************************************
145 inits an EPM_FLOOR structure for named pipe
146 ********************************************************************/
147 NTSTATUS init_epm_floor_nb(EPM_FLOOR *floor, char *host_name)
149 safe_strcpy(floor->rhs.string, host_name, sizeof(floor->rhs.string)-1);
150 return init_epm_floor(floor, EPM_FLOOR_NETBIOS);
153 /*******************************************************************
154 reads and writes EPM_FLOOR.
155 ********************************************************************/
156 BOOL epm_io_floor(const char *desc, EPM_FLOOR *floor,
157 prs_struct *ps, int depth)
159 prs_debug(ps, depth, desc, "epm_io_floor");
160 depth++;
162 if (!prs_uint16("lhs_length", ps, depth, &floor->lhs.length))
163 return False;
164 if (!prs_uint8("protocol", ps, depth, &floor->lhs.protocol))
165 return False;
167 switch (floor->lhs.protocol) {
168 case EPM_FLOOR_UUID:
169 if (!smb_io_uuid("uuid", &floor->lhs.uuid.uuid, ps, depth))
170 return False;
171 if (!prs_uint16("version", ps, depth,
172 &floor->lhs.uuid.version))
173 return False;
174 break;
177 if (!prs_uint16("rhs_length", ps, depth, &floor->rhs.length))
178 return False;
180 switch (floor->lhs.protocol) {
181 case EPM_FLOOR_UUID:
182 case EPM_FLOOR_RPC:
183 if (!prs_uint16("unknown", ps, depth, &floor->rhs.unknown))
184 return False;
185 break;
186 case EPM_FLOOR_TCP:
187 if (!prs_uint16("tcp_port", ps, depth, &floor->rhs.tcp.port))
188 return False;
189 break;
190 case EPM_FLOOR_IP:
191 if (!prs_uint8s(False, "ip_addr", ps, depth,
192 floor->rhs.ip.addr,
193 sizeof(floor->rhs.ip.addr)))
194 return False;
195 break;
196 case EPM_FLOOR_NMPIPES:
197 case EPM_FLOOR_LRPC:
198 case EPM_FLOOR_NETBIOS:
199 if (!prs_uint8s(False, "string", ps, depth,
200 floor->rhs.string,
201 floor->rhs.length))
202 return False;
203 break;
204 default:
205 break;
208 return True;
211 /*******************************************************************
212 Inits a EPM_TOWER structure.
213 ********************************************************************/
214 NTSTATUS init_epm_tower(TALLOC_CTX *ctx, EPM_TOWER *tower,
215 const EPM_FLOOR *floors, int num_floors)
217 int size = 0;
218 int i;
220 DEBUG(5, ("init_epm_tower\n"));
222 size += sizeof(uint16); /* number of floors is in tower length */
223 for (i = 0; i < num_floors; i++) {
224 size += (sizeof(uint16) * 2);
225 size += floors[i].lhs.length;
226 size += floors[i].rhs.length;
229 tower->max_length = tower->length = size;
230 tower->num_floors = num_floors;
231 tower->floors = talloc(ctx, sizeof(EPM_FLOOR) * num_floors);
232 if (!tower->floors) {
233 return NT_STATUS_NO_MEMORY;
235 memcpy(tower->floors, floors, sizeof(EPM_FLOOR) * num_floors);
236 tower->unknown = 0x7e;
238 return NT_STATUS_OK;
241 /*******************************************************************
242 Reads or writes an EPM_TOWER structure.
243 ********************************************************************/
244 BOOL epm_io_tower(const char *desc, EPM_TOWER *tower,
245 prs_struct *ps, int depth)
247 int i;
249 prs_debug(ps, depth, desc, "epm_io_tower");
250 depth++;
252 if (!prs_align(ps))
253 return False;
255 if (!prs_uint32("max_length", ps, depth, &tower->max_length))
256 return False;
257 if (!prs_uint32("length", ps, depth, &tower->length))
258 return False;
259 if (!prs_uint16("num_floors", ps, depth, &tower->num_floors))
260 return False;
262 if (UNMARSHALLING(ps)) {
263 tower->floors = talloc(ps->mem_ctx,
264 sizeof(EPM_FLOOR) * tower->num_floors);
265 if (!tower->floors)
266 return False;
269 for (i = 0; i < tower->num_floors; i++) {
270 if (!epm_io_floor("floor", tower->floors + i, ps, depth))
271 return False;
274 return True;
277 /*******************************************************************
278 Initialize an EPM_TOWER_ARRAY structure
279 ********************************************************************/
280 NTSTATUS init_epm_tower_array(TALLOC_CTX *ctx, EPM_TOWER_ARRAY *array,
281 const EPM_TOWER *towers, int num_towers)
283 int i;
285 array->max_count = num_towers;
286 array->offset = 0;
287 array->count = num_towers;
288 array->tower_ref_ids = talloc(ctx, sizeof(uint32) * num_towers);
289 if (!array->tower_ref_ids) {
290 return NT_STATUS_NO_MEMORY;
292 for (i=0;i<num_towers;i++)
293 array->tower_ref_ids[i] = ++internal_referent_id;
295 array->towers = talloc(ctx, sizeof(EPM_TOWER) * num_towers);
296 if (!array->towers) {
297 return NT_STATUS_NO_MEMORY;
299 memcpy(array->towers, towers, sizeof(EPM_TOWER) * num_towers);
301 return NT_STATUS_OK;
304 /*******************************************************************
305 Reads or writes an EPM_TOWER_ARRAY structure.
306 ********************************************************************/
307 BOOL epm_io_tower_array(const char *desc, EPM_TOWER_ARRAY *array,
308 prs_struct *ps, int depth)
310 int i;
312 prs_debug(ps, depth, desc, "epm_io_tower_array");
313 depth++;
315 if (!prs_uint32("max_count", ps, depth, &array->max_count))
316 return False;
317 if (!prs_uint32("offset", ps, depth, &array->offset))
318 return False;
319 if (!prs_uint32("count", ps, depth, &array->count))
320 return False;
323 if (UNMARSHALLING(ps)) {
324 array->tower_ref_ids = talloc(ps->mem_ctx,
325 sizeof(uint32) * array->count);
326 if (!array->tower_ref_ids) {
327 return False;
330 for (i=0; i < array->count; i++) {
331 if (!prs_uint32("ref_id", ps, depth, &array->tower_ref_ids[i])) {
332 return False;
333 } else {
334 if (array->tower_ref_ids[i] > internal_referent_id) {
335 internal_referent_id = array->tower_ref_ids[i];
342 if (!prs_set_offset(ps, prs_offset(ps) + array->offset))
343 return False;
345 if (UNMARSHALLING(ps)) {
346 array->towers = talloc(ps->mem_ctx,
347 sizeof(EPM_TOWER) * array->count);
348 if (!array->towers) {
349 return False;
353 for (i = 0; i < array->count; i++) {
354 if (!epm_io_tower("tower", &array->towers[i], ps, depth))
355 return False;
358 return True;
361 /*******************************************************************
362 Initialize EPM_R_MAP structure
363 ******************************************************************/
364 NTSTATUS init_epm_r_map(TALLOC_CTX *ctx, EPM_R_MAP *r_map,
365 const EPM_HANDLE *handle, const EPM_TOWER_ARRAY *array,
366 int num_elements, uint32 status)
368 memcpy(&r_map->handle, handle, sizeof(*handle));
369 r_map->num_results = num_elements;
370 r_map->results = talloc(ctx, sizeof(EPM_TOWER_ARRAY) * num_elements);
371 if (!r_map->results) {
372 return NT_STATUS_NO_MEMORY;
374 memcpy(r_map->results, array, sizeof(EPM_TOWER_ARRAY) * num_elements);
375 r_map->status = status;
376 return NT_STATUS_OK;
379 /*************************************************************************
380 Inits a EPM_Q_MAP structure.
381 **************************************************************************
382 * We attempt to hide the ugliness of the wire format by taking a EPM_TOWER
383 * array with a defined size
384 **************************************************************************/
385 NTSTATUS init_epm_q_map(TALLOC_CTX *ctx, EPM_Q_MAP *q_map,
386 const EPM_TOWER *towers, int num_towers)
388 static uint32 handle = 1;
390 ZERO_STRUCTP(q_map);
392 DEBUG(5, ("init_epm_q_map\n"));
393 q_map->handle.data[0] = (handle >> 0) & 0xFF;
394 q_map->handle.data[1] = (handle >> 8) & 0xFF;
395 q_map->handle.data[2] = (handle >> 16) & 0xFF;
396 q_map->handle.data[3] = (handle >> 24) & 0xFF;
398 q_map->tower = talloc(ctx, sizeof(EPM_TOWER) * (num_towers + 1));
399 if (!q_map->tower) {
400 return NT_STATUS_NO_MEMORY;
403 memcpy(q_map->tower, towers, sizeof(EPM_TOWER) * num_towers);
405 ZERO_STRUCT(q_map->tower[num_towers]);
407 /* For now let's not take more than 4 towers per result */
408 q_map->max_towers = num_towers * 4;
410 q_map->tower_ref_id = ++internal_referent_id;
412 handle++;
414 return NT_STATUS_OK;
417 /*****************************************************************
418 epm_io_q_map - read or write EPM_Q_MAP structure
419 ******************************************************************/
420 BOOL epm_io_q_map(const char *desc, EPM_Q_MAP *io_map, prs_struct *ps,
421 int depth)
423 prs_debug(ps, depth, desc, "epm_io_q_map");
424 depth++;
426 if (!epm_io_handle("handle", &io_map->handle, ps, depth))
427 return False;
429 if (!prs_uint32("referent_id", ps, 0, &io_map->tower_ref_id))
430 return False;
431 if (io_map->tower_ref_id > internal_referent_id)
432 internal_referent_id = io_map->tower_ref_id;
434 /* HACK: We need a more elegant way of doing this */
435 if (UNMARSHALLING(ps)) {
436 io_map->tower = talloc(ps->mem_ctx, sizeof(EPM_TOWER));
437 if (!io_map->tower)
438 return False;
440 if (!epm_io_tower("tower", io_map->tower, ps, depth))
441 return False;
442 if (!epm_io_handle("term_handle", &io_map->term_handle, ps, depth))
443 return False;
445 if (!prs_uint32("max_towers", ps, 0, &io_map->max_towers))
446 return False;
448 return True;
451 /*******************************************************************
452 epm_io_r_map - Read/Write EPM_R_MAP structure
453 ******************************************************************/
454 BOOL epm_io_r_map(const char *desc, EPM_R_MAP *io_map,
455 prs_struct *ps, int depth)
457 prs_debug(ps, depth, desc, "epm_io_r_map");
458 depth++;
460 if (!epm_io_handle("handle", &io_map->handle, ps, depth))
461 return False;
462 if (!prs_uint32("num_results", ps, depth, &io_map->num_results))
463 return False;
465 if (UNMARSHALLING(ps)) {
466 io_map->results = talloc(ps->mem_ctx,
467 sizeof(EPM_TOWER_ARRAY) *
468 io_map->num_results);
469 if (!io_map->results)
470 return False;
472 if (!epm_io_tower_array("results", io_map->results, ps, depth))
473 return False;
475 if (!prs_align(ps))
476 return False;
478 if (!prs_uint32("status", ps, depth, &io_map->status))
479 return False;
481 return True;