diff -ur src.orig/game.c src/game.c --- src.orig/game.c 2003-09-17 13:55:17.000000000 -0400 +++ src/game.c 2003-09-17 23:01:10.644146104 -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.bindip[USERNAMELEN-1]=0; + error=0; + } + if (!strcasecmp(id_tag,"dropgroup")) + { + strncpy(game.group, id_value, USERNAMELEN-1); game.bindip[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 -ur src.orig/main.c src/main.c --- src.orig/main.c 2003-09-17 13:55:17.000000000 -0400 +++ src/main.c 2003-09-17 23:17:43.858154624 -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 -ur src.orig/main.h src/main.h --- src.orig/main.h 2003-09-17 13:55:17.000000000 -0400 +++ src/main.h 2003-09-17 23:00:12.054053152 -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; }; Only in src: makefile Files src.orig/tetrix and src/tetrix differ --- bin/game.conf.orig 2003-09-17 23:19:02.703168360 -0400 +++ bin/game.conf 2003-09-17 23:18:58.062873792 -0400 @@ -13,6 +13,11 @@ # 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