Commit a2b117c8 authored by rswindell's avatar rswindell
Browse files

Clean-up some of this USE_LINUX_CAPS patch, but honestly, I think it's

time for it to go away. Using 'sudo setcap sbbs' during build seems like the
better, more supported solution.
parent 82db789d
......@@ -40,6 +40,7 @@
/* ANSI headers */
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
......@@ -304,13 +305,13 @@ static BOOL setid_mutex_initialized=0;
/**********************************************************
* Change uid of the calling process to the user if specified
* **********************************************************/
static BOOL do_seteuid(BOOL to_new)
static BOOL do_seteuid(BOOL to_new)
{
BOOL result=FALSE;
if(capabilities_set)
return(TRUE); /* do nothing */
if(new_uid_name[0]==0) /* not set? */
return(TRUE); /* do nothing */
......@@ -392,7 +393,7 @@ BOOL do_setuid(BOOL force)
lputs(LOG_ERR,"!initgroups FAILED");
lputs(LOG_ERR,strerror(errno));
result=FALSE;
}
}
if(setreuid(new_uid,new_uid))
{
lputs(LOG_ERR,"!setuid FAILED");
......@@ -409,32 +410,33 @@ BOOL do_setuid(BOOL force)
return(result);
}
int change_user(void)
bool change_user(void)
{
if(!do_setuid(FALSE)) {
/* actually try to change the uid of this process */
lputs(LOG_ERR,"!Setting new user_id failed! (Does the user exist?)");
return(-1);
} else {
struct passwd *pwent;
pwent=getpwnam(new_uid_name);
if(pwent != NULL) {
static char uenv[128];
static char henv[MAX_PATH+6];
sprintf(uenv,"USER=%s",pwent->pw_name);
putenv(uenv);
sprintf(henv,"HOME=%s",pwent->pw_dir);
putenv(henv);
}
if(new_gid_name[0]) {
static char genv[128];
sprintf(genv,"GROUP=%s",new_gid_name);
putenv(genv);
}
lprintf(LOG_INFO,"Successfully changed user_id to %s", new_uid_name);
}
return(0);
lputs(LOG_ERR,"!Setting new user-id failed! (Does the user exist?)");
return false;
}
struct passwd *pwent;
pwent=getpwnam(new_uid_name);
if(pwent == NULL)
lprintf(LOG_WARNING, "No password name for: %s", new_uid_name);
else {
static char uenv[128];
static char henv[MAX_PATH+6];
sprintf(uenv,"USER=%s",pwent->pw_name);
putenv(uenv);
sprintf(henv,"HOME=%s",pwent->pw_dir);
putenv(henv);
}
if(new_gid_name[0]) {
static char genv[128];
sprintf(genv,"GROUP=%s",new_gid_name);
putenv(genv);
}
lprintf(LOG_INFO,"Successfully changed user-id to %s", new_uid_name);
return true;
}
#ifdef USE_LINUX_CAPS
......@@ -446,18 +448,20 @@ void whoami(void)
{
uid_t a, b, c;
getresuid(&a, &b, &c);
lprintf(LOG_DEBUG,"Current uids: ruid - %d, euid - %d, suid - %d", a, b, c);
lprintf(LOG_DEBUG,"Current usr ids: ruid - %d, euid - %d, suid - %d", a, b, c);
getresgid(&a, &b, &c);
lprintf(LOG_DEBUG,"Current gids: rgid - %d, egid - %d, sgid - %d", a, b, c);
lprintf(LOG_DEBUG,"Current grp ids: rgid - %d, egid - %d, sgid - %d", a, b, c);
}
void list_caps(void)
bool list_caps(void)
{
cap_t caps = cap_get_proc();
if(caps == NULL)
return false;
ssize_t y = 0;
lprintf(LOG_DEBUG, "The process %d was given capabilities %s", (int) getpid(), cap_to_text(caps, &y));
fflush(0);
cap_free(caps);
return true;
}
static int linux_keepcaps(void)
......@@ -476,11 +480,11 @@ static int linux_keepcaps(void)
return(0);
}
static int linux_setcaps(unsigned int caps)
static bool linux_setcaps(unsigned int caps)
{
struct __user_cap_header_struct caphead;
struct __user_cap_data_struct cap;
memset(&caphead, 0, sizeof(caphead));
caphead.version = _LINUX_CAPABILITY_VERSION;
caphead.pid = 0;
......@@ -488,10 +492,16 @@ static int linux_setcaps(unsigned int caps)
cap.effective = caps;
cap.permitted = caps;
cap.inheritable = 0;
return(syscall(SYS_capset, &caphead, &cap));
int ret = syscall(SYS_capset, &caphead, &cap);
if (ret == 0)
return true;
lprintf(LOG_ERR, "linux_setcaps(0x%x) failed (errno %d: %s)"
, caps, errno, strerror(errno));
return false;
}
static int linux_initialprivs(void)
static bool linux_initialprivs(void)
{
unsigned int caps;
......@@ -502,10 +512,10 @@ static int linux_initialprivs(void)
caps |= (1 << CAP_DAC_READ_SEARCH);
caps |= (1 << CAP_SYS_RESOURCE);
printf("Setting initial privileges\n");
return(linux_setcaps(caps));
return linux_setcaps(caps);
}
static int linux_minprivs(void)
static bool linux_minprivs(void)
{
unsigned int caps;
......@@ -513,7 +523,7 @@ static int linux_minprivs(void)
caps |= (1 << CAP_NET_BIND_SERVICE);
caps |= (1 << CAP_SYS_RESOURCE);
printf("Setting minimum privileges\n");
return(linux_setcaps(caps));
return linux_setcaps(caps);
}
/**********************************************************
* End capabilities section
......@@ -537,7 +547,7 @@ static BOOL winsock_startup(void)
return(FALSE);
}
static BOOL winsock_cleanup(void)
static BOOL winsock_cleanup(void)
{
if(WSACleanup()==0)
return(TRUE);
......@@ -548,7 +558,7 @@ static BOOL winsock_cleanup(void)
#else /* No WINSOCK */
#define winsock_startup() (TRUE)
#define winsock_startup() (TRUE)
#define winsock_cleanup() (TRUE)
#endif
......@@ -702,7 +712,7 @@ static int bbs_lputs(void* p, int level, const char *str)
sprintf(logline,"%sterm %.*s",tstr,(int)sizeof(logline)-32,str);
truncsp(logline);
lputs(level,logline);
return(strlen(logline)+1);
}
......@@ -767,7 +777,7 @@ static int stat_lputs(void* p, int level, const char *str)
sprintf(logline,"%sstat %.*s",tstr,(int)sizeof(logline)-32,str);
truncsp(logline);
lputs(level,logline);
return(strlen(logline)+1);
}
......@@ -834,7 +844,7 @@ static int ftp_lputs(void* p, int level, const char *str)
sprintf(logline,"%sftp %.*s",tstr,(int)sizeof(logline)-32,str);
truncsp(logline);
lputs(level,logline);
return(strlen(logline)+1);
}
......@@ -900,7 +910,7 @@ static int mail_lputs(void* p, int level, const char *str)
sprintf(logline,"%smail %.*s",tstr,(int)sizeof(logline)-32,str);
truncsp(logline);
lputs(level,logline);
return(strlen(logline)+1);
}
......@@ -966,7 +976,7 @@ static int services_lputs(void* p, int level, const char *str)
sprintf(logline,"%ssrvc %.*s",tstr,(int)sizeof(logline)-32,str);
truncsp(logline);
lputs(level,logline);
return(strlen(logline)+1);
}
......@@ -1032,7 +1042,7 @@ static int event_lputs(void* p, int level, const char *str)
sprintf(logline,"%sevnt %.*s",tstr,(int)sizeof(logline)-32,str);
truncsp(logline);
lputs(level,logline);
return(strlen(logline)+1);
}
......@@ -1074,7 +1084,7 @@ static int web_lputs(void* p, int level, const char *str)
sprintf(logline,"%sweb %.*s",tstr,(int)sizeof(logline)-32,str);
truncsp(logline);
lputs(level,logline);
return(strlen(logline)+1);
}
......@@ -1152,7 +1162,7 @@ static void read_startup_ini(BOOL recycle
FILE* fp=NULL;
/* Read .ini file here */
if(ini_file[0]!=0) {
if(ini_file[0]!=0) {
if((fp=fopen(ini_file,"r"))==NULL) {
lprintf(LOG_ERR,"!ERROR %d (%s) opening %s",errno,strerror(errno),ini_file);
} else {
......@@ -1163,13 +1173,13 @@ static void read_startup_ini(BOOL recycle
lputs(LOG_WARNING,"Using default initialization values");
/* We call this function to set defaults, even if there's no .ini file */
sbbs_read_ini(fp,
sbbs_read_ini(fp,
ini_file,
NULL, /* global_startup */
&run_bbs, bbs,
&run_ftp, ftp,
&run_ftp, ftp,
&run_web, web,
&run_mail, mail,
&run_mail, mail,
&run_services, services);
/* read/default any sbbscon-specific .ini keys here */
......@@ -1624,7 +1634,7 @@ int main(int argc, char** argv)
#endif
case 'T': /* Terminal server settings */
switch(toupper(*(arg++))) {
case '-':
case '-':
run_bbs=FALSE;
break;
case 'D': /* debug output */
......@@ -1666,7 +1676,7 @@ int main(int argc, char** argv)
break;
case 'F': /* FTP */
switch(toupper(*(arg++))) {
case '-':
case '-':
run_ftp=FALSE;
break;
case 'P':
......@@ -1751,7 +1761,7 @@ int main(int argc, char** argv)
break;
case 'W': /* Web server */
switch(toupper(*(arg++))) {
case '-':
case '-':
run_web=FALSE;
break;
case 'P':
......@@ -1816,7 +1826,7 @@ int main(int argc, char** argv)
{
SAFECOPY(new_uid_name,arg);
}
#endif
#endif
break;
case 'G': /* groupname */
#ifdef __unix__
......@@ -1824,7 +1834,7 @@ int main(int argc, char** argv)
{
SAFECOPY(new_gid_name,arg);
}
#endif
#endif
break;
default:
show_usage(argv[0]);
......@@ -1961,7 +1971,7 @@ int main(int argc, char** argv)
old_gid = getgid();
if((gr_entry=getgrnam(new_gid_name))!=0)
new_gid=gr_entry->gr_gid;
do_seteuid(TRUE);
#endif
......@@ -1986,25 +1996,17 @@ int main(int argc, char** argv)
#ifdef USE_LINUX_CAPS /* set capabilities and change user before we start threads */
whoami();
list_caps();
if(linux_initialprivs() < 0) {
lputs(LOG_ERR,"linux_initialprivs() FAILED");
/* assuming if we pass here the module is loaded so no further module messages are needed */
lputs(LOG_ERR,"Verify the following kernel module is loaded [See insmod(8)]: capability");
lputs(LOG_ERR,strerror(errno));
}
else {
list_caps();
if(list_caps() && linux_initialprivs()) {
if(linux_keepcaps() < 0) {
lputs(LOG_ERR,"linux_keepcaps() FAILED");
lputs(LOG_ERR,strerror(errno));
}
else {
if(change_user() < 0) {
if(!change_user()) {
lputs(LOG_ERR,"change_user() FAILED");
}
else {
if(linux_minprivs() < 0) {
if(!linux_minprivs()) {
lputs(LOG_ERR,"linux_minprivs() FAILED");
lputs(LOG_ERR,strerror(errno));
}
......@@ -2017,7 +2019,7 @@ int main(int argc, char** argv)
whoami();
list_caps();
#endif /* USE_LINUX_CAPS */
/* Set up blocked signals */
sigemptyset(&sigs);
sigaddset(&sigs,SIGINT);
......@@ -2068,7 +2070,7 @@ int main(int argc, char** argv)
}
#endif /* !defined(DONT_BLAME_SYNCHRONET) */
}
} /* end if(!capabilities_set) */
} /* end if(!capabilities_set) */
_beginthread(status_thread, 0, &status_startup);
#endif /* defined(__unix__) */
......@@ -2092,20 +2094,21 @@ int main(int argc, char** argv)
#endif
#ifdef __unix__
if(getuid() && !capabilities_set) { /* are we running as a normal user? */
uid_t uid = getuid();
if(uid != 0 && !capabilities_set) { /* are we running as a normal user? */
lprintf(LOG_WARNING
,"!Started as non-root user. Cannot bind() to ports below %u.", IPPORT_RESERVED);
,"!Started as non-root user (id %d): May fail to bind TCP/UDP ports below %u", uid, IPPORT_RESERVED);
}
else if(new_uid_name[0]==0) /* check the user arg, if we have uid 0 */
lputs(LOG_WARNING,"WARNING: No user account specified, running as root.");
else
lputs(LOG_WARNING,"WARNING: No user account specified, running as root!");
else
{
lputs(LOG_INFO,"Waiting for child threads to bind ports...");
while((run_bbs && !(bbs_running || bbs_stopped))
|| (run_ftp && !(ftp_running || ftp_stopped))
|| (run_web && !(web_running || web_stopped))
|| (run_mail && !(mail_running || mail_stopped))
while((run_bbs && !(bbs_running || bbs_stopped))
|| (run_ftp && !(ftp_running || ftp_stopped))
|| (run_web && !(web_running || web_stopped))
|| (run_mail && !(mail_running || mail_stopped))
|| (run_services && !(services_running || services_stopped))) {
mswait(1000);
if(run_bbs && !(bbs_running || bbs_stopped))
......@@ -2121,7 +2124,7 @@ int main(int argc, char** argv)
}
if(!capabilities_set) { /* if using capabilities user should already have changed */
if(change_user() < 0)
if(!change_user())
lputs(LOG_ERR,"change_user FAILED");
}
}
......@@ -2293,7 +2296,7 @@ int main(int argc, char** argv)
ftp_startup.recycle_now=TRUE;
web_startup.recycle_now=TRUE;
mail_startup.recycle_now=TRUE;
services_startup.recycle_now=TRUE;
services_startup.recycle_now=TRUE;
}
break;
case 'C':
......@@ -2391,13 +2394,13 @@ int main(int argc, char** argv)
printf("t = terminate servers (immediately)\n");
printf("! = execute external command\n");
printf("? = print this help information\n");
#if 0 /* to do */
#if 0 /* to do */
printf("c# = chat with node #\n");
printf("s# = spy on node #\n");
#endif
break;
default:
break;
break;
}
lputs(LOG_INFO,""); /* redisplay prompt */
}
......
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