diff options
author | Günther Deschner <gd@samba.org> | 2011-02-08 14:17:14 +0100 |
---|---|---|
committer | Günther Deschner <gd@samba.org> | 2011-02-10 22:13:17 +0100 |
commit | 4063bde3edd15b241f2b93bb5aedfef57ec4df91 (patch) | |
tree | 78ee85791d7f3a257c6775067562aee866d5305f /source3/rpc_server/srv_epmapper.c | |
parent | 1fc14a6543bfc5f087ed0ddf02bc7ce28a4d9ed4 (diff) | |
download | samba-4063bde3edd15b241f2b93bb5aedfef57ec4df91.tar.gz samba-4063bde3edd15b241f2b93bb5aedfef57ec4df91.tar.bz2 samba-4063bde3edd15b241f2b93bb5aedfef57ec4df91.zip |
s3-rpc_server: move services into individual directories.
Guenther
Autobuild-User: Günther Deschner <gd@samba.org>
Autobuild-Date: Thu Feb 10 22:13:17 CET 2011 on sn-devel-104
Diffstat (limited to 'source3/rpc_server/srv_epmapper.c')
-rw-r--r-- | source3/rpc_server/srv_epmapper.c | 1038 |
1 files changed, 0 insertions, 1038 deletions
diff --git a/source3/rpc_server/srv_epmapper.c b/source3/rpc_server/srv_epmapper.c deleted file mode 100644 index 5bfb176b84..0000000000 --- a/source3/rpc_server/srv_epmapper.c +++ /dev/null @@ -1,1038 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Endpoint server for the epmapper pipe - - Copyright (C) 2010-2011 Andreas Schneider <asn@samba.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "../libcli/security/security.h" -#include "librpc/gen_ndr/ndr_epmapper.h" -#include "librpc/gen_ndr/srv_epmapper.h" - -typedef uint32_t error_status_t; - -/* An endpoint combined with an interface description */ -struct dcesrv_ep_iface { - const char *name; - struct ndr_syntax_id syntax_id; - struct epm_tower ep; -}; - -/* A rpc service interface like samr, lsarpc or netlogon */ -struct dcesrv_iface { - const char *name; - struct ndr_syntax_id syntax_id; -}; - -struct dcesrv_iface_list { - struct dcesrv_iface_list *next, *prev; - struct dcesrv_iface *iface; -}; - -/* - * An endpoint can serve multiple rpc services interfaces. - * For example \\pipe\netlogon can be used by lsarpc and netlogon. - */ -struct dcesrv_endpoint { - struct dcesrv_endpoint *next, *prev; - - /* The type and the location of the endpoint */ - struct dcerpc_binding *ep_description; - - /* A list of rpc services able to connect to the endpoint */ - struct dcesrv_iface_list *iface_list; -}; - -struct rpc_eps { - struct dcesrv_ep_iface *e; - uint32_t count; -}; - -static struct dcesrv_endpoint *endpoint_table; - -/* - * Check if the UUID and if_version match to an interface. - */ -static bool interface_match(const struct dcesrv_iface *if1, - const struct dcesrv_iface *if2) -{ - return GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid); -} - -/* - * Find the interface operations on an endpoint. - */ -static const struct dcesrv_iface *find_interface(const struct dcesrv_endpoint *endpoint, - const struct dcesrv_iface *iface) -{ - struct dcesrv_iface_list *iflist; - - for (iflist = endpoint->iface_list; iflist; iflist = iflist->next) { - if (interface_match(iflist->iface, iface)) { - return iflist->iface; - } - } - - return NULL; -} - -/* - * See if a uuid and if_version match to an interface - */ -static bool interface_match_by_uuid(const struct dcesrv_iface *iface, - const struct GUID *uuid) -{ - return GUID_equal(&iface->syntax_id.uuid, uuid); -} - -static struct dcesrv_iface_list *find_interface_list(const struct dcesrv_endpoint *endpoint, - const struct dcesrv_iface *iface) -{ - struct dcesrv_iface_list *iflist; - - for (iflist = endpoint->iface_list; iflist; iflist = iflist->next) { - if (interface_match(iflist->iface, iface)) { - return iflist; - } - } - - return NULL; -} - -/* - * Check if two endpoints match. - */ -static bool endpoints_match(const struct dcerpc_binding *ep1, - const struct dcerpc_binding *ep2) -{ - if (ep1->transport != ep2->transport) { - return false; - } - - if (!ep1->endpoint || !ep2->endpoint) { - return ep1->endpoint == ep2->endpoint; - } - - if (!strequal(ep1->endpoint, ep2->endpoint)) { - return false; - } - - return true; -} - -static struct dcesrv_endpoint *find_endpoint(struct dcesrv_endpoint *endpoint_list, - struct dcerpc_binding *ep_description) { - struct dcesrv_endpoint *ep; - - for (ep = endpoint_list; ep != NULL; ep = ep->next) { - if (endpoints_match(ep->ep_description, ep_description)) { - return ep; - } - } - - return NULL; -} - -/* - * Build a list of all interfaces handled by all endpoint servers. - */ -static uint32_t build_ep_list(TALLOC_CTX *mem_ctx, - struct dcesrv_endpoint *endpoint_list, - const struct GUID *uuid, - struct dcesrv_ep_iface **peps) -{ - struct dcesrv_ep_iface *eps = NULL; - struct dcesrv_endpoint *d; - uint32_t total = 0; - NTSTATUS status; - - *peps = NULL; - - for (d = endpoint_list; d != NULL; d = d->next) { - struct dcesrv_iface_list *iface; - struct dcerpc_binding *description; - - for (iface = d->iface_list; iface != NULL; iface = iface->next) { - if (uuid && !interface_match_by_uuid(iface->iface, uuid)) { - continue; - } - - eps = talloc_realloc(mem_ctx, - eps, - struct dcesrv_ep_iface, - total + 1); - if (eps == NULL) { - return 0; - } - eps[total].name = talloc_strdup(eps, - iface->iface->name); - eps[total].syntax_id = iface->iface->syntax_id; - - description = d->ep_description; - description->object = iface->iface->syntax_id; - - status = dcerpc_binding_build_tower(eps, - description, - &eps[total].ep); - if (NT_STATUS_IS_ERR(status)) { - DEBUG(1, ("Unable to build tower for %s\n", - iface->iface->name)); - continue; - } - total++; - } - } - - *peps = eps; - - return total; -} - -static bool is_priviledged_pipe(struct auth_serversupplied_info *info) { - /* If the user is not root, or has the system token, fail */ - if ((info->utok.uid != sec_initial_uid()) && - !security_token_is_system(info->security_token)) { - return false; - } - - return true; -} - -/* - * epm_Insert - * - * Add the specified entries to an endpoint map. - */ -error_status_t _epm_Insert(struct pipes_struct *p, - struct epm_Insert *r) -{ - TALLOC_CTX *tmp_ctx; - error_status_t rc; - NTSTATUS status; - uint32_t i; - - /* If this is not a priviledged users, return */ - if (!is_priviledged_pipe(p->server_info)) { - return EPMAPPER_STATUS_CANT_PERFORM_OP; - } - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return EPMAPPER_STATUS_NO_MEMORY; - } - - DEBUG(3, ("_epm_Insert: Trying to add %u new entries.\n", - r->in.num_ents)); - - for (i = 0; i < r->in.num_ents; i++) { - struct dcerpc_binding *b = NULL; - struct dcesrv_endpoint *ep; - struct dcesrv_iface_list *iflist; - struct dcesrv_iface *iface; - bool add_ep = false; - - status = dcerpc_binding_from_tower(tmp_ctx, - &r->in.entries[i].tower->tower, - &b); - if (!NT_STATUS_IS_OK(status)) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - - DEBUG(3, ("_epm_Insert: Adding transport %s for %s\n", - derpc_transport_string_by_transport(b->transport), - r->in.entries[i].annotation)); - - /* Check if the entry already exits */ - ep = find_endpoint(endpoint_table, b); - if (ep == NULL) { - /* No entry found, create it */ - ep = talloc_zero(NULL, struct dcesrv_endpoint); - if (ep == NULL) { - rc = EPMAPPER_STATUS_CANT_PERFORM_OP; - goto done; - } - add_ep = true; - - ep->ep_description = talloc_steal(ep, b); - } - - /* TODO Replace the entry if the replace flag is set */ - - /* Create an interface */ - iface = talloc(tmp_ctx, struct dcesrv_iface); - if (iface == NULL) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - - iface->name = talloc_strdup(iface, r->in.entries[i].annotation); - if (iface->name == NULL) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - iface->syntax_id = b->object; - - /* - * Check if the rpc service is alrady registered on the - * endpoint. - */ - if (find_interface(ep, iface) != NULL) { - DEBUG(0, ("dcesrv_interface_register: interface '%s' " - "already registered on endpoint\n", - iface->name)); - /* FIXME wrong error code? */ - rc = EPMAPPER_STATUS_OK; - goto done; - } - - /* Create an entry for the interface */ - iflist = talloc(ep, struct dcesrv_iface_list); - if (iflist == NULL) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - iflist->iface = talloc_move(iflist, &iface); - - /* Finally add the interface on the endpoint */ - DLIST_ADD(ep->iface_list, iflist); - - /* If it's a new endpoint add it to the endpoint_table */ - if (add_ep) { - DLIST_ADD(endpoint_table, ep); - } - } - - rc = EPMAPPER_STATUS_OK; -done: - talloc_free(tmp_ctx); - - return rc; -} - - -/* - * epm_Delete - * - * Delete the specified entries from an endpoint map. - */ -error_status_t _epm_Delete(struct pipes_struct *p, - struct epm_Delete *r) -{ - TALLOC_CTX *tmp_ctx; - error_status_t rc; - NTSTATUS status; - uint32_t i; - - DEBUG(3, ("_epm_Delete: Trying to delete %u entries.\n", - r->in.num_ents)); - - /* If this is not a priviledged users, return */ - if (!is_priviledged_pipe(p->server_info)) { - return EPMAPPER_STATUS_CANT_PERFORM_OP; - } - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return EPMAPPER_STATUS_NO_MEMORY; - } - - for (i = 0; i < r->in.num_ents; i++) { - struct dcerpc_binding *b = NULL; - struct dcesrv_endpoint *ep; - struct dcesrv_iface iface; - struct dcesrv_iface_list *iflist; - - status = dcerpc_binding_from_tower(tmp_ctx, - &r->in.entries[i].tower->tower, - &b); - if (!NT_STATUS_IS_OK(status)) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - - DEBUG(3, ("_epm_Delete: Deleting transport '%s' for '%s'\n", - derpc_transport_string_by_transport(b->transport), - r->in.entries[i].annotation)); - - ep = find_endpoint(endpoint_table, b); - if (ep == NULL) { - rc = EPMAPPER_STATUS_OK; - goto done; - } - - iface.name = r->in.entries[i].annotation; - iface.syntax_id = b->object; - - iflist = find_interface_list(ep, &iface); - if (iflist == NULL) { - DEBUG(0, ("_epm_Delete: No interfaces left, delete endpoint\n")); - DLIST_REMOVE(endpoint_table, ep); - talloc_free(ep); - - rc = EPMAPPER_STATUS_OK; - goto done; - } - - DLIST_REMOVE(ep->iface_list, iflist); - - if (ep->iface_list == NULL) { - DEBUG(0, ("_epm_Delete: No interfaces left, delete endpoint\n")); - DLIST_REMOVE(endpoint_table, ep); - talloc_free(ep); - - rc = EPMAPPER_STATUS_OK; - goto done; - } - - } - - rc = EPMAPPER_STATUS_OK; -done: - talloc_free(tmp_ctx); - - return rc; -} - - -/* - * epm_Lookup - * - * Lookup entries in an endpoint map. - */ -error_status_t _epm_Lookup(struct pipes_struct *p, - struct epm_Lookup *r) -{ - struct policy_handle *entry_handle; - struct rpc_eps *eps; - TALLOC_CTX *tmp_ctx; - error_status_t rc; - uint32_t count = 0; - uint32_t num_ents = 0; - uint32_t i; - bool match = false; - bool ok; - - *r->out.num_ents = 0; - r->out.entries = NULL; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return EPMAPPER_STATUS_NO_MEMORY; - } - - DEBUG(3, ("_epm_Lookup: Trying to lookup max. %u entries.\n", - r->in.max_ents)); - - if (r->in.entry_handle == NULL || - policy_handle_empty(r->in.entry_handle)) { - struct GUID *obj; - - DEBUG(5, ("_epm_Lookup: No entry_handle found, creating it.\n")); - - eps = talloc_zero(tmp_ctx, struct rpc_eps); - if (eps == NULL) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - - if (r->in.object == NULL || GUID_all_zero(r->in.object)) { - obj = NULL; - } else { - obj = r->in.object; - } - - switch (r->in.inquiry_type) { - case RPC_C_EP_ALL_ELTS: - /* - * Return all elements from the endpoint map. The - * interface_id, vers_option, and object parameters MUST - * be ignored. - */ - eps->count = build_ep_list(eps, - endpoint_table, - NULL, - &eps->e); - break; - case RPC_C_EP_MATCH_BY_IF: - /* - * Return endpoint map elements that contain the - * interface identifier specified by the interface_id - * and vers_option values. - * - * RPC_C_EP_MATCH_BY_IF and RPC_C_EP_MATCH_BY_BOTH - * need both the same endpoint list. There is a second - * check for the inquiry_type below which differentiates - * between them. - */ - case RPC_C_EP_MATCH_BY_BOTH: - /* - * Return endpoint map elements that contain the - * interface identifier and object UUID specified by - * interface_id, vers_option, and object. - */ - eps->count = build_ep_list(eps, - endpoint_table, - &r->in.interface_id->uuid, - &eps->e); - break; - case RPC_C_EP_MATCH_BY_OBJ: - /* - * Return endpoint map elements that contain the object - * UUID specified by object. - */ - eps->count = build_ep_list(eps, - endpoint_table, - r->in.object, - &eps->e); - break; - default: - rc = EPMAPPER_STATUS_CANT_PERFORM_OP; - goto done; - } - - if (eps->count == 0) { - rc = EPMAPPER_STATUS_NO_MORE_ENTRIES; - goto done; - } - - ok = create_policy_hnd(p, r->out.entry_handle, eps); - if (!ok) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - - ok = find_policy_by_hnd(p, r->out.entry_handle, (void **)(void*) &eps); - if (!ok) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - entry_handle = r->out.entry_handle; - } else { - DEBUG(5, ("_epm_Lookup: Trying to find entry_handle.\n")); - - ok = find_policy_by_hnd(p, r->in.entry_handle, (void **)(void*) &eps); - if (!ok) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - entry_handle = r->in.entry_handle; - } - - if (eps == NULL || eps->e == NULL) { - rc = EPMAPPER_STATUS_NO_MORE_ENTRIES; - goto done; - } - - /* return the next N elements */ - count = r->in.max_ents; - if (count > eps->count) { - count = eps->count; - } - - DEBUG(3, ("_epm_Lookup: Find %u entries\n", count)); - - if (count == 0) { - close_policy_hnd(p, entry_handle); - ZERO_STRUCTP(r->out.entry_handle); - - rc = EPMAPPER_STATUS_NO_MORE_ENTRIES; - goto done; - } - - r->out.entries = talloc_array(p->mem_ctx, struct epm_entry_t, count); - if (r->out.entries == NULL) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - - for (i = 0; i < count; i++) { - match = false; - - switch (r->in.inquiry_type) { - case RPC_C_EP_ALL_ELTS: - /* - * Return all elements from the endpoint map. The - * interface_id, vers_option, and object parameters MUST - * be ignored. - */ - match = true; - break; - case RPC_C_EP_MATCH_BY_IF: - /* - * Return endpoint map elements that contain the - * interface identifier specified by the interface_id - * and vers_option values. - */ - if (GUID_equal(&r->in.interface_id->uuid, - &eps->e[i].syntax_id.uuid)) { - match = true; - } - break; - case RPC_C_EP_MATCH_BY_OBJ: - /* - * Return endpoint map elements that contain the object - * UUID specified by object. - */ - if (GUID_equal(r->in.object, - &eps->e[i].syntax_id.uuid)) { - match = true; - } - break; - case RPC_C_EP_MATCH_BY_BOTH: - /* - * Return endpoint map elements that contain the - * interface identifier and object UUID specified by - * interface_id, vers_option, and object. - */ - if (GUID_equal(&r->in.interface_id->uuid, - &eps->e[i].syntax_id.uuid) && - GUID_equal(r->in.object, &eps->e[i].syntax_id.uuid)) { - match = true; - } - break; - default: - return EPMAPPER_STATUS_CANT_PERFORM_OP; - } - - if (match) { - if (r->in.inquiry_type == RPC_C_EP_MATCH_BY_IF || - r->in.inquiry_type == RPC_C_EP_MATCH_BY_OBJ) { - /* Check inteface version */ - - match = false; - switch (r->in.vers_option) { - case RPC_C_VERS_ALL: - /* - * Return endpoint map elements that - * contain the specified interface UUID, - * regardless of the version numbers. - */ - match = true; - break; - case RPC_C_VERS_COMPATIBLE: - /* - * Return the endpoint map elements that - * contain the same major versions of - * the specified interface UUID and a - * minor version greater than or equal - * to the minor version of the specified - * UUID. - */ - if (r->in.interface_id->vers_major == - (eps->e[i].syntax_id.if_version >> 16) && - r->in.interface_id->vers_minor <= - (eps->e[i].syntax_id.if_version && 0xFFFF)) { - match = true; - } - break; - case RPC_C_VERS_EXACT: - /* - * Return endpoint map elements that - * contain the specified version of the - * specified interface UUID. - */ - if (r->in.interface_id->vers_major == - (eps->e[i].syntax_id.if_version >> 16) && - r->in.interface_id->vers_minor == - (eps->e[i].syntax_id.if_version && 0xFFFF)) { - match = true; - } - match = true; - break; - case RPC_C_VERS_MAJOR_ONLY: - /* - * Return endpoint map elements that - * contain the same version of the - * specified interface UUID and ignore - * the minor version. - */ - if (r->in.interface_id->vers_major == - (eps->e[i].syntax_id.if_version >> 16)) { - match = true; - } - match = true; - break; - case RPC_C_VERS_UPTO: - /* - * Return endpoint map elements that - * contain a version of the specified - * interface UUID less than or equal to - * the specified major and minor - * version. - */ - if (r->in.interface_id->vers_major > - eps->e[i].syntax_id.if_version >> 16) { - match = true; - } else { - if (r->in.interface_id->vers_major == - (eps->e[i].syntax_id.if_version >> 16) && - r->in.interface_id->vers_minor >= - (eps->e[i].syntax_id.if_version && 0xFFFF)) { - match = true; - } - } - break; - default: - return EPMAPPER_STATUS_CANT_PERFORM_OP; - } - } - } - - if (match) { - ZERO_STRUCT(r->out.entries[num_ents].object); - - DEBUG(10, ("_epm_Lookup: Adding tower for '%s'\n", - eps->e[i].name)); - r->out.entries[num_ents].annotation = talloc_strdup(r->out.entries, - eps->e[i].name); - r->out.entries[num_ents].tower = talloc(r->out.entries, - struct epm_twr_t); - if (r->out.entries[num_ents].tower == NULL) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - r->out.entries[num_ents].tower->tower.floors = talloc_move(r->out.entries[num_ents].tower, &eps->e[i].ep.floors); - r->out.entries[num_ents].tower->tower.num_floors = eps->e[i].ep.num_floors; - r->out.entries[num_ents].tower->tower_length = 0; - - num_ents++; - } - } /* end for loop */ - - *r->out.num_ents = num_ents; - - eps->count -= count; - eps->e += count; - if (eps->count == 0) { - close_policy_hnd(p, entry_handle); - ZERO_STRUCTP(r->out.entry_handle); - rc = EPMAPPER_STATUS_NO_MORE_ENTRIES; - goto done; - } - - rc = EPMAPPER_STATUS_OK; -done: - talloc_free(tmp_ctx); - - return rc; -} - -/* - * epm_Map - * - * Apply some algorithm (using the fields in the map_tower) to an endpoint map - * to produce a list of protocol towers. - */ -error_status_t _epm_Map(struct pipes_struct *p, - struct epm_Map *r) -{ - struct policy_handle *entry_handle; - enum dcerpc_transport_t transport; - struct ndr_syntax_id ifid; - struct epm_floor *floors; - struct rpc_eps *eps; - TALLOC_CTX *tmp_ctx; - error_status_t rc; - uint32_t count = 0; - uint32_t num_towers = 0; - uint32_t num_floors = 0; - uint32_t i; - bool ok; - - *r->out.num_towers = 0; - r->out.towers = NULL; - - if (r->in.map_tower == NULL || r->in.max_towers == 0 || - r->in.map_tower->tower.num_floors < 3) { - return EPMAPPER_STATUS_NO_MORE_ENTRIES; - } - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return EPMAPPER_STATUS_NO_MEMORY; - } - - ZERO_STRUCTP(r->out.entry_handle); - - DEBUG(3, ("_epm_Map: Trying to map max. %u towers.\n", - r->in.max_towers)); - - /* - * A tower has normally up to 6 floors - * - * +-----------------------------------------------------------------+ - * | Floor 1 | Provides the RPC interface identifier. (e.g. UUID for | - * | | netlogon) | - * +---------+-------------------------------------------------------+ - * | Floor 2 | Transfer syntax (NDR endcoded) | - * +---------+-------------------------------------------------------+ - * | Floor 3 | RPC protocol identifier (ncacn_tcp_ip, ncacn_np, ...) | - * +---------+-------------------------------------------------------+ - * | Floor 4 | Port address (e.g. TCP Port: 49156) | - * +---------+-------------------------------------------------------+ - * | Floor 5 | Transport (e.g. IP:192.168.51.10) | - * +---------+-------------------------------------------------------+ - * | Floor 6 | Routing | - * +---------+-------------------------------------------------------+ - */ - num_floors = r->in.map_tower->tower.num_floors; - floors = r->in.map_tower->tower.floors; - - /* We accept NDR as the transfer syntax */ - dcerpc_floor_get_lhs_data(&floors[1], &ifid); - - if (floors[1].lhs.protocol != EPM_PROTOCOL_UUID || - !GUID_equal(&ifid.uuid, &ndr_transfer_syntax.uuid) || - ifid.if_version != ndr_transfer_syntax.if_version) { - rc = EPMAPPER_STATUS_NO_MORE_ENTRIES; - goto done; - } - - /* We only talk to sane transports */ - transport = dcerpc_transport_by_tower(&r->in.map_tower->tower); - if (transport == NCA_UNKNOWN) { - DEBUG(2, ("epm_Map: Client requested unknown transport with" - "levels: ")); - for (i = 2; i < r->in.map_tower->tower.num_floors; i++) { - DEBUG(2, ("%d, ", r->in.map_tower->tower.floors[i].lhs.protocol)); - } - DEBUG(2, ("\n")); - rc = EPMAPPER_STATUS_NO_MORE_ENTRIES; - goto done; - } - - if (r->in.entry_handle == NULL || - policy_handle_empty(r->in.entry_handle)) { - struct GUID *obj; - - DEBUG(5, ("_epm_Map: No entry_handle found, creating it.\n")); - - eps = talloc_zero(tmp_ctx, struct rpc_eps); - if (eps == NULL) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - - /* - * *** ATTENTION *** - * CDE 1.1 states: - * - * ept_map() - * Apply some algorithm (using the fields in the map_tower) - * to an endpoint map to produce a list of protocol towers. - * - * The following code is the mysterious "some algorithm"! - */ - - /* Filter by object id if one was given. */ - if (r->in.object == NULL || GUID_all_zero(r->in.object)) { - obj = NULL; - } else { - obj = r->in.object; - } - - eps->count = build_ep_list(eps, - endpoint_table, - obj, - &eps->e); - if (eps->count == 0) { - rc = EPMAPPER_STATUS_NO_MORE_ENTRIES; - goto done; - } - - /* Filter out endpoints which match the interface. */ - { - struct rpc_eps *teps; - uint32_t total = 0; - - teps = talloc_zero(tmp_ctx, struct rpc_eps); - if (teps == NULL) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - - for (i = 0; i < eps->count; i++) { - if (data_blob_cmp(&r->in.map_tower->tower.floors[0].lhs.lhs_data, - &eps->e[i].ep.floors[0].lhs.lhs_data) != 0 || - transport != dcerpc_transport_by_tower(&eps->e[i].ep)) { - continue; - } - - teps->e = talloc_realloc(tmp_ctx, - teps->e, - struct dcesrv_ep_iface, - total + 1); - if (teps->e == NULL) { - return 0; - } - - teps->e[total].ep.floors = talloc_move(teps, &eps->e[i].ep.floors); - teps->e[total].ep.num_floors = eps->e[i].ep.num_floors; - teps->e[total].name = talloc_move(teps, &eps->e[i].name); - teps->e[total].syntax_id = eps->e[i].syntax_id; - - total++; - } - - teps->count = total; - talloc_free(eps); - eps = teps; - } - /* end of "some algorithm" */ - - ok = create_policy_hnd(p, r->out.entry_handle, eps); - if (!ok) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - - ok = find_policy_by_hnd(p, r->out.entry_handle, (void **)(void*) &eps); - if (!ok) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - entry_handle = r->out.entry_handle; - } else { - DEBUG(5, ("_epm_Map: Trying to find entry_handle.\n")); - - ok = find_policy_by_hnd(p, r->in.entry_handle, (void **)(void*) &eps); - if (!ok) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - entry_handle = r->in.entry_handle; - } - - if (eps == NULL || eps->e == NULL) { - rc = EPMAPPER_STATUS_NO_MORE_ENTRIES; - goto done; - } - - /* return the next N elements */ - count = r->in.max_towers; - if (count > eps->count) { - count = eps->count; - } - - if (count == 0) { - close_policy_hnd(p, entry_handle); - ZERO_STRUCTP(r->out.entry_handle); - - rc = EPMAPPER_STATUS_NO_MORE_ENTRIES; - goto done; - } - - r->out.towers = talloc_array(p->mem_ctx, struct epm_twr_p_t, count); - if (r->out.towers == NULL) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - - for (i = 0; i < count; i++) { - DEBUG(5, ("_epm_Map: Map tower for '%s'\n", - eps->e[i].name)); - - r->out.towers[num_towers].twr = talloc(r->out.towers, - struct epm_twr_t); - if (r->out.towers[num_towers].twr == NULL) { - rc = EPMAPPER_STATUS_NO_MEMORY; - goto done; - } - r->out.towers[num_towers].twr->tower.floors = talloc_move(r->out.towers[num_towers].twr, &eps->e[i].ep.floors); - r->out.towers[num_towers].twr->tower.num_floors = eps->e[i].ep.num_floors; - r->out.towers[num_towers].twr->tower_length = 0; - - num_towers++; - } - - *r->out.num_towers = num_towers; - - eps->count -= count; - eps->e += count; - if (eps->count == 0) { - close_policy_hnd(p, entry_handle); - ZERO_STRUCTP(r->out.entry_handle); - } - - rc = EPMAPPER_STATUS_OK; -done: - talloc_free(tmp_ctx); - - return rc; -} - -/* - * epm_LookupHandleFree - */ -error_status_t _epm_LookupHandleFree(struct pipes_struct *p, - struct epm_LookupHandleFree *r) -{ - if (r->in.entry_handle == NULL) { - return EPMAPPER_STATUS_OK; - } - - if (is_valid_policy_hnd(r->in.entry_handle)) { - close_policy_hnd(p, r->in.entry_handle); - } - - r->out.entry_handle = r->in.entry_handle; - - return EPMAPPER_STATUS_OK; -} - - -/* - * epm_InqObject - * - * A client implementation SHOULD NOT call this method. These extensions do not - * provide an alternative method. - */ -error_status_t _epm_InqObject(struct pipes_struct *p, - struct epm_InqObject *r) -{ - p->rng_fault_state = true; - return EPMAPPER_STATUS_CANT_PERFORM_OP; -} - - -/* - * epm_MgmtDelete - * - * A client implementation SHOULD NOT call this method. These extensions do not - * provide an alternative method. -*/ -error_status_t _epm_MgmtDelete(struct pipes_struct *p, - struct epm_MgmtDelete *r) -{ - p->rng_fault_state = true; - return EPMAPPER_STATUS_CANT_PERFORM_OP; -} - - -/* - epm_MapAuth -*/ -error_status_t _epm_MapAuth(struct pipes_struct *p, - struct epm_MapAuth *r) -{ - p->rng_fault_state = true; - return EPMAPPER_STATUS_CANT_PERFORM_OP; -} - -/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */ |