Port knock of 445 prevents smbd from starting

Jeremy Allison jra at samba.org
Wed Jan 15 23:24:37 UTC 2020


On Wed, Jan 15, 2020 at 03:12:45PM -0800, Jeremy Allison via samba-technical wrote:
> On Wed, Jan 15, 2020 at 11:04:25PM +0000, Christopher O Cowan - Christopher.O.Cowan at ibm.com wrote:
> > So, the inbound packet is a connection attempt by the LB, no data is being set.  It looks like it is only verifying that it completes the 3 way handshake.    From my tcpdump traces, I see the SYN -> FIN and then it ends.
> > 
> > It reports a status of NT_STATUS_END_OF_FILE.    The smb_len is 5456, as it returns from read_smb_length_return_keepalive.  Seems to me this should be 0. 
> 
> read_fd_with_timeout() should not return with zero bytes
> when called from read_smb_length_return_keepalive().
> 
> read_smb_length_return_keepalive() ->
> 
> 	status = read_fd_with_timeout(fd, inbuf, 4, 4, timeout, NULL);
> 
> where:
> 
> NTSTATUS read_fd_with_timeout(int fd, char *buf,
>                                   size_t mincnt, size_t maxcnt,
>                                   unsigned int time_out,
>                                   size_t *size_ret)
> 
> mincnt and maxcnt == 4, so it should never be
> returning NT_STATUS_OK unless it read at least
> mincnt bytes.
> 
> Can you instrument read_fd_with_timeout() to
> find out what is going on here ?

Looking at the callers in source3/smbd/process.c
the timeout should be set to zero (blocking read).

In that case you should have:

NTSTATUS read_fd_with_timeout(int fd, char *buf,
                                  size_t mincnt, size_t maxcnt,
                                  unsigned int time_out,
                                  size_t *size_ret)
{
        int pollrtn;
        ssize_t readret;
        size_t nread = 0;

        /* just checking .... */
        if (maxcnt <= 0)
                return NT_STATUS_OK;

        /* Blocking read */
        if (time_out == 0) {
                if (mincnt == 0) {
                        mincnt = maxcnt;
                }

                while (nread < mincnt) {
                        readret = sys_read(fd, buf + nread, maxcnt - nread);

                        if (readret == 0) {
                                DEBUG(5,("read_fd_with_timeout: "
                                        "blocking read. EOF from client.\n"));
                                return NT_STATUS_END_OF_FILE;
                        }

                        if (readret == -1) {
                                return map_nt_error_from_unix(errno);
                        }
                        nread += readret;
                }
                goto done;
        }

so if sys_read() returned zero you should get read_fd_with_timeout()
returning NT_STATUS_END_OF_FILE.

read_smb_length_return_keepalive() should then return
that (NT_STATUS_END_OF_FILE) to the caller and never
try and do a read of any size. See below:

NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf,
                                          unsigned int timeout,
                                          size_t *len)
{
        int msg_type;
        NTSTATUS status;

        status = read_fd_with_timeout(fd, inbuf, 4, 4, timeout, NULL);

        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }




More information about the samba-technical mailing list