LCOV - code coverage report
Current view: top level - source3/rpc_server/mdssvc - srv_mdssvc_nt.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 100 131 76.3 %
Date: 2024-04-21 15:09:00 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines for mdssvc
       4             :  *  Copyright (C) Ralph Boehme 2014
       5             :  *
       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 3 of the License, or
       9             :  *  (at your option) any later version.
      10             :  *
      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.
      15             :  *
      16             :  *  You should have received a copy of the GNU General Public License
      17             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include "includes.h"
      21             : #include "messages.h"
      22             : #include "ntdomain.h"
      23             : #include "rpc_server/rpc_server.h"
      24             : #include "rpc_server/rpc_config.h"
      25             : #include "rpc_server/mdssvc/srv_mdssvc_nt.h"
      26             : #include "libcli/security/security_token.h"
      27             : #include "libcli/security/dom_sid.h"
      28             : #include "gen_ndr/auth.h"
      29             : #include "mdssvc.h"
      30             : #include "smbd/globals.h"
      31             : 
      32             : #include "librpc/rpc/dcesrv_core.h"
      33             : #include "librpc/gen_ndr/ndr_mdssvc.h"
      34             : #include "librpc/gen_ndr/ndr_mdssvc_scompat.h"
      35             : #include "lib/global_contexts.h"
      36             : 
      37             : #undef DBGC_CLASS
      38             : #define DBGC_CLASS DBGC_RPC_SRV
      39             : 
      40          14 : static NTSTATUS create_mdssvc_policy_handle(TALLOC_CTX *mem_ctx,
      41             :                                             struct pipes_struct *p,
      42             :                                             int snum,
      43             :                                             const char *sharename,
      44             :                                             const char *path,
      45             :                                             struct policy_handle *handle)
      46             : {
      47          14 :         struct dcesrv_call_state *dce_call = p->dce_call;
      48             :         struct auth_session_info *session_info =
      49          14 :                 dcesrv_call_session_info(dce_call);
      50             :         struct mds_ctx *mds_ctx;
      51             :         NTSTATUS status;
      52             : 
      53          14 :         ZERO_STRUCTP(handle);
      54             : 
      55          14 :         status = mds_init_ctx(mem_ctx,
      56             :                               messaging_tevent_context(p->msg_ctx),
      57             :                               p->msg_ctx,
      58             :                               session_info,
      59             :                               snum,
      60             :                               sharename,
      61             :                               path,
      62             :                               &mds_ctx);
      63          14 :         if (!NT_STATUS_IS_OK(status)) {
      64           2 :                 DBG_DEBUG("mds_init_ctx() path [%s] failed: %s\n",
      65             :                           path, nt_errstr(status));
      66           2 :                 return status;
      67             :         }
      68             : 
      69          12 :         if (!create_policy_hnd(p, handle, 0, mds_ctx)) {
      70           0 :                 talloc_free(mds_ctx);
      71           0 :                 ZERO_STRUCTP(handle);
      72           0 :                 return NT_STATUS_NO_MEMORY;
      73             :         }
      74             : 
      75          12 :         return NT_STATUS_OK;
      76             : }
      77             : 
      78          16 : void _mdssvc_open(struct pipes_struct *p, struct mdssvc_open *r)
      79             : {
      80             :         const struct loadparm_substitution *lp_sub =
      81          16 :                 loadparm_s3_global_substitution();
      82             :         int snum;
      83          16 :         char *outpath = discard_const_p(char, r->out.share_path);
      84          16 :         char *fake_path = NULL;
      85             :         char *path;
      86             :         NTSTATUS status;
      87             : 
      88          16 :         DBG_DEBUG("[%s]\n", r->in.share_name);
      89             : 
      90          16 :         *r->out.device_id = *r->in.device_id;
      91          16 :         *r->out.unkn2 = *r->in.unkn2;
      92          16 :         *r->out.unkn3 = *r->in.unkn3;
      93          16 :         outpath[0] = '\0';
      94             : 
      95          16 :         snum = lp_servicenumber(r->in.share_name);
      96          16 :         if (!VALID_SNUM(snum)) {
      97           2 :                 return;
      98             :         }
      99             : 
     100          14 :         path = lp_path(talloc_tos(), lp_sub, snum);
     101          14 :         if (path == NULL) {
     102           0 :                 DBG_ERR("Couldn't create path for %s\n",
     103             :                         r->in.share_name);
     104           0 :                 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
     105           0 :                 return;
     106             :         }
     107             : 
     108          14 :         fake_path = talloc_asprintf(p->mem_ctx, "/%s", r->in.share_name);
     109          14 :         if (fake_path == NULL) {
     110           0 :                 DBG_ERR("Couldn't create fake share path for %s\n",
     111             :                         r->in.share_name);
     112           0 :                 talloc_free(path);
     113           0 :                 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
     114           0 :                 return;
     115             :         }
     116             : 
     117          14 :         status = create_mdssvc_policy_handle(p->mem_ctx, p,
     118             :                                              snum,
     119             :                                              r->in.share_name,
     120             :                                              path,
     121             :                                              r->out.handle);
     122          14 :         if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_VOLUME)) {
     123           2 :                 ZERO_STRUCTP(r->out.handle);
     124           2 :                 talloc_free(path);
     125           2 :                 talloc_free(fake_path);
     126           2 :                 return;
     127             :         }
     128          12 :         if (!NT_STATUS_IS_OK(status)) {
     129           0 :                 DBG_ERR("Couldn't create policy handle for %s\n",
     130             :                         r->in.share_name);
     131           0 :                 talloc_free(path);
     132           0 :                 talloc_free(fake_path);
     133           0 :                 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
     134           0 :                 return;
     135             :         }
     136             : 
     137          12 :         strlcpy(outpath, fake_path, 1024);
     138          12 :         talloc_free(path);
     139          12 :         talloc_free(fake_path);
     140          12 :         return;
     141             : }
     142             : 
     143          14 : void _mdssvc_unknown1(struct pipes_struct *p, struct mdssvc_unknown1 *r)
     144             : {
     145             :         struct mds_ctx *mds_ctx;
     146             :         NTSTATUS status;
     147             : 
     148          14 :         mds_ctx = find_policy_by_hnd(p,
     149             :                                      r->in.handle,
     150             :                                      DCESRV_HANDLE_ANY,
     151             :                                      struct mds_ctx,
     152             :                                      &status);
     153          14 :         if (!NT_STATUS_IS_OK(status)) {
     154           4 :                 if (ndr_policy_handle_empty(r->in.handle)) {
     155           2 :                         p->fault_state = 0;
     156             :                 } else {
     157           2 :                         p->fault_state = DCERPC_NCA_S_PROTO_ERROR;
     158             :                 }
     159           4 :                 *r->out.status = 0;
     160           4 :                 *r->out.flags = 0;
     161           4 :                 *r->out.unkn7 = 0;
     162           4 :                 return;
     163             :         }
     164             : 
     165          10 :         DEBUG(10, ("%s: path: %s\n", __func__, mds_ctx->spath));
     166             : 
     167          10 :         *r->out.status = 0;
     168          10 :         *r->out.flags = 0x6b000001;
     169          10 :         *r->out.unkn7 = 0;
     170             : 
     171          10 :         return;
     172             : }
     173             : 
     174          22 : void _mdssvc_cmd(struct pipes_struct *p, struct mdssvc_cmd *r)
     175             : {
     176          22 :         struct dcesrv_call_state *dce_call = p->dce_call;
     177             :         struct auth_session_info *session_info =
     178          22 :                 dcesrv_call_session_info(dce_call);
     179             :         bool ok;
     180             :         struct mds_ctx *mds_ctx;
     181             :         NTSTATUS status;
     182             : 
     183          22 :         mds_ctx = find_policy_by_hnd(p,
     184             :                                      r->in.handle,
     185             :                                      DCESRV_HANDLE_ANY,
     186             :                                      struct mds_ctx,
     187             :                                      &status);
     188          22 :         if (!NT_STATUS_IS_OK(status)) {
     189           2 :                 if (ndr_policy_handle_empty(r->in.handle)) {
     190           0 :                         p->fault_state = 0;
     191             :                 } else {
     192           2 :                         p->fault_state = DCERPC_NCA_S_PROTO_ERROR;
     193             :                 }
     194           2 :                 r->out.response_blob->size = 0;
     195           2 :                 *r->out.fragment = 0;
     196           2 :                 *r->out.unkn9 = 0;
     197           2 :                 return;
     198             :         }
     199             : 
     200          20 :         DEBUG(10, ("%s: path: %s\n", __func__, mds_ctx->spath));
     201             : 
     202          20 :         ok = security_token_is_sid(session_info->security_token,
     203          20 :                                    &mds_ctx->sid);
     204          20 :         if (!ok) {
     205             :                 struct dom_sid_buf buf;
     206           0 :                 DBG_WARNING("not the same sid: %s\n",
     207             :                             dom_sid_str_buf(&mds_ctx->sid, &buf));
     208           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
     209           0 :                 return;
     210             :         }
     211             : 
     212          20 :         if (geteuid() != mds_ctx->uid) {
     213           0 :                 DEBUG(0, ("uid mismatch: %d/%d\n", geteuid(), mds_ctx->uid));
     214           0 :                 smb_panic("uid mismatch");
     215             :         }
     216             : 
     217          20 :         if (r->in.request_blob.size > MAX_SL_FRAGMENT_SIZE) {
     218           0 :                 DEBUG(1, ("%s: request size too large\n", __func__));
     219           0 :                 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
     220           0 :                 return;
     221             :         }
     222             : 
     223          20 :         if (r->in.request_blob.length > MAX_SL_FRAGMENT_SIZE) {
     224           0 :                 DEBUG(1, ("%s: request length too large\n", __func__));
     225           0 :                 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
     226           0 :                 return;
     227             :         }
     228             : 
     229          20 :         if (r->in.max_fragment_size1 > MAX_SL_FRAGMENT_SIZE) {
     230           0 :                 DEBUG(1, ("%s: request fragment size too large: %u\n",
     231             :                           __func__, (unsigned)r->in.max_fragment_size1));
     232           0 :                 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
     233           0 :                 return;
     234             :         }
     235             : 
     236             :         /* We currently don't use fragmentation at the mdssvc RPC layer */
     237          20 :         *r->out.fragment = 0;
     238             : 
     239          20 :         ok = mds_dispatch(mds_ctx,
     240             :                           &r->in.request_blob,
     241             :                           r->out.response_blob,
     242          20 :                           r->in.max_fragment_size1);
     243          20 :         if (ok) {
     244          18 :                 *r->out.unkn9 = 0;
     245             :         } else {
     246             :                 /* FIXME: just interpolating from AFP, needs verification */
     247           2 :                 *r->out.unkn9 = UINT32_MAX;
     248             :         }
     249             : 
     250          20 :         return;
     251             : }
     252             : 
     253          10 : void _mdssvc_close(struct pipes_struct *p, struct mdssvc_close *r)
     254             : {
     255             :         struct mds_ctx *mds_ctx;
     256             :         NTSTATUS status;
     257             : 
     258          10 :         mds_ctx = find_policy_by_hnd(p,
     259             :                                      r->in.in_handle,
     260             :                                      DCESRV_HANDLE_ANY,
     261             :                                      struct mds_ctx,
     262             :                                      &status);
     263          10 :         if (!NT_STATUS_IS_OK(status)) {
     264           4 :                 DBG_WARNING("invalid handle\n");
     265           4 :                 if (ndr_policy_handle_empty(r->in.in_handle)) {
     266           2 :                         p->fault_state = 0;
     267             :                 } else {
     268           2 :                         p->fault_state = DCERPC_NCA_S_PROTO_ERROR;
     269             :                 }
     270           4 :                 return;
     271             :         }
     272             : 
     273           6 :         DBG_DEBUG("Close mdssvc handle for path: %s\n", mds_ctx->spath);
     274           6 :         TALLOC_FREE(mds_ctx);
     275             : 
     276           6 :         *r->out.out_handle = *r->in.in_handle;
     277           6 :         close_policy_hnd(p, r->in.in_handle);
     278             : 
     279           6 :         *r->out.status = 0;
     280             : 
     281           6 :         return;
     282             : }
     283             : 
     284             : static NTSTATUS mdssvc__op_init_server(struct dcesrv_context *dce_ctx,
     285             :                 const struct dcesrv_endpoint_server *ep_server);
     286             : 
     287             : static NTSTATUS mdssvc__op_shutdown_server(struct dcesrv_context *dce_ctx,
     288             :                 const struct dcesrv_endpoint_server *ep_server);
     289             : 
     290             : #define DCESRV_INTERFACE_MDSSVC_INIT_SERVER \
     291             :         mdssvc_init_server
     292             : 
     293             : #define DCESRV_INTERFACE_MDSSVC_SHUTDOWN_SERVER \
     294             :         mdssvc_shutdown_server
     295             : 
     296           8 : static NTSTATUS mdssvc_init_server(struct dcesrv_context *dce_ctx,
     297             :                 const struct dcesrv_endpoint_server *ep_server)
     298             : {
     299           8 :         struct messaging_context *msg_ctx = global_messaging_context();
     300             :         bool ok;
     301             : 
     302           8 :         ok = mds_init(msg_ctx);
     303           8 :         if (!ok) {
     304           0 :                 return NT_STATUS_UNSUCCESSFUL;
     305             :         }
     306             : 
     307           8 :         return mdssvc__op_init_server(dce_ctx, ep_server);
     308             : }
     309             : 
     310           8 : static NTSTATUS mdssvc_shutdown_server(struct dcesrv_context *dce_ctx,
     311             :                 const struct dcesrv_endpoint_server *ep_server)
     312             : {
     313           8 :         mds_shutdown();
     314             : 
     315           8 :         return mdssvc__op_shutdown_server(dce_ctx, ep_server);
     316             : }
     317             : 
     318             : /* include the generated boilerplate */
     319             : #include "librpc/gen_ndr/ndr_mdssvc_scompat.c"

Generated by: LCOV version 1.14