LCOV - code coverage report
Current view: top level - source3/smbd - conn_msg.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 34 53 64.2 %
Date: 2024-04-13 12:30:31 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Manage connections_struct structures
       4             :    Copyright (C) Andrew Tridgell 1998
       5             :    Copyright (C) Alexander Bokovoy 2002
       6             :    Copyright (C) Jeremy Allison 2010
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "smbd/smbd.h"
      24             : #include "smbd/globals.h"
      25             : 
      26             : /****************************************************************************
      27             :  Receive a smbcontrol message to forcibly unmount a share.
      28             :  The message contains just a share name and all instances of that
      29             :  share are unmounted.
      30             :  The special sharename '*' forces unmount of all shares.
      31             : ****************************************************************************/
      32             : 
      33             : struct force_tdis_state {
      34             :         const char *sharename;
      35             : };
      36             : 
      37          72 : static bool force_tdis_check(
      38             :         struct connection_struct *conn,
      39             :         void *private_data)
      40             : {
      41          72 :         struct force_tdis_state *state = private_data;
      42           0 :         const struct loadparm_substitution *lp_sub =
      43          72 :                 loadparm_s3_global_substitution();
      44          72 :         char *servicename = NULL;
      45           0 :         bool do_close;
      46             : 
      47          72 :         if (strcmp(state->sharename, "*") == 0) {
      48           0 :                 DBG_WARNING("Forcing close of all shares\n");
      49           0 :                 return true;
      50             :         }
      51             : 
      52          72 :         servicename = lp_servicename(talloc_tos(), lp_sub, SNUM(conn));
      53          72 :         do_close = strequal(servicename, state->sharename);
      54             : 
      55          72 :         TALLOC_FREE(servicename);
      56             : 
      57          72 :         return do_close;
      58             : }
      59             : 
      60          66 : void msg_force_tdis(struct messaging_context *msg,
      61             :                     void *private_data,
      62             :                     uint32_t msg_type,
      63             :                     struct server_id server_id,
      64             :                     DATA_BLOB *data)
      65             : {
      66          66 :         struct force_tdis_state state = {
      67          66 :                 .sharename = (const char *)data->data,
      68             :         };
      69           0 :         struct smbd_server_connection *sconn =
      70          66 :                 talloc_get_type_abort(private_data,
      71             :                 struct smbd_server_connection);
      72             : 
      73          66 :         if ((data->length == 0) || (data->data[data->length-1] != 0)) {
      74           0 :                 DBG_WARNING("Ignoring invalid sharename\n");
      75           0 :                 return;
      76             :         }
      77             : 
      78          66 :         conn_force_tdis(sconn, force_tdis_check, &state);
      79             : }
      80             : 
      81           4 : static bool force_tdis_denied_check(
      82             :         struct connection_struct *conn,
      83             :         void *private_data)
      84             : {
      85           0 :         bool do_close;
      86           0 :         uint32_t share_access;
      87           0 :         bool read_only;
      88           0 :         NTSTATUS status;
      89             : 
      90           4 :         do_close = force_tdis_check(conn, private_data);
      91           4 :         if (!do_close) {
      92           0 :                 return false;
      93             :         }
      94             : 
      95           4 :         status = check_user_share_access(
      96             :                 conn,
      97           4 :                 conn->session_info,
      98             :                 &share_access,
      99             :                 &read_only);
     100           4 :         if (!NT_STATUS_IS_OK(status)) {
     101           2 :                 DBG_DEBUG("check_user_share_access returned %s\n",
     102             :                           nt_errstr(status));
     103           2 :                 return true;    /* close the share */
     104             :         }
     105             : 
     106           2 :         if (conn->share_access != share_access) {
     107           0 :                 DBG_DEBUG("share_access changed from %"PRIx32" to %"PRIx32"\n",
     108             :                           conn->share_access, share_access);
     109           0 :                 return true;    /* close the share */
     110             :         }
     111             : 
     112           2 :         if (conn->read_only != read_only) {
     113           0 :                 DBG_DEBUG("read_only changed from %s to %s\n",
     114             :                           conn->read_only ? "true" : "false",
     115             :                           read_only ? "true" : "false");
     116           0 :                 return true;    /* close the share */
     117             :         }
     118             : 
     119             :         /*
     120             :          * all still ok, keep the connection open
     121             :          */
     122           2 :         return false;
     123             : }
     124             : 
     125           4 : void msg_force_tdis_denied(
     126             :         struct messaging_context *msg,
     127             :         void *private_data,
     128             :         uint32_t msg_type,
     129             :         struct server_id server_id,
     130             :         DATA_BLOB *data)
     131             : {
     132           4 :         struct force_tdis_state state = {
     133           4 :                 .sharename = (const char *)data->data,
     134             :         };
     135           0 :         struct smbd_server_connection *sconn =
     136           4 :                 talloc_get_type_abort(private_data,
     137             :                 struct smbd_server_connection);
     138             : 
     139           4 :         if ((data->length == 0) || (data->data[data->length-1] != 0)) {
     140           0 :                 DBG_WARNING("Ignoring invalid sharename\n");
     141           0 :                 return;
     142             :         }
     143             : 
     144           4 :         change_to_root_user();
     145           4 :         reload_services(sconn, conn_snum_used, false);
     146             : 
     147           4 :         conn_force_tdis(sconn, force_tdis_denied_check, &state);
     148             : }

Generated by: LCOV version 1.14