Commit 772ac0b2 authored by deuce's avatar deuce
Browse files

Linux will now (sort of) run as a non-root user. After hours of trying

to track down the issue, I finally gave up... as a result, there is a new
feature!

Linux will no longer completely drop it's root privs (It never really did
anyways, and you couldn't possibly make it... but now it does so even less)

As a result, Linux can now recycle all servers when running as non-root.

From a security standpoint, doing this is more secure than running as root,
but less secure than the behaviour on POSIX.4 compliant pthreads.  Running
the BBS as root means that if a user can create a file with the name of his
choice, or pass *any* command through to a shell, that user will get root
access to the machine.  Using the new behaviour, the user would need to
trick the Synchronet binary itself into executing arbitrary and specially
crafted code... probobly using the dreaded buffer overflow... of which
there are probobly some in the web server code.  :-)  If the user can do
this much more tricky feat, then the user gets root privs.  If not, the
user will have to find something else to exploit on your system.

Knowing that some *BSD users (surely not OpenBSD users though) will want to
trade security for convenience, I stole a page out of the Sendmail book and
implemented a "DONT_BLAME_SYNCHRONET" make option.  Compiling like this:
gmake DONT_BLAME_SYNCHRONET=1

Will implement this same behaviour on non-Linux platforms.  Allowing this
partial security feature.
parent 85c4a27e
......@@ -164,6 +164,10 @@ ifndef NSPRDIR
NSPRDIR := ../../lib/mozilla/nspr/$(os).$(BUILD)
endif
ifdef DONT_BLAME_SYNCHRONET
LFLAGS += -DDONT_BLAME_SYNCHRONET
endif
LFLAGS += -L$(JSLIBDIR) -l$(JSLIB)
# The following are needed for echocfg (uses UIFC)
......
......@@ -4495,6 +4495,10 @@ void DLLCALL ftp_server(void* arg)
startup=(ftp_startup_t*)arg;
#ifdef _THREAD_SUID_BROKEN
startup->seteuid(TRUE);
#endif
if(startup==NULL) {
sbbs_beep(100,500);
fprintf(stderr, "No startup structure passed!\n");
......@@ -4531,6 +4535,7 @@ void DLLCALL ftp_server(void* arg)
served=0;
startup->recycle_now=FALSE;
recycle_server=TRUE;
do {
thread_up(FALSE /* setuid */);
......@@ -4660,10 +4665,6 @@ void DLLCALL ftp_server(void* arg)
return;
}
/* signal caller that we've started up successfully */
if(startup->started!=NULL)
startup->started();
lprintf("%04d FTP Server thread started on port %d",server_socket,startup->port);
status(STATUS_WFC);
......@@ -4675,6 +4676,10 @@ void DLLCALL ftp_server(void* arg)
initialized=t;
}
/* signal caller that we've started up successfully */
if(startup->started!=NULL)
startup->started();
while(server_socket!=INVALID_SOCKET) {
if(!(startup->options&FTP_OPT_NO_RECYCLE)) {
......
......@@ -2941,10 +2941,10 @@ static void sendmail_thread(void* arg)
smb_t smb;
smbmsg_t msg;
sendmail_running=TRUE;
thread_up(TRUE /* setuid */);
sendmail_running=TRUE;
lprintf("0000 SendMail thread started");
memset(&msg,0,sizeof(msg));
......@@ -3346,6 +3346,10 @@ void DLLCALL mail_server(void* arg)
startup=(mail_startup_t*)arg;
#ifdef _THREAD_SUID_BROKEN
startup->seteuid(TRUE);
#endif
if(startup==NULL) {
sbbs_beep(100,500);
fprintf(stderr, "No startup structure passed!\n");
......@@ -3375,6 +3379,7 @@ void DLLCALL mail_server(void* arg)
served=0;
startup->recycle_now=FALSE;
recycle_server=TRUE;
do {
thread_up(FALSE /* setuid */);
......@@ -3548,10 +3553,6 @@ void DLLCALL mail_server(void* arg)
if(!(startup->options&MAIL_OPT_NO_SENDMAIL))
_beginthread(sendmail_thread, 0, NULL);
/* signal caller that we've started up successfully */
if(startup->started!=NULL)
startup->started();
lprintf("%04d Mail Server thread started",server_socket);
status(STATUS_WFC);
......@@ -3563,6 +3564,10 @@ void DLLCALL mail_server(void* arg)
initialized=t;
}
/* signal caller that we've started up successfully */
if(startup->started!=NULL)
startup->started();
while(server_socket!=INVALID_SOCKET) {
if(!(startup->options&MAIL_OPT_NO_RECYCLE)) {
......
......@@ -3540,6 +3540,10 @@ void DLLCALL bbs_thread(void* arg)
return;
}
#ifdef _THREAD_SUID_BROKEN
startup->seteuid(TRUE);
#endif
/* Setup intelligent defaults */
if(startup->telnet_port==0) startup->telnet_port=IPPORT_TELNET;
if(startup->rlogin_port==0) startup->rlogin_port=513;
......@@ -3806,10 +3810,6 @@ void DLLCALL bbs_thread(void* arg)
lprintf("RLogin server listening on port %d",startup->rlogin_port);
}
/* signal caller that we've started up successfully */
if(startup->started!=NULL)
startup->started();
sbbs = new sbbs_t(0, server_addr.sin_addr.s_addr
,"BBS System", telnet_socket, &scfg, text, NULL);
sbbs->online = 0;
......@@ -3930,6 +3930,11 @@ void DLLCALL bbs_thread(void* arg)
}
#endif // __unix__ (unix-domain spy sockets)
/* signal caller that we've started up successfully */
if(startup->started!=NULL)
startup->started();
while(telnet_socket!=INVALID_SOCKET) {
if(node_threads_running==0 && !event_mutex_locked) { /* check for re-run flags */
......
......@@ -229,25 +229,6 @@ static int lputs(char *str)
}
#ifdef __unix__
/**********************************************************
* Change uid of the calling process to the user if specified
* **********************************************************/
static BOOL do_setuid(void)
{
BOOL result=FALSE;
setregid(-1,old_gid);
setreuid(-1,old_uid);
if(!setregid(new_gid,new_gid) && !setreuid(new_uid,new_uid))
result=TRUE;
if(!result) {
lputs("!setuid FAILED");
lputs(strerror(errno));
}
return result;
}
/**********************************************************
* Change uid of the calling process to the user if specified
* **********************************************************/
......@@ -287,6 +268,29 @@ static BOOL do_seteuid(BOOL to_new)
}
return result;
}
/**********************************************************
* Change uid of the calling process to the user if specified
* **********************************************************/
static BOOL do_setuid(void)
{
#if defined(_THREAD_SUID_BROKEN) || defined(DONT_BLAME_SYNCHRONET)
return(do_seteuid(TRUE));
#else
BOOL result=FALSE;
setregid(-1,old_gid);
setreuid(-1,old_uid);
if(!setregid(new_gid,new_gid) && !setreuid(new_uid,new_uid))
result=TRUE;
if(!result) {
lputs("!setuid FAILED");
lputs(strerror(errno));
}
return result;
#endif
}
#endif /* __unix__ */
#ifdef _WINSOCKAPI_
......@@ -1537,6 +1541,7 @@ int main(int argc, char** argv)
/* ToDo: Something seems to be broken here on FreeBSD now */
/* ToDo: Now, they try to re-bind on FreeBSD */
/* ToDo: Seems like I switched problems with Linux */
#if defined(DONT_BLAME_SYNCHRONET) || defined(_THREAD_SUID_BROKEN)
if(bbs_startup.telnet_port < IPPORT_RESERVED
|| (bbs_startup.options & BBS_OPT_ALLOW_RLOGIN
&& bbs_startup.rlogin_port < IPPORT_RESERVED))
......@@ -1551,6 +1556,7 @@ int main(int argc, char** argv)
mail_startup.options|=MAIL_OPT_NO_RECYCLE;
/* Perhaps a BBS_OPT_NO_RECYCLE_LOW option? */
services_startup.options|=BBS_OPT_NO_RECYCLE;
#endif
}
}
......
......@@ -1590,6 +1590,10 @@ void DLLCALL services_thread(void* arg)
return;
}
#ifdef _THREAD_SUID_BROKEN
startup->seteuid(TRUE);
#endif
/* Setup intelligent defaults */
if(startup->sem_chk_freq==0) startup->sem_chk_freq=5;
if(startup->js_max_bytes==0) startup->js_max_bytes=JAVASCRIPT_MAX_BYTES;
......@@ -1769,10 +1773,6 @@ void DLLCALL services_thread(void* arg)
_beginthread(js_static_service_thread, 0, &service[i]);
}
/* signal caller that we've started up successfully */
if(startup->started!=NULL)
startup->started();
status("Listening");
if(initialized==0) {
......@@ -1785,6 +1785,10 @@ void DLLCALL services_thread(void* arg)
terminated=FALSE;
/* signal caller that we've started up successfully */
if(startup->started!=NULL)
startup->started();
/* Main Server Loop */
while(!terminated) {
......
......@@ -2264,7 +2264,7 @@ void http_session_thread(void* arg)
socket=session.socket;
lprintf("%04d Session thread started", session.socket);
thread_up(FALSE /* setuid */);
thread_up(TRUE /* setuid */);
session.finished=FALSE;
if(startup->options&BBS_OPT_NO_HOST_LOOKUP)
......@@ -2435,6 +2435,10 @@ void DLLCALL web_server(void* arg)
return;
}
#ifdef _THREAD_SUID_BROKEN
startup->seteuid(TRUE);
#endif
/* Setup intelligent defaults */
if(startup->port==0) startup->port=IPPORT_HTTP;
if(startup->root_dir[0]==0) SAFECOPY(startup->root_dir,"../html");
......@@ -2582,14 +2586,14 @@ void DLLCALL web_server(void* arg)
lprintf("Web Server listening on port %d",startup->port);
status("Listening");
/* signal caller that we've started up successfully */
if(startup->started!=NULL)
startup->started();
lprintf("Web Server thread started");
sprintf(path,"%swebsrvr.rec",scfg.ctrl_dir);
/* signal caller that we've started up successfully */
if(startup->started!=NULL)
startup->started();
while(server_socket!=INVALID_SOCKET) {
/* check for re-cycle semaphores */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment