[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Wed Jan 15 22:52:03 UTC 2020
The branch, master has been updated
via ebced94a872 torture: Test smbcontrol close-denied-share
via 5394885167f smbd: Add close-denied-share message
via c9850e3d803 smbd: Move sharename check of conn_force_tdis() into a callback
via 733f798074b texpect: Avoid duplicate sys_write()
via 4fabe1d1072 texpect: Reformat long line
via 4371982619d texpect: Use lib/replace's closefrom()
via 2198da1b9bf s3:libsmb: Fix querying all names registered within broadcast area
from 0fcc2e93192 fuzz: add nmblib/parse_packet target
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit ebced94a8721ffd25386bda452a1857fa92b9899
Author: Volker Lendecke <vl at samba.org>
Date: Tue Jan 14 13:13:17 2020 +0100
torture: Test smbcontrol close-denied-share
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Wed Jan 15 22:51:14 UTC 2020 on sn-devel-184
commit 5394885167fac40a910613272f10b7077e59f05c
Author: Volker Lendecke <vl at samba.org>
Date: Mon Jan 13 15:19:58 2020 +0100
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 at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit c9850e3d80320a5d13a69194246cce3f09f4ba3e
Author: Volker Lendecke <vl at samba.org>
Date: Mon Jan 13 15:37:25 2020 +0100
smbd: Move sharename check of conn_force_tdis() into a callback
Next commit will have an additional check
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 733f798074b76ed8b96272a29c8cb91eef7a7118
Author: Volker Lendecke <vl at samba.org>
Date: Wed Jan 15 12:40:38 2020 +0100
texpect: Avoid duplicate sys_write()
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 4fabe1d1072147c609f2e8a2c86da04724564cb2
Author: Volker Lendecke <vl at samba.org>
Date: Wed Jan 15 12:37:59 2020 +0100
texpect: Reformat long line
There will be more deps soon
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 4371982619d4fb0b784813950055a0f19e0e8667
Author: Volker Lendecke <vl at samba.org>
Date: Wed Jan 15 12:37:22 2020 +0100
texpect: Use lib/replace's closefrom()
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 2198da1b9bf79e86112aeeb8e9653f6a82f69e8d
Author: Samuel Cabrero <scabrero at samba.org>
Date: Tue Jan 14 17:12:33 2020 +0100
s3:libsmb: Fix querying all names registered within broadcast area
Wait for additional replies until timeout when '*' is given to nmblookup
as name.
Introduced by 8da8c36b53cc115f0d446b666fc24fc9423d808e.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=8927
Signed-off-by: Samuel Cabrero <scabrero at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
-----------------------------------------------------------------------
Summary of changes:
docs-xml/manpages/smbcontrol.1.xml | 10 +++
lib/texpect/texpect.c | 38 +--------
lib/texpect/wscript | 5 +-
librpc/idl/messaging.idl | 3 +
source3/libsmb/namequery.c | 18 ++++-
source3/script/tests/test_close_denied_share.sh | 80 +++++++++++++++++++
source3/selftest/tests.py | 10 +++
source3/smbd/conn_idle.c | 31 +++----
source3/smbd/conn_msg.c | 102 +++++++++++++++++++++++-
source3/smbd/process.c | 5 ++
source3/smbd/proto.h | 12 ++-
source3/smbd/server.c | 2 +
source3/utils/smbcontrol.c | 29 +++++++
13 files changed, 283 insertions(+), 62 deletions(-)
create mode 100755 source3/script/tests/test_close_denied_share.sh
Changeset truncated at 500 lines:
diff --git a/docs-xml/manpages/smbcontrol.1.xml b/docs-xml/manpages/smbcontrol.1.xml
index 77a2054c449..935713b46a0 100644
--- a/docs-xml/manpages/smbcontrol.1.xml
+++ b/docs-xml/manpages/smbcontrol.1.xml
@@ -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
diff --git a/lib/texpect/texpect.c b/lib/texpect/texpect.c
index 32b2fded410..8c9431e366e 100644
--- a/lib/texpect/texpect.c
+++ b/lib/texpect/texpect.c
@@ -34,6 +34,7 @@
#include "replace.h"
#include "system/filesys.h"
#include "system/wait.h"
+#include "lib/util/sys_rw.h"
#ifdef HAVE_PTY_H
#include <pty.h>
@@ -176,24 +177,6 @@ static char *iscmd(const char *buf, const char *s)
return strdup(buf + len);
}
-/*******************************************************************
-A write wrapper that will deal with EINTR.
-********************************************************************/
-
-static ssize_t sys_write(int fd, const void *buf, size_t count)
-{
- ssize_t ret;
-
- do {
- ret = write(fd, buf, count);
-#if defined(EWOULDBLOCK)
- } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
-#else
- } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
-#endif
- return ret;
-}
-
static void parse_configuration(const char *fn)
{
struct command *c;
@@ -235,23 +218,6 @@ static void parse_configuration(const char *fn)
fclose(cmd);
}
-/* A wrapper to close als file descriptors above the given fd */
-static int sys_closefrom(int fd)
-{
- int num = getdtablesize();
-
- if (num < 0) {
- num = 1024;
- }
-
- for (; fd <= num; fd++) {
- close(fd);
- }
-
- return 0;
-}
-
-
/*
*
*/
@@ -463,7 +429,7 @@ int main(int argc, const char **argv)
dup2(slave, STDOUT_FILENO);
dup2(slave, STDERR_FILENO);
- sys_closefrom(STDERR_FILENO + 1);
+ closefrom(STDERR_FILENO + 1);
/* texpect <expect_instructions> <progname> [<args>] */
execvp(program, program_args);
diff --git a/lib/texpect/wscript b/lib/texpect/wscript
index aaa3104f1ed..44f92a85136 100644
--- a/lib/texpect/wscript
+++ b/lib/texpect/wscript
@@ -4,4 +4,7 @@ def configure(conf):
conf.CHECK_FUNCS_IN('openpty', 'util', checklibc=True, headers='pty.h util.h bsd/libutil.h libutil.h')
def build(bld):
- bld.SAMBA_BINARY('texpect', 'texpect.c', deps='popt util replace', for_selftest=True)
+ bld.SAMBA_BINARY('texpect',
+ 'texpect.c',
+ deps='popt util replace sys_rw',
+ for_selftest=True)
diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl
index f355c7503d9..8160c76149c 100644
--- a/librpc/idl/messaging.idl
+++ b/librpc/idl/messaging.idl
@@ -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,
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 5d4fca70b20..e27b60b0398 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -1221,6 +1221,7 @@ struct name_query_state {
struct sockaddr_storage my_addr;
struct sockaddr_storage addr;
bool bcast;
+ bool bcast_star_query;
uint8_t buf[1024];
@@ -1288,6 +1289,16 @@ struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx,
nmb->header.nscount = 0;
nmb->header.arcount = 0;
+ if (bcast && (strcmp(name, "*")==0)) {
+ /*
+ * We're doing a broadcast query for all
+ * names in the area. Remember this so
+ * we will wait for all names within
+ * the timeout period.
+ */
+ state->bcast_star_query = true;
+ }
+
make_nmb_name(&nmb->question.question_name,name,name_type);
nmb->question.question_type = 0x20;
@@ -1445,9 +1456,12 @@ static bool name_query_validator(struct packet_struct *p, void *private_data)
if (state->bcast) {
/*
* We have to collect all entries coming in from broadcast
- * queries. If we got a unique name, we're done.
+ * queries. If we got a unique name and we are not querying
+ * all names registered within broadcast area (query
+ * for the name '*', so state->bcast_star_query is set),
+ * we're done.
*/
- return got_unique_netbios_name;
+ return (got_unique_netbios_name && !state->bcast_star_query);
}
/*
* WINS responses are accepted when they are received
diff --git a/source3/script/tests/test_close_denied_share.sh b/source3/script/tests/test_close_denied_share.sh
new file mode 100755
index 00000000000..6b7d78663fe
--- /dev/null
+++ b/source3/script/tests/test_close_denied_share.sh
@@ -0,0 +1,80 @@
+#!/bin/bash
+#
+# Test smbcontrol close-denied-share command.
+#
+# Verify that changing and querying the security descriptor works. Also
+# ensure that the output format for ACL entries does not change.
+#
+# The test uses well-known SIDs to not require looking up names and SIDs
+#
+# Copyright (C) 2015, 2019 Christof Schmitt
+
+if [ $# -lt 6 ]; then
+ echo Usage: test_close_denied_share.sh \
+ SERVERCONFFILE SHARESEC SMBCLIENT SMBCONTROL IP SHARE
+exit 1
+fi
+
+CONF=$1
+SHARESEC=$2
+SMBCLIENT=$3
+SMBCONTROL=$4
+SERVER=$5
+SHARE=$6
+
+incdir=$(dirname $0)/../../../testprogs/blackbox
+. $incdir/subunit.sh
+
+failed=0
+
+rm -f smbclient-stdin smbclient-stdout
+mkfifo smbclient-stdin smbclient-stdout
+
+CLI_FORCE_INTERACTIVE=1; export CLI_FORCE_INTERACTIVE
+
+${SMBCLIENT} //${SERVER}/${SHARE} ${CONF} -U${USER}%${PASSWORD} \
+ < smbclient-stdin > smbclient-stdout &
+CLIENT_PID=$!
+
+sleep 1
+
+exec 100>smbclient-stdin 101<smbclient-stdout
+
+# consume the smbclient startup message
+
+head -n 1 <&101
+
+testit "smbcontrol" ${SMBCONTROL} ${CONF} smbd close-denied-share ${SHARE} ||
+ failed=$(expr $failed + 1)
+sleep 1
+
+echo dir >&100
+
+COUNT=$(head -n 2 <&101 |
+ grep NT_STATUS_NETWORK_NAME_DELETED |
+ wc -l)
+testit "Verify close-denied-share did not kill valid client" \
+ test $COUNT -eq 0 || failed=$(expr $failed + 1)
+
+testit "Deny access" ${SHARESEC} ${CONF} --replace S-1-1-0:DENIED/0x0/FULL \
+ ${SHARE} || failed=$(expr $failed + 1)
+
+testit "smbcontrol" ${SMBCONTROL} ${CONF} smbd close-denied-share ${SHARE} ||
+ failed=$(expr $failed + 1)
+sleep 1
+
+echo dir >&100
+
+COUNT=$(head -n 2 <&101 |
+ grep NT_STATUS_NETWORK_NAME_DELETED |
+ wc -l)
+testit "Verify close-denied-share did kill now-invalid client" \
+ test $COUNT -eq 1 || failed=$(expr $failed + 1)
+
+kill ${CLIENT_PID}
+rm -f smbclient-stdin smbclient-stdout
+
+testit "Allow access" ${SHARESEC} ${CONF} --replace S-1-1-0:ALLOWED/0x0/FULL \
+ ${SHARE} || failed=$(expr $failed + 1)
+
+testok $0 $failed
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 7f51d344bab..ca427cc0c7c 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -784,6 +784,16 @@ plantestsuite("samba3.blackbox.sharesec", "simpleserver:local",
configuration, os.path.join(bindir(), "sharesec"),
os.path.join(bindir(), "net"), "tmp"])
+plantestsuite("samba3.blackbox.close-denied-share", "simpleserver:local",
+ [os.path.join(samba3srcdir,
+ "script/tests/test_close_denied_share.sh"),
+ configuration,
+ os.path.join(bindir(), "sharesec"),
+ os.path.join(bindir(), "smbclient"),
+ os.path.join(bindir(), "smbcontrol"),
+ '$SERVER_IP',
+ "tmp"])
+
plantestsuite("samba3.blackbox.net_tdb", "simpleserver:local",
[os.path.join(samba3srcdir, "script/tests/test_net_tdb.sh"),
smbclient3, '$SERVER', 'tmp', '$USERNAME', '$PASSWORD',
diff --git a/source3/smbd/conn_idle.c b/source3/smbd/conn_idle.c
index 078a0ed6917..cd12e3f1266 100644
--- a/source3/smbd/conn_idle.c
+++ b/source3/smbd/conn_idle.c
@@ -81,17 +81,13 @@ bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
The special sharename '*' forces unmount of all shares.
****************************************************************************/
-void conn_force_tdis(struct smbd_server_connection *sconn, const char *sharename)
+void conn_force_tdis(
+ struct smbd_server_connection *sconn,
+ bool (*check_fn)(struct connection_struct *conn,
+ void *private_data),
+ void *private_data)
{
- const struct loadparm_substitution *lp_sub =
- loadparm_s3_global_substitution();
connection_struct *conn, *next;
- bool close_all = false;
-
- if (strcmp(sharename, "*") == 0) {
- close_all = true;
- DEBUG(1, ("conn_force_tdis: Forcing close of all shares\n"));
- }
/* SMB1 and SMB 2*/
for (conn = sconn->connections; conn; conn = next) {
@@ -107,21 +103,16 @@ void conn_force_tdis(struct smbd_server_connection *sconn, const char *sharename
}
tcon = conn->tcon;
- if (close_all) {
- do_close = true;
- } else if (strequal(lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
- sharename)) {
- DEBUG(1, ("conn_force_tdis: Forcing close of "
- "share '%s' (wire_id=0x%08x)\n",
- tcon->global->share_name,
- tcon->global->tcon_wire_id));
- do_close = true;
- }
-
+ do_close = check_fn(conn, private_data);
if (!do_close) {
continue;
}
+ DBG_WARNING("Forcing close of "
+ "share '%s' (wire_id=0x%08x)\n",
+ tcon->global->share_name,
+ tcon->global->tcon_wire_id);
+
if (sconn->using_smb2) {
vuid = conn->vuid;
}
diff --git a/source3/smbd/conn_msg.c b/source3/smbd/conn_msg.c
index b4d563dbb99..9435d388508 100644
--- a/source3/smbd/conn_msg.c
+++ b/source3/smbd/conn_msg.c
@@ -30,13 +30,108 @@
The special sharename '*' forces unmount of all shares.
****************************************************************************/
+struct force_tdis_state {
+ const char *sharename;
+};
+
+static bool force_tdis_check(
+ struct connection_struct *conn,
+ void *private_data)
+{
+ struct force_tdis_state *state = private_data;
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
+ char *servicename = NULL;
+ bool do_close;
+
+ if (strcmp(state->sharename, "*") == 0) {
+ DBG_WARNING("Forcing close of all shares\n");
+ return true;
+ }
+
+ servicename = lp_servicename(talloc_tos(), lp_sub, SNUM(conn));
+ do_close = strequal(servicename, state->sharename);
+
+ TALLOC_FREE(servicename);
+
+ return do_close;
+}
+
void msg_force_tdis(struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
struct server_id server_id,
DATA_BLOB *data)
{
- const char *sharename = (const char *)data->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;
+ }
+
+ 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);
@@ -46,5 +141,8 @@ void msg_force_tdis(struct messaging_context *msg,
return;
}
- conn_force_tdis(sconn, sharename);
+ change_to_root_user();
+ reload_services(sconn, conn_snum_used, false);
+
+ conn_force_tdis(sconn, force_tdis_denied_check, &state);
}
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index f6eeafc88cf..70398b4967e 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -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,
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 4b1960b0c14..de4a53c6187 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -154,12 +154,22 @@ connection_struct *conn_new(struct smbd_server_connection *sconn);
bool conn_idle_all(struct smbd_server_connection *sconn, time_t t);
void conn_clear_vuid_caches(struct smbd_server_connection *sconn, uint64_t vuid);
void conn_free(connection_struct *conn);
-void conn_force_tdis(struct smbd_server_connection *sconn, const char *sharename);
+void conn_force_tdis(
+ struct smbd_server_connection *sconn,
+ bool (*check_fn)(struct connection_struct *conn,
+ void *private_data),
+ void *private_data);
void msg_force_tdis(struct messaging_context *msg,
void *private_data,
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 */
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 8fd4752ea45..cedd2b312a3 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -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);
--
Samba Shared Repository
More information about the samba-cvs
mailing list