LCOV - code coverage report
Current view: top level - source4/rpc_server/epmapper - rpc_epmapper.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 89 114 78.1 %
Date: 2021-08-25 13:27:56 Functions: 6 12 50.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    endpoint server for the epmapper pipe
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003
       7             :    Copyright (C) Jelmer Vernooij 2004
       8             :    
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             :    
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             :    
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "librpc/gen_ndr/ndr_epmapper.h"
      25             : #include "rpc_server/dcerpc_server.h"
      26             : 
      27             : #define DCESRV_INTERFACE_EPMAPPER_BIND(context, iface) \
      28             :        dcesrv_interface_epmapper_bind(context, iface)
      29        5326 : static NTSTATUS dcesrv_interface_epmapper_bind(struct dcesrv_connection_context *context,
      30             :                                              const struct dcesrv_interface *iface)
      31             : {
      32        5451 :         return dcesrv_interface_bind_allow_connect(context, iface);
      33             : }
      34             : 
      35             : typedef uint32_t error_status_t;
      36             : 
      37             : /* handle types for this module */
      38             : enum handle_types {HTYPE_LOOKUP};
      39             : 
      40             : /* a endpoint combined with an interface description */
      41             : struct dcesrv_ep_iface {
      42             :         const char *name;
      43             :         struct epm_tower ep;
      44             : };
      45             : 
      46             : /*
      47             :   build a list of all interfaces handled by all endpoint servers
      48             : */
      49        6140 : static uint32_t build_ep_list(TALLOC_CTX *mem_ctx,
      50             :                               struct dcesrv_endpoint *endpoint_list,
      51             :                               struct dcesrv_ep_iface **eps)
      52             : {
      53             :         struct dcesrv_endpoint *d;
      54        6140 :         uint32_t total = 0;
      55             :         NTSTATUS status;
      56             : 
      57        6140 :         *eps = NULL;
      58             : 
      59      124144 :         for (d=endpoint_list; d; d=d->next) {
      60             :                 struct dcesrv_if_list *iface;
      61             : 
      62      505099 :                 for (iface=d->interface_list;iface;iface=iface->next) {
      63             :                         struct dcerpc_binding *description;
      64             : 
      65      387095 :                         (*eps) = talloc_realloc(mem_ctx, 
      66             :                                                   *eps, 
      67             :                                                   struct dcesrv_ep_iface,
      68             :                                                   total + 1);
      69      387095 :                         if (!*eps) {
      70           0 :                                 return 0;
      71             :                         }
      72      387095 :                         (*eps)[total].name = iface->iface->name;
      73             : 
      74      387095 :                         description = dcerpc_binding_dup(*eps, d->ep_description);
      75      387095 :                         if (description == NULL) {
      76           0 :                                 return 0;
      77             :                         }
      78             : 
      79      387095 :                         status = dcerpc_binding_set_abstract_syntax(description,
      80      387095 :                                                 &iface->iface->syntax_id);
      81      387095 :                         if (!NT_STATUS_IS_OK(status)) {
      82           0 :                                 return 0;
      83             :                         }
      84             : 
      85      387095 :                         status = dcerpc_binding_build_tower(*eps, description, &(*eps)[total].ep);
      86      387095 :                         TALLOC_FREE(description);
      87      387095 :                         if (!NT_STATUS_IS_OK(status)) {
      88           0 :                                 DBG_ERR("Unable to build tower for %s - %s\n",
      89             :                                         iface->iface->name,
      90             :                                         nt_errstr(status));
      91           0 :                                 continue;
      92             :                         }
      93      379845 :                         total++;
      94             :                 }
      95             :         }
      96             : 
      97        6015 :         return total;
      98             : }
      99             : 
     100             : 
     101           0 : static error_status_t dcesrv_epm_Insert(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct epm_Insert *r)
     102             : {
     103           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     104             : }
     105             : 
     106           0 : static error_status_t dcesrv_epm_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 
     107             :                                  struct epm_Delete *r)
     108             : {
     109           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     110             : }
     111             : 
     112             : 
     113             : /*
     114             :   implement epm_Lookup. This call is used to enumerate the interfaces
     115             :   available on a rpc server
     116             : */
     117          54 : static error_status_t dcesrv_epm_Lookup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 
     118             :                                  struct epm_Lookup *r)
     119             : {
     120             :         struct dcesrv_handle *h;
     121             :         struct rpc_eps {
     122             :                 uint32_t count;
     123             :                 struct dcesrv_ep_iface *e;
     124             :         } *eps;
     125             :         uint32_t num_ents;
     126             :         unsigned int i;
     127             : 
     128          54 :         DCESRV_PULL_HANDLE_FAULT(h, r->in.entry_handle, HTYPE_LOOKUP);
     129             : 
     130          49 :         eps = h->data;
     131             : 
     132          49 :         if (!eps) {
     133             :                 /* this is the first call - fill the list. Subsequent calls 
     134             :                    will feed from this list, stored in the handle */
     135          14 :                 eps = talloc(h, struct rpc_eps);
     136          14 :                 if (!eps) {
     137           0 :                         return EPMAPPER_STATUS_NO_MEMORY;
     138             :                 }
     139          14 :                 h->data = eps;
     140             : 
     141          14 :                 eps->count = build_ep_list(h, dce_call->conn->dce_ctx->endpoint_list, &eps->e);
     142             :         }
     143             : 
     144             :         /* return the next N elements */
     145          49 :         num_ents = r->in.max_ents;
     146          49 :         if (num_ents > eps->count) {
     147           6 :                 num_ents = eps->count;
     148             :         }
     149             : 
     150          49 :         *r->out.entry_handle = h->wire_handle;
     151          49 :         r->out.num_ents = talloc(mem_ctx, uint32_t);
     152          49 :         *r->out.num_ents = num_ents;
     153             : 
     154          49 :         if (num_ents == 0) {
     155           0 :                 r->out.entries = NULL;
     156           0 :                 ZERO_STRUCTP(r->out.entry_handle);
     157           0 :                 talloc_free(h);
     158           0 :                 return EPMAPPER_STATUS_NO_MORE_ENTRIES;
     159             :         }
     160             : 
     161          49 :         r->out.entries = talloc_array(mem_ctx, struct epm_entry_t, num_ents);
     162          49 :         if (!r->out.entries) {
     163           0 :                 return EPMAPPER_STATUS_NO_MEMORY;
     164             :         }
     165             : 
     166         413 :         for (i=0;i<num_ents;i++) {
     167         364 :                 ZERO_STRUCT(r->out.entries[i].object);
     168         364 :                 r->out.entries[i].annotation = eps->e[i].name;
     169         364 :                 r->out.entries[i].tower = talloc(mem_ctx, struct epm_twr_t);
     170         364 :                 if (!r->out.entries[i].tower) {
     171           0 :                         return EPMAPPER_STATUS_NO_MEMORY;
     172             :                 }
     173         364 :                 r->out.entries[i].tower->tower = eps->e[i].ep;
     174             :         }
     175             : 
     176          49 :         eps->count -= num_ents;
     177          49 :         eps->e += num_ents;
     178             : 
     179          49 :         return EPMAPPER_STATUS_OK;
     180             : }
     181             : 
     182             : 
     183             : /*
     184             :   implement epm_Map. This is used to find the specific endpoint to talk to given
     185             :   a generic protocol tower
     186             : */
     187        6126 : static error_status_t dcesrv_epm_Map(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 
     188             :                               struct epm_Map *r)
     189             : {
     190             :         uint32_t count;
     191             :         unsigned int i;
     192             :         struct dcesrv_ep_iface *eps;
     193             :         struct epm_floor *floors;
     194             :         enum dcerpc_transport_t transport;
     195             :         struct ndr_syntax_id ndr_syntax;
     196             : 
     197        6126 :         count = build_ep_list(mem_ctx, dce_call->conn->dce_ctx->endpoint_list, &eps);
     198             : 
     199        6126 :         ZERO_STRUCT(*r->out.entry_handle);
     200        6126 :         r->out.num_towers = talloc(mem_ctx, uint32_t);
     201        6126 :         if (!r->out.num_towers) {
     202           0 :                 return EPMAPPER_STATUS_NO_MEMORY;
     203             :         }
     204        6126 :         *r->out.num_towers = 1;
     205        6126 :         r->out.towers = talloc(mem_ctx, struct epm_twr_p_t);
     206        6126 :         if (!r->out.towers) {
     207           0 :                 return EPMAPPER_STATUS_NO_MEMORY;
     208             :         }
     209        6126 :         r->out.towers->twr = talloc(mem_ctx, struct epm_twr_t);
     210        6126 :         if (!r->out.towers->twr) {
     211           0 :                 return EPMAPPER_STATUS_NO_MEMORY;
     212             :         }
     213             :         
     214       18253 :         if (!r->in.map_tower || r->in.max_towers == 0 || 
     215        6126 :             r->in.map_tower->tower.num_floors < 3) {
     216             :                 goto failed;
     217             :         }
     218             : 
     219        6126 :         floors = r->in.map_tower->tower.floors;
     220             : 
     221        6126 :         dcerpc_floor_get_lhs_data(&r->in.map_tower->tower.floors[1], &ndr_syntax);
     222             : 
     223       12252 :         if (floors[1].lhs.protocol != EPM_PROTOCOL_UUID ||
     224        6126 :             !ndr_syntax_id_equal(&ndr_syntax, &ndr_transfer_syntax_ndr)) {
     225             :                 goto failed;
     226             :         }
     227             : 
     228        6126 :         transport = dcerpc_transport_by_tower(&r->in.map_tower->tower);
     229             : 
     230        6126 :         if (transport == -1) {
     231         138 :                 DEBUG(2, ("Client requested unknown transport with levels: "));
     232         552 :                 for (i = 2; i < r->in.map_tower->tower.num_floors; i++) {
     233         414 :                         DEBUG(2, ("%d, ", r->in.map_tower->tower.floors[i].lhs.protocol));
     234             :                 }
     235         138 :                 DEBUG(2, ("\n"));
     236         138 :                 goto failed;
     237             :         }
     238             : 
     239      508725 :         for (i=0;i<count;i++) {
     240      254314 :                 if (
     241      254314 :                         data_blob_cmp(&r->in.map_tower->tower.floors[0].lhs.lhs_data, 
     242      254314 :                         &eps[i].ep.floors[0].lhs.lhs_data) != 0 
     243       18061 :                         || transport != dcerpc_transport_by_tower(&eps[i].ep)) {
     244      248437 :                         continue;
     245             :                 }
     246             :                 
     247        5877 :                 r->out.towers->twr->tower = eps[i].ep;
     248        5877 :                 r->out.towers->twr->tower_length = 0;
     249        5752 :                 return EPMAPPER_STATUS_OK;
     250             :         }
     251             : 
     252             : 
     253         111 : failed:
     254         249 :         *r->out.num_towers = 0;
     255         249 :         r->out.towers->twr = NULL;
     256             : 
     257         249 :         return EPMAPPER_STATUS_NO_MORE_ENTRIES;
     258             : }
     259             : 
     260           8 : static error_status_t dcesrv_epm_LookupHandleFree(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 
     261             :                                            struct epm_LookupHandleFree *r)
     262             : {
     263           8 :         struct dcesrv_handle *h = NULL;
     264             : 
     265           8 :         r->out.entry_handle = r->in.entry_handle;
     266             : 
     267           8 :         DCESRV_PULL_HANDLE_FAULT(h, r->in.entry_handle, HTYPE_LOOKUP);
     268           8 :         TALLOC_FREE(h);
     269             : 
     270           8 :         ZERO_STRUCTP(r->out.entry_handle);
     271             : 
     272           8 :         return EPMAPPER_STATUS_OK;
     273             : }
     274             : 
     275           0 : static error_status_t dcesrv_epm_InqObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 
     276             :                                     struct epm_InqObject *r)
     277             : {
     278           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     279             : }
     280             : 
     281           0 : static error_status_t dcesrv_epm_MgmtDelete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 
     282             :                                struct epm_MgmtDelete *r)
     283             : {
     284           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     285             : }
     286             : 
     287           0 : static error_status_t dcesrv_epm_MapAuth(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     288             :                             struct epm_MapAuth *r)
     289             : {
     290           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     291             : }
     292             : 
     293             : /* include the generated boilerplate */
     294             : #include "librpc/gen_ndr/ndr_epmapper_s.c"

Generated by: LCOV version 1.13