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 2f515e9b Lines: 107 141 75.9 %
Date: 2024-04-21 15:09:00 Functions: 5 10 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        6276 : static NTSTATUS dcesrv_interface_epmapper_bind(struct dcesrv_connection_context *context,
      30             :                                              const struct dcesrv_interface *iface)
      31             : {
      32        6276 :         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        6935 : static uint32_t build_ep_list(TALLOC_CTX *mem_ctx,
      50             :                               struct dcesrv_endpoint *endpoint_list,
      51             :                               struct dcesrv_ep_iface **eps)
      52             : {
      53         125 :         struct dcesrv_endpoint *d;
      54        6935 :         uint32_t total = 0;
      55         125 :         NTSTATUS status;
      56             : 
      57        6935 :         *eps = NULL;
      58             : 
      59      132430 :         for (d=endpoint_list; d; d=d->next) {
      60        2125 :                 struct dcesrv_if_list *iface;
      61             : 
      62      545318 :                 for (iface=d->interface_list;iface;iface=iface->next) {
      63        7000 :                         struct dcerpc_binding *description;
      64             : 
      65      419823 :                         (*eps) = talloc_realloc(mem_ctx, 
      66             :                                                   *eps, 
      67             :                                                   struct dcesrv_ep_iface,
      68             :                                                   total + 1);
      69      419823 :                         if (!*eps) {
      70           0 :                                 return 0;
      71             :                         }
      72      419823 :                         (*eps)[total].name = iface->iface->name;
      73             : 
      74      419823 :                         description = dcerpc_binding_dup(*eps, d->ep_description);
      75      419823 :                         if (description == NULL) {
      76           0 :                                 return 0;
      77             :                         }
      78             : 
      79      426823 :                         status = dcerpc_binding_set_abstract_syntax(description,
      80      419823 :                                                 &iface->iface->syntax_id);
      81      419823 :                         if (!NT_STATUS_IS_OK(status)) {
      82           0 :                                 return 0;
      83             :                         }
      84             : 
      85      419823 :                         status = dcerpc_binding_build_tower(*eps, description, &(*eps)[total].ep);
      86      419823 :                         TALLOC_FREE(description);
      87      419823 :                         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      412823 :                         total++;
      94             :                 }
      95             :         }
      96             : 
      97        6810 :         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           0 :         struct dcesrv_handle *h;
     121           0 :         struct rpc_eps {
     122             :                 uint32_t count;
     123             :                 struct dcesrv_ep_iface *e;
     124             :         } *eps;
     125           0 :         uint32_t num_ents;
     126           0 :         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         401 :         for (i=0;i<num_ents;i++) {
     167         352 :                 ZERO_STRUCT(r->out.entries[i].object);
     168         352 :                 r->out.entries[i].annotation = eps->e[i].name;
     169         352 :                 r->out.entries[i].tower = talloc(mem_ctx, struct epm_twr_t);
     170         352 :                 if (!r->out.entries[i].tower) {
     171           0 :                         return EPMAPPER_STATUS_NO_MEMORY;
     172             :                 }
     173         352 :                 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        6921 : static error_status_t dcesrv_epm_Map(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 
     188             :                               struct epm_Map *r)
     189             : {
     190         125 :         uint32_t count;
     191         125 :         unsigned int i;
     192         125 :         struct dcesrv_ep_iface *eps;
     193         125 :         struct epm_floor *floors;
     194         125 :         enum dcerpc_transport_t transport;
     195         125 :         struct ndr_syntax_id abstract_syntax;
     196         125 :         struct ndr_syntax_id ndr_syntax;
     197         125 :         NTSTATUS status;
     198             : 
     199        6921 :         count = build_ep_list(mem_ctx, dce_call->conn->dce_ctx->endpoint_list, &eps);
     200             : 
     201        6921 :         ZERO_STRUCT(*r->out.entry_handle);
     202        6921 :         r->out.num_towers = talloc(mem_ctx, uint32_t);
     203        6921 :         if (!r->out.num_towers) {
     204           0 :                 return EPMAPPER_STATUS_NO_MEMORY;
     205             :         }
     206        6921 :         *r->out.num_towers = 1;
     207        6921 :         r->out.towers = talloc(mem_ctx, struct epm_twr_p_t);
     208        6921 :         if (!r->out.towers) {
     209           0 :                 return EPMAPPER_STATUS_NO_MEMORY;
     210             :         }
     211        6921 :         r->out.towers->twr = talloc(mem_ctx, struct epm_twr_t);
     212        6921 :         if (!r->out.towers->twr) {
     213           0 :                 return EPMAPPER_STATUS_NO_MEMORY;
     214             :         }
     215             :         
     216        6921 :         if (!r->in.map_tower || r->in.max_towers == 0 || 
     217        6921 :             r->in.map_tower->tower.num_floors < 3) {
     218           0 :                 goto failed;
     219             :         }
     220             : 
     221        6921 :         floors = r->in.map_tower->tower.floors;
     222             : 
     223        6921 :         status = dcerpc_floor_get_uuid_full(&floors[0], &abstract_syntax);
     224        6921 :         if (!NT_STATUS_IS_OK(status)) {
     225           0 :                 goto failed;
     226             :         }
     227             : 
     228        6921 :         status = dcerpc_floor_get_uuid_full(&floors[1], &ndr_syntax);
     229        6921 :         if (!NT_STATUS_IS_OK(status)) {
     230           0 :                 goto failed;
     231             :         }
     232             : 
     233        6921 :         if (!ndr_syntax_id_equal(&ndr_syntax, &ndr_transfer_syntax_ndr)) {
     234           0 :                 goto failed;
     235             :         }
     236             : 
     237        6921 :         transport = dcerpc_transport_by_tower(&r->in.map_tower->tower);
     238             : 
     239        6921 :         if (transport == -1) {
     240         132 :                 DEBUG(2, ("Client requested unknown transport with levels: "));
     241         528 :                 for (i = 2; i < r->in.map_tower->tower.num_floors; i++) {
     242         396 :                         DEBUG(2, ("%d, ", r->in.map_tower->tower.floors[i].lhs.protocol));
     243             :                 }
     244         132 :                 DEBUG(2, ("\n"));
     245         132 :                 goto failed;
     246             :         }
     247             : 
     248      275087 :         for (i=0;i<count;i++) {
     249        5245 :                 struct ndr_syntax_id ep_abstract_syntax;
     250        5245 :                 int match;
     251             : 
     252      274925 :                 if (transport != dcerpc_transport_by_tower(&eps[i].ep)) {
     253      268298 :                         continue;
     254             :                 }
     255             : 
     256       55191 :                 status = dcerpc_floor_get_uuid_full(&eps[i].ep.floors[0],
     257             :                                                     &ep_abstract_syntax);
     258       55191 :                 if (!NT_STATUS_IS_OK(status)) {
     259           0 :                         continue;
     260             :                 }
     261             : 
     262       55191 :                 match = ndr_syntax_id_equal(&ep_abstract_syntax,
     263             :                                             &abstract_syntax);
     264       55191 :                 if (!match) {
     265       48564 :                         continue;
     266             :                 }
     267             : 
     268        6627 :                 r->out.towers->twr->tower = eps[i].ep;
     269        6627 :                 r->out.towers->twr->tower_length = 0;
     270        6627 :                 return EPMAPPER_STATUS_OK;
     271             :         }
     272             : 
     273             : 
     274         162 : failed:
     275         294 :         *r->out.num_towers = 0;
     276         294 :         r->out.towers->twr = NULL;
     277             : 
     278         294 :         return EPMAPPER_STATUS_NO_MORE_ENTRIES;
     279             : }
     280             : 
     281           8 : static error_status_t dcesrv_epm_LookupHandleFree(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 
     282             :                                            struct epm_LookupHandleFree *r)
     283             : {
     284           8 :         struct dcesrv_handle *h = NULL;
     285             : 
     286           8 :         r->out.entry_handle = r->in.entry_handle;
     287             : 
     288           8 :         DCESRV_PULL_HANDLE_FAULT(h, r->in.entry_handle, HTYPE_LOOKUP);
     289           8 :         TALLOC_FREE(h);
     290             : 
     291           8 :         ZERO_STRUCTP(r->out.entry_handle);
     292             : 
     293           8 :         return EPMAPPER_STATUS_OK;
     294             : }
     295             : 
     296           0 : static error_status_t dcesrv_epm_InqObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 
     297             :                                     struct epm_InqObject *r)
     298             : {
     299           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     300             : }
     301             : 
     302           0 : static error_status_t dcesrv_epm_MgmtDelete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 
     303             :                                struct epm_MgmtDelete *r)
     304             : {
     305           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     306             : }
     307             : 
     308           0 : static error_status_t dcesrv_epm_MapAuth(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     309             :                             struct epm_MapAuth *r)
     310             : {
     311           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     312             : }
     313             : 
     314             : /* include the generated boilerplate */
     315             : #include "librpc/gen_ndr/ndr_epmapper_s.c"

Generated by: LCOV version 1.14