janitor duty (merges from 3.0) and cleanup compiler warning on SuSE 9 in the end...
[gd/samba/.git] / source3 / rpc_parse / parse_epmapper.c
index 9e21da04dd3bcd6b74354f2376bfc563150738c7..bc2cd175034922375549b052adef4cb70dd58750 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_PARSE
 
+static uint32 internal_referent_id = 0;
+
+
 /*******************************************************************
  Reads or writes a handle.
 ********************************************************************/
 BOOL epm_io_handle(const char *desc, EPM_HANDLE *handle, prs_struct *ps,
                   int depth)
 {
+       if (!prs_align(ps))
+               return False;
 
        if (!prs_uint8s(False, "data", ps, depth, handle->data, 
                        sizeof(handle->data)))
@@ -40,32 +45,37 @@ BOOL epm_io_handle(const char *desc, EPM_HANDLE *handle, prs_struct *ps,
 /*******************************************************************
  inits an EPM_FLOOR structure.
 ********************************************************************/
-NTSTATUS init_epm_floor(EPM_FLOOR *floor, uint8 protocol)
+NTSTATUS init_epm_floor(EPM_FLOOR *efloor, uint8 protocol)
 {
        /* handle lhs */
-       floor->lhs.protocol = protocol;
-       floor->lhs.length = sizeof(floor->lhs.protocol);
+       efloor->lhs.protocol = protocol;
+       efloor->lhs.length = sizeof(efloor->lhs.protocol);
 
-       switch(floor->lhs.protocol) {
+       switch(efloor->lhs.protocol) {
        case EPM_FLOOR_UUID:
-               floor->lhs.length += sizeof(floor->lhs.uuid.uuid);
-               floor->lhs.length += sizeof(floor->lhs.uuid.version);
+               efloor->lhs.length += sizeof(efloor->lhs.uuid.uuid);
+               efloor->lhs.length += sizeof(efloor->lhs.uuid.version);
                break;
        default:
                break;
        }
 
        /* handle rhs */
-       switch(floor->lhs.protocol) {
+       switch(efloor->lhs.protocol) {
        case EPM_FLOOR_RPC:
        case EPM_FLOOR_UUID:
-               floor->rhs.length = sizeof(floor->rhs.unknown);
+               efloor->rhs.length = sizeof(efloor->rhs.unknown);
                break;
        case EPM_FLOOR_TCP:
-               floor->rhs.length = sizeof(floor->rhs.tcp.port);
+               efloor->rhs.length = sizeof(efloor->rhs.tcp.port);
                break;
        case EPM_FLOOR_IP:
-               floor->rhs.length = sizeof(floor->rhs.ip.addr);
+               efloor->rhs.length = sizeof(efloor->rhs.ip.addr);
+               break;
+       case EPM_FLOOR_NMPIPES:
+       case EPM_FLOOR_LRPC:
+       case EPM_FLOOR_NETBIOS:
+               efloor->rhs.length = strlen(efloor->rhs.string) + 1;
                break;
        default:
                break;
@@ -77,83 +87,118 @@ NTSTATUS init_epm_floor(EPM_FLOOR *floor, uint8 protocol)
 /*******************************************************************
  inits an EPM_FLOOR structure with a UUID
 ********************************************************************/
-NTSTATUS init_epm_floor_uuid(EPM_FLOOR *floor,
-                            const RPC_UUID *uuid, uint16 version)
+NTSTATUS init_epm_floor_uuid(EPM_FLOOR *efloor,
+                            const struct uuid uuid, uint16 version)
 {
-       memcpy(&floor->lhs.uuid.uuid, uuid, sizeof(*uuid));
-       floor->lhs.uuid.version = version;
-       floor->rhs.unknown = 0;
-       return init_epm_floor(floor, EPM_FLOOR_UUID);
+       memcpy(&efloor->lhs.uuid.uuid, &uuid, sizeof(uuid));
+       efloor->lhs.uuid.version = version;
+       efloor->rhs.unknown = 0;
+       return init_epm_floor(efloor, EPM_FLOOR_UUID);
 }
 
 /*******************************************************************
  inits an EPM_FLOOR structure for RPC
 ********************************************************************/
-NTSTATUS init_epm_floor_rpc(EPM_FLOOR *floor)
+NTSTATUS init_epm_floor_rpc(EPM_FLOOR *efloor)
 {
-       floor->rhs.unknown = 0;
-       return init_epm_floor(floor, EPM_FLOOR_RPC);
+       efloor->rhs.unknown = 0;
+       return init_epm_floor(efloor, EPM_FLOOR_RPC);
 }
 
 /*******************************************************************
  inits an EPM_FLOOR structure for TCP
 ********************************************************************/
-NTSTATUS init_epm_floor_tcp(EPM_FLOOR *floor, uint16 port)
+NTSTATUS init_epm_floor_tcp(EPM_FLOOR *efloor, uint16 port)
 {
-       floor->rhs.tcp.port = htons(port);
-       return init_epm_floor(floor, EPM_FLOOR_TCP);
+       efloor->rhs.tcp.port = htons(port);
+       return init_epm_floor(efloor, EPM_FLOOR_TCP);
 }
 
 /*******************************************************************
  inits an EPM_FLOOR structure for IP
 ********************************************************************/
-NTSTATUS init_epm_floor_ip(EPM_FLOOR *floor, uint8 addr[4])
+NTSTATUS init_epm_floor_ip(EPM_FLOOR *efloor, uint8 addr[4])
+{
+       memcpy(&efloor->rhs.ip.addr, addr, sizeof(addr));
+       return init_epm_floor(efloor, EPM_FLOOR_IP);
+}
+
+/*******************************************************************
+ inits an EPM_FLOOR structure for named pipe
+********************************************************************/
+NTSTATUS init_epm_floor_np(EPM_FLOOR *efloor, const char *pipe_name)
 {
-       memcpy(&floor->rhs.ip.addr, addr, sizeof(addr));
-       return init_epm_floor(floor, EPM_FLOOR_IP);
+       safe_strcpy(efloor->rhs.string, pipe_name, sizeof(efloor->rhs.string)-1);
+       return init_epm_floor(efloor, EPM_FLOOR_NMPIPES);
+}
+
+/*******************************************************************
+ inits an EPM_FLOOR structure for named pipe
+********************************************************************/
+NTSTATUS init_epm_floor_lrpc(EPM_FLOOR *efloor, const char *pipe_name)
+{
+       safe_strcpy(efloor->rhs.string, pipe_name, sizeof(efloor->rhs.string)-1);
+       return init_epm_floor(efloor, EPM_FLOOR_LRPC);
+}
+
+/*******************************************************************
+ inits an EPM_FLOOR structure for named pipe
+********************************************************************/
+NTSTATUS init_epm_floor_nb(EPM_FLOOR *efloor, char *host_name)
+{
+       safe_strcpy(efloor->rhs.string, host_name, sizeof(efloor->rhs.string)-1);
+       return init_epm_floor(efloor, EPM_FLOOR_NETBIOS);
 }
 
 /*******************************************************************
  reads and writes EPM_FLOOR.
 ********************************************************************/
-BOOL epm_io_floor(const char *desc, EPM_FLOOR *floor,
+BOOL epm_io_floor(const char *desc, EPM_FLOOR *efloor,
                  prs_struct *ps, int depth)
 {
        prs_debug(ps, depth, desc, "epm_io_floor");
        depth++;
 
-       if (!prs_uint16("lhs_length", ps, depth, &floor->lhs.length))
+       if (!prs_uint16("lhs_length", ps, depth, &efloor->lhs.length))
                return False;
-       if (!prs_uint8("protocol", ps, depth, &floor->lhs.protocol))
+       if (!prs_uint8("protocol", ps, depth, &efloor->lhs.protocol))
                return False;
 
-       switch (floor->lhs.protocol) {
+       switch (efloor->lhs.protocol) {
        case EPM_FLOOR_UUID:
-               if (!smb_io_rpc_uuid("uuid", &floor->lhs.uuid.uuid, ps, depth))
+               if (!smb_io_uuid("uuid", &efloor->lhs.uuid.uuid, ps, depth))
                        return False;
                if (!prs_uint16("version", ps, depth, 
-                               &floor->lhs.uuid.version))
+                               &efloor->lhs.uuid.version))
                        return False;
                break;
        }
 
-       if (!prs_uint16("rhs_length", ps, depth, &floor->rhs.length))
+       if (!prs_uint16("rhs_length", ps, depth, &efloor->rhs.length))
                return False;
 
-       switch (floor->lhs.protocol) {
+       switch (efloor->lhs.protocol) {
        case EPM_FLOOR_UUID:
        case EPM_FLOOR_RPC:
-               if (!prs_uint16("unknown", ps, depth, &floor->rhs.unknown))
+               if (!prs_uint16("unknown", ps, depth, &efloor->rhs.unknown))
                        return False;
                break;
        case EPM_FLOOR_TCP:
-               if (!prs_uint16("tcp_port", ps, depth, &floor->rhs.tcp.port))
+               if (!prs_uint16("tcp_port", ps, depth, &efloor->rhs.tcp.port))
                        return False;
                break;
        case EPM_FLOOR_IP:
                if (!prs_uint8s(False, "ip_addr", ps, depth, 
-                               floor->rhs.ip.addr,
-                               sizeof(floor->rhs.ip.addr)))
+                               efloor->rhs.ip.addr,
+                               sizeof(efloor->rhs.ip.addr)))
+                       return False;
+               break;
+       case EPM_FLOOR_NMPIPES:
+       case EPM_FLOOR_LRPC:
+       case EPM_FLOOR_NETBIOS:
+               if (!prs_uint8s(False, "string", ps, depth,
+                               efloor->rhs.string,
+                               efloor->rhs.length))
                        return False;
                break;
        default:
@@ -169,20 +214,18 @@ BOOL epm_io_floor(const char *desc, EPM_FLOOR *floor,
 NTSTATUS init_epm_tower(TALLOC_CTX *ctx, EPM_TOWER *tower, 
                        const EPM_FLOOR *floors, int num_floors)
 {
-       static uint32 internal_referent_id = 0;
        int size = 0;
        int i;
 
        DEBUG(5, ("init_epm_tower\n"));
 
+       size += sizeof(uint16); /* number of floors is in tower length */
        for (i = 0; i < num_floors; i++) {
-               size += (sizeof(uint32) * 2);
+               size += (sizeof(uint16) * 2);
                size += floors[i].lhs.length;
                size += floors[i].rhs.length;
        }
-       size += sizeof(uint8); /* this could be aligning... */
 
-       tower->referent_id = ++internal_referent_id;
        tower->max_length = tower->length = size;
        tower->num_floors = num_floors;
        tower->floors = talloc(ctx, sizeof(EPM_FLOOR) * num_floors);
@@ -206,8 +249,9 @@ BOOL epm_io_tower(const char *desc, EPM_TOWER *tower,
        prs_debug(ps, depth, desc, "epm_io_tower");
        depth++;
 
-       if (!prs_uint32("referent_id", ps, depth, &tower->referent_id))
+       if (!prs_align(ps))
                return False;
+
        if (!prs_uint32("max_length", ps, depth, &tower->max_length))
                return False;
        if (!prs_uint32("length", ps, depth, &tower->length))
@@ -227,9 +271,6 @@ BOOL epm_io_tower(const char *desc, EPM_TOWER *tower,
                        return False;
        }
 
-       if (!prs_uint8("unknown", ps, depth, &tower->unknown))
-               return False;
-
        return True;
 }
 
@@ -239,9 +280,18 @@ BOOL epm_io_tower(const char *desc, EPM_TOWER *tower,
 NTSTATUS init_epm_tower_array(TALLOC_CTX *ctx, EPM_TOWER_ARRAY *array,
                              const EPM_TOWER *towers, int num_towers)
 {
+       int i;
+
        array->max_count = num_towers;
        array->offset = 0;
        array->count = num_towers;
+       array->tower_ref_ids = talloc(ctx, sizeof(uint32) * num_towers);
+       if (!array->tower_ref_ids) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       for (i=0;i<num_towers;i++)
+               array->tower_ref_ids[i] = ++internal_referent_id;
+
        array->towers = talloc(ctx, sizeof(EPM_TOWER) * num_towers);
        if (!array->towers) {
                return NT_STATUS_NO_MEMORY;
@@ -269,6 +319,26 @@ BOOL epm_io_tower_array(const char *desc, EPM_TOWER_ARRAY *array,
        if (!prs_uint32("count", ps, depth, &array->count))
                return False;
 
+
+       if (UNMARSHALLING(ps)) {
+               array->tower_ref_ids = talloc(ps->mem_ctx,
+                                             sizeof(uint32) * array->count);
+               if (!array->tower_ref_ids) {
+                       return False;
+               }
+       }
+       for (i=0; i < array->count; i++) {
+               if (!prs_uint32("ref_id", ps, depth, &array->tower_ref_ids[i])) {
+                       return False;
+               } else {
+                       if (array->tower_ref_ids[i] > internal_referent_id) {
+                               internal_referent_id = array->tower_ref_ids[i];
+                       }
+               }
+       }
+                       
+                       
+
        if (!prs_set_offset(ps, prs_offset(ps) + array->offset))
                return False;
 
@@ -281,7 +351,7 @@ BOOL epm_io_tower_array(const char *desc, EPM_TOWER_ARRAY *array,
        }
 
        for (i = 0; i < array->count; i++) {
-               if (!epm_io_tower("tower", array->towers + 1, ps, depth))
+               if (!epm_io_tower("tower", &array->towers[i], ps, depth))
                        return False;
        }
 
@@ -337,6 +407,8 @@ NTSTATUS init_epm_q_map(TALLOC_CTX *ctx, EPM_Q_MAP *q_map,
        /* For now let's not take more than 4 towers per result */
        q_map->max_towers = num_towers * 4;
 
+       q_map->tower_ref_id = ++internal_referent_id;
+
        handle++;
 
        return NT_STATUS_OK;
@@ -345,7 +417,8 @@ NTSTATUS init_epm_q_map(TALLOC_CTX *ctx, EPM_Q_MAP *q_map,
 /*****************************************************************
   epm_io_q_map - read or write EPM_Q_MAP structure
 ******************************************************************/
-BOOL epm_io_q_map(char *desc, EPM_Q_MAP *io_map, prs_struct *ps, int depth)
+BOOL epm_io_q_map(const char *desc, EPM_Q_MAP *io_map, prs_struct *ps, 
+                 int depth)
 {
        prs_debug(ps, depth, desc, "epm_io_q_map");
        depth++;
@@ -353,6 +426,11 @@ BOOL epm_io_q_map(char *desc, EPM_Q_MAP *io_map, prs_struct *ps, int depth)
        if (!epm_io_handle("handle", &io_map->handle, ps, depth))
                return False;
 
+       if (!prs_uint32("referent_id", ps, 0, &io_map->tower_ref_id))
+               return False;
+       if (io_map->tower_ref_id > internal_referent_id)
+               internal_referent_id = io_map->tower_ref_id;
+
        /* HACK: We need a more elegant way of doing this */
        if (UNMARSHALLING(ps)) {
                io_map->tower = talloc(ps->mem_ctx, sizeof(EPM_TOWER));
@@ -373,11 +451,9 @@ BOOL epm_io_q_map(char *desc, EPM_Q_MAP *io_map, prs_struct *ps, int depth)
 /*******************************************************************
   epm_io_r_map - Read/Write EPM_R_MAP structure
 ******************************************************************/
-BOOL epm_io_r_map(char *desc, EPM_R_MAP *io_map,
+BOOL epm_io_r_map(const char *desc, EPM_R_MAP *io_map,
                  prs_struct *ps, int depth)
 {
-       int i;
-
        prs_debug(ps, depth, desc, "epm_io_r_map");
        depth++;
 
@@ -393,11 +469,11 @@ BOOL epm_io_r_map(char *desc, EPM_R_MAP *io_map,
                if (!io_map->results)
                        return False;
        }
-       for (i = 0; i < io_map->num_results; i++) {
-               if (!epm_io_tower_array("results", io_map->results + i,
-                                       ps, depth))
+       if (!epm_io_tower_array("results", io_map->results, ps, depth))
                        return False;
-       }
+
+       if (!prs_align(ps))
+               return False;
 
        if (!prs_uint32("status", ps, depth, &io_map->status))
                return False;