#include "includes.h"
-extern int DEBUGLEVEL;
-
struct timeval smb_last_time;
static char *InBuffer = NULL;
extern int last_message;
extern int global_oplock_break;
extern userdom_struct current_user_info;
-extern char *last_inbuf;
-extern char *InBuffer;
-extern char *OutBuffer;
extern int smb_read_error;
-extern VOLATILE SIG_ATOMIC_T reload_after_sighup;
+extern VOLATILE sig_atomic_t reload_after_sighup;
extern BOOL global_machine_password_needs_changing;
extern fstring global_myworkgroup;
extern pstring global_myname;
if(msg->msg_buf == NULL)
{
DEBUG(0,("push_message: malloc fail (2)\n"));
- free((char *)msg);
+ SAFE_FREE(msg);
return False;
}
/* check for sighup processing */
if (reload_after_sighup) {
- unbecome_user();
+ change_to_root_user();
DEBUG(1,("Reloading services after SIGHUP\n"));
reload_services(False);
reload_after_sighup = False;
memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
/* Free the message we just copied. */
- free((char *)msg->msg_buf);
- free((char *)msg);
+ SAFE_FREE(msg->msg_buf);
+ SAFE_FREE(msg);
DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
return True;
signals */
if (selrtn == -1 && errno == EINTR) {
async_processing(&fds, buffer, buffer_len);
+ /*
+ * After async processing we must go and do the select again, as
+ * the state of the flag in fds for the server file descriptor is
+ * indeterminate - we may have done I/O on it in the oplock processing. JRA.
+ */
goto again;
}
return False;
}
- if (!FD_ISSET(smbd_server_fd(),&fds) || selrtn > 1) {
+ /*
+ * Ensure we process oplock break messages by preference.
+ * This is IMPORTANT ! Otherwise we can starve other processes
+ * sending us an oplock break message. JRA.
+ */
+
+ if (oplock_message_waiting(&fds)) {
async_processing(&fds, buffer, buffer_len);
- if (!FD_ISSET(smbd_server_fd(),&fds)) goto again;
+ /*
+ * After async processing we must go and do the select again, as
+ * the state of the flag in fds for the server file descriptor is
+ * indeterminate - we may have done I/O on it in the oplock processing. JRA.
+ */
+ goto again;
}
return receive_smb(smbd_server_fd(), buffer, 0);
do {
ret = receive_message_or_smb(inbuf,bufsize,timeout);
- got_keepalive = (ret && (CVAL(inbuf,0) == 0x85));
+ got_keepalive = (ret && (CVAL(inbuf,0) == SMBkeepalive));
} while (ret && got_keepalive);
return ret;
/* 0x19 */ { NULL, NULL, 0 },
/* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
/* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
-/* 0x1c */ { "SMBreadBs",NULL,AS_USER},
+/* 0x1c */ { "SMBreadBs",NULL,0 },
/* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
-/* 0x20 */ { "SMBwritec",NULL,AS_USER},
+/* 0x20 */ { "SMBwritec",NULL,0},
/* 0x21 */ { NULL, NULL, 0 },
/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
/* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
if (len < 4) len = smb_len(data)+4;
for (i=1;i<100;i++) {
- slprintf(fname,sizeof(fname), "/tmp/%s.%d.%s", name, i,
+ slprintf(fname,sizeof(fname)-1, "/tmp/%s.%d.%s", name, i,
type ? "req" : "resp");
fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
if (fd != -1 || errno != EEXIST) break;
{
static pid_t pid= (pid_t)-1;
int outsize = 0;
- extern int global_smbpid;
+ extern uint16 global_smbpid;
type &= 0xff;
/* does this protocol need to be run as root? */
if (!(flags & AS_USER))
- unbecome_user();
+ change_to_root_user();
+
+ /* does this protocol need a valid tree connection? */
+ if ((flags & AS_USER) && !conn) {
+ return ERROR_DOS(ERRSRV, ERRinvnid);
+ }
+
/* does this protocol need to be run as the connected user? */
- if ((flags & AS_USER) && !become_user(conn,session_tag)) {
+ if ((flags & AS_USER) && !change_to_user(conn,session_tag)) {
if (flags & AS_GUEST)
flags &= ~AS_USER;
else
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
}
/* this code is to work around a bug is MS client 3 without
/* does it need write permission? */
if ((flags & NEED_WRITE) && !CAN_WRITE(conn))
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
/* ipc services are limited */
if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC)) {
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
}
/* load service specific parameters */
- if (conn && !become_service(conn,(flags & AS_USER)?True:False)) {
- return(ERROR(ERRSRV,ERRaccess));
+ if (conn && !set_current_service(conn,(flags & AS_USER)?True:False)) {
+ return(ERROR_DOS(ERRSRV,ERRaccess));
}
/* does this protocol need to be run as guest? */
if ((flags & AS_GUEST) &&
- (!become_guest() ||
+ (!change_to_guest() ||
!check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) {
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
}
last_inbuf = inbuf;
/* Always add one to the smbd process count, as exit_server() always
* subtracts one.
*/
- tdb_lock_bystring(conn_tdb_ctx(), "INFO/total_smbds");
- total_smbds = tdb_fetch_int(conn_tdb_ctx(), "INFO/total_smbds");
- total_smbds = total_smbds < 0 ? 1 : total_smbds + 1;
- tdb_store_int(conn_tdb_ctx(), "INFO/total_smbds", total_smbds);
- tdb_unlock_bystring(conn_tdb_ctx(), "INFO/total_smbds");
-
+
+ total_smbds = 1; /* In case we need to create the entry. */
+
+ if (!conn_tdb_ctx()) {
+ DEBUG(0,("smbd_process_limit: max smbd processes parameter set with status parameter not \
+set. Ignoring max smbd restriction.\n"));
+ return False;
+ }
+
+ if (tdb_change_int_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, 1) == -1)
+ return True;
+
return total_smbds > lp_max_smbd_processes();
}
else
static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
DEBUG( 1, ( "Connection denied from %s\n",
client_addr() ) );
- send_smb(smbd_server_fd(),(char *)buf);
+ (void)send_smb(smbd_server_fd(),(char *)buf);
exit_server("connection denied");
}
}
if (msg_type == 0)
show_msg(inbuf);
- else if(msg_type == 0x85)
+ else if(msg_type == SMBkeepalive)
return; /* Keepalive packet. */
nread = construct_reply(inbuf,outbuf,nread,max_send);
nread, smb_len(outbuf)));
}
else
- send_smb(smbd_server_fd(),outbuf);
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("process_smb: send_smb failed.");
}
trans_num++;
}
void construct_reply_common(char *inbuf,char *outbuf)
{
- memset(outbuf,'\0',smb_size);
-
- set_message(outbuf,0,0,True);
- CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
-
- memcpy(outbuf+4,inbuf+4,4);
- CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
- CVAL(outbuf,smb_reh) = 0;
- SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); /* bit 7 set
- means a reply */
- SSVAL(outbuf,smb_flg2,
- (SVAL(inbuf,smb_flg2)&FLAGS2_UNICODE_STRINGS) | FLAGS2_LONG_PATH_COMPONENTS);
- /* say we support long filenames */
-
- SSVAL(outbuf,smb_err,SMB_SUCCESS);
- SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
- SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
- SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
- SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
+ memset(outbuf,'\0',smb_size);
+
+ set_message(outbuf,0,0,True);
+ CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
+
+ memcpy(outbuf+4,inbuf+4,4);
+ CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
+ CVAL(outbuf,smb_reh) = 0;
+ SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
+ SSVAL(outbuf,smb_flg2,
+ FLAGS2_UNICODE_STRINGS | FLAGS2_LONG_PATH_COMPONENTS |
+ FLAGS2_32_BIT_ERROR_CODES | FLAGS2_EXTENDED_SECURITY);
+
+ SSVAL(outbuf,smb_err,SMB_SUCCESS);
+ SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
+ SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
+ SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
+ SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
}
/****************************************************************************
last_idle_closed_check = t;
/* become root again if waiting */
- unbecome_user();
+ change_to_root_user();
/* check if we need to reload services */
check_reload(t);
/* also send a keepalive to the password server if its still
connected */
if (cli && cli->initialised)
- send_keepalive(cli->fd);
+ if (!send_keepalive(cli->fd)) {
+ DEBUG( 2, ( "password server keepalive failed.\n"));
+ cli_shutdown(cli);
+ }
last_keepalive_sent_time = t;
}
/*
* Now we are root, check if the log files need pruning.
+ * Force a log file check.
*/
- if(need_to_check_log_size())
- check_log_size();
+ force_check_log_size();
+ check_log_size();
/*
* Modify the select timeout depending upon
time_t last_timeout_processing_time = time(NULL);
unsigned int num_smbs = 0;
- InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+ InBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
+ OutBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
if ((InBuffer == NULL) || (OutBuffer == NULL))
return;
/* re-initialise the timezone */
TimeInit();
+ /* register our message handlers */
+ message_register(MSG_SMB_FORCE_TDIS, msg_force_tdis);
+
while (True) {
int deadtime = lp_deadtime()*60;
int select_timeout = setup_select_timeout();
lp_talloc_free();
main_loop_talloc_free();
- while (!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout)) {
+ while (!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout)) {
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(last_timeout_processing_time - new_check_time >= (select_timeout/1000)) {
+ if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) {
if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
return;
num_smbs = 0; /* Reset smb counter. */