BOOL global_machine_password_needs_changing = False;
extern int max_send;
+/****************************************************************************
+ Function to return the current request mid from Inbuffer.
+****************************************************************************/
+
+uint16 get_current_mid(void)
+{
+ return SVAL(InBuffer,smb_mid);
+}
+
/****************************************************************************
structure to hold a linked list of queued messages.
for processing.
****************************************************************************/
typedef struct {
- ubi_slNode msg_next;
- char *msg_buf;
- int msg_len;
+ ubi_slNode msg_next;
+ char *msg_buf;
+ int msg_len;
} pending_message_list;
static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
static BOOL push_message(ubi_slList *list_head, char *buf, int msg_len)
{
- pending_message_list *msg = (pending_message_list *)
+ pending_message_list *msg = (pending_message_list *)
malloc(sizeof(pending_message_list));
- if(msg == NULL)
- {
- DEBUG(0,("push_message: malloc fail (1)\n"));
- return False;
- }
+ if(msg == NULL) {
+ DEBUG(0,("push_message: malloc fail (1)\n"));
+ return False;
+ }
- msg->msg_buf = (char *)malloc(msg_len);
- if(msg->msg_buf == NULL)
- {
- DEBUG(0,("push_message: malloc fail (2)\n"));
- SAFE_FREE(msg);
- return False;
- }
+ msg->msg_buf = (char *)malloc(msg_len);
+ if(msg->msg_buf == NULL) {
+ DEBUG(0,("push_message: malloc fail (2)\n"));
+ SAFE_FREE(msg);
+ return False;
+ }
- memcpy(msg->msg_buf, buf, msg_len);
- msg->msg_len = msg_len;
+ memcpy(msg->msg_buf, buf, msg_len);
+ msg->msg_len = msg_len;
- ubi_slAddTail( list_head, msg);
+ ubi_slAddTail( list_head, msg);
- return True;
+ /* Push the MID of this packet on the signing queue. */
+ srv_defer_sign_response(SVAL(buf,smb_mid));
+
+ return True;
}
/****************************************************************************
void respond_to_all_remaining_local_messages(void)
{
- char buffer[1024];
-
- /*
- * Assert we have no exclusive open oplocks.
- */
-
- if(get_number_of_exclusive_open_oplocks()) {
- DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
- get_number_of_exclusive_open_oplocks() ));
- return;
- }
-
- /*
- * Keep doing receive_local_message with a 1 ms timeout until
- * we have no more messages.
- */
- while(receive_local_message(buffer, sizeof(buffer), 1)) {
- /* Deal with oplock break requests from other smbd's. */
- process_local_message(buffer, sizeof(buffer));
- }
-
- return;
+ char buffer[1024];
+
+ /*
+ * Assert we have no exclusive open oplocks.
+ */
+
+ if(get_number_of_exclusive_open_oplocks()) {
+ DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
+ get_number_of_exclusive_open_oplocks() ));
+ return;
+ }
+
+ /*
+ * Keep doing receive_local_message with a 1 ms timeout until
+ * we have no more messages.
+ */
+
+ while(receive_local_message(buffer, sizeof(buffer), 1)) {
+ /* Deal with oplock break requests from other smbd's. */
+ process_local_message(buffer, sizeof(buffer));
+ }
+
+ return;
}
#define CAN_IPC (1<<3)
#define AS_GUEST (1<<5)
#define QUEUE_IN_OPLOCK (1<<6)
+#define DO_CHDIR (1<<7)
/*
define a list of possible SMB messages and their corresponding
functions. Any message that has a NULL function is unimplemented -
please feel free to contribute implementations!
*/
-static const struct smb_message_struct
-{
- const char *name;
- int (*fn)(connection_struct *conn, char *, char *, int, int);
- int flags;
-}
- smb_messages[256] = {
+static const struct smb_message_struct {
+ const char *name;
+ int (*fn)(connection_struct *conn, char *, char *, int, int);
+ int flags;
+} smb_messages[256] = {
/* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
/* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
/* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
/* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
/* 0x10 */ { "SMBchkpth",reply_chkpth,AS_USER},
-/* 0x11 */ { "SMBexit",reply_exit,0},
+/* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
/* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
/* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
/* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
/* 0x6e */ { NULL, NULL, 0 },
/* 0x6f */ { NULL, NULL, 0 },
/* 0x70 */ { "SMBtcon",reply_tcon,0},
-/* 0x71 */ { "SMBtdis",reply_tdis,0},
+/* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
/* 0x72 */ { "SMBnegprot",reply_negprot,0},
/* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
/* 0x74 */ { "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
/* 0xa2 */ { "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
/* 0xa3 */ { NULL, NULL, 0 },
/* 0xa4 */ { "SMBntcancel", reply_ntcancel, 0 },
-/* 0xa5 */ { NULL, NULL, 0 },
+/* 0xa5 */ { "SMBntrename", reply_ntrename, AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
/* 0xa6 */ { NULL, NULL, 0 },
/* 0xa7 */ { NULL, NULL, 0 },
/* 0xa8 */ { NULL, NULL, 0 },
if (ret != len)
DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
close(fd);
- DEBUG(0,("created %s len %d\n", fname, len));
+ DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
}
}
uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
- DEBUG(3,("switch message %s (pid %d)\n",smb_fn_name(type),(int)pid));
+ DEBUG(3,("switch message %s (pid %d) conn 0x%x\n",smb_fn_name(type),(int)pid,(unsigned int)conn));
smb_dump(smb_fn_name(type), 1, inbuf, size);
if(global_oplock_break) {
if(session_tag != UID_FIELD_INVALID)
vuser = get_valid_user_struct(session_tag);
if(vuser != NULL)
- current_user_info = vuser->user;
+ set_current_user_info(&vuser->user);
}
/* does this protocol need to be run as root? */
if (flags & AS_GUEST)
flags &= ~AS_USER;
else
- return(ERROR_DOS(ERRSRV,ERRaccess));
+ return(ERROR_FORCE_DOS(ERRSRV,ERRbaduid));
}
/* this code is to work around a bug is MS client 3 without
return(ERROR_DOS(ERRSRV,ERRaccess));
/* load service specific parameters */
- if (conn && !set_current_service(conn,(flags & AS_USER)?True:False))
+ if (conn && !set_current_service(conn,(flags & (AS_USER|DO_CHDIR)?True:False)))
return(ERROR_DOS(ERRSRV,ERRaccess));
/* does this protocol need to be run as guest? */
}
/****************************************************************************
- process an smb from the client - split out from the smbd_process() code so
- it can be used by the oplock break code.
+ Process an smb from the client - split out from the smbd_process() code so
+ it can be used by the oplock break code.
****************************************************************************/
+
void process_smb(char *inbuf, char *outbuf)
{
- static int trans_num;
- int msg_type = CVAL(inbuf,0);
- int32 len = smb_len(inbuf);
- int nread = len + 4;
-
- DO_PROFILE_INC(smb_count);
-
- if (trans_num == 0) {
- /* on the first packet, check the global hosts allow/ hosts
- deny parameters before doing any parsing of the packet
- passed to us by the client. This prevents attacks on our
- parsing code from hosts not in the hosts allow list */
- if (smbd_process_limit() ||
- !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) {
- /* send a negative session response "not listening on calling
- name" */
- static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
- DEBUG( 1, ( "Connection denied from %s\n",
- client_addr() ) );
- (void)send_smb(smbd_server_fd(),(char *)buf);
- exit_server("connection denied");
- }
- }
-
- DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type, len ) );
- DEBUG( 3, ( "Transaction %d of length %d\n", trans_num, nread ) );
-
- if (msg_type == 0)
- show_msg(inbuf);
- else if(msg_type == SMBkeepalive)
- return; /* Keepalive packet. */
-
- nread = construct_reply(inbuf,outbuf,nread,max_send);
+ static int trans_num;
+ int msg_type = CVAL(inbuf,0);
+ int32 len = smb_len(inbuf);
+ int nread = len + 4;
+
+ DO_PROFILE_INC(smb_count);
+
+ if (trans_num == 0) {
+ /* on the first packet, check the global hosts allow/ hosts
+ deny parameters before doing any parsing of the packet
+ passed to us by the client. This prevents attacks on our
+ parsing code from hosts not in the hosts allow list */
+ if (smbd_process_limit() ||
+ !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) {
+ /* send a negative session response "not listening on calling name" */
+ static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
+ DEBUG( 1, ( "Connection denied from %s\n", client_addr() ) );
+ (void)send_smb(smbd_server_fd(),(char *)buf);
+ exit_server("connection denied");
+ }
+ }
+
+ DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type, len ) );
+ DEBUG( 3, ( "Transaction %d of length %d\n", trans_num, nread ) );
+
+ if (msg_type == 0)
+ show_msg(inbuf);
+ else if(msg_type == SMBkeepalive)
+ return; /* Keepalive packet. */
+
+ nread = construct_reply(inbuf,outbuf,nread,max_send);
- if(nread > 0)
- {
- if (CVAL(outbuf,0) == 0)
- show_msg(outbuf);
+ if(nread > 0) {
+ if (CVAL(outbuf,0) == 0)
+ show_msg(outbuf);
- if (nread != smb_len(outbuf) + 4)
- {
- DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
- nread, smb_len(outbuf)));
- }
- else
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("process_smb: send_smb failed.");
- }
- trans_num++;
+ if (nread != smb_len(outbuf) + 4) {
+ DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
+ nread, smb_len(outbuf)));
+ } else if (!send_smb(smbd_server_fd(),outbuf)) {
+ exit_server("process_smb: send_smb failed.");
+ }
+ }
+ trans_num++;
}
-
-
/****************************************************************************
-return a string containing the function name of a SMB command
+ Return a string containing the function name of a SMB command.
****************************************************************************/
+
const char *smb_fn_name(int type)
{
const char *unknown_name = "SMBunknown";
return(smb_messages[type].name);
}
-
/****************************************************************************
- Helper function for contruct_reply.
+ Helper functions for contruct_reply.
****************************************************************************/
+static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_EXTENDED_SECURITY|FLAGS2_32_BIT_ERROR_CODES;
+
+void remove_from_common_flags2(uint32 v)
+{
+ common_flags2 &= ~v;
+}
+
void construct_reply_common(char *inbuf,char *outbuf)
{
memset(outbuf,'\0',smb_size);
SCVAL(outbuf,smb_reh,0);
SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
SSVAL(outbuf,smb_flg2,
- (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
- FLAGS2_LONG_PATH_COMPONENTS |
- FLAGS2_32_BIT_ERROR_CODES | FLAGS2_EXTENDED_SECURITY);
+ (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
+ common_flags2);
SSVAL(outbuf,smb_err,SMB_SUCCESS);
SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
}
/****************************************************************************
- construct a chained reply and add it to the already made reply
- **************************************************************************/
+ Construct a chained reply and add it to the already made reply
+****************************************************************************/
+
int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
{
- static char *orig_inbuf;
- static char *orig_outbuf;
- int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
- unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
- char *inbuf2, *outbuf2;
- int outsize2;
- char inbuf_saved[smb_wct];
- char outbuf_saved[smb_wct];
- int wct = CVAL(outbuf,smb_wct);
- int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
-
- /* maybe its not chained */
- if (smb_com2 == 0xFF) {
- SCVAL(outbuf,smb_vwv0,0xFF);
- return outsize;
- }
-
- if (chain_size == 0) {
- /* this is the first part of the chain */
- orig_inbuf = inbuf;
- orig_outbuf = outbuf;
- }
-
- /*
- * The original Win95 redirector dies on a reply to
- * a lockingX and read chain unless the chain reply is
- * 4 byte aligned. JRA.
- */
-
- outsize = (outsize + 3) & ~3;
-
- /* we need to tell the client where the next part of the reply will be */
- SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
- SCVAL(outbuf,smb_vwv0,smb_com2);
-
- /* remember how much the caller added to the chain, only counting stuff
- after the parameter words */
- chain_size += outsize - smb_wct;
-
- /* work out pointers into the original packets. The
- headers on these need to be filled in */
- inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
- outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
-
- /* remember the original command type */
- smb_com1 = CVAL(orig_inbuf,smb_com);
-
- /* save the data which will be overwritten by the new headers */
- memcpy(inbuf_saved,inbuf2,smb_wct);
- memcpy(outbuf_saved,outbuf2,smb_wct);
-
- /* give the new packet the same header as the last part of the SMB */
- memmove(inbuf2,inbuf,smb_wct);
-
- /* create the in buffer */
- SCVAL(inbuf2,smb_com,smb_com2);
-
- /* create the out buffer */
- construct_reply_common(inbuf2, outbuf2);
-
- DEBUG(3,("Chained message\n"));
- show_msg(inbuf2);
-
- /* process the request */
- outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
- bufsize-chain_size);
-
- /* copy the new reply and request headers over the old ones, but
- preserve the smb_com field */
- memmove(orig_outbuf,outbuf2,smb_wct);
- SCVAL(orig_outbuf,smb_com,smb_com1);
-
- /* restore the saved data, being careful not to overwrite any
- data from the reply header */
- memcpy(inbuf2,inbuf_saved,smb_wct);
- {
- int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
- if (ofs < 0) ofs = 0;
- memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
- }
-
- return outsize2;
+ static char *orig_inbuf;
+ static char *orig_outbuf;
+ int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
+ unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
+ char *inbuf2, *outbuf2;
+ int outsize2;
+ char inbuf_saved[smb_wct];
+ char outbuf_saved[smb_wct];
+ int wct = CVAL(outbuf,smb_wct);
+ int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
+
+ /* maybe its not chained */
+ if (smb_com2 == 0xFF) {
+ SCVAL(outbuf,smb_vwv0,0xFF);
+ return outsize;
+ }
+
+ if (chain_size == 0) {
+ /* this is the first part of the chain */
+ orig_inbuf = inbuf;
+ orig_outbuf = outbuf;
+ }
+
+ /*
+ * The original Win95 redirector dies on a reply to
+ * a lockingX and read chain unless the chain reply is
+ * 4 byte aligned. JRA.
+ */
+
+ outsize = (outsize + 3) & ~3;
+
+ /* we need to tell the client where the next part of the reply will be */
+ SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
+ SCVAL(outbuf,smb_vwv0,smb_com2);
+
+ /* remember how much the caller added to the chain, only counting stuff
+ after the parameter words */
+ chain_size += outsize - smb_wct;
+
+ /* work out pointers into the original packets. The
+ headers on these need to be filled in */
+ inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
+ outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
+
+ /* remember the original command type */
+ smb_com1 = CVAL(orig_inbuf,smb_com);
+
+ /* save the data which will be overwritten by the new headers */
+ memcpy(inbuf_saved,inbuf2,smb_wct);
+ memcpy(outbuf_saved,outbuf2,smb_wct);
+
+ /* give the new packet the same header as the last part of the SMB */
+ memmove(inbuf2,inbuf,smb_wct);
+
+ /* create the in buffer */
+ SCVAL(inbuf2,smb_com,smb_com2);
+
+ /* create the out buffer */
+ construct_reply_common(inbuf2, outbuf2);
+
+ DEBUG(3,("Chained message\n"));
+ show_msg(inbuf2);
+
+ /* process the request */
+ outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
+ bufsize-chain_size);
+
+ /* copy the new reply and request headers over the old ones, but
+ preserve the smb_com field */
+ memmove(orig_outbuf,outbuf2,smb_wct);
+ SCVAL(orig_outbuf,smb_com,smb_com1);
+
+ /* restore the saved data, being careful not to overwrite any
+ data from the reply header */
+ memcpy(inbuf2,inbuf_saved,smb_wct);
+
+ {
+ int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
+ if (ofs < 0) ofs = 0;
+ memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
+ }
+
+ return outsize2;
}
/****************************************************************************
void check_reload(int t)
{
- static time_t last_smb_conf_reload_time = 0;
+ static time_t last_smb_conf_reload_time = 0;
+ static time_t last_load_printers_reload_time = 0;
+ time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
+
+ if(last_smb_conf_reload_time == 0) {
+ last_smb_conf_reload_time = t;
+ /* Our printing subsystem might not be ready at smbd start up.
+ Then no printer is available till the first printers check
+ is performed. A lower initial interval circumvents this. */
+ if ( printcap_cache_time > 60 )
+ last_load_printers_reload_time = t - printcap_cache_time + 60;
+ else
+ last_load_printers_reload_time = t;
+ }
- if(last_smb_conf_reload_time == 0)
- last_smb_conf_reload_time = t;
+ if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
+ reload_services(True);
+ reload_after_sighup = False;
+ last_smb_conf_reload_time = t;
+ }
- if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK))
- {
- reload_services(True);
- reload_after_sighup = False;
- last_smb_conf_reload_time = t;
- }
+ /* 'printcap cache time = 0' disable the feature */
+
+ if ( printcap_cache_time != 0 )
+ {
+ /* see if it's time to reload or if the clock has been set back */
+
+ if ( (t >= last_load_printers_reload_time+printcap_cache_time)
+ || (t-last_load_printers_reload_time < 0) )
+ {
+ DEBUG( 3,( "Printcap cache time expired.\n"));
+ remove_stale_printers();
+ load_printers();
+ last_load_printers_reload_time = t;
+ }
+ }
}
/****************************************************************************
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;
- extern int keepalive;
-
- if (smb_read_error == READ_EOF)
- {
- DEBUG(3,("end of file from client\n"));
- return False;
- }
-
- if (smb_read_error == READ_ERROR)
- {
- DEBUG(3,("receive_smb error (%s) exiting\n",
- strerror(errno)));
- return False;
- }
-
- *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();
-
- /* 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)
- {
- extern struct auth_context *negprot_global_auth_context;
- 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 */
- lp_security() == SEC_DOMAIN)
- {
- unsigned char trust_passwd_hash[16];
- time_t lct;
-
- /*
- * We're in domain level security, and the code that
- * read the machine password flagged that the machine
- * password needs changing.
- */
-
- /*
- * First, open the machine password file with an exclusive lock.
- */
-
- if (secrets_lock_trust_account_password(lp_workgroup(), True) == False) {
- DEBUG(0,("process: unable to lock the machine account password for \
+ static time_t last_keepalive_sent_time = 0;
+ static time_t last_idle_closed_check = 0;
+ time_t t;
+ BOOL allidle = True;
+ extern int keepalive;
+
+ if (smb_read_error == READ_EOF) {
+ DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));
+ return False;
+ }
+
+ if (smb_read_error == READ_ERROR) {
+ DEBUG(3,("timeout_processing: receive_smb error (%s) Exiting\n",
+ strerror(errno)));
+ return False;
+ }
+
+ if (smb_read_error == READ_BAD_SIG) {
+ DEBUG(3,("timeout_processing: receive_smb error bad smb signature. Exiting\n"));
+ return False;
+ }
+
+ *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) {
+ extern struct auth_context *negprot_global_auth_context;
+ 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 */
+ lp_security() == SEC_DOMAIN) {
+
+ unsigned char trust_passwd_hash[16];
+ time_t lct;
+
+ /*
+ * We're in domain level security, and the code that
+ * read the machine password flagged that the machine
+ * password needs changing.
+ */
+
+ /*
+ * First, open the machine password file with an exclusive lock.
+ */
+
+ if (secrets_lock_trust_account_password(lp_workgroup(), True) == False) {
+ DEBUG(0,("process: unable to lock the machine account password for \
machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
- return True;
- }
+ return True;
+ }
- if(!secrets_fetch_trust_account_password(lp_workgroup(),
- trust_passwd_hash,
- &lct, NULL)) {
- DEBUG(0,("process: unable to read the machine account password for \
+ if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) {
+ DEBUG(0,("process: unable to read the machine account password for \
machine %s in domain %s.\n", global_myname(), lp_workgroup()));
- secrets_lock_trust_account_password(lp_workgroup(), False);
- return True;
- }
+ secrets_lock_trust_account_password(lp_workgroup(), False);
+ return True;
+ }
- /*
- * Make sure someone else hasn't already done this.
- */
+ /*
+ * Make sure someone else hasn't already done this.
+ */
- if(t < lct + lp_machine_password_timeout()) {
- global_machine_password_needs_changing = False;
- secrets_lock_trust_account_password(lp_workgroup(), False);
- return True;
- }
+ if(t < lct + lp_machine_password_timeout()) {
+ global_machine_password_needs_changing = False;
+ secrets_lock_trust_account_password(lp_workgroup(), False);
+ return True;
+ }
- /* always just contact the PDC here */
+ /* always just contact the PDC here */
- change_trust_account_password( lp_workgroup(), NULL);
- global_machine_password_needs_changing = False;
- 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(t);
-
- /* update printer queue caches if necessary */
+ change_trust_account_password( lp_workgroup(), NULL);
+ global_machine_password_needs_changing = False;
+ 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(t);
+
+ /* update printer queue caches if necessary */
- update_monitored_printq_cache();
+ update_monitored_printq_cache();
- /*
- * Check to see if we have any change notifies
- * outstanding on the queue.
- */
- process_pending_change_notify_queue(t);
+ /*
+ * Check to see if we have any change notifies
+ * outstanding on the queue.
+ */
+ process_pending_change_notify_queue(t);
- /*
- * Now we are root, check if the log files need pruning.
- * Force a log file check.
- */
- force_check_log_size();
- check_log_size();
+ /*
+ * Now we are root, check if the log files need pruning.
+ * Force a log file check.
+ */
+ force_check_log_size();
+ check_log_size();
- /* Send any queued printer notify message to interested smbd's. */
+ /* Send any queued printer notify message to interested smbd's. */
- print_notify_send_messages(0);
+ print_notify_send_messages(0);
- /*
- * Modify the select timeout depending upon
- * what we have remaining in our queues.
- */
+ /*
+ * Modify the select timeout depending upon
+ * what we have remaining in our queues.
+ */
- *select_timeout = setup_select_timeout();
+ *select_timeout = setup_select_timeout();
- return True;
+ return True;
}
/****************************************************************************
if ((InBuffer == NULL) || (OutBuffer == NULL))
return;
+#if defined(DEVELOPER)
clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size);
+#endif
max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
lp_talloc_free();
main_loop_talloc_free();
+ /* run all registered idle events */
+ smb_run_idle_events(time(NULL));
+
+
/* Did someone ask for immediate checks on things like blocking locks ? */
if (select_timeout == 0) {
if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
num_smbs = 0; /* Reset smb counter. */
}
+#if defined(DEVELOPER)
clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
+#endif
while (!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout)) {
if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))