From d1aaf12ac2a3cf45329f4be295f5922e5416d1b9 Mon Sep 17 00:00:00 2001
From: deuce <>
Date: Mon, 28 Aug 2006 22:56:16 +0000
Subject: [PATCH] Since NPTL is no has broken suid stuff, stop assuming it
 does. Since the only way to correcty detect NPTL is at *runtime*, add that
 detection in to main() and honour it throughout.  sbbscon.h makes the
 thread_suid_broken variable/macro available to other files which need it.

---
 src/sbbs3/ftpsrvr.c  |   4 +-
 src/sbbs3/mailsrvr.c |   4 +-
 src/sbbs3/main.cpp   |   4 +-
 src/sbbs3/sbbscon.c  | 103 +++++++++++++++++++++++++++----------------
 src/sbbs3/sbbscon.h  |  10 +++++
 src/sbbs3/services.c |   4 +-
 src/sbbs3/websrvr.c  |   4 +-
 7 files changed, 90 insertions(+), 43 deletions(-)
 create mode 100644 src/sbbs3/sbbscon.h

diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c
index 91ac1347fa..41fe13bac9 100644
--- a/src/sbbs3/ftpsrvr.c
+++ b/src/sbbs3/ftpsrvr.c
@@ -63,6 +63,7 @@
 #include "text.h"			/* TOTAL_TEXT */
 #include "ftpsrvr.h"
 #include "telnet.h"
+#include "sbbscon.h"		/* thread_suid_broken */
 
 /* Constants */
 
@@ -4565,7 +4566,8 @@ void DLLCALL ftp_server(void* arg)
 	startup=(ftp_startup_t*)arg;
 
 #ifdef _THREAD_SUID_BROKEN
-	startup->seteuid(TRUE);
+	if(thread_suid_broken)
+		startup->seteuid(TRUE);
 #endif
 
     if(startup==NULL) {
diff --git a/src/sbbs3/mailsrvr.c b/src/sbbs3/mailsrvr.c
index 5b75b1babf..f2693f529c 100644
--- a/src/sbbs3/mailsrvr.c
+++ b/src/sbbs3/mailsrvr.c
@@ -66,6 +66,7 @@
 #include "base64.h"
 #include "ini_file.h"
 #include "netwrap.h"	/* getNameServerList() */
+#include "sbbscon.h"        /* thread_suid_broken */
 
 /* Constants */
 #define FORWARD			"forward:"
@@ -4092,7 +4093,8 @@ void DLLCALL mail_server(void* arg)
 	startup=(mail_startup_t*)arg;
 
 #ifdef _THREAD_SUID_BROKEN
-	startup->seteuid(TRUE);
+	if(thread_suid_broken)
+		startup->seteuid(TRUE);
 #endif
 
     if(startup==NULL) {
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 7a004398a4..e3ac019d7f 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -38,6 +38,7 @@
 #include "sbbs.h"
 #include "ident.h"
 #include "telnet.h" 
+#include "sbbscon.h"        /* thread_suid_broken */
 
 #ifdef __unix__
 	#include <sys/un.h>
@@ -3796,7 +3797,8 @@ void DLLCALL bbs_thread(void* arg)
 	}
 
 #ifdef _THREAD_SUID_BROKEN
-	startup->seteuid(TRUE);
+	if(thread_suid_broken)
+		startup->seteuid(TRUE);
 #endif
 
 	/* Setup intelligent defaults */
diff --git a/src/sbbs3/sbbscon.c b/src/sbbs3/sbbscon.c
index be5b61c3ad..cf131b372d 100644
--- a/src/sbbs3/sbbscon.c
+++ b/src/sbbs3/sbbscon.c
@@ -51,6 +51,7 @@
 #include "ftpsrvr.h"	/* ftp_startup_t, ftp_server */
 #include "mailsrvr.h"	/* mail_startup_t, mail_server */
 #include "services.h"	/* services_startup_t, services_thread */
+#include "sbbscon.h"
 
 /* XPDEV headers */
 #include "conwrap.h"	/* kbhit/getch */
@@ -290,11 +291,6 @@ static BOOL do_seteuid(BOOL to_new)
 			result=FALSE;
 	}
 
-#if defined(_THREAD_SUID_BROKEN)
-	SLEEP(5);
-	SLEEP(5);
-#endif
-
 	pthread_mutex_unlock(&setid_mutex);
 
 	if(!result) {
@@ -310,11 +306,16 @@ static BOOL do_seteuid(BOOL to_new)
 BOOL do_setuid(BOOL force)
 {
 	BOOL result=TRUE;
-#if defined(DONT_BLAME_SYNCHRONET) || defined(_THREAD_SUID_BROKEN)
+#if defined(DONT_BLAME_SYNCHRONET)
 	if(!force)
 		return(do_seteuid(TRUE));
 #endif
 
+#if defined(_THREAD_SUID_BROKEN)
+	if(thread_suid_broken && (!force))
+		return(do_seteuid(TRUE));
+#endif
+
 	if(!setid_mutex_initialized) {
 		pthread_mutex_init(&setid_mutex,NULL);
 		setid_mutex_initialized=TRUE;
@@ -383,6 +384,13 @@ static void thread_up(void* p, BOOL up, BOOL setuid)
    	static pthread_mutex_t mutex;
 	static BOOL mutex_initialized;
 
+#ifdef _THREAD_SUID_BROKEN
+	if(thread_suid_broken && up && setuid) {
+		do_seteuid(FALSE);
+		do_setuid(FALSE);
+	}
+#endif
+
 	if(!mutex_initialized) {
 		pthread_mutex_init(&mutex,NULL);
 		mutex_initialized=TRUE;
@@ -390,13 +398,6 @@ static void thread_up(void* p, BOOL up, BOOL setuid)
 
 	pthread_mutex_lock(&mutex);
 
-#ifdef _THREAD_SUID_BROKEN
-	if(up && setuid) {
-		do_seteuid(FALSE);
-		do_setuid(FALSE);
-	}
-#endif
-
 	if(up)
 	    thread_count++;
     else if(thread_count>0)
@@ -489,8 +490,10 @@ static void bbs_started(void* p)
 	bbs_running=TRUE;
 	bbs_stopped=FALSE;
 	#ifdef _THREAD_SUID_BROKEN
-	    do_seteuid(FALSE);
-	    do_setuid(FALSE);
+		if(thread_suid_broken) {
+	    	do_seteuid(FALSE);
+	    	do_setuid(FALSE);
+		}
 	#endif
 }
 
@@ -549,8 +552,10 @@ static void ftp_started(void* p)
 	ftp_running=TRUE;
 	ftp_stopped=FALSE;
 	#ifdef _THREAD_SUID_BROKEN
-	    do_seteuid(FALSE);
-	    do_setuid(FALSE);
+		if(thread_suid_broken) {
+	    	do_seteuid(FALSE);
+	    	do_setuid(FALSE);
+		}
 	#endif
 }
 
@@ -605,8 +610,10 @@ static void mail_started(void* p)
 	mail_running=TRUE;
 	mail_stopped=FALSE;
 	#ifdef _THREAD_SUID_BROKEN
-	    do_seteuid(FALSE);
-	    do_setuid(FALSE);
+		if(thread_suid_broken) {
+	    	do_seteuid(FALSE);
+	    	do_setuid(FALSE);
+		}
 	#endif
 }
 
@@ -661,8 +668,10 @@ static void services_started(void* p)
 	services_running=TRUE;
 	services_stopped=FALSE;
 	#ifdef _THREAD_SUID_BROKEN
-	    do_seteuid(FALSE);
-	    do_setuid(FALSE);
+		if(thread_suid_broken) {
+	    	do_seteuid(FALSE);
+	    	do_setuid(FALSE);
+		}
 	#endif
 }
 
@@ -757,8 +766,10 @@ static void web_started(void* p)
 	web_running=TRUE;
 	web_stopped=FALSE;
 	#ifdef _THREAD_SUID_BROKEN
-	    do_seteuid(FALSE);
-	    do_setuid(FALSE);
+		if(thread_suid_broken)
+	    	do_seteuid(FALSE);
+	    	do_setuid(FALSE);
+		}
 	#endif
 }
 
@@ -1021,6 +1032,9 @@ int main(int argc, char** argv)
 	struct group*	gr_entry;
 	sigset_t		sigs;
 #endif
+#ifdef _THREAD_SUID_BROKEN
+	size_t	conflen;
+#endif
 
 #ifdef __QNX__
 	setlocale( LC_ALL, "C-TRADITIONAL" );
@@ -1593,6 +1607,17 @@ int main(int argc, char** argv)
 	do_seteuid(TRUE);
 #endif
 
+#ifdef _THREAD_SUID_BROKEN
+	/* check if we're using NPTL */
+	conflen=confstr (_CS_GNU_LIBPTHREAD_VERSION, NULL, 0);
+	if (conflen > 0) {
+		char *buf = alloca (conflen);
+		confstr (_CS_GNU_LIBPTHREAD_VERSION, buf, conflen);
+		if (strstr (buf, "NPTL"))
+			thread_suid_broken=FALSE;
+	}
+#endif
+
 	/* Install Ctrl-C/Break signal handler here */
 #if defined(_WIN32)
 	SetConsoleCtrlHandler(ControlHandler, TRUE /* Add */);
@@ -1613,21 +1638,23 @@ int main(int argc, char** argv)
 	if(new_uid_name[0]!=0) {        /*  check the user arg, if we have uid 0 */
 		/* Can't recycle servers (re-bind ports) as non-root user */
 		/* If DONT_BLAME_SYNCHRONET is set, keeps root credentials laying around */
-#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))
-			bbs_startup.options|=BBS_OPT_NO_RECYCLE;
-		if(ftp_startup.port < IPPORT_RESERVED)
-			ftp_startup.options|=FTP_OPT_NO_RECYCLE;
-		if(web_startup.port < IPPORT_RESERVED)
-			web_startup.options|=BBS_OPT_NO_RECYCLE;
-		if((mail_startup.options & MAIL_OPT_ALLOW_POP3
-			&& mail_startup.pop3_port < IPPORT_RESERVED)
-			|| mail_startup.smtp_port < IPPORT_RESERVED)
-			mail_startup.options|=MAIL_OPT_NO_RECYCLE;
-		/* Perhaps a BBS_OPT_NO_RECYCLE_LOW option? */
-		services_startup.options|=BBS_OPT_NO_RECYCLE;
+#if !defined(DONT_BLAME_SYNCHRONET)
+		if(!thread_suid_broken) {
+ 			if(bbs_startup.telnet_port < IPPORT_RESERVED
+				|| (bbs_startup.options & BBS_OPT_ALLOW_RLOGIN
+					&& bbs_startup.rlogin_port < IPPORT_RESERVED))
+				bbs_startup.options|=BBS_OPT_NO_RECYCLE;
+			if(ftp_startup.port < IPPORT_RESERVED)
+				ftp_startup.options|=FTP_OPT_NO_RECYCLE;
+			if(web_startup.port < IPPORT_RESERVED)
+				web_startup.options|=BBS_OPT_NO_RECYCLE;
+			if((mail_startup.options & MAIL_OPT_ALLOW_POP3
+				&& mail_startup.pop3_port < IPPORT_RESERVED)
+				|| mail_startup.smtp_port < IPPORT_RESERVED)
+				mail_startup.options|=MAIL_OPT_NO_RECYCLE;
+			/* Perhaps a BBS_OPT_NO_RECYCLE_LOW option? */
+			services_startup.options|=BBS_OPT_NO_RECYCLE;
+		}
 #endif
 	}
 #endif
diff --git a/src/sbbs3/sbbscon.h b/src/sbbs3/sbbscon.h
new file mode 100644
index 0000000000..090111bd79
--- /dev/null
+++ b/src/sbbs3/sbbscon.h
@@ -0,0 +1,10 @@
+#ifndef _SBBSCON_H_
+#define _SBBSCON_H_
+
+#ifdef _THREAD_SUID_BROKEN
+extern int	thread_suid_broken;			/* NPTL is no longer broken */
+#else
+#define thread_suid_broken FALSE
+#endif
+
+#endif
diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c
index 399ca9f0bd..e2228f6980 100644
--- a/src/sbbs3/services.c
+++ b/src/sbbs3/services.c
@@ -69,6 +69,7 @@
 #include "services.h"
 #include "ident.h"	/* identify() */
 #include "sbbs_ini.h"
+#include "sbbscon.h"        /* thread_suid_broken */
 
 /* Constants */
 
@@ -1642,7 +1643,8 @@ void DLLCALL services_thread(void* arg)
 	}
 
 #ifdef _THREAD_SUID_BROKEN
-	startup->seteuid(TRUE);
+	if(thread_suid_broken)
+		startup->seteuid(TRUE);
 #endif
 
 	/* Setup intelligent defaults */
diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c
index 85b66026d5..74e1ebba30 100644
--- a/src/sbbs3/websrvr.c
+++ b/src/sbbs3/websrvr.c
@@ -65,6 +65,7 @@
 #include "semwrap.h"
 #include "websrvr.h"
 #include "base64.h"
+#include "sbbscon.h"        /* thread_suid_broken */
 
 static const char*	server_name="Synchronet Web Server";
 static const char*	newline="\r\n";
@@ -4719,7 +4720,8 @@ void DLLCALL web_server(void* arg)
 	}
 
 #ifdef _THREAD_SUID_BROKEN
-	startup->seteuid(TRUE);
+	if(thread_suid_broken)
+		startup->seteuid(TRUE);
 #endif
 
 	/* Setup intelligent defaults */
-- 
GitLab