LCOV - code coverage report
Current view: top level - source3/smbd - process.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 905 1669 54.2 %
Date: 2021-08-25 13:27:56 Functions: 61 91 67.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    process incoming packets - main loop
       4             :    Copyright (C) Andrew Tridgell 1992-1998
       5             :    Copyright (C) Volker Lendecke 2005-2007
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "../lib/tsocket/tsocket.h"
      23             : #include "system/filesys.h"
      24             : #include "smbd/smbd.h"
      25             : #include "smbd/globals.h"
      26             : #include "librpc/gen_ndr/netlogon.h"
      27             : #include "../lib/async_req/async_sock.h"
      28             : #include "ctdbd_conn.h"
      29             : #include "../lib/util/select.h"
      30             : #include "printing/queue_process.h"
      31             : #include "system/select.h"
      32             : #include "passdb.h"
      33             : #include "auth.h"
      34             : #include "messages.h"
      35             : #include "lib/messages_ctdb.h"
      36             : #include "smbprofile.h"
      37             : #include "rpc_server/spoolss/srv_spoolss_nt.h"
      38             : #include "../lib/util/tevent_ntstatus.h"
      39             : #include "../libcli/security/dom_sid.h"
      40             : #include "../libcli/security/security_token.h"
      41             : #include "lib/id_cache.h"
      42             : #include "lib/util/sys_rw_data.h"
      43             : #include "system/threads.h"
      44             : #include "lib/pthreadpool/pthreadpool_tevent.h"
      45             : #include "util_event.h"
      46             : #include "libcli/smb/smbXcli_base.h"
      47             : #include "lib/util/time_basic.h"
      48             : #include "smb1_utils.h"
      49             : 
      50             : /* Internal message queue for deferred opens. */
      51             : struct pending_message_list {
      52             :         struct pending_message_list *next, *prev;
      53             :         struct timeval request_time; /* When was this first issued? */
      54             :         struct smbd_server_connection *sconn;
      55             :         struct smbXsrv_connection *xconn;
      56             :         struct tevent_timer *te;
      57             :         struct smb_perfcount_data pcd;
      58             :         uint32_t seqnum;
      59             :         bool encrypted;
      60             :         bool processed;
      61             :         DATA_BLOB buf;
      62             :         struct deferred_open_record *open_rec;
      63             : };
      64             : 
      65             : static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
      66             :                                    char *outbuf);
      67             : static struct pending_message_list *get_deferred_open_message_smb(
      68             :         struct smbd_server_connection *sconn, uint64_t mid);
      69             : static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
      70             : 
      71       27904 : static void smbd_echo_init(struct smbXsrv_connection *xconn)
      72             : {
      73       28434 :         xconn->smb1.echo_handler.trusted_fd = -1;
      74       28434 :         xconn->smb1.echo_handler.socket_lock_fd = -1;
      75             : #ifdef HAVE_ROBUST_MUTEXES
      76       28434 :         xconn->smb1.echo_handler.socket_mutex = NULL;
      77             : #endif
      78       27904 : }
      79             : 
      80     1239512 : static bool smbd_echo_active(struct smbXsrv_connection *xconn)
      81             : {
      82     1255154 :         if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
      83           0 :                 return true;
      84             :         }
      85             : 
      86             : #ifdef HAVE_ROBUST_MUTEXES
      87     1255154 :         if (xconn->smb1.echo_handler.socket_mutex != NULL) {
      88           0 :                 return true;
      89             :         }
      90             : #endif
      91             : 
      92     1239512 :         return false;
      93             : }
      94             : 
      95      627577 : static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
      96             : {
      97      627577 :         if (!smbd_echo_active(xconn)) {
      98      619756 :                 return true;
      99             :         }
     100             : 
     101           0 :         xconn->smb1.echo_handler.ref_count++;
     102             : 
     103           0 :         if (xconn->smb1.echo_handler.ref_count > 1) {
     104           0 :                 return true;
     105             :         }
     106             : 
     107           0 :         DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
     108             : 
     109             : #ifdef HAVE_ROBUST_MUTEXES
     110           0 :         if (xconn->smb1.echo_handler.socket_mutex != NULL) {
     111           0 :                 int ret = EINTR;
     112             : 
     113           0 :                 while (ret == EINTR) {
     114           0 :                         ret = pthread_mutex_lock(
     115             :                                 xconn->smb1.echo_handler.socket_mutex);
     116           0 :                         if (ret == 0) {
     117           0 :                                 break;
     118             :                         }
     119             :                 }
     120           0 :                 if (ret != 0) {
     121           0 :                         DEBUG(1, ("pthread_mutex_lock failed: %s\n",
     122             :                                   strerror(ret)));
     123           0 :                         return false;
     124             :                 }
     125             :         }
     126             : #endif
     127             : 
     128           0 :         if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
     129             :                 bool ok;
     130             : 
     131             :                 do {
     132           0 :                         ok = fcntl_lock(
     133             :                                 xconn->smb1.echo_handler.socket_lock_fd,
     134             :                                 F_SETLKW, 0, 0, F_WRLCK);
     135           0 :                 } while (!ok && (errno == EINTR));
     136             : 
     137           0 :                 if (!ok) {
     138           0 :                         DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
     139           0 :                         return false;
     140             :                 }
     141             :         }
     142             : 
     143           0 :         DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
     144             : 
     145           0 :         return true;
     146             : }
     147             : 
     148      627577 : void smbd_lock_socket(struct smbXsrv_connection *xconn)
     149             : {
     150      627577 :         if (!smbd_lock_socket_internal(xconn)) {
     151           0 :                 exit_server_cleanly("failed to lock socket");
     152             :         }
     153      627577 : }
     154             : 
     155      627577 : static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
     156             : {
     157      627577 :         if (!smbd_echo_active(xconn)) {
     158      619756 :                 return true;
     159             :         }
     160             : 
     161           0 :         xconn->smb1.echo_handler.ref_count--;
     162             : 
     163           0 :         if (xconn->smb1.echo_handler.ref_count > 0) {
     164           0 :                 return true;
     165             :         }
     166             : 
     167             : #ifdef HAVE_ROBUST_MUTEXES
     168           0 :         if (xconn->smb1.echo_handler.socket_mutex != NULL) {
     169             :                 int ret;
     170           0 :                 ret = pthread_mutex_unlock(
     171             :                         xconn->smb1.echo_handler.socket_mutex);
     172           0 :                 if (ret != 0) {
     173           0 :                         DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
     174             :                                   strerror(ret)));
     175           0 :                         return false;
     176             :                 }
     177             :         }
     178             : #endif
     179             : 
     180           0 :         if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
     181             :                 bool ok;
     182             : 
     183             :                 do {
     184           0 :                         ok = fcntl_lock(
     185             :                                 xconn->smb1.echo_handler.socket_lock_fd,
     186             :                                 F_SETLKW, 0, 0, F_UNLCK);
     187           0 :                 } while (!ok && (errno == EINTR));
     188             : 
     189           0 :                 if (!ok) {
     190           0 :                         DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
     191           0 :                         return false;
     192             :                 }
     193             :         }
     194             : 
     195           0 :         DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
     196             : 
     197           0 :         return true;
     198             : }
     199             : 
     200      627577 : void smbd_unlock_socket(struct smbXsrv_connection *xconn)
     201             : {
     202      627577 :         if (!smbd_unlock_socket_internal(xconn)) {
     203           0 :                 exit_server_cleanly("failed to unlock socket");
     204             :         }
     205      627577 : }
     206             : 
     207             : /* Accessor function for smb_read_error for smbd functions. */
     208             : 
     209             : /****************************************************************************
     210             :  Send an smb to a fd.
     211             : ****************************************************************************/
     212             : 
     213      627538 : bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
     214             :                   bool do_signing, uint32_t seqnum,
     215             :                   bool do_encrypt,
     216             :                   struct smb_perfcount_data *pcd)
     217             : {
     218      627538 :         size_t len = 0;
     219             :         ssize_t ret;
     220      627538 :         char *buf_out = buffer;
     221             : 
     222      627538 :         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
     223             :                 /*
     224             :                  * we're not supposed to do any io
     225             :                  */
     226          42 :                 return true;
     227             :         }
     228             : 
     229      627496 :         smbd_lock_socket(xconn);
     230             : 
     231      627496 :         if (do_signing) {
     232             :                 NTSTATUS status;
     233             : 
     234             :                 /* Sign the outgoing packet if required. */
     235      625835 :                 status = srv_calculate_sign_mac(xconn, buf_out, seqnum);
     236      625835 :                 if (!NT_STATUS_IS_OK(status)) {
     237           0 :                         DBG_ERR("Failed to calculate signing mac: %s\n",
     238             :                                 nt_errstr(status));
     239           0 :                         return false;
     240             :                 }
     241             :         }
     242             : 
     243      627496 :         if (do_encrypt) {
     244      184607 :                 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
     245      184607 :                 if (!NT_STATUS_IS_OK(status)) {
     246           0 :                         DEBUG(0, ("send_smb: SMB encryption failed "
     247             :                                 "on outgoing packet! Error %s\n",
     248             :                                 nt_errstr(status) ));
     249           0 :                         ret = -1;
     250           0 :                         goto out;
     251             :                 }
     252             :         }
     253             : 
     254      627496 :         len = smb_len_large(buf_out) + 4;
     255             : 
     256      627496 :         ret = write_data(xconn->transport.sock, buf_out, len);
     257      627496 :         if (ret <= 0) {
     258         148 :                 int saved_errno = errno;
     259             :                 /*
     260             :                  * Try and give an error message saying what
     261             :                  * client failed.
     262             :                  */
     263         148 :                 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
     264             :                          (int)getpid(), (int)len,
     265             :                          smbXsrv_connection_dbg(xconn),
     266             :                          (int)ret, strerror(saved_errno)));
     267         148 :                 errno = saved_errno;
     268             : 
     269         148 :                 srv_free_enc_buffer(xconn, buf_out);
     270         148 :                 goto out;
     271             :         }
     272             : 
     273      627348 :         SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
     274      627348 :         srv_free_enc_buffer(xconn, buf_out);
     275      627496 : out:
     276      627496 :         SMB_PERFCOUNT_END(pcd);
     277             : 
     278      627496 :         smbd_unlock_socket(xconn);
     279      627496 :         return (ret > 0);
     280             : }
     281             : 
     282             : /*******************************************************************
     283             :  Setup the word count and byte count for a smb message.
     284             : ********************************************************************/
     285             : 
     286     1269954 : size_t srv_set_message(char *buf,
     287             :                        size_t num_words,
     288             :                        size_t num_bytes,
     289             :                        bool zero)
     290             : {
     291     1269954 :         if (zero && (num_words || num_bytes)) {
     292      142049 :                 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
     293             :         }
     294     1269954 :         SCVAL(buf,smb_wct,num_words);
     295     1269954 :         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
     296     1269954 :         smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
     297     1269954 :         return (smb_size + num_words*2 + num_bytes);
     298             : }
     299             : 
     300      671309 : static bool valid_smb_header(const uint8_t *inbuf)
     301             : {
     302      671309 :         if (is_encrypted_packet(inbuf)) {
     303           0 :                 return true;
     304             :         }
     305             :         /*
     306             :          * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
     307             :          * but it just looks weird to call strncmp for this one.
     308             :          */
     309      671309 :         return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
     310             : }
     311             : 
     312             : /* Socket functions for smbd packet processing. */
     313             : 
     314      650714 : static bool valid_packet_size(size_t len)
     315             : {
     316             :         /*
     317             :          * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
     318             :          * of header. Don't print the error if this fits.... JRA.
     319             :          */
     320             : 
     321      650714 :         if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
     322           0 :                 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
     323             :                                         (unsigned long)len));
     324           0 :                 return false;
     325             :         }
     326      642506 :         return true;
     327             : }
     328             : 
     329      650714 : static NTSTATUS read_packet_remainder(int fd, char *buffer,
     330             :                                       unsigned int timeout, ssize_t len)
     331             : {
     332             :         NTSTATUS status;
     333             : 
     334      650714 :         if (len <= 0) {
     335           0 :                 return NT_STATUS_OK;
     336             :         }
     337             : 
     338      650714 :         status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
     339      650714 :         if (!NT_STATUS_IS_OK(status)) {
     340             :                 char addr[INET6_ADDRSTRLEN];
     341           0 :                 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
     342             :                           "error = %s.\n",
     343             :                           get_peer_addr(fd, addr, sizeof(addr)),
     344             :                           nt_errstr(status)));
     345             :         }
     346      650714 :         return status;
     347             : }
     348             : 
     349             : /****************************************************************************
     350             :  Attempt a zerocopy writeX read. We know here that len > smb_size-4
     351             : ****************************************************************************/
     352             : 
     353             : /*
     354             :  * Unfortunately, earlier versions of smbclient/libsmbclient
     355             :  * don't send this "standard" writeX header. I've fixed this
     356             :  * for 3.2 but we'll use the old method with earlier versions.
     357             :  * Windows and CIFSFS at least use this standard size. Not
     358             :  * sure about MacOSX.
     359             :  */
     360             : 
     361             : #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
     362             :                                 (2*14) + /* word count (including bcc) */ \
     363             :                                 1 /* pad byte */)
     364             : 
     365           0 : static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
     366             :                                                     const char lenbuf[4],
     367             :                                                     struct smbXsrv_connection *xconn,
     368             :                                                     int sock,
     369             :                                                     char **buffer,
     370             :                                                     unsigned int timeout,
     371             :                                                     size_t *p_unread,
     372             :                                                     size_t *len_ret)
     373             : {
     374             :         /* Size of a WRITEX call (+4 byte len). */
     375             :         char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
     376           0 :         ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
     377             :         ssize_t toread;
     378             :         NTSTATUS status;
     379             : 
     380           0 :         memcpy(writeX_header, lenbuf, 4);
     381             : 
     382           0 :         status = read_fd_with_timeout(
     383             :                 sock, writeX_header + 4,
     384             :                 STANDARD_WRITE_AND_X_HEADER_SIZE,
     385             :                 STANDARD_WRITE_AND_X_HEADER_SIZE,
     386             :                 timeout, NULL);
     387             : 
     388           0 :         if (!NT_STATUS_IS_OK(status)) {
     389           0 :                 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
     390             :                           "error = %s.\n",
     391             :                           smbXsrv_connection_dbg(xconn),
     392             :                           nt_errstr(status)));
     393           0 :                 return status;
     394             :         }
     395             : 
     396             :         /*
     397             :          * Ok - now try and see if this is a possible
     398             :          * valid writeX call.
     399             :          */
     400             : 
     401           0 :         if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
     402             :                 /*
     403             :                  * If the data offset is beyond what
     404             :                  * we've read, drain the extra bytes.
     405             :                  */
     406           0 :                 uint16_t doff = SVAL(writeX_header,smb_vwv11);
     407             :                 ssize_t newlen;
     408             : 
     409           0 :                 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
     410           0 :                         size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
     411           0 :                         if (drain_socket(sock, drain) != drain) {
     412           0 :                                 smb_panic("receive_smb_raw_talloc_partial_read:"
     413             :                                         " failed to drain pending bytes");
     414             :                         }
     415             :                 } else {
     416           0 :                         doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
     417             :                 }
     418             : 
     419             :                 /* Spoof down the length and null out the bcc. */
     420           0 :                 set_message_bcc(writeX_header, 0);
     421           0 :                 newlen = smb_len(writeX_header);
     422             : 
     423             :                 /* Copy the header we've written. */
     424             : 
     425           0 :                 *buffer = (char *)talloc_memdup(mem_ctx,
     426             :                                 writeX_header,
     427             :                                 sizeof(writeX_header));
     428             : 
     429           0 :                 if (*buffer == NULL) {
     430           0 :                         DEBUG(0, ("Could not allocate inbuf of length %d\n",
     431             :                                   (int)sizeof(writeX_header)));
     432           0 :                         return NT_STATUS_NO_MEMORY;
     433             :                 }
     434             : 
     435             :                 /* Work out the remaining bytes. */
     436           0 :                 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
     437           0 :                 *len_ret = newlen + 4;
     438           0 :                 return NT_STATUS_OK;
     439             :         }
     440             : 
     441           0 :         if (!valid_packet_size(len)) {
     442           0 :                 return NT_STATUS_INVALID_PARAMETER;
     443             :         }
     444             : 
     445             :         /*
     446             :          * Not a valid writeX call. Just do the standard
     447             :          * talloc and return.
     448             :          */
     449             : 
     450           0 :         *buffer = talloc_array(mem_ctx, char, len+4);
     451             : 
     452           0 :         if (*buffer == NULL) {
     453           0 :                 DEBUG(0, ("Could not allocate inbuf of length %d\n",
     454             :                           (int)len+4));
     455           0 :                 return NT_STATUS_NO_MEMORY;
     456             :         }
     457             : 
     458             :         /* Copy in what we already read. */
     459           0 :         memcpy(*buffer,
     460             :                 writeX_header,
     461             :                 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
     462           0 :         toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
     463             : 
     464           0 :         if(toread > 0) {
     465           0 :                 status = read_packet_remainder(
     466             :                         sock,
     467           0 :                         (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
     468             :                         timeout, toread);
     469             : 
     470           0 :                 if (!NT_STATUS_IS_OK(status)) {
     471           0 :                         DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
     472             :                                    nt_errstr(status)));
     473           0 :                         return status;
     474             :                 }
     475             :         }
     476             : 
     477           0 :         *len_ret = len + 4;
     478           0 :         return NT_STATUS_OK;
     479             : }
     480             : 
     481      655556 : static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
     482             :                                        struct smbXsrv_connection *xconn,
     483             :                                        int sock,
     484             :                                        char **buffer, unsigned int timeout,
     485             :                                        size_t *p_unread, size_t *plen)
     486             : {
     487             :         char lenbuf[4];
     488             :         size_t len;
     489      655556 :         int min_recv_size = lp_min_receive_file_size();
     490             :         NTSTATUS status;
     491             : 
     492      655556 :         *p_unread = 0;
     493             : 
     494      655556 :         status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
     495             :                                                   &len);
     496      655556 :         if (!NT_STATUS_IS_OK(status)) {
     497        4842 :                 return status;
     498             :         }
     499             : 
     500      650714 :         if (CVAL(lenbuf,0) == 0 && min_recv_size &&
     501           0 :             (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
     502           0 :                 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
     503           0 :             !srv_is_signing_active(xconn) &&
     504           0 :             xconn->smb1.echo_handler.trusted_fde == NULL) {
     505             : 
     506           0 :                 return receive_smb_raw_talloc_partial_read(
     507             :                         mem_ctx, lenbuf, xconn, sock, buffer, timeout,
     508             :                         p_unread, plen);
     509             :         }
     510             : 
     511      650714 :         if (!valid_packet_size(len)) {
     512           0 :                 return NT_STATUS_INVALID_PARAMETER;
     513             :         }
     514             : 
     515             :         /*
     516             :          * The +4 here can't wrap, we've checked the length above already.
     517             :          */
     518             : 
     519      650714 :         *buffer = talloc_array(mem_ctx, char, len+4);
     520             : 
     521      650714 :         if (*buffer == NULL) {
     522           0 :                 DEBUG(0, ("Could not allocate inbuf of length %d\n",
     523             :                           (int)len+4));
     524           0 :                 return NT_STATUS_NO_MEMORY;
     525             :         }
     526             : 
     527      658922 :         memcpy(*buffer, lenbuf, sizeof(lenbuf));
     528             : 
     529      650714 :         status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
     530      650714 :         if (!NT_STATUS_IS_OK(status)) {
     531           0 :                 return status;
     532             :         }
     533             : 
     534      650714 :         *plen = len + 4;
     535      650714 :         return NT_STATUS_OK;
     536             : }
     537             : 
     538      655556 : static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
     539             :                                    struct smbXsrv_connection *xconn,
     540             :                                    int sock,
     541             :                                    char **buffer, unsigned int timeout,
     542             :                                    size_t *p_unread, bool *p_encrypted,
     543             :                                    size_t *p_len,
     544             :                                    uint32_t *seqnum,
     545             :                                    bool trusted_channel)
     546             : {
     547      655556 :         size_t len = 0;
     548             :         NTSTATUS status;
     549             : 
     550      655556 :         *p_encrypted = false;
     551             : 
     552      655556 :         status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
     553             :                                         p_unread, &len);
     554      655556 :         if (!NT_STATUS_IS_OK(status)) {
     555        4842 :                 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
     556             :                       ("receive_smb_raw_talloc failed for client %s "
     557             :                        "read error = %s.\n",
     558             :                        smbXsrv_connection_dbg(xconn),
     559             :                        nt_errstr(status)) );
     560        4842 :                 return status;
     561             :         }
     562             : 
     563      650714 :         if (is_encrypted_packet((uint8_t *)*buffer)) {
     564      184603 :                 status = srv_decrypt_buffer(xconn, *buffer);
     565      184603 :                 if (!NT_STATUS_IS_OK(status)) {
     566           0 :                         DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
     567             :                                 "incoming packet! Error %s\n",
     568             :                                 nt_errstr(status) ));
     569           0 :                         return status;
     570             :                 }
     571      184603 :                 *p_encrypted = true;
     572             :         }
     573             : 
     574             :         /* Check the incoming SMB signature. */
     575      650714 :         if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
     576           0 :                 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
     577             :                           "incoming packet!\n"));
     578           0 :                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
     579             :         }
     580             : 
     581      650714 :         *p_len = len;
     582      650714 :         return NT_STATUS_OK;
     583             : }
     584             : 
     585             : /*
     586             :  * Initialize a struct smb_request from an inbuf
     587             :  */
     588             : 
     589      646395 : static bool init_smb_request(struct smb_request *req,
     590             :                              struct smbd_server_connection *sconn,
     591             :                              struct smbXsrv_connection *xconn,
     592             :                              const uint8_t *inbuf,
     593             :                              size_t unread_bytes, bool encrypted,
     594             :                              uint32_t seqnum)
     595             : {
     596             :         struct smbXsrv_tcon *tcon;
     597             :         NTSTATUS status;
     598             :         NTTIME now;
     599      646395 :         size_t req_size = smb_len(inbuf) + 4;
     600             : 
     601             :         /* Ensure we have at least smb_size bytes. */
     602      646395 :         if (req_size < smb_size) {
     603           0 :                 DEBUG(0,("init_smb_request: invalid request size %u\n",
     604             :                         (unsigned int)req_size ));
     605           0 :                 return false;
     606             :         }
     607             : 
     608      646395 :         req->request_time = timeval_current();
     609      646395 :         now = timeval_to_nttime(&req->request_time);
     610             : 
     611      646395 :         req->cmd    = CVAL(inbuf, smb_com);
     612      646395 :         req->flags2 = SVAL(inbuf, smb_flg2);
     613      646395 :         req->smbpid = SVAL(inbuf, smb_pid);
     614      646395 :         req->mid    = (uint64_t)SVAL(inbuf, smb_mid);
     615      646395 :         req->seqnum = seqnum;
     616      646395 :         req->vuid   = SVAL(inbuf, smb_uid);
     617      646395 :         req->tid    = SVAL(inbuf, smb_tid);
     618      646395 :         req->wct    = CVAL(inbuf, smb_wct);
     619      646395 :         req->vwv    = (const uint16_t *)(inbuf+smb_vwv);
     620      646395 :         req->buflen = smb_buflen(inbuf);
     621      646395 :         req->buf    = (const uint8_t *)smb_buf_const(inbuf);
     622      646395 :         req->unread_bytes = unread_bytes;
     623      646395 :         req->encrypted = encrypted;
     624      646395 :         req->sconn = sconn;
     625      646395 :         req->xconn = xconn;
     626      646395 :         req->conn = NULL;
     627      646395 :         if (xconn != NULL) {
     628      646395 :                 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
     629      646395 :                 if (NT_STATUS_IS_OK(status)) {
     630      606937 :                         req->conn = tcon->compat;
     631             :                 }
     632             :         }
     633      646395 :         req->chain_fsp = NULL;
     634      646395 :         req->smb2req = NULL;
     635      646395 :         req->chain = NULL;
     636      646395 :         req->posix_pathnames = lp_posix_pathnames();
     637      646395 :         smb_init_perfcount_data(&req->pcd);
     638             : 
     639             :         /* Ensure we have at least wct words and 2 bytes of bcc. */
     640      646395 :         if (smb_size + req->wct*2 > req_size) {
     641           0 :                 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
     642             :                         (unsigned int)req->wct,
     643             :                         (unsigned int)req_size));
     644           0 :                 return false;
     645             :         }
     646             :         /* Ensure bcc is correct. */
     647      646395 :         if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
     648           0 :                 DEBUG(0,("init_smb_request: invalid bcc number %u "
     649             :                         "(wct = %u, size %u)\n",
     650             :                         (unsigned int)req->buflen,
     651             :                         (unsigned int)req->wct,
     652             :                         (unsigned int)req_size));
     653           0 :                 return false;
     654             :         }
     655             : 
     656      646395 :         req->outbuf = NULL;
     657      646395 :         return true;
     658             : }
     659             : 
     660             : static void process_smb(struct smbXsrv_connection *xconn,
     661             :                         uint8_t *inbuf, size_t nread, size_t unread_bytes,
     662             :                         uint32_t seqnum, bool encrypted,
     663             :                         struct smb_perfcount_data *deferred_pcd);
     664             : 
     665        3978 : static void smbd_deferred_open_timer(struct tevent_context *ev,
     666             :                                      struct tevent_timer *te,
     667             :                                      struct timeval _tval,
     668             :                                      void *private_data)
     669             : {
     670        3978 :         struct pending_message_list *msg = talloc_get_type(private_data,
     671             :                                            struct pending_message_list);
     672        3978 :         struct smbd_server_connection *sconn = msg->sconn;
     673        3978 :         struct smbXsrv_connection *xconn = msg->xconn;
     674        3978 :         TALLOC_CTX *mem_ctx = talloc_tos();
     675        3978 :         uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
     676             :         uint8_t *inbuf;
     677             : 
     678        3978 :         inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
     679             :                                          msg->buf.length);
     680        3978 :         if (inbuf == NULL) {
     681           0 :                 exit_server("smbd_deferred_open_timer: talloc failed\n");
     682             :                 return;
     683             :         }
     684             : 
     685             :         /* We leave this message on the queue so the open code can
     686             :            know this is a retry. */
     687        3978 :         DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
     688             :                 (unsigned long long)mid ));
     689             : 
     690             :         /* Mark the message as processed so this is not
     691             :          * re-processed in error. */
     692        3978 :         msg->processed = true;
     693             : 
     694        7956 :         process_smb(xconn, inbuf,
     695             :                     msg->buf.length, 0,
     696        3978 :                     msg->seqnum, msg->encrypted, &msg->pcd);
     697             : 
     698             :         /* If it's still there and was processed, remove it. */
     699        3995 :         msg = get_deferred_open_message_smb(sconn, mid);
     700        3978 :         if (msg && msg->processed) {
     701          32 :                 remove_deferred_open_message_smb(xconn, mid);
     702             :         }
     703        3978 : }
     704             : 
     705             : /****************************************************************************
     706             :  Function to push a message onto the tail of a linked list of smb messages ready
     707             :  for processing.
     708             : ****************************************************************************/
     709             : 
     710        4062 : static bool push_queued_message(struct smb_request *req,
     711             :                                 struct timeval request_time,
     712             :                                 struct timeval end_time,
     713             :                                 struct deferred_open_record *open_rec)
     714             : {
     715        4062 :         int msg_len = smb_len(req->inbuf) + 4;
     716             :         struct pending_message_list *msg;
     717             : 
     718        4062 :         msg = talloc_zero(NULL, struct pending_message_list);
     719             : 
     720        4062 :         if(msg == NULL) {
     721           0 :                 DEBUG(0,("push_message: malloc fail (1)\n"));
     722           0 :                 return False;
     723             :         }
     724        4062 :         msg->sconn = req->sconn;
     725        4062 :         msg->xconn = req->xconn;
     726             : 
     727        4062 :         msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
     728        4062 :         if(msg->buf.data == NULL) {
     729           0 :                 DEBUG(0,("push_message: malloc fail (2)\n"));
     730           0 :                 TALLOC_FREE(msg);
     731           0 :                 return False;
     732             :         }
     733             : 
     734        4062 :         msg->request_time = request_time;
     735        4062 :         msg->seqnum = req->seqnum;
     736        4062 :         msg->encrypted = req->encrypted;
     737        4062 :         msg->processed = false;
     738        4062 :         SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
     739             : 
     740        4062 :         if (open_rec) {
     741        4062 :                 msg->open_rec = talloc_move(msg, &open_rec);
     742             :         }
     743             : 
     744             : #if 0
     745             :         msg->te = tevent_add_timer(msg->sconn->ev_ctx,
     746             :                                    msg,
     747             :                                    end_time,
     748             :                                    smbd_deferred_open_timer,
     749             :                                    msg);
     750             :         if (!msg->te) {
     751             :                 DEBUG(0,("push_message: event_add_timed failed\n"));
     752             :                 TALLOC_FREE(msg);
     753             :                 return false;
     754             :         }
     755             : #endif
     756             : 
     757        4062 :         DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
     758             : 
     759        4062 :         DEBUG(10,("push_message: pushed message length %u on "
     760             :                   "deferred_open_queue\n", (unsigned int)msg_len));
     761             : 
     762        4045 :         return True;
     763             : }
     764             : 
     765             : /****************************************************************************
     766             :  Function to delete a sharing violation open message by mid.
     767             : ****************************************************************************/
     768             : 
     769        4360 : void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
     770             :                                       uint64_t mid)
     771             : {
     772        4360 :         struct smbd_server_connection *sconn = xconn->client->sconn;
     773             :         struct pending_message_list *pml;
     774             : 
     775        4360 :         if (sconn->using_smb2) {
     776         382 :                 remove_deferred_open_message_smb2(xconn, mid);
     777         382 :                 return;
     778             :         }
     779             : 
     780        3978 :         for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
     781        3978 :                 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
     782        3978 :                         DEBUG(10,("remove_deferred_open_message_smb: "
     783             :                                   "deleting mid %llu len %u\n",
     784             :                                   (unsigned long long)mid,
     785             :                                   (unsigned int)pml->buf.length ));
     786        3978 :                         DLIST_REMOVE(sconn->deferred_open_queue, pml);
     787        3978 :                         TALLOC_FREE(pml);
     788        3961 :                         return;
     789             :                 }
     790             :         }
     791             : }
     792             : 
     793             : /****************************************************************************
     794             :  Move a sharing violation open retry message to the front of the list and
     795             :  schedule it for immediate processing.
     796             : ****************************************************************************/
     797             : 
     798        4376 : bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
     799             :                                         uint64_t mid)
     800             : {
     801        4376 :         struct smbd_server_connection *sconn = xconn->client->sconn;
     802             :         struct pending_message_list *pml;
     803        4376 :         int i = 0;
     804             : 
     805        4376 :         if (sconn->using_smb2) {
     806         398 :                 return schedule_deferred_open_message_smb2(xconn, mid);
     807             :         }
     808             : 
     809        3978 :         for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
     810        3978 :                 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
     811             : 
     812        3978 :                 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
     813             :                         "msg_mid = %llu\n",
     814             :                         i++,
     815             :                         (unsigned long long)msg_mid ));
     816             : 
     817        3978 :                 if (mid == msg_mid) {
     818             :                         struct tevent_timer *te;
     819             : 
     820        3978 :                         if (pml->processed) {
     821             :                                 /* A processed message should not be
     822             :                                  * rescheduled. */
     823           0 :                                 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
     824             :                                         "message mid %llu was already processed\n",
     825             :                                         (unsigned long long)msg_mid ));
     826           0 :                                 continue;
     827             :                         }
     828             : 
     829        3978 :                         DEBUG(10,("schedule_deferred_open_message_smb: "
     830             :                                 "scheduling mid %llu\n",
     831             :                                 (unsigned long long)mid ));
     832             : 
     833             :                         /*
     834             :                          * smbd_deferred_open_timer() calls
     835             :                          * process_smb() to redispatch the request
     836             :                          * including the required impersonation.
     837             :                          *
     838             :                          * So we can just use the raw tevent_context.
     839             :                          */
     840        3978 :                         te = tevent_add_timer(xconn->client->raw_ev_ctx,
     841             :                                               pml,
     842             :                                               timeval_zero(),
     843             :                                               smbd_deferred_open_timer,
     844             :                                               pml);
     845        3978 :                         if (!te) {
     846           0 :                                 DEBUG(10,("schedule_deferred_open_message_smb: "
     847             :                                         "event_add_timed() failed, "
     848             :                                         "skipping mid %llu\n",
     849             :                                         (unsigned long long)msg_mid ));
     850             :                         }
     851             : 
     852        3978 :                         TALLOC_FREE(pml->te);
     853        3978 :                         pml->te = te;
     854        3978 :                         DLIST_PROMOTE(sconn->deferred_open_queue, pml);
     855        3961 :                         return true;
     856             :                 }
     857             :         }
     858             : 
     859           0 :         DEBUG(10,("schedule_deferred_open_message_smb: failed to "
     860             :                 "find message mid %llu\n",
     861             :                 (unsigned long long)mid ));
     862             : 
     863           0 :         return false;
     864             : }
     865             : 
     866             : /****************************************************************************
     867             :  Return true if this mid is on the deferred queue and was not yet processed.
     868             : ****************************************************************************/
     869             : 
     870      142448 : bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
     871             : {
     872      142448 :         struct smbd_server_connection *sconn = xconn->client->sconn;
     873             :         struct pending_message_list *pml;
     874             : 
     875      142448 :         if (sconn->using_smb2) {
     876      101684 :                 return open_was_deferred_smb2(xconn, mid);
     877             :         }
     878             : 
     879       40836 :         for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
     880         193 :                 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
     881         121 :                         return True;
     882             :                 }
     883             :         }
     884       35859 :         return False;
     885             : }
     886             : 
     887             : /****************************************************************************
     888             :  Return the message queued by this mid.
     889             : ****************************************************************************/
     890             : 
     891      156293 : static struct pending_message_list *get_deferred_open_message_smb(
     892             :         struct smbd_server_connection *sconn, uint64_t mid)
     893             : {
     894             :         struct pending_message_list *pml;
     895             : 
     896      158344 :         for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
     897        8072 :                 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
     898        7958 :                         return pml;
     899             :                 }
     900             :         }
     901      148335 :         return NULL;
     902             : }
     903             : 
     904             : /****************************************************************************
     905             :  Get the state data queued by this mid.
     906             : ****************************************************************************/
     907             : 
     908     1029905 : bool get_deferred_open_message_state(struct smb_request *smbreq,
     909             :                                 struct timeval *p_request_time,
     910             :                                 struct deferred_open_record **open_rec)
     911             : {
     912             :         struct pending_message_list *pml;
     913             : 
     914     1029905 :         if (smbreq->sconn->using_smb2) {
     915      875619 :                 return get_deferred_open_message_state_smb2(smbreq->smb2req,
     916             :                                         p_request_time,
     917             :                                         open_rec);
     918             :         }
     919             : 
     920      156240 :         pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
     921      154286 :         if (!pml) {
     922      144442 :                 return false;
     923             :         }
     924        7924 :         if (p_request_time) {
     925        3978 :                 *p_request_time = pml->request_time;
     926             :         }
     927        7924 :         if (open_rec != NULL) {
     928        3946 :                 *open_rec = pml->open_rec;
     929             :         }
     930        7890 :         return true;
     931             : }
     932             : 
     933             : /****************************************************************************
     934             :  Function to push a deferred open smb message onto a linked list of local smb
     935             :  messages ready for processing.
     936             : ****************************************************************************/
     937             : 
     938        4512 : bool push_deferred_open_message_smb(struct smb_request *req,
     939             :                                     struct timeval timeout,
     940             :                                     struct file_id id,
     941             :                                     struct deferred_open_record *open_rec)
     942             : {
     943             :         struct timeval_buf tvbuf;
     944             :         struct timeval end_time;
     945             : 
     946        4512 :         if (req->smb2req) {
     947         450 :                 return push_deferred_open_message_smb2(req->smb2req,
     948             :                                                 req->request_time,
     949             :                                                 timeout,
     950             :                                                 id,
     951             :                                                 open_rec);
     952             :         }
     953             : 
     954        4062 :         if (req->unread_bytes) {
     955           0 :                 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
     956             :                         "unread_bytes = %u\n",
     957             :                         (unsigned int)req->unread_bytes ));
     958           0 :                 smb_panic("push_deferred_open_message_smb: "
     959             :                         "logic error unread_bytes != 0" );
     960             :         }
     961             : 
     962        4062 :         end_time = timeval_sum(&req->request_time, &timeout);
     963             : 
     964        4062 :         DBG_DEBUG("pushing message len %u mid %"PRIu64" timeout time [%s]\n",
     965             :                   (unsigned int) smb_len(req->inbuf)+4,
     966             :                   req->mid,
     967             :                   timeval_str_buf(&end_time, false, true, &tvbuf));
     968             : 
     969        4062 :         return push_queued_message(req, req->request_time, end_time, open_rec);
     970             : }
     971             : 
     972          13 : static void smbd_sig_term_handler(struct tevent_context *ev,
     973             :                                   struct tevent_signal *se,
     974             :                                   int signum,
     975             :                                   int count,
     976             :                                   void *siginfo,
     977             :                                   void *private_data)
     978             : {
     979          13 :         exit_server_cleanly("termination signal");
     980             : }
     981             : 
     982       27504 : static void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
     983             : {
     984             :         struct tevent_signal *se;
     985             : 
     986       27504 :         se = tevent_add_signal(sconn->ev_ctx,
     987             :                                sconn,
     988             :                                SIGTERM, 0,
     989             :                                smbd_sig_term_handler,
     990             :                                sconn);
     991       27504 :         if (!se) {
     992           0 :                 exit_server("failed to setup SIGTERM handler");
     993             :         }
     994       27504 : }
     995             : 
     996           0 : static void smbd_sig_hup_handler(struct tevent_context *ev,
     997             :                                   struct tevent_signal *se,
     998             :                                   int signum,
     999             :                                   int count,
    1000             :                                   void *siginfo,
    1001             :                                   void *private_data)
    1002             : {
    1003           0 :         struct smbd_server_connection *sconn =
    1004             :                 talloc_get_type_abort(private_data,
    1005             :                 struct smbd_server_connection);
    1006             : 
    1007           0 :         change_to_root_user();
    1008           0 :         DEBUG(1,("Reloading services after SIGHUP\n"));
    1009           0 :         reload_services(sconn, conn_snum_used, false);
    1010           0 : }
    1011             : 
    1012       27504 : static void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
    1013             : {
    1014             :         struct tevent_signal *se;
    1015             : 
    1016       27504 :         se = tevent_add_signal(sconn->ev_ctx,
    1017             :                                sconn,
    1018             :                                SIGHUP, 0,
    1019             :                                smbd_sig_hup_handler,
    1020             :                                sconn);
    1021       27504 :         if (!se) {
    1022           0 :                 exit_server("failed to setup SIGHUP handler");
    1023             :         }
    1024       27504 : }
    1025             : 
    1026         634 : static void smbd_conf_updated(struct messaging_context *msg,
    1027             :                               void *private_data,
    1028             :                               uint32_t msg_type,
    1029             :                               struct server_id server_id,
    1030             :                               DATA_BLOB *data)
    1031             : {
    1032         634 :         struct smbd_server_connection *sconn =
    1033             :                 talloc_get_type_abort(private_data,
    1034             :                 struct smbd_server_connection);
    1035             : 
    1036         634 :         DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
    1037             :                   "updated. Reloading.\n"));
    1038         634 :         change_to_root_user();
    1039         634 :         reload_services(sconn, conn_snum_used, false);
    1040         634 : }
    1041             : 
    1042             : /*
    1043             :  * Only allow 5 outstanding trans requests. We're allocating memory, so
    1044             :  * prevent a DoS.
    1045             :  */
    1046             : 
    1047       50809 : NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
    1048             : {
    1049       50809 :         int count = 0;
    1050       50809 :         for (; list != NULL; list = list->next) {
    1051             : 
    1052           0 :                 if (list->mid == mid) {
    1053           0 :                         return NT_STATUS_INVALID_PARAMETER;
    1054             :                 }
    1055             : 
    1056           0 :                 count += 1;
    1057             :         }
    1058       50809 :         if (count > 5) {
    1059           0 :                 return NT_STATUS_INSUFFICIENT_RESOURCES;
    1060             :         }
    1061             : 
    1062       50809 :         return NT_STATUS_OK;
    1063             : }
    1064             : 
    1065             : /*
    1066             : These flags determine some of the permissions required to do an operation 
    1067             : 
    1068             : Note that I don't set NEED_WRITE on some write operations because they
    1069             : are used by some brain-dead clients when printing, and I don't want to
    1070             : force write permissions on print services.
    1071             : */
    1072             : #define AS_USER (1<<0)
    1073             : #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
    1074             : #define TIME_INIT (1<<2)
    1075             : #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
    1076             : #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
    1077             : #define DO_CHDIR (1<<6)
    1078             : 
    1079             : /* 
    1080             :    define a list of possible SMB messages and their corresponding
    1081             :    functions. Any message that has a NULL function is unimplemented -
    1082             :    please feel free to contribute implementations!
    1083             : */
    1084             : static const struct smb_message_struct {
    1085             :         const char *name;
    1086             :         void (*fn)(struct smb_request *req);
    1087             :         int flags;
    1088             : } smb_messages[256] = {
    1089             : 
    1090             : /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
    1091             : /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
    1092             : /* 0x02 */ { "SMBopen",reply_open,AS_USER },
    1093             : /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
    1094             : /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
    1095             : /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
    1096             : /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
    1097             : /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
    1098             : /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
    1099             : /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
    1100             : /* 0x0a */ { "SMBread",reply_read,AS_USER},
    1101             : /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
    1102             : /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
    1103             : /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
    1104             : /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
    1105             : /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
    1106             : /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
    1107             : /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
    1108             : /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
    1109             : /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
    1110             : /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
    1111             : /* 0x15 */ { NULL, NULL, 0 },
    1112             : /* 0x16 */ { NULL, NULL, 0 },
    1113             : /* 0x17 */ { NULL, NULL, 0 },
    1114             : /* 0x18 */ { NULL, NULL, 0 },
    1115             : /* 0x19 */ { NULL, NULL, 0 },
    1116             : /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
    1117             : /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
    1118             : /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
    1119             : /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
    1120             : /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
    1121             : /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
    1122             : /* 0x20 */ { "SMBwritec", NULL,0},
    1123             : /* 0x21 */ { NULL, NULL, 0 },
    1124             : /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
    1125             : /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
    1126             : /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
    1127             : /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
    1128             : /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
    1129             : /* 0x27 */ { "SMBioctl",reply_ioctl,0},
    1130             : /* 0x28 */ { "SMBioctls", NULL,AS_USER},
    1131             : /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
    1132             : /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
    1133             : /* 0x2b */ { "SMBecho",reply_echo,0},
    1134             : /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
    1135             : /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
    1136             : /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
    1137             : /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
    1138             : /* 0x30 */ { NULL, NULL, 0 },
    1139             : /* 0x31 */ { NULL, NULL, 0 },
    1140             : /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
    1141             : /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
    1142             : /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
    1143             : /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
    1144             : /* 0x36 */ { NULL, NULL, 0 },
    1145             : /* 0x37 */ { NULL, NULL, 0 },
    1146             : /* 0x38 */ { NULL, NULL, 0 },
    1147             : /* 0x39 */ { NULL, NULL, 0 },
    1148             : /* 0x3a */ { NULL, NULL, 0 },
    1149             : /* 0x3b */ { NULL, NULL, 0 },
    1150             : /* 0x3c */ { NULL, NULL, 0 },
    1151             : /* 0x3d */ { NULL, NULL, 0 },
    1152             : /* 0x3e */ { NULL, NULL, 0 },
    1153             : /* 0x3f */ { NULL, NULL, 0 },
    1154             : /* 0x40 */ { NULL, NULL, 0 },
    1155             : /* 0x41 */ { NULL, NULL, 0 },
    1156             : /* 0x42 */ { NULL, NULL, 0 },
    1157             : /* 0x43 */ { NULL, NULL, 0 },
    1158             : /* 0x44 */ { NULL, NULL, 0 },
    1159             : /* 0x45 */ { NULL, NULL, 0 },
    1160             : /* 0x46 */ { NULL, NULL, 0 },
    1161             : /* 0x47 */ { NULL, NULL, 0 },
    1162             : /* 0x48 */ { NULL, NULL, 0 },
    1163             : /* 0x49 */ { NULL, NULL, 0 },
    1164             : /* 0x4a */ { NULL, NULL, 0 },
    1165             : /* 0x4b */ { NULL, NULL, 0 },
    1166             : /* 0x4c */ { NULL, NULL, 0 },
    1167             : /* 0x4d */ { NULL, NULL, 0 },
    1168             : /* 0x4e */ { NULL, NULL, 0 },
    1169             : /* 0x4f */ { NULL, NULL, 0 },
    1170             : /* 0x50 */ { NULL, NULL, 0 },
    1171             : /* 0x51 */ { NULL, NULL, 0 },
    1172             : /* 0x52 */ { NULL, NULL, 0 },
    1173             : /* 0x53 */ { NULL, NULL, 0 },
    1174             : /* 0x54 */ { NULL, NULL, 0 },
    1175             : /* 0x55 */ { NULL, NULL, 0 },
    1176             : /* 0x56 */ { NULL, NULL, 0 },
    1177             : /* 0x57 */ { NULL, NULL, 0 },
    1178             : /* 0x58 */ { NULL, NULL, 0 },
    1179             : /* 0x59 */ { NULL, NULL, 0 },
    1180             : /* 0x5a */ { NULL, NULL, 0 },
    1181             : /* 0x5b */ { NULL, NULL, 0 },
    1182             : /* 0x5c */ { NULL, NULL, 0 },
    1183             : /* 0x5d */ { NULL, NULL, 0 },
    1184             : /* 0x5e */ { NULL, NULL, 0 },
    1185             : /* 0x5f */ { NULL, NULL, 0 },
    1186             : /* 0x60 */ { NULL, NULL, 0 },
    1187             : /* 0x61 */ { NULL, NULL, 0 },
    1188             : /* 0x62 */ { NULL, NULL, 0 },
    1189             : /* 0x63 */ { NULL, NULL, 0 },
    1190             : /* 0x64 */ { NULL, NULL, 0 },
    1191             : /* 0x65 */ { NULL, NULL, 0 },
    1192             : /* 0x66 */ { NULL, NULL, 0 },
    1193             : /* 0x67 */ { NULL, NULL, 0 },
    1194             : /* 0x68 */ { NULL, NULL, 0 },
    1195             : /* 0x69 */ { NULL, NULL, 0 },
    1196             : /* 0x6a */ { NULL, NULL, 0 },
    1197             : /* 0x6b */ { NULL, NULL, 0 },
    1198             : /* 0x6c */ { NULL, NULL, 0 },
    1199             : /* 0x6d */ { NULL, NULL, 0 },
    1200             : /* 0x6e */ { NULL, NULL, 0 },
    1201             : /* 0x6f */ { NULL, NULL, 0 },
    1202             : /* 0x70 */ { "SMBtcon",reply_tcon,0},
    1203             : /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
    1204             : /* 0x72 */ { "SMBnegprot",reply_negprot,0},
    1205             : /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
    1206             : /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
    1207             : /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
    1208             : /* 0x76 */ { NULL, NULL, 0 },
    1209             : /* 0x77 */ { NULL, NULL, 0 },
    1210             : /* 0x78 */ { NULL, NULL, 0 },
    1211             : /* 0x79 */ { NULL, NULL, 0 },
    1212             : /* 0x7a */ { NULL, NULL, 0 },
    1213             : /* 0x7b */ { NULL, NULL, 0 },
    1214             : /* 0x7c */ { NULL, NULL, 0 },
    1215             : /* 0x7d */ { NULL, NULL, 0 },
    1216             : /* 0x7e */ { NULL, NULL, 0 },
    1217             : /* 0x7f */ { NULL, NULL, 0 },
    1218             : /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
    1219             : /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
    1220             : /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
    1221             : /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
    1222             : /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
    1223             : /* 0x85 */ { NULL, NULL, 0 },
    1224             : /* 0x86 */ { NULL, NULL, 0 },
    1225             : /* 0x87 */ { NULL, NULL, 0 },
    1226             : /* 0x88 */ { NULL, NULL, 0 },
    1227             : /* 0x89 */ { NULL, NULL, 0 },
    1228             : /* 0x8a */ { NULL, NULL, 0 },
    1229             : /* 0x8b */ { NULL, NULL, 0 },
    1230             : /* 0x8c */ { NULL, NULL, 0 },
    1231             : /* 0x8d */ { NULL, NULL, 0 },
    1232             : /* 0x8e */ { NULL, NULL, 0 },
    1233             : /* 0x8f */ { NULL, NULL, 0 },
    1234             : /* 0x90 */ { NULL, NULL, 0 },
    1235             : /* 0x91 */ { NULL, NULL, 0 },
    1236             : /* 0x92 */ { NULL, NULL, 0 },
    1237             : /* 0x93 */ { NULL, NULL, 0 },
    1238             : /* 0x94 */ { NULL, NULL, 0 },
    1239             : /* 0x95 */ { NULL, NULL, 0 },
    1240             : /* 0x96 */ { NULL, NULL, 0 },
    1241             : /* 0x97 */ { NULL, NULL, 0 },
    1242             : /* 0x98 */ { NULL, NULL, 0 },
    1243             : /* 0x99 */ { NULL, NULL, 0 },
    1244             : /* 0x9a */ { NULL, NULL, 0 },
    1245             : /* 0x9b */ { NULL, NULL, 0 },
    1246             : /* 0x9c */ { NULL, NULL, 0 },
    1247             : /* 0x9d */ { NULL, NULL, 0 },
    1248             : /* 0x9e */ { NULL, NULL, 0 },
    1249             : /* 0x9f */ { NULL, NULL, 0 },
    1250             : /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
    1251             : /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
    1252             : /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
    1253             : /* 0xa3 */ { NULL, NULL, 0 },
    1254             : /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
    1255             : /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
    1256             : /* 0xa6 */ { NULL, NULL, 0 },
    1257             : /* 0xa7 */ { NULL, NULL, 0 },
    1258             : /* 0xa8 */ { NULL, NULL, 0 },
    1259             : /* 0xa9 */ { NULL, NULL, 0 },
    1260             : /* 0xaa */ { NULL, NULL, 0 },
    1261             : /* 0xab */ { NULL, NULL, 0 },
    1262             : /* 0xac */ { NULL, NULL, 0 },
    1263             : /* 0xad */ { NULL, NULL, 0 },
    1264             : /* 0xae */ { NULL, NULL, 0 },
    1265             : /* 0xaf */ { NULL, NULL, 0 },
    1266             : /* 0xb0 */ { NULL, NULL, 0 },
    1267             : /* 0xb1 */ { NULL, NULL, 0 },
    1268             : /* 0xb2 */ { NULL, NULL, 0 },
    1269             : /* 0xb3 */ { NULL, NULL, 0 },
    1270             : /* 0xb4 */ { NULL, NULL, 0 },
    1271             : /* 0xb5 */ { NULL, NULL, 0 },
    1272             : /* 0xb6 */ { NULL, NULL, 0 },
    1273             : /* 0xb7 */ { NULL, NULL, 0 },
    1274             : /* 0xb8 */ { NULL, NULL, 0 },
    1275             : /* 0xb9 */ { NULL, NULL, 0 },
    1276             : /* 0xba */ { NULL, NULL, 0 },
    1277             : /* 0xbb */ { NULL, NULL, 0 },
    1278             : /* 0xbc */ { NULL, NULL, 0 },
    1279             : /* 0xbd */ { NULL, NULL, 0 },
    1280             : /* 0xbe */ { NULL, NULL, 0 },
    1281             : /* 0xbf */ { NULL, NULL, 0 },
    1282             : /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
    1283             : /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
    1284             : /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
    1285             : /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
    1286             : /* 0xc4 */ { NULL, NULL, 0 },
    1287             : /* 0xc5 */ { NULL, NULL, 0 },
    1288             : /* 0xc6 */ { NULL, NULL, 0 },
    1289             : /* 0xc7 */ { NULL, NULL, 0 },
    1290             : /* 0xc8 */ { NULL, NULL, 0 },
    1291             : /* 0xc9 */ { NULL, NULL, 0 },
    1292             : /* 0xca */ { NULL, NULL, 0 },
    1293             : /* 0xcb */ { NULL, NULL, 0 },
    1294             : /* 0xcc */ { NULL, NULL, 0 },
    1295             : /* 0xcd */ { NULL, NULL, 0 },
    1296             : /* 0xce */ { NULL, NULL, 0 },
    1297             : /* 0xcf */ { NULL, NULL, 0 },
    1298             : /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
    1299             : /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
    1300             : /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
    1301             : /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
    1302             : /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
    1303             : /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
    1304             : /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
    1305             : /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
    1306             : /* 0xd8 */ { NULL, NULL, 0 },
    1307             : /* 0xd9 */ { NULL, NULL, 0 },
    1308             : /* 0xda */ { NULL, NULL, 0 },
    1309             : /* 0xdb */ { NULL, NULL, 0 },
    1310             : /* 0xdc */ { NULL, NULL, 0 },
    1311             : /* 0xdd */ { NULL, NULL, 0 },
    1312             : /* 0xde */ { NULL, NULL, 0 },
    1313             : /* 0xdf */ { NULL, NULL, 0 },
    1314             : /* 0xe0 */ { NULL, NULL, 0 },
    1315             : /* 0xe1 */ { NULL, NULL, 0 },
    1316             : /* 0xe2 */ { NULL, NULL, 0 },
    1317             : /* 0xe3 */ { NULL, NULL, 0 },
    1318             : /* 0xe4 */ { NULL, NULL, 0 },
    1319             : /* 0xe5 */ { NULL, NULL, 0 },
    1320             : /* 0xe6 */ { NULL, NULL, 0 },
    1321             : /* 0xe7 */ { NULL, NULL, 0 },
    1322             : /* 0xe8 */ { NULL, NULL, 0 },
    1323             : /* 0xe9 */ { NULL, NULL, 0 },
    1324             : /* 0xea */ { NULL, NULL, 0 },
    1325             : /* 0xeb */ { NULL, NULL, 0 },
    1326             : /* 0xec */ { NULL, NULL, 0 },
    1327             : /* 0xed */ { NULL, NULL, 0 },
    1328             : /* 0xee */ { NULL, NULL, 0 },
    1329             : /* 0xef */ { NULL, NULL, 0 },
    1330             : /* 0xf0 */ { NULL, NULL, 0 },
    1331             : /* 0xf1 */ { NULL, NULL, 0 },
    1332             : /* 0xf2 */ { NULL, NULL, 0 },
    1333             : /* 0xf3 */ { NULL, NULL, 0 },
    1334             : /* 0xf4 */ { NULL, NULL, 0 },
    1335             : /* 0xf5 */ { NULL, NULL, 0 },
    1336             : /* 0xf6 */ { NULL, NULL, 0 },
    1337             : /* 0xf7 */ { NULL, NULL, 0 },
    1338             : /* 0xf8 */ { NULL, NULL, 0 },
    1339             : /* 0xf9 */ { NULL, NULL, 0 },
    1340             : /* 0xfa */ { NULL, NULL, 0 },
    1341             : /* 0xfb */ { NULL, NULL, 0 },
    1342             : /* 0xfc */ { NULL, NULL, 0 },
    1343             : /* 0xfd */ { NULL, NULL, 0 },
    1344             : /* 0xfe */ { NULL, NULL, 0 },
    1345             : /* 0xff */ { NULL, NULL, 0 }
    1346             : 
    1347             : };
    1348             : 
    1349             : /*******************************************************************
    1350             :  allocate and initialize a reply packet
    1351             : ********************************************************************/
    1352             : 
    1353      488202 : static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
    1354             :                           const uint8_t *inbuf, char **outbuf,
    1355             :                           uint8_t num_words, uint32_t num_bytes)
    1356             : {
    1357      488202 :         size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
    1358             : 
    1359             :         /*
    1360             :          * Protect against integer wrap.
    1361             :          * The SMB layer reply can be up to 0xFFFFFF bytes.
    1362             :          */
    1363      488202 :         if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
    1364             :                 char *msg;
    1365           0 :                 if (asprintf(&msg, "num_bytes too large: %u",
    1366             :                              (unsigned)num_bytes) == -1) {
    1367           0 :                         msg = discard_const_p(char, "num_bytes too large");
    1368             :                 }
    1369           0 :                 smb_panic(msg);
    1370             :         }
    1371             : 
    1372             :         /*
    1373             :          * Here we include the NBT header for now.
    1374             :          */
    1375      488202 :         *outbuf = talloc_array(mem_ctx, char,
    1376             :                                NBT_HDR_SIZE + smb_len);
    1377      488202 :         if (*outbuf == NULL) {
    1378           0 :                 return false;
    1379             :         }
    1380             : 
    1381      488202 :         construct_reply_common(req->cmd, inbuf, *outbuf);
    1382      488202 :         srv_set_message(*outbuf, num_words, num_bytes, false);
    1383             :         /*
    1384             :          * Zero out the word area, the caller has to take care of the bcc area
    1385             :          * himself
    1386             :          */
    1387      488202 :         if (num_words != 0) {
    1388      106273 :                 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
    1389             :         }
    1390             : 
    1391      480428 :         return true;
    1392             : }
    1393             : 
    1394      488202 : void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
    1395             : {
    1396             :         char *outbuf;
    1397      488202 :         if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
    1398             :                            num_bytes)) {
    1399           0 :                 smb_panic("could not allocate output buffer\n");
    1400             :         }
    1401      488202 :         req->outbuf = (uint8_t *)outbuf;
    1402      488202 : }
    1403             : 
    1404             : 
    1405             : /*******************************************************************
    1406             :  Dump a packet to a file.
    1407             : ********************************************************************/
    1408             : 
    1409      646362 : static void smb_dump(const char *name, int type, const char *data)
    1410             : {
    1411             :         size_t len;
    1412             :         int fd, i;
    1413      646362 :         char *fname = NULL;
    1414      646362 :         if (DEBUGLEVEL < 50) {
    1415      638135 :                 return;
    1416             :         }
    1417             : 
    1418           0 :         len = smb_len_tcp(data)+4;
    1419           0 :         for (i=1;i<100;i++) {
    1420           0 :                 fname = talloc_asprintf(talloc_tos(),
    1421             :                                 "/tmp/%s.%d.%s",
    1422             :                                 name,
    1423             :                                 i,
    1424             :                                 type ? "req" : "resp");
    1425           0 :                 if (fname == NULL) {
    1426           0 :                         return;
    1427             :                 }
    1428           0 :                 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
    1429           0 :                 if (fd != -1 || errno != EEXIST) break;
    1430           0 :                 TALLOC_FREE(fname);
    1431             :         }
    1432           0 :         if (fd != -1) {
    1433           0 :                 ssize_t ret = write(fd, data, len);
    1434           0 :                 if (ret != len)
    1435           0 :                         DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
    1436           0 :                 close(fd);
    1437           0 :                 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
    1438             :         }
    1439           0 :         TALLOC_FREE(fname);
    1440             : }
    1441             : 
    1442      620784 : static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
    1443             :                                         struct smb_request *req,
    1444             :                                         uint8_t type,
    1445             :                                         bool *update_session_globalp,
    1446             :                                         bool *update_tcon_globalp)
    1447             : {
    1448      620784 :         connection_struct *conn = req->conn;
    1449      620784 :         struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
    1450      620784 :         uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
    1451      620784 :         uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
    1452      620784 :         bool update_session = false;
    1453      620784 :         bool update_tcon = false;
    1454             : 
    1455      620784 :         if (req->encrypted) {
    1456      184633 :                 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
    1457             :         }
    1458             : 
    1459      620784 :         if (srv_is_signing_active(req->xconn)) {
    1460       62658 :                 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
    1461      550563 :         } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
    1462             :                 /*
    1463             :                  * echo can be unsigned. Sesssion setup except final
    1464             :                  * session setup response too
    1465             :                  */
    1466        4453 :                 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
    1467             :         }
    1468             : 
    1469     1241568 :         update_session |= smbXsrv_set_crypto_flag(
    1470      620784 :                 &session->global->encryption_flags, encrypt_flag);
    1471     1241568 :         update_session |= smbXsrv_set_crypto_flag(
    1472      620784 :                 &session->global->signing_flags, sign_flag);
    1473             : 
    1474      620784 :         if (tcon) {
    1475     1206433 :                 update_tcon |= smbXsrv_set_crypto_flag(
    1476      606863 :                         &tcon->global->encryption_flags, encrypt_flag);
    1477     1206433 :                 update_tcon |= smbXsrv_set_crypto_flag(
    1478      606863 :                         &tcon->global->signing_flags, sign_flag);
    1479             :         }
    1480             : 
    1481      620784 :         if (update_session) {
    1482        9627 :                 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
    1483             :         }
    1484             : 
    1485      620784 :         *update_session_globalp = update_session;
    1486      620784 :         *update_tcon_globalp = update_tcon;
    1487      620784 :         return;
    1488             : }
    1489             : 
    1490             : /****************************************************************************
    1491             :  Prepare everything for calling the actual request function, and potentially
    1492             :  call the request function via the "new" interface.
    1493             : 
    1494             :  Return False if the "legacy" function needs to be called, everything is
    1495             :  prepared.
    1496             : 
    1497             :  Return True if we're done.
    1498             : 
    1499             :  I know this API sucks, but it is the one with the least code change I could
    1500             :  find.
    1501             : ****************************************************************************/
    1502             : 
    1503      646364 : static connection_struct *switch_message(uint8_t type, struct smb_request *req)
    1504             : {
    1505      646364 :         const struct loadparm_substitution *lp_sub =
    1506             :                 loadparm_s3_global_substitution();
    1507             :         int flags;
    1508             :         uint64_t session_tag;
    1509      646364 :         connection_struct *conn = NULL;
    1510      646364 :         struct smbXsrv_connection *xconn = req->xconn;
    1511      646364 :         NTTIME now = timeval_to_nttime(&req->request_time);
    1512      646364 :         struct smbXsrv_session *session = NULL;
    1513             :         NTSTATUS status;
    1514             : 
    1515      646364 :         errno = 0;
    1516             : 
    1517      646364 :         if (!xconn->smb1.negprot.done) {
    1518       20185 :                 switch (type) {
    1519             :                         /*
    1520             :                          * Without a negprot the request must
    1521             :                          * either be a negprot, or one of the
    1522             :                          * evil old SMB mailslot messaging types.
    1523             :                          */
    1524       19653 :                         case SMBnegprot:
    1525             :                         case SMBsendstrt:
    1526             :                         case SMBsendend:
    1527             :                         case SMBsendtxt:
    1528       19653 :                                 break;
    1529           2 :                         default:
    1530           2 :                                 exit_server_cleanly("The first request "
    1531             :                                         "should be a negprot");
    1532             :                 }
    1533      626179 :         }
    1534             : 
    1535      646362 :         if (smb_messages[type].fn == NULL) {
    1536           0 :                 DEBUG(0,("Unknown message type %d!\n",type));
    1537           0 :                 smb_dump("Unknown", 1, (const char *)req->inbuf);
    1538           0 :                 reply_unknown_new(req, type);
    1539           0 :                 return NULL;
    1540             :         }
    1541             : 
    1542      646362 :         flags = smb_messages[type].flags;
    1543             : 
    1544             :         /* In share mode security we must ignore the vuid. */
    1545      646362 :         session_tag = req->vuid;
    1546      646362 :         conn = req->conn;
    1547             : 
    1548      646362 :         DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
    1549             :                  (int)getpid(), (unsigned long)conn));
    1550             : 
    1551      646362 :         smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
    1552             : 
    1553             :         /* Ensure this value is replaced in the incoming packet. */
    1554      646362 :         SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
    1555             : 
    1556             :         /*
    1557             :          * Ensure the correct username is in current_user_info.  This is a
    1558             :          * really ugly bugfix for problems with multiple session_setup_and_X's
    1559             :          * being done and allowing %U and %G substitutions to work correctly.
    1560             :          * There is a reason this code is done here, don't move it unless you
    1561             :          * know what you're doing... :-).
    1562             :          * JRA.
    1563             :          */
    1564             : 
    1565             :         /*
    1566             :          * lookup an existing session
    1567             :          *
    1568             :          * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
    1569             :          * here, the main check is still in change_to_user()
    1570             :          */
    1571      646362 :         status = smb1srv_session_lookup(xconn,
    1572             :                                         session_tag,
    1573             :                                         now,
    1574             :                                         &session);
    1575      646362 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
    1576           8 :                 switch (type) {
    1577           4 :                 case SMBsesssetupX:
    1578           4 :                         status = NT_STATUS_OK;
    1579           4 :                         break;
    1580           4 :                 default:
    1581           4 :                         DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
    1582             :                                  (unsigned long long)session_tag,
    1583             :                                  (unsigned long long)req->mid));
    1584           4 :                         reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
    1585           4 :                         return conn;
    1586             :                 }
    1587      646354 :         }
    1588             : 
    1589     1267169 :         if (session != NULL &&
    1590     1237128 :             session->global->auth_session_info != NULL &&
    1591      616317 :             !(flags & AS_USER))
    1592             :         {
    1593             :                 /*
    1594             :                  * change_to_user() implies set_current_user_info()
    1595             :                  * and chdir_connect_service().
    1596             :                  *
    1597             :                  * So we only call set_current_user_info if
    1598             :                  * we don't have AS_USER specified.
    1599             :                  */
    1600      833861 :                 set_current_user_info(
    1601      277763 :                         session->global->auth_session_info->unix_info->sanitized_username,
    1602      278049 :                         session->global->auth_session_info->unix_info->unix_name,
    1603      278049 :                         session->global->auth_session_info->info->domain_name);
    1604             :         }
    1605             : 
    1606             :         /* Does this call need to be run as the connected user? */
    1607      646358 :         if (flags & AS_USER) {
    1608             : 
    1609             :                 /* Does this call need a valid tree connection? */
    1610      338297 :                 if (!conn) {
    1611             :                         /*
    1612             :                          * Amazingly, the error code depends on the command
    1613             :                          * (from Samba4).
    1614             :                          */
    1615          21 :                         if (type == SMBntcreateX) {
    1616           0 :                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
    1617             :                         } else {
    1618          21 :                                 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
    1619             :                         }
    1620          20 :                         return NULL;
    1621             :                 }
    1622             : 
    1623      338276 :                 set_current_case_sensitive(conn, SVAL(req->inbuf,smb_flg));
    1624             : 
    1625             :                 /*
    1626             :                  * change_to_user() implies set_current_user_info()
    1627             :                  * and chdir_connect_service().
    1628             :                  */
    1629      338276 :                 if (!change_to_user_and_service(conn,session_tag)) {
    1630          17 :                         DEBUG(0, ("Error: Could not change to user. Removing "
    1631             :                                 "deferred open, mid=%llu.\n",
    1632             :                                 (unsigned long long)req->mid));
    1633          17 :                         reply_force_doserror(req, ERRSRV, ERRbaduid);
    1634          17 :                         return conn;
    1635             :                 }
    1636             : 
    1637             :                 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
    1638             : 
    1639             :                 /* Does it need write permission? */
    1640      338259 :                 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
    1641           4 :                         reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
    1642           4 :                         return conn;
    1643             :                 }
    1644             : 
    1645             :                 /* IPC services are limited */
    1646      338255 :                 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
    1647           0 :                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    1648           0 :                         return conn;
    1649             :                 }
    1650      308061 :         } else if (flags & AS_GUEST) {
    1651             :                 /*
    1652             :                  * Does this protocol need to be run as guest? (Only archane
    1653             :                  * messenger service requests have this...)
    1654             :                  */
    1655          84 :                 if (!change_to_guest()) {
    1656           0 :                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    1657           0 :                         return conn;
    1658             :                 }
    1659             :         } else {
    1660             :                 /* This call needs to be run as root */
    1661      307977 :                 change_to_root_user();
    1662             :         }
    1663             : 
    1664             :         /* load service specific parameters */
    1665      646316 :         if (conn) {
    1666      606883 :                 if (req->encrypted) {
    1667      184439 :                         conn->encrypted_tid = true;
    1668             :                         /* encrypted required from now on. */
    1669      184439 :                         conn->encrypt_level = SMB_SIGNING_REQUIRED;
    1670      422444 :                 } else if (ENCRYPTION_REQUIRED(conn)) {
    1671          14 :                         if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
    1672          14 :                                 DEBUG(1,("service[%s] requires encryption"
    1673             :                                         "%s ACCESS_DENIED. mid=%llu\n",
    1674             :                                         lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
    1675             :                                         smb_fn_name(type),
    1676             :                                         (unsigned long long)req->mid));
    1677          14 :                                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    1678          14 :                                 return conn;
    1679             :                         }
    1680             :                 }
    1681             : 
    1682      606869 :                 if (flags & DO_CHDIR) {
    1683             :                         bool ok;
    1684             : 
    1685        5464 :                         ok = chdir_current_service(conn);
    1686        5464 :                         if (!ok) {
    1687           0 :                                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    1688           0 :                                 return conn;
    1689             :                         }
    1690             :                 }
    1691      606869 :                 conn->num_smb_operations++;
    1692             :         }
    1693             : 
    1694             :         /*
    1695             :          * Update encryption and signing state tracking flags that are
    1696             :          * used by smbstatus to display signing and encryption status.
    1697             :          */
    1698      646302 :         if (session != NULL) {
    1699      620784 :                 bool update_session_global = false;
    1700      620784 :                 bool update_tcon_global = false;
    1701             : 
    1702      620784 :                 req->session = session;
    1703             : 
    1704      620784 :                 smb1srv_update_crypto_flags(session, req, type,
    1705             :                                             &update_session_global,
    1706             :                                             &update_tcon_global);
    1707             : 
    1708      620784 :                 if (update_session_global) {
    1709        9627 :                         status = smbXsrv_session_update(session);
    1710        9627 :                         if (!NT_STATUS_IS_OK(status)) {
    1711           0 :                                 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
    1712           0 :                                 return conn;
    1713             :                         }
    1714             :                 }
    1715             : 
    1716      620784 :                 if (update_tcon_global) {
    1717        7626 :                         status = smbXsrv_tcon_update(req->conn->tcon);
    1718        7626 :                         if (!NT_STATUS_IS_OK(status)) {
    1719           0 :                                 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
    1720           0 :                                 return conn;
    1721             :                         }
    1722             :                 }
    1723             :         }
    1724             : 
    1725      646302 :         smb_messages[type].fn(req);
    1726      645858 :         return req->conn;
    1727             : }
    1728             : 
    1729             : /****************************************************************************
    1730             :  Construct a reply to the incoming packet.
    1731             : ****************************************************************************/
    1732             : 
    1733      646289 : static void construct_reply(struct smbXsrv_connection *xconn,
    1734             :                             char *inbuf, int size, size_t unread_bytes,
    1735             :                             uint32_t seqnum, bool encrypted,
    1736             :                             struct smb_perfcount_data *deferred_pcd)
    1737             : {
    1738      646289 :         struct smbd_server_connection *sconn = xconn->client->sconn;
    1739             :         struct smb_request *req;
    1740             : 
    1741      646289 :         if (!(req = talloc(talloc_tos(), struct smb_request))) {
    1742           0 :                 smb_panic("could not allocate smb_request");
    1743             :         }
    1744             : 
    1745      646289 :         if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
    1746             :                               encrypted, seqnum)) {
    1747           0 :                 exit_server_cleanly("Invalid SMB request");
    1748             :         }
    1749             : 
    1750      646289 :         req->inbuf  = (uint8_t *)talloc_move(req, &inbuf);
    1751             : 
    1752             :         /* we popped this message off the queue - keep original perf data */
    1753      646289 :         if (deferred_pcd)
    1754        3970 :                 req->pcd = *deferred_pcd;
    1755             :         else {
    1756      642319 :                 SMB_PERFCOUNT_START(&req->pcd);
    1757      642319 :                 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
    1758      642319 :                 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
    1759             :         }
    1760             : 
    1761      646289 :         req->conn = switch_message(req->cmd, req);
    1762             : 
    1763      645845 :         if (req->outbuf == NULL) {
    1764             :                 /*
    1765             :                  * Request has suspended itself, will come
    1766             :                  * back here.
    1767             :                  */
    1768      218513 :                 return;
    1769             :         }
    1770      425475 :         if (CVAL(req->outbuf,0) == 0) {
    1771      425475 :                 show_msg((char *)req->outbuf);
    1772             :         }
    1773      425475 :         smb_request_done(req);
    1774             : }
    1775             : 
    1776          45 : static void construct_reply_chain(struct smbXsrv_connection *xconn,
    1777             :                                   char *inbuf, int size, uint32_t seqnum,
    1778             :                                   bool encrypted,
    1779             :                                   struct smb_perfcount_data *deferred_pcd)
    1780             : {
    1781          45 :         struct smb_request **reqs = NULL;
    1782             :         struct smb_request *req;
    1783             :         unsigned num_reqs;
    1784             :         bool ok;
    1785             : 
    1786          45 :         ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
    1787             :                               seqnum, &reqs, &num_reqs);
    1788          45 :         if (!ok) {
    1789             :                 char errbuf[smb_size];
    1790           0 :                 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
    1791             :                              __LINE__, __FILE__);
    1792           0 :                 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
    1793             :                                   NULL)) {
    1794           0 :                         exit_server_cleanly("construct_reply_chain: "
    1795             :                                             "srv_send_smb failed.");
    1796             :                 }
    1797           0 :                 return;
    1798             :         }
    1799             : 
    1800          45 :         req = reqs[0];
    1801          45 :         req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
    1802             : 
    1803          45 :         req->conn = switch_message(req->cmd, req);
    1804             : 
    1805          43 :         if (req->outbuf == NULL) {
    1806             :                 /*
    1807             :                  * Request has suspended itself, will come
    1808             :                  * back here.
    1809             :                  */
    1810          16 :                 return;
    1811             :         }
    1812          27 :         smb_request_done(req);
    1813             : }
    1814             : 
    1815             : /*
    1816             :  * To be called from an async SMB handler that is potentially chained
    1817             :  * when it is finished for shipping.
    1818             :  */
    1819             : 
    1820      432801 : void smb_request_done(struct smb_request *req)
    1821             : {
    1822      432801 :         struct smb_request **reqs = NULL;
    1823             :         struct smb_request *first_req;
    1824             :         size_t i, num_reqs, next_index;
    1825             :         NTSTATUS status;
    1826             : 
    1827      432801 :         if (req->chain == NULL) {
    1828      426274 :                 first_req = req;
    1829      426274 :                 goto shipit;
    1830             :         }
    1831             : 
    1832          27 :         reqs = req->chain;
    1833          27 :         num_reqs = talloc_array_length(reqs);
    1834             : 
    1835          27 :         for (i=0; i<num_reqs; i++) {
    1836          27 :                 if (reqs[i] == req) {
    1837          24 :                         break;
    1838             :                 }
    1839             :         }
    1840          27 :         if (i == num_reqs) {
    1841             :                 /*
    1842             :                  * Invalid chain, should not happen
    1843             :                  */
    1844           0 :                 status = NT_STATUS_INTERNAL_ERROR;
    1845           0 :                 goto error;
    1846             :         }
    1847          27 :         next_index = i+1;
    1848             : 
    1849          84 :         while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
    1850          30 :                 struct smb_request *next = reqs[next_index];
    1851             :                 struct smbXsrv_tcon *tcon;
    1852          30 :                 NTTIME now = timeval_to_nttime(&req->request_time);
    1853             : 
    1854          30 :                 next->vuid = SVAL(req->outbuf, smb_uid);
    1855          30 :                 next->tid  = SVAL(req->outbuf, smb_tid);
    1856          30 :                 status = smb1srv_tcon_lookup(req->xconn, next->tid,
    1857             :                                              now, &tcon);
    1858             : 
    1859          30 :                 if (NT_STATUS_IS_OK(status)) {
    1860          26 :                         next->conn = tcon->compat;
    1861             :                 } else {
    1862           4 :                         next->conn = NULL;
    1863             :                 }
    1864          30 :                 next->chain_fsp = req->chain_fsp;
    1865          30 :                 next->inbuf = req->inbuf;
    1866             : 
    1867          30 :                 req = next;
    1868          30 :                 req->conn = switch_message(req->cmd, req);
    1869             : 
    1870          30 :                 if (req->outbuf == NULL) {
    1871             :                         /*
    1872             :                          * Request has suspended itself, will come
    1873             :                          * back here.
    1874             :                          */
    1875           0 :                         return;
    1876             :                 }
    1877          30 :                 next_index += 1;
    1878             :         }
    1879             : 
    1880          27 :         first_req = reqs[0];
    1881             : 
    1882          57 :         for (i=1; i<next_index; i++) {
    1883             :                 bool ok;
    1884             : 
    1885          30 :                 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
    1886          30 :                 if (!ok) {
    1887           0 :                         status = NT_STATUS_INTERNAL_ERROR;
    1888           0 :                         goto error;
    1889             :                 }
    1890             :         }
    1891             : 
    1892          27 :         SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
    1893          27 :         SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
    1894             : 
    1895             :         /*
    1896             :          * This scary statement intends to set the
    1897             :          * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
    1898             :          * to the value last_req->outbuf carries
    1899             :          */
    1900          27 :         SSVAL(first_req->outbuf, smb_flg2,
    1901             :               (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
    1902             :               |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
    1903             : 
    1904             :         /*
    1905             :          * Transfer the error codes from the subrequest to the main one
    1906             :          */
    1907          27 :         SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
    1908          27 :         SSVAL(first_req->outbuf, smb_err,  SVAL(req->outbuf, smb_err));
    1909             : 
    1910          27 :         _smb_setlen_large(
    1911             :                 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
    1912             : 
    1913      432801 : shipit:
    1914     1724701 :         if (!srv_send_smb(first_req->xconn,
    1915      432801 :                           (char *)first_req->outbuf,
    1916      432801 :                           true, first_req->seqnum+1,
    1917      432801 :                           IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
    1918             :                           &first_req->pcd)) {
    1919          79 :                 exit_server_cleanly("construct_reply_chain: srv_send_smb "
    1920             :                                     "failed.");
    1921             :         }
    1922      432722 :         TALLOC_FREE(req);       /* non-chained case */
    1923      432722 :         TALLOC_FREE(reqs);      /* chained case */
    1924      426219 :         return;
    1925             : 
    1926           0 : error:
    1927             :         {
    1928             :                 char errbuf[smb_size];
    1929           0 :                 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
    1930           0 :                 if (!srv_send_smb(req->xconn, errbuf, true,
    1931           0 :                                   req->seqnum+1, req->encrypted,
    1932             :                                   NULL)) {
    1933           0 :                         exit_server_cleanly("construct_reply_chain: "
    1934             :                                             "srv_send_smb failed.");
    1935             :                 }
    1936             :         }
    1937           0 :         TALLOC_FREE(req);       /* non-chained case */
    1938           0 :         TALLOC_FREE(reqs);      /* chained case */
    1939             : }
    1940             : 
    1941             : /****************************************************************************
    1942             :  Process an smb from the client
    1943             : ****************************************************************************/
    1944      654692 : static void process_smb(struct smbXsrv_connection *xconn,
    1945             :                         uint8_t *inbuf, size_t nread, size_t unread_bytes,
    1946             :                         uint32_t seqnum, bool encrypted,
    1947             :                         struct smb_perfcount_data *deferred_pcd)
    1948             : {
    1949      654692 :         struct smbd_server_connection *sconn = xconn->client->sconn;
    1950      654692 :         int msg_type = CVAL(inbuf,0);
    1951             : 
    1952      654692 :         DO_PROFILE_INC(request);
    1953             : 
    1954      654692 :         DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
    1955             :                     smb_len(inbuf) ) );
    1956      654692 :         DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
    1957             :                   sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
    1958             : 
    1959      654692 :         if (msg_type != NBSSmessage) {
    1960             :                 /*
    1961             :                  * NetBIOS session request, keepalive, etc.
    1962             :                  */
    1963        1095 :                 reply_special(xconn, (char *)inbuf, nread);
    1964        1022 :                 goto done;
    1965             :         }
    1966             : 
    1967      653597 :         if (sconn->using_smb2) {
    1968             :                 /* At this point we're not really using smb2,
    1969             :                  * we make the decision here.. */
    1970       32226 :                 if (smbd_is_smb2_header(inbuf, nread)) {
    1971        7251 :                         const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
    1972        7251 :                         size_t pdulen = nread - NBT_HDR_SIZE;
    1973        7251 :                         NTSTATUS status = smbd_smb2_process_negprot(
    1974             :                                                 xconn,
    1975             :                                                 0,
    1976             :                                                 inpdu,
    1977             :                                                 pdulen);
    1978        7251 :                         if (!NT_STATUS_IS_OK(status)) {
    1979           0 :                                 exit_server_cleanly("SMB2 negprot fail");
    1980             :                         }
    1981        7251 :                         return;
    1982             :                 }
    1983       24975 :                 if (nread >= smb_size && valid_smb_header(inbuf)
    1984       24975 :                                 && CVAL(inbuf, smb_com) != 0x72) {
    1985             :                         /* This is a non-negprot SMB1 packet.
    1986             :                            Disable SMB2 from now on. */
    1987        4872 :                         sconn->using_smb2 = false;
    1988             :                 }
    1989             :         }
    1990             : 
    1991             :         /* Make sure this is an SMB packet. smb_size contains NetBIOS header
    1992             :          * so subtract 4 from it. */
    1993      646346 :         if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
    1994          12 :                 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
    1995             :                          smb_len(inbuf)));
    1996             : 
    1997             :                 /* special magic for immediate exit */
    1998          24 :                 if ((nread == 9) &&
    1999          24 :                     (IVAL(inbuf, 4) == SMB_SUICIDE_PACKET) &&
    2000          12 :                     lp_parm_bool(-1, "smbd", "suicide mode", false)) {
    2001          12 :                         uint8_t exitcode = CVAL(inbuf, 8);
    2002          12 :                         DBG_WARNING("SUICIDE: Exiting immediately with code %d\n",
    2003             :                                     (int)exitcode);
    2004          12 :                         exit(exitcode);
    2005             :                 }
    2006             : 
    2007           0 :                 exit_server_cleanly("Non-SMB packet");
    2008             :         }
    2009             : 
    2010      646334 :         show_msg((char *)inbuf);
    2011             : 
    2012      646334 :         if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
    2013          45 :                 construct_reply_chain(xconn, (char *)inbuf, nread,
    2014             :                                       seqnum, encrypted, deferred_pcd);
    2015             :         } else {
    2016      646289 :                 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
    2017             :                                 seqnum, encrypted, deferred_pcd);
    2018             :         }
    2019             : 
    2020      645809 :         sconn->trans_num++;
    2021             : 
    2022      646831 : done:
    2023      646831 :         sconn->num_requests++;
    2024             : 
    2025             :         /* The timeout_processing function isn't run nearly
    2026             :            often enough to implement 'max log size' without
    2027             :            overrunning the size of the file by many megabytes.
    2028             :            This is especially true if we are running at debug
    2029             :            level 10.  Checking every 50 SMBs is a nice
    2030             :            tradeoff of performance vs log file size overrun. */
    2031             : 
    2032      657891 :         if ((sconn->num_requests % 50) == 0 &&
    2033       11060 :             need_to_check_log_size()) {
    2034           0 :                 change_to_root_user();
    2035           0 :                 check_log_size();
    2036             :         }
    2037             : }
    2038             : 
    2039             : /****************************************************************************
    2040             :  Return a string containing the function name of a SMB command.
    2041             : ****************************************************************************/
    2042             : 
    2043      646362 : const char *smb_fn_name(int type)
    2044             : {
    2045      646362 :         const char *unknown_name = "SMBunknown";
    2046             : 
    2047      646362 :         if (smb_messages[type].name == NULL)
    2048           0 :                 return(unknown_name);
    2049             : 
    2050      646362 :         return(smb_messages[type].name);
    2051             : }
    2052             : 
    2053             : /****************************************************************************
    2054             :  Helper functions for contruct_reply.
    2055             : ****************************************************************************/
    2056             : 
    2057        4789 : void add_to_common_flags2(uint32_t v)
    2058             : {
    2059        4789 :         common_flags2 |= v;
    2060        4789 : }
    2061             : 
    2062           8 : void remove_from_common_flags2(uint32_t v)
    2063             : {
    2064           8 :         common_flags2 &= ~v;
    2065           8 : }
    2066             : 
    2067      630137 : static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
    2068             :                                    char *outbuf)
    2069             : {
    2070      630137 :         uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
    2071      630137 :         uint16_t out_flags2 = common_flags2;
    2072             : 
    2073      630137 :         out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
    2074      630137 :         out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
    2075      630137 :         out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
    2076             : 
    2077      630137 :         srv_set_message(outbuf,0,0,false);
    2078             : 
    2079      630137 :         SCVAL(outbuf, smb_com, cmd);
    2080      630137 :         SIVAL(outbuf,smb_rcls,0);
    2081      630137 :         SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); 
    2082      630137 :         SSVAL(outbuf,smb_flg2, out_flags2);
    2083      638007 :         memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
    2084      638007 :         memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
    2085             : 
    2086      630137 :         SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
    2087      630137 :         SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
    2088      630137 :         SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
    2089      630137 :         SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
    2090      630137 :         SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
    2091      630137 : }
    2092             : 
    2093      141935 : void construct_reply_common_req(struct smb_request *req, char *outbuf)
    2094             : {
    2095      141935 :         construct_reply_common(req->cmd, req->inbuf, outbuf);
    2096      141935 : }
    2097             : 
    2098             : /**
    2099             :  * @brief Find the smb_cmd offset of the last command pushed
    2100             :  * @param[in] buf       The buffer we're building up
    2101             :  * @retval              Where can we put our next andx cmd?
    2102             :  *
    2103             :  * While chaining requests, the "next" request we're looking at needs to put
    2104             :  * its SMB_Command before the data the previous request already built up added
    2105             :  * to the chain. Find the offset to the place where we have to put our cmd.
    2106             :  */
    2107             : 
    2108          30 : static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
    2109             : {
    2110             :         uint8_t cmd;
    2111             :         size_t ofs;
    2112             : 
    2113          30 :         cmd = CVAL(buf, smb_com);
    2114             : 
    2115          30 :         if (!smb1cli_is_andx_req(cmd)) {
    2116           0 :                 return false;
    2117             :         }
    2118             : 
    2119          28 :         ofs = smb_vwv0;
    2120             : 
    2121          66 :         while (CVAL(buf, ofs) != 0xff) {
    2122             : 
    2123           8 :                 if (!smb1cli_is_andx_req(CVAL(buf, ofs))) {
    2124           0 :                         return false;
    2125             :                 }
    2126             : 
    2127             :                 /*
    2128             :                  * ofs is from start of smb header, so add the 4 length
    2129             :                  * bytes. The next cmd is right after the wct field.
    2130             :                  */
    2131           8 :                 ofs = SVAL(buf, ofs+2) + 4 + 1;
    2132             : 
    2133           8 :                 if (ofs+4 >= talloc_get_size(buf)) {
    2134           0 :                         return false;
    2135             :                 }
    2136             :         }
    2137             : 
    2138          30 :         *pofs = ofs;
    2139          30 :         return true;
    2140             : }
    2141             : 
    2142             : /**
    2143             :  * @brief Do the smb chaining at a buffer level
    2144             :  * @param[in] poutbuf           Pointer to the talloc'ed buffer to be modified
    2145             :  * @param[in] andx_buf          Buffer to be appended
    2146             :  */
    2147             : 
    2148          30 : static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
    2149             : {
    2150          30 :         uint8_t smb_command     = CVAL(andx_buf, smb_com);
    2151          30 :         uint8_t wct             = CVAL(andx_buf, smb_wct);
    2152          30 :         const uint16_t *vwv     = (const uint16_t *)(andx_buf + smb_vwv);
    2153          30 :         uint32_t num_bytes      = smb_buflen(andx_buf);
    2154          30 :         const uint8_t *bytes    = (const uint8_t *)smb_buf_const(andx_buf);
    2155             : 
    2156             :         uint8_t *outbuf;
    2157             :         size_t old_size, new_size;
    2158             :         size_t ofs;
    2159          30 :         size_t chain_padding = 0;
    2160             :         size_t andx_cmd_ofs;
    2161             : 
    2162             : 
    2163          30 :         old_size = talloc_get_size(*poutbuf);
    2164             : 
    2165          30 :         if ((old_size % 4) != 0) {
    2166             :                 /*
    2167             :                  * Align the wct field of subsequent requests to a 4-byte
    2168             :                  * boundary
    2169             :                  */
    2170          30 :                 chain_padding = 4 - (old_size % 4);
    2171             :         }
    2172             : 
    2173             :         /*
    2174             :          * After the old request comes the new wct field (1 byte), the vwv's
    2175             :          * and the num_bytes field.
    2176             :          */
    2177             : 
    2178          30 :         new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
    2179          30 :         new_size += num_bytes;
    2180             : 
    2181          30 :         if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
    2182           0 :                 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
    2183             :                           (unsigned)new_size));
    2184           0 :                 return false;
    2185             :         }
    2186             : 
    2187          30 :         outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
    2188          30 :         if (outbuf == NULL) {
    2189           0 :                 DEBUG(0, ("talloc failed\n"));
    2190           0 :                 return false;
    2191             :         }
    2192          30 :         *poutbuf = outbuf;
    2193             : 
    2194          30 :         if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
    2195           0 :                 DEBUG(1, ("invalid command chain\n"));
    2196           0 :                 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
    2197           0 :                 return false;
    2198             :         }
    2199             : 
    2200          30 :         if (chain_padding != 0) {
    2201          32 :                 memset(outbuf + old_size, 0, chain_padding);
    2202          30 :                 old_size += chain_padding;
    2203             :         }
    2204             : 
    2205          30 :         SCVAL(outbuf, andx_cmd_ofs, smb_command);
    2206          30 :         SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
    2207             : 
    2208          30 :         ofs = old_size;
    2209             : 
    2210             :         /*
    2211             :          * Push the chained request:
    2212             :          *
    2213             :          * wct field
    2214             :          */
    2215             : 
    2216          30 :         SCVAL(outbuf, ofs, wct);
    2217          30 :         ofs += 1;
    2218             : 
    2219             :         /*
    2220             :          * vwv array
    2221             :          */
    2222             : 
    2223          32 :         memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
    2224             : 
    2225             :         /*
    2226             :          * HACK ALERT
    2227             :          *
    2228             :          * Read&X has an offset into its data buffer at
    2229             :          * vwv[6]. reply_read_andx has no idea anymore that it's
    2230             :          * running from within a chain, so we have to fix up the
    2231             :          * offset here.
    2232             :          *
    2233             :          * Although it looks disgusting at this place, I want to keep
    2234             :          * it here. The alternative would be to push knowledge about
    2235             :          * the andx chain down into read&x again.
    2236             :          */
    2237             : 
    2238          30 :         if (smb_command == SMBreadX) {
    2239             :                 uint8_t *bytes_addr;
    2240             : 
    2241          10 :                 if (wct < 7) {
    2242             :                         /*
    2243             :                          * Invalid read&x response
    2244             :                          */
    2245           0 :                         return false;
    2246             :                 }
    2247             : 
    2248          10 :                 bytes_addr = outbuf + ofs        /* vwv start */
    2249          10 :                         + sizeof(uint16_t) * wct /* vwv array */
    2250             :                         + sizeof(uint16_t)       /* bcc */
    2251          10 :                         + 1;                     /* padding byte */
    2252             : 
    2253          10 :                 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
    2254             :                       bytes_addr - outbuf - 4);
    2255             :         }
    2256             : 
    2257          30 :         ofs += sizeof(uint16_t) * wct;
    2258             : 
    2259             :         /*
    2260             :          * bcc (byte count)
    2261             :          */
    2262             : 
    2263          30 :         SSVAL(outbuf, ofs, num_bytes);
    2264          30 :         ofs += sizeof(uint16_t);
    2265             : 
    2266             :         /*
    2267             :          * The bytes field
    2268             :          */
    2269             : 
    2270          32 :         memcpy(outbuf + ofs, bytes, num_bytes);
    2271             : 
    2272          30 :         return true;
    2273             : }
    2274             : 
    2275      646334 : bool smb1_is_chain(const uint8_t *buf)
    2276             : {
    2277             :         uint8_t cmd, wct, andx_cmd;
    2278             : 
    2279      646334 :         cmd = CVAL(buf, smb_com);
    2280      646334 :         if (!smb1cli_is_andx_req(cmd)) {
    2281      429661 :                 return false;
    2282             :         }
    2283      209455 :         wct = CVAL(buf, smb_wct);
    2284      209455 :         if (wct < 2) {
    2285           0 :                 return false;
    2286             :         }
    2287      209455 :         andx_cmd = CVAL(buf, smb_vwv);
    2288      209455 :         return (andx_cmd != 0xFF);
    2289             : }
    2290             : 
    2291          45 : bool smb1_walk_chain(const uint8_t *buf,
    2292             :                      bool (*fn)(uint8_t cmd,
    2293             :                                 uint8_t wct, const uint16_t *vwv,
    2294             :                                 uint16_t num_bytes, const uint8_t *bytes,
    2295             :                                 void *private_data),
    2296             :                      void *private_data)
    2297             : {
    2298          45 :         size_t smblen = smb_len(buf);
    2299          45 :         const char *smb_buf = smb_base(buf);
    2300             :         uint8_t cmd, chain_cmd;
    2301             :         uint8_t wct;
    2302             :         const uint16_t *vwv;
    2303             :         uint16_t num_bytes;
    2304             :         const uint8_t *bytes;
    2305             : 
    2306          45 :         cmd = CVAL(buf, smb_com);
    2307          45 :         wct = CVAL(buf, smb_wct);
    2308          45 :         vwv = (const uint16_t *)(buf + smb_vwv);
    2309          45 :         num_bytes = smb_buflen(buf);
    2310          45 :         bytes = (const uint8_t *)smb_buf_const(buf);
    2311             : 
    2312          45 :         if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
    2313           0 :                 return false;
    2314             :         }
    2315             : 
    2316          45 :         if (!smb1cli_is_andx_req(cmd)) {
    2317           0 :                 return true;
    2318             :         }
    2319          45 :         if (wct < 2) {
    2320           0 :                 return false;
    2321             :         }
    2322             : 
    2323          45 :         chain_cmd = CVAL(vwv, 0);
    2324             : 
    2325         133 :         while (chain_cmd != 0xff) {
    2326             :                 uint32_t chain_offset;  /* uint32_t to avoid overflow */
    2327             :                 size_t length_needed;
    2328             :                 ptrdiff_t vwv_offset;
    2329             : 
    2330          61 :                 chain_offset = SVAL(vwv+1, 0);
    2331             : 
    2332             :                 /*
    2333             :                  * Check if the client tries to fool us. The chain
    2334             :                  * offset needs to point beyond the current request in
    2335             :                  * the chain, it needs to strictly grow. Otherwise we
    2336             :                  * might be tricked into an endless loop always
    2337             :                  * processing the same request over and over again. We
    2338             :                  * used to assume that vwv and the byte buffer array
    2339             :                  * in a chain are always attached, but OS/2 the
    2340             :                  * Write&X/Read&X chain puts the Read&X vwv array
    2341             :                  * right behind the Write&X vwv chain. The Write&X bcc
    2342             :                  * array is put behind the Read&X vwv array. So now we
    2343             :                  * check whether the chain offset points strictly
    2344             :                  * behind the previous vwv array. req->buf points
    2345             :                  * right after the vwv array of the previous
    2346             :                  * request. See
    2347             :                  * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
    2348             :                  * more information.
    2349             :                  */
    2350             : 
    2351          61 :                 vwv_offset = ((const char *)vwv - smb_buf);
    2352          61 :                 if (chain_offset <= vwv_offset) {
    2353           0 :                         return false;
    2354             :                 }
    2355             : 
    2356             :                 /*
    2357             :                  * Next check: Make sure the chain offset does not
    2358             :                  * point beyond the overall smb request length.
    2359             :                  */
    2360             : 
    2361          61 :                 length_needed = chain_offset+1; /* wct */
    2362          61 :                 if (length_needed > smblen) {
    2363           0 :                         return false;
    2364             :                 }
    2365             : 
    2366             :                 /*
    2367             :                  * Now comes the pointer magic. Goal here is to set up
    2368             :                  * vwv and buf correctly again. The chain offset (the
    2369             :                  * former vwv[1]) points at the new wct field.
    2370             :                  */
    2371             : 
    2372          61 :                 wct = CVAL(smb_buf, chain_offset);
    2373             : 
    2374          61 :                 if (smb1cli_is_andx_req(chain_cmd) && (wct < 2)) {
    2375           0 :                         return false;
    2376             :                 }
    2377             : 
    2378             :                 /*
    2379             :                  * Next consistency check: Make the new vwv array fits
    2380             :                  * in the overall smb request.
    2381             :                  */
    2382             : 
    2383          61 :                 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
    2384          61 :                 if (length_needed > smblen) {
    2385           0 :                         return false;
    2386             :                 }
    2387          61 :                 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
    2388             : 
    2389             :                 /*
    2390             :                  * Now grab the new byte buffer....
    2391             :                  */
    2392             : 
    2393          61 :                 num_bytes = SVAL(vwv+wct, 0);
    2394             : 
    2395             :                 /*
    2396             :                  * .. and check that it fits.
    2397             :                  */
    2398             : 
    2399          61 :                 length_needed += num_bytes;
    2400          61 :                 if (length_needed > smblen) {
    2401           0 :                         return false;
    2402             :                 }
    2403          61 :                 bytes = (const uint8_t *)(vwv+wct+1);
    2404             : 
    2405          61 :                 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
    2406           0 :                         return false;
    2407             :                 }
    2408             : 
    2409          61 :                 if (!smb1cli_is_andx_req(chain_cmd)) {
    2410          18 :                         return true;
    2411             :                 }
    2412          43 :                 chain_cmd = CVAL(vwv, 0);
    2413             :         }
    2414          24 :         return true;
    2415             : }
    2416             : 
    2417           0 : static bool smb1_chain_length_cb(uint8_t cmd,
    2418             :                                  uint8_t wct, const uint16_t *vwv,
    2419             :                                  uint16_t num_bytes, const uint8_t *bytes,
    2420             :                                  void *private_data)
    2421             : {
    2422           0 :         unsigned *count = (unsigned *)private_data;
    2423           0 :         *count += 1;
    2424           0 :         return true;
    2425             : }
    2426             : 
    2427           0 : unsigned smb1_chain_length(const uint8_t *buf)
    2428             : {
    2429           0 :         unsigned count = 0;
    2430             : 
    2431           0 :         if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
    2432           0 :                 return 0;
    2433             :         }
    2434           0 :         return count;
    2435             : }
    2436             : 
    2437             : struct smb1_parse_chain_state {
    2438             :         TALLOC_CTX *mem_ctx;
    2439             :         const uint8_t *buf;
    2440             :         struct smbd_server_connection *sconn;
    2441             :         struct smbXsrv_connection *xconn;
    2442             :         bool encrypted;
    2443             :         uint32_t seqnum;
    2444             : 
    2445             :         struct smb_request **reqs;
    2446             :         unsigned num_reqs;
    2447             : };
    2448             : 
    2449         106 : static bool smb1_parse_chain_cb(uint8_t cmd,
    2450             :                                 uint8_t wct, const uint16_t *vwv,
    2451             :                                 uint16_t num_bytes, const uint8_t *bytes,
    2452             :                                 void *private_data)
    2453             : {
    2454         106 :         struct smb1_parse_chain_state *state =
    2455             :                 (struct smb1_parse_chain_state *)private_data;
    2456             :         struct smb_request **reqs;
    2457             :         struct smb_request *req;
    2458             :         bool ok;
    2459             : 
    2460         106 :         reqs = talloc_realloc(state->mem_ctx, state->reqs,
    2461             :                               struct smb_request *, state->num_reqs+1);
    2462         106 :         if (reqs == NULL) {
    2463           0 :                 return false;
    2464             :         }
    2465         106 :         state->reqs = reqs;
    2466             : 
    2467         106 :         req = talloc(reqs, struct smb_request);
    2468         106 :         if (req == NULL) {
    2469           0 :                 return false;
    2470             :         }
    2471             : 
    2472         212 :         ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
    2473         106 :                               state->encrypted, state->seqnum);
    2474         106 :         if (!ok) {
    2475           0 :                 return false;
    2476             :         }
    2477         106 :         req->cmd = cmd;
    2478         106 :         req->wct = wct;
    2479         106 :         req->vwv = vwv;
    2480         106 :         req->buflen = num_bytes;
    2481         106 :         req->buf = bytes;
    2482             : 
    2483         106 :         reqs[state->num_reqs] = req;
    2484         106 :         state->num_reqs += 1;
    2485         106 :         return true;
    2486             : }
    2487             : 
    2488          45 : bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
    2489             :                       struct smbXsrv_connection *xconn,
    2490             :                       bool encrypted, uint32_t seqnum,
    2491             :                       struct smb_request ***reqs, unsigned *num_reqs)
    2492             : {
    2493          45 :         struct smbd_server_connection *sconn = NULL;
    2494             :         struct smb1_parse_chain_state state;
    2495             :         unsigned i;
    2496             : 
    2497          45 :         if (xconn != NULL) {
    2498          45 :                 sconn = xconn->client->sconn;
    2499             :         }
    2500             : 
    2501          45 :         state.mem_ctx = mem_ctx;
    2502          45 :         state.buf = buf;
    2503          45 :         state.sconn = sconn;
    2504          45 :         state.xconn = xconn;
    2505          45 :         state.encrypted = encrypted;
    2506          45 :         state.seqnum = seqnum;
    2507          45 :         state.reqs = NULL;
    2508          45 :         state.num_reqs = 0;
    2509             : 
    2510          45 :         if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
    2511           0 :                 TALLOC_FREE(state.reqs);
    2512           0 :                 return false;
    2513             :         }
    2514         148 :         for (i=0; i<state.num_reqs; i++) {
    2515         106 :                 state.reqs[i]->chain = state.reqs;
    2516             :         }
    2517          45 :         *reqs = state.reqs;
    2518          45 :         *num_reqs = state.num_reqs;
    2519          45 :         return true;
    2520             : }
    2521             : 
    2522             : /****************************************************************************
    2523             :  Check if services need reloading.
    2524             : ****************************************************************************/
    2525             : 
    2526         752 : static void check_reload(struct smbd_server_connection *sconn, time_t t)
    2527             : {
    2528             : 
    2529         752 :         if (last_smb_conf_reload_time == 0) {
    2530         122 :                 last_smb_conf_reload_time = t;
    2531             :         }
    2532             : 
    2533         752 :         if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
    2534         180 :                 reload_services(sconn, conn_snum_used, true);
    2535         180 :                 last_smb_conf_reload_time = t;
    2536             :         }
    2537         752 : }
    2538             : 
    2539           0 : static bool fd_is_readable(int fd)
    2540             : {
    2541             :         int ret, revents;
    2542             : 
    2543           0 :         ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
    2544             : 
    2545           0 :         return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
    2546             : 
    2547             : }
    2548             : 
    2549           0 : static void smbd_server_connection_write_handler(
    2550             :         struct smbXsrv_connection *xconn)
    2551             : {
    2552             :         /* TODO: make write nonblocking */
    2553           0 : }
    2554             : 
    2555      655556 : static void smbd_server_connection_read_handler(
    2556             :         struct smbXsrv_connection *xconn, int fd)
    2557             : {
    2558      655556 :         uint8_t *inbuf = NULL;
    2559      655556 :         size_t inbuf_len = 0;
    2560      655556 :         size_t unread_bytes = 0;
    2561      655556 :         bool encrypted = false;
    2562      655556 :         TALLOC_CTX *mem_ctx = talloc_tos();
    2563             :         NTSTATUS status;
    2564             :         uint32_t seqnum;
    2565             : 
    2566      655556 :         bool async_echo = lp_async_smb_echo_handler();
    2567      655556 :         bool from_client = false;
    2568             : 
    2569      655556 :         if (async_echo) {
    2570           0 :                 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
    2571             :                         /*
    2572             :                          * This is the super-ugly hack to prefer the packets
    2573             :                          * forwarded by the echo handler over the ones by the
    2574             :                          * client directly
    2575             :                          */
    2576           0 :                         fd = xconn->smb1.echo_handler.trusted_fd;
    2577             :                 }
    2578             :         }
    2579             : 
    2580      655556 :         from_client = (xconn->transport.sock == fd);
    2581             : 
    2582      655556 :         if (async_echo && from_client) {
    2583           0 :                 smbd_lock_socket(xconn);
    2584             : 
    2585           0 :                 if (!fd_is_readable(fd)) {
    2586           0 :                         DEBUG(10,("the echo listener was faster\n"));
    2587           0 :                         smbd_unlock_socket(xconn);
    2588           0 :                         return;
    2589             :                 }
    2590             :         }
    2591             : 
    2592             :         /* TODO: make this completely nonblocking */
    2593      655556 :         status = receive_smb_talloc(mem_ctx, xconn, fd,
    2594             :                                     (char **)(void *)&inbuf,
    2595             :                                     0, /* timeout */
    2596             :                                     &unread_bytes,
    2597             :                                     &encrypted,
    2598             :                                     &inbuf_len, &seqnum,
    2599      655556 :                                     !from_client /* trusted channel */);
    2600             : 
    2601      655556 :         if (async_echo && from_client) {
    2602           0 :                 smbd_unlock_socket(xconn);
    2603             :         }
    2604             : 
    2605      655556 :         if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
    2606           0 :                 goto process;
    2607             :         }
    2608      655556 :         if (NT_STATUS_IS_ERR(status)) {
    2609        4842 :                 exit_server_cleanly("failed to receive smb request");
    2610             :         }
    2611      650714 :         if (!NT_STATUS_IS_OK(status)) {
    2612           0 :                 return;
    2613             :         }
    2614             : 
    2615      650714 : process:
    2616      650714 :         process_smb(xconn, inbuf, inbuf_len, unread_bytes,
    2617             :                     seqnum, encrypted, NULL);
    2618             : }
    2619             : 
    2620      655556 : static void smbd_server_connection_handler(struct tevent_context *ev,
    2621             :                                            struct tevent_fd *fde,
    2622             :                                            uint16_t flags,
    2623             :                                            void *private_data)
    2624             : {
    2625      655556 :         struct smbXsrv_connection *xconn =
    2626             :                 talloc_get_type_abort(private_data,
    2627             :                 struct smbXsrv_connection);
    2628             : 
    2629      655556 :         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
    2630             :                 /*
    2631             :                  * we're not supposed to do any io
    2632             :                  */
    2633           0 :                 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
    2634           0 :                 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
    2635           0 :                 return;
    2636             :         }
    2637             : 
    2638      655556 :         if (flags & TEVENT_FD_WRITE) {
    2639           0 :                 smbd_server_connection_write_handler(xconn);
    2640           0 :                 return;
    2641             :         }
    2642      655556 :         if (flags & TEVENT_FD_READ) {
    2643      655556 :                 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
    2644      650104 :                 return;
    2645             :         }
    2646             : }
    2647             : 
    2648           0 : static void smbd_server_echo_handler(struct tevent_context *ev,
    2649             :                                      struct tevent_fd *fde,
    2650             :                                      uint16_t flags,
    2651             :                                      void *private_data)
    2652             : {
    2653           0 :         struct smbXsrv_connection *xconn =
    2654             :                 talloc_get_type_abort(private_data,
    2655             :                 struct smbXsrv_connection);
    2656             : 
    2657           0 :         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
    2658             :                 /*
    2659             :                  * we're not supposed to do any io
    2660             :                  */
    2661           0 :                 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
    2662           0 :                 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
    2663           0 :                 return;
    2664             :         }
    2665             : 
    2666           0 :         if (flags & TEVENT_FD_WRITE) {
    2667           0 :                 smbd_server_connection_write_handler(xconn);
    2668           0 :                 return;
    2669             :         }
    2670           0 :         if (flags & TEVENT_FD_READ) {
    2671           0 :                 smbd_server_connection_read_handler(
    2672             :                         xconn, xconn->smb1.echo_handler.trusted_fd);
    2673           0 :                 return;
    2674             :         }
    2675             : }
    2676             : 
    2677             : struct smbd_release_ip_state {
    2678             :         struct smbXsrv_connection *xconn;
    2679             :         struct tevent_immediate *im;
    2680             :         char addr[INET6_ADDRSTRLEN];
    2681             : };
    2682             : 
    2683           0 : static void smbd_release_ip_immediate(struct tevent_context *ctx,
    2684             :                                       struct tevent_immediate *im,
    2685             :                                       void *private_data)
    2686             : {
    2687           0 :         struct smbd_release_ip_state *state =
    2688             :                 talloc_get_type_abort(private_data,
    2689             :                 struct smbd_release_ip_state);
    2690           0 :         struct smbXsrv_connection *xconn = state->xconn;
    2691             : 
    2692           0 :         if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
    2693             :                 /*
    2694             :                  * smbd_server_connection_terminate() already triggered ?
    2695             :                  */
    2696           0 :                 return;
    2697             :         }
    2698             : 
    2699           0 :         smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
    2700             : }
    2701             : 
    2702             : /****************************************************************************
    2703             : received when we should release a specific IP
    2704             : ****************************************************************************/
    2705           0 : static int release_ip(struct tevent_context *ev,
    2706             :                       uint32_t src_vnn, uint32_t dst_vnn,
    2707             :                       uint64_t dst_srvid,
    2708             :                       const uint8_t *msg, size_t msglen,
    2709             :                       void *private_data)
    2710             : {
    2711           0 :         struct smbd_release_ip_state *state =
    2712             :                 talloc_get_type_abort(private_data,
    2713             :                 struct smbd_release_ip_state);
    2714           0 :         struct smbXsrv_connection *xconn = state->xconn;
    2715             :         const char *ip;
    2716           0 :         const char *addr = state->addr;
    2717           0 :         const char *p = addr;
    2718             : 
    2719           0 :         if (msglen == 0) {
    2720           0 :                 return 0;
    2721             :         }
    2722           0 :         if (msg[msglen-1] != '\0') {
    2723           0 :                 return 0;
    2724             :         }
    2725             : 
    2726           0 :         ip = (const char *)msg;
    2727             : 
    2728           0 :         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
    2729             :                 /* avoid recursion */
    2730           0 :                 return 0;
    2731             :         }
    2732             : 
    2733           0 :         if (strncmp("::ffff:", addr, 7) == 0) {
    2734           0 :                 p = addr + 7;
    2735             :         }
    2736             : 
    2737           0 :         DEBUG(10, ("Got release IP message for %s, "
    2738             :                    "our address is %s\n", ip, p));
    2739             : 
    2740           0 :         if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
    2741           0 :                 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
    2742             :                         ip));
    2743             :                 /*
    2744             :                  * With SMB2 we should do a clean disconnect,
    2745             :                  * the previous_session_id in the session setup
    2746             :                  * will cleanup the old session, tcons and opens.
    2747             :                  *
    2748             :                  * A clean disconnect is needed in order to support
    2749             :                  * durable handles.
    2750             :                  *
    2751             :                  * Note: typically this is never triggered
    2752             :                  *       as we got a TCP RST (triggered by ctdb event scripts)
    2753             :                  *       before we get CTDB_SRVID_RELEASE_IP.
    2754             :                  *
    2755             :                  * We used to call _exit(1) here, but as this was mostly never
    2756             :                  * triggered and has implication on our process model,
    2757             :                  * we can just use smbd_server_connection_terminate()
    2758             :                  * (also for SMB1).
    2759             :                  *
    2760             :                  * We don't call smbd_server_connection_terminate() directly
    2761             :                  * as we might be called from within ctdbd_migrate(),
    2762             :                  * we need to defer our action to the next event loop
    2763             :                  */
    2764           0 :                 tevent_schedule_immediate(state->im,
    2765             :                                           xconn->client->raw_ev_ctx,
    2766             :                                           smbd_release_ip_immediate,
    2767             :                                           state);
    2768             : 
    2769             :                 /*
    2770             :                  * Make sure we don't get any io on the connection.
    2771             :                  */
    2772           0 :                 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
    2773           0 :                 return EADDRNOTAVAIL;
    2774             :         }
    2775             : 
    2776           0 :         return 0;
    2777             : }
    2778             : 
    2779           0 : static int match_cluster_movable_ip(uint32_t total_ip_count,
    2780             :                                     const struct sockaddr_storage *ip,
    2781             :                                     bool is_movable_ip,
    2782             :                                     void *private_data)
    2783             : {
    2784           0 :         const struct sockaddr_storage *srv = private_data;
    2785           0 :         struct samba_sockaddr pub_ip = {
    2786             :                 .u = {
    2787             :                         .ss = *ip,
    2788             :                 },
    2789             :         };
    2790           0 :         struct samba_sockaddr srv_ip = {
    2791             :                 .u = {
    2792             :                         .ss = *srv,
    2793             :                 },
    2794             :         };
    2795             : 
    2796           0 :         if (is_movable_ip && sockaddr_equal(&pub_ip.u.sa, &srv_ip.u.sa)) {
    2797           0 :                 return EADDRNOTAVAIL;
    2798             :         }
    2799             : 
    2800           0 :         return 0;
    2801             : }
    2802             : 
    2803           0 : static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
    2804             :                                   struct sockaddr_storage *srv,
    2805             :                                   struct sockaddr_storage *clnt)
    2806             : {
    2807             :         struct smbd_release_ip_state *state;
    2808             :         struct ctdbd_connection *cconn;
    2809             :         int ret;
    2810             : 
    2811           0 :         cconn = messaging_ctdb_connection();
    2812           0 :         if (cconn == NULL) {
    2813           0 :                 return NT_STATUS_NO_MEMORY;
    2814             :         }
    2815             : 
    2816           0 :         state = talloc_zero(xconn, struct smbd_release_ip_state);
    2817           0 :         if (state == NULL) {
    2818           0 :                 return NT_STATUS_NO_MEMORY;
    2819             :         }
    2820           0 :         state->xconn = xconn;
    2821           0 :         state->im = tevent_create_immediate(state);
    2822           0 :         if (state->im == NULL) {
    2823           0 :                 return NT_STATUS_NO_MEMORY;
    2824             :         }
    2825           0 :         if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
    2826           0 :                 return NT_STATUS_NO_MEMORY;
    2827             :         }
    2828             : 
    2829           0 :         if (xconn->client->server_multi_channel_enabled) {
    2830           0 :                 ret = ctdbd_public_ip_foreach(cconn,
    2831             :                                               match_cluster_movable_ip,
    2832             :                                               srv);
    2833           0 :                 if (ret == EADDRNOTAVAIL) {
    2834           0 :                         xconn->has_cluster_movable_ip = true;
    2835           0 :                         DBG_DEBUG("cluster movable IP on %s\n",
    2836             :                                   smbXsrv_connection_dbg(xconn));
    2837           0 :                 } else if (ret != 0) {
    2838           0 :                         DBG_ERR("failed to iterate cluster IPs: %s\n",
    2839             :                                 strerror(ret));
    2840           0 :                         return NT_STATUS_INTERNAL_ERROR;
    2841             :                 }
    2842             :         }
    2843             : 
    2844           0 :         ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
    2845           0 :         if (ret != 0) {
    2846           0 :                 return map_nt_error_from_unix(ret);
    2847             :         }
    2848           0 :         return NT_STATUS_OK;
    2849             : }
    2850             : 
    2851           0 : static void msg_kill_client_ip(struct messaging_context *msg_ctx,
    2852             :                                   void *private_data, uint32_t msg_type,
    2853             :                                   struct server_id server_id, DATA_BLOB *data)
    2854             : {
    2855           0 :         struct smbd_server_connection *sconn = talloc_get_type_abort(
    2856             :                 private_data, struct smbd_server_connection);
    2857           0 :         const char *ip = (char *) data->data;
    2858             :         char *client_ip;
    2859             : 
    2860           0 :         DBG_DEBUG("Got kill request for client IP %s\n", ip);
    2861             : 
    2862           0 :         client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
    2863             :                                                      talloc_tos());
    2864           0 :         if (client_ip == NULL) {
    2865           0 :                 return;
    2866             :         }
    2867             : 
    2868           0 :         if (strequal(ip, client_ip)) {
    2869           0 :                 DBG_WARNING("Got kill client message for %s - "
    2870             :                             "exiting immediately\n", ip);
    2871           0 :                 exit_server_cleanly("Forced disconnect for client");
    2872             :         }
    2873             : 
    2874           0 :         TALLOC_FREE(client_ip);
    2875             : }
    2876             : 
    2877             : /*
    2878             :  * Send keepalive packets to our client
    2879             :  */
    2880          45 : static bool keepalive_fn(const struct timeval *now, void *private_data)
    2881             : {
    2882          45 :         struct smbd_server_connection *sconn = talloc_get_type_abort(
    2883             :                 private_data, struct smbd_server_connection);
    2884          45 :         struct smbXsrv_connection *xconn = NULL;
    2885             :         bool ret;
    2886             : 
    2887          45 :         if (sconn->using_smb2) {
    2888             :                 /* Don't do keepalives on an SMB2 connection. */
    2889          45 :                 return false;
    2890             :         }
    2891             : 
    2892             :         /*
    2893             :          * With SMB1 we only have 1 connection
    2894             :          */
    2895           0 :         xconn = sconn->client->connections;
    2896           0 :         smbd_lock_socket(xconn);
    2897           0 :         ret = send_keepalive(xconn->transport.sock);
    2898           0 :         smbd_unlock_socket(xconn);
    2899             : 
    2900           0 :         if (!ret) {
    2901           0 :                 int saved_errno = errno;
    2902             :                 /*
    2903             :                  * Try and give an error message saying what
    2904             :                  * client failed.
    2905             :                  */
    2906           0 :                 DEBUG(0, ("send_keepalive failed for client %s. "
    2907             :                           "Error %s - exiting\n",
    2908             :                           smbXsrv_connection_dbg(xconn),
    2909             :                           strerror(saved_errno)));
    2910           0 :                 errno = saved_errno;
    2911           0 :                 return False;
    2912             :         }
    2913           0 :         return True;
    2914             : }
    2915             : 
    2916             : /*
    2917             :  * Do the recurring check if we're idle
    2918             :  */
    2919         759 : static bool deadtime_fn(const struct timeval *now, void *private_data)
    2920             : {
    2921         759 :         struct smbd_server_connection *sconn =
    2922             :                 (struct smbd_server_connection *)private_data;
    2923             : 
    2924         759 :         if ((conn_num_open(sconn) == 0)
    2925         754 :             || (conn_idle_all(sconn, now->tv_sec))) {
    2926           7 :                 DEBUG( 2, ( "Closing idle connection\n" ) );
    2927           7 :                 messaging_send(sconn->msg_ctx,
    2928           7 :                                messaging_server_id(sconn->msg_ctx),
    2929             :                                MSG_SHUTDOWN, &data_blob_null);
    2930           7 :                 return False;
    2931             :         }
    2932             : 
    2933         752 :         return True;
    2934             : }
    2935             : 
    2936             : /*
    2937             :  * Do the recurring log file and smb.conf reload checks.
    2938             :  */
    2939             : 
    2940         752 : static bool housekeeping_fn(const struct timeval *now, void *private_data)
    2941             : {
    2942         752 :         struct smbd_server_connection *sconn = talloc_get_type_abort(
    2943             :                 private_data, struct smbd_server_connection);
    2944             : 
    2945         752 :         DEBUG(5, ("housekeeping\n"));
    2946             : 
    2947         752 :         change_to_root_user();
    2948             : 
    2949             :         /* update printer queue caches if necessary */
    2950         752 :         update_monitored_printq_cache(sconn->msg_ctx);
    2951             : 
    2952             :         /* check if we need to reload services */
    2953         752 :         check_reload(sconn, time_mono(NULL));
    2954             : 
    2955             :         /*
    2956             :          * Force a log file check.
    2957             :          */
    2958         752 :         force_check_log_size();
    2959         752 :         check_log_size();
    2960         752 :         return true;
    2961             : }
    2962             : 
    2963             : /*
    2964             :  * Read an smb packet in the echo handler child, giving the parent
    2965             :  * smbd one second to react once the socket becomes readable.
    2966             :  */
    2967             : 
    2968             : struct smbd_echo_read_state {
    2969             :         struct tevent_context *ev;
    2970             :         struct smbXsrv_connection *xconn;
    2971             : 
    2972             :         char *buf;
    2973             :         size_t buflen;
    2974             :         uint32_t seqnum;
    2975             : };
    2976             : 
    2977             : static void smbd_echo_read_readable(struct tevent_req *subreq);
    2978             : static void smbd_echo_read_waited(struct tevent_req *subreq);
    2979             : 
    2980           0 : static struct tevent_req *smbd_echo_read_send(
    2981             :         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
    2982             :         struct smbXsrv_connection *xconn)
    2983             : {
    2984             :         struct tevent_req *req, *subreq;
    2985             :         struct smbd_echo_read_state *state;
    2986             : 
    2987           0 :         req = tevent_req_create(mem_ctx, &state,
    2988             :                                 struct smbd_echo_read_state);
    2989           0 :         if (req == NULL) {
    2990           0 :                 return NULL;
    2991             :         }
    2992           0 :         state->ev = ev;
    2993           0 :         state->xconn = xconn;
    2994             : 
    2995           0 :         subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
    2996           0 :         if (tevent_req_nomem(subreq, req)) {
    2997           0 :                 return tevent_req_post(req, ev);
    2998             :         }
    2999           0 :         tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
    3000           0 :         return req;
    3001             : }
    3002             : 
    3003           0 : static void smbd_echo_read_readable(struct tevent_req *subreq)
    3004             : {
    3005           0 :         struct tevent_req *req = tevent_req_callback_data(
    3006             :                 subreq, struct tevent_req);
    3007           0 :         struct smbd_echo_read_state *state = tevent_req_data(
    3008             :                 req, struct smbd_echo_read_state);
    3009             :         bool ok;
    3010             :         int err;
    3011             : 
    3012           0 :         ok = wait_for_read_recv(subreq, &err);
    3013           0 :         TALLOC_FREE(subreq);
    3014           0 :         if (!ok) {
    3015           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(err));
    3016           0 :                 return;
    3017             :         }
    3018             : 
    3019             :         /*
    3020             :          * Give the parent smbd one second to step in
    3021             :          */
    3022             : 
    3023           0 :         subreq = tevent_wakeup_send(
    3024             :                 state, state->ev, timeval_current_ofs(1, 0));
    3025           0 :         if (tevent_req_nomem(subreq, req)) {
    3026           0 :                 return;
    3027             :         }
    3028           0 :         tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
    3029             : }
    3030             : 
    3031           0 : static void smbd_echo_read_waited(struct tevent_req *subreq)
    3032             : {
    3033           0 :         struct tevent_req *req = tevent_req_callback_data(
    3034             :                 subreq, struct tevent_req);
    3035           0 :         struct smbd_echo_read_state *state = tevent_req_data(
    3036             :                 req, struct smbd_echo_read_state);
    3037           0 :         struct smbXsrv_connection *xconn = state->xconn;
    3038             :         bool ok;
    3039             :         NTSTATUS status;
    3040           0 :         size_t unread = 0;
    3041             :         bool encrypted;
    3042             : 
    3043           0 :         ok = tevent_wakeup_recv(subreq);
    3044           0 :         TALLOC_FREE(subreq);
    3045           0 :         if (!ok) {
    3046           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
    3047           0 :                 return;
    3048             :         }
    3049             : 
    3050           0 :         ok = smbd_lock_socket_internal(xconn);
    3051           0 :         if (!ok) {
    3052           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(errno));
    3053           0 :                 DEBUG(0, ("%s: failed to lock socket\n", __location__));
    3054           0 :                 return;
    3055             :         }
    3056             : 
    3057           0 :         if (!fd_is_readable(xconn->transport.sock)) {
    3058           0 :                 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
    3059             :                           (int)getpid()));
    3060             : 
    3061           0 :                 ok = smbd_unlock_socket_internal(xconn);
    3062           0 :                 if (!ok) {
    3063           0 :                         tevent_req_nterror(req, map_nt_error_from_unix(errno));
    3064           0 :                         DEBUG(1, ("%s: failed to unlock socket\n",
    3065             :                                 __location__));
    3066           0 :                         return;
    3067             :                 }
    3068             : 
    3069           0 :                 subreq = wait_for_read_send(state, state->ev,
    3070             :                                             xconn->transport.sock, false);
    3071           0 :                 if (tevent_req_nomem(subreq, req)) {
    3072           0 :                         return;
    3073             :                 }
    3074           0 :                 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
    3075           0 :                 return;
    3076             :         }
    3077             : 
    3078           0 :         status = receive_smb_talloc(state, xconn,
    3079             :                                     xconn->transport.sock,
    3080             :                                     &state->buf,
    3081             :                                     0 /* timeout */,
    3082             :                                     &unread,
    3083             :                                     &encrypted,
    3084             :                                     &state->buflen,
    3085             :                                     &state->seqnum,
    3086             :                                     false /* trusted_channel*/);
    3087             : 
    3088           0 :         if (tevent_req_nterror(req, status)) {
    3089           0 :                 tevent_req_nterror(req, status);
    3090           0 :                 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
    3091             :                           (int)getpid(), nt_errstr(status)));
    3092           0 :                 return;
    3093             :         }
    3094             : 
    3095           0 :         ok = smbd_unlock_socket_internal(xconn);
    3096           0 :         if (!ok) {
    3097           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(errno));
    3098           0 :                 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
    3099           0 :                 return;
    3100             :         }
    3101           0 :         tevent_req_done(req);
    3102             : }
    3103             : 
    3104           0 : static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
    3105             :                                     char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
    3106             : {
    3107           0 :         struct smbd_echo_read_state *state = tevent_req_data(
    3108             :                 req, struct smbd_echo_read_state);
    3109             :         NTSTATUS status;
    3110             : 
    3111           0 :         if (tevent_req_is_nterror(req, &status)) {
    3112           0 :                 return status;
    3113             :         }
    3114           0 :         *pbuf = talloc_move(mem_ctx, &state->buf);
    3115           0 :         *pbuflen = state->buflen;
    3116           0 :         *pseqnum = state->seqnum;
    3117           0 :         return NT_STATUS_OK;
    3118             : }
    3119             : 
    3120             : struct smbd_echo_state {
    3121             :         struct tevent_context *ev;
    3122             :         struct iovec *pending;
    3123             :         struct smbd_server_connection *sconn;
    3124             :         struct smbXsrv_connection *xconn;
    3125             :         int parent_pipe;
    3126             : 
    3127             :         struct tevent_fd *parent_fde;
    3128             : 
    3129             :         struct tevent_req *write_req;
    3130             : };
    3131             : 
    3132             : static void smbd_echo_writer_done(struct tevent_req *req);
    3133             : 
    3134           0 : static void smbd_echo_activate_writer(struct smbd_echo_state *state)
    3135             : {
    3136             :         int num_pending;
    3137             : 
    3138           0 :         if (state->write_req != NULL) {
    3139           0 :                 return;
    3140             :         }
    3141             : 
    3142           0 :         num_pending = talloc_array_length(state->pending);
    3143           0 :         if (num_pending == 0) {
    3144           0 :                 return;
    3145             :         }
    3146             : 
    3147           0 :         state->write_req = writev_send(state, state->ev, NULL,
    3148             :                                        state->parent_pipe, false,
    3149             :                                        state->pending, num_pending);
    3150           0 :         if (state->write_req == NULL) {
    3151           0 :                 DEBUG(1, ("writev_send failed\n"));
    3152           0 :                 exit(1);
    3153             :         }
    3154             : 
    3155           0 :         talloc_steal(state->write_req, state->pending);
    3156           0 :         state->pending = NULL;
    3157             : 
    3158           0 :         tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
    3159             :                                 state);
    3160             : }
    3161             : 
    3162           0 : static void smbd_echo_writer_done(struct tevent_req *req)
    3163             : {
    3164           0 :         struct smbd_echo_state *state = tevent_req_callback_data(
    3165             :                 req, struct smbd_echo_state);
    3166             :         ssize_t written;
    3167             :         int err;
    3168             : 
    3169           0 :         written = writev_recv(req, &err);
    3170           0 :         TALLOC_FREE(req);
    3171           0 :         state->write_req = NULL;
    3172           0 :         if (written == -1) {
    3173           0 :                 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
    3174           0 :                 exit(1);
    3175             :         }
    3176           0 :         DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
    3177           0 :         smbd_echo_activate_writer(state);
    3178           0 : }
    3179             : 
    3180           0 : static bool smbd_echo_reply(struct smbd_echo_state *state,
    3181             :                             uint8_t *inbuf, size_t inbuf_len,
    3182             :                             uint32_t seqnum)
    3183             : {
    3184             :         struct smb_request req;
    3185             :         uint16_t num_replies;
    3186             :         char *outbuf;
    3187             :         bool ok;
    3188             : 
    3189           0 :         if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
    3190           0 :                 DEBUG(10, ("Got netbios keepalive\n"));
    3191             :                 /*
    3192             :                  * Just swallow it
    3193             :                  */
    3194           0 :                 return true;
    3195             :         }
    3196             : 
    3197           0 :         if (inbuf_len < smb_size) {
    3198           0 :                 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
    3199           0 :                 return false;
    3200             :         }
    3201           0 :         if (!valid_smb_header(inbuf)) {
    3202           0 :                 DEBUG(10, ("Got invalid SMB header\n"));
    3203           0 :                 return false;
    3204             :         }
    3205             : 
    3206           0 :         if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
    3207             :                               seqnum)) {
    3208           0 :                 return false;
    3209             :         }
    3210           0 :         req.inbuf = inbuf;
    3211             : 
    3212           0 :         DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
    3213             :                    smb_messages[req.cmd].name
    3214             :                    ? smb_messages[req.cmd].name : "unknown"));
    3215             : 
    3216           0 :         if (req.cmd != SMBecho) {
    3217           0 :                 return false;
    3218             :         }
    3219           0 :         if (req.wct < 1) {
    3220           0 :                 return false;
    3221             :         }
    3222             : 
    3223           0 :         num_replies = SVAL(req.vwv+0, 0);
    3224           0 :         if (num_replies != 1) {
    3225             :                 /* Not a Windows "Hey, you're still there?" request */
    3226           0 :                 return false;
    3227             :         }
    3228             : 
    3229           0 :         if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
    3230           0 :                            1, req.buflen)) {
    3231           0 :                 DEBUG(10, ("create_outbuf failed\n"));
    3232           0 :                 return false;
    3233             :         }
    3234           0 :         req.outbuf = (uint8_t *)outbuf;
    3235             : 
    3236           0 :         SSVAL(req.outbuf, smb_vwv0, num_replies);
    3237             : 
    3238           0 :         if (req.buflen > 0) {
    3239           0 :                 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
    3240             :         }
    3241             : 
    3242           0 :         ok = srv_send_smb(req.xconn,
    3243             :                           (char *)outbuf,
    3244             :                           true, seqnum+1,
    3245             :                           false, &req.pcd);
    3246           0 :         TALLOC_FREE(outbuf);
    3247           0 :         if (!ok) {
    3248           0 :                 exit(1);
    3249             :         }
    3250             : 
    3251           0 :         return true;
    3252             : }
    3253             : 
    3254           0 : static void smbd_echo_exit(struct tevent_context *ev,
    3255             :                            struct tevent_fd *fde, uint16_t flags,
    3256             :                            void *private_data)
    3257             : {
    3258           0 :         DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
    3259           0 :         exit(0);
    3260             : }
    3261             : 
    3262             : static void smbd_echo_got_packet(struct tevent_req *req);
    3263             : 
    3264           0 : static void smbd_echo_loop(struct smbXsrv_connection *xconn,
    3265             :                            int parent_pipe)
    3266             : {
    3267             :         struct smbd_echo_state *state;
    3268             :         struct tevent_req *read_req;
    3269             : 
    3270           0 :         state = talloc_zero(xconn, struct smbd_echo_state);
    3271           0 :         if (state == NULL) {
    3272           0 :                 DEBUG(1, ("talloc failed\n"));
    3273           0 :                 return;
    3274             :         }
    3275           0 :         state->xconn = xconn;
    3276           0 :         state->parent_pipe = parent_pipe;
    3277           0 :         state->ev = samba_tevent_context_init(state);
    3278           0 :         if (state->ev == NULL) {
    3279           0 :                 DEBUG(1, ("samba_tevent_context_init failed\n"));
    3280           0 :                 TALLOC_FREE(state);
    3281           0 :                 return;
    3282             :         }
    3283           0 :         state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
    3284             :                                         TEVENT_FD_READ, smbd_echo_exit,
    3285             :                                         state);
    3286           0 :         if (state->parent_fde == NULL) {
    3287           0 :                 DEBUG(1, ("tevent_add_fd failed\n"));
    3288           0 :                 TALLOC_FREE(state);
    3289           0 :                 return;
    3290             :         }
    3291             : 
    3292           0 :         read_req = smbd_echo_read_send(state, state->ev, xconn);
    3293           0 :         if (read_req == NULL) {
    3294           0 :                 DEBUG(1, ("smbd_echo_read_send failed\n"));
    3295           0 :                 TALLOC_FREE(state);
    3296           0 :                 return;
    3297             :         }
    3298           0 :         tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
    3299             : 
    3300             :         while (true) {
    3301           0 :                 if (tevent_loop_once(state->ev) == -1) {
    3302           0 :                         DEBUG(1, ("tevent_loop_once failed: %s\n",
    3303             :                                   strerror(errno)));
    3304           0 :                         break;
    3305             :                 }
    3306             :         }
    3307           0 :         TALLOC_FREE(state);
    3308             : }
    3309             : 
    3310           0 : static void smbd_echo_got_packet(struct tevent_req *req)
    3311             : {
    3312           0 :         struct smbd_echo_state *state = tevent_req_callback_data(
    3313             :                 req, struct smbd_echo_state);
    3314             :         NTSTATUS status;
    3315           0 :         char *buf = NULL;
    3316           0 :         size_t buflen = 0;
    3317           0 :         uint32_t seqnum = 0;
    3318             :         bool reply;
    3319             : 
    3320           0 :         status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
    3321           0 :         TALLOC_FREE(req);
    3322           0 :         if (!NT_STATUS_IS_OK(status)) {
    3323           0 :                 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
    3324             :                           nt_errstr(status)));
    3325           0 :                 exit(1);
    3326             :         }
    3327             : 
    3328           0 :         reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
    3329           0 :         if (!reply) {
    3330             :                 size_t num_pending;
    3331             :                 struct iovec *tmp;
    3332             :                 struct iovec *iov;
    3333             : 
    3334           0 :                 num_pending = talloc_array_length(state->pending);
    3335           0 :                 tmp = talloc_realloc(state, state->pending, struct iovec,
    3336             :                                      num_pending+1);
    3337           0 :                 if (tmp == NULL) {
    3338           0 :                         DEBUG(1, ("talloc_realloc failed\n"));
    3339           0 :                         exit(1);
    3340             :                 }
    3341           0 :                 state->pending = tmp;
    3342             : 
    3343           0 :                 if (buflen >= smb_size) {
    3344             :                         /*
    3345             :                          * place the seqnum in the packet so that the main process
    3346             :                          * can reply with signing
    3347             :                          */
    3348           0 :                         SIVAL(buf, smb_ss_field, seqnum);
    3349           0 :                         SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
    3350             :                 }
    3351             : 
    3352           0 :                 iov = &state->pending[num_pending];
    3353           0 :                 iov->iov_base = talloc_move(state->pending, &buf);
    3354           0 :                 iov->iov_len = buflen;
    3355             : 
    3356           0 :                 DEBUG(10,("echo_handler[%d]: forward to main\n",
    3357             :                           (int)getpid()));
    3358           0 :                 smbd_echo_activate_writer(state);
    3359             :         }
    3360             : 
    3361           0 :         req = smbd_echo_read_send(state, state->ev, state->xconn);
    3362           0 :         if (req == NULL) {
    3363           0 :                 DEBUG(1, ("smbd_echo_read_send failed\n"));
    3364           0 :                 exit(1);
    3365             :         }
    3366           0 :         tevent_req_set_callback(req, smbd_echo_got_packet, state);
    3367           0 : }
    3368             : 
    3369             : 
    3370             : /*
    3371             :  * Handle SMBecho requests in a forked child process
    3372             :  */
    3373           0 : bool fork_echo_handler(struct smbXsrv_connection *xconn)
    3374             : {
    3375             :         int listener_pipe[2];
    3376             :         int res;
    3377             :         pid_t child;
    3378           0 :         bool use_mutex = false;
    3379             : 
    3380           0 :         res = pipe(listener_pipe);
    3381           0 :         if (res == -1) {
    3382           0 :                 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
    3383           0 :                 return false;
    3384             :         }
    3385             : 
    3386             : #ifdef HAVE_ROBUST_MUTEXES
    3387           0 :         use_mutex = tdb_runtime_check_for_robust_mutexes();
    3388             : 
    3389           0 :         if (use_mutex) {
    3390             :                 pthread_mutexattr_t a;
    3391             : 
    3392           0 :                 xconn->smb1.echo_handler.socket_mutex =
    3393           0 :                         anonymous_shared_allocate(sizeof(pthread_mutex_t));
    3394           0 :                 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
    3395           0 :                         DEBUG(1, ("Could not create mutex shared memory: %s\n",
    3396             :                                   strerror(errno)));
    3397           0 :                         goto fail;
    3398             :                 }
    3399             : 
    3400           0 :                 res = pthread_mutexattr_init(&a);
    3401           0 :                 if (res != 0) {
    3402           0 :                         DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
    3403             :                                   strerror(res)));
    3404           0 :                         goto fail;
    3405             :                 }
    3406           0 :                 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
    3407           0 :                 if (res != 0) {
    3408           0 :                         DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
    3409             :                                   strerror(res)));
    3410           0 :                         pthread_mutexattr_destroy(&a);
    3411           0 :                         goto fail;
    3412             :                 }
    3413           0 :                 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
    3414           0 :                 if (res != 0) {
    3415           0 :                         DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
    3416             :                                   strerror(res)));
    3417           0 :                         pthread_mutexattr_destroy(&a);
    3418           0 :                         goto fail;
    3419             :                 }
    3420           0 :                 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
    3421           0 :                 if (res != 0) {
    3422           0 :                         DEBUG(1, ("pthread_mutexattr_setrobust failed: "
    3423             :                                   "%s\n", strerror(res)));
    3424           0 :                         pthread_mutexattr_destroy(&a);
    3425           0 :                         goto fail;
    3426             :                 }
    3427           0 :                 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
    3428             :                                          &a);
    3429           0 :                 pthread_mutexattr_destroy(&a);
    3430           0 :                 if (res != 0) {
    3431           0 :                         DEBUG(1, ("pthread_mutex_init failed: %s\n",
    3432             :                                   strerror(res)));
    3433           0 :                         goto fail;
    3434             :                 }
    3435             :         }
    3436             : #endif
    3437             : 
    3438           0 :         if (!use_mutex) {
    3439           0 :                 xconn->smb1.echo_handler.socket_lock_fd =
    3440           0 :                         create_unlink_tmp(lp_lock_directory());
    3441           0 :                 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
    3442           0 :                         DEBUG(1, ("Could not create lock fd: %s\n",
    3443             :                                   strerror(errno)));
    3444           0 :                         goto fail;
    3445             :                 }
    3446             :         }
    3447             : 
    3448           0 :         child = fork();
    3449           0 :         if (child == 0) {
    3450             :                 NTSTATUS status;
    3451             : 
    3452           0 :                 close(listener_pipe[0]);
    3453           0 :                 set_blocking(listener_pipe[1], false);
    3454             : 
    3455           0 :                 status = smbd_reinit_after_fork(xconn->client->msg_ctx,
    3456           0 :                                                 xconn->client->raw_ev_ctx,
    3457             :                                                 true,
    3458             :                                                 "smbd-echo");
    3459           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3460           0 :                         DEBUG(1, ("reinit_after_fork failed: %s\n",
    3461             :                                   nt_errstr(status)));
    3462           0 :                         exit(1);
    3463             :                 }
    3464           0 :                 initialize_password_db(true, xconn->client->raw_ev_ctx);
    3465           0 :                 smbd_echo_loop(xconn, listener_pipe[1]);
    3466           0 :                 exit(0);
    3467             :         }
    3468           0 :         close(listener_pipe[1]);
    3469           0 :         listener_pipe[1] = -1;
    3470           0 :         xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
    3471             : 
    3472           0 :         DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
    3473             : 
    3474             :         /*
    3475             :          * Without smb signing this is the same as the normal smbd
    3476             :          * listener. This needs to change once signing comes in.
    3477             :          */
    3478           0 :         xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(
    3479             :                                         xconn->client->raw_ev_ctx,
    3480             :                                         xconn,
    3481             :                                         xconn->smb1.echo_handler.trusted_fd,
    3482             :                                         TEVENT_FD_READ,
    3483             :                                         smbd_server_echo_handler,
    3484             :                                         xconn);
    3485           0 :         if (xconn->smb1.echo_handler.trusted_fde == NULL) {
    3486           0 :                 DEBUG(1, ("event_add_fd failed\n"));
    3487           0 :                 goto fail;
    3488             :         }
    3489             : 
    3490           0 :         return true;
    3491             : 
    3492           0 : fail:
    3493           0 :         if (listener_pipe[0] != -1) {
    3494           0 :                 close(listener_pipe[0]);
    3495             :         }
    3496           0 :         if (listener_pipe[1] != -1) {
    3497           0 :                 close(listener_pipe[1]);
    3498             :         }
    3499           0 :         if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
    3500           0 :                 close(xconn->smb1.echo_handler.socket_lock_fd);
    3501             :         }
    3502             : #ifdef HAVE_ROBUST_MUTEXES
    3503           0 :         if (xconn->smb1.echo_handler.socket_mutex != NULL) {
    3504           0 :                 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
    3505           0 :                 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
    3506             :         }
    3507             : #endif
    3508           0 :         smbd_echo_init(xconn);
    3509             : 
    3510           0 :         return false;
    3511             : }
    3512             : 
    3513           0 : static bool uid_in_use(struct auth_session_info *session_info,
    3514             :                        uid_t uid)
    3515             : {
    3516           0 :         if (session_info->unix_token->uid == uid) {
    3517           0 :                 return true;
    3518             :         }
    3519           0 :         return false;
    3520             : }
    3521             : 
    3522           0 : static bool gid_in_use(struct auth_session_info *session_info,
    3523             :                        gid_t gid)
    3524             : {
    3525             :         uint32_t i;
    3526           0 :         struct security_unix_token *utok = NULL;
    3527             : 
    3528           0 :         utok = session_info->unix_token;
    3529           0 :         if (utok->gid == gid) {
    3530           0 :                 return true;
    3531             :         }
    3532             : 
    3533           0 :         for(i = 0; i < utok->ngroups; i++) {
    3534           0 :                 if (utok->groups[i] == gid) {
    3535           0 :                         return true;
    3536             :                 }
    3537             :         }
    3538           0 :         return false;
    3539             : }
    3540             : 
    3541           0 : static bool sid_in_use(struct auth_session_info *session_info,
    3542             :                        const struct dom_sid *psid)
    3543             : {
    3544           0 :         struct security_token *tok = NULL;
    3545             : 
    3546           0 :         tok = session_info->security_token;
    3547           0 :         if (tok == NULL) {
    3548             :                 /*
    3549             :                  * Not sure session_info->security_token can
    3550             :                  * ever be NULL. This check might be not
    3551             :                  * necessary.
    3552             :                  */
    3553           0 :                 return false;
    3554             :         }
    3555           0 :         if (security_token_has_sid(tok, psid)) {
    3556           0 :                 return true;
    3557             :         }
    3558           0 :         return false;
    3559             : }
    3560             : 
    3561             : struct id_in_use_state {
    3562             :         const struct id_cache_ref *id;
    3563             :         bool match;
    3564             : };
    3565             : 
    3566           0 : static int id_in_use_cb(struct smbXsrv_session *session,
    3567             :                         void *private_data)
    3568             : {
    3569           0 :         struct id_in_use_state *state = (struct id_in_use_state *)
    3570             :                 private_data;
    3571           0 :         struct auth_session_info *session_info =
    3572           0 :                 session->global->auth_session_info;
    3573             : 
    3574           0 :         switch(state->id->type) {
    3575           0 :         case UID:
    3576           0 :                 state->match = uid_in_use(session_info, state->id->id.uid);
    3577           0 :                 break;
    3578           0 :         case GID:
    3579           0 :                 state->match = gid_in_use(session_info, state->id->id.gid);
    3580           0 :                 break;
    3581           0 :         case SID:
    3582           0 :                 state->match = sid_in_use(session_info, &state->id->id.sid);
    3583           0 :                 break;
    3584           0 :         default:
    3585           0 :                 state->match = false;
    3586           0 :                 break;
    3587             :         }
    3588           0 :         if (state->match) {
    3589           0 :                 return -1;
    3590             :         }
    3591           0 :         return 0;
    3592             : }
    3593             : 
    3594           0 : static bool id_in_use(struct smbd_server_connection *sconn,
    3595             :                       const struct id_cache_ref *id)
    3596             : {
    3597             :         struct id_in_use_state state;
    3598             :         NTSTATUS status;
    3599             : 
    3600           0 :         state = (struct id_in_use_state) {
    3601             :                 .id = id,
    3602             :                 .match = false,
    3603             :         };
    3604             : 
    3605           0 :         status = smbXsrv_session_local_traverse(sconn->client,
    3606             :                                                 id_in_use_cb,
    3607             :                                                 &state);
    3608           0 :         if (!NT_STATUS_IS_OK(status)) {
    3609           0 :                 return false;
    3610             :         }
    3611             : 
    3612           0 :         return state.match;
    3613             : }
    3614             : 
    3615           0 : static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
    3616             :                                void *private_data,
    3617             :                                uint32_t msg_type,
    3618             :                                struct server_id server_id,
    3619             :                                DATA_BLOB* data)
    3620             : {
    3621           0 :         const char *msg = (data && data->data)
    3622           0 :                 ? (const char *)data->data : "<NULL>";
    3623             :         struct id_cache_ref id;
    3624           0 :         struct smbd_server_connection *sconn =
    3625             :                 talloc_get_type_abort(private_data,
    3626             :                 struct smbd_server_connection);
    3627             : 
    3628           0 :         if (!id_cache_ref_parse(msg, &id)) {
    3629           0 :                 DEBUG(0, ("Invalid ?ID: %s\n", msg));
    3630           0 :                 return;
    3631             :         }
    3632             : 
    3633           0 :         if (id_in_use(sconn, &id)) {
    3634           0 :                 exit_server_cleanly(msg);
    3635             :         }
    3636           0 :         id_cache_delete_from_cache(&id);
    3637             : }
    3638             : 
    3639       27838 : NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
    3640             :                                         enum protocol_types protocol)
    3641             : {
    3642             :         NTSTATUS status;
    3643             : 
    3644       27838 :         conn->protocol = protocol;
    3645             : 
    3646       27838 :         if (conn->client->session_table != NULL) {
    3647         930 :                 return NT_STATUS_OK;
    3648             :         }
    3649             : 
    3650       26908 :         if (protocol >= PROTOCOL_SMB2_02) {
    3651       22052 :                 status = smb2srv_session_table_init(conn);
    3652       22052 :                 if (!NT_STATUS_IS_OK(status)) {
    3653           0 :                         conn->protocol = PROTOCOL_NONE;
    3654           0 :                         return status;
    3655             :                 }
    3656             : 
    3657       22052 :                 status = smb2srv_open_table_init(conn);
    3658       22052 :                 if (!NT_STATUS_IS_OK(status)) {
    3659           0 :                         conn->protocol = PROTOCOL_NONE;
    3660           0 :                         return status;
    3661             :                 }
    3662             :         } else {
    3663        4856 :                 status = smb1srv_session_table_init(conn);
    3664        4856 :                 if (!NT_STATUS_IS_OK(status)) {
    3665           0 :                         conn->protocol = PROTOCOL_NONE;
    3666           0 :                         return status;
    3667             :                 }
    3668             : 
    3669        4856 :                 status = smb1srv_tcon_table_init(conn);
    3670        4856 :                 if (!NT_STATUS_IS_OK(status)) {
    3671           0 :                         conn->protocol = PROTOCOL_NONE;
    3672           0 :                         return status;
    3673             :                 }
    3674             : 
    3675        4856 :                 status = smb1srv_open_table_init(conn);
    3676        4856 :                 if (!NT_STATUS_IS_OK(status)) {
    3677           0 :                         conn->protocol = PROTOCOL_NONE;
    3678           0 :                         return status;
    3679             :                 }
    3680             :         }
    3681             : 
    3682       26908 :         set_Protocol(protocol);
    3683       26908 :         return NT_STATUS_OK;
    3684             : }
    3685             : 
    3686             : struct smbd_tevent_trace_state {
    3687             :         struct tevent_context *ev;
    3688             :         TALLOC_CTX *frame;
    3689             :         SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
    3690             : };
    3691             : 
    3692    17276630 : static void smbd_tevent_trace_callback(enum tevent_trace_point point,
    3693             :                                        void *private_data)
    3694             : {
    3695    17276630 :         struct smbd_tevent_trace_state *state =
    3696             :                 (struct smbd_tevent_trace_state *)private_data;
    3697             : 
    3698    17276630 :         switch (point) {
    3699     3290379 :         case TEVENT_TRACE_BEFORE_WAIT:
    3700     3290379 :                 if (!smbprofile_dump_pending()) {
    3701             :                         /*
    3702             :                          * If there's no dump pending
    3703             :                          * we don't want to schedule a new 1 sec timer.
    3704             :                          *
    3705             :                          * Instead we want to sleep as long as nothing happens.
    3706             :                          */
    3707     3318621 :                         smbprofile_dump_setup(NULL);
    3708             :                 }
    3709     3318621 :                 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
    3710     3290379 :                 break;
    3711     3318621 :         case TEVENT_TRACE_AFTER_WAIT:
    3712     3318621 :                 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
    3713     3290379 :                 if (!smbprofile_dump_pending()) {
    3714             :                         /*
    3715             :                          * We need to flush our state after sleeping
    3716             :                          * (hopefully a long time).
    3717             :                          */
    3718     3318621 :                         smbprofile_dump();
    3719             :                         /*
    3720             :                          * future profiling events should trigger timers
    3721             :                          * on our main event context.
    3722             :                          */
    3723     3318621 :                         smbprofile_dump_setup(state->ev);
    3724             :                 }
    3725     3290379 :                 break;
    3726     5333446 :         case TEVENT_TRACE_BEFORE_LOOP_ONCE:
    3727     5333446 :                 TALLOC_FREE(state->frame);
    3728     5333446 :                 state->frame = talloc_stackframe_pool(8192);
    3729     5333446 :                 break;
    3730     5305942 :         case TEVENT_TRACE_AFTER_LOOP_ONCE:
    3731     5305942 :                 TALLOC_FREE(state->frame);
    3732     5257021 :                 break;
    3733             :         }
    3734             : 
    3735    17276630 :         errno = 0;
    3736    17276630 : }
    3737             : 
    3738             : /**
    3739             :  * Create a debug string for the connection
    3740             :  *
    3741             :  * This is allocated to talloc_tos() or a string constant
    3742             :  * in certain corner cases. The returned string should
    3743             :  * hence not be free'd directly but only via the talloc stack.
    3744             :  */
    3745          37 : const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
    3746             : {
    3747             :         const char *ret;
    3748             :         char *addr;
    3749             :         /*
    3750             :          * TODO: this can be improved later
    3751             :          * maybe including the client guid or more
    3752             :          */
    3753          37 :         addr = tsocket_address_string(xconn->remote_address, talloc_tos());
    3754          37 :         if (addr == NULL) {
    3755           0 :                 return "<tsocket_address_string() failed>";
    3756             :         }
    3757             : 
    3758          37 :         ret = talloc_asprintf(talloc_tos(), "ptr=%p,id=%llu,addr=%s",
    3759          37 :                               xconn, (unsigned long long)xconn->channel_id, addr);
    3760          37 :         TALLOC_FREE(addr);
    3761          37 :         if (ret == NULL) {
    3762           0 :                 return "<talloc_asprintf() failed>";
    3763             :         }
    3764             : 
    3765          37 :         return ret;
    3766             : }
    3767             : 
    3768       28420 : static int smbXsrv_connection_destructor(struct smbXsrv_connection *xconn)
    3769             : {
    3770       28420 :         DBG_DEBUG("xconn[%s]\n", smbXsrv_connection_dbg(xconn));
    3771       28420 :         return 0;
    3772             : }
    3773             : 
    3774       28434 : NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
    3775             :                              NTTIME now, struct smbXsrv_connection **_xconn)
    3776             : {
    3777       28434 :         TALLOC_CTX *frame = talloc_stackframe();
    3778             :         struct smbXsrv_connection *xconn;
    3779             :         struct sockaddr_storage ss_srv;
    3780       28434 :         void *sp_srv = (void *)&ss_srv;
    3781       28434 :         struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
    3782             :         struct sockaddr_storage ss_clnt;
    3783       28434 :         void *sp_clnt = (void *)&ss_clnt;
    3784       28434 :         struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
    3785             :         socklen_t sa_socklen;
    3786       28434 :         struct tsocket_address *local_address = NULL;
    3787       28434 :         struct tsocket_address *remote_address = NULL;
    3788       28434 :         const char *remaddr = NULL;
    3789             :         char *p;
    3790       28434 :         const char *rhost = NULL;
    3791             :         int ret;
    3792             :         int tmp;
    3793             : 
    3794       28434 :         *_xconn = NULL;
    3795             : 
    3796       28434 :         DO_PROFILE_INC(connect);
    3797             : 
    3798       28434 :         xconn = talloc_zero(client, struct smbXsrv_connection);
    3799       28434 :         if (xconn == NULL) {
    3800           0 :                 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
    3801           0 :                 TALLOC_FREE(frame);
    3802           0 :                 return NT_STATUS_NO_MEMORY;
    3803             :         }
    3804       28434 :         talloc_set_destructor(xconn, smbXsrv_connection_destructor);
    3805       28434 :         talloc_steal(frame, xconn);
    3806       28434 :         xconn->client = client;
    3807       28434 :         xconn->connect_time = now;
    3808       28434 :         if (client->next_channel_id != 0) {
    3809       28434 :                 xconn->channel_id = client->next_channel_id++;
    3810             :         }
    3811             : 
    3812       28434 :         xconn->transport.sock = sock_fd;
    3813       28434 :         smbd_echo_init(xconn);
    3814       28434 :         xconn->protocol = PROTOCOL_NONE;
    3815             : 
    3816             :         /* Ensure child is set to blocking mode */
    3817       28434 :         set_blocking(sock_fd,True);
    3818             : 
    3819       28434 :         set_socket_options(sock_fd, "SO_KEEPALIVE");
    3820       28434 :         set_socket_options(sock_fd, lp_socket_options());
    3821             : 
    3822       28434 :         sa_socklen = sizeof(ss_clnt);
    3823       28434 :         ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
    3824       28434 :         if (ret != 0) {
    3825           0 :                 int saved_errno = errno;
    3826           0 :                 int level = (errno == ENOTCONN)?2:0;
    3827           0 :                 DEBUG(level,("getpeername() failed - %s\n",
    3828             :                       strerror(saved_errno)));
    3829           0 :                 TALLOC_FREE(frame);
    3830           0 :                 return map_nt_error_from_unix_common(saved_errno);
    3831             :         }
    3832       28434 :         ret = tsocket_address_bsd_from_sockaddr(xconn,
    3833             :                                                 sa_clnt, sa_socklen,
    3834             :                                                 &remote_address);
    3835       28434 :         if (ret != 0) {
    3836           0 :                 int saved_errno = errno;
    3837           0 :                 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
    3838             :                         __location__, strerror(saved_errno)));
    3839           0 :                 TALLOC_FREE(frame);
    3840           0 :                 return map_nt_error_from_unix_common(saved_errno);
    3841             :         }
    3842             : 
    3843       28434 :         sa_socklen = sizeof(ss_srv);
    3844       28434 :         ret = getsockname(sock_fd, sa_srv, &sa_socklen);
    3845       28434 :         if (ret != 0) {
    3846           0 :                 int saved_errno = errno;
    3847           0 :                 int level = (errno == ENOTCONN)?2:0;
    3848           0 :                 DEBUG(level,("getsockname() failed - %s\n",
    3849             :                       strerror(saved_errno)));
    3850           0 :                 TALLOC_FREE(frame);
    3851           0 :                 return map_nt_error_from_unix_common(saved_errno);
    3852             :         }
    3853       28434 :         ret = tsocket_address_bsd_from_sockaddr(xconn,
    3854             :                                                 sa_srv, sa_socklen,
    3855             :                                                 &local_address);
    3856       28434 :         if (ret != 0) {
    3857           0 :                 int saved_errno = errno;
    3858           0 :                 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
    3859             :                         __location__, strerror(saved_errno)));
    3860           0 :                 TALLOC_FREE(frame);
    3861           0 :                 return map_nt_error_from_unix_common(saved_errno);
    3862             :         }
    3863             : 
    3864       28434 :         if (tsocket_address_is_inet(remote_address, "ip")) {
    3865       28434 :                 remaddr = tsocket_address_inet_addr_string(remote_address,
    3866             :                                                            talloc_tos());
    3867       28434 :                 if (remaddr == NULL) {
    3868           0 :                         DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
    3869             :                                  __location__, strerror(errno)));
    3870           0 :                         TALLOC_FREE(frame);
    3871           0 :                         return NT_STATUS_NO_MEMORY;
    3872             :                 }
    3873             :         } else {
    3874           0 :                 remaddr = "0.0.0.0";
    3875             :         }
    3876             : 
    3877             :         /*
    3878             :          * Before the first packet, check the global hosts allow/ hosts deny
    3879             :          * parameters before doing any parsing of packets passed to us by the
    3880             :          * client. This prevents attacks on our parsing code from hosts not in
    3881             :          * the hosts allow list.
    3882             :          */
    3883             : 
    3884       28434 :         ret = get_remote_hostname(remote_address,
    3885             :                                   &p, talloc_tos());
    3886       28434 :         if (ret < 0) {
    3887           0 :                 int saved_errno = errno;
    3888           0 :                 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
    3889             :                         __location__, strerror(saved_errno)));
    3890           0 :                 TALLOC_FREE(frame);
    3891           0 :                 return map_nt_error_from_unix_common(saved_errno);
    3892             :         }
    3893       28434 :         rhost = p;
    3894       28434 :         if (strequal(rhost, "UNKNOWN")) {
    3895           0 :                 rhost = remaddr;
    3896             :         }
    3897             : 
    3898       28434 :         xconn->local_address = local_address;
    3899       28434 :         xconn->remote_address = remote_address;
    3900       28434 :         xconn->remote_hostname = talloc_strdup(xconn, rhost);
    3901       28434 :         if (xconn->remote_hostname == NULL) {
    3902           0 :                 return NT_STATUS_NO_MEMORY;
    3903             :         }
    3904             : 
    3905       28434 :         if (!srv_init_signing(xconn)) {
    3906           0 :                 DEBUG(0, ("Failed to init smb_signing\n"));
    3907           0 :                 TALLOC_FREE(frame);
    3908           0 :                 return NT_STATUS_INTERNAL_ERROR;
    3909             :         }
    3910             : 
    3911       28434 :         if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
    3912             :                           xconn->remote_hostname,
    3913             :                           remaddr)) {
    3914           0 :                 DEBUG( 1, ("Connection denied from %s to %s\n",
    3915             :                            tsocket_address_string(remote_address, talloc_tos()),
    3916             :                            tsocket_address_string(local_address, talloc_tos())));
    3917             : 
    3918             :                 /*
    3919             :                  * We return a valid xconn
    3920             :                  * so that the caller can return an error message
    3921             :                  * to the client
    3922             :                  */
    3923           0 :                 DLIST_ADD_END(client->connections, xconn);
    3924           0 :                 talloc_steal(client, xconn);
    3925             : 
    3926           0 :                 *_xconn = xconn;
    3927           0 :                 TALLOC_FREE(frame);
    3928           0 :                 return NT_STATUS_NETWORK_ACCESS_DENIED;
    3929             :         }
    3930             : 
    3931       28434 :         DEBUG(10, ("Connection allowed from %s to %s\n",
    3932             :                    tsocket_address_string(remote_address, talloc_tos()),
    3933             :                    tsocket_address_string(local_address, talloc_tos())));
    3934             : 
    3935       28434 :         if (lp_clustering()) {
    3936             :                 /*
    3937             :                  * We need to tell ctdb about our client's TCP
    3938             :                  * connection, so that for failover ctdbd can send
    3939             :                  * tickle acks, triggering a reconnection by the
    3940             :                  * client.
    3941             :                  */
    3942             :                 NTSTATUS status;
    3943             : 
    3944           0 :                 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
    3945           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3946           0 :                         DEBUG(0, ("ctdbd_register_ips failed: %s\n",
    3947             :                                   nt_errstr(status)));
    3948             :                 }
    3949             :         }
    3950             : 
    3951       28434 :         tmp = lp_max_xmit();
    3952       28434 :         tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
    3953       28434 :         tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
    3954             : 
    3955       28434 :         xconn->smb1.negprot.max_recv = tmp;
    3956             : 
    3957       28434 :         xconn->smb1.sessions.done_sesssetup = false;
    3958       28434 :         xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
    3959             : 
    3960       28434 :         xconn->transport.fde = tevent_add_fd(client->raw_ev_ctx,
    3961             :                                              xconn,
    3962             :                                              sock_fd,
    3963             :                                              TEVENT_FD_READ,
    3964             :                                              smbd_server_connection_handler,
    3965             :                                              xconn);
    3966       28434 :         if (!xconn->transport.fde) {
    3967           0 :                 TALLOC_FREE(frame);
    3968           0 :                 return NT_STATUS_NO_MEMORY;
    3969             :         }
    3970       28434 :         tevent_fd_set_auto_close(xconn->transport.fde);
    3971             : 
    3972             :         /* for now we only have one connection */
    3973       28434 :         DLIST_ADD_END(client->connections, xconn);
    3974       28434 :         talloc_steal(client, xconn);
    3975             : 
    3976       28434 :         *_xconn = xconn;
    3977       28434 :         TALLOC_FREE(frame);
    3978       28434 :         return NT_STATUS_OK;
    3979             : }
    3980             : 
    3981             : /****************************************************************************
    3982             :  Process commands from the client
    3983             : ****************************************************************************/
    3984             : 
    3985       27504 : void smbd_process(struct tevent_context *ev_ctx,
    3986             :                   struct messaging_context *msg_ctx,
    3987             :                   struct dcesrv_context *dce_ctx,
    3988             :                   int sock_fd,
    3989             :                   bool interactive)
    3990             : {
    3991       55008 :         struct smbd_tevent_trace_state trace_state = {
    3992             :                 .ev = ev_ctx,
    3993       27504 :                 .frame = talloc_stackframe(),
    3994             :         };
    3995       27504 :         const struct loadparm_substitution *lp_sub =
    3996             :                 loadparm_s3_global_substitution();
    3997       27504 :         struct smbXsrv_client *client = NULL;
    3998       27504 :         struct smbd_server_connection *sconn = NULL;
    3999       27504 :         struct smbXsrv_connection *xconn = NULL;
    4000       27504 :         const char *locaddr = NULL;
    4001       27504 :         const char *remaddr = NULL;
    4002             :         int ret;
    4003             :         NTSTATUS status;
    4004       27504 :         struct timeval tv = timeval_current();
    4005       27504 :         NTTIME now = timeval_to_nttime(&tv);
    4006       27504 :         char *chroot_dir = NULL;
    4007             :         int rc;
    4008             : 
    4009       27504 :         status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
    4010       27504 :         if (!NT_STATUS_IS_OK(status)) {
    4011           0 :                 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
    4012           0 :                 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
    4013             :         }
    4014             : 
    4015             :         /*
    4016             :          * TODO: remove this...:-)
    4017             :          */
    4018       27504 :         global_smbXsrv_client = client;
    4019             : 
    4020       27504 :         sconn = talloc_zero(client, struct smbd_server_connection);
    4021       27504 :         if (sconn == NULL) {
    4022           0 :                 exit_server("failed to create smbd_server_connection");
    4023             :         }
    4024             : 
    4025       27504 :         client->sconn = sconn;
    4026       27504 :         sconn->client = client;
    4027             : 
    4028       27504 :         sconn->ev_ctx = ev_ctx;
    4029       27504 :         sconn->msg_ctx = msg_ctx;
    4030       27504 :         sconn->dce_ctx = dce_ctx;
    4031             : 
    4032       27504 :         ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
    4033             :                                       &sconn->pool);
    4034       27504 :         if (ret != 0) {
    4035           0 :                 exit_server("pthreadpool_tevent_init() failed.");
    4036             :         }
    4037             : 
    4038       27504 :         if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
    4039             :                 /*
    4040             :                  * We're not making the decision here,
    4041             :                  * we're just allowing the client
    4042             :                  * to decide between SMB1 and SMB2
    4043             :                  * with the first negprot
    4044             :                  * packet.
    4045             :                  */
    4046       27504 :                 sconn->using_smb2 = true;
    4047             :         }
    4048             : 
    4049       27504 :         if (!interactive) {
    4050       27504 :                 smbd_setup_sig_term_handler(sconn);
    4051       27504 :                 smbd_setup_sig_hup_handler(sconn);
    4052             :         }
    4053             : 
    4054       27504 :         status = smbd_add_connection(client, sock_fd, now, &xconn);
    4055       27504 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
    4056             :                 /*
    4057             :                  * send a negative session response "not listening on calling
    4058             :                  * name"
    4059             :                  */
    4060           0 :                 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
    4061           0 :                 (void)srv_send_smb(xconn,(char *)buf, false,
    4062             :                                    0, false, NULL);
    4063           0 :                 exit_server_cleanly("connection denied");
    4064       27504 :         } else if (!NT_STATUS_IS_OK(status)) {
    4065           0 :                 exit_server_cleanly(nt_errstr(status));
    4066             :         }
    4067             : 
    4068       27504 :         sconn->local_address =
    4069       27504 :                 tsocket_address_copy(xconn->local_address, sconn);
    4070       27504 :         if (sconn->local_address == NULL) {
    4071           0 :                 exit_server_cleanly("tsocket_address_copy() failed");
    4072             :         }
    4073       27504 :         sconn->remote_address =
    4074       27504 :                 tsocket_address_copy(xconn->remote_address, sconn);
    4075       27504 :         if (sconn->remote_address == NULL) {
    4076           0 :                 exit_server_cleanly("tsocket_address_copy() failed");
    4077             :         }
    4078       27504 :         sconn->remote_hostname =
    4079       27504 :                 talloc_strdup(sconn, xconn->remote_hostname);
    4080       27504 :         if (sconn->remote_hostname == NULL) {
    4081           0 :                 exit_server_cleanly("tsocket_strdup() failed");
    4082             :         }
    4083             : 
    4084       54478 :         client->global->local_address =
    4085       54478 :                 tsocket_address_string(sconn->local_address,
    4086       27504 :                                        client->global);
    4087       27504 :         if (client->global->local_address == NULL) {
    4088           0 :                 exit_server_cleanly("tsocket_address_string() failed");
    4089             :         }
    4090       54478 :         client->global->remote_address =
    4091       54478 :                 tsocket_address_string(sconn->remote_address,
    4092       26974 :                                        client->global);
    4093       27504 :         if (client->global->remote_address == NULL) {
    4094           0 :                 exit_server_cleanly("tsocket_address_string() failed");
    4095             :         }
    4096       54478 :         client->global->remote_name =
    4097       54478 :                 talloc_strdup(client->global, sconn->remote_hostname);
    4098       27504 :         if (client->global->remote_name == NULL) {
    4099           0 :                 exit_server_cleanly("tsocket_strdup() failed");
    4100             :         }
    4101             : 
    4102       27504 :         if (tsocket_address_is_inet(sconn->local_address, "ip")) {
    4103       27504 :                 locaddr = tsocket_address_inet_addr_string(
    4104             :                                 sconn->local_address,
    4105             :                                 talloc_tos());
    4106       27504 :                 if (locaddr == NULL) {
    4107           0 :                         DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
    4108             :                                  __location__, strerror(errno)));
    4109           0 :                         exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
    4110             :                 }
    4111             :         } else {
    4112           0 :                 locaddr = "0.0.0.0";
    4113             :         }
    4114             : 
    4115       27504 :         if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
    4116       27504 :                 remaddr = tsocket_address_inet_addr_string(
    4117             :                                 sconn->remote_address,
    4118             :                                 talloc_tos());
    4119       27504 :                 if (remaddr == NULL) {
    4120           0 :                         DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
    4121             :                                  __location__, strerror(errno)));
    4122           0 :                         exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
    4123             :                 }
    4124             :         } else {
    4125           0 :                 remaddr = "0.0.0.0";
    4126             :         }
    4127             : 
    4128             :         /* this is needed so that we get decent entries
    4129             :            in smbstatus for port 445 connects */
    4130       27504 :         set_remote_machine_name(remaddr, false);
    4131       27504 :         reload_services(sconn, conn_snum_used, true);
    4132       27504 :         sub_set_socket_ids(remaddr,
    4133             :                            sconn->remote_hostname,
    4134             :                            locaddr);
    4135             : 
    4136       27504 :         if (lp_preload_modules()) {
    4137           0 :                 smb_load_all_modules_absoute_path(lp_preload_modules());
    4138             :         }
    4139             : 
    4140       27504 :         smb_perfcount_init();
    4141             : 
    4142       27504 :         if (!init_account_policy()) {
    4143           0 :                 exit_server("Could not open account policy tdb.\n");
    4144             :         }
    4145             : 
    4146       27504 :         chroot_dir = lp_root_directory(talloc_tos(), lp_sub);
    4147       27504 :         if (chroot_dir[0] != '\0') {
    4148           0 :                 rc = chdir(chroot_dir);
    4149           0 :                 if (rc != 0) {
    4150           0 :                         DBG_ERR("Failed to chdir to %s\n", chroot_dir);
    4151           0 :                         exit_server("Failed to chdir()");
    4152             :                 }
    4153             : 
    4154           0 :                 rc = chroot(chroot_dir);
    4155           0 :                 if (rc != 0) {
    4156           0 :                         DBG_ERR("Failed to change root to %s\n", chroot_dir);
    4157           0 :                         exit_server("Failed to chroot()");
    4158             :                 }
    4159           0 :                 DBG_WARNING("Changed root to %s\n", chroot_dir);
    4160             : 
    4161           0 :                 TALLOC_FREE(chroot_dir);
    4162             :         }
    4163             : 
    4164       27504 :         if (!file_init(sconn)) {
    4165           0 :                 exit_server("file_init() failed");
    4166             :         }
    4167             : 
    4168             :         /* Setup oplocks */
    4169       27504 :         if (!init_oplocks(sconn))
    4170           0 :                 exit_server("Failed to init oplocks");
    4171             : 
    4172             :         /* register our message handlers */
    4173       27504 :         messaging_register(sconn->msg_ctx, sconn,
    4174             :                            MSG_SMB_FORCE_TDIS, msg_force_tdis);
    4175       27504 :         messaging_register(
    4176             :                 sconn->msg_ctx,
    4177             :                 sconn,
    4178             :                 MSG_SMB_FORCE_TDIS_DENIED,
    4179             :                 msg_force_tdis_denied);
    4180       27504 :         messaging_register(sconn->msg_ctx, sconn,
    4181             :                            MSG_SMB_CLOSE_FILE, msg_close_file);
    4182       27504 :         messaging_register(sconn->msg_ctx, sconn,
    4183             :                            MSG_SMB_FILE_RENAME, msg_file_was_renamed);
    4184             : 
    4185       27504 :         id_cache_register_msgs(sconn->msg_ctx);
    4186       27504 :         messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
    4187       27504 :         messaging_register(sconn->msg_ctx, sconn,
    4188             :                            ID_CACHE_KILL, smbd_id_cache_kill);
    4189             : 
    4190       27504 :         messaging_deregister(sconn->msg_ctx,
    4191       27504 :                              MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
    4192       27504 :         messaging_register(sconn->msg_ctx, sconn,
    4193             :                            MSG_SMB_CONF_UPDATED, smbd_conf_updated);
    4194             : 
    4195       27504 :         messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
    4196             :                              NULL);
    4197       27504 :         messaging_register(sconn->msg_ctx, sconn,
    4198             :                            MSG_SMB_KILL_CLIENT_IP,
    4199             :                            msg_kill_client_ip);
    4200             : 
    4201       27504 :         messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
    4202             : 
    4203             :         /*
    4204             :          * Use the default MSG_DEBUG handler to avoid rebroadcasting
    4205             :          * MSGs to all child processes
    4206             :          */
    4207       27504 :         messaging_deregister(sconn->msg_ctx,
    4208             :                              MSG_DEBUG, NULL);
    4209       27504 :         messaging_register(sconn->msg_ctx, NULL,
    4210             :                            MSG_DEBUG, debug_message);
    4211             : 
    4212       27504 :         if ((lp_keepalive() != 0)
    4213       27504 :             && !(event_add_idle(ev_ctx, NULL,
    4214       27504 :                                 timeval_set(lp_keepalive(), 0),
    4215             :                                 "keepalive", keepalive_fn,
    4216             :                                 sconn))) {
    4217           0 :                 DEBUG(0, ("Could not add keepalive event\n"));
    4218           0 :                 exit(1);
    4219             :         }
    4220             : 
    4221       27504 :         if (!(event_add_idle(ev_ctx, NULL,
    4222             :                              timeval_set(IDLE_CLOSED_TIMEOUT, 0),
    4223             :                              "deadtime", deadtime_fn, sconn))) {
    4224           0 :                 DEBUG(0, ("Could not add deadtime event\n"));
    4225           0 :                 exit(1);
    4226             :         }
    4227             : 
    4228       27504 :         if (!(event_add_idle(ev_ctx, NULL,
    4229             :                              timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
    4230             :                              "housekeeping", housekeeping_fn, sconn))) {
    4231           0 :                 DEBUG(0, ("Could not add housekeeping event\n"));
    4232           0 :                 exit(1);
    4233             :         }
    4234             : 
    4235       27504 :         smbprofile_dump_setup(ev_ctx);
    4236             : 
    4237       27504 :         if (!init_dptrs(sconn)) {
    4238           0 :                 exit_server("init_dptrs() failed");
    4239             :         }
    4240             : 
    4241       27504 :         TALLOC_FREE(trace_state.frame);
    4242             : 
    4243       27504 :         tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
    4244             :                                   &trace_state);
    4245             : 
    4246       27504 :         ret = tevent_loop_wait(ev_ctx);
    4247           0 :         if (ret != 0) {
    4248           0 :                 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
    4249             :                           " exiting\n", ret, strerror(errno)));
    4250             :         }
    4251             : 
    4252           0 :         TALLOC_FREE(trace_state.frame);
    4253             : 
    4254           0 :         exit_server_cleanly(NULL);
    4255             : }
    4256             : 
    4257      151513 : bool req_is_in_chain(const struct smb_request *req)
    4258             : {
    4259      151513 :         if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
    4260             :                 /*
    4261             :                  * We're right now handling a subsequent request, so we must
    4262             :                  * be in a chain
    4263             :                  */
    4264          32 :                 return true;
    4265             :         }
    4266             : 
    4267      151475 :         if (!smb1cli_is_andx_req(req->cmd)) {
    4268          32 :                 return false;
    4269             :         }
    4270             : 
    4271      151443 :         if (req->wct < 2) {
    4272             :                 /*
    4273             :                  * Okay, an illegal request, but definitely not chained :-)
    4274             :                  */
    4275           0 :                 return false;
    4276             :         }
    4277             : 
    4278      151443 :         return (CVAL(req->vwv+0, 0) != 0xFF);
    4279             : }

Generated by: LCOV version 1.13