diff options
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/ChangeLog | 12 | ||||
| -rw-r--r-- | lib-src/Makefile.in | 16 | ||||
| -rw-r--r-- | lib-src/update-game-score.c | 33 |
3 files changed, 43 insertions, 18 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 37f037ef324..b67038ff81a 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2015-01-21 Ulrich Müller <ulm@gentoo.org> | ||
| 2 | |||
| 3 | * update-game-score.c: Allow the program to run sgid instead | ||
| 4 | of suid, in order to match common practice for most games. | ||
| 5 | (main): Check if we are running sgid. Pass appropriate file | ||
| 6 | permission bits to 'write_scores'. | ||
| 7 | (write_scores): New 'mode' argument, instead of hardcoding 0644. | ||
| 8 | (get_prefix): Update error message. | ||
| 9 | * Makefile.in (gamegroup): New variable, set by configure. | ||
| 10 | ($(DESTDIR)${archlibdir}): Handle both suid or sgid when | ||
| 11 | installing the 'update-game-score' program. | ||
| 12 | |||
| 1 | 2015-01-16 Eli Zaretskii <eliz@gnu.org> | 13 | 2015-01-16 Eli Zaretskii <eliz@gnu.org> |
| 2 | 14 | ||
| 3 | * Makefile.in (AM_V_RC, am__v_RC_, am__v_RC_0, am__v_RC_1): New | 15 | * Makefile.in (AM_V_RC, am__v_RC_, am__v_RC_0, am__v_RC_1): New |
diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in index 01592bd21a5..2997f1b35a8 100644 --- a/lib-src/Makefile.in +++ b/lib-src/Makefile.in | |||
| @@ -122,6 +122,7 @@ archlibdir=@archlibdir@ | |||
| 122 | 122 | ||
| 123 | gamedir=@gamedir@ | 123 | gamedir=@gamedir@ |
| 124 | gameuser=@gameuser@ | 124 | gameuser=@gameuser@ |
| 125 | gamegroup=@gamegroup@ | ||
| 125 | 126 | ||
| 126 | # ==================== Utility Programs for the Build ================= | 127 | # ==================== Utility Programs for the Build ================= |
| 127 | 128 | ||
| @@ -263,10 +264,17 @@ $(DESTDIR)${archlibdir}: all | |||
| 263 | umask 022; ${MKDIR_P} "$(DESTDIR)${gamedir}"; \ | 264 | umask 022; ${MKDIR_P} "$(DESTDIR)${gamedir}"; \ |
| 264 | touch "$(DESTDIR)${gamedir}/snake-scores"; \ | 265 | touch "$(DESTDIR)${gamedir}/snake-scores"; \ |
| 265 | touch "$(DESTDIR)${gamedir}/tetris-scores" | 266 | touch "$(DESTDIR)${gamedir}/tetris-scores" |
| 266 | -if chown ${gameuser} "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}" && chmod u+s "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}"; then \ | 267 | ifneq ($(gameuser),) |
| 267 | chown ${gameuser} "$(DESTDIR)${gamedir}"; \ | 268 | chown ${gameuser} "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}" |
| 268 | chmod u=rwx,g=rwx,o=rx "$(DESTDIR)${gamedir}"; \ | 269 | chmod u+s,go-r "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}" |
| 269 | fi | 270 | chown ${gameuser} "$(DESTDIR)${gamedir}" |
| 271 | chmod u=rwx,g=rx,o=rx "$(DESTDIR)${gamedir}" | ||
| 272 | else ifneq ($(gamegroup),) | ||
| 273 | chgrp ${gamegroup} "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}" | ||
| 274 | chmod g+s,o-r "$(DESTDIR)${archlibdir}/update-game-score${EXEEXT}" | ||
| 275 | chgrp ${gamegroup} "$(DESTDIR)${gamedir}" | ||
| 276 | chmod u=rwx,g=rwx,o=rx "$(DESTDIR)${gamedir}" | ||
| 277 | endif | ||
| 270 | exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && /bin/pwd`; \ | 278 | exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && /bin/pwd`; \ |
| 271 | if [ "$$exp_archlibdir" != "`cd ${srcdir} && /bin/pwd`" ]; then \ | 279 | if [ "$$exp_archlibdir" != "`cd ${srcdir} && /bin/pwd`" ]; then \ |
| 272 | for file in ${SCRIPTS}; do \ | 280 | for file in ${SCRIPTS}; do \ |
diff --git a/lib-src/update-game-score.c b/lib-src/update-game-score.c index d3354af2783..4f154832c81 100644 --- a/lib-src/update-game-score.c +++ b/lib-src/update-game-score.c | |||
| @@ -21,8 +21,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | /* This program allows a game to securely and atomically update a | 23 | /* This program allows a game to securely and atomically update a |
| 24 | score file. It should be installed setuid, owned by an appropriate | 24 | score file. It should be installed either setuid or setgid, owned |
| 25 | user like `games'. | 25 | by an appropriate user or group like `games'. |
| 26 | 26 | ||
| 27 | Alternatively, it can be compiled without HAVE_SHARED_GAME_DIR | 27 | Alternatively, it can be compiled without HAVE_SHARED_GAME_DIR |
| 28 | defined, and in that case it will store scores in the user's home | 28 | defined, and in that case it will store scores in the user's home |
| @@ -88,7 +88,7 @@ static int push_score (struct score_entry **scores, ptrdiff_t *count, | |||
| 88 | ptrdiff_t *size, struct score_entry const *newscore); | 88 | ptrdiff_t *size, struct score_entry const *newscore); |
| 89 | static void sort_scores (struct score_entry *scores, ptrdiff_t count, | 89 | static void sort_scores (struct score_entry *scores, ptrdiff_t count, |
| 90 | bool reverse); | 90 | bool reverse); |
| 91 | static int write_scores (const char *filename, | 91 | static int write_scores (const char *filename, mode_t mode, |
| 92 | const struct score_entry *scores, ptrdiff_t count); | 92 | const struct score_entry *scores, ptrdiff_t count); |
| 93 | 93 | ||
| 94 | static _Noreturn void | 94 | static _Noreturn void |
| @@ -122,18 +122,19 @@ get_user_id (void) | |||
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | static const char * | 124 | static const char * |
| 125 | get_prefix (bool running_suid, const char *user_prefix) | 125 | get_prefix (bool privileged, const char *user_prefix) |
| 126 | { | 126 | { |
| 127 | if (!running_suid && user_prefix == NULL) | 127 | if (privileged) |
| 128 | lose ("Not using a shared game directory, and no prefix given."); | ||
| 129 | if (running_suid) | ||
| 130 | { | 128 | { |
| 131 | #ifdef HAVE_SHARED_GAME_DIR | 129 | #ifdef HAVE_SHARED_GAME_DIR |
| 132 | return HAVE_SHARED_GAME_DIR; | 130 | return HAVE_SHARED_GAME_DIR; |
| 133 | #else | 131 | #else |
| 134 | lose ("This program was compiled without HAVE_SHARED_GAME_DIR,\n and should not be suid."); | 132 | lose ("This program was compiled without HAVE_SHARED_GAME_DIR,\n" |
| 133 | "and should not run with elevated privileges."); | ||
| 135 | #endif | 134 | #endif |
| 136 | } | 135 | } |
| 136 | if (user_prefix == NULL) | ||
| 137 | lose ("Not using a shared game directory, and no prefix given."); | ||
| 137 | return user_prefix; | 138 | return user_prefix; |
| 138 | } | 139 | } |
| 139 | 140 | ||
| @@ -173,7 +174,7 @@ int | |||
| 173 | main (int argc, char **argv) | 174 | main (int argc, char **argv) |
| 174 | { | 175 | { |
| 175 | int c; | 176 | int c; |
| 176 | bool running_suid; | 177 | bool running_suid, running_sgid; |
| 177 | void *lockstate; | 178 | void *lockstate; |
| 178 | char *scorefile; | 179 | char *scorefile; |
| 179 | char *end, *nl, *user, *data; | 180 | char *end, *nl, *user, *data; |
| @@ -214,8 +215,11 @@ main (int argc, char **argv) | |||
| 214 | usage (EXIT_FAILURE); | 215 | usage (EXIT_FAILURE); |
| 215 | 216 | ||
| 216 | running_suid = (getuid () != geteuid ()); | 217 | running_suid = (getuid () != geteuid ()); |
| 218 | running_sgid = (getgid () != getegid ()); | ||
| 219 | if (running_suid && running_sgid) | ||
| 220 | lose ("This program can run either suid or sgid, but not both."); | ||
| 217 | 221 | ||
| 218 | prefix = get_prefix (running_suid, user_prefix); | 222 | prefix = get_prefix (running_suid || running_sgid, user_prefix); |
| 219 | 223 | ||
| 220 | scorefile = malloc (strlen (prefix) + strlen (argv[optind]) + 2); | 224 | scorefile = malloc (strlen (prefix) + strlen (argv[optind]) + 2); |
| 221 | if (!scorefile) | 225 | if (!scorefile) |
| @@ -270,7 +274,8 @@ main (int argc, char **argv) | |||
| 270 | scores += scorecount - max_scores; | 274 | scores += scorecount - max_scores; |
| 271 | scorecount = max_scores; | 275 | scorecount = max_scores; |
| 272 | } | 276 | } |
| 273 | if (write_scores (scorefile, scores, scorecount) < 0) | 277 | if (write_scores (scorefile, running_sgid ? 0664 : 0644, |
| 278 | scores, scorecount) < 0) | ||
| 274 | { | 279 | { |
| 275 | unlock_file (scorefile, lockstate); | 280 | unlock_file (scorefile, lockstate); |
| 276 | lose_syserr ("Failed to write scores file"); | 281 | lose_syserr ("Failed to write scores file"); |
| @@ -421,8 +426,8 @@ sort_scores (struct score_entry *scores, ptrdiff_t count, bool reverse) | |||
| 421 | } | 426 | } |
| 422 | 427 | ||
| 423 | static int | 428 | static int |
| 424 | write_scores (const char *filename, const struct score_entry *scores, | 429 | write_scores (const char *filename, mode_t mode, |
| 425 | ptrdiff_t count) | 430 | const struct score_entry *scores, ptrdiff_t count) |
| 426 | { | 431 | { |
| 427 | int fd; | 432 | int fd; |
| 428 | FILE *f; | 433 | FILE *f; |
| @@ -435,7 +440,7 @@ write_scores (const char *filename, const struct score_entry *scores, | |||
| 435 | if (fd < 0) | 440 | if (fd < 0) |
| 436 | return -1; | 441 | return -1; |
| 437 | #ifndef DOS_NT | 442 | #ifndef DOS_NT |
| 438 | if (fchmod (fd, 0644) != 0) | 443 | if (fchmod (fd, mode) != 0) |
| 439 | return -1; | 444 | return -1; |
| 440 | #endif | 445 | #endif |
| 441 | f = fdopen (fd, "w"); | 446 | f = fdopen (fd, "w"); |