Revert "smbd: Fix CID 1504457 Resource leak"
[samba.git] / source3 / smbd / smb1_process.c
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 "smbd/smbXsrv_open.h"
27 #include "librpc/gen_ndr/netlogon.h"
28 #include "../lib/async_req/async_sock.h"
29 #include "ctdbd_conn.h"
30 #include "../lib/util/select.h"
31 #include "printing/queue_process.h"
32 #include "system/select.h"
33 #include "passdb.h"
34 #include "auth.h"
35 #include "messages.h"
36 #include "lib/messages_ctdb.h"
37 #include "smbprofile.h"
38 #include "rpc_server/spoolss/srv_spoolss_nt.h"
39 #include "../lib/util/tevent_ntstatus.h"
40 #include "../libcli/security/dom_sid.h"
41 #include "../libcli/security/security_token.h"
42 #include "lib/id_cache.h"
43 #include "lib/util/sys_rw_data.h"
44 #include "system/threads.h"
45 #include "lib/pthreadpool/pthreadpool_tevent.h"
46 #include "util_event.h"
47 #include "libcli/smb/smbXcli_base.h"
48 #include "lib/util/time_basic.h"
49 #include "source3/lib/substitute.h"
50 #include "lib/util/util_process.h"
51
52 /* Internal message queue for deferred opens. */
53 struct pending_message_list {
54         struct pending_message_list *next, *prev;
55         struct timeval request_time; /* When was this first issued? */
56         struct smbd_server_connection *sconn;
57         struct smbXsrv_connection *xconn;
58         struct tevent_timer *te;
59         uint32_t seqnum;
60         bool encrypted;
61         bool processed;
62         DATA_BLOB buf;
63         struct deferred_open_record *open_rec;
64 };
65
66 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
67
68 void smbd_echo_init(struct smbXsrv_connection *xconn)
69 {
70         xconn->smb1.echo_handler.trusted_fd = -1;
71         xconn->smb1.echo_handler.socket_lock_fd = -1;
72 #ifdef HAVE_ROBUST_MUTEXES
73         xconn->smb1.echo_handler.socket_mutex = NULL;
74 #endif
75 }
76
77 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
78 {
79         if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
80                 return true;
81         }
82
83 #ifdef HAVE_ROBUST_MUTEXES
84         if (xconn->smb1.echo_handler.socket_mutex != NULL) {
85                 return true;
86         }
87 #endif
88
89         return false;
90 }
91
92 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
93 {
94         if (!smbd_echo_active(xconn)) {
95                 return true;
96         }
97
98         xconn->smb1.echo_handler.ref_count++;
99
100         if (xconn->smb1.echo_handler.ref_count > 1) {
101                 return true;
102         }
103
104         DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
105
106 #ifdef HAVE_ROBUST_MUTEXES
107         if (xconn->smb1.echo_handler.socket_mutex != NULL) {
108                 int ret = EINTR;
109
110                 while (ret == EINTR) {
111                         ret = pthread_mutex_lock(
112                                 xconn->smb1.echo_handler.socket_mutex);
113                         if (ret == 0) {
114                                 break;
115                         }
116                 }
117                 if (ret != 0) {
118                         DEBUG(1, ("pthread_mutex_lock failed: %s\n",
119                                   strerror(ret)));
120                         return false;
121                 }
122         }
123 #endif
124
125         if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
126                 bool ok;
127
128                 do {
129                         ok = fcntl_lock(
130                                 xconn->smb1.echo_handler.socket_lock_fd,
131                                 F_SETLKW, 0, 0, F_WRLCK);
132                 } while (!ok && (errno == EINTR));
133
134                 if (!ok) {
135                         DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
136                         return false;
137                 }
138         }
139
140         DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
141
142         return true;
143 }
144
145 void smbd_lock_socket(struct smbXsrv_connection *xconn)
146 {
147         if (!smbd_lock_socket_internal(xconn)) {
148                 exit_server_cleanly("failed to lock socket");
149         }
150 }
151
152 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
153 {
154         if (!smbd_echo_active(xconn)) {
155                 return true;
156         }
157
158         xconn->smb1.echo_handler.ref_count--;
159
160         if (xconn->smb1.echo_handler.ref_count > 0) {
161                 return true;
162         }
163
164 #ifdef HAVE_ROBUST_MUTEXES
165         if (xconn->smb1.echo_handler.socket_mutex != NULL) {
166                 int ret;
167                 ret = pthread_mutex_unlock(
168                         xconn->smb1.echo_handler.socket_mutex);
169                 if (ret != 0) {
170                         DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
171                                   strerror(ret)));
172                         return false;
173                 }
174         }
175 #endif
176
177         if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
178                 bool ok;
179
180                 do {
181                         ok = fcntl_lock(
182                                 xconn->smb1.echo_handler.socket_lock_fd,
183                                 F_SETLKW, 0, 0, F_UNLCK);
184                 } while (!ok && (errno == EINTR));
185
186                 if (!ok) {
187                         DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
188                         return false;
189                 }
190         }
191
192         DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
193
194         return true;
195 }
196
197 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
198 {
199         if (!smbd_unlock_socket_internal(xconn)) {
200                 exit_server_cleanly("failed to unlock socket");
201         }
202 }
203
204 /* Accessor function for smb_read_error for smbd functions. */
205
206 /****************************************************************************
207  Send an smb to a fd.
208 ****************************************************************************/
209
210 bool smb1_srv_send(struct smbXsrv_connection *xconn,
211                    char *buffer,
212                    bool do_signing,
213                    uint32_t seqnum,
214                    bool do_encrypt)
215 {
216         size_t len = 0;
217         ssize_t ret;
218         char *buf_out = buffer;
219
220         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
221                 /*
222                  * we're not supposed to do any io
223                  */
224                 return true;
225         }
226
227         smbd_lock_socket(xconn);
228
229         if (do_signing) {
230                 NTSTATUS status;
231
232                 /* Sign the outgoing packet if required. */
233                 status = smb1_srv_calculate_sign_mac(xconn, buf_out, seqnum);
234                 if (!NT_STATUS_IS_OK(status)) {
235                         DBG_ERR("Failed to calculate signing mac: %s\n",
236                                 nt_errstr(status));
237                         return false;
238                 }
239         }
240
241         if (do_encrypt) {
242                 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
243                 if (!NT_STATUS_IS_OK(status)) {
244                         DEBUG(0, ("send_smb: SMB encryption failed "
245                                 "on outgoing packet! Error %s\n",
246                                 nt_errstr(status) ));
247                         ret = -1;
248                         goto out;
249                 }
250         }
251
252         len = smb_len_large(buf_out) + 4;
253
254         ret = write_data(xconn->transport.sock, buf_out, len);
255         if (ret <= 0) {
256                 int saved_errno = errno;
257                 /*
258                  * Try and give an error message saying what
259                  * client failed.
260                  */
261                 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
262                          (int)getpid(), (int)len,
263                          smbXsrv_connection_dbg(xconn),
264                          (int)ret, strerror(saved_errno)));
265                 errno = saved_errno;
266
267                 srv_free_enc_buffer(xconn, buf_out);
268                 goto out;
269         }
270
271         srv_free_enc_buffer(xconn, buf_out);
272 out:
273         smbd_unlock_socket(xconn);
274         return (ret > 0);
275 }
276
277 /* Socket functions for smbd packet processing. */
278
279 static bool valid_packet_size(size_t len)
280 {
281         /*
282          * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
283          * of header. Don't print the error if this fits.... JRA.
284          */
285
286         if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
287                 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
288                                         (unsigned long)len));
289                 return false;
290         }
291         return true;
292 }
293
294 /****************************************************************************
295  Attempt a zerocopy writeX read. We know here that len > smb_size-4
296 ****************************************************************************/
297
298 /*
299  * Unfortunately, earlier versions of smbclient/libsmbclient
300  * don't send this "standard" writeX header. I've fixed this
301  * for 3.2 but we'll use the old method with earlier versions.
302  * Windows and CIFSFS at least use this standard size. Not
303  * sure about MacOSX.
304  */
305
306 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
307                                 (2*14) + /* word count (including bcc) */ \
308                                 1 /* pad byte */)
309
310 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
311                                                     const char lenbuf[4],
312                                                     struct smbXsrv_connection *xconn,
313                                                     int sock,
314                                                     char **buffer,
315                                                     unsigned int timeout,
316                                                     size_t *p_unread,
317                                                     size_t *len_ret)
318 {
319         /* Size of a WRITEX call (+4 byte len). */
320         char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
321         ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
322         ssize_t toread;
323         NTSTATUS status;
324
325         memcpy(writeX_header, lenbuf, 4);
326
327         status = read_fd_with_timeout(
328                 sock, writeX_header + 4,
329                 STANDARD_WRITE_AND_X_HEADER_SIZE,
330                 STANDARD_WRITE_AND_X_HEADER_SIZE,
331                 timeout, NULL);
332
333         if (!NT_STATUS_IS_OK(status)) {
334                 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
335                           "error = %s.\n",
336                           smbXsrv_connection_dbg(xconn),
337                           nt_errstr(status)));
338                 return status;
339         }
340
341         /*
342          * Ok - now try and see if this is a possible
343          * valid writeX call.
344          */
345
346         if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
347                 /*
348                  * If the data offset is beyond what
349                  * we've read, drain the extra bytes.
350                  */
351                 uint16_t doff = SVAL(writeX_header,smb_vwv11);
352                 ssize_t newlen;
353
354                 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
355                         size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
356                         if (drain_socket(sock, drain) != drain) {
357                                 smb_panic("receive_smb_raw_talloc_partial_read:"
358                                         " failed to drain pending bytes");
359                         }
360                 } else {
361                         doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
362                 }
363
364                 /* Spoof down the length and null out the bcc. */
365                 set_message_bcc(writeX_header, 0);
366                 newlen = smb_len(writeX_header);
367
368                 /* Copy the header we've written. */
369
370                 *buffer = (char *)talloc_memdup(mem_ctx,
371                                 writeX_header,
372                                 sizeof(writeX_header));
373
374                 if (*buffer == NULL) {
375                         DEBUG(0, ("Could not allocate inbuf of length %d\n",
376                                   (int)sizeof(writeX_header)));
377                         return NT_STATUS_NO_MEMORY;
378                 }
379
380                 /* Work out the remaining bytes. */
381                 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
382                 *len_ret = newlen + 4;
383                 return NT_STATUS_OK;
384         }
385
386         if (!valid_packet_size(len)) {
387                 return NT_STATUS_INVALID_PARAMETER;
388         }
389
390         /*
391          * Not a valid writeX call. Just do the standard
392          * talloc and return.
393          */
394
395         *buffer = talloc_array(mem_ctx, char, len+4);
396
397         if (*buffer == NULL) {
398                 DEBUG(0, ("Could not allocate inbuf of length %d\n",
399                           (int)len+4));
400                 return NT_STATUS_NO_MEMORY;
401         }
402
403         /* Copy in what we already read. */
404         memcpy(*buffer,
405                 writeX_header,
406                 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
407         toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
408
409         if(toread > 0) {
410                 status = read_packet_remainder(
411                         sock,
412                         (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
413                         timeout, toread);
414
415                 if (!NT_STATUS_IS_OK(status)) {
416                         DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
417                                    nt_errstr(status)));
418                         return status;
419                 }
420         }
421
422         *len_ret = len + 4;
423         return NT_STATUS_OK;
424 }
425
426 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
427                                        struct smbXsrv_connection *xconn,
428                                        int sock,
429                                        char **buffer, unsigned int timeout,
430                                        size_t *p_unread, size_t *plen)
431 {
432         char lenbuf[4];
433         size_t len;
434         int min_recv_size = lp_min_receive_file_size();
435         NTSTATUS status;
436
437         *p_unread = 0;
438
439         status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
440                                                   &len);
441         if (!NT_STATUS_IS_OK(status)) {
442                 return status;
443         }
444
445         if (CVAL(lenbuf,0) == 0 && min_recv_size &&
446             (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
447                 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
448             !smb1_srv_is_signing_active(xconn) &&
449             xconn->smb1.echo_handler.trusted_fde == NULL) {
450
451                 return receive_smb_raw_talloc_partial_read(
452                         mem_ctx, lenbuf, xconn, sock, buffer, timeout,
453                         p_unread, plen);
454         }
455
456         if (!valid_packet_size(len)) {
457                 return NT_STATUS_INVALID_PARAMETER;
458         }
459
460         /*
461          * The +4 here can't wrap, we've checked the length above already.
462          */
463
464         *buffer = talloc_array(mem_ctx, char, len+4);
465
466         if (*buffer == NULL) {
467                 DEBUG(0, ("Could not allocate inbuf of length %d\n",
468                           (int)len+4));
469                 return NT_STATUS_NO_MEMORY;
470         }
471
472         memcpy(*buffer, lenbuf, sizeof(lenbuf));
473
474         status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
475         if (!NT_STATUS_IS_OK(status)) {
476                 return status;
477         }
478
479         *plen = len + 4;
480         return NT_STATUS_OK;
481 }
482
483 NTSTATUS smb1_receive_talloc(TALLOC_CTX *mem_ctx,
484                              struct smbXsrv_connection *xconn,
485                              int sock,
486                              char **buffer, unsigned int timeout,
487                              size_t *p_unread, bool *p_encrypted,
488                              size_t *p_len,
489                              uint32_t *seqnum,
490                              bool trusted_channel)
491 {
492         size_t len = 0;
493         NTSTATUS status;
494
495         *p_encrypted = false;
496
497         status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
498                                         p_unread, &len);
499         if (!NT_STATUS_IS_OK(status)) {
500                 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
501                       ("receive_smb_raw_talloc failed for client %s "
502                        "read error = %s.\n",
503                        smbXsrv_connection_dbg(xconn),
504                        nt_errstr(status)) );
505                 return status;
506         }
507
508         if (is_encrypted_packet((uint8_t *)*buffer)) {
509                 status = srv_decrypt_buffer(xconn, *buffer);
510                 if (!NT_STATUS_IS_OK(status)) {
511                         DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
512                                 "incoming packet! Error %s\n",
513                                 nt_errstr(status) ));
514                         return status;
515                 }
516                 *p_encrypted = true;
517         }
518
519         /* Check the incoming SMB signature. */
520         if (!smb1_srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
521                 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
522                           "incoming packet!\n"));
523                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
524         }
525
526         *p_len = len;
527         return NT_STATUS_OK;
528 }
529
530 /****************************************************************************
531  Function to push a message onto the tail of a linked list of smb messages ready
532  for processing.
533 ****************************************************************************/
534
535 static bool push_queued_message(struct smb_request *req,
536                                 struct timeval request_time,
537                                 struct timeval end_time,
538                                 struct deferred_open_record *open_rec)
539 {
540         int msg_len = smb_len(req->inbuf) + 4;
541         struct pending_message_list *msg;
542
543         msg = talloc_zero(NULL, struct pending_message_list);
544
545         if(msg == NULL) {
546                 DEBUG(0,("push_message: malloc fail (1)\n"));
547                 return False;
548         }
549         msg->sconn = req->sconn;
550         msg->xconn = req->xconn;
551
552         msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
553         if(msg->buf.data == NULL) {
554                 DEBUG(0,("push_message: malloc fail (2)\n"));
555                 TALLOC_FREE(msg);
556                 return False;
557         }
558
559         msg->request_time = request_time;
560         msg->seqnum = req->seqnum;
561         msg->encrypted = req->encrypted;
562         msg->processed = false;
563
564         if (open_rec) {
565                 msg->open_rec = talloc_move(msg, &open_rec);
566         }
567
568 #if 0
569         msg->te = tevent_add_timer(msg->sconn->ev_ctx,
570                                    msg,
571                                    end_time,
572                                    smbd_deferred_open_timer,
573                                    msg);
574         if (!msg->te) {
575                 DEBUG(0,("push_message: event_add_timed failed\n"));
576                 TALLOC_FREE(msg);
577                 return false;
578         }
579 #endif
580
581         DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
582
583         DEBUG(10,("push_message: pushed message length %u on "
584                   "deferred_open_queue\n", (unsigned int)msg_len));
585
586         return True;
587 }
588
589 /****************************************************************************
590  Function to push a deferred open smb message onto a linked list of local smb
591  messages ready for processing.
592 ****************************************************************************/
593
594 bool push_deferred_open_message_smb1(struct smb_request *req,
595                                      struct timeval timeout,
596                                      struct file_id id,
597                                      struct deferred_open_record *open_rec)
598 {
599         struct timeval_buf tvbuf;
600         struct timeval end_time;
601
602         if (req->unread_bytes) {
603                 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
604                         "unread_bytes = %u\n",
605                         (unsigned int)req->unread_bytes ));
606                 smb_panic("push_deferred_open_message_smb: "
607                         "logic error unread_bytes != 0" );
608         }
609
610         end_time = timeval_sum(&req->request_time, &timeout);
611
612         DBG_DEBUG("pushing message len %u mid %"PRIu64" timeout time [%s]\n",
613                   (unsigned int) smb_len(req->inbuf)+4,
614                   req->mid,
615                   timeval_str_buf(&end_time, false, true, &tvbuf));
616
617         return push_queued_message(req, req->request_time, end_time, open_rec);
618 }
619
620 /*
621  * Only allow 5 outstanding trans requests. We're allocating memory, so
622  * prevent a DoS.
623  */
624
625 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
626 {
627         int count = 0;
628         for (; list != NULL; list = list->next) {
629
630                 if (list->mid == mid) {
631                         return NT_STATUS_INVALID_PARAMETER;
632                 }
633
634                 count += 1;
635         }
636         if (count > 5) {
637                 return NT_STATUS_INSUFFICIENT_RESOURCES;
638         }
639
640         return NT_STATUS_OK;
641 }
642
643 /*
644 These flags determine some of the permissions required to do an operation 
645
646 Note that I don't set NEED_WRITE on some write operations because they
647 are used by some brain-dead clients when printing, and I don't want to
648 force write permissions on print services.
649 */
650 #define AS_USER (1<<0)
651 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
652 #define TIME_INIT (1<<2)
653 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
654 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
655 #define DO_CHDIR (1<<6)
656
657 /* 
658    define a list of possible SMB messages and their corresponding
659    functions. Any message that has a NULL function is unimplemented -
660    please feel free to contribute implementations!
661 */
662 static const struct smb_message_struct {
663         const char *name;
664         void (*fn)(struct smb_request *req);
665         int flags;
666 } smb_messages[256] = {
667
668 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
669 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
670 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
671 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
672 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
673 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
674 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
675 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
676 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
677 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
678 /* 0x0a */ { "SMBread",reply_read,AS_USER},
679 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
680 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
681 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
682 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
683 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
684 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
685 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
686 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
687 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
688 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
689 /* 0x15 */ { NULL, NULL, 0 },
690 /* 0x16 */ { NULL, NULL, 0 },
691 /* 0x17 */ { NULL, NULL, 0 },
692 /* 0x18 */ { NULL, NULL, 0 },
693 /* 0x19 */ { NULL, NULL, 0 },
694 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
695 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
696 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
697 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
698 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
699 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
700 /* 0x20 */ { "SMBwritec", NULL,0},
701 /* 0x21 */ { NULL, NULL, 0 },
702 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
703 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
704 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
705 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
706 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
707 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
708 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
709 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
710 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
711 /* 0x2b */ { "SMBecho",reply_echo,0},
712 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
713 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
714 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
715 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
716 /* 0x30 */ { NULL, NULL, 0 },
717 /* 0x31 */ { NULL, NULL, 0 },
718 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
719 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
720 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
721 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
722 /* 0x36 */ { NULL, NULL, 0 },
723 /* 0x37 */ { NULL, NULL, 0 },
724 /* 0x38 */ { NULL, NULL, 0 },
725 /* 0x39 */ { NULL, NULL, 0 },
726 /* 0x3a */ { NULL, NULL, 0 },
727 /* 0x3b */ { NULL, NULL, 0 },
728 /* 0x3c */ { NULL, NULL, 0 },
729 /* 0x3d */ { NULL, NULL, 0 },
730 /* 0x3e */ { NULL, NULL, 0 },
731 /* 0x3f */ { NULL, NULL, 0 },
732 /* 0x40 */ { NULL, NULL, 0 },
733 /* 0x41 */ { NULL, NULL, 0 },
734 /* 0x42 */ { NULL, NULL, 0 },
735 /* 0x43 */ { NULL, NULL, 0 },
736 /* 0x44 */ { NULL, NULL, 0 },
737 /* 0x45 */ { NULL, NULL, 0 },
738 /* 0x46 */ { NULL, NULL, 0 },
739 /* 0x47 */ { NULL, NULL, 0 },
740 /* 0x48 */ { NULL, NULL, 0 },
741 /* 0x49 */ { NULL, NULL, 0 },
742 /* 0x4a */ { NULL, NULL, 0 },
743 /* 0x4b */ { NULL, NULL, 0 },
744 /* 0x4c */ { NULL, NULL, 0 },
745 /* 0x4d */ { NULL, NULL, 0 },
746 /* 0x4e */ { NULL, NULL, 0 },
747 /* 0x4f */ { NULL, NULL, 0 },
748 /* 0x50 */ { NULL, NULL, 0 },
749 /* 0x51 */ { NULL, NULL, 0 },
750 /* 0x52 */ { NULL, NULL, 0 },
751 /* 0x53 */ { NULL, NULL, 0 },
752 /* 0x54 */ { NULL, NULL, 0 },
753 /* 0x55 */ { NULL, NULL, 0 },
754 /* 0x56 */ { NULL, NULL, 0 },
755 /* 0x57 */ { NULL, NULL, 0 },
756 /* 0x58 */ { NULL, NULL, 0 },
757 /* 0x59 */ { NULL, NULL, 0 },
758 /* 0x5a */ { NULL, NULL, 0 },
759 /* 0x5b */ { NULL, NULL, 0 },
760 /* 0x5c */ { NULL, NULL, 0 },
761 /* 0x5d */ { NULL, NULL, 0 },
762 /* 0x5e */ { NULL, NULL, 0 },
763 /* 0x5f */ { NULL, NULL, 0 },
764 /* 0x60 */ { NULL, NULL, 0 },
765 /* 0x61 */ { NULL, NULL, 0 },
766 /* 0x62 */ { NULL, NULL, 0 },
767 /* 0x63 */ { NULL, NULL, 0 },
768 /* 0x64 */ { NULL, NULL, 0 },
769 /* 0x65 */ { NULL, NULL, 0 },
770 /* 0x66 */ { NULL, NULL, 0 },
771 /* 0x67 */ { NULL, NULL, 0 },
772 /* 0x68 */ { NULL, NULL, 0 },
773 /* 0x69 */ { NULL, NULL, 0 },
774 /* 0x6a */ { NULL, NULL, 0 },
775 /* 0x6b */ { NULL, NULL, 0 },
776 /* 0x6c */ { NULL, NULL, 0 },
777 /* 0x6d */ { NULL, NULL, 0 },
778 /* 0x6e */ { NULL, NULL, 0 },
779 /* 0x6f */ { NULL, NULL, 0 },
780 /* 0x70 */ { "SMBtcon",reply_tcon,0},
781 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
782 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
783 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
784 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
785 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
786 /* 0x76 */ { NULL, NULL, 0 },
787 /* 0x77 */ { NULL, NULL, 0 },
788 /* 0x78 */ { NULL, NULL, 0 },
789 /* 0x79 */ { NULL, NULL, 0 },
790 /* 0x7a */ { NULL, NULL, 0 },
791 /* 0x7b */ { NULL, NULL, 0 },
792 /* 0x7c */ { NULL, NULL, 0 },
793 /* 0x7d */ { NULL, NULL, 0 },
794 /* 0x7e */ { NULL, NULL, 0 },
795 /* 0x7f */ { NULL, NULL, 0 },
796 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
797 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
798 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
799 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
800 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
801 /* 0x85 */ { NULL, NULL, 0 },
802 /* 0x86 */ { NULL, NULL, 0 },
803 /* 0x87 */ { NULL, NULL, 0 },
804 /* 0x88 */ { NULL, NULL, 0 },
805 /* 0x89 */ { NULL, NULL, 0 },
806 /* 0x8a */ { NULL, NULL, 0 },
807 /* 0x8b */ { NULL, NULL, 0 },
808 /* 0x8c */ { NULL, NULL, 0 },
809 /* 0x8d */ { NULL, NULL, 0 },
810 /* 0x8e */ { NULL, NULL, 0 },
811 /* 0x8f */ { NULL, NULL, 0 },
812 /* 0x90 */ { NULL, NULL, 0 },
813 /* 0x91 */ { NULL, NULL, 0 },
814 /* 0x92 */ { NULL, NULL, 0 },
815 /* 0x93 */ { NULL, NULL, 0 },
816 /* 0x94 */ { NULL, NULL, 0 },
817 /* 0x95 */ { NULL, NULL, 0 },
818 /* 0x96 */ { NULL, NULL, 0 },
819 /* 0x97 */ { NULL, NULL, 0 },
820 /* 0x98 */ { NULL, NULL, 0 },
821 /* 0x99 */ { NULL, NULL, 0 },
822 /* 0x9a */ { NULL, NULL, 0 },
823 /* 0x9b */ { NULL, NULL, 0 },
824 /* 0x9c */ { NULL, NULL, 0 },
825 /* 0x9d */ { NULL, NULL, 0 },
826 /* 0x9e */ { NULL, NULL, 0 },
827 /* 0x9f */ { NULL, NULL, 0 },
828 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
829 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
830 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
831 /* 0xa3 */ { NULL, NULL, 0 },
832 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
833 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
834 /* 0xa6 */ { NULL, NULL, 0 },
835 /* 0xa7 */ { NULL, NULL, 0 },
836 /* 0xa8 */ { NULL, NULL, 0 },
837 /* 0xa9 */ { NULL, NULL, 0 },
838 /* 0xaa */ { NULL, NULL, 0 },
839 /* 0xab */ { NULL, NULL, 0 },
840 /* 0xac */ { NULL, NULL, 0 },
841 /* 0xad */ { NULL, NULL, 0 },
842 /* 0xae */ { NULL, NULL, 0 },
843 /* 0xaf */ { NULL, NULL, 0 },
844 /* 0xb0 */ { NULL, NULL, 0 },
845 /* 0xb1 */ { NULL, NULL, 0 },
846 /* 0xb2 */ { NULL, NULL, 0 },
847 /* 0xb3 */ { NULL, NULL, 0 },
848 /* 0xb4 */ { NULL, NULL, 0 },
849 /* 0xb5 */ { NULL, NULL, 0 },
850 /* 0xb6 */ { NULL, NULL, 0 },
851 /* 0xb7 */ { NULL, NULL, 0 },
852 /* 0xb8 */ { NULL, NULL, 0 },
853 /* 0xb9 */ { NULL, NULL, 0 },
854 /* 0xba */ { NULL, NULL, 0 },
855 /* 0xbb */ { NULL, NULL, 0 },
856 /* 0xbc */ { NULL, NULL, 0 },
857 /* 0xbd */ { NULL, NULL, 0 },
858 /* 0xbe */ { NULL, NULL, 0 },
859 /* 0xbf */ { NULL, NULL, 0 },
860 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
861 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
862 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
863 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
864 /* 0xc4 */ { NULL, NULL, 0 },
865 /* 0xc5 */ { NULL, NULL, 0 },
866 /* 0xc6 */ { NULL, NULL, 0 },
867 /* 0xc7 */ { NULL, NULL, 0 },
868 /* 0xc8 */ { NULL, NULL, 0 },
869 /* 0xc9 */ { NULL, NULL, 0 },
870 /* 0xca */ { NULL, NULL, 0 },
871 /* 0xcb */ { NULL, NULL, 0 },
872 /* 0xcc */ { NULL, NULL, 0 },
873 /* 0xcd */ { NULL, NULL, 0 },
874 /* 0xce */ { NULL, NULL, 0 },
875 /* 0xcf */ { NULL, NULL, 0 },
876 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
877 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
878 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
879 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
880 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
881 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
882 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
883 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
884 /* 0xd8 */ { NULL, NULL, 0 },
885 /* 0xd9 */ { NULL, NULL, 0 },
886 /* 0xda */ { NULL, NULL, 0 },
887 /* 0xdb */ { NULL, NULL, 0 },
888 /* 0xdc */ { NULL, NULL, 0 },
889 /* 0xdd */ { NULL, NULL, 0 },
890 /* 0xde */ { NULL, NULL, 0 },
891 /* 0xdf */ { NULL, NULL, 0 },
892 /* 0xe0 */ { NULL, NULL, 0 },
893 /* 0xe1 */ { NULL, NULL, 0 },
894 /* 0xe2 */ { NULL, NULL, 0 },
895 /* 0xe3 */ { NULL, NULL, 0 },
896 /* 0xe4 */ { NULL, NULL, 0 },
897 /* 0xe5 */ { NULL, NULL, 0 },
898 /* 0xe6 */ { NULL, NULL, 0 },
899 /* 0xe7 */ { NULL, NULL, 0 },
900 /* 0xe8 */ { NULL, NULL, 0 },
901 /* 0xe9 */ { NULL, NULL, 0 },
902 /* 0xea */ { NULL, NULL, 0 },
903 /* 0xeb */ { NULL, NULL, 0 },
904 /* 0xec */ { NULL, NULL, 0 },
905 /* 0xed */ { NULL, NULL, 0 },
906 /* 0xee */ { NULL, NULL, 0 },
907 /* 0xef */ { NULL, NULL, 0 },
908 /* 0xf0 */ { NULL, NULL, 0 },
909 /* 0xf1 */ { NULL, NULL, 0 },
910 /* 0xf2 */ { NULL, NULL, 0 },
911 /* 0xf3 */ { NULL, NULL, 0 },
912 /* 0xf4 */ { NULL, NULL, 0 },
913 /* 0xf5 */ { NULL, NULL, 0 },
914 /* 0xf6 */ { NULL, NULL, 0 },
915 /* 0xf7 */ { NULL, NULL, 0 },
916 /* 0xf8 */ { NULL, NULL, 0 },
917 /* 0xf9 */ { NULL, NULL, 0 },
918 /* 0xfa */ { NULL, NULL, 0 },
919 /* 0xfb */ { NULL, NULL, 0 },
920 /* 0xfc */ { NULL, NULL, 0 },
921 /* 0xfd */ { NULL, NULL, 0 },
922 /* 0xfe */ { NULL, NULL, 0 },
923 /* 0xff */ { NULL, NULL, 0 }
924
925 };
926
927
928 /*******************************************************************
929  Dump a packet to a file.
930 ********************************************************************/
931
932 static void smb_dump(const char *name, int type, const char *data)
933 {
934         size_t len;
935         int fd, i;
936         char *fname = NULL;
937         if (DEBUGLEVEL < 50) {
938                 return;
939         }
940
941         len = smb_len_tcp(data)+4;
942         for (i=1;i<100;i++) {
943                 fname = talloc_asprintf(talloc_tos(),
944                                 "/tmp/%s.%d.%s",
945                                 name,
946                                 i,
947                                 type ? "req" : "resp");
948                 if (fname == NULL) {
949                         return;
950                 }
951                 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
952                 if (fd != -1 || errno != EEXIST) break;
953                 TALLOC_FREE(fname);
954         }
955         if (fd != -1) {
956                 ssize_t ret = write(fd, data, len);
957                 if (ret != len)
958                         DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
959                 close(fd);
960                 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
961         }
962         TALLOC_FREE(fname);
963 }
964
965 static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
966                                         struct smb_request *req,
967                                         uint8_t type,
968                                         bool *update_session_globalp,
969                                         bool *update_tcon_globalp)
970 {
971         connection_struct *conn = req->conn;
972         struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
973         uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
974         uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
975         bool update_session = false;
976         bool update_tcon = false;
977
978         if (req->encrypted) {
979                 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
980         }
981
982         if (smb1_srv_is_signing_active(req->xconn)) {
983                 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
984         } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
985                 /*
986                  * echo can be unsigned. Session setup except final
987                  * session setup response too
988                  */
989                 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
990         }
991
992         update_session |= smbXsrv_set_crypto_flag(
993                 &session->global->encryption_flags, encrypt_flag);
994         update_session |= smbXsrv_set_crypto_flag(
995                 &session->global->signing_flags, sign_flag);
996
997         if (tcon) {
998                 update_tcon |= smbXsrv_set_crypto_flag(
999                         &tcon->global->encryption_flags, encrypt_flag);
1000                 update_tcon |= smbXsrv_set_crypto_flag(
1001                         &tcon->global->signing_flags, sign_flag);
1002         }
1003
1004         if (update_session) {
1005                 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1006         }
1007
1008         *update_session_globalp = update_session;
1009         *update_tcon_globalp = update_tcon;
1010         return;
1011 }
1012
1013 static void set_current_case_sensitive(connection_struct *conn, uint16_t flags)
1014 {
1015         int snum;
1016         enum remote_arch_types ra_type;
1017
1018         SMB_ASSERT(conn != NULL);
1019         SMB_ASSERT(!conn->sconn->using_smb2);
1020
1021         snum = SNUM(conn);
1022
1023         /*
1024          * Obey the client case sensitivity requests - only for clients that
1025          * support it. */
1026         switch (lp_case_sensitive(snum)) {
1027         case Auto:
1028                 /*
1029                  * We need this ugliness due to DOS/Win9x clients that lie
1030                  * about case insensitivity. */
1031                 ra_type = get_remote_arch();
1032                 if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
1033                         /*
1034                          * Client can't support per-packet case sensitive
1035                          * pathnames. */
1036                         conn->case_sensitive = false;
1037                 } else {
1038                         conn->case_sensitive =
1039                                         !(flags & FLAG_CASELESS_PATHNAMES);
1040                 }
1041         break;
1042         case True:
1043                 conn->case_sensitive = true;
1044                 break;
1045         default:
1046                 conn->case_sensitive = false;
1047                 break;
1048         }
1049 }
1050
1051 /****************************************************************************
1052  Prepare everything for calling the actual request function, and potentially
1053  call the request function via the "new" interface.
1054
1055  Return False if the "legacy" function needs to be called, everything is
1056  prepared.
1057
1058  Return True if we're done.
1059
1060  I know this API sucks, but it is the one with the least code change I could
1061  find.
1062 ****************************************************************************/
1063
1064 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1065 {
1066         const struct loadparm_substitution *lp_sub =
1067                 loadparm_s3_global_substitution();
1068         int flags;
1069         uint64_t session_tag;
1070         connection_struct *conn = NULL;
1071         struct smbXsrv_connection *xconn = req->xconn;
1072         NTTIME now = timeval_to_nttime(&req->request_time);
1073         struct smbXsrv_session *session = NULL;
1074         NTSTATUS status;
1075
1076         errno = 0;
1077
1078         if (!xconn->smb1.negprot.done) {
1079                 switch (type) {
1080                         /*
1081                          * Without a negprot the request must
1082                          * either be a negprot, or one of the
1083                          * evil old SMB mailslot messaging types.
1084                          */
1085                         case SMBnegprot:
1086                         case SMBsendstrt:
1087                         case SMBsendend:
1088                         case SMBsendtxt:
1089                                 break;
1090                         default:
1091                                 exit_server_cleanly("The first request "
1092                                         "should be a negprot");
1093                 }
1094         }
1095
1096         if (smb_messages[type].fn == NULL) {
1097                 DEBUG(0,("Unknown message type %d!\n",type));
1098                 smb_dump("Unknown", 1, (const char *)req->inbuf);
1099                 reply_unknown_new(req, type);
1100                 return NULL;
1101         }
1102
1103         flags = smb_messages[type].flags;
1104
1105         /* In share mode security we must ignore the vuid. */
1106         session_tag = req->vuid;
1107         conn = req->conn;
1108
1109         DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1110                  (int)getpid(), (unsigned long)conn));
1111
1112         smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1113
1114         /* Ensure this value is replaced in the incoming packet. */
1115         SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1116
1117         /*
1118          * Ensure the correct username is in current_user_info.  This is a
1119          * really ugly bugfix for problems with multiple session_setup_and_X's
1120          * being done and allowing %U and %G substitutions to work correctly.
1121          * There is a reason this code is done here, don't move it unless you
1122          * know what you're doing... :-).
1123          * JRA.
1124          */
1125
1126         /*
1127          * lookup an existing session
1128          *
1129          * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1130          * here, the main check is still in change_to_user()
1131          */
1132         status = smb1srv_session_lookup(xconn,
1133                                         session_tag,
1134                                         now,
1135                                         &session);
1136         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1137                 switch (type) {
1138                 case SMBsesssetupX:
1139                         status = NT_STATUS_OK;
1140                         break;
1141                 default:
1142                         DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1143                                  (unsigned long long)session_tag,
1144                                  (unsigned long long)req->mid));
1145                         reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1146                         return conn;
1147                 }
1148         }
1149
1150         if (session != NULL &&
1151             session->global->auth_session_info != NULL &&
1152             !(flags & AS_USER))
1153         {
1154                 /*
1155                  * change_to_user() implies set_current_user_info()
1156                  * and chdir_connect_service().
1157                  *
1158                  * So we only call set_current_user_info if
1159                  * we don't have AS_USER specified.
1160                  */
1161                 set_current_user_info(
1162                         session->global->auth_session_info->unix_info->sanitized_username,
1163                         session->global->auth_session_info->unix_info->unix_name,
1164                         session->global->auth_session_info->info->domain_name);
1165         }
1166
1167         /* Does this call need to be run as the connected user? */
1168         if (flags & AS_USER) {
1169
1170                 /* Does this call need a valid tree connection? */
1171                 if (!conn) {
1172                         /*
1173                          * Amazingly, the error code depends on the command
1174                          * (from Samba4).
1175                          */
1176                         if (type == SMBntcreateX) {
1177                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1178                         } else {
1179                                 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1180                         }
1181                         return NULL;
1182                 }
1183
1184                 set_current_case_sensitive(conn, SVAL(req->inbuf,smb_flg));
1185
1186                 /*
1187                  * change_to_user() implies set_current_user_info()
1188                  * and chdir_connect_service().
1189                  */
1190                 if (!change_to_user_and_service(conn,session_tag)) {
1191                         DEBUG(0, ("Error: Could not change to user. Removing "
1192                                 "deferred open, mid=%llu.\n",
1193                                 (unsigned long long)req->mid));
1194                         reply_force_doserror(req, ERRSRV, ERRbaduid);
1195                         return conn;
1196                 }
1197
1198                 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1199
1200                 /* Does it need write permission? */
1201                 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1202                         reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1203                         return conn;
1204                 }
1205
1206                 /* IPC services are limited */
1207                 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1208                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1209                         return conn;
1210                 }
1211         } else if (flags & AS_GUEST) {
1212                 /*
1213                  * Does this protocol need to be run as guest? (Only archane
1214                  * messenger service requests have this...)
1215                  */
1216                 if (!change_to_guest()) {
1217                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1218                         return conn;
1219                 }
1220         } else {
1221                 /* This call needs to be run as root */
1222                 change_to_root_user();
1223         }
1224
1225         /* load service specific parameters */
1226         if (conn) {
1227                 if (req->encrypted) {
1228                         conn->encrypted_tid = true;
1229                         /* encrypted required from now on. */
1230                         conn->encrypt_level = SMB_SIGNING_REQUIRED;
1231                 } else if (ENCRYPTION_REQUIRED(conn)) {
1232                         if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1233                                 DEBUG(1,("service[%s] requires encryption"
1234                                         "%s ACCESS_DENIED. mid=%llu\n",
1235                                         lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
1236                                         smb_fn_name(type),
1237                                         (unsigned long long)req->mid));
1238                                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1239                                 return conn;
1240                         }
1241                 }
1242
1243                 if (flags & DO_CHDIR) {
1244                         bool ok;
1245
1246                         ok = chdir_current_service(conn);
1247                         if (!ok) {
1248                                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1249                                 return conn;
1250                         }
1251                 }
1252                 conn->num_smb_operations++;
1253         }
1254
1255         /*
1256          * Update encryption and signing state tracking flags that are
1257          * used by smbstatus to display signing and encryption status.
1258          */
1259         if (session != NULL) {
1260                 bool update_session_global = false;
1261                 bool update_tcon_global = false;
1262
1263                 req->session = session;
1264
1265                 smb1srv_update_crypto_flags(session, req, type,
1266                                             &update_session_global,
1267                                             &update_tcon_global);
1268
1269                 if (update_session_global) {
1270                         status = smbXsrv_session_update(session);
1271                         if (!NT_STATUS_IS_OK(status)) {
1272                                 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1273                                 return conn;
1274                         }
1275                 }
1276
1277                 if (update_tcon_global) {
1278                         status = smbXsrv_tcon_update(req->conn->tcon);
1279                         if (!NT_STATUS_IS_OK(status)) {
1280                                 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1281                                 return conn;
1282                         }
1283                 }
1284         }
1285
1286         smb_messages[type].fn(req);
1287         return req->conn;
1288 }
1289
1290 /****************************************************************************
1291  Construct a reply to the incoming packet.
1292 ****************************************************************************/
1293
1294 void construct_reply(struct smbXsrv_connection *xconn,
1295                      char *inbuf,
1296                      int size,
1297                      size_t unread_bytes,
1298                      uint32_t seqnum,
1299                      bool encrypted)
1300 {
1301         struct smbd_server_connection *sconn = xconn->client->sconn;
1302         struct smb_request *req;
1303
1304         if (!(req = talloc(talloc_tos(), struct smb_request))) {
1305                 smb_panic("could not allocate smb_request");
1306         }
1307
1308         if (!init_smb1_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1309                               encrypted, seqnum)) {
1310                 exit_server_cleanly("Invalid SMB request");
1311         }
1312
1313         req->inbuf  = (uint8_t *)talloc_move(req, &inbuf);
1314
1315         req->conn = switch_message(req->cmd, req);
1316
1317         if (req->outbuf == NULL) {
1318                 /*
1319                  * Request has suspended itself, will come
1320                  * back here.
1321                  */
1322                 return;
1323         }
1324         if (CVAL(req->outbuf,0) == 0) {
1325                 show_msg((char *)req->outbuf);
1326         }
1327         smb_request_done(req);
1328 }
1329
1330 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1331                                   char *inbuf,
1332                                   int size,
1333                                   uint32_t seqnum,
1334                                   bool encrypted)
1335 {
1336         struct smb_request **reqs = NULL;
1337         struct smb_request *req;
1338         unsigned num_reqs;
1339         bool ok;
1340
1341         ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
1342                               seqnum, &reqs, &num_reqs);
1343         if (!ok) {
1344                 char errbuf[smb_size];
1345                 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1346                              __LINE__, __FILE__);
1347                 if (!smb1_srv_send(xconn, errbuf, true, seqnum, encrypted)) {
1348                         exit_server_cleanly("construct_reply_chain: "
1349                                             "smb1_srv_send failed.");
1350                 }
1351                 return;
1352         }
1353
1354         req = reqs[0];
1355         req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1356
1357         req->conn = switch_message(req->cmd, req);
1358
1359         if (req->outbuf == NULL) {
1360                 /*
1361                  * Request has suspended itself, will come
1362                  * back here.
1363                  */
1364                 return;
1365         }
1366         smb_request_done(req);
1367 }
1368
1369 /*
1370  * To be called from an async SMB handler that is potentially chained
1371  * when it is finished for shipping.
1372  */
1373
1374 void smb_request_done(struct smb_request *req)
1375 {
1376         struct smb_request **reqs = NULL;
1377         struct smb_request *first_req;
1378         size_t i, num_reqs, next_index;
1379         NTSTATUS status;
1380
1381         if (req->chain == NULL) {
1382                 first_req = req;
1383                 goto shipit;
1384         }
1385
1386         reqs = req->chain;
1387         num_reqs = talloc_array_length(reqs);
1388
1389         for (i=0; i<num_reqs; i++) {
1390                 if (reqs[i] == req) {
1391                         break;
1392                 }
1393         }
1394         if (i == num_reqs) {
1395                 /*
1396                  * Invalid chain, should not happen
1397                  */
1398                 status = NT_STATUS_INTERNAL_ERROR;
1399                 goto error;
1400         }
1401         next_index = i+1;
1402
1403         while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1404                 struct smb_request *next = reqs[next_index];
1405                 struct smbXsrv_tcon *tcon;
1406                 NTTIME now = timeval_to_nttime(&req->request_time);
1407
1408                 next->vuid = SVAL(req->outbuf, smb_uid);
1409                 next->tid  = SVAL(req->outbuf, smb_tid);
1410                 status = smb1srv_tcon_lookup(req->xconn, next->tid,
1411                                              now, &tcon);
1412
1413                 if (NT_STATUS_IS_OK(status)) {
1414                         next->conn = tcon->compat;
1415                 } else {
1416                         next->conn = NULL;
1417                 }
1418                 next->chain_fsp = req->chain_fsp;
1419                 next->inbuf = req->inbuf;
1420
1421                 req = next;
1422                 req->conn = switch_message(req->cmd, req);
1423
1424                 if (req->outbuf == NULL) {
1425                         /*
1426                          * Request has suspended itself, will come
1427                          * back here.
1428                          */
1429                         return;
1430                 }
1431                 next_index += 1;
1432         }
1433
1434         first_req = reqs[0];
1435
1436         for (i=1; i<next_index; i++) {
1437                 bool ok;
1438
1439                 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1440                 if (!ok) {
1441                         status = NT_STATUS_INTERNAL_ERROR;
1442                         goto error;
1443                 }
1444         }
1445
1446         SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1447         SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1448
1449         /*
1450          * This scary statement intends to set the
1451          * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1452          * to the value last_req->outbuf carries
1453          */
1454         SSVAL(first_req->outbuf, smb_flg2,
1455               (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1456               |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1457
1458         /*
1459          * Transfer the error codes from the subrequest to the main one
1460          */
1461         SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1462         SSVAL(first_req->outbuf, smb_err,  SVAL(req->outbuf, smb_err));
1463
1464         _smb_setlen_large(
1465                 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1466
1467 shipit:
1468         if (!smb1_srv_send(first_req->xconn,
1469                            (char *)first_req->outbuf,
1470                            true,
1471                            first_req->seqnum + 1,
1472                            IS_CONN_ENCRYPTED(req->conn) ||
1473                                    first_req->encrypted)) {
1474                 exit_server_cleanly("construct_reply_chain: smb1_srv_send "
1475                                     "failed.");
1476         }
1477         TALLOC_FREE(req);       /* non-chained case */
1478         TALLOC_FREE(reqs);      /* chained case */
1479         return;
1480
1481 error:
1482         {
1483                 char errbuf[smb_size];
1484                 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1485                 if (!smb1_srv_send(req->xconn,
1486                                    errbuf,
1487                                    true,
1488                                    req->seqnum + 1,
1489                                    req->encrypted)) {
1490                         exit_server_cleanly("construct_reply_chain: "
1491                                             "smb1_srv_send failed.");
1492                 }
1493         }
1494         TALLOC_FREE(req);       /* non-chained case */
1495         TALLOC_FREE(reqs);      /* chained case */
1496 }
1497
1498 /****************************************************************************
1499  Process an smb from the client
1500 ****************************************************************************/
1501
1502 void process_smb1(struct smbXsrv_connection *xconn,
1503                   uint8_t *inbuf,
1504                   size_t nread,
1505                   size_t unread_bytes,
1506                   uint32_t seqnum,
1507                   bool encrypted)
1508 {
1509         struct smbd_server_connection *sconn = xconn->client->sconn;
1510
1511         /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1512          * so subtract 4 from it. */
1513         if ((nread < (smb_size - 4)) || !valid_smb1_header(inbuf)) {
1514                 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1515                          smb_len(inbuf)));
1516
1517                 /* special magic for immediate exit */
1518                 if ((nread == 9) &&
1519                     (IVAL(inbuf, 4) == SMB_SUICIDE_PACKET) &&
1520                     lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1521                         uint8_t exitcode = CVAL(inbuf, 8);
1522                         DBG_WARNING("SUICIDE: Exiting immediately with code %d\n",
1523                                     (int)exitcode);
1524                         exit(exitcode);
1525                 }
1526
1527                 exit_server_cleanly("Non-SMB packet");
1528         }
1529
1530         show_msg((char *)inbuf);
1531
1532         if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1533                 construct_reply_chain(xconn,
1534                                       (char *)inbuf,
1535                                       nread,
1536                                       seqnum,
1537                                       encrypted);
1538         } else {
1539                 construct_reply(xconn,
1540                                 (char *)inbuf,
1541                                 nread,
1542                                 unread_bytes,
1543                                 seqnum,
1544                                 encrypted);
1545         }
1546
1547         sconn->trans_num++;
1548 }
1549
1550 /****************************************************************************
1551  Return a string containing the function name of a SMB command.
1552 ****************************************************************************/
1553
1554 const char *smb_fn_name(int type)
1555 {
1556         const char *unknown_name = "SMBunknown";
1557
1558         if (smb_messages[type].name == NULL)
1559                 return(unknown_name);
1560
1561         return(smb_messages[type].name);
1562 }
1563
1564 /****************************************************************************
1565  Helper functions for contruct_reply.
1566 ****************************************************************************/
1567
1568 void add_to_common_flags2(uint32_t v)
1569 {
1570         common_flags2 |= v;
1571 }
1572
1573 void remove_from_common_flags2(uint32_t v)
1574 {
1575         common_flags2 &= ~v;
1576 }
1577
1578 /**
1579  * @brief Find the smb_cmd offset of the last command pushed
1580  * @param[in] buf       The buffer we're building up
1581  * @retval              Where can we put our next andx cmd?
1582  *
1583  * While chaining requests, the "next" request we're looking at needs to put
1584  * its SMB_Command before the data the previous request already built up added
1585  * to the chain. Find the offset to the place where we have to put our cmd.
1586  */
1587
1588 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1589 {
1590         uint8_t cmd;
1591         size_t ofs;
1592
1593         cmd = CVAL(buf, smb_com);
1594
1595         if (!smb1cli_is_andx_req(cmd)) {
1596                 return false;
1597         }
1598
1599         ofs = smb_vwv0;
1600
1601         while (CVAL(buf, ofs) != 0xff) {
1602
1603                 if (!smb1cli_is_andx_req(CVAL(buf, ofs))) {
1604                         return false;
1605                 }
1606
1607                 /*
1608                  * ofs is from start of smb header, so add the 4 length
1609                  * bytes. The next cmd is right after the wct field.
1610                  */
1611                 ofs = SVAL(buf, ofs+2) + 4 + 1;
1612
1613                 if (ofs+4 >= talloc_get_size(buf)) {
1614                         return false;
1615                 }
1616         }
1617
1618         *pofs = ofs;
1619         return true;
1620 }
1621
1622 /**
1623  * @brief Do the smb chaining at a buffer level
1624  * @param[in] poutbuf           Pointer to the talloc'ed buffer to be modified
1625  * @param[in] andx_buf          Buffer to be appended
1626  */
1627
1628 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1629 {
1630         uint8_t smb_command     = CVAL(andx_buf, smb_com);
1631         uint8_t wct             = CVAL(andx_buf, smb_wct);
1632         const uint16_t *vwv     = (const uint16_t *)(andx_buf + smb_vwv);
1633         uint32_t num_bytes      = smb_buflen(andx_buf);
1634         const uint8_t *bytes    = (const uint8_t *)smb_buf_const(andx_buf);
1635
1636         uint8_t *outbuf;
1637         size_t old_size, new_size;
1638         size_t ofs;
1639         size_t chain_padding = 0;
1640         size_t andx_cmd_ofs;
1641
1642
1643         old_size = talloc_get_size(*poutbuf);
1644
1645         if ((old_size % 4) != 0) {
1646                 /*
1647                  * Align the wct field of subsequent requests to a 4-byte
1648                  * boundary
1649                  */
1650                 chain_padding = 4 - (old_size % 4);
1651         }
1652
1653         /*
1654          * After the old request comes the new wct field (1 byte), the vwv's
1655          * and the num_bytes field.
1656          */
1657
1658         new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1659         new_size += num_bytes;
1660
1661         if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1662                 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
1663                           (unsigned)new_size));
1664                 return false;
1665         }
1666
1667         outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1668         if (outbuf == NULL) {
1669                 DEBUG(0, ("talloc failed\n"));
1670                 return false;
1671         }
1672         *poutbuf = outbuf;
1673
1674         if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1675                 DEBUG(1, ("invalid command chain\n"));
1676                 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
1677                 return false;
1678         }
1679
1680         if (chain_padding != 0) {
1681                 memset(outbuf + old_size, 0, chain_padding);
1682                 old_size += chain_padding;
1683         }
1684
1685         SCVAL(outbuf, andx_cmd_ofs, smb_command);
1686         SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1687
1688         ofs = old_size;
1689
1690         /*
1691          * Push the chained request:
1692          *
1693          * wct field
1694          */
1695
1696         SCVAL(outbuf, ofs, wct);
1697         ofs += 1;
1698
1699         /*
1700          * vwv array
1701          */
1702
1703         memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1704
1705         /*
1706          * HACK ALERT
1707          *
1708          * Read&X has an offset into its data buffer at
1709          * vwv[6]. reply_read_andx has no idea anymore that it's
1710          * running from within a chain, so we have to fix up the
1711          * offset here.
1712          *
1713          * Although it looks disgusting at this place, I want to keep
1714          * it here. The alternative would be to push knowledge about
1715          * the andx chain down into read&x again.
1716          */
1717
1718         if (smb_command == SMBreadX) {
1719                 uint8_t *bytes_addr;
1720
1721                 if (wct < 7) {
1722                         /*
1723                          * Invalid read&x response
1724                          */
1725                         return false;
1726                 }
1727
1728                 bytes_addr = outbuf + ofs        /* vwv start */
1729                         + sizeof(uint16_t) * wct /* vwv array */
1730                         + sizeof(uint16_t)       /* bcc */
1731                         + 1;                     /* padding byte */
1732
1733                 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
1734                       bytes_addr - outbuf - 4);
1735         }
1736
1737         ofs += sizeof(uint16_t) * wct;
1738
1739         /*
1740          * bcc (byte count)
1741          */
1742
1743         SSVAL(outbuf, ofs, num_bytes);
1744         ofs += sizeof(uint16_t);
1745
1746         /*
1747          * The bytes field
1748          */
1749
1750         memcpy(outbuf + ofs, bytes, num_bytes);
1751
1752         return true;
1753 }
1754
1755 bool smb1_is_chain(const uint8_t *buf)
1756 {
1757         uint8_t cmd, wct, andx_cmd;
1758
1759         cmd = CVAL(buf, smb_com);
1760         if (!smb1cli_is_andx_req(cmd)) {
1761                 return false;
1762         }
1763         wct = CVAL(buf, smb_wct);
1764         if (wct < 2) {
1765                 return false;
1766         }
1767         andx_cmd = CVAL(buf, smb_vwv);
1768         return (andx_cmd != 0xFF);
1769 }
1770
1771 bool smb1_walk_chain(const uint8_t *buf,
1772                      bool (*fn)(uint8_t cmd,
1773                                 uint8_t wct, const uint16_t *vwv,
1774                                 uint16_t num_bytes, const uint8_t *bytes,
1775                                 void *private_data),
1776                      void *private_data)
1777 {
1778         size_t smblen = smb_len(buf);
1779         const char *smb_buf = smb_base(buf);
1780         uint8_t cmd, chain_cmd;
1781         uint8_t wct;
1782         const uint16_t *vwv;
1783         uint16_t num_bytes;
1784         const uint8_t *bytes;
1785
1786         cmd = CVAL(buf, smb_com);
1787         wct = CVAL(buf, smb_wct);
1788         vwv = (const uint16_t *)(buf + smb_vwv);
1789         num_bytes = smb_buflen(buf);
1790         bytes = (const uint8_t *)smb_buf_const(buf);
1791
1792         if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
1793                 return false;
1794         }
1795
1796         if (!smb1cli_is_andx_req(cmd)) {
1797                 return true;
1798         }
1799         if (wct < 2) {
1800                 return false;
1801         }
1802
1803         chain_cmd = CVAL(vwv, 0);
1804
1805         while (chain_cmd != 0xff) {
1806                 uint32_t chain_offset;  /* uint32_t to avoid overflow */
1807                 size_t length_needed;
1808                 ptrdiff_t vwv_offset;
1809
1810                 chain_offset = SVAL(vwv+1, 0);
1811
1812                 /*
1813                  * Check if the client tries to fool us. The chain
1814                  * offset needs to point beyond the current request in
1815                  * the chain, it needs to strictly grow. Otherwise we
1816                  * might be tricked into an endless loop always
1817                  * processing the same request over and over again. We
1818                  * used to assume that vwv and the byte buffer array
1819                  * in a chain are always attached, but OS/2 the
1820                  * Write&X/Read&X chain puts the Read&X vwv array
1821                  * right behind the Write&X vwv chain. The Write&X bcc
1822                  * array is put behind the Read&X vwv array. So now we
1823                  * check whether the chain offset points strictly
1824                  * behind the previous vwv array. req->buf points
1825                  * right after the vwv array of the previous
1826                  * request. See
1827                  * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
1828                  * more information.
1829                  */
1830
1831                 vwv_offset = ((const char *)vwv - smb_buf);
1832                 if (chain_offset <= vwv_offset) {
1833                         return false;
1834                 }
1835
1836                 /*
1837                  * Next check: Make sure the chain offset does not
1838                  * point beyond the overall smb request length.
1839                  */
1840
1841                 length_needed = chain_offset+1; /* wct */
1842                 if (length_needed > smblen) {
1843                         return false;
1844                 }
1845
1846                 /*
1847                  * Now comes the pointer magic. Goal here is to set up
1848                  * vwv and buf correctly again. The chain offset (the
1849                  * former vwv[1]) points at the new wct field.
1850                  */
1851
1852                 wct = CVAL(smb_buf, chain_offset);
1853
1854                 if (smb1cli_is_andx_req(chain_cmd) && (wct < 2)) {
1855                         return false;
1856                 }
1857
1858                 /*
1859                  * Next consistency check: Make the new vwv array fits
1860                  * in the overall smb request.
1861                  */
1862
1863                 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
1864                 if (length_needed > smblen) {
1865                         return false;
1866                 }
1867                 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
1868
1869                 /*
1870                  * Now grab the new byte buffer....
1871                  */
1872
1873                 num_bytes = SVAL(vwv+wct, 0);
1874
1875                 /*
1876                  * .. and check that it fits.
1877                  */
1878
1879                 length_needed += num_bytes;
1880                 if (length_needed > smblen) {
1881                         return false;
1882                 }
1883                 bytes = (const uint8_t *)(vwv+wct+1);
1884
1885                 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
1886                         return false;
1887                 }
1888
1889                 if (!smb1cli_is_andx_req(chain_cmd)) {
1890                         return true;
1891                 }
1892                 chain_cmd = CVAL(vwv, 0);
1893         }
1894         return true;
1895 }
1896
1897 static bool smb1_chain_length_cb(uint8_t cmd,
1898                                  uint8_t wct, const uint16_t *vwv,
1899                                  uint16_t num_bytes, const uint8_t *bytes,
1900                                  void *private_data)
1901 {
1902         unsigned *count = (unsigned *)private_data;
1903         *count += 1;
1904         return true;
1905 }
1906
1907 unsigned smb1_chain_length(const uint8_t *buf)
1908 {
1909         unsigned count = 0;
1910
1911         if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
1912                 return 0;
1913         }
1914         return count;
1915 }
1916
1917 struct smb1_parse_chain_state {
1918         TALLOC_CTX *mem_ctx;
1919         const uint8_t *buf;
1920         struct smbd_server_connection *sconn;
1921         struct smbXsrv_connection *xconn;
1922         bool encrypted;
1923         uint32_t seqnum;
1924
1925         struct smb_request **reqs;
1926         unsigned num_reqs;
1927 };
1928
1929 static bool smb1_parse_chain_cb(uint8_t cmd,
1930                                 uint8_t wct, const uint16_t *vwv,
1931                                 uint16_t num_bytes, const uint8_t *bytes,
1932                                 void *private_data)
1933 {
1934         struct smb1_parse_chain_state *state =
1935                 (struct smb1_parse_chain_state *)private_data;
1936         struct smb_request **reqs;
1937         struct smb_request *req;
1938         bool ok;
1939
1940         reqs = talloc_realloc(state->mem_ctx, state->reqs,
1941                               struct smb_request *, state->num_reqs+1);
1942         if (reqs == NULL) {
1943                 return false;
1944         }
1945         state->reqs = reqs;
1946
1947         req = talloc(reqs, struct smb_request);
1948         if (req == NULL) {
1949                 return false;
1950         }
1951
1952         ok = init_smb1_request(req, state->sconn, state->xconn, state->buf, 0,
1953                               state->encrypted, state->seqnum);
1954         if (!ok) {
1955                 return false;
1956         }
1957         req->cmd = cmd;
1958         req->wct = wct;
1959         req->vwv = vwv;
1960         req->buflen = num_bytes;
1961         req->buf = bytes;
1962
1963         reqs[state->num_reqs] = req;
1964         state->num_reqs += 1;
1965         return true;
1966 }
1967
1968 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
1969                       struct smbXsrv_connection *xconn,
1970                       bool encrypted, uint32_t seqnum,
1971                       struct smb_request ***reqs, unsigned *num_reqs)
1972 {
1973         struct smbd_server_connection *sconn = NULL;
1974         struct smb1_parse_chain_state state;
1975         unsigned i;
1976
1977         if (xconn != NULL) {
1978                 sconn = xconn->client->sconn;
1979         }
1980
1981         state.mem_ctx = mem_ctx;
1982         state.buf = buf;
1983         state.sconn = sconn;
1984         state.xconn = xconn;
1985         state.encrypted = encrypted;
1986         state.seqnum = seqnum;
1987         state.reqs = NULL;
1988         state.num_reqs = 0;
1989
1990         if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
1991                 TALLOC_FREE(state.reqs);
1992                 return false;
1993         }
1994         for (i=0; i<state.num_reqs; i++) {
1995                 state.reqs[i]->chain = state.reqs;
1996         }
1997         *reqs = state.reqs;
1998         *num_reqs = state.num_reqs;
1999         return true;
2000 }
2001
2002 static bool fd_is_readable(int fd)
2003 {
2004         int ret, revents;
2005
2006         ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2007
2008         return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2009
2010 }
2011
2012 static void smbd_server_connection_write_handler(
2013         struct smbXsrv_connection *xconn)
2014 {
2015         /* TODO: make write nonblocking */
2016 }
2017
2018 void smbd_smb1_server_connection_read_handler(struct smbXsrv_connection *xconn,
2019                                               int fd)
2020 {
2021         uint8_t *inbuf = NULL;
2022         size_t inbuf_len = 0;
2023         size_t unread_bytes = 0;
2024         bool encrypted = false;
2025         TALLOC_CTX *mem_ctx = talloc_tos();
2026         NTSTATUS status;
2027         uint32_t seqnum;
2028
2029         bool async_echo = lp_async_smb_echo_handler();
2030         bool from_client = false;
2031
2032         if (async_echo) {
2033                 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2034                         /*
2035                          * This is the super-ugly hack to prefer the packets
2036                          * forwarded by the echo handler over the ones by the
2037                          * client directly
2038                          */
2039                         fd = xconn->smb1.echo_handler.trusted_fd;
2040                 }
2041         }
2042
2043         from_client = (xconn->transport.sock == fd);
2044
2045         if (async_echo && from_client) {
2046                 smbd_lock_socket(xconn);
2047
2048                 if (!fd_is_readable(fd)) {
2049                         DEBUG(10,("the echo listener was faster\n"));
2050                         smbd_unlock_socket(xconn);
2051                         return;
2052                 }
2053         }
2054
2055         /* TODO: make this completely nonblocking */
2056         status = receive_smb_talloc(mem_ctx, xconn, fd,
2057                                     (char **)(void *)&inbuf,
2058                                     0, /* timeout */
2059                                     &unread_bytes,
2060                                     &encrypted,
2061                                     &inbuf_len, &seqnum,
2062                                     !from_client /* trusted channel */);
2063
2064         if (async_echo && from_client) {
2065                 smbd_unlock_socket(xconn);
2066         }
2067
2068         if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2069                 goto process;
2070         }
2071         if (NT_STATUS_IS_ERR(status)) {
2072                 exit_server_cleanly("failed to receive smb request");
2073         }
2074         if (!NT_STATUS_IS_OK(status)) {
2075                 return;
2076         }
2077
2078 process:
2079         process_smb(xconn, inbuf, inbuf_len, unread_bytes, seqnum, encrypted);
2080 }
2081
2082 static void smbd_server_echo_handler(struct tevent_context *ev,
2083                                      struct tevent_fd *fde,
2084                                      uint16_t flags,
2085                                      void *private_data)
2086 {
2087         struct smbXsrv_connection *xconn =
2088                 talloc_get_type_abort(private_data,
2089                 struct smbXsrv_connection);
2090
2091         if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2092                 /*
2093                  * we're not supposed to do any io
2094                  */
2095                 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2096                 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2097                 return;
2098         }
2099
2100         if (flags & TEVENT_FD_WRITE) {
2101                 smbd_server_connection_write_handler(xconn);
2102                 return;
2103         }
2104         if (flags & TEVENT_FD_READ) {
2105                 smbd_smb1_server_connection_read_handler(
2106                         xconn, xconn->smb1.echo_handler.trusted_fd);
2107                 return;
2108         }
2109 }
2110
2111 /*
2112  * Send keepalive packets to our client
2113  */
2114 bool keepalive_fn(const struct timeval *now, void *private_data)
2115 {
2116         struct smbd_server_connection *sconn = talloc_get_type_abort(
2117                 private_data, struct smbd_server_connection);
2118         struct smbXsrv_connection *xconn = NULL;
2119         bool ret;
2120
2121         if (sconn->using_smb2) {
2122                 /* Don't do keepalives on an SMB2 connection. */
2123                 return false;
2124         }
2125
2126         /*
2127          * With SMB1 we only have 1 connection
2128          */
2129         xconn = sconn->client->connections;
2130         smbd_lock_socket(xconn);
2131         ret = send_keepalive(xconn->transport.sock);
2132         smbd_unlock_socket(xconn);
2133
2134         if (!ret) {
2135                 int saved_errno = errno;
2136                 /*
2137                  * Try and give an error message saying what
2138                  * client failed.
2139                  */
2140                 DEBUG(0, ("send_keepalive failed for client %s. "
2141                           "Error %s - exiting\n",
2142                           smbXsrv_connection_dbg(xconn),
2143                           strerror(saved_errno)));
2144                 errno = saved_errno;
2145                 return False;
2146         }
2147         return True;
2148 }
2149
2150 /*
2151  * Read an smb packet in the echo handler child, giving the parent
2152  * smbd one second to react once the socket becomes readable.
2153  */
2154
2155 struct smbd_echo_read_state {
2156         struct tevent_context *ev;
2157         struct smbXsrv_connection *xconn;
2158
2159         char *buf;
2160         size_t buflen;
2161         uint32_t seqnum;
2162 };
2163
2164 static void smbd_echo_read_readable(struct tevent_req *subreq);
2165 static void smbd_echo_read_waited(struct tevent_req *subreq);
2166
2167 static struct tevent_req *smbd_echo_read_send(
2168         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2169         struct smbXsrv_connection *xconn)
2170 {
2171         struct tevent_req *req, *subreq;
2172         struct smbd_echo_read_state *state;
2173
2174         req = tevent_req_create(mem_ctx, &state,
2175                                 struct smbd_echo_read_state);
2176         if (req == NULL) {
2177                 return NULL;
2178         }
2179         state->ev = ev;
2180         state->xconn = xconn;
2181
2182         subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2183         if (tevent_req_nomem(subreq, req)) {
2184                 return tevent_req_post(req, ev);
2185         }
2186         tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2187         return req;
2188 }
2189
2190 static void smbd_echo_read_readable(struct tevent_req *subreq)
2191 {
2192         struct tevent_req *req = tevent_req_callback_data(
2193                 subreq, struct tevent_req);
2194         struct smbd_echo_read_state *state = tevent_req_data(
2195                 req, struct smbd_echo_read_state);
2196         bool ok;
2197         int err;
2198
2199         ok = wait_for_read_recv(subreq, &err);
2200         TALLOC_FREE(subreq);
2201         if (!ok) {
2202                 tevent_req_nterror(req, map_nt_error_from_unix(err));
2203                 return;
2204         }
2205
2206         /*
2207          * Give the parent smbd one second to step in
2208          */
2209
2210         subreq = tevent_wakeup_send(
2211                 state, state->ev, timeval_current_ofs(1, 0));
2212         if (tevent_req_nomem(subreq, req)) {
2213                 return;
2214         }
2215         tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2216 }
2217
2218 static void smbd_echo_read_waited(struct tevent_req *subreq)
2219 {
2220         struct tevent_req *req = tevent_req_callback_data(
2221                 subreq, struct tevent_req);
2222         struct smbd_echo_read_state *state = tevent_req_data(
2223                 req, struct smbd_echo_read_state);
2224         struct smbXsrv_connection *xconn = state->xconn;
2225         bool ok;
2226         NTSTATUS status;
2227         size_t unread = 0;
2228         bool encrypted;
2229
2230         ok = tevent_wakeup_recv(subreq);
2231         TALLOC_FREE(subreq);
2232         if (!ok) {
2233                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2234                 return;
2235         }
2236
2237         ok = smbd_lock_socket_internal(xconn);
2238         if (!ok) {
2239                 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2240                 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2241                 return;
2242         }
2243
2244         if (!fd_is_readable(xconn->transport.sock)) {
2245                 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2246                           (int)getpid()));
2247
2248                 ok = smbd_unlock_socket_internal(xconn);
2249                 if (!ok) {
2250                         tevent_req_nterror(req, map_nt_error_from_unix(errno));
2251                         DEBUG(1, ("%s: failed to unlock socket\n",
2252                                 __location__));
2253                         return;
2254                 }
2255
2256                 subreq = wait_for_read_send(state, state->ev,
2257                                             xconn->transport.sock, false);
2258                 if (tevent_req_nomem(subreq, req)) {
2259                         return;
2260                 }
2261                 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2262                 return;
2263         }
2264
2265         status = receive_smb_talloc(state, xconn,
2266                                     xconn->transport.sock,
2267                                     &state->buf,
2268                                     0 /* timeout */,
2269                                     &unread,
2270                                     &encrypted,
2271                                     &state->buflen,
2272                                     &state->seqnum,
2273                                     false /* trusted_channel*/);
2274
2275         if (tevent_req_nterror(req, status)) {
2276                 tevent_req_nterror(req, status);
2277                 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2278                           (int)getpid(), nt_errstr(status)));
2279                 return;
2280         }
2281
2282         ok = smbd_unlock_socket_internal(xconn);
2283         if (!ok) {
2284                 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2285                 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2286                 return;
2287         }
2288         tevent_req_done(req);
2289 }
2290
2291 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2292                                     char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2293 {
2294         struct smbd_echo_read_state *state = tevent_req_data(
2295                 req, struct smbd_echo_read_state);
2296         NTSTATUS status;
2297
2298         if (tevent_req_is_nterror(req, &status)) {
2299                 return status;
2300         }
2301         *pbuf = talloc_move(mem_ctx, &state->buf);
2302         *pbuflen = state->buflen;
2303         *pseqnum = state->seqnum;
2304         return NT_STATUS_OK;
2305 }
2306
2307 struct smbd_echo_state {
2308         struct tevent_context *ev;
2309         struct iovec *pending;
2310         struct smbd_server_connection *sconn;
2311         struct smbXsrv_connection *xconn;
2312         int parent_pipe;
2313
2314         struct tevent_fd *parent_fde;
2315
2316         struct tevent_req *write_req;
2317 };
2318
2319 static void smbd_echo_writer_done(struct tevent_req *req);
2320
2321 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2322 {
2323         int num_pending;
2324
2325         if (state->write_req != NULL) {
2326                 return;
2327         }
2328
2329         num_pending = talloc_array_length(state->pending);
2330         if (num_pending == 0) {
2331                 return;
2332         }
2333
2334         state->write_req = writev_send(state, state->ev, NULL,
2335                                        state->parent_pipe, false,
2336                                        state->pending, num_pending);
2337         if (state->write_req == NULL) {
2338                 DEBUG(1, ("writev_send failed\n"));
2339                 exit(1);
2340         }
2341
2342         talloc_steal(state->write_req, state->pending);
2343         state->pending = NULL;
2344
2345         tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2346                                 state);
2347 }
2348
2349 static void smbd_echo_writer_done(struct tevent_req *req)
2350 {
2351         struct smbd_echo_state *state = tevent_req_callback_data(
2352                 req, struct smbd_echo_state);
2353         ssize_t written;
2354         int err;
2355
2356         written = writev_recv(req, &err);
2357         TALLOC_FREE(req);
2358         state->write_req = NULL;
2359         if (written == -1) {
2360                 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2361                 exit(1);
2362         }
2363         DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2364         smbd_echo_activate_writer(state);
2365 }
2366
2367 static bool smbd_echo_reply(struct smbd_echo_state *state,
2368                             uint8_t *inbuf, size_t inbuf_len,
2369                             uint32_t seqnum)
2370 {
2371         struct smb_request req;
2372         uint16_t num_replies;
2373         char *outbuf;
2374         bool ok;
2375
2376         if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2377                 DEBUG(10, ("Got netbios keepalive\n"));
2378                 /*
2379                  * Just swallow it
2380                  */
2381                 return true;
2382         }
2383
2384         if (inbuf_len < smb_size) {
2385                 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2386                 return false;
2387         }
2388         if (!valid_smb1_header(inbuf)) {
2389                 DEBUG(10, ("Got invalid SMB header\n"));
2390                 return false;
2391         }
2392
2393         if (!init_smb1_request(&req, state->sconn, state->xconn, inbuf, 0, false,
2394                               seqnum)) {
2395                 return false;
2396         }
2397         req.inbuf = inbuf;
2398
2399         DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2400                    smb_fn_name(req.cmd)));
2401
2402         if (req.cmd != SMBecho) {
2403                 return false;
2404         }
2405         if (req.wct < 1) {
2406                 return false;
2407         }
2408
2409         num_replies = SVAL(req.vwv+0, 0);
2410         if (num_replies != 1) {
2411                 /* Not a Windows "Hey, you're still there?" request */
2412                 return false;
2413         }
2414
2415         if (!create_smb1_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
2416                            1, req.buflen)) {
2417                 DEBUG(10, ("create_smb1_outbuf failed\n"));
2418                 return false;
2419         }
2420         req.outbuf = (uint8_t *)outbuf;
2421
2422         SSVAL(req.outbuf, smb_vwv0, num_replies);
2423
2424         if (req.buflen > 0) {
2425                 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2426         }
2427
2428         ok = smb1_srv_send(req.xconn, (char *)outbuf, true, seqnum + 1, false);
2429         TALLOC_FREE(outbuf);
2430         if (!ok) {
2431                 exit(1);
2432         }
2433
2434         return true;
2435 }
2436
2437 static void smbd_echo_exit(struct tevent_context *ev,
2438                            struct tevent_fd *fde, uint16_t flags,
2439                            void *private_data)
2440 {
2441         DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2442         exit(0);
2443 }
2444
2445 static void smbd_echo_got_packet(struct tevent_req *req);
2446
2447 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
2448                            int parent_pipe)
2449 {
2450         struct smbd_echo_state *state;
2451         struct tevent_req *read_req;
2452
2453         state = talloc_zero(xconn, struct smbd_echo_state);
2454         if (state == NULL) {
2455                 DEBUG(1, ("talloc failed\n"));
2456                 return;
2457         }
2458         state->xconn = xconn;
2459         state->parent_pipe = parent_pipe;
2460         state->ev = samba_tevent_context_init(state);
2461         if (state->ev == NULL) {
2462                 DEBUG(1, ("samba_tevent_context_init failed\n"));
2463                 TALLOC_FREE(state);
2464                 return;
2465         }
2466         state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2467                                         TEVENT_FD_READ, smbd_echo_exit,
2468                                         state);
2469         if (state->parent_fde == NULL) {
2470                 DEBUG(1, ("tevent_add_fd failed\n"));
2471                 TALLOC_FREE(state);
2472                 return;
2473         }
2474
2475         read_req = smbd_echo_read_send(state, state->ev, xconn);
2476         if (read_req == NULL) {
2477                 DEBUG(1, ("smbd_echo_read_send failed\n"));
2478                 TALLOC_FREE(state);
2479                 return;
2480         }
2481         tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2482
2483         while (true) {
2484                 if (tevent_loop_once(state->ev) == -1) {
2485                         DEBUG(1, ("tevent_loop_once failed: %s\n",
2486                                   strerror(errno)));
2487                         break;
2488                 }
2489         }
2490         TALLOC_FREE(state);
2491 }
2492
2493 static void smbd_echo_got_packet(struct tevent_req *req)
2494 {
2495         struct smbd_echo_state *state = tevent_req_callback_data(
2496                 req, struct smbd_echo_state);
2497         NTSTATUS status;
2498         char *buf = NULL;
2499         size_t buflen = 0;
2500         uint32_t seqnum = 0;
2501         bool reply;
2502
2503         status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2504         TALLOC_FREE(req);
2505         if (!NT_STATUS_IS_OK(status)) {
2506                 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2507                           nt_errstr(status)));
2508                 exit(1);
2509         }
2510
2511         reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2512         if (!reply) {
2513                 size_t num_pending;
2514                 struct iovec *tmp;
2515                 struct iovec *iov;
2516
2517                 num_pending = talloc_array_length(state->pending);
2518                 tmp = talloc_realloc(state, state->pending, struct iovec,
2519                                      num_pending+1);
2520                 if (tmp == NULL) {
2521                         DEBUG(1, ("talloc_realloc failed\n"));
2522                         exit(1);
2523                 }
2524                 state->pending = tmp;
2525
2526                 if (buflen >= smb_size) {
2527                         /*
2528                          * place the seqnum in the packet so that the main process
2529                          * can reply with signing
2530                          */
2531                         SIVAL(buf, smb_ss_field, seqnum);
2532                         SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2533                 }
2534
2535                 iov = &state->pending[num_pending];
2536                 iov->iov_base = talloc_move(state->pending, &buf);
2537                 iov->iov_len = buflen;
2538
2539                 DEBUG(10,("echo_handler[%d]: forward to main\n",
2540                           (int)getpid()));
2541                 smbd_echo_activate_writer(state);
2542         }
2543
2544         req = smbd_echo_read_send(state, state->ev, state->xconn);
2545         if (req == NULL) {
2546                 DEBUG(1, ("smbd_echo_read_send failed\n"));
2547                 exit(1);
2548         }
2549         tevent_req_set_callback(req, smbd_echo_got_packet, state);
2550 }
2551
2552
2553 /*
2554  * Handle SMBecho requests in a forked child process
2555  */
2556 bool fork_echo_handler(struct smbXsrv_connection *xconn)
2557 {
2558         int listener_pipe[2];
2559         int res;
2560         pid_t child;
2561         bool use_mutex = false;
2562
2563         res = pipe(listener_pipe);
2564         if (res == -1) {
2565                 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2566                 return false;
2567         }
2568
2569 #ifdef HAVE_ROBUST_MUTEXES
2570         use_mutex = tdb_runtime_check_for_robust_mutexes();
2571
2572         if (use_mutex) {
2573                 pthread_mutexattr_t a;
2574
2575                 xconn->smb1.echo_handler.socket_mutex =
2576                         anonymous_shared_allocate(sizeof(pthread_mutex_t));
2577                 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
2578                         DEBUG(1, ("Could not create mutex shared memory: %s\n",
2579                                   strerror(errno)));
2580                         goto fail;
2581                 }
2582
2583                 res = pthread_mutexattr_init(&a);
2584                 if (res != 0) {
2585                         DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
2586                                   strerror(res)));
2587                         goto fail;
2588                 }
2589                 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
2590                 if (res != 0) {
2591                         DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
2592                                   strerror(res)));
2593                         pthread_mutexattr_destroy(&a);
2594                         goto fail;
2595                 }
2596                 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
2597                 if (res != 0) {
2598                         DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
2599                                   strerror(res)));
2600                         pthread_mutexattr_destroy(&a);
2601                         goto fail;
2602                 }
2603                 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
2604                 if (res != 0) {
2605                         DEBUG(1, ("pthread_mutexattr_setrobust failed: "
2606                                   "%s\n", strerror(res)));
2607                         pthread_mutexattr_destroy(&a);
2608                         goto fail;
2609                 }
2610                 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
2611                                          &a);
2612                 pthread_mutexattr_destroy(&a);
2613                 if (res != 0) {
2614                         DEBUG(1, ("pthread_mutex_init failed: %s\n",
2615                                   strerror(res)));
2616                         goto fail;
2617                 }
2618         }
2619 #endif
2620
2621         if (!use_mutex) {
2622                 xconn->smb1.echo_handler.socket_lock_fd =
2623                         create_unlink_tmp(lp_lock_directory());
2624                 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
2625                         DEBUG(1, ("Could not create lock fd: %s\n",
2626                                   strerror(errno)));
2627                         goto fail;
2628                 }
2629         }
2630
2631         child = fork();
2632         if (child == 0) {
2633                 NTSTATUS status;
2634
2635                 close(listener_pipe[0]);
2636                 set_blocking(listener_pipe[1], false);
2637
2638                 status = smbd_reinit_after_fork(xconn->client->msg_ctx,
2639                                                 xconn->client->raw_ev_ctx,
2640                                                 true);
2641                 if (!NT_STATUS_IS_OK(status)) {
2642                         DEBUG(1, ("reinit_after_fork failed: %s\n",
2643                                   nt_errstr(status)));
2644                         exit(1);
2645                 }
2646                 process_set_title("smbd-echo", "echo handler");
2647                 initialize_password_db(true, xconn->client->raw_ev_ctx);
2648                 smbd_echo_loop(xconn, listener_pipe[1]);
2649                 exit(0);
2650         }
2651         close(listener_pipe[1]);
2652         listener_pipe[1] = -1;
2653         xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2654
2655         DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
2656
2657         /*
2658          * Without smb signing this is the same as the normal smbd
2659          * listener. This needs to change once signing comes in.
2660          */
2661         xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(
2662                                         xconn->client->raw_ev_ctx,
2663                                         xconn,
2664                                         xconn->smb1.echo_handler.trusted_fd,
2665                                         TEVENT_FD_READ,
2666                                         smbd_server_echo_handler,
2667                                         xconn);
2668         if (xconn->smb1.echo_handler.trusted_fde == NULL) {
2669                 DEBUG(1, ("event_add_fd failed\n"));
2670                 goto fail;
2671         }
2672
2673         return true;
2674
2675 fail:
2676         if (listener_pipe[0] != -1) {
2677                 close(listener_pipe[0]);
2678         }
2679         if (listener_pipe[1] != -1) {
2680                 close(listener_pipe[1]);
2681         }
2682         if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
2683                 close(xconn->smb1.echo_handler.socket_lock_fd);
2684         }
2685 #ifdef HAVE_ROBUST_MUTEXES
2686         if (xconn->smb1.echo_handler.socket_mutex != NULL) {
2687                 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
2688                 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
2689         }
2690 #endif
2691         smbd_echo_init(xconn);
2692
2693         return false;
2694 }
2695
2696 bool req_is_in_chain(const struct smb_request *req)
2697 {
2698         if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
2699                 /*
2700                  * We're right now handling a subsequent request, so we must
2701                  * be in a chain
2702                  */
2703                 return true;
2704         }
2705
2706         if (!smb1cli_is_andx_req(req->cmd)) {
2707                 return false;
2708         }
2709
2710         if (req->wct < 2) {
2711                 /*
2712                  * Okay, an illegal request, but definitely not chained :-)
2713                  */
2714                 return false;
2715         }
2716
2717         return (CVAL(req->vwv+0, 0) != 0xFF);
2718 }