ctdb-common: Map ENOENT for a missing event script to ENOEXEC
[samba.git] / source3 / smbd / conn_msg.c
blob9435d3885086656b069e672c225805dee5f9b8b4
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
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/>.
22 #include "includes.h"
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
29 share are unmounted.
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,
39 void *private_data)
41 struct force_tdis_state *state = private_data;
42 const struct loadparm_substitution *lp_sub =
43 loadparm_s3_global_substitution();
44 char *servicename = NULL;
45 bool do_close;
47 if (strcmp(state->sharename, "*") == 0) {
48 DBG_WARNING("Forcing close of all shares\n");
49 return true;
52 servicename = lp_servicename(talloc_tos(), lp_sub, SNUM(conn));
53 do_close = strequal(servicename, state->sharename);
55 TALLOC_FREE(servicename);
57 return do_close;
60 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)
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");
75 return;
78 conn_force_tdis(sconn, force_tdis_check, &state);
81 static bool force_tdis_denied_check(
82 struct connection_struct *conn,
83 void *private_data)
85 bool do_close;
86 uint32_t share_access;
87 bool read_only;
88 NTSTATUS status;
90 do_close = force_tdis_check(conn, private_data);
91 if (!do_close) {
92 return false;
95 status = check_user_share_access(
96 conn,
97 conn->session_info,
98 &share_access,
99 &read_only);
100 if (!NT_STATUS_IS_OK(status)) {
101 DBG_DEBUG("check_user_share_access returned %s\n",
102 nt_errstr(status));
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
122 return false;
125 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)
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");
141 return;
144 change_to_root_user();
145 reload_services(sconn, conn_snum_used, false);
147 conn_force_tdis(sconn, force_tdis_denied_check, &state);