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