1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

smbd: Add close-denied-share message

This is like close-share, but kicks out only active users where share
access controls are changed such that now access would be denied

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Volker Lendecke 2020-01-13 15:19:58 +01:00 committed by Jeremy Allison
parent c9850e3d80
commit 5394885167
7 changed files with 124 additions and 0 deletions

View File

@ -119,6 +119,16 @@
</listitem>
</varlistentry>
<varlistentry><term>close-denied-share</term>
<listitem><para>Behave like <constant>close-share</constant>,
but don't disconnect users that are still allowed to access
the share. It can safely be sent to all smbds after changing
share access controls. It will only affect users who have been
denied access since having connected initially. This message
can only be sent to <constant>smbd</constant>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>debug</term>
<listitem><para>Set debug level to the value specified by the

View File

@ -111,6 +111,9 @@ interface messaging
MSG_SMB_NOTIFY_STARTED = 0x031F,
MSG_SMB_SLEEP = 0x0320,
/* smbd message */
MSG_SMB_FORCE_TDIS_DENIED = 0x0321,
/* winbind messages */
MSG_WINBIND_FINISHED = 0x0401,
MSG_WINBIND_FORGET_STATE = 0x0402,

View File

@ -77,3 +77,72 @@ void msg_force_tdis(struct messaging_context *msg,
conn_force_tdis(sconn, force_tdis_check, &state);
}
static bool force_tdis_denied_check(
struct connection_struct *conn,
void *private_data)
{
bool do_close;
uint32_t share_access;
bool read_only;
NTSTATUS status;
do_close = force_tdis_check(conn, private_data);
if (!do_close) {
return false;
}
status = check_user_share_access(
conn,
conn->session_info,
&share_access,
&read_only);
if (!NT_STATUS_IS_OK(status)) {
DBG_DEBUG("check_user_share_access returned %s\n",
nt_errstr(status));
return true; /* close the share */
}
if (conn->share_access != share_access) {
DBG_DEBUG("share_access changed from %"PRIx32" to %"PRIx32"\n",
conn->share_access, share_access);
return true; /* close the share */
}
if (conn->read_only != read_only) {
DBG_DEBUG("read_only changed from %s to %s\n",
conn->read_only ? "true" : "false",
read_only ? "true" : "false");
return true; /* close the share */
}
/*
* all still ok, keep the connection open
*/
return false;
}
void msg_force_tdis_denied(
struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
struct server_id server_id,
DATA_BLOB *data)
{
struct force_tdis_state state = {
.sharename = (const char *)data->data,
};
struct smbd_server_connection *sconn =
talloc_get_type_abort(private_data,
struct smbd_server_connection);
if ((data->length == 0) || (data->data[data->length-1] != 0)) {
DBG_WARNING("Ignoring invalid sharename\n");
return;
}
change_to_root_user();
reload_services(sconn, conn_snum_used, false);
conn_force_tdis(sconn, force_tdis_denied_check, &state);
}

View File

@ -4096,6 +4096,11 @@ void smbd_process(struct tevent_context *ev_ctx,
/* register our message handlers */
messaging_register(sconn->msg_ctx, sconn,
MSG_SMB_FORCE_TDIS, msg_force_tdis);
messaging_register(
sconn->msg_ctx,
sconn,
MSG_SMB_FORCE_TDIS_DENIED,
msg_force_tdis_denied);
messaging_register(sconn->msg_ctx, sconn,
MSG_SMB_CLOSE_FILE, msg_close_file);
messaging_register(sconn->msg_ctx, sconn,

View File

@ -164,6 +164,12 @@ void msg_force_tdis(struct messaging_context *msg,
uint32_t msg_type,
struct server_id server_id,
DATA_BLOB *data);
void msg_force_tdis_denied(
struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
struct server_id server_id,
DATA_BLOB *data);
/* The following definitions come from smbd/connection.c */

View File

@ -1254,6 +1254,8 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug);
messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS,
smb_parent_send_to_children);
messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS_DENIED,
smb_parent_send_to_children);
messaging_register(msg_ctx, NULL, MSG_SMB_KILL_CLIENT_IP,
smb_parent_send_to_children);
messaging_register(msg_ctx, NULL, MSG_SMB_TELL_NUM_CHILDREN,

View File

@ -807,6 +807,30 @@ static bool do_closeshare(struct tevent_context *ev_ctx,
strlen(argv[1]) + 1);
}
/*
* Close a share if access denied by now
**/
static bool do_close_denied_share(
struct tevent_context *ev_ctx,
struct messaging_context *msg_ctx,
const struct server_id pid,
const int argc, const char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: smbcontrol <dest> close-denied-share "
"<sharename>\n");
return False;
}
return send_message(
msg_ctx,
pid,
MSG_SMB_FORCE_TDIS_DENIED,
argv[1],
strlen(argv[1]) + 1);
}
/* Kill a client by IP address */
static bool do_kill_client_by_ip(struct tevent_context *ev_ctx,
struct messaging_context *msg_ctx,
@ -1433,6 +1457,11 @@ static const struct {
.fn = do_closeshare,
.help = "Forcibly disconnect a share",
},
{
.name = "close-denied-share",
.fn = do_close_denied_share,
.help = "Forcibly disconnect users from shares disallowed now",
},
{
.name = "kill-client-ip",
.fn = do_kill_client_by_ip,