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