Michael Thomas cc5a4cd
diff -Naur --exclude '*.swp' bsd-games-2.17/tetris/scores.c bsd-games-2.17.new/tetris/scores.c
Michael Thomas cc5a4cd
--- bsd-games-2.17/tetris/scores.c	2006-04-22 20:46:56.000000000 -0700
Michael Thomas cc5a4cd
+++ bsd-games-2.17.new/tetris/scores.c	2006-04-22 22:02:45.000000000 -0700
Michael Thomas cc5a4cd
@@ -41,6 +41,7 @@
Michael Thomas cc5a4cd
  *
Michael Thomas cc5a4cd
  * Major whacks since then.
Michael Thomas cc5a4cd
  */
Michael Thomas cc5a4cd
+#define _GNU_SOURCE /* this must be done before the first include of unistd.h */
Michael Thomas cc5a4cd
 #include <err.h>
Michael Thomas cc5a4cd
 #include <errno.h>
Michael Thomas cc5a4cd
 #include <fcntl.h>
Michael Thomas cc5a4cd
@@ -77,85 +78,88 @@
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
 static int checkscores(struct highscore *, int);
Michael Thomas cc5a4cd
 static int cmpscores(const void *, const void *);
Michael Thomas cc5a4cd
-static void getscores(FILE **);
Michael Thomas cc5a4cd
+static void getscores(FILE *);
Michael Thomas cc5a4cd
 static void printem(int, int, struct highscore *, int, const char *);
Michael Thomas cc5a4cd
 static char *thisuser(void);
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
 /*
Michael Thomas cc5a4cd
- * Read the score file.  Can be called from savescore (before showscores)
Michael Thomas cc5a4cd
- * or showscores (if savescore will not be called).  If the given pointer
Michael Thomas cc5a4cd
- * is not NULL, sets *fpp to an open file pointer that corresponds to a
Michael Thomas cc5a4cd
- * read/write score file that is locked with LOCK_EX.  Otherwise, the
Michael Thomas cc5a4cd
- * file is locked with LOCK_SH for the read and closed before return.
Michael Thomas cc5a4cd
- *
Michael Thomas cc5a4cd
- * Note, we assume closing the stdio file releases the lock.
Michael Thomas cc5a4cd
+ * Read the score file from a previously opened file pointer.  If the file
Michael Thomas cc5a4cd
+ * pointer is null, then read the scoreboard from a known location.  Otherwise,
Michael Thomas cc5a4cd
+ * the FILE pointer is rewound, read, and left open to be read again later.
Michael Thomas cc5a4cd
  */
Michael Thomas cc5a4cd
 static void
Michael Thomas cc5a4cd
-getscores(fpp)
Michael Thomas cc5a4cd
-	FILE **fpp;
Michael Thomas cc5a4cd
+getscores(fp)
Michael Thomas cc5a4cd
+    FILE *fp;
Michael Thomas cc5a4cd
 {
Michael Thomas cc5a4cd
-	int sd, mint, lck;
Michael Thomas cc5a4cd
-	mode_t mask;
Michael Thomas cc5a4cd
-	const char *mstr, *human;
Michael Thomas cc5a4cd
-	FILE *sf;
Michael Thomas cc5a4cd
-
Michael Thomas cc5a4cd
-	if (fpp != NULL) {
Michael Thomas cc5a4cd
-		mint = O_RDWR | O_CREAT;
Michael Thomas cc5a4cd
-		mstr = "r+";
Michael Thomas cc5a4cd
-		human = "read/write";
Michael Thomas cc5a4cd
-		lck = LOCK_EX;
Michael Thomas cc5a4cd
-	} else {
Michael Thomas cc5a4cd
-		mint = O_RDONLY;
Michael Thomas cc5a4cd
-		mstr = "r";
Michael Thomas cc5a4cd
-		human = "reading";
Michael Thomas cc5a4cd
-		lck = LOCK_SH;
Michael Thomas cc5a4cd
-	}
Michael Thomas cc5a4cd
-	setegid(egid);
Michael Thomas cc5a4cd
-	mask = umask(S_IWOTH);
Michael Thomas cc5a4cd
-	sd = open(_PATH_SCOREFILE, mint, 0666);
Michael Thomas cc5a4cd
-	(void)umask(mask);
Michael Thomas cc5a4cd
-	if (sd < 0) {
Michael Thomas cc5a4cd
-		if (fpp == NULL) {
Michael Thomas cc5a4cd
-			nscores = 0;
Michael Thomas cc5a4cd
-			setegid(gid);
Michael Thomas cc5a4cd
-			return;
Michael Thomas cc5a4cd
-		}
Michael Thomas cc5a4cd
-		err(1, "cannot open %s for %s", _PATH_SCOREFILE, human);
Michael Thomas cc5a4cd
-	}
Michael Thomas cc5a4cd
-	if ((sf = fdopen(sd, mstr)) == NULL) {
Michael Thomas cc5a4cd
-		err(1, "cannot fdopen %s for %s", _PATH_SCOREFILE, human);
Michael Thomas cc5a4cd
-	}
Michael Thomas cc5a4cd
-	setegid(gid);
Michael Thomas cc5a4cd
+	int sd = -1;
Michael Thomas cc5a4cd
+        FILE *sf = fp;
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
-	/*
Michael Thomas cc5a4cd
-	 * Grab a lock.
Michael Thomas cc5a4cd
-	 */
Michael Thomas cc5a4cd
-	if (flock(sd, lck))
Michael Thomas cc5a4cd
-		warn("warning: score file %s cannot be locked",
Michael Thomas cc5a4cd
-		    _PATH_SCOREFILE);
Michael Thomas cc5a4cd
+        if (sf == NULL) {
Michael Thomas cc5a4cd
+            sd = open(_PATH_SCOREFILE, O_RDONLY, 0664);
Michael Thomas cc5a4cd
+            if (sd < 0) {
Michael Thomas cc5a4cd
+                    nscores = 0;
Michael Thomas cc5a4cd
+                    return;
Michael Thomas cc5a4cd
+                    err(1, "cannot open %s for reading", _PATH_SCOREFILE);
Michael Thomas cc5a4cd
+            }
Michael Thomas cc5a4cd
+            if ((sf = fdopen(sd, "r")) == NULL) {
Michael Thomas cc5a4cd
+                    err(1, "cannot fdopen %s for reading", _PATH_SCOREFILE);
Michael Thomas cc5a4cd
+            }
Michael Thomas cc5a4cd
+        } else {
Michael Thomas cc5a4cd
+            rewind(sf);
Michael Thomas cc5a4cd
+        }
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
 	nscores = fread(scores, sizeof(scores[0]), MAXHISCORES, sf);
Michael Thomas cc5a4cd
 	if (ferror(sf)) {
Michael Thomas cc5a4cd
 		err(1, "error reading %s", _PATH_SCOREFILE);
Michael Thomas cc5a4cd
 	}
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
-	if (fpp)
Michael Thomas cc5a4cd
-		*fpp = sf;
Michael Thomas cc5a4cd
-	else
Michael Thomas cc5a4cd
-		(void)fclose(sf);
Michael Thomas cc5a4cd
+	else {
Michael Thomas cc5a4cd
+                if (fp == NULL) {
Michael Thomas cc5a4cd
+                        (void)fclose(sf);
Michael Thomas cc5a4cd
+                }
Michael Thomas cc5a4cd
+        }
Michael Thomas cc5a4cd
+}
Michael Thomas cc5a4cd
+
Michael Thomas cc5a4cd
+/*
Michael Thomas cc5a4cd
+ * Open the high score file and then drop setgid privileges.  If running
Michael Thomas cc5a4cd
+ * setgid, then calling this function a second time will result in a
Michael Thomas cc5a4cd
+ * permission denied error since gid privileges will have been lost.
Michael Thomas cc5a4cd
+ */
Michael Thomas cc5a4cd
+void
Michael Thomas cc5a4cd
+open_score(fd, fp)
Michael Thomas cc5a4cd
+    int *fd;
Michael Thomas cc5a4cd
+    FILE **fp;
Michael Thomas cc5a4cd
+{
Michael Thomas cc5a4cd
+    *fd = open(_PATH_SCOREFILE, O_RDWR | O_CREAT, 0664);
Michael Thomas cc5a4cd
+    if (*fd < 0) {
Michael Thomas cc5a4cd
+        err(1, "Could not open scoreboard file %s", _PATH_SCOREFILE);
Michael Thomas cc5a4cd
+    } else {
Michael Thomas cc5a4cd
+        *fp = fdopen(*fd, "r+");
Michael Thomas cc5a4cd
+        if (*fp == NULL) {
Michael Thomas cc5a4cd
+            err(1, "Could not open scoreboard file %s", _PATH_SCOREFILE);
Michael Thomas cc5a4cd
+        }
Michael Thomas cc5a4cd
+    }
Michael Thomas cc5a4cd
+    if (setresgid(-1, getgid(), getgid()) == -1) {
Michael Thomas cc5a4cd
+        perror("Could not drop setgid privileges.  Aborting.");
Michael Thomas cc5a4cd
+        exit(1);
Michael Thomas cc5a4cd
+    }
Michael Thomas cc5a4cd
 }
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
 void
Michael Thomas cc5a4cd
-savescore(level)
Michael Thomas cc5a4cd
+savescore(level, sf)
Michael Thomas cc5a4cd
 	int level;
Michael Thomas cc5a4cd
+        FILE *sf;
Michael Thomas cc5a4cd
 {
Michael Thomas cc5a4cd
 	struct highscore *sp;
Michael Thomas cc5a4cd
 	int i;
Michael Thomas cc5a4cd
 	int change;
Michael Thomas cc5a4cd
-	FILE *sf;
Michael Thomas cc5a4cd
 	const char *me;
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
-	getscores(&sf);
Michael Thomas cc5a4cd
+        if (sf == NULL) {
Michael Thomas cc5a4cd
+            return;
Michael Thomas cc5a4cd
+        }
Michael Thomas cc5a4cd
+
Michael Thomas cc5a4cd
+	getscores(sf);
Michael Thomas cc5a4cd
 	gotscores = 1;
Michael Thomas cc5a4cd
 	(void)time(&now;;
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
@@ -215,14 +219,17 @@
Michael Thomas cc5a4cd
 static char *
Michael Thomas cc5a4cd
 thisuser()
Michael Thomas cc5a4cd
 {
Michael Thomas cc5a4cd
-	const char *p;
Michael Thomas cc5a4cd
+	const char *p = (char *)NULL;
Michael Thomas cc5a4cd
 	struct passwd *pw;
Michael Thomas cc5a4cd
 	size_t l;
Michael Thomas cc5a4cd
 	static char u[sizeof(scores[0].hs_name)];
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
 	if (u[0])
Michael Thomas cc5a4cd
 		return (u);
Michael Thomas cc5a4cd
+        /* Don't use getlogin() as it will return the wrong result
Michael Thomas cc5a4cd
+         * for someone who has su'd to a different user.
Michael Thomas cc5a4cd
 	p = getlogin();
Michael Thomas cc5a4cd
+         */
Michael Thomas cc5a4cd
 	if (p == NULL || *p == '\0') {
Michael Thomas cc5a4cd
 		pw = getpwuid(getuid());
Michael Thomas cc5a4cd
 		if (pw != NULL)
Michael Thomas cc5a4cd
@@ -359,7 +366,7 @@
Michael Thomas cc5a4cd
 	int levelfound[NLEVELS];
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
 	if (!gotscores)
Michael Thomas cc5a4cd
-		getscores((FILE **)NULL);
Michael Thomas cc5a4cd
+		getscores(NULL);
Michael Thomas cc5a4cd
 	(void)printf("\n\t\t\t    Tetris High Scores\n");
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
 	/*
Michael Thomas cc5a4cd
diff -Naur --exclude '*.swp' bsd-games-2.17/tetris/scores.h bsd-games-2.17.new/tetris/scores.h
Michael Thomas cc5a4cd
--- bsd-games-2.17/tetris/scores.h	2006-04-22 20:46:56.000000000 -0700
Michael Thomas cc5a4cd
+++ bsd-games-2.17.new/tetris/scores.h	2006-04-22 16:30:46.000000000 -0700
Michael Thomas cc5a4cd
@@ -48,5 +48,6 @@
Michael Thomas cc5a4cd
 #define MAXSCORES	9	/* maximum high score entries per person */
Michael Thomas cc5a4cd
 #define	EXPIRATION	(5L * 365 * 24 * 60 * 60)
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
-void	savescore(int);
Michael Thomas cc5a4cd
+void	savescore(int, FILE *);
Michael Thomas cc5a4cd
+void    open_score(int *, FILE **);
Michael Thomas cc5a4cd
 void	showscores(int);
Michael Thomas cc5a4cd
diff -Naur --exclude '*.swp' bsd-games-2.17/tetris/tetris.c bsd-games-2.17.new/tetris/tetris.c
Michael Thomas cc5a4cd
--- bsd-games-2.17/tetris/tetris.c	2006-04-22 20:46:56.000000000 -0700
Michael Thomas cc5a4cd
+++ bsd-games-2.17.new/tetris/tetris.c	2006-04-22 21:02:27.000000000 -0700
Michael Thomas cc5a4cd
@@ -135,10 +135,15 @@
Michael Thomas cc5a4cd
 	char key_write[6][10];
Michael Thomas cc5a4cd
 	int ch, i, j;
Michael Thomas cc5a4cd
 	int fd;
Michael Thomas cc5a4cd
+        int sd = 0;
Michael Thomas cc5a4cd
+        FILE *sf = (FILE *)NULL;
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
-	gid = getgid();
Michael Thomas cc5a4cd
-	egid = getegid();
Michael Thomas cc5a4cd
-	setegid(gid);
Michael Thomas cc5a4cd
+        /*
Michael Thomas cc5a4cd
+         * This function has the side effect of dropping setgid privileges.
Michael Thomas cc5a4cd
+         * sd is not used, but is kept around in case we want to add code
Michael Thomas cc5a4cd
+         * to lock shared access to the scoreboard later.
Michael Thomas cc5a4cd
+         */
Michael Thomas cc5a4cd
+        open_score(&sd, &sf);
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
 	fd = open("/dev/null", O_RDONLY);
Michael Thomas cc5a4cd
 	if (fd < 3)
Michael Thomas cc5a4cd
@@ -307,7 +312,7 @@
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
 	(void)printf("Your score:  %d point%s  x  level %d  =  %d\n",
Michael Thomas cc5a4cd
 	    score, score == 1 ? "" : "s", level, score * level);
Michael Thomas cc5a4cd
-	savescore(level);
Michael Thomas cc5a4cd
+	savescore(level, sf);
Michael Thomas cc5a4cd
 
Michael Thomas cc5a4cd
 	printf("\nHit RETURN to see high scores, ^C to skip.\n");
Michael Thomas cc5a4cd