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