diff -ru tetrinetx-1.13.16+qirc-1.40c.orig/bin/game.conf tetrinetx-1.13.16+qirc-1.40c/bin/game.conf --- tetrinetx-1.13.16+qirc-1.40c.orig/bin/game.conf 1999-09-06 08:14:38.000000000 -0400 +++ tetrinetx-1.13.16+qirc-1.40c/bin/game.conf 2009-06-15 00:17:22.000000000 -0400 @@ -8,11 +8,16 @@ # Any text after a # is ignored, and can be used as comments. # pidfile [game.pid] - Where should the Process ID be written -pidfile=game.pid +pidfile=/var/run/tetrix.pid # bindip [0.0.0.0] - What IP should server be bound to (0.0.0.0 means all) bindip=0.0.0.0 +# username/group to switch UID/GID to +droproot=1 +dropuser=games +dropgroup=games + # maxchannels [1] - How many channels should be available on server maxchannels=8 diff -ru tetrinetx-1.13.16+qirc-1.40c.orig/src/config.h tetrinetx-1.13.16+qirc-1.40c/src/config.h --- tetrinetx-1.13.16+qirc-1.40c.orig/src/config.h 2001-04-23 22:31:29.000000000 -0400 +++ tetrinetx-1.13.16+qirc-1.40c/src/config.h 2009-06-15 00:17:22.000000000 -0400 @@ -7,16 +7,16 @@ */ /* Location of the various external files */ -#define FILE_MOTD "game.motd" /* Message of the Day File */ -#define FILE_PMOTD "game.pmotd" /* Playback motd */ -#define FILE_CONF "game.conf" /* Game configuration File */ -#define FILE_WINLIST "game.winlist" /* Winlist storage file */ -#define FILE_WINLIST2 "game.winlist2" /* Winlist storage file */ -#define FILE_WINLIST3 "game.winlist3" /* Winlist storage file */ +#define FILE_MOTD "GENTOO_CONFDIR/game.motd" /* Message of the Day File */ +#define FILE_PMOTD "GENTOO_CONFDIR/game.pmotd" /* Playback motd */ +#define FILE_CONF "GENTOO_CONFDIR/game.conf" /* Game configuration File */ +#define FILE_WINLIST "GENTOO_STATEDIR/game.winlist" /* Winlist storage file */ +#define FILE_WINLIST2 "GENTOO_STATEDIR/game.winlist2" /* Winlist storage file */ +#define FILE_WINLIST3 "GENTOO_STATEDIR/game.winlist3" /* Winlist storage file */ -#define FILE_BAN "game.ban" /* List of Banned IP's */ -#define FILE_BAN_COMPROMISE "game.ban.compromise" /* List of Banned IP's */ -#define FILE_ALLOW "game.allow" /* List of allow IP's */ -#define FILE_LOG "game.log" /* Logfile */ -#define FILE_PID "game.pid" /* Default PID */ -#define FILE_SECURE "game.secure" /* Security file */ +#define FILE_BAN "GENTOO_CONFDIR/game.ban" /* List of Banned IP's */ +#define FILE_BAN_COMPROMISE "GENTOO_CONFDIR/game.ban.compromise" /* List of Banned IP's */ +#define FILE_ALLOW "GENTOO_CONFDIR/game.allow" /* List of allow IP's */ +#define FILE_LOG "GENTOO_LOGDIR/tetrix.log" /* Logfile */ +#define FILE_PID "/var/run/tetrix.pid" /* Default PID */ +#define FILE_SECURE "GENTOO_CONFDIR/game.secure" /* Security file */ diff -ru tetrinetx-1.13.16+qirc-1.40c.orig/src/game.c tetrinetx-1.13.16+qirc-1.40c/src/game.c --- tetrinetx-1.13.16+qirc-1.40c.orig/src/game.c 2001-04-23 22:31:29.000000000 -0400 +++ tetrinetx-1.13.16+qirc-1.40c/src/game.c 2009-06-15 00:17:22.000000000 -0400 @@ -2,6 +2,8 @@ game.c */ +#include +#include /* securitywrite() */ /* Writes out the security structure into a text format game.secure file */ @@ -149,6 +151,11 @@ fprintf(file_out,"# bindip [0.0.0.0] - What IP should server be bound to (0.0.0.0 means all)\n"); fprintf(file_out,"bindip=%s\n", game.bindip); fprintf(file_out,"\n"); + fprintf(file_out,"# username/group to switch UID/GID to"); + fprintf(file_out,"droproot=%d\n", game.droproot); + fprintf(file_out,"dropuser=%s\n", game.user); + fprintf(file_out,"dropgroup=%s\n", game.group); + fprintf(file_out,"\n"); fprintf(file_out,"# maxchannels [1] - How many channels should be available on server\n"); fprintf(file_out,"maxchannels=%d\n", game.maxchannels); fprintf(file_out,"\n"); @@ -466,6 +473,21 @@ strncpy(game.bindip, id_value, IPLEN-1); game.bindip[IPLEN-1]=0; error=0; } + if (!strcasecmp(id_tag,"droproot")) + { + game.droproot=atoi(id_value); + error=0; + } + if (!strcasecmp(id_tag,"dropuser")) + { + strncpy(game.user, id_value, USERNAMELEN-1); game.user[USERNAMELEN-1]=0; + error=0; + } + if (!strcasecmp(id_tag,"dropgroup")) + { + strncpy(game.group, id_value, USERNAMELEN-1); game.group[USERNAMELEN-1]=0; + error=0; + } if (!strcasecmp(id_tag,"maxchannels")) @@ -854,6 +876,22 @@ } fclose(file_in); lvprintf(3,"Read game configuration from %s\n", FILE_CONF); + if (game.droproot) { + struct passwd *vpw; + struct group *vgr; + game.droproot = 0; + vpw = getpwnam(game.user); + if (vpw) { + game.userid = vpw->pw_uid; + vgr = getgrnam(game.group); + if (vgr) { + game.groupid = vgr->gr_gid; + game.droproot = 1; + } + } + if (!game.droproot) + lvprintf(2,"Drop root was requested but the specified user/group were invalid!\n"); + } return(0); } diff -ru tetrinetx-1.13.16+qirc-1.40c.orig/src/main.c tetrinetx-1.13.16+qirc-1.40c/src/main.c --- tetrinetx-1.13.16+qirc-1.40c.orig/src/main.c 2002-07-08 23:53:49.000000000 -0400 +++ tetrinetx-1.13.16+qirc-1.40c/src/main.c 2009-06-15 00:17:22.000000000 -0400 @@ -4878,10 +4878,13 @@ long int timeticks, otimeticks; /* Initialise */ + xx = (argc == 2 && !strcmp(argv[1],"-q")); + if (!xx) printf("Loading Tetrix. Please wait...\n"); init_main(); init_resolver(); init_game(); + if (!xx) printf("Initializing security/ban list...\n"); init_security(); init_banlist(banlist, MAXBAN); @@ -4890,6 +4893,7 @@ read_banlist(FILE_BAN_COMPROMISE, combanlist, MAXBAN); init_allowlist(); read_allowlist(); + if (!xx) printf("Initializing winlist...\n"); init_winlist(winlist, MAXWINLIST); init_winlist(winlist2, MAXWINLIST); @@ -4898,16 +4902,21 @@ readwinlist(FILE_WINLIST2, winlist2, MAXWINLIST); readwinlist(FILE_WINLIST3, winlist3, MAXWINLIST); sleep(1); + if (!xx) printf("Initialize network connection...\n"); init_net(); + if (!xx) printf("Gameplay ... "); usleep(300000); init_telnet_port(); + if (!xx) printf("Spectator ... "); usleep(300000); init_playback_port(); + if (!xx) printf("Ircadm ... \n"); init_query_port(); + if (!xx) printf("Completed!!!\n"); if (securityread() < 0) @@ -4933,6 +4942,14 @@ /* Write out PID */ writepid(); + + /* drop root */ + if (game.droproot) { + if (setgid(game.groupid)) + perror("Could not setgid"); + if (setuid(game.userid)) + perror("Could not setuid"); + } /* Reset time */ timeticks = time(NULL); diff -ru tetrinetx-1.13.16+qirc-1.40c.orig/src/main.h tetrinetx-1.13.16+qirc-1.40c/src/main.h --- tetrinetx-1.13.16+qirc-1.40c.orig/src/main.h 2001-04-29 15:00:28.000000000 -0400 +++ tetrinetx-1.13.16+qirc-1.40c/src/main.h 2009-06-15 00:17:22.000000000 -0400 @@ -48,6 +48,7 @@ /* Defines */ #define TETVERSION "1.13" /* What Tetrinet version we are for */ #define SERVERBUILD "16+qirc-1.40b" /* What build we are at */ +#define USERNAMELEN 30 /* Maximum length of username/group for droproot */ #define NICKLEN 30 /* Maximum length of Nickname */ #define VERLEN 10 /* Maximum length of Tetrinet version */ #define UHOSTLEN 121 /* Maximum length of Hostname */ @@ -235,6 +236,12 @@ int verbose; /* Verbosity */ char pidfile[PIDFILELEN+1]; + + int droproot; /* should we drop root when starting ? */ + char user[USERNAMELEN+1]; + uid_t userid; + char group[USERNAMELEN+1]; + gid_t groupid; }; diff -ru tetrinetx-1.13.16+qirc-1.40c.orig/src/net.c tetrinetx-1.13.16+qirc-1.40c/src/net.c --- tetrinetx-1.13.16+qirc-1.40c.orig/src/net.c 2001-04-23 22:31:29.000000000 -0400 +++ tetrinetx-1.13.16+qirc-1.40c/src/net.c 2009-06-15 00:19:16.000000000 -0400 @@ -57,21 +57,21 @@ p=getenv("HOSTNAME"); if (p!=NULL) { strncpy(s,p, UHOSTLEN); s[UHOSTLEN] = 0; - if (strchr(s,'.')!=NULL) return; + if (*s) return; } gethostname(s,80); - if (strchr(s,'.')!=NULL) return; + if (*s) return; hp=gethostbyname(s); if (hp==NULL) fatal("Hostname self-lookup failed.",0); strncpy(s,hp->h_name, UHOSTLEN); s[UHOSTLEN] = 0; - if (strchr(s,'.')!=NULL) return; + if (*s) return; if (hp->h_aliases[0] == NULL) fatal("Can't determine your hostname!",0); strncpy(s,hp->h_aliases[0], UHOSTLEN); s[UHOSTLEN] = 0; - if (strchr(s,'.')==NULL) + if (!*s) fatal("Can't determine your hostname!",0); }