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