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
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.
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.
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/>.
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
26 /****************************************************************************
27 Receive a smbcontrol message to forcibly unmount a share.
28 The message contains just a share name and all instances of that
30 The special sharename '*' forces unmount of all shares.
31 ****************************************************************************/
33 struct force_tdis_state
{
34 const char *sharename
;
37 static bool force_tdis_check(
38 struct connection_struct
*conn
,
41 struct force_tdis_state
*state
= private_data
;
42 const struct loadparm_substitution
*lp_sub
=
43 loadparm_s3_global_substitution();
44 char *servicename
= NULL
;
47 if (strcmp(state
->sharename
, "*") == 0) {
48 DBG_WARNING("Forcing close of all shares\n");
52 servicename
= lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
));
53 do_close
= strequal(servicename
, state
->sharename
);
55 TALLOC_FREE(servicename
);
60 void msg_force_tdis(struct messaging_context
*msg
,
63 struct server_id server_id
,
66 struct force_tdis_state state
= {
67 .sharename
= (const char *)data
->data
,
69 struct smbd_server_connection
*sconn
=
70 talloc_get_type_abort(private_data
,
71 struct smbd_server_connection
);
73 if ((data
->length
== 0) || (data
->data
[data
->length
-1] != 0)) {
74 DBG_WARNING("Ignoring invalid sharename\n");
78 conn_force_tdis(sconn
, force_tdis_check
, &state
);
81 static bool force_tdis_denied_check(
82 struct connection_struct
*conn
,
86 uint32_t share_access
;
90 do_close
= force_tdis_check(conn
, private_data
);
95 status
= check_user_share_access(
100 if (!NT_STATUS_IS_OK(status
)) {
101 DBG_DEBUG("check_user_share_access returned %s\n",
103 return true; /* close the share */
106 if (conn
->share_access
!= share_access
) {
107 DBG_DEBUG("share_access changed from %"PRIx32
" to %"PRIx32
"\n",
108 conn
->share_access
, share_access
);
109 return true; /* close the share */
112 if (conn
->read_only
!= read_only
) {
113 DBG_DEBUG("read_only changed from %s to %s\n",
114 conn
->read_only
? "true" : "false",
115 read_only
? "true" : "false");
116 return true; /* close the share */
120 * all still ok, keep the connection open
125 void msg_force_tdis_denied(
126 struct messaging_context
*msg
,
129 struct server_id server_id
,
132 struct force_tdis_state state
= {
133 .sharename
= (const char *)data
->data
,
135 struct smbd_server_connection
*sconn
=
136 talloc_get_type_abort(private_data
,
137 struct smbd_server_connection
);
139 if ((data
->length
== 0) || (data
->data
[data
->length
-1] != 0)) {
140 DBG_WARNING("Ignoring invalid sharename\n");
144 change_to_root_user();
145 reload_services(sconn
, conn_snum_used
, false);
147 conn_force_tdis(sconn
, force_tdis_denied_check
, &state
);