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