#include "includes.h"
uint16 global_smbpid;
+extern int keepalive;
extern struct auth_context *negprot_global_auth_context;
extern int smb_echo_count;
return SVAL(InBuffer,smb_mid);
}
-/*
- * Initialize a struct smb_request from an inbuf
- */
-
-void init_smb_request(struct smb_request *req, const uint8 *inbuf)
-{
- req->flags2 = SVAL(inbuf, smb_flg2);
- req->smbpid = SVAL(inbuf, smb_pid);
- req->mid = SVAL(inbuf, smb_mid);
- req->vuid = SVAL(inbuf, smb_uid);
-}
-
/****************************************************************************
structure to hold a linked list of queued messages.
for processing.
static struct pending_message_list *deferred_open_queue;
/****************************************************************************
- Function to push a message onto the tail of a linked list of smb messages
- ready for processing.
+ Function to push a message onto the tail of a linked list of smb messages ready
+ for processing.
****************************************************************************/
static BOOL push_queued_message(char *buf, int msg_len,
for (pml = deferred_open_queue; pml; pml = pml->next) {
if (mid == SVAL(pml->buf.data,smb_mid)) {
- DEBUG(10,("remove_deferred_open_smb_message: "
+ DEBUG(10,("remove_sharing_violation_open_smb_message: "
"deleting mid %u len %u\n",
(unsigned int)mid,
(unsigned int)pml->buf.length ));
for (pml = deferred_open_queue; pml; pml = pml->next) {
uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
- DEBUG(10, ("schedule_deferred_open_smb_message: [%d] "
- "msg_mid = %u\n", i++, (unsigned int)msg_mid ));
+ DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
+ (unsigned int)msg_mid ));
if (mid == msg_mid) {
- DEBUG(10, ("schedule_deferred_open_smb_message: "
- "scheduling mid %u\n", mid));
+ DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
+ mid ));
pml->end_time.tv_sec = 0;
pml->end_time.tv_usec = 0;
DLIST_PROMOTE(deferred_open_queue, pml);
}
}
- DEBUG(10, ("schedule_deferred_open_smb_message: failed to find "
- "message mid %u\n", mid ));
+ DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
+ mid ));
}
/****************************************************************************
struct idle_event {
struct timed_event *te;
struct timeval interval;
- char *name;
BOOL (*handler)(const struct timeval *now, void *private_data);
void *private_data;
};
return;
}
- event->te = event_add_timed(ctx, event,
+ event->te = event_add_timed(smbd_event_context(), event,
timeval_sum(now, &event->interval),
- event->name,
+ "idle_event_handler",
idle_event_handler, event);
/* We can't do much but fail here. */
SMB_ASSERT(event->te != NULL);
}
-struct idle_event *event_add_idle(struct event_context *event_ctx,
- TALLOC_CTX *mem_ctx,
+struct idle_event *add_idle_event(TALLOC_CTX *mem_ctx,
struct timeval interval,
- const char *name,
BOOL (*handler)(const struct timeval *now,
void *private_data),
void *private_data)
result->handler = handler;
result->private_data = private_data;
- if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
- DEBUG(0, ("talloc failed\n"));
- TALLOC_FREE(result);
- return NULL;
- }
-
- result->te = event_add_timed(event_ctx, result,
+ result->te = event_add_timed(smbd_event_context(), result,
timeval_sum(&now, &interval),
- result->name,
+ "idle_event_handler",
idle_event_handler, result);
if (result->te == NULL) {
DEBUG(0, ("event_add_timed failed\n"));
process_aio_queue();
- process_kernel_oplocks(smbd_messaging_context(), pfds);
+ process_kernel_oplocks(pfds);
/* Do the aio check again after receive_local_message as it does a
select and may have eaten our signal. */
* messages as we need to synchronously process any messages
* we may have sent to ourselves from the previous SMB.
*/
- message_dispatch(smbd_messaging_context());
+ message_dispatch();
/*
* Check to see if we already have a message on the deferred open queue
goto again;
}
- return receive_smb(smbd_server_fd(), buffer, 0);
+ return receive_smb(smbd_server_fd(), buffer,
+ BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE, 0);
}
/*
return;
}
- process_kernel_oplocks(smbd_messaging_context(), NULL);
+ process_kernel_oplocks(NULL);
return;
}
}
if (!change_to_user(conn,session_tag)) {
+ remove_deferred_open_smb_message(
+ SVAL(inbuf, smb_mid));
return(ERROR_NT(NT_STATUS_DOS(ERRSRV,ERRbaduid)));
}
outsize += chain_size;
- if(outsize > 4) {
- smb_setlen(inbuf,outbuf,outsize - 4);
- }
+ if(outsize > 4)
+ smb_setlen(outbuf,outsize - 4);
return(outsize);
}
void construct_reply_common(const char *inbuf, char *outbuf)
{
- set_message(inbuf,outbuf,0,0,False);
+ set_message(outbuf,0,0,False);
SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
SIVAL(outbuf,smb_rcls,0);
/* work out the new size for the in buffer. */
new_size = size - (inbuf2 - inbuf);
if (new_size < 0) {
- DEBUG(0,("chain_reply: chain packet size incorrect "
- "(orig size = %d, offset = %d)\n",
- size, (int)(inbuf2 - inbuf) ));
+ DEBUG(0,("chain_reply: chain packet size incorrect (orig size = %d, "
+ "offset = %d)\n",
+ size,
+ (inbuf2 - inbuf) ));
exit_server_cleanly("Bad chained packet");
return(-1);
}
/* And set it in the header. */
- smb_setlen(inbuf, inbuf2, new_size);
+ smb_setlen(inbuf2, new_size);
/* create the out buffer */
construct_reply_common(inbuf2, outbuf2);
{
int select_timeout;
- select_timeout = SMBD_SELECT_TIMEOUT*1000;
+ select_timeout = blocking_locks_timeout_ms(SMBD_SELECT_TIMEOUT*1000);
if (print_notify_messages_pending()) {
select_timeout = MIN(select_timeout, 1000);
Process any timeout housekeeping. Return False if the caller should exit.
****************************************************************************/
-static BOOL timeout_processing(int *select_timeout,
- time_t *last_timeout_processing_time)
+static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_timeout_processing_time)
{
+ static time_t last_keepalive_sent_time = 0;
+ static time_t last_idle_closed_check = 0;
time_t t;
+ BOOL allidle = True;
if (smb_read_error == READ_EOF) {
DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));
*last_timeout_processing_time = t = time(NULL);
+ if(last_keepalive_sent_time == 0)
+ last_keepalive_sent_time = t;
+
+ if(last_idle_closed_check == 0)
+ last_idle_closed_check = t;
+
/* become root again if waiting */
change_to_root_user();
+ /* run all registered idle events */
+ smb_run_idle_events(t);
+
/* check if we need to reload services */
check_reload(t);
+ /* automatic timeout if all connections are closed */
+ if (conn_num_open()==0 && (t - last_idle_closed_check) >= IDLE_CLOSED_TIMEOUT) {
+ DEBUG( 2, ( "Closing idle connection\n" ) );
+ return False;
+ } else {
+ last_idle_closed_check = t;
+ }
+
+ if (keepalive && (t - last_keepalive_sent_time)>keepalive) {
+ if (!send_keepalive(smbd_server_fd())) {
+ DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
+ return False;
+ }
+
+ /* send a keepalive for a password server or the like.
+ This is attached to the auth_info created in the
+ negprot */
+ if (negprot_global_auth_context && negprot_global_auth_context->challenge_set_method
+ && negprot_global_auth_context->challenge_set_method->send_keepalive) {
+
+ negprot_global_auth_context->challenge_set_method->send_keepalive
+ (&negprot_global_auth_context->challenge_set_method->private_data);
+ }
+
+ last_keepalive_sent_time = t;
+ }
+
+ /* check for connection timeouts */
+ allidle = conn_idle_all(t, deadtime);
+
+ if (allidle && conn_num_open()>0) {
+ DEBUG(2,("Closing idle connection 2.\n"));
+ return False;
+ }
+
if(global_machine_password_needs_changing &&
/* for ADS we need to do a regular ADS password change, not a domain
password change */
secrets_lock_trust_account_password(lp_workgroup(), False);
}
+ /*
+ * Check to see if we have any blocking locks
+ * outstanding on the queue.
+ */
+ process_blocking_lock_queue();
+
/* update printer queue caches if necessary */
update_monitored_printq_cache();
/* Send any queued printer notify message to interested smbd's. */
- print_notify_send_messages(smbd_messaging_context(), 0);
+ print_notify_send_messages(0);
/*
* Modify the select timeout depending upon
max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
while (True) {
+ int deadtime = lp_deadtime()*60;
int select_timeout = setup_select_timeout();
int num_echos;
+ if (deadtime <= 0)
+ deadtime = DEFAULT_SMBD_TIMEOUT;
+
errno = 0;
/* free up temporary memory */
/* Did someone ask for immediate checks on things like blocking locks ? */
if (select_timeout == 0) {
- if(!timeout_processing(&select_timeout,
- &last_timeout_processing_time))
+ if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
return;
num_smbs = 0; /* Reset smb counter. */
}
#endif
while (!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout)) {
- if(!timeout_processing(&select_timeout,
- &last_timeout_processing_time))
+ if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
return;
num_smbs = 0; /* Reset smb counter. */
}
process_smb(InBuffer, OutBuffer);
if (smb_echo_count != num_echos) {
- if(!timeout_processing( &select_timeout, &last_timeout_processing_time))
+ if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
return;
num_smbs = 0; /* Reset smb counter. */
}
if ((num_smbs % 200) == 0) {
time_t new_check_time = time(NULL);
if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) {
- if(!timeout_processing(
- &select_timeout,
- &last_timeout_processing_time))
+ if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
return;
num_smbs = 0; /* Reset smb counter. */
last_timeout_processing_time = new_check_time; /* Reset time. */