source: src/router/samba36/source3/smbd/process.c @ 18464

Last change on this file since 18464 was 18464, checked in by BrainSlayer, 16 months ago

additional patch

File size: 84.1 KB
Line 
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/pcap.h"
31#include "system/select.h"
32#include "passdb.h"
33#include "auth.h"
34#include "messages.h"
35#include "smbprofile.h"
36#include "rpc_server/spoolss/srv_spoolss_nt.h"
37#include "libsmb/libsmb.h"
38
39extern bool global_machine_password_needs_changing;
40
41static void construct_reply_common(struct smb_request *req, const char *inbuf,
42                                   char *outbuf);
43static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
44
45static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
46{
47        bool ok;
48
49        if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
50                return true;
51        }
52
53        sconn->smb1.echo_handler.ref_count++;
54
55        if (sconn->smb1.echo_handler.ref_count > 1) {
56                return true;
57        }
58
59        DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
60
61        do {
62                ok = fcntl_lock(
63                        sconn->smb1.echo_handler.socket_lock_fd,
64                        SMB_F_SETLKW, 0, 0, F_WRLCK);
65        } while (!ok && (errno == EINTR));
66
67        if (!ok) {
68                DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
69                return false;
70        }
71
72        DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
73
74        return true;
75}
76
77void smbd_lock_socket(struct smbd_server_connection *sconn)
78{
79        if (!smbd_lock_socket_internal(sconn)) {
80                exit_server_cleanly("failed to lock socket");
81        }
82}
83
84static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
85{
86        bool ok;
87
88        if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
89                return true;
90        }
91
92        sconn->smb1.echo_handler.ref_count--;
93
94        if (sconn->smb1.echo_handler.ref_count > 0) {
95                return true;
96        }
97
98        do {
99                ok = fcntl_lock(
100                        sconn->smb1.echo_handler.socket_lock_fd,
101                        SMB_F_SETLKW, 0, 0, F_UNLCK);
102        } while (!ok && (errno == EINTR));
103
104        if (!ok) {
105                DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
106                return false;
107        }
108
109        DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
110
111        return true;
112}
113
114void smbd_unlock_socket(struct smbd_server_connection *sconn)
115{
116        if (!smbd_unlock_socket_internal(sconn)) {
117                exit_server_cleanly("failed to unlock socket");
118        }
119}
120
121/* Accessor function for smb_read_error for smbd functions. */
122
123/****************************************************************************
124 Send an smb to a fd.
125****************************************************************************/
126
127bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
128                  bool do_signing, uint32_t seqnum,
129                  bool do_encrypt,
130                  struct smb_perfcount_data *pcd)
131{
132        size_t len = 0;
133        size_t nwritten=0;
134        ssize_t ret;
135        char *buf_out = buffer;
136
137        smbd_lock_socket(sconn);
138
139        if (do_signing) {
140                /* Sign the outgoing packet if required. */
141                srv_calculate_sign_mac(sconn, buf_out, seqnum);
142        }
143
144        if (do_encrypt) {
145                NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
146                if (!NT_STATUS_IS_OK(status)) {
147                        DEBUG(0, ("send_smb: SMB encryption failed "
148                                "on outgoing packet! Error %s\n",
149                                nt_errstr(status) ));
150                        goto out;
151                }
152        }
153
154        len = smb_len(buf_out) + 4;
155
156        ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
157        if (ret <= 0) {
158
159                char addr[INET6_ADDRSTRLEN];
160                /*
161                 * Try and give an error message saying what
162                 * client failed.
163                 */
164                DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
165                         (int)sys_getpid(), (int)len,
166                         get_peer_addr(sconn->sock, addr, sizeof(addr)),
167                         (int)ret, strerror(errno) ));
168
169                srv_free_enc_buffer(buf_out);
170                goto out;
171        }
172
173        SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
174        srv_free_enc_buffer(buf_out);
175out:
176        SMB_PERFCOUNT_END(pcd);
177
178        smbd_unlock_socket(sconn);
179        return true;
180}
181
182/*******************************************************************
183 Setup the word count and byte count for a smb message.
184********************************************************************/
185
186int srv_set_message(char *buf,
187                        int num_words,
188                        int num_bytes,
189                        bool zero)
190{
191        if (zero && (num_words || num_bytes)) {
192                memset(buf + smb_size,'\0',num_words*2 + num_bytes);
193        }
194        SCVAL(buf,smb_wct,num_words);
195        SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
196        smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
197        return (smb_size + num_words*2 + num_bytes);
198}
199
200static bool valid_smb_header(const uint8_t *inbuf)
201{
202        if (is_encrypted_packet(inbuf)) {
203                return true;
204        }
205        /*
206         * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
207         * but it just looks weird to call strncmp for this one.
208         */
209        return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
210}
211
212/* Socket functions for smbd packet processing. */
213
214static bool valid_packet_size(size_t len)
215{
216        /*
217         * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
218         * of header. Don't print the error if this fits.... JRA.
219         */
220
221        if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
222                DEBUG(0,("Invalid packet length! (%lu bytes).\n",
223                                        (unsigned long)len));
224                return false;
225        }
226        return true;
227}
228
229static NTSTATUS read_packet_remainder(int fd, char *buffer,
230                                      unsigned int timeout, ssize_t len)
231{
232        NTSTATUS status;
233
234        if (len <= 0) {
235                return NT_STATUS_OK;
236        }
237
238        status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
239        if (!NT_STATUS_IS_OK(status)) {
240                char addr[INET6_ADDRSTRLEN];
241                DEBUG(0, ("read_fd_with_timeout failed for client %s read "
242                          "error = %s.\n",
243                          get_peer_addr(fd, addr, sizeof(addr)),
244                          nt_errstr(status)));
245        }
246        return status;
247}
248
249/****************************************************************************
250 Attempt a zerocopy writeX read. We know here that len > smb_size-4
251****************************************************************************/
252
253/*
254 * Unfortunately, earlier versions of smbclient/libsmbclient
255 * don't send this "standard" writeX header. I've fixed this
256 * for 3.2 but we'll use the old method with earlier versions.
257 * Windows and CIFSFS at least use this standard size. Not
258 * sure about MacOSX.
259 */
260
261#define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
262                                (2*14) + /* word count (including bcc) */ \
263                                1 /* pad byte */)
264
265static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
266                                                    const char lenbuf[4],
267                                                    struct smbd_server_connection *sconn,
268                                                    int sock,
269                                                    char **buffer,
270                                                    unsigned int timeout,
271                                                    size_t *p_unread,
272                                                    size_t *len_ret)
273{
274        /* Size of a WRITEX call (+4 byte len). */
275        char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
276        ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
277        ssize_t toread;
278        NTSTATUS status;
279
280        memcpy(writeX_header, lenbuf, 4);
281
282        status = read_fd_with_timeout(
283                sock, writeX_header + 4,
284                STANDARD_WRITE_AND_X_HEADER_SIZE,
285                STANDARD_WRITE_AND_X_HEADER_SIZE,
286                timeout, NULL);
287
288        if (!NT_STATUS_IS_OK(status)) {
289                DEBUG(0, ("read_fd_with_timeout failed for client %s read "
290                          "error = %s.\n", sconn->client_id.addr,
291                          nt_errstr(status)));
292                return status;
293        }
294
295        /*
296         * Ok - now try and see if this is a possible
297         * valid writeX call.
298         */
299
300        if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
301                /*
302                 * If the data offset is beyond what
303                 * we've read, drain the extra bytes.
304                 */
305                uint16_t doff = SVAL(writeX_header,smb_vwv11);
306                ssize_t newlen;
307
308                if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
309                        size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
310                        if (drain_socket(sock, drain) != drain) {
311                                smb_panic("receive_smb_raw_talloc_partial_read:"
312                                        " failed to drain pending bytes");
313                        }
314                } else {
315                        doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
316                }
317
318                /* Spoof down the length and null out the bcc. */
319                set_message_bcc(writeX_header, 0);
320                newlen = smb_len(writeX_header);
321
322                /* Copy the header we've written. */
323
324                *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
325                                writeX_header,
326                                sizeof(writeX_header));
327
328                if (*buffer == NULL) {
329                        DEBUG(0, ("Could not allocate inbuf of length %d\n",
330                                  (int)sizeof(writeX_header)));
331                        return NT_STATUS_NO_MEMORY;
332                }
333
334                /* Work out the remaining bytes. */
335                *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
336                *len_ret = newlen + 4;
337                return NT_STATUS_OK;
338        }
339
340        if (!valid_packet_size(len)) {
341                return NT_STATUS_INVALID_PARAMETER;
342        }
343
344        /*
345         * Not a valid writeX call. Just do the standard
346         * talloc and return.
347         */
348
349        *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
350
351        if (*buffer == NULL) {
352                DEBUG(0, ("Could not allocate inbuf of length %d\n",
353                          (int)len+4));
354                return NT_STATUS_NO_MEMORY;
355        }
356
357        /* Copy in what we already read. */
358        memcpy(*buffer,
359                writeX_header,
360                4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
361        toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
362
363        if(toread > 0) {
364                status = read_packet_remainder(
365                        sock,
366                        (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
367                        timeout, toread);
368
369                if (!NT_STATUS_IS_OK(status)) {
370                        DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
371                                   nt_errstr(status)));
372                        return status;
373                }
374        }
375
376        *len_ret = len + 4;
377        return NT_STATUS_OK;
378}
379
380static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
381                                       struct smbd_server_connection *sconn,
382                                       int sock,
383                                       char **buffer, unsigned int timeout,
384                                       size_t *p_unread, size_t *plen)
385{
386        char lenbuf[4];
387        size_t len;
388        int min_recv_size = lp_min_receive_file_size();
389        NTSTATUS status;
390
391        *p_unread = 0;
392
393        status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
394                                                  &len);
395        if (!NT_STATUS_IS_OK(status)) {
396                return status;
397        }
398
399        if (CVAL(lenbuf,0) == 0 && min_recv_size &&
400            (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
401                (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
402            !srv_is_signing_active(sconn) &&
403            sconn->smb1.echo_handler.trusted_fde == NULL) {
404
405                return receive_smb_raw_talloc_partial_read(
406                        mem_ctx, lenbuf, sconn, sock, buffer, timeout,
407                        p_unread, plen);
408        }
409
410        if (!valid_packet_size(len)) {
411                return NT_STATUS_INVALID_PARAMETER;
412        }
413
414        /*
415         * The +4 here can't wrap, we've checked the length above already.
416         */
417
418        *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
419
420        if (*buffer == NULL) {
421                DEBUG(0, ("Could not allocate inbuf of length %d\n",
422                          (int)len+4));
423                return NT_STATUS_NO_MEMORY;
424        }
425
426        memcpy(*buffer, lenbuf, sizeof(lenbuf));
427
428        status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
429        if (!NT_STATUS_IS_OK(status)) {
430                return status;
431        }
432
433        *plen = len + 4;
434        return NT_STATUS_OK;
435}
436
437static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
438                                   struct smbd_server_connection *sconn,
439                                   int sock,
440                                   char **buffer, unsigned int timeout,
441                                   size_t *p_unread, bool *p_encrypted,
442                                   size_t *p_len,
443                                   uint32_t *seqnum,
444                                   bool trusted_channel)
445{
446        size_t len = 0;
447        NTSTATUS status;
448
449        *p_encrypted = false;
450
451        status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
452                                        p_unread, &len);
453        if (!NT_STATUS_IS_OK(status)) {
454                DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
455                      ("receive_smb_raw_talloc failed for client %s "
456                       "read error = %s.\n",
457                       sconn->client_id.addr, nt_errstr(status)));
458                return status;
459        }
460
461        if (is_encrypted_packet((uint8_t *)*buffer)) {
462                status = srv_decrypt_buffer(*buffer);
463                if (!NT_STATUS_IS_OK(status)) {
464                        DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
465                                "incoming packet! Error %s\n",
466                                nt_errstr(status) ));
467                        return status;
468                }
469                *p_encrypted = true;
470        }
471
472        /* Check the incoming SMB signature. */
473        if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
474                DEBUG(0, ("receive_smb: SMB Signature verification failed on "
475                          "incoming packet!\n"));
476                return NT_STATUS_INVALID_NETWORK_RESPONSE;
477        }
478
479        *p_len = len;
480        return NT_STATUS_OK;
481}
482
483/*
484 * Initialize a struct smb_request from an inbuf
485 */
486
487static bool init_smb_request(struct smb_request *req,
488                             struct smbd_server_connection *sconn,
489                             const uint8 *inbuf,
490                             size_t unread_bytes, bool encrypted,
491                             uint32_t seqnum)
492{
493        size_t req_size = smb_len(inbuf) + 4;
494        /* Ensure we have at least smb_size bytes. */
495        if (req_size < smb_size) {
496                DEBUG(0,("init_smb_request: invalid request size %u\n",
497                        (unsigned int)req_size ));
498                return false;
499        }
500        req->cmd    = CVAL(inbuf, smb_com);
501        req->flags2 = SVAL(inbuf, smb_flg2);
502        req->smbpid = SVAL(inbuf, smb_pid);
503        req->mid    = (uint64_t)SVAL(inbuf, smb_mid);
504        req->seqnum = seqnum;
505        req->vuid   = SVAL(inbuf, smb_uid);
506        req->tid    = SVAL(inbuf, smb_tid);
507        req->wct    = CVAL(inbuf, smb_wct);
508        req->vwv    = (uint16_t *)(inbuf+smb_vwv);
509        req->buflen = smb_buflen(inbuf);
510        req->buf    = (const uint8_t *)smb_buf(inbuf);
511        req->unread_bytes = unread_bytes;
512        req->encrypted = encrypted;
513        req->sconn = sconn;
514        req->conn = conn_find(sconn,req->tid);
515        req->chain_fsp = NULL;
516        req->chain_outbuf = NULL;
517        req->done = false;
518        req->smb2req = NULL;
519        smb_init_perfcount_data(&req->pcd);
520
521        /* Ensure we have at least wct words and 2 bytes of bcc. */
522        if (smb_size + req->wct*2 > req_size) {
523                DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
524                        (unsigned int)req->wct,
525                        (unsigned int)req_size));
526                return false;
527        }
528        /* Ensure bcc is correct. */
529        if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
530                DEBUG(0,("init_smb_request: invalid bcc number %u "
531                        "(wct = %u, size %u)\n",
532                        (unsigned int)req->buflen,
533                        (unsigned int)req->wct,
534                        (unsigned int)req_size));
535                return false;
536        }
537
538        req->outbuf = NULL;
539        return true;
540}
541
542static void process_smb(struct smbd_server_connection *conn,
543                        uint8_t *inbuf, size_t nread, size_t unread_bytes,
544                        uint32_t seqnum, bool encrypted,
545                        struct smb_perfcount_data *deferred_pcd);
546
547static void smbd_deferred_open_timer(struct event_context *ev,
548                                     struct timed_event *te,
549                                     struct timeval _tval,
550                                     void *private_data)
551{
552        struct pending_message_list *msg = talloc_get_type(private_data,
553                                           struct pending_message_list);
554        TALLOC_CTX *mem_ctx = talloc_tos();
555        uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
556        uint8_t *inbuf;
557
558        inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
559                                         msg->buf.length);
560        if (inbuf == NULL) {
561                exit_server("smbd_deferred_open_timer: talloc failed\n");
562                return;
563        }
564
565        /* We leave this message on the queue so the open code can
566           know this is a retry. */
567        DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
568                (unsigned long long)mid ));
569
570        /* Mark the message as processed so this is not
571         * re-processed in error. */
572        msg->processed = true;
573
574        process_smb(smbd_server_conn, inbuf,
575                    msg->buf.length, 0,
576                    msg->seqnum, msg->encrypted, &msg->pcd);
577
578        /* If it's still there and was processed, remove it. */
579        msg = get_deferred_open_message_smb(mid);
580        if (msg && msg->processed) {
581                remove_deferred_open_message_smb(mid);
582        }
583}
584
585/****************************************************************************
586 Function to push a message onto the tail of a linked list of smb messages ready
587 for processing.
588****************************************************************************/
589
590static bool push_queued_message(struct smb_request *req,
591                                struct timeval request_time,
592                                struct timeval end_time,
593                                char *private_data, size_t private_len)
594{
595        int msg_len = smb_len(req->inbuf) + 4;
596        struct pending_message_list *msg;
597
598        msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
599
600        if(msg == NULL) {
601                DEBUG(0,("push_message: malloc fail (1)\n"));
602                return False;
603        }
604
605        msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
606        if(msg->buf.data == NULL) {
607                DEBUG(0,("push_message: malloc fail (2)\n"));
608                TALLOC_FREE(msg);
609                return False;
610        }
611
612        msg->request_time = request_time;
613        msg->seqnum = req->seqnum;
614        msg->encrypted = req->encrypted;
615        msg->processed = false;
616        SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
617
618        if (private_data) {
619                msg->private_data = data_blob_talloc(msg, private_data,
620                                                     private_len);
621                if (msg->private_data.data == NULL) {
622                        DEBUG(0,("push_message: malloc fail (3)\n"));
623                        TALLOC_FREE(msg);
624                        return False;
625                }
626        }
627
628        msg->te = event_add_timed(smbd_event_context(),
629                                  msg,
630                                  end_time,
631                                  smbd_deferred_open_timer,
632                                  msg);
633        if (!msg->te) {
634                DEBUG(0,("push_message: event_add_timed failed\n"));
635                TALLOC_FREE(msg);
636                return false;
637        }
638
639        DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
640
641        DEBUG(10,("push_message: pushed message length %u on "
642                  "deferred_open_queue\n", (unsigned int)msg_len));
643
644        return True;
645}
646
647/****************************************************************************
648 Function to delete a sharing violation open message by mid.
649****************************************************************************/
650
651void remove_deferred_open_message_smb(uint64_t mid)
652{
653        struct pending_message_list *pml;
654
655        if (smbd_server_conn->using_smb2) {
656                remove_deferred_open_message_smb2(smbd_server_conn, mid);
657                return;
658        }
659
660        for (pml = deferred_open_queue; pml; pml = pml->next) {
661                if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
662                        DEBUG(10,("remove_deferred_open_message_smb: "
663                                  "deleting mid %llu len %u\n",
664                                  (unsigned long long)mid,
665                                  (unsigned int)pml->buf.length ));
666                        DLIST_REMOVE(deferred_open_queue, pml);
667                        TALLOC_FREE(pml);
668                        return;
669                }
670        }
671}
672
673/****************************************************************************
674 Move a sharing violation open retry message to the front of the list and
675 schedule it for immediate processing.
676****************************************************************************/
677
678void schedule_deferred_open_message_smb(uint64_t mid)
679{
680        struct pending_message_list *pml;
681        int i = 0;
682
683        if (smbd_server_conn->using_smb2) {
684                schedule_deferred_open_message_smb2(smbd_server_conn, mid);
685                return;
686        }
687
688        for (pml = deferred_open_queue; pml; pml = pml->next) {
689                uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
690
691                DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
692                        "msg_mid = %llu\n",
693                        i++,
694                        (unsigned long long)msg_mid ));
695
696                if (mid == msg_mid) {
697                        struct timed_event *te;
698
699                        if (pml->processed) {
700                                /* A processed message should not be
701                                 * rescheduled. */
702                                DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
703                                        "message mid %llu was already processed\n",
704                                        (unsigned long long)msg_mid ));
705                                continue;
706                        }
707
708                        DEBUG(10,("schedule_deferred_open_message_smb: "
709                                "scheduling mid %llu\n",
710                                (unsigned long long)mid ));
711
712                        te = event_add_timed(smbd_event_context(),
713                                             pml,
714                                             timeval_zero(),
715                                             smbd_deferred_open_timer,
716                                             pml);
717                        if (!te) {
718                                DEBUG(10,("schedule_deferred_open_message_smb: "
719                                        "event_add_timed() failed, "
720                                        "skipping mid %llu\n",
721                                        (unsigned long long)msg_mid ));
722                        }
723
724                        TALLOC_FREE(pml->te);
725                        pml->te = te;
726                        DLIST_PROMOTE(deferred_open_queue, pml);
727                        return;
728                }
729        }
730
731        DEBUG(10,("schedule_deferred_open_message_smb: failed to "
732                "find message mid %llu\n",
733                (unsigned long long)mid ));
734}
735
736/****************************************************************************
737 Return true if this mid is on the deferred queue and was not yet processed.
738****************************************************************************/
739
740bool open_was_deferred(uint64_t mid)
741{
742        struct pending_message_list *pml;
743
744        if (smbd_server_conn->using_smb2) {
745                return open_was_deferred_smb2(smbd_server_conn, mid);
746        }
747
748        for (pml = deferred_open_queue; pml; pml = pml->next) {
749                if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
750                        return True;
751                }
752        }
753        return False;
754}
755
756/****************************************************************************
757 Return the message queued by this mid.
758****************************************************************************/
759
760static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
761{
762        struct pending_message_list *pml;
763
764        for (pml = deferred_open_queue; pml; pml = pml->next) {
765                if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
766                        return pml;
767                }
768        }
769        return NULL;
770}
771
772/****************************************************************************
773 Get the state data queued by this mid.
774****************************************************************************/
775
776bool get_deferred_open_message_state(struct smb_request *smbreq,
777                                struct timeval *p_request_time,
778                                void **pp_state)
779{
780        struct pending_message_list *pml;
781
782        if (smbd_server_conn->using_smb2) {
783                return get_deferred_open_message_state_smb2(smbreq->smb2req,
784                                        p_request_time,
785                                        pp_state);
786        }
787
788        pml = get_deferred_open_message_smb(smbreq->mid);
789        if (!pml) {
790                return false;
791        }
792        if (p_request_time) {
793                *p_request_time = pml->request_time;
794        }
795        if (pp_state) {
796                *pp_state = (void *)pml->private_data.data;
797        }
798        return true;
799}
800
801/****************************************************************************
802 Function to push a deferred open smb message onto a linked list of local smb
803 messages ready for processing.
804****************************************************************************/
805
806bool push_deferred_open_message_smb(struct smb_request *req,
807                               struct timeval request_time,
808                               struct timeval timeout,
809                               struct file_id id,
810                               char *private_data, size_t priv_len)
811{
812        struct timeval end_time;
813
814        if (req->smb2req) {
815                return push_deferred_open_message_smb2(req->smb2req,
816                                                request_time,
817                                                timeout,
818                                                id,
819                                                private_data,
820                                                priv_len);
821        }
822
823        if (req->unread_bytes) {
824                DEBUG(0,("push_deferred_open_message_smb: logic error ! "
825                        "unread_bytes = %u\n",
826                        (unsigned int)req->unread_bytes ));
827                smb_panic("push_deferred_open_message_smb: "
828                        "logic error unread_bytes != 0" );
829        }
830
831        end_time = timeval_sum(&request_time, &timeout);
832
833        DEBUG(10,("push_deferred_open_message_smb: pushing message "
834                "len %u mid %llu timeout time [%u.%06u]\n",
835                (unsigned int) smb_len(req->inbuf)+4,
836                (unsigned long long)req->mid,
837                (unsigned int)end_time.tv_sec,
838                (unsigned int)end_time.tv_usec));
839
840        return push_queued_message(req, request_time, end_time,
841                                   private_data, priv_len);
842}
843
844struct idle_event {
845        struct timed_event *te;
846        struct timeval interval;
847        char *name;
848        bool (*handler)(const struct timeval *now, void *private_data);
849        void *private_data;
850};
851
852static void smbd_idle_event_handler(struct event_context *ctx,
853                                    struct timed_event *te,
854                                    struct timeval now,
855                                    void *private_data)
856{
857        struct idle_event *event =
858                talloc_get_type_abort(private_data, struct idle_event);
859
860        TALLOC_FREE(event->te);
861
862        DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
863                  event->name, event->te));
864
865        if (!event->handler(&now, event->private_data)) {
866                DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
867                          event->name, event->te));
868                /* Don't repeat, delete ourselves */
869                TALLOC_FREE(event);
870                return;
871        }
872
873        DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
874                  event->name, event->te));
875
876        event->te = event_add_timed(ctx, event,
877                                    timeval_sum(&now, &event->interval),
878                                    smbd_idle_event_handler, event);
879
880        /* We can't do much but fail here. */
881        SMB_ASSERT(event->te != NULL);
882}
883
884struct idle_event *event_add_idle(struct event_context *event_ctx,
885                                  TALLOC_CTX *mem_ctx,
886                                  struct timeval interval,
887                                  const char *name,
888                                  bool (*handler)(const struct timeval *now,
889                                                  void *private_data),
890                                  void *private_data)
891{
892        struct idle_event *result;
893        struct timeval now = timeval_current();
894
895        result = TALLOC_P(mem_ctx, struct idle_event);
896        if (result == NULL) {
897                DEBUG(0, ("talloc failed\n"));
898                return NULL;
899        }
900
901        result->interval = interval;
902        result->handler = handler;
903        result->private_data = private_data;
904
905        if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
906                DEBUG(0, ("talloc failed\n"));
907                TALLOC_FREE(result);
908                return NULL;
909        }
910
911        result->te = event_add_timed(event_ctx, result,
912                                     timeval_sum(&now, &interval),
913                                     smbd_idle_event_handler, result);
914        if (result->te == NULL) {
915                DEBUG(0, ("event_add_timed failed\n"));
916                TALLOC_FREE(result);
917                return NULL;
918        }
919
920        DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
921        return result;
922}
923
924static void smbd_sig_term_handler(struct tevent_context *ev,
925                                  struct tevent_signal *se,
926                                  int signum,
927                                  int count,
928                                  void *siginfo,
929                                  void *private_data)
930{
931        exit_server_cleanly("termination signal");
932}
933
934void smbd_setup_sig_term_handler(void)
935{
936        struct tevent_signal *se;
937
938        se = tevent_add_signal(smbd_event_context(),
939                               smbd_event_context(),
940                               SIGTERM, 0,
941                               smbd_sig_term_handler,
942                               NULL);
943        if (!se) {
944                exit_server("failed to setup SIGTERM handler");
945        }
946}
947
948static void smbd_sig_hup_handler(struct tevent_context *ev,
949                                  struct tevent_signal *se,
950                                  int signum,
951                                  int count,
952                                  void *siginfo,
953                                  void *private_data)
954{
955        struct messaging_context *msg_ctx = talloc_get_type_abort(
956                private_data, struct messaging_context);
957        change_to_root_user();
958        DEBUG(1,("Reloading services after SIGHUP\n"));
959        reload_services(msg_ctx, smbd_server_conn->sock, False);
960        if (am_parent) {
961                pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
962        }
963}
964
965void smbd_setup_sig_hup_handler(struct tevent_context *ev,
966                                struct messaging_context *msg_ctx)
967{
968        struct tevent_signal *se;
969
970        se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
971                               msg_ctx);
972        if (!se) {
973                exit_server("failed to setup SIGHUP handler");
974        }
975}
976
977static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
978{
979        int timeout;
980        int num_pfds = 0;
981        int ret;
982        bool retry;
983
984        timeout = SMBD_SELECT_TIMEOUT * 1000;
985
986        /*
987         * Are there any timed events waiting ? If so, ensure we don't
988         * select for longer than it would take to wait for them.
989         */
990
991        event_add_to_poll_args(smbd_event_context(), conn,
992                               &conn->pfds, &num_pfds, &timeout);
993
994        /* Process a signal and timed events now... */
995        if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
996                return NT_STATUS_RETRY;
997        }
998
999        {
1000                int sav;
1001                START_PROFILE(smbd_idle);
1002
1003                ret = sys_poll(conn->pfds, num_pfds, timeout);
1004                sav = errno;
1005
1006                END_PROFILE(smbd_idle);
1007                errno = sav;
1008        }
1009
1010        if (ret == -1) {
1011                if (errno == EINTR) {
1012                        return NT_STATUS_RETRY;
1013                }
1014                return map_nt_error_from_unix(errno);
1015        }
1016
1017        retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1018                                num_pfds);
1019        if (retry) {
1020                return NT_STATUS_RETRY;
1021        }
1022
1023        /* Did we timeout ? */
1024        if (ret == 0) {
1025                return NT_STATUS_RETRY;
1026        }
1027
1028        /* should not be reached */
1029        return NT_STATUS_INTERNAL_ERROR;
1030}
1031
1032/*
1033 * Only allow 5 outstanding trans requests. We're allocating memory, so
1034 * prevent a DoS.
1035 */
1036
1037NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1038{
1039        int count = 0;
1040        for (; list != NULL; list = list->next) {
1041
1042                if (list->mid == mid) {
1043                        return NT_STATUS_INVALID_PARAMETER;
1044                }
1045
1046                count += 1;
1047        }
1048        if (count > 5) {
1049                return NT_STATUS_INSUFFICIENT_RESOURCES;
1050        }
1051
1052        return NT_STATUS_OK;
1053}
1054
1055/*
1056These flags determine some of the permissions required to do an operation
1057
1058Note that I don't set NEED_WRITE on some write operations because they
1059are used by some brain-dead clients when printing, and I don't want to
1060force write permissions on print services.
1061*/
1062#define AS_USER (1<<0)
1063#define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1064#define TIME_INIT (1<<2)
1065#define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1066#define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1067#define DO_CHDIR (1<<6)
1068
1069/*
1070   define a list of possible SMB messages and their corresponding
1071   functions. Any message that has a NULL function is unimplemented -
1072   please feel free to contribute implementations!
1073*/
1074static const struct smb_message_struct {
1075        const char *name;
1076        void (*fn)(struct smb_request *req);
1077        int flags;
1078} smb_messages[256] = {
1079
1080/* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1081/* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1082/* 0x02 */ { "SMBopen",reply_open,AS_USER },
1083/* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1084/* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1085/* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1086/* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1087/* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1088/* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1089/* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1090/* 0x0a */ { "SMBread",reply_read,AS_USER},
1091/* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1092/* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1093/* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1094/* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1095/* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1096/* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1097/* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1098/* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1099/* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1100/* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1101/* 0x15 */ { NULL, NULL, 0 },
1102/* 0x16 */ { NULL, NULL, 0 },
1103/* 0x17 */ { NULL, NULL, 0 },
1104/* 0x18 */ { NULL, NULL, 0 },
1105/* 0x19 */ { NULL, NULL, 0 },
1106/* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1107/* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1108/* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1109/* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1110/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1111/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1112/* 0x20 */ { "SMBwritec", NULL,0},
1113/* 0x21 */ { NULL, NULL, 0 },
1114/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1115/* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1116/* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1117/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1118/* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1119/* 0x27 */ { "SMBioctl",reply_ioctl,0},
1120/* 0x28 */ { "SMBioctls", NULL,AS_USER},
1121/* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1122/* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1123/* 0x2b */ { "SMBecho",reply_echo,0},
1124/* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1125/* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1126/* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1127/* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1128/* 0x30 */ { NULL, NULL, 0 },
1129/* 0x31 */ { NULL, NULL, 0 },
1130/* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1131/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1132/* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1133/* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1134/* 0x36 */ { NULL, NULL, 0 },
1135/* 0x37 */ { NULL, NULL, 0 },
1136/* 0x38 */ { NULL, NULL, 0 },
1137/* 0x39 */ { NULL, NULL, 0 },
1138/* 0x3a */ { NULL, NULL, 0 },
1139/* 0x3b */ { NULL, NULL, 0 },
1140/* 0x3c */ { NULL, NULL, 0 },
1141/* 0x3d */ { NULL, NULL, 0 },
1142/* 0x3e */ { NULL, NULL, 0 },
1143/* 0x3f */ { NULL, NULL, 0 },
1144/* 0x40 */ { NULL, NULL, 0 },
1145/* 0x41 */ { NULL, NULL, 0 },
1146/* 0x42 */ { NULL, NULL, 0 },
1147/* 0x43 */ { NULL, NULL, 0 },
1148/* 0x44 */ { NULL, NULL, 0 },
1149/* 0x45 */ { NULL, NULL, 0 },
1150/* 0x46 */ { NULL, NULL, 0 },
1151/* 0x47 */ { NULL, NULL, 0 },
1152/* 0x48 */ { NULL, NULL, 0 },
1153/* 0x49 */ { NULL, NULL, 0 },
1154/* 0x4a */ { NULL, NULL, 0 },
1155/* 0x4b */ { NULL, NULL, 0 },
1156/* 0x4c */ { NULL, NULL, 0 },
1157/* 0x4d */ { NULL, NULL, 0 },
1158/* 0x4e */ { NULL, NULL, 0 },
1159/* 0x4f */ { NULL, NULL, 0 },
1160/* 0x50 */ { NULL, NULL, 0 },
1161/* 0x51 */ { NULL, NULL, 0 },
1162/* 0x52 */ { NULL, NULL, 0 },
1163/* 0x53 */ { NULL, NULL, 0 },
1164/* 0x54 */ { NULL, NULL, 0 },
1165/* 0x55 */ { NULL, NULL, 0 },
1166/* 0x56 */ { NULL, NULL, 0 },
1167/* 0x57 */ { NULL, NULL, 0 },
1168/* 0x58 */ { NULL, NULL, 0 },
1169/* 0x59 */ { NULL, NULL, 0 },
1170/* 0x5a */ { NULL, NULL, 0 },
1171/* 0x5b */ { NULL, NULL, 0 },
1172/* 0x5c */ { NULL, NULL, 0 },
1173/* 0x5d */ { NULL, NULL, 0 },
1174/* 0x5e */ { NULL, NULL, 0 },
1175/* 0x5f */ { NULL, NULL, 0 },
1176/* 0x60 */ { NULL, NULL, 0 },
1177/* 0x61 */ { NULL, NULL, 0 },
1178/* 0x62 */ { NULL, NULL, 0 },
1179/* 0x63 */ { NULL, NULL, 0 },
1180/* 0x64 */ { NULL, NULL, 0 },
1181/* 0x65 */ { NULL, NULL, 0 },
1182/* 0x66 */ { NULL, NULL, 0 },
1183/* 0x67 */ { NULL, NULL, 0 },
1184/* 0x68 */ { NULL, NULL, 0 },
1185/* 0x69 */ { NULL, NULL, 0 },
1186/* 0x6a */ { NULL, NULL, 0 },
1187/* 0x6b */ { NULL, NULL, 0 },
1188/* 0x6c */ { NULL, NULL, 0 },
1189/* 0x6d */ { NULL, NULL, 0 },
1190/* 0x6e */ { NULL, NULL, 0 },
1191/* 0x6f */ { NULL, NULL, 0 },
1192/* 0x70 */ { "SMBtcon",reply_tcon,0},
1193/* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1194/* 0x72 */ { "SMBnegprot",reply_negprot,0},
1195/* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1196/* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1197/* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1198/* 0x76 */ { NULL, NULL, 0 },
1199/* 0x77 */ { NULL, NULL, 0 },
1200/* 0x78 */ { NULL, NULL, 0 },
1201/* 0x79 */ { NULL, NULL, 0 },
1202/* 0x7a */ { NULL, NULL, 0 },
1203/* 0x7b */ { NULL, NULL, 0 },
1204/* 0x7c */ { NULL, NULL, 0 },
1205/* 0x7d */ { NULL, NULL, 0 },
1206/* 0x7e */ { NULL, NULL, 0 },
1207/* 0x7f */ { NULL, NULL, 0 },
1208/* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1209/* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1210/* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1211/* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1212/* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1213/* 0x85 */ { NULL, NULL, 0 },
1214/* 0x86 */ { NULL, NULL, 0 },
1215/* 0x87 */ { NULL, NULL, 0 },
1216/* 0x88 */ { NULL, NULL, 0 },
1217/* 0x89 */ { NULL, NULL, 0 },
1218/* 0x8a */ { NULL, NULL, 0 },
1219/* 0x8b */ { NULL, NULL, 0 },
1220/* 0x8c */ { NULL, NULL, 0 },
1221/* 0x8d */ { NULL, NULL, 0 },
1222/* 0x8e */ { NULL, NULL, 0 },
1223/* 0x8f */ { NULL, NULL, 0 },
1224/* 0x90 */ { NULL, NULL, 0 },
1225/* 0x91 */ { NULL, NULL, 0 },
1226/* 0x92 */ { NULL, NULL, 0 },
1227/* 0x93 */ { NULL, NULL, 0 },
1228/* 0x94 */ { NULL, NULL, 0 },
1229/* 0x95 */ { NULL, NULL, 0 },
1230/* 0x96 */ { NULL, NULL, 0 },
1231/* 0x97 */ { NULL, NULL, 0 },
1232/* 0x98 */ { NULL, NULL, 0 },
1233/* 0x99 */ { NULL, NULL, 0 },
1234/* 0x9a */ { NULL, NULL, 0 },
1235/* 0x9b */ { NULL, NULL, 0 },
1236/* 0x9c */ { NULL, NULL, 0 },
1237/* 0x9d */ { NULL, NULL, 0 },
1238/* 0x9e */ { NULL, NULL, 0 },
1239/* 0x9f */ { NULL, NULL, 0 },
1240/* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1241/* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1242/* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1243/* 0xa3 */ { NULL, NULL, 0 },
1244/* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1245/* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1246/* 0xa6 */ { NULL, NULL, 0 },
1247/* 0xa7 */ { NULL, NULL, 0 },
1248/* 0xa8 */ { NULL, NULL, 0 },
1249/* 0xa9 */ { NULL, NULL, 0 },
1250/* 0xaa */ { NULL, NULL, 0 },
1251/* 0xab */ { NULL, NULL, 0 },
1252/* 0xac */ { NULL, NULL, 0 },
1253/* 0xad */ { NULL, NULL, 0 },
1254/* 0xae */ { NULL, NULL, 0 },
1255/* 0xaf */ { NULL, NULL, 0 },
1256/* 0xb0 */ { NULL, NULL, 0 },
1257/* 0xb1 */ { NULL, NULL, 0 },
1258/* 0xb2 */ { NULL, NULL, 0 },
1259/* 0xb3 */ { NULL, NULL, 0 },
1260/* 0xb4 */ { NULL, NULL, 0 },
1261/* 0xb5 */ { NULL, NULL, 0 },
1262/* 0xb6 */ { NULL, NULL, 0 },
1263/* 0xb7 */ { NULL, NULL, 0 },
1264/* 0xb8 */ { NULL, NULL, 0 },
1265/* 0xb9 */ { NULL, NULL, 0 },
1266/* 0xba */ { NULL, NULL, 0 },
1267/* 0xbb */ { NULL, NULL, 0 },
1268/* 0xbc */ { NULL, NULL, 0 },
1269/* 0xbd */ { NULL, NULL, 0 },
1270/* 0xbe */ { NULL, NULL, 0 },
1271/* 0xbf */ { NULL, NULL, 0 },
1272/* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1273/* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1274/* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1275/* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1276/* 0xc4 */ { NULL, NULL, 0 },
1277/* 0xc5 */ { NULL, NULL, 0 },
1278/* 0xc6 */ { NULL, NULL, 0 },
1279/* 0xc7 */ { NULL, NULL, 0 },
1280/* 0xc8 */ { NULL, NULL, 0 },
1281/* 0xc9 */ { NULL, NULL, 0 },
1282/* 0xca */ { NULL, NULL, 0 },
1283/* 0xcb */ { NULL, NULL, 0 },
1284/* 0xcc */ { NULL, NULL, 0 },
1285/* 0xcd */ { NULL, NULL, 0 },
1286/* 0xce */ { NULL, NULL, 0 },
1287/* 0xcf */ { NULL, NULL, 0 },
1288/* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1289/* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1290/* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1291/* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1292/* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1293/* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1294/* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1295/* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1296/* 0xd8 */ { NULL, NULL, 0 },
1297/* 0xd9 */ { NULL, NULL, 0 },
1298/* 0xda */ { NULL, NULL, 0 },
1299/* 0xdb */ { NULL, NULL, 0 },
1300/* 0xdc */ { NULL, NULL, 0 },
1301/* 0xdd */ { NULL, NULL, 0 },
1302/* 0xde */ { NULL, NULL, 0 },
1303/* 0xdf */ { NULL, NULL, 0 },
1304/* 0xe0 */ { NULL, NULL, 0 },
1305/* 0xe1 */ { NULL, NULL, 0 },
1306/* 0xe2 */ { NULL, NULL, 0 },
1307/* 0xe3 */ { NULL, NULL, 0 },
1308/* 0xe4 */ { NULL, NULL, 0 },
1309/* 0xe5 */ { NULL, NULL, 0 },
1310/* 0xe6 */ { NULL, NULL, 0 },
1311/* 0xe7 */ { NULL, NULL, 0 },
1312/* 0xe8 */ { NULL, NULL, 0 },
1313/* 0xe9 */ { NULL, NULL, 0 },
1314/* 0xea */ { NULL, NULL, 0 },
1315/* 0xeb */ { NULL, NULL, 0 },
1316/* 0xec */ { NULL, NULL, 0 },
1317/* 0xed */ { NULL, NULL, 0 },
1318/* 0xee */ { NULL, NULL, 0 },
1319/* 0xef */ { NULL, NULL, 0 },
1320/* 0xf0 */ { NULL, NULL, 0 },
1321/* 0xf1 */ { NULL, NULL, 0 },
1322/* 0xf2 */ { NULL, NULL, 0 },
1323/* 0xf3 */ { NULL, NULL, 0 },
1324/* 0xf4 */ { NULL, NULL, 0 },
1325/* 0xf5 */ { NULL, NULL, 0 },
1326/* 0xf6 */ { NULL, NULL, 0 },
1327/* 0xf7 */ { NULL, NULL, 0 },
1328/* 0xf8 */ { NULL, NULL, 0 },
1329/* 0xf9 */ { NULL, NULL, 0 },
1330/* 0xfa */ { NULL, NULL, 0 },
1331/* 0xfb */ { NULL, NULL, 0 },
1332/* 0xfc */ { NULL, NULL, 0 },
1333/* 0xfd */ { NULL, NULL, 0 },
1334/* 0xfe */ { NULL, NULL, 0 },
1335/* 0xff */ { NULL, NULL, 0 }
1336
1337};
1338
1339/*******************************************************************
1340 allocate and initialize a reply packet
1341********************************************************************/
1342
1343static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1344                          const char *inbuf, char **outbuf, uint8_t num_words,
1345                          uint32_t num_bytes)
1346{
1347        /*
1348         * Protect against integer wrap
1349         */
1350        if ((num_bytes > 0xffffff)
1351            || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1352                char *msg;
1353                if (asprintf(&msg, "num_bytes too large: %u",
1354                             (unsigned)num_bytes) == -1) {
1355                        msg = CONST_DISCARD(char *, "num_bytes too large");
1356                }
1357                smb_panic(msg);
1358        }
1359
1360        *outbuf = TALLOC_ARRAY(mem_ctx, char,
1361                               smb_size + num_words*2 + num_bytes);
1362        if (*outbuf == NULL) {
1363                return false;
1364        }
1365
1366        construct_reply_common(req, inbuf, *outbuf);
1367        srv_set_message(*outbuf, num_words, num_bytes, false);
1368        /*
1369         * Zero out the word area, the caller has to take care of the bcc area
1370         * himself
1371         */
1372        if (num_words != 0) {
1373                memset(*outbuf + smb_vwv0, 0, num_words*2);
1374        }
1375
1376        return true;
1377}
1378
1379void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1380{
1381        char *outbuf;
1382        if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1383                           num_bytes)) {
1384                smb_panic("could not allocate output buffer\n");
1385        }
1386        req->outbuf = (uint8_t *)outbuf;
1387}
1388
1389
1390/*******************************************************************
1391 Dump a packet to a file.
1392********************************************************************/
1393
1394static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1395{
1396        int fd, i;
1397        char *fname = NULL;
1398        if (DEBUGLEVEL < 50) {
1399                return;
1400        }
1401
1402        if (len < 4) len = smb_len(data)+4;
1403        for (i=1;i<100;i++) {
1404                if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1405                             type ? "req" : "resp") == -1) {
1406                        return;
1407                }
1408                fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1409                if (fd != -1 || errno != EEXIST) break;
1410        }
1411        if (fd != -1) {
1412                ssize_t ret = write(fd, data, len);
1413                if (ret != len)
1414                        DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1415                close(fd);
1416                DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1417        }
1418        SAFE_FREE(fname);
1419}
1420
1421/****************************************************************************
1422 Prepare everything for calling the actual request function, and potentially
1423 call the request function via the "new" interface.
1424
1425 Return False if the "legacy" function needs to be called, everything is
1426 prepared.
1427
1428 Return True if we're done.
1429
1430 I know this API sucks, but it is the one with the least code change I could
1431 find.
1432****************************************************************************/
1433
1434static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1435{
1436        int flags;
1437        uint16 session_tag;
1438        connection_struct *conn = NULL;
1439        struct smbd_server_connection *sconn = req->sconn;
1440
1441        errno = 0;
1442
1443        /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1444         * so subtract 4 from it. */
1445        if ((size < (smb_size - 4)) ||
1446            !valid_smb_header(req->inbuf)) {
1447                DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1448                         smb_len(req->inbuf)));
1449                exit_server_cleanly("Non-SMB packet");
1450        }
1451
1452        if (smb_messages[type].fn == NULL) {
1453                DEBUG(0,("Unknown message type %d!\n",type));
1454                smb_dump("Unknown", 1, (char *)req->inbuf, size);
1455                reply_unknown_new(req, type);
1456                return NULL;
1457        }
1458
1459        flags = smb_messages[type].flags;
1460
1461        /* In share mode security we must ignore the vuid. */
1462        session_tag = (lp_security() == SEC_SHARE)
1463                ? UID_FIELD_INVALID : req->vuid;
1464        conn = req->conn;
1465
1466        DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1467                 (int)sys_getpid(), (unsigned long)conn));
1468
1469        smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1470
1471        /* Ensure this value is replaced in the incoming packet. */
1472        SSVAL(req->inbuf,smb_uid,session_tag);
1473
1474        /*
1475         * Ensure the correct username is in current_user_info.  This is a
1476         * really ugly bugfix for problems with multiple session_setup_and_X's
1477         * being done and allowing %U and %G substitutions to work correctly.
1478         * There is a reason this code is done here, don't move it unless you
1479         * know what you're doing... :-).
1480         * JRA.
1481         */
1482
1483        if (session_tag != sconn->smb1.sessions.last_session_tag) {
1484                user_struct *vuser = NULL;
1485
1486                sconn->smb1.sessions.last_session_tag = session_tag;
1487                if(session_tag != UID_FIELD_INVALID) {
1488                        vuser = get_valid_user_struct(sconn, session_tag);
1489                        if (vuser) {
1490                                set_current_user_info(
1491                                        vuser->session_info->sanitized_username,
1492                                        vuser->session_info->unix_name,
1493                                        vuser->session_info->info3->base.domain.string);
1494                        }
1495                }
1496        }
1497
1498        /* Does this call need to be run as the connected user? */
1499        if (flags & AS_USER) {
1500
1501                /* Does this call need a valid tree connection? */
1502                if (!conn) {
1503                        /*
1504                         * Amazingly, the error code depends on the command
1505                         * (from Samba4).
1506                         */
1507                        if (type == SMBntcreateX) {
1508                                reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1509                        } else {
1510                                reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1511                        }
1512                        return NULL;
1513                }
1514
1515                if (!change_to_user(conn,session_tag)) {
1516                        DEBUG(0, ("Error: Could not change to user. Removing "
1517                                "deferred open, mid=%llu.\n",
1518                                (unsigned long long)req->mid));
1519                        reply_force_doserror(req, ERRSRV, ERRbaduid);
1520                        return conn;
1521                }
1522
1523                /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1524
1525                /* Does it need write permission? */
1526                if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1527                        reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1528                        return conn;
1529                }
1530
1531                /* IPC services are limited */
1532                if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1533                        reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1534                        return conn;
1535                }
1536        } else {
1537                /* This call needs to be run as root */
1538                change_to_root_user();
1539        }
1540
1541        /* load service specific parameters */
1542        if (conn) {
1543                if (req->encrypted) {
1544                        conn->encrypted_tid = true;
1545                        /* encrypted required from now on. */
1546                        conn->encrypt_level = Required;
1547                } else if (ENCRYPTION_REQUIRED(conn)) {
1548                        if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1549                                exit_server_cleanly("encryption required "
1550                                        "on connection");
1551                                return conn;
1552                        }
1553                }
1554
1555                if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1556                                         (flags & (AS_USER|DO_CHDIR)
1557                                          ?True:False))) {
1558                        reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1559                        return conn;
1560                }
1561                conn->num_smb_operations++;
1562        }
1563
1564        /* does this protocol need to be run as guest? */
1565        if ((flags & AS_GUEST)
1566            && (!change_to_guest() ||
1567                !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1568                              sconn->client_id.name,
1569                              sconn->client_id.addr))) {
1570                reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1571                return conn;
1572        }
1573
1574        smb_messages[type].fn(req);
1575        return req->conn;
1576}
1577
1578/****************************************************************************
1579 Construct a reply to the incoming packet.
1580****************************************************************************/
1581
1582static void construct_reply(struct smbd_server_connection *sconn,
1583                            char *inbuf, int size, size_t unread_bytes,
1584                            uint32_t seqnum, bool encrypted,
1585                            struct smb_perfcount_data *deferred_pcd)
1586{
1587        connection_struct *conn;
1588        struct smb_request *req;
1589
1590        if (!(req = talloc(talloc_tos(), struct smb_request))) {
1591                smb_panic("could not allocate smb_request");
1592        }
1593
1594        if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1595                              encrypted, seqnum)) {
1596                exit_server_cleanly("Invalid SMB request");
1597        }
1598
1599        req->inbuf  = (uint8_t *)talloc_move(req, &inbuf);
1600
1601        /* we popped this message off the queue - keep original perf data */
1602        if (deferred_pcd)
1603                req->pcd = *deferred_pcd;
1604        else {
1605                SMB_PERFCOUNT_START(&req->pcd);
1606                SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1607                SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1608        }
1609
1610        conn = switch_message(req->cmd, req, size);
1611
1612        if (req->unread_bytes) {
1613                /* writeX failed. drain socket. */
1614                if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1615                                req->unread_bytes) {
1616                        smb_panic("failed to drain pending bytes");
1617                }
1618                req->unread_bytes = 0;
1619        }
1620
1621        if (req->done) {
1622                TALLOC_FREE(req);
1623                return;
1624        }
1625
1626        if (req->outbuf == NULL) {
1627                return;
1628        }
1629
1630        if (CVAL(req->outbuf,0) == 0) {
1631                show_msg((char *)req->outbuf);
1632        }
1633
1634        if (!srv_send_smb(req->sconn,
1635                        (char *)req->outbuf,
1636                        true, req->seqnum+1,
1637                        IS_CONN_ENCRYPTED(conn)||req->encrypted,
1638                        &req->pcd)) {
1639                exit_server_cleanly("construct_reply: srv_send_smb failed.");
1640        }
1641
1642        TALLOC_FREE(req);
1643
1644        return;
1645}
1646
1647/****************************************************************************
1648 Process an smb from the client
1649****************************************************************************/
1650static void process_smb(struct smbd_server_connection *sconn,
1651                        uint8_t *inbuf, size_t nread, size_t unread_bytes,
1652                        uint32_t seqnum, bool encrypted,
1653                        struct smb_perfcount_data *deferred_pcd)
1654{
1655        int msg_type = CVAL(inbuf,0);
1656
1657        DO_PROFILE_INC(smb_count);
1658
1659        DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1660                    smb_len(inbuf) ) );
1661        DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1662                  sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1663
1664        if (msg_type != 0) {
1665                /*
1666                 * NetBIOS session request, keepalive, etc.
1667                 */
1668                reply_special(sconn, (char *)inbuf, nread);
1669                goto done;
1670        }
1671
1672        if (sconn->using_smb2) {
1673                /* At this point we're not really using smb2,
1674                 * we make the decision here.. */
1675                if (smbd_is_smb2_header(inbuf, nread)) {
1676                        smbd_smb2_first_negprot(sconn, inbuf, nread);
1677                        return;
1678                } else if (nread >= smb_size && valid_smb_header(inbuf)
1679                                && CVAL(inbuf, smb_com) != 0x72) {
1680                        /* This is a non-negprot SMB1 packet.
1681                           Disable SMB2 from now on. */
1682                        sconn->using_smb2 = false;
1683                }
1684        }
1685
1686        show_msg((char *)inbuf);
1687
1688        construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1689                        encrypted, deferred_pcd);
1690        sconn->trans_num++;
1691
1692done:
1693        sconn->num_requests++;
1694
1695        /* The timeout_processing function isn't run nearly
1696           often enough to implement 'max log size' without
1697           overrunning the size of the file by many megabytes.
1698           This is especially true if we are running at debug
1699           level 10.  Checking every 50 SMBs is a nice
1700           tradeoff of performance vs log file size overrun. */
1701
1702        if ((sconn->num_requests % 50) == 0 &&
1703            need_to_check_log_size()) {
1704                change_to_root_user();
1705                check_log_size();
1706        }
1707}
1708
1709/****************************************************************************
1710 Return a string containing the function name of a SMB command.
1711****************************************************************************/
1712
1713const char *smb_fn_name(int type)
1714{
1715        const char *unknown_name = "SMBunknown";
1716
1717        if (smb_messages[type].name == NULL)
1718                return(unknown_name);
1719
1720        return(smb_messages[type].name);
1721}
1722
1723/****************************************************************************
1724 Helper functions for contruct_reply.
1725****************************************************************************/
1726
1727void add_to_common_flags2(uint32 v)
1728{
1729        common_flags2 |= v;
1730}
1731
1732void remove_from_common_flags2(uint32 v)
1733{
1734        common_flags2 &= ~v;
1735}
1736
1737static void construct_reply_common(struct smb_request *req, const char *inbuf,
1738                                   char *outbuf)
1739{
1740        srv_set_message(outbuf,0,0,false);
1741
1742        SCVAL(outbuf, smb_com, req->cmd);
1743        SIVAL(outbuf,smb_rcls,0);
1744        SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1745        SSVAL(outbuf,smb_flg2,
1746                (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1747                common_flags2);
1748        memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1749
1750        SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1751        SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1752        SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1753        SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1754}
1755
1756void construct_reply_common_req(struct smb_request *req, char *outbuf)
1757{
1758        construct_reply_common(req, (char *)req->inbuf, outbuf);
1759}
1760
1761/*
1762 * How many bytes have we already accumulated up to the current wct field
1763 * offset?
1764 */
1765
1766size_t req_wct_ofs(struct smb_request *req)
1767{
1768        size_t buf_size;
1769
1770        if (req->chain_outbuf == NULL) {
1771                return smb_wct - 4;
1772        }
1773        buf_size = talloc_get_size(req->chain_outbuf);
1774        if ((buf_size % 4) != 0) {
1775                buf_size += (4 - (buf_size % 4));
1776        }
1777        return buf_size - 4;
1778}
1779
1780/*
1781 * Hack around reply_nterror & friends not being aware of chained requests,
1782 * generating illegal (i.e. wct==0) chain replies.
1783 */
1784
1785static void fixup_chain_error_packet(struct smb_request *req)
1786{
1787        uint8_t *outbuf = req->outbuf;
1788        req->outbuf = NULL;
1789        reply_outbuf(req, 2, 0);
1790        memcpy(req->outbuf, outbuf, smb_wct);
1791        TALLOC_FREE(outbuf);
1792        SCVAL(req->outbuf, smb_vwv0, 0xff);
1793}
1794
1795/**
1796 * @brief Find the smb_cmd offset of the last command pushed
1797 * @param[in] buf       The buffer we're building up
1798 * @retval              Where can we put our next andx cmd?
1799 *
1800 * While chaining requests, the "next" request we're looking at needs to put
1801 * its SMB_Command before the data the previous request already built up added
1802 * to the chain. Find the offset to the place where we have to put our cmd.
1803 */
1804
1805static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1806{
1807        uint8_t cmd;
1808        size_t ofs;
1809
1810        cmd = CVAL(buf, smb_com);
1811
1812        SMB_ASSERT(is_andx_req(cmd));
1813
1814        ofs = smb_vwv0;
1815
1816        while (CVAL(buf, ofs) != 0xff) {
1817
1818                if (!is_andx_req(CVAL(buf, ofs))) {
1819                        return false;
1820                }
1821
1822                /*
1823                 * ofs is from start of smb header, so add the 4 length
1824                 * bytes. The next cmd is right after the wct field.
1825                 */
1826                ofs = SVAL(buf, ofs+2) + 4 + 1;
1827
1828                SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1829        }
1830
1831        *pofs = ofs;
1832        return true;
1833}
1834
1835/**
1836 * @brief Do the smb chaining at a buffer level
1837 * @param[in] poutbuf           Pointer to the talloc'ed buffer to be modified
1838 * @param[in] smb_command       The command that we want to issue
1839 * @param[in] wct               How many words?
1840 * @param[in] vwv               The words, already in network order
1841 * @param[in] bytes_alignment   How shall we align "bytes"?
1842 * @param[in] num_bytes         How many bytes?
1843 * @param[in] bytes             The data the request ships
1844 *
1845 * smb_splice_chain() adds the vwv and bytes to the request already present in
1846 * *poutbuf.
1847 */
1848
1849static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1850                             uint8_t wct, const uint16_t *vwv,
1851                             size_t bytes_alignment,
1852                             uint32_t num_bytes, const uint8_t *bytes)
1853{
1854        uint8_t *outbuf;
1855        size_t old_size, new_size;
1856        size_t ofs;
1857        size_t chain_padding = 0;
1858        size_t bytes_padding = 0;
1859        bool first_request;
1860
1861        old_size = talloc_get_size(*poutbuf);
1862
1863        /*
1864         * old_size == smb_wct means we're pushing the first request in for
1865         * libsmb/
1866         */
1867
1868        first_request = (old_size == smb_wct);
1869
1870        if (!first_request && ((old_size % 4) != 0)) {
1871                /*
1872                 * Align the wct field of subsequent requests to a 4-byte
1873                 * boundary
1874                 */
1875                chain_padding = 4 - (old_size % 4);
1876        }
1877
1878        /*
1879         * After the old request comes the new wct field (1 byte), the vwv's
1880         * and the num_bytes field. After at we might need to align the bytes
1881         * given to us to "bytes_alignment", increasing the num_bytes value.
1882         */
1883
1884        new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1885
1886        if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1887                bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1888        }
1889
1890        new_size += bytes_padding + num_bytes;
1891
1892        if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1893                DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1894                          (unsigned)new_size));
1895                return false;
1896        }
1897
1898        outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1899        if (outbuf == NULL) {
1900                DEBUG(0, ("talloc failed\n"));
1901                return false;
1902        }
1903        *poutbuf = outbuf;
1904
1905        if (first_request) {
1906                SCVAL(outbuf, smb_com, smb_command);
1907        } else {
1908                size_t andx_cmd_ofs;
1909
1910                if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1911                        DEBUG(1, ("invalid command chain\n"));
1912                        *poutbuf = TALLOC_REALLOC_ARRAY(
1913                                NULL, *poutbuf, uint8_t, old_size);
1914                        return false;
1915                }
1916
1917                if (chain_padding != 0) {
1918                        memset(outbuf + old_size, 0, chain_padding);
1919                        old_size += chain_padding;
1920                }
1921
1922                SCVAL(outbuf, andx_cmd_ofs, smb_command);
1923                SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1924        }
1925
1926        ofs = old_size;
1927
1928        /*
1929         * Push the chained request:
1930         *
1931         * wct field
1932         */
1933
1934        SCVAL(outbuf, ofs, wct);
1935        ofs += 1;
1936
1937        /*
1938         * vwv array
1939         */
1940
1941        memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1942        ofs += sizeof(uint16_t) * wct;
1943
1944        /*
1945         * bcc (byte count)
1946         */
1947
1948        SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1949        ofs += sizeof(uint16_t);
1950
1951        /*
1952         * padding
1953         */
1954
1955        if (bytes_padding != 0) {
1956                memset(outbuf + ofs, 0, bytes_padding);
1957                ofs += bytes_padding;
1958        }
1959
1960        /*
1961         * The bytes field
1962         */
1963
1964        memcpy(outbuf + ofs, bytes, num_bytes);
1965
1966        return true;
1967}
1968
1969/****************************************************************************
1970 Construct a chained reply and add it to the already made reply
1971****************************************************************************/
1972
1973void chain_reply(struct smb_request *req)
1974{
1975        size_t smblen = smb_len(req->inbuf);
1976        size_t already_used, length_needed;
1977        uint8_t chain_cmd;
1978        uint32_t chain_offset;  /* uint32_t to avoid overflow */
1979
1980        uint8_t wct;
1981        uint16_t *vwv;
1982        uint16_t buflen;
1983        uint8_t *buf;
1984
1985        if (IVAL(req->outbuf, smb_rcls) != 0) {
1986                fixup_chain_error_packet(req);
1987        }
1988
1989        /*
1990         * Any of the AndX requests and replies have at least a wct of
1991         * 2. vwv[0] is the next command, vwv[1] is the offset from the
1992         * beginning of the SMB header to the next wct field.
1993         *
1994         * None of the AndX requests put anything valuable in vwv[0] and [1],
1995         * so we can overwrite it here to form the chain.
1996         */
1997
1998        if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1999                if (req->chain_outbuf == NULL) {
2000                        req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2001                                req, req->outbuf, uint8_t,
2002                                smb_len(req->outbuf) + 4);
2003                        if (req->chain_outbuf == NULL) {
2004                                smb_panic("talloc failed");
2005                        }
2006                }
2007                req->outbuf = NULL;
2008                goto error;
2009        }
2010
2011        /*
2012         * Here we assume that this is the end of the chain. For that we need
2013         * to set "next command" to 0xff and the offset to 0. If we later find
2014         * more commands in the chain, this will be overwritten again.
2015         */
2016
2017        SCVAL(req->outbuf, smb_vwv0, 0xff);
2018        SCVAL(req->outbuf, smb_vwv0+1, 0);
2019        SSVAL(req->outbuf, smb_vwv1, 0);
2020
2021        if (req->chain_outbuf == NULL) {
2022                /*
2023                 * In req->chain_outbuf we collect all the replies. Start the
2024                 * chain by copying in the first reply.
2025                 *
2026                 * We do the realloc because later on we depend on
2027                 * talloc_get_size to determine the length of
2028                 * chain_outbuf. The reply_xxx routines might have
2029                 * over-allocated (reply_pipe_read_and_X used to be such an
2030                 * example).
2031                 */
2032                req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2033                        req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2034                if (req->chain_outbuf == NULL) {
2035                        smb_panic("talloc failed");
2036                }
2037                req->outbuf = NULL;
2038        } else {
2039                /*
2040                 * Update smb headers where subsequent chained commands
2041                 * may have updated them.
2042                 */
2043                SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2044                SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2045
2046                if (!smb_splice_chain(&req->chain_outbuf,
2047                                      CVAL(req->outbuf, smb_com),
2048                                      CVAL(req->outbuf, smb_wct),
2049                                      (uint16_t *)(req->outbuf + smb_vwv),
2050                                      0, smb_buflen(req->outbuf),
2051                                      (uint8_t *)smb_buf(req->outbuf))) {
2052                        goto error;
2053                }
2054                TALLOC_FREE(req->outbuf);
2055        }
2056
2057        /*
2058         * We use the old request's vwv field to grab the next chained command
2059         * and offset into the chained fields.
2060         */
2061
2062        chain_cmd = CVAL(req->vwv+0, 0);
2063        chain_offset = SVAL(req->vwv+1, 0);
2064
2065        if (chain_cmd == 0xff) {
2066                /*
2067                 * End of chain, no more requests from the client. So ship the
2068                 * replies.
2069                 */
2070                smb_setlen((char *)(req->chain_outbuf),
2071                           talloc_get_size(req->chain_outbuf) - 4);
2072
2073                if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2074                                  true, req->seqnum+1,
2075                                  IS_CONN_ENCRYPTED(req->conn)
2076                                  ||req->encrypted,
2077                                  &req->pcd)) {
2078                        exit_server_cleanly("chain_reply: srv_send_smb "
2079                                            "failed.");
2080                }
2081                TALLOC_FREE(req->chain_outbuf);
2082                req->done = true;
2083                return;
2084        }
2085
2086        /* add a new perfcounter for this element of chain */
2087        SMB_PERFCOUNT_ADD(&req->pcd);
2088        SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2089        SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2090
2091        /*
2092         * Check if the client tries to fool us. The chain offset
2093         * needs to point beyond the current request in the chain, it
2094         * needs to strictly grow. Otherwise we might be tricked into
2095         * an endless loop always processing the same request over and
2096         * over again. We used to assume that vwv and the byte buffer
2097         * array in a chain are always attached, but OS/2 the
2098         * Write&X/Read&X chain puts the Read&X vwv array right behind
2099         * the Write&X vwv chain. The Write&X bcc array is put behind
2100         * the Read&X vwv array. So now we check whether the chain
2101         * offset points strictly behind the previous vwv
2102         * array. req->buf points right after the vwv array of the
2103         * previous request. See
2104         * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2105         * information.
2106         */
2107
2108        already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2109        if (chain_offset <= already_used) {
2110                goto error;
2111        }
2112
2113        /*
2114         * Next check: Make sure the chain offset does not point beyond the
2115         * overall smb request length.
2116         */
2117
2118        length_needed = chain_offset+1; /* wct */
2119        if (length_needed > smblen) {
2120                goto error;
2121        }
2122
2123        /*
2124         * Now comes the pointer magic. Goal here is to set up req->vwv and
2125         * req->buf correctly again to be able to call the subsequent
2126         * switch_message(). The chain offset (the former vwv[1]) points at
2127         * the new wct field.
2128         */
2129
2130        wct = CVAL(smb_base(req->inbuf), chain_offset);
2131
2132        /*
2133         * Next consistency check: Make the new vwv array fits in the overall
2134         * smb request.
2135         */
2136
2137        length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2138        if (length_needed > smblen) {
2139                goto error;
2140        }
2141        vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2142
2143        /*
2144         * Now grab the new byte buffer....
2145         */
2146
2147        buflen = SVAL(vwv+wct, 0);
2148
2149        /*
2150         * .. and check that it fits.
2151         */
2152
2153        length_needed += buflen;
2154        if (length_needed > smblen) {
2155                goto error;
2156        }
2157        buf = (uint8_t *)(vwv+wct+1);
2158
2159        req->cmd = chain_cmd;
2160        req->wct = wct;
2161        req->vwv = vwv;
2162        req->buflen = buflen;
2163        req->buf = buf;
2164
2165        switch_message(chain_cmd, req, smblen);
2166
2167        if (req->outbuf == NULL) {
2168                /*
2169                 * This happens if the chained command has suspended itself or
2170                 * if it has called srv_send_smb() itself.
2171                 */
2172                return;
2173        }
2174
2175        /*
2176         * We end up here if the chained command was not itself chained or
2177         * suspended, but for example a close() command. We now need to splice
2178         * the chained commands' outbuf into the already built up chain_outbuf
2179         * and ship the result.
2180         */
2181        goto done;
2182
2183 error:
2184        /*
2185         * We end up here if there's any error in the chain syntax. Report a
2186         * DOS error, just like Windows does.
2187         */
2188        reply_force_doserror(req, ERRSRV, ERRerror);
2189        fixup_chain_error_packet(req);
2190
2191 done:
2192        /*
2193         * This scary statement intends to set the
2194         * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2195         * to the value req->outbuf carries
2196         */
2197        SSVAL(req->chain_outbuf, smb_flg2,
2198              (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2199              | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2200
2201        /*
2202         * Transfer the error codes from the subrequest to the main one
2203         */
2204        SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2205        SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2206
2207        if (!smb_splice_chain(&req->chain_outbuf,
2208                              CVAL(req->outbuf, smb_com),
2209                              CVAL(req->outbuf, smb_wct),
2210                              (uint16_t *)(req->outbuf + smb_vwv),
2211                              0, smb_buflen(req->outbuf),
2212                              (uint8_t *)smb_buf(req->outbuf))) {
2213                exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2214        }
2215        TALLOC_FREE(req->outbuf);
2216
2217        smb_setlen((char *)(req->chain_outbuf),
2218                   talloc_get_size(req->chain_outbuf) - 4);
2219
2220        show_msg((char *)(req->chain_outbuf));
2221
2222        if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2223                          true, req->seqnum+1,
2224                          IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2225                          &req->pcd)) {
2226                exit_server_cleanly("chain_reply: srv_send_smb failed.");
2227        }
2228        TALLOC_FREE(req->chain_outbuf);
2229        req->done = true;
2230}
2231
2232/****************************************************************************
2233 Check if services need reloading.
2234****************************************************************************/
2235
2236static void check_reload(struct smbd_server_connection *sconn, time_t t)
2237{
2238
2239        if (last_smb_conf_reload_time == 0) {
2240                last_smb_conf_reload_time = t;
2241        }
2242
2243        if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2244                reload_services(sconn->msg_ctx, sconn->sock, True);
2245                last_smb_conf_reload_time = t;
2246        }
2247}
2248
2249static bool fd_is_readable(int fd)
2250{
2251        int ret, revents;
2252
2253        ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2254
2255        return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2256
2257}
2258
2259static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2260{
2261        /* TODO: make write nonblocking */
2262}
2263
2264static void smbd_server_connection_read_handler(
2265        struct smbd_server_connection *conn, int fd)
2266{
2267        uint8_t *inbuf = NULL;
2268        size_t inbuf_len = 0;
2269        size_t unread_bytes = 0;
2270        bool encrypted = false;
2271        TALLOC_CTX *mem_ctx = talloc_tos();
2272        NTSTATUS status;
2273        uint32_t seqnum;
2274
2275        bool from_client = (conn->sock == fd);
2276
2277        if (from_client) {
2278                smbd_lock_socket(conn);
2279
2280                if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2281                        DEBUG(10,("the echo listener was faster\n"));
2282                        smbd_unlock_socket(conn);
2283                        return;
2284                }
2285
2286                /* TODO: make this completely nonblocking */
2287                status = receive_smb_talloc(mem_ctx, conn, fd,
2288                                            (char **)(void *)&inbuf,
2289                                            0, /* timeout */
2290                                            &unread_bytes,
2291                                            &encrypted,
2292                                            &inbuf_len, &seqnum,
2293                                            false /* trusted channel */);
2294                smbd_unlock_socket(conn);
2295        } else {
2296                /* TODO: make this completely nonblocking */
2297                status = receive_smb_talloc(mem_ctx, conn, fd,
2298                                            (char **)(void *)&inbuf,
2299                                            0, /* timeout */
2300                                            &unread_bytes,
2301                                            &encrypted,
2302                                            &inbuf_len, &seqnum,
2303                                            true /* trusted channel */);
2304        }
2305
2306        if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2307                goto process;
2308        }
2309        if (NT_STATUS_IS_ERR(status)) {
2310                exit_server_cleanly("failed to receive smb request");
2311        }
2312        if (!NT_STATUS_IS_OK(status)) {
2313                return;
2314        }
2315
2316process:
2317        process_smb(conn, inbuf, inbuf_len, unread_bytes,
2318                    seqnum, encrypted, NULL);
2319}
2320
2321static void smbd_server_connection_handler(struct event_context *ev,
2322                                           struct fd_event *fde,
2323                                           uint16_t flags,
2324                                           void *private_data)
2325{
2326        struct smbd_server_connection *conn = talloc_get_type(private_data,
2327                                              struct smbd_server_connection);
2328
2329        if (flags & EVENT_FD_WRITE) {
2330                smbd_server_connection_write_handler(conn);
2331                return;
2332        }
2333        if (flags & EVENT_FD_READ) {
2334                smbd_server_connection_read_handler(conn, conn->sock);
2335                return;
2336        }
2337}
2338
2339static void smbd_server_echo_handler(struct event_context *ev,
2340                                     struct fd_event *fde,
2341                                     uint16_t flags,
2342                                     void *private_data)
2343{
2344        struct smbd_server_connection *conn = talloc_get_type(private_data,
2345                                              struct smbd_server_connection);
2346
2347        if (flags & EVENT_FD_WRITE) {
2348                smbd_server_connection_write_handler(conn);
2349                return;
2350        }
2351        if (flags & EVENT_FD_READ) {
2352                smbd_server_connection_read_handler(
2353                        conn, conn->smb1.echo_handler.trusted_fd);
2354                return;
2355        }
2356}
2357
2358/****************************************************************************
2359received when we should release a specific IP
2360****************************************************************************/
2361static void release_ip(const char *ip, void *priv)
2362{
2363        const char *addr = (const char *)priv;
2364        const char *p = addr;
2365
2366        if (strncmp("::ffff:", addr, 7) == 0) {
2367                p = addr + 7;
2368        }
2369
2370        DEBUG(10, ("Got release IP message for %s, "
2371                   "our address is %s\n", ip, p));
2372
2373        if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2374                /* we can't afford to do a clean exit - that involves
2375                   database writes, which would potentially mean we
2376                   are still running after the failover has finished -
2377                   we have to get rid of this process ID straight
2378                   away */
2379                DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2380                        ip));
2381                /* note we must exit with non-zero status so the unclean handler gets
2382                   called in the parent, so that the brl database is tickled */
2383                _exit(1);
2384        }
2385}
2386
2387static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2388                           uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2389{
2390        struct smbd_server_connection *sconn = talloc_get_type_abort(
2391                private_data, struct smbd_server_connection);
2392
2393        release_ip((char *)data->data, sconn->client_id.addr);
2394}
2395
2396#ifdef CLUSTER_SUPPORT
2397static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2398                               struct sockaddr_storage *client)
2399{
2400        socklen_t length;
2401        length = sizeof(*server);
2402        if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2403                return -1;
2404        }
2405        length = sizeof(*client);
2406        if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2407                return -1;
2408        }
2409        return 0;
2410}
2411#endif
2412
2413/*
2414 * Send keepalive packets to our client
2415 */
2416static bool keepalive_fn(const struct timeval *now, void *private_data)
2417{
2418        struct smbd_server_connection *sconn = smbd_server_conn;
2419        bool ret;
2420
2421        if (sconn->using_smb2) {
2422                /* Don't do keepalives on an SMB2 connection. */
2423                return false;
2424        }
2425
2426        smbd_lock_socket(smbd_server_conn);
2427        ret = send_keepalive(sconn->sock);
2428        smbd_unlock_socket(smbd_server_conn);
2429
2430        if (!ret) {
2431                char addr[INET6_ADDRSTRLEN];
2432                /*
2433                 * Try and give an error message saying what
2434                 * client failed.
2435                 */
2436                DEBUG(0, ("send_keepalive failed for client %s. "
2437                          "Error %s - exiting\n",
2438                          get_peer_addr(sconn->sock, addr, sizeof(addr)),
2439                          strerror(errno)));
2440                return False;
2441        }
2442        return True;
2443}
2444
2445/*
2446 * Do the recurring check if we're idle
2447 */
2448static bool deadtime_fn(const struct timeval *now, void *private_data)
2449{
2450        struct smbd_server_connection *sconn =
2451                (struct smbd_server_connection *)private_data;
2452
2453        if ((conn_num_open(sconn) == 0)
2454            || (conn_idle_all(sconn, now->tv_sec))) {
2455                DEBUG( 2, ( "Closing idle connection\n" ) );
2456                messaging_send(sconn->msg_ctx,
2457                               messaging_server_id(sconn->msg_ctx),
2458                               MSG_SHUTDOWN, &data_blob_null);
2459                return False;
2460        }
2461
2462        return True;
2463}
2464
2465/*
2466 * Do the recurring log file and smb.conf reload checks.
2467 */
2468
2469static bool housekeeping_fn(const struct timeval *now, void *private_data)
2470{
2471        struct smbd_server_connection *sconn = talloc_get_type_abort(
2472                private_data, struct smbd_server_connection);
2473
2474        DEBUG(5, ("housekeeping\n"));
2475
2476        change_to_root_user();
2477
2478#ifdef PRINTER_SUPPORT
2479        /* update printer queue caches if necessary */
2480        update_monitored_printq_cache(sconn->msg_ctx);
2481#endif
2482
2483        /* check if we need to reload services */
2484        check_reload(sconn, time_mono(NULL));
2485
2486#ifdef NETLOGON_SUPPORT
2487        /* Change machine password if neccessary. */
2488        attempt_machine_password_change();
2489#endif
2490
2491        /*
2492         * Force a log file check.
2493         */
2494        force_check_log_size();
2495        check_log_size();
2496        return true;
2497}
2498
2499static int create_unlink_tmp(const char *dir)
2500{
2501        char *fname;
2502        int fd;
2503
2504        fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2505        if (fname == NULL) {
2506                errno = ENOMEM;
2507                return -1;
2508        }
2509        fd = mkstemp(fname);
2510        if (fd == -1) {
2511                TALLOC_FREE(fname);
2512                return -1;
2513        }
2514        if (unlink(fname) == -1) {
2515                int sys_errno = errno;
2516                close(fd);
2517                TALLOC_FREE(fname);
2518                errno = sys_errno;
2519                return -1;
2520        }
2521        TALLOC_FREE(fname);
2522        return fd;
2523}
2524
2525struct smbd_echo_state {
2526        struct tevent_context *ev;
2527        struct iovec *pending;
2528        struct smbd_server_connection *sconn;
2529        int parent_pipe;
2530
2531        struct tevent_fd *parent_fde;
2532
2533        struct tevent_fd *read_fde;
2534        struct tevent_req *write_req;
2535};
2536
2537static void smbd_echo_writer_done(struct tevent_req *req);
2538
2539static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2540{
2541        int num_pending;
2542
2543        if (state->write_req != NULL) {
2544                return;
2545        }
2546
2547        num_pending = talloc_array_length(state->pending);
2548        if (num_pending == 0) {
2549                return;
2550        }
2551
2552        state->write_req = writev_send(state, state->ev, NULL,
2553                                       state->parent_pipe, false,
2554                                       state->pending, num_pending);
2555        if (state->write_req == NULL) {
2556                DEBUG(1, ("writev_send failed\n"));
2557                exit(1);
2558        }
2559
2560        talloc_steal(state->write_req, state->pending);
2561        state->pending = NULL;
2562
2563        tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2564                                state);
2565}
2566
2567static void smbd_echo_writer_done(struct tevent_req *req)
2568{
2569        struct smbd_echo_state *state = tevent_req_callback_data(
2570                req, struct smbd_echo_state);
2571        ssize_t written;
2572        int err;
2573
2574        written = writev_recv(req, &err);
2575        TALLOC_FREE(req);
2576        state->write_req = NULL;
2577        if (written == -1) {
2578                DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2579                exit(1);
2580        }
2581        DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2582        smbd_echo_activate_writer(state);
2583}
2584
2585static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2586                            uint32_t seqnum)
2587{
2588        struct smb_request req;
2589        uint16_t num_replies;
2590        size_t out_len;
2591        char *outbuf;
2592        bool ok;
2593
2594        if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2595                DEBUG(10, ("Got netbios keepalive\n"));
2596                /*
2597                 * Just swallow it
2598                 */
2599                return true;
2600        }
2601
2602        if (inbuf_len < smb_size) {
2603                DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2604                return false;
2605        }
2606        if (!valid_smb_header(inbuf)) {
2607                DEBUG(10, ("Got invalid SMB header\n"));
2608                return false;
2609        }
2610
2611        if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2612                              seqnum)) {
2613                return false;
2614        }
2615        req.inbuf = inbuf;
2616
2617        DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2618                   smb_messages[req.cmd].name
2619                   ? smb_messages[req.cmd].name : "unknown"));
2620
2621        if (req.cmd != SMBecho) {
2622                return false;
2623        }
2624        if (req.wct < 1) {
2625                return false;
2626        }
2627
2628        num_replies = SVAL(req.vwv+0, 0);
2629        if (num_replies != 1) {
2630                /* Not a Windows "Hey, you're still there?" request */
2631                return false;
2632        }
2633
2634        if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2635                           1, req.buflen)) {
2636                DEBUG(10, ("create_outbuf failed\n"));
2637                return false;
2638        }
2639        req.outbuf = (uint8_t *)outbuf;
2640
2641        SSVAL(req.outbuf, smb_vwv0, num_replies);
2642
2643        if (req.buflen > 0) {
2644                memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2645        }
2646
2647        out_len = smb_len(req.outbuf) + 4;
2648
2649        ok = srv_send_smb(req.sconn,
2650                          (char *)outbuf,
2651                          true, seqnum+1,
2652                          false, &req.pcd);
2653        TALLOC_FREE(outbuf);
2654        if (!ok) {
2655                exit(1);
2656        }
2657
2658        return true;
2659}
2660
2661static void smbd_echo_exit(struct tevent_context *ev,
2662                           struct tevent_fd *fde, uint16_t flags,
2663                           void *private_data)
2664{
2665        DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2666        exit(0);
2667}
2668
2669static void smbd_echo_reader(struct tevent_context *ev,
2670                             struct tevent_fd *fde, uint16_t flags,
2671                             void *private_data)
2672{
2673        struct smbd_echo_state *state = talloc_get_type_abort(
2674                private_data, struct smbd_echo_state);
2675        struct smbd_server_connection *sconn = state->sconn;
2676        size_t unread, num_pending;
2677        NTSTATUS status;
2678        struct iovec *tmp;
2679        size_t iov_len;
2680        uint32_t seqnum = 0;
2681        bool reply;
2682        bool ok;
2683        bool encrypted = false;
2684
2685        smb_msleep(1000);
2686
2687        ok = smbd_lock_socket_internal(sconn);
2688        if (!ok) {
2689                DEBUG(0, ("%s: failed to lock socket\n",
2690                        __location__));
2691                exit(1);
2692        }
2693
2694        if (!fd_is_readable(sconn->sock)) {
2695                DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2696                          (int)sys_getpid()));
2697                ok = smbd_unlock_socket_internal(sconn);
2698                if (!ok) {
2699                        DEBUG(1, ("%s: failed to unlock socket in\n",
2700                                __location__));
2701                        exit(1);
2702                }
2703                return;
2704        }
2705
2706        num_pending = talloc_array_length(state->pending);
2707        tmp = talloc_realloc(state, state->pending, struct iovec,
2708                             num_pending+1);
2709        if (tmp == NULL) {
2710                DEBUG(1, ("talloc_realloc failed\n"));
2711                exit(1);
2712        }
2713        state->pending = tmp;
2714
2715        DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2716
2717        status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2718                                    (char **)(void *)&state->pending[num_pending].iov_base,
2719                                    0 /* timeout */,
2720                                    &unread,
2721                                    &encrypted,
2722                                    &iov_len,
2723                                    &seqnum,
2724                                    false /* trusted_channel*/);
2725        if (!NT_STATUS_IS_OK(status)) {
2726                DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2727                          (int)sys_getpid(), nt_errstr(status)));
2728                exit(1);
2729        }
2730        state->pending[num_pending].iov_len = iov_len;
2731
2732        ok = smbd_unlock_socket_internal(sconn);
2733        if (!ok) {
2734                DEBUG(1, ("%s: failed to unlock socket in\n",
2735                        __location__));
2736                exit(1);
2737        }
2738
2739        reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2740                                state->pending[num_pending].iov_len,
2741                                seqnum);
2742        if (reply) {
2743                DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2744                /* no check, shrinking by some bytes does not fail */
2745                state->pending = talloc_realloc(state, state->pending,
2746                                                struct iovec,
2747                                                num_pending);
2748                return;
2749        }
2750
2751        if (state->pending[num_pending].iov_len >= smb_size) {
2752                /*
2753                 * place the seqnum in the packet so that the main process
2754                 * can reply with signing
2755                 */
2756                SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2757                      smb_ss_field, seqnum);
2758                SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2759                      smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2760        }
2761
2762        DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2763        smbd_echo_activate_writer(state);
2764}
2765
2766static void smbd_echo_loop(struct smbd_server_connection *sconn,
2767                           int parent_pipe)
2768{
2769        struct smbd_echo_state *state;
2770
2771        state = talloc_zero(sconn, struct smbd_echo_state);
2772        if (state == NULL) {
2773                DEBUG(1, ("talloc failed\n"));
2774                return;
2775        }
2776        state->sconn = sconn;
2777        state->parent_pipe = parent_pipe;
2778        state->ev = s3_tevent_context_init(state);
2779        if (state->ev == NULL) {
2780                DEBUG(1, ("tevent_context_init failed\n"));
2781                TALLOC_FREE(state);
2782                return;
2783        }
2784        state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2785                                        TEVENT_FD_READ, smbd_echo_exit,
2786                                        state);
2787        if (state->parent_fde == NULL) {
2788                DEBUG(1, ("tevent_add_fd failed\n"));
2789                TALLOC_FREE(state);
2790                return;
2791        }
2792        state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2793                                        TEVENT_FD_READ, smbd_echo_reader,
2794                                        state);
2795        if (state->read_fde == NULL) {
2796                DEBUG(1, ("tevent_add_fd failed\n"));
2797                TALLOC_FREE(state);
2798                return;
2799        }
2800
2801        while (true) {
2802                if (tevent_loop_once(state->ev) == -1) {
2803                        DEBUG(1, ("tevent_loop_once failed: %s\n",
2804                                  strerror(errno)));
2805                        break;
2806                }
2807        }
2808        TALLOC_FREE(state);
2809}
2810
2811/*
2812 * Handle SMBecho requests in a forked child process
2813 */
2814bool fork_echo_handler(struct smbd_server_connection *sconn)
2815{
2816        int listener_pipe[2];
2817        int res;
2818        pid_t child;
2819
2820        res = pipe(listener_pipe);
2821        if (res == -1) {
2822                DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2823                return false;
2824        }
2825        sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2826        if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2827                DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2828                goto fail;
2829        }
2830
2831        child = sys_fork();
2832        if (child == 0) {
2833                NTSTATUS status;
2834
2835                close(listener_pipe[0]);
2836                set_blocking(listener_pipe[1], false);
2837
2838                status = reinit_after_fork(sconn->msg_ctx,
2839                                           smbd_event_context(),
2840                                           procid_self(), false);
2841                if (!NT_STATUS_IS_OK(status)) {
2842                        DEBUG(1, ("reinit_after_fork failed: %s\n",
2843                                  nt_errstr(status)));
2844                        exit(1);
2845                }
2846                smbd_echo_loop(sconn, listener_pipe[1]);
2847                exit(0);
2848        }
2849        close(listener_pipe[1]);
2850        listener_pipe[1] = -1;
2851        sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2852
2853        DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2854
2855        /*
2856         * Without smb signing this is the same as the normal smbd
2857         * listener. This needs to change once signing comes in.
2858         */
2859        sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2860                                        sconn,
2861                                        sconn->smb1.echo_handler.trusted_fd,
2862                                        EVENT_FD_READ,
2863                                        smbd_server_echo_handler,
2864                                        sconn);
2865        if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2866                DEBUG(1, ("event_add_fd failed\n"));
2867                goto fail;
2868        }
2869
2870        return true;
2871
2872fail:
2873        if (listener_pipe[0] != -1) {
2874                close(listener_pipe[0]);
2875        }
2876        if (listener_pipe[1] != -1) {
2877                close(listener_pipe[1]);
2878        }
2879        sconn->smb1.echo_handler.trusted_fd = -1;
2880        if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2881                close(sconn->smb1.echo_handler.socket_lock_fd);
2882        }
2883        sconn->smb1.echo_handler.trusted_fd = -1;
2884        sconn->smb1.echo_handler.socket_lock_fd = -1;
2885        return false;
2886}
2887
2888#if CLUSTER_SUPPORT
2889
2890static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2891                                  struct sockaddr_storage *srv,
2892                                  struct sockaddr_storage *clnt)
2893{
2894        struct ctdbd_connection *cconn;
2895        char tmp_addr[INET6_ADDRSTRLEN];
2896        char *addr;
2897
2898        cconn = messaging_ctdbd_connection();
2899        if (cconn == NULL) {
2900                return NT_STATUS_NO_MEMORY;
2901        }
2902
2903        client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2904        addr = talloc_strdup(cconn, tmp_addr);
2905        if (addr == NULL) {
2906                return NT_STATUS_NO_MEMORY;
2907        }
2908        return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2909}
2910
2911#endif
2912
2913/****************************************************************************
2914 Process commands from the client
2915****************************************************************************/
2916
2917void smbd_process(struct smbd_server_connection *sconn)
2918{
2919        TALLOC_CTX *frame = talloc_stackframe();
2920        struct sockaddr_storage ss;
2921        struct sockaddr *sa = NULL;
2922        socklen_t sa_socklen;
2923        struct tsocket_address *local_address = NULL;
2924        struct tsocket_address *remote_address = NULL;
2925        const char *remaddr = NULL;
2926        int ret;
2927
2928        if (lp_maxprotocol() == PROTOCOL_SMB2) {
2929                /*
2930                 * We're not making the decision here,
2931                 * we're just allowing the client
2932                 * to decide between SMB1 and SMB2
2933                 * with the first negprot
2934                 * packet.
2935                 */
2936                sconn->using_smb2 = true;
2937        }
2938
2939        /* Ensure child is set to blocking mode */
2940        set_blocking(sconn->sock,True);
2941
2942        set_socket_options(sconn->sock, "SO_KEEPALIVE");
2943        set_socket_options(sconn->sock, lp_socket_options());
2944
2945        sa = (struct sockaddr *)(void *)&ss;
2946        sa_socklen = sizeof(ss);
2947        ret = getpeername(sconn->sock, sa, &sa_socklen);
2948        if (ret != 0) {
2949                int level = (errno == ENOTCONN)?2:0;
2950                DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2951                exit_server_cleanly("getpeername() failed.\n");
2952        }
2953        ret = tsocket_address_bsd_from_sockaddr(sconn,
2954                                                sa, sa_socklen,
2955                                                &remote_address);
2956        if (ret != 0) {
2957                DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2958                        __location__, strerror(errno)));
2959                exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2960        }
2961
2962        sa = (struct sockaddr *)(void *)&ss;
2963        sa_socklen = sizeof(ss);
2964        ret = getsockname(sconn->sock, sa, &sa_socklen);
2965        if (ret != 0) {
2966                int level = (errno == ENOTCONN)?2:0;
2967                DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2968                exit_server_cleanly("getsockname() failed.\n");
2969        }
2970        ret = tsocket_address_bsd_from_sockaddr(sconn,
2971                                                sa, sa_socklen,
2972                                                &local_address);
2973        if (ret != 0) {
2974                DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2975                        __location__, strerror(errno)));
2976                exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2977        }
2978
2979        sconn->local_address = local_address;
2980        sconn->remote_address = remote_address;
2981
2982        if (tsocket_address_is_inet(remote_address, "ip")) {
2983                remaddr = tsocket_address_inet_addr_string(
2984                                sconn->remote_address,
2985                                talloc_tos());
2986                if (remaddr == NULL) {
2987
2988                }
2989        } else {
2990                remaddr = "0.0.0.0";
2991        }
2992
2993        /* this is needed so that we get decent entries
2994           in smbstatus for port 445 connects */
2995        set_remote_machine_name(remaddr, false);
2996        reload_services(sconn->msg_ctx, sconn->sock, true);
2997
2998        /*
2999         * Before the first packet, check the global hosts allow/ hosts deny
3000         * parameters before doing any parsing of packets passed to us by the
3001         * client. This prevents attacks on our parsing code from hosts not in
3002         * the hosts allow list.
3003         */
3004
3005        if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3006                          sconn->client_id.name,
3007                          sconn->client_id.addr)) {
3008                /*
3009                 * send a negative session response "not listening on calling
3010                 * name"
3011                 */
3012                unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3013                DEBUG( 1, ("Connection denied from %s to %s\n",
3014                           tsocket_address_string(remote_address, talloc_tos()),
3015                           tsocket_address_string(local_address, talloc_tos())));
3016                (void)srv_send_smb(sconn,(char *)buf, false,
3017                                   0, false, NULL);
3018                exit_server_cleanly("connection denied");
3019        }
3020
3021        DEBUG(10, ("Connection allowed from %s to %s\n",
3022                   tsocket_address_string(remote_address, talloc_tos()),
3023                   tsocket_address_string(local_address, talloc_tos())));
3024
3025        init_modules();
3026
3027        smb_perfcount_init();
3028
3029        if (!init_account_policy()) {
3030                exit_server("Could not open account policy tdb.\n");
3031        }
3032
3033        if (*lp_rootdir()) {
3034                if (chroot(lp_rootdir()) != 0) {
3035                        DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3036                        exit_server("Failed to chroot()");
3037                }
3038                if (chdir("/") == -1) {
3039                        DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3040                        exit_server("Failed to chroot()");
3041                }
3042                DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3043        }
3044
3045        if (!srv_init_signing(sconn)) {
3046                exit_server("Failed to init smb_signing");
3047        }
3048
3049        /* Setup oplocks */
3050        if (!init_oplocks(sconn->msg_ctx))
3051                exit_server("Failed to init oplocks");
3052
3053        /* register our message handlers */
3054        messaging_register(sconn->msg_ctx, NULL,
3055                           MSG_SMB_FORCE_TDIS, msg_force_tdis);
3056        messaging_register(sconn->msg_ctx, sconn,
3057                           MSG_SMB_RELEASE_IP, msg_release_ip);
3058        messaging_register(sconn->msg_ctx, NULL,
3059                           MSG_SMB_CLOSE_FILE, msg_close_file);
3060
3061        /*
3062         * Use the default MSG_DEBUG handler to avoid rebroadcasting
3063         * MSGs to all child processes
3064         */
3065        messaging_deregister(sconn->msg_ctx,
3066                             MSG_DEBUG, NULL);
3067        messaging_register(sconn->msg_ctx, NULL,
3068                           MSG_DEBUG, debug_message);
3069
3070        if ((lp_keepalive() != 0)
3071            && !(event_add_idle(smbd_event_context(), NULL,
3072                                timeval_set(lp_keepalive(), 0),
3073                                "keepalive", keepalive_fn,
3074                                NULL))) {
3075                DEBUG(0, ("Could not add keepalive event\n"));
3076                exit(1);
3077        }
3078
3079        if (!(event_add_idle(smbd_event_context(), NULL,
3080                             timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3081                             "deadtime", deadtime_fn, sconn))) {
3082                DEBUG(0, ("Could not add deadtime event\n"));
3083                exit(1);
3084        }
3085
3086        if (!(event_add_idle(smbd_event_context(), NULL,
3087                             timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3088                             "housekeeping", housekeeping_fn, sconn))) {
3089                DEBUG(0, ("Could not add housekeeping event\n"));
3090                exit(1);
3091        }
3092
3093#ifdef CLUSTER_SUPPORT
3094
3095        if (lp_clustering()) {
3096                /*
3097                 * We need to tell ctdb about our client's TCP
3098                 * connection, so that for failover ctdbd can send
3099                 * tickle acks, triggering a reconnection by the
3100                 * client.
3101                 */
3102
3103                struct sockaddr_storage srv, clnt;
3104
3105                if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3106                        NTSTATUS status;
3107                        status = smbd_register_ips(sconn, &srv, &clnt);
3108                        if (!NT_STATUS_IS_OK(status)) {
3109                                DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3110                                          nt_errstr(status)));
3111                        }
3112                } else
3113                {
3114                        DEBUG(0,("Unable to get tcp info for "
3115                                 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3116                                 strerror(errno)));
3117                }
3118        }
3119
3120#endif
3121
3122        sconn->nbt.got_session = false;
3123
3124        sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3125
3126        sconn->smb1.sessions.done_sesssetup = false;
3127        sconn->smb1.sessions.max_send = BUFFER_SIZE;
3128        sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3129        /* users from session setup */
3130        sconn->smb1.sessions.session_userlist = NULL;
3131        /* workgroup from session setup. */
3132        sconn->smb1.sessions.session_workgroup = NULL;
3133        /* this holds info on user ids that are already validated for this VC */
3134        sconn->smb1.sessions.validated_users = NULL;
3135        sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3136        sconn->smb1.sessions.num_validated_vuids = 0;
3137
3138        conn_init(sconn);
3139        if (!init_dptrs(sconn)) {
3140                exit_server("init_dptrs() failed");
3141        }
3142
3143        sconn->smb1.fde = event_add_fd(smbd_event_context(),
3144                                                  sconn,
3145                                                  sconn->sock,
3146                                                  EVENT_FD_READ,
3147                                                  smbd_server_connection_handler,
3148                                                  sconn);
3149        if (!sconn->smb1.fde) {
3150                exit_server("failed to create smbd_server_connection fde");
3151        }
3152
3153        TALLOC_FREE(frame);
3154
3155        while (True) {
3156                NTSTATUS status;
3157
3158                frame = talloc_stackframe_pool(8192);
3159
3160                errno = 0;
3161
3162                status = smbd_server_connection_loop_once(sconn);
3163                if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3164                    !NT_STATUS_IS_OK(status)) {
3165                        DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3166                                  " exiting\n", nt_errstr(status)));
3167                        break;
3168                }
3169
3170                TALLOC_FREE(frame);
3171        }
3172
3173        exit_server_cleanly(NULL);
3174}
3175
3176bool req_is_in_chain(struct smb_request *req)
3177{
3178        if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3179                /*
3180                 * We're right now handling a subsequent request, so we must
3181                 * be in a chain
3182                 */
3183                return true;
3184        }
3185
3186        if (!is_andx_req(req->cmd)) {
3187                return false;
3188        }
3189
3190        if (req->wct < 2) {
3191                /*
3192                 * Okay, an illegal request, but definitely not chained :-)
3193                 */
3194                return false;
3195        }
3196
3197        return (CVAL(req->vwv+0, 0) != 0xFF);
3198}
Note: See TracBrowser for help on using the repository browser.