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