[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