Fix bug #5477 - recvfile code was broken.
[Samba.git] / source / smbd / process.c
blobc8ad19dd15ca797a243564dca30a6b73183f823d
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
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.
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.
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/>.
21 #include "includes.h"
23 extern int smb_echo_count;
26 * Size of data we can send to client. Set
27 * by the client for all protocols above CORE.
28 * Set by us for CORE protocol.
30 int max_send = BUFFER_SIZE;
32 * Size of the data we can receive. Set by us.
33 * Can be modified by the max xmit parameter.
35 int max_recv = BUFFER_SIZE;
37 SIG_ATOMIC_T reload_after_sighup = 0;
38 SIG_ATOMIC_T got_sig_term = 0;
39 extern bool global_machine_password_needs_changing;
40 extern int max_send;
42 /* Accessor function for smb_read_error for smbd functions. */
44 /****************************************************************************
45 Send an smb to a fd.
46 ****************************************************************************/
48 bool srv_send_smb(int fd, char *buffer, bool do_encrypt)
50 size_t len;
51 size_t nwritten=0;
52 ssize_t ret;
53 char *buf_out = buffer;
55 /* Sign the outgoing packet if required. */
56 srv_calculate_sign_mac(buf_out);
58 if (do_encrypt) {
59 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
60 if (!NT_STATUS_IS_OK(status)) {
61 DEBUG(0, ("send_smb: SMB encryption failed "
62 "on outgoing packet! Error %s\n",
63 nt_errstr(status) ));
64 return false;
68 len = smb_len(buf_out) + 4;
70 while (nwritten < len) {
71 ret = write_data(fd,buf_out+nwritten,len - nwritten);
72 if (ret <= 0) {
73 DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
74 (int)len,(int)ret, strerror(errno) ));
75 srv_free_enc_buffer(buf_out);
76 return false;
78 nwritten += ret;
81 srv_free_enc_buffer(buf_out);
82 return true;
85 /*******************************************************************
86 Setup the word count and byte count for a smb message.
87 ********************************************************************/
89 int srv_set_message(char *buf,
90 int num_words,
91 int num_bytes,
92 bool zero)
94 if (zero && (num_words || num_bytes)) {
95 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
97 SCVAL(buf,smb_wct,num_words);
98 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
99 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
100 return (smb_size + num_words*2 + num_bytes);
103 static bool valid_smb_header(const uint8_t *inbuf)
105 if (is_encrypted_packet(inbuf)) {
106 return true;
108 return (strncmp(smb_base(inbuf),"\377SMB",4) == 0);
111 /* Socket functions for smbd packet processing. */
113 static bool valid_packet_size(size_t len)
116 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
117 * of header. Don't print the error if this fits.... JRA.
120 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
121 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
122 (unsigned long)len));
123 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) {
124 return false;
127 return true;
130 static NTSTATUS read_packet_remainder(int fd, char *buffer,
131 unsigned int timeout, ssize_t len)
133 if (len <= 0) {
134 return NT_STATUS_OK;
137 return read_socket_with_timeout(fd, buffer, len, len, timeout, NULL);
140 /****************************************************************************
141 Attempt a zerocopy writeX read. We know here that len > smb_size-4
142 ****************************************************************************/
145 * Unfortunately, earlier versions of smbclient/libsmbclient
146 * don't send this "standard" writeX header. I've fixed this
147 * for 3.2 but we'll use the old method with earlier versions.
148 * Windows and CIFSFS at least use this standard size. Not
149 * sure about MacOSX.
152 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
153 (2*14) + /* word count (including bcc) */ \
154 1 /* pad byte */)
156 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
157 const char lenbuf[4],
158 int fd, char **buffer,
159 unsigned int timeout,
160 size_t *p_unread,
161 size_t *len_ret)
163 /* Size of a WRITEX call (+4 byte len). */
164 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
165 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
166 ssize_t toread;
167 NTSTATUS status;
169 memcpy(writeX_header, lenbuf, sizeof(lenbuf));
171 status = read_socket_with_timeout(
172 fd, writeX_header + 4,
173 STANDARD_WRITE_AND_X_HEADER_SIZE,
174 STANDARD_WRITE_AND_X_HEADER_SIZE,
175 timeout, NULL);
177 if (!NT_STATUS_IS_OK(status)) {
178 return status;
182 * Ok - now try and see if this is a possible
183 * valid writeX call.
186 if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
188 * If the data offset is beyond what
189 * we've read, drain the extra bytes.
191 uint16_t doff = SVAL(writeX_header,smb_vwv11);
192 ssize_t newlen;
194 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
195 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
196 if (drain_socket(smbd_server_fd(), drain) != drain) {
197 smb_panic("receive_smb_raw_talloc_partial_read:"
198 " failed to drain pending bytes");
200 } else {
201 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
204 /* Spoof down the length and null out the bcc. */
205 set_message_bcc(writeX_header, 0);
206 newlen = smb_len(writeX_header);
208 /* Copy the header we've written. */
210 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
211 writeX_header,
212 sizeof(writeX_header));
214 if (*buffer == NULL) {
215 DEBUG(0, ("Could not allocate inbuf of length %d\n",
216 (int)sizeof(writeX_header)));
217 return NT_STATUS_NO_MEMORY;
220 /* Work out the remaining bytes. */
221 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
222 *len_ret = newlen + 4;
223 return NT_STATUS_OK;
226 if (!valid_packet_size(len)) {
227 return NT_STATUS_INVALID_PARAMETER;
231 * Not a valid writeX call. Just do the standard
232 * talloc and return.
235 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
237 if (*buffer == NULL) {
238 DEBUG(0, ("Could not allocate inbuf of length %d\n",
239 (int)len+4));
240 return NT_STATUS_NO_MEMORY;
243 /* Copy in what we already read. */
244 memcpy(*buffer,
245 writeX_header,
246 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
247 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
249 if(toread > 0) {
250 status = read_packet_remainder(
251 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
252 timeout, toread);
254 if (!NT_STATUS_IS_OK(status)) {
255 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
256 nt_errstr(status)));
257 return status;
261 *len_ret = len + 4;
262 return NT_STATUS_OK;
265 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
266 char **buffer, unsigned int timeout,
267 size_t *p_unread, size_t *plen)
269 char lenbuf[4];
270 size_t len;
271 int min_recv_size = lp_min_receive_file_size();
272 NTSTATUS status;
274 *p_unread = 0;
276 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
277 if (!NT_STATUS_IS_OK(status)) {
278 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
279 return status;
282 if (CVAL(lenbuf,0) == 0 &&
283 min_recv_size &&
284 smb_len_large(lenbuf) > min_recv_size && /* Could be a UNIX large writeX. */
285 !srv_is_signing_active()) {
287 return receive_smb_raw_talloc_partial_read(
288 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
291 if (!valid_packet_size(len)) {
292 return NT_STATUS_INVALID_PARAMETER;
296 * The +4 here can't wrap, we've checked the length above already.
299 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
301 if (*buffer == NULL) {
302 DEBUG(0, ("Could not allocate inbuf of length %d\n",
303 (int)len+4));
304 return NT_STATUS_NO_MEMORY;
307 memcpy(*buffer, lenbuf, sizeof(lenbuf));
309 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
310 if (!NT_STATUS_IS_OK(status)) {
311 return status;
314 *plen = len + 4;
315 return NT_STATUS_OK;
318 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
319 char **buffer, unsigned int timeout,
320 size_t *p_unread, bool *p_encrypted,
321 size_t *p_len)
323 size_t len = 0;
324 NTSTATUS status;
326 *p_encrypted = false;
328 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
329 p_unread, &len);
330 if (!NT_STATUS_IS_OK(status)) {
331 return status;
334 if (is_encrypted_packet((uint8_t *)*buffer)) {
335 status = srv_decrypt_buffer(*buffer);
336 if (!NT_STATUS_IS_OK(status)) {
337 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
338 "incoming packet! Error %s\n",
339 nt_errstr(status) ));
340 return status;
342 *p_encrypted = true;
345 /* Check the incoming SMB signature. */
346 if (!srv_check_sign_mac(*buffer, true)) {
347 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
348 "incoming packet!\n"));
349 return NT_STATUS_INVALID_NETWORK_RESPONSE;
352 *p_len = len;
353 return NT_STATUS_OK;
357 * Initialize a struct smb_request from an inbuf
360 void init_smb_request(struct smb_request *req,
361 const uint8 *inbuf,
362 size_t unread_bytes,
363 bool encrypted)
365 size_t req_size = smb_len(inbuf) + 4;
366 /* Ensure we have at least smb_size bytes. */
367 if (req_size < smb_size) {
368 DEBUG(0,("init_smb_request: invalid request size %u\n",
369 (unsigned int)req_size ));
370 exit_server_cleanly("Invalid SMB request");
372 req->flags2 = SVAL(inbuf, smb_flg2);
373 req->smbpid = SVAL(inbuf, smb_pid);
374 req->mid = SVAL(inbuf, smb_mid);
375 req->vuid = SVAL(inbuf, smb_uid);
376 req->tid = SVAL(inbuf, smb_tid);
377 req->wct = CVAL(inbuf, smb_wct);
378 req->unread_bytes = unread_bytes;
379 req->encrypted = encrypted;
380 req->conn = conn_find(req->tid);
382 /* Ensure we have at least wct words and 2 bytes of bcc. */
383 if (smb_size + req->wct*2 > req_size) {
384 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
385 (unsigned int)req->wct,
386 (unsigned int)req_size));
387 exit_server_cleanly("Invalid SMB request");
389 /* Ensure bcc is correct. */
390 if (((uint8 *)smb_buf(inbuf)) + smb_buflen(inbuf) > inbuf + req_size) {
391 DEBUG(0,("init_smb_request: invalid bcc number %u "
392 "(wct = %u, size %u)\n",
393 (unsigned int)smb_buflen(inbuf),
394 (unsigned int)req->wct,
395 (unsigned int)req_size));
396 exit_server_cleanly("Invalid SMB request");
398 req->inbuf = inbuf;
399 req->outbuf = NULL;
402 /****************************************************************************
403 structure to hold a linked list of queued messages.
404 for processing.
405 ****************************************************************************/
407 static struct pending_message_list *deferred_open_queue;
409 /****************************************************************************
410 Function to push a message onto the tail of a linked list of smb messages ready
411 for processing.
412 ****************************************************************************/
414 static bool push_queued_message(struct smb_request *req,
415 struct timeval request_time,
416 struct timeval end_time,
417 char *private_data, size_t private_len)
419 int msg_len = smb_len(req->inbuf) + 4;
420 struct pending_message_list *msg;
422 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
424 if(msg == NULL) {
425 DEBUG(0,("push_message: malloc fail (1)\n"));
426 return False;
429 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
430 if(msg->buf.data == NULL) {
431 DEBUG(0,("push_message: malloc fail (2)\n"));
432 TALLOC_FREE(msg);
433 return False;
436 msg->request_time = request_time;
437 msg->end_time = end_time;
438 msg->encrypted = req->encrypted;
440 if (private_data) {
441 msg->private_data = data_blob_talloc(msg, private_data,
442 private_len);
443 if (msg->private_data.data == NULL) {
444 DEBUG(0,("push_message: malloc fail (3)\n"));
445 TALLOC_FREE(msg);
446 return False;
450 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
452 DEBUG(10,("push_message: pushed message length %u on "
453 "deferred_open_queue\n", (unsigned int)msg_len));
455 return True;
458 /****************************************************************************
459 Function to delete a sharing violation open message by mid.
460 ****************************************************************************/
462 void remove_deferred_open_smb_message(uint16 mid)
464 struct pending_message_list *pml;
466 for (pml = deferred_open_queue; pml; pml = pml->next) {
467 if (mid == SVAL(pml->buf.data,smb_mid)) {
468 DEBUG(10,("remove_sharing_violation_open_smb_message: "
469 "deleting mid %u len %u\n",
470 (unsigned int)mid,
471 (unsigned int)pml->buf.length ));
472 DLIST_REMOVE(deferred_open_queue, pml);
473 TALLOC_FREE(pml);
474 return;
479 /****************************************************************************
480 Move a sharing violation open retry message to the front of the list and
481 schedule it for immediate processing.
482 ****************************************************************************/
484 void schedule_deferred_open_smb_message(uint16 mid)
486 struct pending_message_list *pml;
487 int i = 0;
489 for (pml = deferred_open_queue; pml; pml = pml->next) {
490 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
491 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
492 (unsigned int)msg_mid ));
493 if (mid == msg_mid) {
494 DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
495 mid ));
496 pml->end_time.tv_sec = 0;
497 pml->end_time.tv_usec = 0;
498 DLIST_PROMOTE(deferred_open_queue, pml);
499 return;
503 DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
504 mid ));
507 /****************************************************************************
508 Return true if this mid is on the deferred queue.
509 ****************************************************************************/
511 bool open_was_deferred(uint16 mid)
513 struct pending_message_list *pml;
515 for (pml = deferred_open_queue; pml; pml = pml->next) {
516 if (SVAL(pml->buf.data,smb_mid) == mid) {
517 return True;
520 return False;
523 /****************************************************************************
524 Return the message queued by this mid.
525 ****************************************************************************/
527 struct pending_message_list *get_open_deferred_message(uint16 mid)
529 struct pending_message_list *pml;
531 for (pml = deferred_open_queue; pml; pml = pml->next) {
532 if (SVAL(pml->buf.data,smb_mid) == mid) {
533 return pml;
536 return NULL;
539 /****************************************************************************
540 Function to push a deferred open smb message onto a linked list of local smb
541 messages ready for processing.
542 ****************************************************************************/
544 bool push_deferred_smb_message(struct smb_request *req,
545 struct timeval request_time,
546 struct timeval timeout,
547 char *private_data, size_t priv_len)
549 struct timeval end_time;
551 if (req->unread_bytes) {
552 DEBUG(0,("push_deferred_smb_message: logic error ! "
553 "unread_bytes = %u\n",
554 (unsigned int)req->unread_bytes ));
555 smb_panic("push_deferred_smb_message: "
556 "logic error unread_bytes != 0" );
559 end_time = timeval_sum(&request_time, &timeout);
561 DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
562 "timeout time [%u.%06u]\n",
563 (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
564 (unsigned int)end_time.tv_sec,
565 (unsigned int)end_time.tv_usec));
567 return push_queued_message(req, request_time, end_time,
568 private_data, priv_len);
571 struct idle_event {
572 struct timed_event *te;
573 struct timeval interval;
574 char *name;
575 bool (*handler)(const struct timeval *now, void *private_data);
576 void *private_data;
579 static void idle_event_handler(struct event_context *ctx,
580 struct timed_event *te,
581 const struct timeval *now,
582 void *private_data)
584 struct idle_event *event =
585 talloc_get_type_abort(private_data, struct idle_event);
587 TALLOC_FREE(event->te);
589 if (!event->handler(now, event->private_data)) {
590 /* Don't repeat, delete ourselves */
591 TALLOC_FREE(event);
592 return;
595 event->te = event_add_timed(ctx, event,
596 timeval_sum(now, &event->interval),
597 event->name,
598 idle_event_handler, event);
600 /* We can't do much but fail here. */
601 SMB_ASSERT(event->te != NULL);
604 struct idle_event *event_add_idle(struct event_context *event_ctx,
605 TALLOC_CTX *mem_ctx,
606 struct timeval interval,
607 const char *name,
608 bool (*handler)(const struct timeval *now,
609 void *private_data),
610 void *private_data)
612 struct idle_event *result;
613 struct timeval now = timeval_current();
615 result = TALLOC_P(mem_ctx, struct idle_event);
616 if (result == NULL) {
617 DEBUG(0, ("talloc failed\n"));
618 return NULL;
621 result->interval = interval;
622 result->handler = handler;
623 result->private_data = private_data;
625 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
626 DEBUG(0, ("talloc failed\n"));
627 TALLOC_FREE(result);
628 return NULL;
631 result->te = event_add_timed(event_ctx, result,
632 timeval_sum(&now, &interval),
633 result->name,
634 idle_event_handler, result);
635 if (result->te == NULL) {
636 DEBUG(0, ("event_add_timed failed\n"));
637 TALLOC_FREE(result);
638 return NULL;
641 return result;
644 /****************************************************************************
645 Do all async processing in here. This includes kernel oplock messages, change
646 notify events etc.
647 ****************************************************************************/
649 static void async_processing(fd_set *pfds)
651 DEBUG(10,("async_processing: Doing async processing.\n"));
653 process_aio_queue();
655 process_kernel_oplocks(smbd_messaging_context(), pfds);
657 /* Do the aio check again after receive_local_message as it does a
658 select and may have eaten our signal. */
659 /* Is this till true? -- vl */
660 process_aio_queue();
662 if (got_sig_term) {
663 exit_server_cleanly("termination signal");
666 /* check for sighup processing */
667 if (reload_after_sighup) {
668 change_to_root_user();
669 DEBUG(1,("Reloading services after SIGHUP\n"));
670 reload_services(False);
671 reload_after_sighup = 0;
675 /****************************************************************************
676 Add a fd to the set we will be select(2)ing on.
677 ****************************************************************************/
679 static int select_on_fd(int fd, int maxfd, fd_set *fds)
681 if (fd != -1) {
682 FD_SET(fd, fds);
683 maxfd = MAX(maxfd, fd);
686 return maxfd;
689 /****************************************************************************
690 Do a select on an two fd's - with timeout.
692 If a local udp message has been pushed onto the
693 queue (this can only happen during oplock break
694 processing) call async_processing()
696 If a pending smb message has been pushed onto the
697 queue (this can only happen during oplock break
698 processing) return this next.
700 If the first smbfd is ready then read an smb from it.
701 if the second (loopback UDP) fd is ready then read a message
702 from it and setup the buffer header to identify the length
703 and from address.
704 Returns False on timeout or error.
705 Else returns True.
707 The timeout is in milliseconds
708 ****************************************************************************/
710 static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer,
711 size_t *buffer_len, int timeout,
712 size_t *p_unread, bool *p_encrypted)
714 fd_set r_fds, w_fds;
715 int selrtn;
716 struct timeval to;
717 int maxfd = 0;
718 size_t len = 0;
719 NTSTATUS status;
721 *p_unread = 0;
723 again:
725 if (timeout >= 0) {
726 to.tv_sec = timeout / 1000;
727 to.tv_usec = (timeout % 1000) * 1000;
728 } else {
729 to.tv_sec = SMBD_SELECT_TIMEOUT;
730 to.tv_usec = 0;
734 * Note that this call must be before processing any SMB
735 * messages as we need to synchronously process any messages
736 * we may have sent to ourselves from the previous SMB.
738 message_dispatch(smbd_messaging_context());
741 * Check to see if we already have a message on the deferred open queue
742 * and it's time to schedule.
744 if(deferred_open_queue != NULL) {
745 bool pop_message = False;
746 struct pending_message_list *msg = deferred_open_queue;
748 if (timeval_is_zero(&msg->end_time)) {
749 pop_message = True;
750 } else {
751 struct timeval tv;
752 SMB_BIG_INT tdif;
754 GetTimeOfDay(&tv);
755 tdif = usec_time_diff(&msg->end_time, &tv);
756 if (tdif <= 0) {
757 /* Timed out. Schedule...*/
758 pop_message = True;
759 DEBUG(10,("receive_message_or_smb: queued message timed out.\n"));
760 } else {
761 /* Make a more accurate select timeout. */
762 to.tv_sec = tdif / 1000000;
763 to.tv_usec = tdif % 1000000;
764 DEBUG(10,("receive_message_or_smb: select with timeout of [%u.%06u]\n",
765 (unsigned int)to.tv_sec, (unsigned int)to.tv_usec ));
769 if (pop_message) {
771 *buffer = (char *)talloc_memdup(mem_ctx, msg->buf.data,
772 msg->buf.length);
773 if (*buffer == NULL) {
774 DEBUG(0, ("talloc failed\n"));
775 return NT_STATUS_NO_MEMORY;
777 *buffer_len = msg->buf.length;
778 *p_encrypted = msg->encrypted;
780 /* We leave this message on the queue so the open code can
781 know this is a retry. */
782 DEBUG(5,("receive_message_or_smb: returning deferred open smb message.\n"));
783 return NT_STATUS_OK;
788 * Setup the select fd sets.
791 FD_ZERO(&r_fds);
792 FD_ZERO(&w_fds);
795 * Ensure we process oplock break messages by preference.
796 * We have to do this before the select, after the select
797 * and if the select returns EINTR. This is due to the fact
798 * that the selects called from async_processing can eat an EINTR
799 * caused by a signal (we can't take the break message there).
800 * This is hideously complex - *MUST* be simplified for 3.0 ! JRA.
803 if (oplock_message_waiting(&r_fds)) {
804 DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
805 async_processing(&r_fds);
807 * After async processing we must go and do the select again, as
808 * the state of the flag in fds for the server file descriptor is
809 * indeterminate - we may have done I/O on it in the oplock processing. JRA.
811 goto again;
815 * Are there any timed events waiting ? If so, ensure we don't
816 * select for longer than it would take to wait for them.
820 struct timeval now;
821 GetTimeOfDay(&now);
823 event_add_to_select_args(smbd_event_context(), &now,
824 &r_fds, &w_fds, &to, &maxfd);
827 if (timeval_is_zero(&to)) {
828 /* Process a timed event now... */
829 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
830 goto again;
835 int sav;
836 START_PROFILE(smbd_idle);
838 maxfd = select_on_fd(smbd_server_fd(), maxfd, &r_fds);
839 maxfd = select_on_fd(oplock_notify_fd(), maxfd, &r_fds);
841 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
842 sav = errno;
844 END_PROFILE(smbd_idle);
845 errno = sav;
848 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
849 goto again;
852 /* if we get EINTR then maybe we have received an oplock
853 signal - treat this as select returning 1. This is ugly, but
854 is the best we can do until the oplock code knows more about
855 signals */
856 if (selrtn == -1 && errno == EINTR) {
857 async_processing(&r_fds);
859 * After async processing we must go and do the select again, as
860 * the state of the flag in fds for the server file descriptor is
861 * indeterminate - we may have done I/O on it in the oplock processing. JRA.
863 goto again;
866 /* Check if error */
867 if (selrtn == -1) {
868 /* something is wrong. Maybe the socket is dead? */
869 return map_nt_error_from_unix(errno);
872 /* Did we timeout ? */
873 if (selrtn == 0) {
874 return NT_STATUS_IO_TIMEOUT;
878 * Ensure we process oplock break messages by preference.
879 * This is IMPORTANT ! Otherwise we can starve other processes
880 * sending us an oplock break message. JRA.
883 if (oplock_message_waiting(&r_fds)) {
884 async_processing(&r_fds);
886 * After async processing we must go and do the select again, as
887 * the state of the flag in fds for the server file descriptor is
888 * indeterminate - we may have done I/O on it in the oplock processing. JRA.
890 goto again;
894 * We've just woken up from a protentially long select sleep.
895 * Ensure we process local messages as we need to synchronously
896 * process any messages from other smbd's to avoid file rename race
897 * conditions. This call is cheap if there are no messages waiting.
898 * JRA.
900 message_dispatch(smbd_messaging_context());
902 status = receive_smb_talloc(mem_ctx, smbd_server_fd(), buffer, 0,
903 p_unread, p_encrypted, &len);
905 if (!NT_STATUS_IS_OK(status)) {
906 return status;
909 *buffer_len = len;
911 return NT_STATUS_OK;
915 * Only allow 5 outstanding trans requests. We're allocating memory, so
916 * prevent a DoS.
919 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
921 int count = 0;
922 for (; list != NULL; list = list->next) {
924 if (list->mid == mid) {
925 return NT_STATUS_INVALID_PARAMETER;
928 count += 1;
930 if (count > 5) {
931 return NT_STATUS_INSUFFICIENT_RESOURCES;
934 return NT_STATUS_OK;
937 /****************************************************************************
938 We're terminating and have closed all our files/connections etc.
939 If there are any pending local messages we need to respond to them
940 before termination so that other smbds don't think we just died whilst
941 holding oplocks.
942 ****************************************************************************/
944 void respond_to_all_remaining_local_messages(void)
947 * Assert we have no exclusive open oplocks.
950 if(get_number_of_exclusive_open_oplocks()) {
951 DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
952 get_number_of_exclusive_open_oplocks() ));
953 return;
956 process_kernel_oplocks(smbd_messaging_context(), NULL);
958 return;
963 These flags determine some of the permissions required to do an operation
965 Note that I don't set NEED_WRITE on some write operations because they
966 are used by some brain-dead clients when printing, and I don't want to
967 force write permissions on print services.
969 #define AS_USER (1<<0)
970 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
971 #define TIME_INIT (1<<2)
972 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
973 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
974 #define DO_CHDIR (1<<6)
977 define a list of possible SMB messages and their corresponding
978 functions. Any message that has a NULL function is unimplemented -
979 please feel free to contribute implementations!
981 static const struct smb_message_struct {
982 const char *name;
983 void (*fn_new)(struct smb_request *req);
984 int flags;
985 } smb_messages[256] = {
987 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
988 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
989 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
990 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
991 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
992 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
993 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
994 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
995 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
996 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
997 /* 0x0a */ { "SMBread",reply_read,AS_USER},
998 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
999 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1000 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1001 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1002 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1003 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1004 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1005 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1006 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1007 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1008 /* 0x15 */ { NULL, NULL, 0 },
1009 /* 0x16 */ { NULL, NULL, 0 },
1010 /* 0x17 */ { NULL, NULL, 0 },
1011 /* 0x18 */ { NULL, NULL, 0 },
1012 /* 0x19 */ { NULL, NULL, 0 },
1013 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1014 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1015 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1016 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1017 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1018 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1019 /* 0x20 */ { "SMBwritec", NULL,0},
1020 /* 0x21 */ { NULL, NULL, 0 },
1021 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1022 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1023 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1024 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1025 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1026 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1027 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1028 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1029 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1030 /* 0x2b */ { "SMBecho",reply_echo,0},
1031 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1032 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1033 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1034 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1035 /* 0x30 */ { NULL, NULL, 0 },
1036 /* 0x31 */ { NULL, NULL, 0 },
1037 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1038 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER},
1039 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1040 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1041 /* 0x36 */ { NULL, NULL, 0 },
1042 /* 0x37 */ { NULL, NULL, 0 },
1043 /* 0x38 */ { NULL, NULL, 0 },
1044 /* 0x39 */ { NULL, NULL, 0 },
1045 /* 0x3a */ { NULL, NULL, 0 },
1046 /* 0x3b */ { NULL, NULL, 0 },
1047 /* 0x3c */ { NULL, NULL, 0 },
1048 /* 0x3d */ { NULL, NULL, 0 },
1049 /* 0x3e */ { NULL, NULL, 0 },
1050 /* 0x3f */ { NULL, NULL, 0 },
1051 /* 0x40 */ { NULL, NULL, 0 },
1052 /* 0x41 */ { NULL, NULL, 0 },
1053 /* 0x42 */ { NULL, NULL, 0 },
1054 /* 0x43 */ { NULL, NULL, 0 },
1055 /* 0x44 */ { NULL, NULL, 0 },
1056 /* 0x45 */ { NULL, NULL, 0 },
1057 /* 0x46 */ { NULL, NULL, 0 },
1058 /* 0x47 */ { NULL, NULL, 0 },
1059 /* 0x48 */ { NULL, NULL, 0 },
1060 /* 0x49 */ { NULL, NULL, 0 },
1061 /* 0x4a */ { NULL, NULL, 0 },
1062 /* 0x4b */ { NULL, NULL, 0 },
1063 /* 0x4c */ { NULL, NULL, 0 },
1064 /* 0x4d */ { NULL, NULL, 0 },
1065 /* 0x4e */ { NULL, NULL, 0 },
1066 /* 0x4f */ { NULL, NULL, 0 },
1067 /* 0x50 */ { NULL, NULL, 0 },
1068 /* 0x51 */ { NULL, NULL, 0 },
1069 /* 0x52 */ { NULL, NULL, 0 },
1070 /* 0x53 */ { NULL, NULL, 0 },
1071 /* 0x54 */ { NULL, NULL, 0 },
1072 /* 0x55 */ { NULL, NULL, 0 },
1073 /* 0x56 */ { NULL, NULL, 0 },
1074 /* 0x57 */ { NULL, NULL, 0 },
1075 /* 0x58 */ { NULL, NULL, 0 },
1076 /* 0x59 */ { NULL, NULL, 0 },
1077 /* 0x5a */ { NULL, NULL, 0 },
1078 /* 0x5b */ { NULL, NULL, 0 },
1079 /* 0x5c */ { NULL, NULL, 0 },
1080 /* 0x5d */ { NULL, NULL, 0 },
1081 /* 0x5e */ { NULL, NULL, 0 },
1082 /* 0x5f */ { NULL, NULL, 0 },
1083 /* 0x60 */ { NULL, NULL, 0 },
1084 /* 0x61 */ { NULL, NULL, 0 },
1085 /* 0x62 */ { NULL, NULL, 0 },
1086 /* 0x63 */ { NULL, NULL, 0 },
1087 /* 0x64 */ { NULL, NULL, 0 },
1088 /* 0x65 */ { NULL, NULL, 0 },
1089 /* 0x66 */ { NULL, NULL, 0 },
1090 /* 0x67 */ { NULL, NULL, 0 },
1091 /* 0x68 */ { NULL, NULL, 0 },
1092 /* 0x69 */ { NULL, NULL, 0 },
1093 /* 0x6a */ { NULL, NULL, 0 },
1094 /* 0x6b */ { NULL, NULL, 0 },
1095 /* 0x6c */ { NULL, NULL, 0 },
1096 /* 0x6d */ { NULL, NULL, 0 },
1097 /* 0x6e */ { NULL, NULL, 0 },
1098 /* 0x6f */ { NULL, NULL, 0 },
1099 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1100 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1101 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1102 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1103 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1104 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1105 /* 0x76 */ { NULL, NULL, 0 },
1106 /* 0x77 */ { NULL, NULL, 0 },
1107 /* 0x78 */ { NULL, NULL, 0 },
1108 /* 0x79 */ { NULL, NULL, 0 },
1109 /* 0x7a */ { NULL, NULL, 0 },
1110 /* 0x7b */ { NULL, NULL, 0 },
1111 /* 0x7c */ { NULL, NULL, 0 },
1112 /* 0x7d */ { NULL, NULL, 0 },
1113 /* 0x7e */ { NULL, NULL, 0 },
1114 /* 0x7f */ { NULL, NULL, 0 },
1115 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1116 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1117 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1118 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1119 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1120 /* 0x85 */ { NULL, NULL, 0 },
1121 /* 0x86 */ { NULL, NULL, 0 },
1122 /* 0x87 */ { NULL, NULL, 0 },
1123 /* 0x88 */ { NULL, NULL, 0 },
1124 /* 0x89 */ { NULL, NULL, 0 },
1125 /* 0x8a */ { NULL, NULL, 0 },
1126 /* 0x8b */ { NULL, NULL, 0 },
1127 /* 0x8c */ { NULL, NULL, 0 },
1128 /* 0x8d */ { NULL, NULL, 0 },
1129 /* 0x8e */ { NULL, NULL, 0 },
1130 /* 0x8f */ { NULL, NULL, 0 },
1131 /* 0x90 */ { NULL, NULL, 0 },
1132 /* 0x91 */ { NULL, NULL, 0 },
1133 /* 0x92 */ { NULL, NULL, 0 },
1134 /* 0x93 */ { NULL, NULL, 0 },
1135 /* 0x94 */ { NULL, NULL, 0 },
1136 /* 0x95 */ { NULL, NULL, 0 },
1137 /* 0x96 */ { NULL, NULL, 0 },
1138 /* 0x97 */ { NULL, NULL, 0 },
1139 /* 0x98 */ { NULL, NULL, 0 },
1140 /* 0x99 */ { NULL, NULL, 0 },
1141 /* 0x9a */ { NULL, NULL, 0 },
1142 /* 0x9b */ { NULL, NULL, 0 },
1143 /* 0x9c */ { NULL, NULL, 0 },
1144 /* 0x9d */ { NULL, NULL, 0 },
1145 /* 0x9e */ { NULL, NULL, 0 },
1146 /* 0x9f */ { NULL, NULL, 0 },
1147 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1148 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1149 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1150 /* 0xa3 */ { NULL, NULL, 0 },
1151 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1152 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1153 /* 0xa6 */ { NULL, NULL, 0 },
1154 /* 0xa7 */ { NULL, NULL, 0 },
1155 /* 0xa8 */ { NULL, NULL, 0 },
1156 /* 0xa9 */ { NULL, NULL, 0 },
1157 /* 0xaa */ { NULL, NULL, 0 },
1158 /* 0xab */ { NULL, NULL, 0 },
1159 /* 0xac */ { NULL, NULL, 0 },
1160 /* 0xad */ { NULL, NULL, 0 },
1161 /* 0xae */ { NULL, NULL, 0 },
1162 /* 0xaf */ { NULL, NULL, 0 },
1163 /* 0xb0 */ { NULL, NULL, 0 },
1164 /* 0xb1 */ { NULL, NULL, 0 },
1165 /* 0xb2 */ { NULL, NULL, 0 },
1166 /* 0xb3 */ { NULL, NULL, 0 },
1167 /* 0xb4 */ { NULL, NULL, 0 },
1168 /* 0xb5 */ { NULL, NULL, 0 },
1169 /* 0xb6 */ { NULL, NULL, 0 },
1170 /* 0xb7 */ { NULL, NULL, 0 },
1171 /* 0xb8 */ { NULL, NULL, 0 },
1172 /* 0xb9 */ { NULL, NULL, 0 },
1173 /* 0xba */ { NULL, NULL, 0 },
1174 /* 0xbb */ { NULL, NULL, 0 },
1175 /* 0xbc */ { NULL, NULL, 0 },
1176 /* 0xbd */ { NULL, NULL, 0 },
1177 /* 0xbe */ { NULL, NULL, 0 },
1178 /* 0xbf */ { NULL, NULL, 0 },
1179 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1180 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1181 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1182 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1183 /* 0xc4 */ { NULL, NULL, 0 },
1184 /* 0xc5 */ { NULL, NULL, 0 },
1185 /* 0xc6 */ { NULL, NULL, 0 },
1186 /* 0xc7 */ { NULL, NULL, 0 },
1187 /* 0xc8 */ { NULL, NULL, 0 },
1188 /* 0xc9 */ { NULL, NULL, 0 },
1189 /* 0xca */ { NULL, NULL, 0 },
1190 /* 0xcb */ { NULL, NULL, 0 },
1191 /* 0xcc */ { NULL, NULL, 0 },
1192 /* 0xcd */ { NULL, NULL, 0 },
1193 /* 0xce */ { NULL, NULL, 0 },
1194 /* 0xcf */ { NULL, NULL, 0 },
1195 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1196 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1197 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1198 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1199 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1200 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1201 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1202 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1203 /* 0xd8 */ { NULL, NULL, 0 },
1204 /* 0xd9 */ { NULL, NULL, 0 },
1205 /* 0xda */ { NULL, NULL, 0 },
1206 /* 0xdb */ { NULL, NULL, 0 },
1207 /* 0xdc */ { NULL, NULL, 0 },
1208 /* 0xdd */ { NULL, NULL, 0 },
1209 /* 0xde */ { NULL, NULL, 0 },
1210 /* 0xdf */ { NULL, NULL, 0 },
1211 /* 0xe0 */ { NULL, NULL, 0 },
1212 /* 0xe1 */ { NULL, NULL, 0 },
1213 /* 0xe2 */ { NULL, NULL, 0 },
1214 /* 0xe3 */ { NULL, NULL, 0 },
1215 /* 0xe4 */ { NULL, NULL, 0 },
1216 /* 0xe5 */ { NULL, NULL, 0 },
1217 /* 0xe6 */ { NULL, NULL, 0 },
1218 /* 0xe7 */ { NULL, NULL, 0 },
1219 /* 0xe8 */ { NULL, NULL, 0 },
1220 /* 0xe9 */ { NULL, NULL, 0 },
1221 /* 0xea */ { NULL, NULL, 0 },
1222 /* 0xeb */ { NULL, NULL, 0 },
1223 /* 0xec */ { NULL, NULL, 0 },
1224 /* 0xed */ { NULL, NULL, 0 },
1225 /* 0xee */ { NULL, NULL, 0 },
1226 /* 0xef */ { NULL, NULL, 0 },
1227 /* 0xf0 */ { NULL, NULL, 0 },
1228 /* 0xf1 */ { NULL, NULL, 0 },
1229 /* 0xf2 */ { NULL, NULL, 0 },
1230 /* 0xf3 */ { NULL, NULL, 0 },
1231 /* 0xf4 */ { NULL, NULL, 0 },
1232 /* 0xf5 */ { NULL, NULL, 0 },
1233 /* 0xf6 */ { NULL, NULL, 0 },
1234 /* 0xf7 */ { NULL, NULL, 0 },
1235 /* 0xf8 */ { NULL, NULL, 0 },
1236 /* 0xf9 */ { NULL, NULL, 0 },
1237 /* 0xfa */ { NULL, NULL, 0 },
1238 /* 0xfb */ { NULL, NULL, 0 },
1239 /* 0xfc */ { NULL, NULL, 0 },
1240 /* 0xfd */ { NULL, NULL, 0 },
1241 /* 0xfe */ { NULL, NULL, 0 },
1242 /* 0xff */ { NULL, NULL, 0 }
1246 /*******************************************************************
1247 allocate and initialize a reply packet
1248 ********************************************************************/
1250 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1253 * Protect against integer wrap
1255 if ((num_bytes > 0xffffff)
1256 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1257 char *msg;
1258 if (asprintf(&msg, "num_bytes too large: %u",
1259 (unsigned)num_bytes) == -1) {
1260 msg = CONST_DISCARD(char *, "num_bytes too large");
1262 smb_panic(msg);
1265 if (!(req->outbuf = TALLOC_ARRAY(
1266 req, uint8,
1267 smb_size + num_words*2 + num_bytes))) {
1268 smb_panic("could not allocate output buffer\n");
1271 construct_reply_common((char *)req->inbuf, (char *)req->outbuf);
1272 srv_set_message((char *)req->outbuf, num_words, num_bytes, false);
1274 * Zero out the word area, the caller has to take care of the bcc area
1275 * himself
1277 if (num_words != 0) {
1278 memset(req->outbuf + smb_vwv0, 0, num_words*2);
1281 return;
1285 /*******************************************************************
1286 Dump a packet to a file.
1287 ********************************************************************/
1289 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1291 int fd, i;
1292 char *fname = NULL;
1293 if (DEBUGLEVEL < 50) {
1294 return;
1297 if (len < 4) len = smb_len(data)+4;
1298 for (i=1;i<100;i++) {
1299 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1300 type ? "req" : "resp") == -1) {
1301 return;
1303 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1304 if (fd != -1 || errno != EEXIST) break;
1306 if (fd != -1) {
1307 ssize_t ret = write(fd, data, len);
1308 if (ret != len)
1309 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1310 close(fd);
1311 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1313 SAFE_FREE(fname);
1316 /****************************************************************************
1317 Prepare everything for calling the actual request function, and potentially
1318 call the request function via the "new" interface.
1320 Return False if the "legacy" function needs to be called, everything is
1321 prepared.
1323 Return True if we're done.
1325 I know this API sucks, but it is the one with the least code change I could
1326 find.
1327 ****************************************************************************/
1329 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1331 int flags;
1332 uint16 session_tag;
1333 connection_struct *conn = NULL;
1335 static uint16 last_session_tag = UID_FIELD_INVALID;
1337 errno = 0;
1339 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1340 * so subtract 4 from it. */
1341 if (!valid_smb_header(req->inbuf)
1342 || (size < (smb_size - 4))) {
1343 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1344 smb_len(req->inbuf)));
1345 exit_server_cleanly("Non-SMB packet");
1348 if (smb_messages[type].fn_new == NULL) {
1349 DEBUG(0,("Unknown message type %d!\n",type));
1350 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1351 reply_unknown_new(req, type);
1352 return NULL;
1355 flags = smb_messages[type].flags;
1357 /* In share mode security we must ignore the vuid. */
1358 session_tag = (lp_security() == SEC_SHARE)
1359 ? UID_FIELD_INVALID : req->vuid;
1360 conn = req->conn;
1362 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1363 (int)sys_getpid(), (unsigned long)conn));
1365 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1367 /* Ensure this value is replaced in the incoming packet. */
1368 SSVAL(req->inbuf,smb_uid,session_tag);
1371 * Ensure the correct username is in current_user_info. This is a
1372 * really ugly bugfix for problems with multiple session_setup_and_X's
1373 * being done and allowing %U and %G substitutions to work correctly.
1374 * There is a reason this code is done here, don't move it unless you
1375 * know what you're doing... :-).
1376 * JRA.
1379 if (session_tag != last_session_tag) {
1380 user_struct *vuser = NULL;
1382 last_session_tag = session_tag;
1383 if(session_tag != UID_FIELD_INVALID) {
1384 vuser = get_valid_user_struct(session_tag);
1385 if (vuser) {
1386 set_current_user_info(
1387 vuser->server_info->sanitized_username,
1388 vuser->server_info->unix_name,
1389 pdb_get_fullname(vuser->server_info
1390 ->sam_account),
1391 pdb_get_domain(vuser->server_info
1392 ->sam_account));
1397 /* Does this call need to be run as the connected user? */
1398 if (flags & AS_USER) {
1400 /* Does this call need a valid tree connection? */
1401 if (!conn) {
1403 * Amazingly, the error code depends on the command
1404 * (from Samba4).
1406 if (type == SMBntcreateX) {
1407 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1408 } else {
1409 reply_doserror(req, ERRSRV, ERRinvnid);
1411 return NULL;
1414 if (!change_to_user(conn,session_tag)) {
1415 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1416 return conn;
1419 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1421 /* Does it need write permission? */
1422 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1423 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1424 return conn;
1427 /* IPC services are limited */
1428 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1429 reply_doserror(req, ERRSRV,ERRaccess);
1430 return conn;
1432 } else {
1433 /* This call needs to be run as root */
1434 change_to_root_user();
1437 /* load service specific parameters */
1438 if (conn) {
1439 if (req->encrypted) {
1440 conn->encrypted_tid = true;
1441 /* encrypted required from now on. */
1442 conn->encrypt_level = Required;
1443 } else if (ENCRYPTION_REQUIRED(conn)) {
1444 uint8 com = CVAL(req->inbuf,smb_com);
1445 if (com != SMBtrans2 && com != SMBtranss2) {
1446 exit_server_cleanly("encryption required "
1447 "on connection");
1448 return conn;
1452 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1453 (flags & (AS_USER|DO_CHDIR)
1454 ?True:False))) {
1455 reply_doserror(req, ERRSRV, ERRaccess);
1456 return conn;
1458 conn->num_smb_operations++;
1461 /* does this protocol need to be run as guest? */
1462 if ((flags & AS_GUEST)
1463 && (!change_to_guest() ||
1464 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1465 lp_hostsdeny(-1)))) {
1466 reply_doserror(req, ERRSRV, ERRaccess);
1467 return conn;
1470 smb_messages[type].fn_new(req);
1471 return req->conn;
1474 /****************************************************************************
1475 Construct a reply to the incoming packet.
1476 ****************************************************************************/
1478 static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool encrypted)
1480 uint8 type = CVAL(inbuf,smb_com);
1481 connection_struct *conn;
1482 struct smb_request *req;
1484 chain_size = 0;
1485 file_chain_reset();
1486 reset_chain_p();
1488 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1489 smb_panic("could not allocate smb_request");
1491 init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
1493 conn = switch_message(type, req, size);
1495 if (req->unread_bytes) {
1496 /* writeX failed. drain socket. */
1497 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1498 req->unread_bytes) {
1499 smb_panic("failed to drain pending bytes");
1501 req->unread_bytes = 0;
1504 if (req->outbuf == NULL) {
1505 return;
1508 if (CVAL(req->outbuf,0) == 0) {
1509 show_msg((char *)req->outbuf);
1512 if (!srv_send_smb(smbd_server_fd(),
1513 (char *)req->outbuf,
1514 IS_CONN_ENCRYPTED(conn)||req->encrypted)) {
1515 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1518 TALLOC_FREE(req);
1520 return;
1523 /****************************************************************************
1524 Process an smb from the client
1525 ****************************************************************************/
1527 static void process_smb(char *inbuf, size_t nread, size_t unread_bytes, bool encrypted)
1529 static int trans_num;
1530 int msg_type = CVAL(inbuf,0);
1532 DO_PROFILE_INC(smb_count);
1534 if (trans_num == 0) {
1535 char addr[INET6_ADDRSTRLEN];
1537 /* on the first packet, check the global hosts allow/ hosts
1538 deny parameters before doing any parsing of the packet
1539 passed to us by the client. This prevents attacks on our
1540 parsing code from hosts not in the hosts allow list */
1542 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
1543 lp_hostsdeny(-1))) {
1544 /* send a negative session response "not listening on calling name" */
1545 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
1546 DEBUG( 1, ( "Connection denied from %s\n",
1547 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
1548 (void)srv_send_smb(smbd_server_fd(),(char *)buf,false);
1549 exit_server_cleanly("connection denied");
1553 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1554 smb_len(inbuf) ) );
1555 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1556 (int)nread,
1557 (unsigned int)unread_bytes ));
1559 if (msg_type != 0) {
1561 * NetBIOS session request, keepalive, etc.
1563 reply_special(inbuf);
1564 return;
1567 show_msg(inbuf);
1569 construct_reply(inbuf,nread,unread_bytes,encrypted);
1571 trans_num++;
1574 /****************************************************************************
1575 Return a string containing the function name of a SMB command.
1576 ****************************************************************************/
1578 const char *smb_fn_name(int type)
1580 const char *unknown_name = "SMBunknown";
1582 if (smb_messages[type].name == NULL)
1583 return(unknown_name);
1585 return(smb_messages[type].name);
1588 /****************************************************************************
1589 Helper functions for contruct_reply.
1590 ****************************************************************************/
1592 static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_32_BIT_ERROR_CODES;
1594 void add_to_common_flags2(uint32 v)
1596 common_flags2 |= v;
1599 void remove_from_common_flags2(uint32 v)
1601 common_flags2 &= ~v;
1604 void construct_reply_common(const char *inbuf, char *outbuf)
1606 srv_set_message(outbuf,0,0,false);
1608 SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
1609 SIVAL(outbuf,smb_rcls,0);
1610 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1611 SSVAL(outbuf,smb_flg2,
1612 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1613 common_flags2);
1614 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1616 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1617 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1618 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1619 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1622 /****************************************************************************
1623 Construct a chained reply and add it to the already made reply
1624 ****************************************************************************/
1626 void chain_reply(struct smb_request *req)
1628 static char *orig_inbuf;
1631 * Dirty little const_discard: We mess with req->inbuf, which is
1632 * declared as const. If maybe at some point this routine gets
1633 * rewritten, this const_discard could go away.
1635 char *inbuf = CONST_DISCARD(char *, req->inbuf);
1636 int size = smb_len(req->inbuf)+4;
1638 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
1639 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
1640 char *inbuf2;
1641 int outsize2;
1642 int new_size;
1643 char inbuf_saved[smb_wct];
1644 char *outbuf = (char *)req->outbuf;
1645 size_t outsize = smb_len(outbuf) + 4;
1646 size_t outsize_padded;
1647 size_t ofs, to_move;
1649 struct smb_request *req2;
1650 size_t caller_outputlen;
1651 char *caller_output;
1653 /* Maybe its not chained, or it's an error packet. */
1654 if (smb_com2 == 0xFF || SVAL(outbuf,smb_rcls) != 0) {
1655 SCVAL(outbuf,smb_vwv0,0xFF);
1656 return;
1659 if (chain_size == 0) {
1660 /* this is the first part of the chain */
1661 orig_inbuf = inbuf;
1665 * We need to save the output the caller added to the chain so that we
1666 * can splice it into the final output buffer later.
1669 caller_outputlen = outsize - smb_wct;
1671 caller_output = (char *)memdup(outbuf + smb_wct, caller_outputlen);
1673 if (caller_output == NULL) {
1674 /* TODO: NT_STATUS_NO_MEMORY */
1675 smb_panic("could not dup outbuf");
1679 * The original Win95 redirector dies on a reply to
1680 * a lockingX and read chain unless the chain reply is
1681 * 4 byte aligned. JRA.
1684 outsize_padded = (outsize + 3) & ~3;
1687 * remember how much the caller added to the chain, only counting
1688 * stuff after the parameter words
1690 chain_size += outsize_padded - smb_wct;
1693 * work out pointers into the original packets. The
1694 * headers on these need to be filled in
1696 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
1698 /* remember the original command type */
1699 smb_com1 = CVAL(orig_inbuf,smb_com);
1701 /* save the data which will be overwritten by the new headers */
1702 memcpy(inbuf_saved,inbuf2,smb_wct);
1704 /* give the new packet the same header as the last part of the SMB */
1705 memmove(inbuf2,inbuf,smb_wct);
1707 /* create the in buffer */
1708 SCVAL(inbuf2,smb_com,smb_com2);
1710 /* work out the new size for the in buffer. */
1711 new_size = size - (inbuf2 - inbuf);
1712 if (new_size < 0) {
1713 DEBUG(0,("chain_reply: chain packet size incorrect "
1714 "(orig size = %d, offset = %d)\n",
1715 size, (int)(inbuf2 - inbuf) ));
1716 exit_server_cleanly("Bad chained packet");
1717 return;
1720 /* And set it in the header. */
1721 smb_setlen(inbuf2, new_size - 4);
1723 DEBUG(3,("Chained message\n"));
1724 show_msg(inbuf2);
1726 if (!(req2 = talloc(talloc_tos(), struct smb_request))) {
1727 smb_panic("could not allocate smb_request");
1729 init_smb_request(req2, (uint8 *)inbuf2,0, req->encrypted);
1731 /* process the request */
1732 switch_message(smb_com2, req2, new_size);
1735 * We don't accept deferred operations in chained requests.
1737 SMB_ASSERT(req2->outbuf != NULL);
1738 outsize2 = smb_len(req2->outbuf)+4;
1741 * Move away the new command output so that caller_output fits in,
1742 * copy in the caller_output saved above.
1745 SMB_ASSERT(outsize_padded >= smb_wct);
1748 * "ofs" is the space we need for caller_output. Equal to
1749 * caller_outputlen plus the padding.
1752 ofs = outsize_padded - smb_wct;
1755 * "to_move" is the amount of bytes the secondary routine gave us
1758 to_move = outsize2 - smb_wct;
1760 if (to_move + ofs + smb_wct + chain_size > max_send) {
1761 smb_panic("replies too large -- would have to cut");
1765 * In the "new" API "outbuf" is allocated via reply_outbuf, just for
1766 * the first request in the chain. So we have to re-allocate it. In
1767 * the "old" API the only outbuf ever used is the global OutBuffer
1768 * which is always large enough.
1771 outbuf = TALLOC_REALLOC_ARRAY(NULL, outbuf, char,
1772 to_move + ofs + smb_wct);
1773 if (outbuf == NULL) {
1774 smb_panic("could not realloc outbuf");
1777 req->outbuf = (uint8 *)outbuf;
1779 memmove(outbuf + smb_wct + ofs, req2->outbuf + smb_wct, to_move);
1780 memcpy(outbuf + smb_wct, caller_output, caller_outputlen);
1783 * copy the new reply header over the old one but preserve the smb_com
1784 * field
1786 memmove(outbuf, req2->outbuf, smb_wct);
1787 SCVAL(outbuf, smb_com, smb_com1);
1790 * We've just copied in the whole "wct" area from the secondary
1791 * function. Fix up the chaining: com2 and the offset need to be
1792 * readjusted.
1795 SCVAL(outbuf, smb_vwv0, smb_com2);
1796 SSVAL(outbuf, smb_vwv1, chain_size + smb_wct - 4);
1798 if (outsize_padded > outsize) {
1801 * Due to padding we have some uninitialized bytes after the
1802 * caller's output
1805 memset(outbuf + outsize, 0, outsize_padded - outsize);
1808 smb_setlen(outbuf, outsize2 + chain_size - 4);
1811 * restore the saved data, being careful not to overwrite any data
1812 * from the reply header
1814 memcpy(inbuf2,inbuf_saved,smb_wct);
1816 SAFE_FREE(caller_output);
1817 TALLOC_FREE(req2);
1819 return;
1822 /****************************************************************************
1823 Setup the needed select timeout in milliseconds.
1824 ****************************************************************************/
1826 static int setup_select_timeout(void)
1828 int select_timeout;
1830 select_timeout = SMBD_SELECT_TIMEOUT*1000;
1832 if (print_notify_messages_pending()) {
1833 select_timeout = MIN(select_timeout, 1000);
1836 return select_timeout;
1839 /****************************************************************************
1840 Check if services need reloading.
1841 ****************************************************************************/
1843 void check_reload(time_t t)
1845 static pid_t mypid = 0;
1846 static time_t last_smb_conf_reload_time = 0;
1847 static time_t last_printer_reload_time = 0;
1848 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1850 if(last_smb_conf_reload_time == 0) {
1851 last_smb_conf_reload_time = t;
1852 /* Our printing subsystem might not be ready at smbd start up.
1853 Then no printer is available till the first printers check
1854 is performed. A lower initial interval circumvents this. */
1855 if ( printcap_cache_time > 60 )
1856 last_printer_reload_time = t - printcap_cache_time + 60;
1857 else
1858 last_printer_reload_time = t;
1861 if (mypid != getpid()) { /* First time or fork happened meanwhile */
1862 /* randomize over 60 second the printcap reload to avoid all
1863 * process hitting cupsd at the same time */
1864 int time_range = 60;
1866 last_printer_reload_time += random() % time_range;
1867 mypid = getpid();
1870 if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
1871 reload_services(True);
1872 reload_after_sighup = False;
1873 last_smb_conf_reload_time = t;
1876 /* 'printcap cache time = 0' disable the feature */
1878 if ( printcap_cache_time != 0 )
1880 /* see if it's time to reload or if the clock has been set back */
1882 if ( (t >= last_printer_reload_time+printcap_cache_time)
1883 || (t-last_printer_reload_time < 0) )
1885 DEBUG( 3,( "Printcap cache time expired.\n"));
1886 reload_printers();
1887 last_printer_reload_time = t;
1892 /****************************************************************************
1893 Process any timeout housekeeping. Return False if the caller should exit.
1894 ****************************************************************************/
1896 static void timeout_processing(int *select_timeout,
1897 time_t *last_timeout_processing_time)
1899 time_t t;
1901 *last_timeout_processing_time = t = time(NULL);
1903 /* become root again if waiting */
1904 change_to_root_user();
1906 /* check if we need to reload services */
1907 check_reload(t);
1909 if(global_machine_password_needs_changing &&
1910 /* for ADS we need to do a regular ADS password change, not a domain
1911 password change */
1912 lp_security() == SEC_DOMAIN) {
1914 unsigned char trust_passwd_hash[16];
1915 time_t lct;
1916 void *lock;
1919 * We're in domain level security, and the code that
1920 * read the machine password flagged that the machine
1921 * password needs changing.
1925 * First, open the machine password file with an exclusive lock.
1928 lock = secrets_get_trust_account_lock(NULL, lp_workgroup());
1930 if (lock == NULL) {
1931 DEBUG(0,("process: unable to lock the machine account password for \
1932 machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
1933 return;
1936 if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) {
1937 DEBUG(0,("process: unable to read the machine account password for \
1938 machine %s in domain %s.\n", global_myname(), lp_workgroup()));
1939 TALLOC_FREE(lock);
1940 return;
1944 * Make sure someone else hasn't already done this.
1947 if(t < lct + lp_machine_password_timeout()) {
1948 global_machine_password_needs_changing = False;
1949 TALLOC_FREE(lock);
1950 return;
1953 /* always just contact the PDC here */
1955 change_trust_account_password( lp_workgroup(), NULL);
1956 global_machine_password_needs_changing = False;
1957 TALLOC_FREE(lock);
1960 /* update printer queue caches if necessary */
1962 update_monitored_printq_cache();
1965 * Now we are root, check if the log files need pruning.
1966 * Force a log file check.
1968 force_check_log_size();
1969 check_log_size();
1971 /* Send any queued printer notify message to interested smbd's. */
1973 print_notify_send_messages(smbd_messaging_context(), 0);
1976 * Modify the select timeout depending upon
1977 * what we have remaining in our queues.
1980 *select_timeout = setup_select_timeout();
1982 return;
1985 /****************************************************************************
1986 Process commands from the client
1987 ****************************************************************************/
1989 void smbd_process(void)
1991 time_t last_timeout_processing_time = time(NULL);
1992 unsigned int num_smbs = 0;
1993 size_t unread_bytes = 0;
1995 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
1997 while (True) {
1998 int select_timeout = setup_select_timeout();
1999 int num_echos;
2000 char *inbuf = NULL;
2001 size_t inbuf_len = 0;
2002 bool encrypted = false;
2003 TALLOC_CTX *frame = talloc_stackframe_pool(8192);
2005 errno = 0;
2007 /* Did someone ask for immediate checks on things like blocking locks ? */
2008 if (select_timeout == 0) {
2009 timeout_processing(&select_timeout,
2010 &last_timeout_processing_time);
2011 num_smbs = 0; /* Reset smb counter. */
2014 run_events(smbd_event_context(), 0, NULL, NULL);
2016 while (True) {
2017 NTSTATUS status;
2019 status = receive_message_or_smb(
2020 talloc_tos(), &inbuf, &inbuf_len,
2021 select_timeout, &unread_bytes, &encrypted);
2023 if (NT_STATUS_IS_OK(status)) {
2024 break;
2027 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
2028 timeout_processing(
2029 &select_timeout,
2030 &last_timeout_processing_time);
2031 continue;
2034 DEBUG(3, ("receive_message_or_smb failed: %s, "
2035 "exiting\n", nt_errstr(status)));
2036 return;
2038 num_smbs = 0; /* Reset smb counter. */
2043 * Ensure we do timeout processing if the SMB we just got was
2044 * only an echo request. This allows us to set the select
2045 * timeout in 'receive_message_or_smb()' to any value we like
2046 * without worrying that the client will send echo requests
2047 * faster than the select timeout, thus starving out the
2048 * essential processing (change notify, blocking locks) that
2049 * the timeout code does. JRA.
2051 num_echos = smb_echo_count;
2053 process_smb(inbuf, inbuf_len, unread_bytes, encrypted);
2055 TALLOC_FREE(inbuf);
2057 if (smb_echo_count != num_echos) {
2058 timeout_processing(&select_timeout,
2059 &last_timeout_processing_time);
2060 num_smbs = 0; /* Reset smb counter. */
2063 num_smbs++;
2066 * If we are getting smb requests in a constant stream
2067 * with no echos, make sure we attempt timeout processing
2068 * every select_timeout milliseconds - but only check for this
2069 * every 200 smb requests.
2072 if ((num_smbs % 200) == 0) {
2073 time_t new_check_time = time(NULL);
2074 if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) {
2075 timeout_processing(
2076 &select_timeout,
2077 &last_timeout_processing_time);
2078 num_smbs = 0; /* Reset smb counter. */
2079 last_timeout_processing_time = new_check_time; /* Reset time. */
2083 /* The timeout_processing function isn't run nearly
2084 often enough to implement 'max log size' without
2085 overrunning the size of the file by many megabytes.
2086 This is especially true if we are running at debug
2087 level 10. Checking every 50 SMBs is a nice
2088 tradeoff of performance vs log file size overrun. */
2090 if ((num_smbs % 50) == 0 && need_to_check_log_size()) {
2091 change_to_root_user();
2092 check_log_size();
2094 TALLOC_FREE(frame);