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