[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Mon Mar 22 10:26:50 MDT 2010


The branch, master has been updated
       via  cad0c00... s3: Implement an asynchronous echo responder process
       via  0c77e3a... s3:smbd: don't allow SMB2 if the async echo handler is active
       via  5a069f7... s3:smbd: disable SMB encryption when the echo handler is active
       via  d663b4c... s3:smbd: disallow readbraw and writebraw if the echo handler is active
       via  fbf112b... s3:smbd: disable sendfile if the echo handler is active
       via  453e6af... s3:smbd: don't use recvfile if the echo handler is active
       via  79e5e3d... s3:smbd: setup a shared memory area for the signing state
       via  44d655b... s3:smbd: add echo handler information to struct smbd_server_connection
       via  752240c... s3:param: add "async smb echo handler" option
       via  b2c107f... s3:smbd: pass down trusted_channel via receive_smb_talloc()
       via  1e7086e... s3:smbd: let reply_readbraw_error use the locked socket
       via  c1653e3... s3:smbd: send keepalive packets under the socket lock
       via  977aa66... s3:smbd: smbd_[un]lock_socket() while accessing the socket to the client
       via  8de8554... s3:smbd: add smbd_[un]lock_socket() dummies
       via  0b7da43... s3:smbd: add an option to skip signings checks srv_check_sign_mac for trusted channels
       via  048c919... s3:libsmb: add a smb_signing_init_ex() function
       via  01f2c02... lib/util: add allocate_anonymous_shared()
      from  13400a6... s3: Fix a bad memleak in winbind

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit cad0c004ad54d80dcb25803f0ebb317344a42792
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Mar 18 12:50:22 2010 +0100

    s3: Implement an asynchronous echo responder process
    
    This replies to echo requests when the main smbd is stuck somewhere
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 0c77e3a1bae728de3f48bdce4a82d85007ea9b45
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 22 09:06:07 2010 +0100

    s3:smbd: don't allow SMB2 if the async echo handler is active
    
    metze

commit 5a069f7209855e69082a176969533cc0d0ac0f55
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Mar 19 15:47:11 2010 +0100

    s3:smbd: disable SMB encryption when the echo handler is active
    
    metze

commit d663b4c6c03450366375eb0951209bc374835935
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 22 09:11:05 2010 +0100

    s3:smbd: disallow readbraw and writebraw if the echo handler is active
    
    metze

commit fbf112bd1684acf420b104e0e7d66721af47c676
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Mar 19 12:08:13 2010 +0100

    s3:smbd: disable sendfile if the echo handler is active
    
    metze

commit 453e6af5b81c8f206d87ec2e62fd79172f695950
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 18 20:22:26 2010 +0100

    s3:smbd: don't use recvfile if the echo handler is active
    
    metze

commit 79e5e3dda7178c4d3c5952a48474d6dcafba91ec
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Mar 19 14:59:19 2010 +0100

    s3:smbd: setup a shared memory area for the signing state
    
    metze

commit 44d655b33fecb7a543ff957940716ba93fec12cd
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 22 08:42:13 2010 +0100

    s3:smbd: add echo handler information to struct smbd_server_connection
    
    metze

commit 752240ccdc4dcdce7a2270ee5544e007c44bcf4d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 22 08:35:33 2010 +0100

    s3:param: add "async smb echo handler" option
    
    This will enable an extra forked process that will reply
    to SMBecho requests, while the main process is blocked by another
    request.
    
    metze

commit b2c107ffbcd067ccc42f81a2d0969f7f88b63ae7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 18 15:36:19 2010 +0100

    s3:smbd: pass down trusted_channel via receive_smb_talloc()
    
    metze

commit 1e7086e5ce0924687d657de583adb63a9f0c1bfb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Mar 19 12:04:32 2010 +0100

    s3:smbd: let reply_readbraw_error use the locked socket
    
    metze

commit c1653e3b0e536e835faf82a5aadadaec1cd38d1a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Mar 19 12:02:27 2010 +0100

    s3:smbd: send keepalive packets under the socket lock
    
    metze

commit 977aa660f452d8ebc8f3a2f4bfbf0dda0bc230a2
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 18 09:23:48 2010 +0100

    s3:smbd: smbd_[un]lock_socket() while accessing the socket to the client
    
    metze

commit 8de8554628bd3b16d9e488adfc31c8014c2eb1db
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 18 09:17:43 2010 +0100

    s3:smbd: add smbd_[un]lock_socket() dummies
    
    metze

commit 0b7da43da0bd5c7e0986854cda63103f082a26ee
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 18 09:14:40 2010 +0100

    s3:smbd: add an option to skip signings checks srv_check_sign_mac for trusted channels
    
    metze

commit 048c919dc0b7bc038becad34c2861c43c72c43c9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Mar 17 15:07:07 2010 +0100

    s3:libsmb: add a smb_signing_init_ex() function
    
    Make it possible to overload memory handling functions.
    
    metze

commit 01f2c023f7d2a4b0e016676638a062a5ba29ec0b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 22 08:27:58 2010 +0100

    lib/util: add allocate_anonymous_shared()
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 lib/util/util.c               |   28 ++
 lib/util/util.h               |    5 +
 source3/include/proto.h       |    3 +-
 source3/include/smb_signing.h |    5 +
 source3/libsmb/smb_signing.c  |   59 ++++-
 source3/param/loadparm.c      |   11 +
 source3/smbd/globals.c        |    3 +
 source3/smbd/globals.h        |   22 ++
 source3/smbd/process.c        |  543 +++++++++++++++++++++++++++++++++++++++--
 source3/smbd/reply.c          |   32 +++
 source3/smbd/signing.c        |  104 ++++++++-
 source3/smbd/trans2.c         |   10 +
 12 files changed, 799 insertions(+), 26 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/util.c b/lib/util/util.c
index 0064cef..d645f7e 100644
--- a/lib/util/util.c
+++ b/lib/util/util.c
@@ -25,6 +25,8 @@
 #include "system/network.h"
 #include "system/filesys.h"
 #include "system/locale.h"
+#include "system/shmem.h"
+
 #undef malloc
 #undef strcasecmp
 #undef strncasecmp
@@ -862,4 +864,30 @@ bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
 	return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
 }
 
+/* Map a shared memory buffer of at least nelem counters. */
+void *allocate_anonymous_shared(size_t bufsz)
+{
+	void *buf;
+	size_t pagesz = getpagesize();
+
+	if (bufsz % pagesz) {
+		bufsz = (bufsz + pagesz) % pagesz; /* round up to pagesz */
+	}
+
+#ifdef MAP_ANON
+	/* BSD */
+	buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED,
+			-1 /* fd */, 0 /* offset */);
+#else
+	buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
+			open("/dev/zero", O_RDWR), 0 /* offset */);
+#endif
+
+	if (buf == MAP_FAILED) {
+		return NULL;
+	}
+
+	return buf;
+
+}
 
diff --git a/lib/util/util.h b/lib/util/util.h
index e1160d5..2d4a025 100644
--- a/lib/util/util.h
+++ b/lib/util/util.h
@@ -880,6 +880,11 @@ bool add_uid_to_array_unique(TALLOC_CTX *mem_ctx, uid_t uid,
 bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
 			     gid_t **gids, size_t *num_gids);
 
+/**
+ * Allocate anonymous shared memory of the given size
+ */
+void *allocate_anonymous_shared(size_t bufsz);
+
 /*
   run a command as a child process, with a timeout.
 
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 4832a60..06d324e 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -3302,7 +3302,7 @@ void cli_set_signing_negotiated(struct cli_state *cli);
 
 struct smbd_server_connection;
 bool srv_check_sign_mac(struct smbd_server_connection *conn,
-			const char *inbuf, uint32_t *seqnum);
+			const char *inbuf, uint32_t *seqnum, bool trusted_channel);
 void srv_calculate_sign_mac(struct smbd_server_connection *conn,
 			    char *outbuf, uint32_t seqnum);
 void srv_cancel_sign_response(struct smbd_server_connection *conn);
@@ -4215,6 +4215,7 @@ bool lp_dos_filemode(int );
 bool lp_dos_filetimes(int );
 bool lp_dos_filetime_resolution(int );
 bool lp_fake_dir_create_times(int);
+bool lp_async_smb_echo_handler(void);
 bool lp_blocking_locks(int );
 bool lp_inherit_perms(int );
 bool lp_inherit_acls(int );
diff --git a/source3/include/smb_signing.h b/source3/include/smb_signing.h
index 770c40c..d2eda9b 100644
--- a/source3/include/smb_signing.h
+++ b/source3/include/smb_signing.h
@@ -27,6 +27,11 @@ struct smb_signing_state;
 struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx,
 					   bool allowed,
 					   bool mandatory);
+struct smb_signing_state *smb_signing_init_ex(TALLOC_CTX *mem_ctx,
+					      bool allowed,
+					      bool mandatory,
+					      void *(*alloc_fn)(TALLOC_CTX *, size_t),
+					      void (*free_fn)(TALLOC_CTX *, void *));
 uint32_t smb_signing_next_seqnum(struct smb_signing_state *si, bool oneway);
 void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway);
 void smb_signing_sign_pdu(struct smb_signing_state *si,
diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c
index 32d2883..104cf76 100644
--- a/source3/libsmb/smb_signing.c
+++ b/source3/libsmb/smb_signing.c
@@ -43,25 +43,50 @@ struct smb_signing_state {
 
 	/* the next expected seqnum */
 	uint32_t seqnum;
+
+	TALLOC_CTX *mem_ctx;
+	void *(*alloc_fn)(TALLOC_CTX *mem_ctx, size_t len);
+	void (*free_fn)(TALLOC_CTX *mem_ctx, void *ptr);
 };
 
 static void smb_signing_reset_info(struct smb_signing_state *si)
 {
 	si->active = false;
 	si->bsrspyl = false;
-	data_blob_free(&si->mac_key);
 	si->seqnum = 0;
+
+	if (si->free_fn) {
+		si->free_fn(si->mem_ctx, si->mac_key.data);
+	} else {
+		talloc_free(si->mac_key.data);
+	}
+	si->mac_key.data = NULL;
+	si->mac_key.length = 0;
 }
 
-struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx,
-					   bool allowed,
-					   bool mandatory)
+struct smb_signing_state *smb_signing_init_ex(TALLOC_CTX *mem_ctx,
+					      bool allowed,
+					      bool mandatory,
+					      void *(*alloc_fn)(TALLOC_CTX *, size_t),
+					      void (*free_fn)(TALLOC_CTX *, void *))
 {
 	struct smb_signing_state *si;
 
-	si = talloc_zero(mem_ctx, struct smb_signing_state);
-	if (si == NULL) {
-		return NULL;
+	if (alloc_fn) {
+		void *p = alloc_fn(mem_ctx, sizeof(struct smb_signing_state));
+		if (p == NULL) {
+			return NULL;
+		}
+		memset(p, 0, sizeof(struct smb_signing_state));
+		si = (struct smb_signing_state *)p;
+		si->mem_ctx = mem_ctx;
+		si->alloc_fn = alloc_fn;
+		si->free_fn = free_fn;
+	} else {
+		si = talloc_zero(mem_ctx, struct smb_signing_state);
+		if (si == NULL) {
+			return NULL;
+		}
 	}
 
 	if (mandatory) {
@@ -74,6 +99,13 @@ struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx,
 	return si;
 }
 
+struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx,
+					   bool allowed,
+					   bool mandatory)
+{
+	return smb_signing_init_ex(mem_ctx, allowed, mandatory, NULL, NULL);
+}
+
 static bool smb_signing_good(struct smb_signing_state *si,
 			     bool good, uint32_t seq)
 {
@@ -312,7 +344,18 @@ bool smb_signing_activate(struct smb_signing_state *si,
 	smb_signing_reset_info(si);
 
 	len = response.length + user_session_key.length;
-	si->mac_key = data_blob_talloc(si, NULL, len);
+	if (si->alloc_fn) {
+		si->mac_key.data = (uint8_t *)si->alloc_fn(si->mem_ctx, len);
+		if (si->mac_key.data == NULL) {
+			return false;
+		}
+	} else {
+		si->mac_key.data = (uint8_t *)talloc_size(si, len);
+		if (si->mac_key.data == NULL) {
+			return false;
+		}
+	}
+	si->mac_key.length = len;
 
 	ofs = 0;
 	memcpy(&si->mac_key.data[ofs], user_session_key.data, user_session_key.length);
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index e94c270..76b0d35 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -360,6 +360,7 @@ struct global {
 	int cups_connection_timeout;
 	char *szSMBPerfcountModule;
 	bool bMapUntrustedToDomain;
+	bool bAsyncSMBEchoHandler;
 };
 
 static struct global Globals;
@@ -4353,6 +4354,15 @@ static struct parm_struct parm_table[] = {
 		.flags		= FLAG_ADVANCED | FLAG_GLOBAL,
 	},
 	{
+		.label		= "async smb echo handler",
+		.type		= P_BOOL,
+		.p_class	= P_GLOBAL,
+		.ptr		= &Globals.bAsyncSMBEchoHandler,
+		.special	= NULL,
+		.enum_list	= NULL,
+		.flags		= FLAG_ADVANCED | FLAG_GLOBAL,
+	},
+	{
 		.label		= "panic action",
 		.type		= P_STRING,
 		.p_class	= P_GLOBAL,
@@ -5701,6 +5711,7 @@ FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
+FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index a632aa2..0284171 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -151,4 +151,7 @@ void smbd_init_globals(void)
 	if (!smbd_server_conn) {
 		exit_server("failed to create smbd_server_connection");
 	}
+
+	smbd_server_conn->smb1.echo_handler.trusted_fd = -1;
+	smbd_server_conn->smb1.echo_handler.socket_lock_fd = -1;
 }
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 428733d..6e5262a 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -153,6 +153,9 @@ struct smbd_smb2_tcon;
 
 DATA_BLOB negprot_spnego(void);
 
+bool smbd_lock_socket(struct smbd_server_connection *sconn);
+bool smbd_unlock_socket(struct smbd_server_connection *sconn);
+
 NTSTATUS smb2_signing_sign_pdu(DATA_BLOB session_key,
 			       struct iovec *vector,
 			       int count);
@@ -432,6 +435,25 @@ struct smbd_server_connection {
 	bool allow_smb2;
 	struct {
 		struct fd_event *fde;
+
+		struct {
+			/*
+			 * fd for the fcntl lock mutexing access to smbd_server_fd
+			 */
+			int socket_lock_fd;
+
+			/*
+			 * fd for the trusted pipe from
+			 * echo handler child
+			 */
+			int trusted_fd;
+
+			/*
+			 * fde for the trusted_fd
+			 */
+			struct fd_event *trusted_fde;
+		} echo_handler;
+
 		uint64_t num_requests;
 		struct {
 			bool encrypted_passwords;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index f467587..6068816 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -40,6 +40,46 @@ extern bool global_machine_password_needs_changing;
 static void construct_reply_common(struct smb_request *req, const char *inbuf,
 				   char *outbuf);
 
+bool smbd_lock_socket(struct smbd_server_connection *sconn)
+{
+	bool ok;
+
+	if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
+		return true;
+	}
+
+	DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
+
+	ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
+			SMB_F_SETLKW, 0, 0, F_WRLCK);
+	if (!ok) {
+		return false;
+	}
+
+	DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
+
+	return true;
+}
+
+bool smbd_unlock_socket(struct smbd_server_connection *sconn)
+{
+	bool ok;
+
+	if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
+		return true;
+	}
+
+	ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
+			SMB_F_SETLKW, 0, 0, F_UNLCK);
+	if (!ok) {
+		return false;
+	}
+
+	DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
+
+	return true;
+}
+
 /* Accessor function for smb_read_error for smbd functions. */
 
 /****************************************************************************
@@ -55,6 +95,12 @@ bool srv_send_smb(int fd, char *buffer,
 	size_t nwritten=0;
 	ssize_t ret;
 	char *buf_out = buffer;
+	bool ok;
+
+	ok = smbd_lock_socket(smbd_server_conn);
+	if (!ok) {
+		exit_server_cleanly("failed to lock socket");
+	}
 
 	if (do_signing) {
 		/* Sign the outgoing packet if required. */
@@ -75,8 +121,8 @@ bool srv_send_smb(int fd, char *buffer,
 
 	ret = write_data(fd,buf_out+nwritten,len - nwritten);
 	if (ret <= 0) {
-		DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
-			 (int)len,(int)ret, strerror(errno) ));
+		DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
+			(int)sys_getpid(), (int)len,(int)ret, strerror(errno) ));
 		srv_free_enc_buffer(buf_out);
 		goto out;
 	}
@@ -85,6 +131,12 @@ bool srv_send_smb(int fd, char *buffer,
 	srv_free_enc_buffer(buf_out);
 out:
 	SMB_PERFCOUNT_END(pcd);
+
+	ok = smbd_unlock_socket(smbd_server_conn);
+	if (!ok) {
+		exit_server_cleanly("failed to unlock socket");
+	}
+
 	return true;
 }
 
@@ -290,7 +342,8 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
 	if (CVAL(lenbuf,0) == 0 && min_recv_size &&
 	    (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
 		(min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
-	    !srv_is_signing_active(smbd_server_conn)) {
+	    !srv_is_signing_active(smbd_server_conn) &&
+	    smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
 
 		return receive_smb_raw_talloc_partial_read(
 			mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
@@ -327,7 +380,8 @@ static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,	int fd,
 				   char **buffer, unsigned int timeout,
 				   size_t *p_unread, bool *p_encrypted,
 				   size_t *p_len,
-				   uint32_t *seqnum)
+				   uint32_t *seqnum,
+				   bool trusted_channel)
 {
 	size_t len = 0;
 	NTSTATUS status;
@@ -352,7 +406,7 @@ static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,	int fd,
 	}
 
 	/* Check the incoming SMB signature. */
-	if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum)) {
+	if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
 		DEBUG(0, ("receive_smb: SMB Signature verification failed on "
 			  "incoming packet!\n"));
 		return NT_STATUS_INVALID_NETWORK_RESPONSE;
@@ -2088,12 +2142,29 @@ void check_reload(time_t t)
 	}
 }
 
+static bool fd_is_readable(int fd)
+{
+	fd_set fds;
+	struct timeval timeout = {0, };
+	int ret;
+
+	FD_ZERO(&fds);
+	FD_SET(fd, &fds);
+
+	ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
+	if (ret == -1) {
+		return false;
+	}
+	return FD_ISSET(fd, &fds);
+}
+
 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
 {
 	/* TODO: make write nonblocking */
 }
 
-static void smbd_server_connection_read_handler(struct smbd_server_connection *conn)
+static void smbd_server_connection_read_handler(
+	struct smbd_server_connection *conn, int fd)
 {
 	uint8_t *inbuf = NULL;
 	size_t inbuf_len = 0;
@@ -2103,14 +2174,48 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c
 	NTSTATUS status;
 	uint32_t seqnum;
 
-	/* TODO: make this completely nonblocking */
+	bool ok;
+
+	bool from_client = (smbd_server_fd() == fd)?true:false;
+
+	if (from_client) {
+		ok = smbd_lock_socket(conn);
+		if (!ok) {
+			exit_server_cleanly("failed to lock socket");
+		}
+
+		if (!fd_is_readable(smbd_server_fd())) {
+			DEBUG(10,("the echo listener was faster\n"));
+			ok = smbd_unlock_socket(conn);
+			if (!ok) {
+				exit_server_cleanly("failed to unlock");
+			}
+			return;
+		}
+
+		/* TODO: make this completely nonblocking */
+		status = receive_smb_talloc(mem_ctx, fd,
+					    (char **)(void *)&inbuf,
+					    0, /* timeout */
+					    &unread_bytes,
+					    &encrypted,
+					    &inbuf_len, &seqnum,
+					    false /* trusted channel */);
+		ok = smbd_unlock_socket(conn);
+		if (!ok) {
+			exit_server_cleanly("failed to unlock");
+		}
+	} else {
+		/* TODO: make this completely nonblocking */
+		status = receive_smb_talloc(mem_ctx, fd,
+					    (char **)(void *)&inbuf,
+					    0, /* timeout */
+					    &unread_bytes,
+					    &encrypted,
+					    &inbuf_len, &seqnum,
+					    true /* trusted channel */);
+	}
 
-	status = receive_smb_talloc(mem_ctx, smbd_server_fd(),
-				    (char **)(void *)&inbuf,
-				    0, /* timeout */
-				    &unread_bytes,
-				    &encrypted,
-				    &inbuf_len, &seqnum);
 	if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
 		goto process;
 	}
@@ -2137,10 +2242,25 @@ static void smbd_server_connection_handler(struct event_context *ev,
 	if (flags & EVENT_FD_WRITE) {
 		smbd_server_connection_write_handler(conn);
 	} else if (flags & EVENT_FD_READ) {
-		smbd_server_connection_read_handler(conn);
+		smbd_server_connection_read_handler(conn, smbd_server_fd());
 	}
 }
 
+static void smbd_server_echo_handler(struct event_context *ev,
+				     struct fd_event *fde,
+				     uint16_t flags,
+				     void *private_data)
+{
+	struct smbd_server_connection *conn = talloc_get_type(private_data,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list