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.
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
,
38 if (!prs_uint8s(False
, "data", ps
, depth
, handle
->data
,
39 sizeof(handle
->data
)))
45 /*******************************************************************
46 inits an EPM_FLOOR structure.
47 ********************************************************************/
48 NTSTATUS
init_epm_floor(EPM_FLOOR
*floor
, uint8 protocol
)
51 floor
->lhs
.protocol
= protocol
;
52 floor
->lhs
.length
= sizeof(floor
->lhs
.protocol
);
54 switch(floor
->lhs
.protocol
) {
56 floor
->lhs
.length
+= sizeof(floor
->lhs
.uuid
.uuid
);
57 floor
->lhs
.length
+= sizeof(floor
->lhs
.uuid
.version
);
64 switch(floor
->lhs
.protocol
) {
67 floor
->rhs
.length
= sizeof(floor
->rhs
.unknown
);
70 floor
->rhs
.length
= sizeof(floor
->rhs
.tcp
.port
);
73 floor
->rhs
.length
= sizeof(floor
->rhs
.ip
.addr
);
75 case EPM_FLOOR_NMPIPES
:
77 case EPM_FLOOR_NETBIOS
:
78 floor
->rhs
.length
= strlen(floor
->rhs
.string
) + 1;
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");
162 if (!prs_uint16("lhs_length", ps
, depth
, &floor
->lhs
.length
))
164 if (!prs_uint8("protocol", ps
, depth
, &floor
->lhs
.protocol
))
167 switch (floor
->lhs
.protocol
) {
169 if (!smb_io_uuid("uuid", &floor
->lhs
.uuid
.uuid
, ps
, depth
))
171 if (!prs_uint16("version", ps
, depth
,
172 &floor
->lhs
.uuid
.version
))
177 if (!prs_uint16("rhs_length", ps
, depth
, &floor
->rhs
.length
))
180 switch (floor
->lhs
.protocol
) {
183 if (!prs_uint16("unknown", ps
, depth
, &floor
->rhs
.unknown
))
187 if (!prs_uint16("tcp_port", ps
, depth
, &floor
->rhs
.tcp
.port
))
191 if (!prs_uint8s(False
, "ip_addr", ps
, depth
,
193 sizeof(floor
->rhs
.ip
.addr
)))
196 case EPM_FLOOR_NMPIPES
:
198 case EPM_FLOOR_NETBIOS
:
199 if (!prs_uint8s(False
, "string", ps
, depth
,
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
)
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;
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
)
249 prs_debug(ps
, depth
, desc
, "epm_io_tower");
255 if (!prs_uint32("max_length", ps
, depth
, &tower
->max_length
))
257 if (!prs_uint32("length", ps
, depth
, &tower
->length
))
259 if (!prs_uint16("num_floors", ps
, depth
, &tower
->num_floors
))
262 if (UNMARSHALLING(ps
)) {
263 tower
->floors
= talloc(ps
->mem_ctx
,
264 sizeof(EPM_FLOOR
) * tower
->num_floors
);
269 for (i
= 0; i
< tower
->num_floors
; i
++) {
270 if (!epm_io_floor("floor", tower
->floors
+ i
, ps
, depth
))
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
)
285 array
->max_count
= num_towers
;
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
);
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
)
312 prs_debug(ps
, depth
, desc
, "epm_io_tower_array");
315 if (!prs_uint32("max_count", ps
, depth
, &array
->max_count
))
317 if (!prs_uint32("offset", ps
, depth
, &array
->offset
))
319 if (!prs_uint32("count", ps
, depth
, &array
->count
))
323 if (UNMARSHALLING(ps
)) {
324 array
->tower_ref_ids
= talloc(ps
->mem_ctx
,
325 sizeof(uint32
) * array
->count
);
326 if (!array
->tower_ref_ids
) {
330 for (i
=0; i
< array
->count
; i
++) {
331 if (!prs_uint32("ref_id", ps
, depth
, &array
->tower_ref_ids
[i
])) {
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
))
345 if (UNMARSHALLING(ps
)) {
346 array
->towers
= talloc(ps
->mem_ctx
,
347 sizeof(EPM_TOWER
) * array
->count
);
348 if (!array
->towers
) {
353 for (i
= 0; i
< array
->count
; i
++) {
354 if (!epm_io_tower("tower", &array
->towers
[i
], ps
, depth
))
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
;
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;
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));
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
;
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
,
423 prs_debug(ps
, depth
, desc
, "epm_io_q_map");
426 if (!epm_io_handle("handle", &io_map
->handle
, ps
, depth
))
429 if (!prs_uint32("referent_id", ps
, 0, &io_map
->tower_ref_id
))
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
));
440 if (!epm_io_tower("tower", io_map
->tower
, ps
, depth
))
442 if (!epm_io_handle("term_handle", &io_map
->term_handle
, ps
, depth
))
445 if (!prs_uint32("max_towers", ps
, 0, &io_map
->max_towers
))
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");
460 if (!epm_io_handle("handle", &io_map
->handle
, ps
, depth
))
462 if (!prs_uint32("num_results", ps
, depth
, &io_map
->num_results
))
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
)
472 if (!epm_io_tower_array("results", io_map
->results
, ps
, depth
))
478 if (!prs_uint32("status", ps
, depth
, &io_map
->status
))