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