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