From: Simon Ruderich Date: Thu, 15 May 2014 16:48:20 +0000 (+0200) Subject: drop privileges when running as group utmp X-Git-Url: https://ruderich.org/simon/gitweb/?a=commitdiff_plain;h=3553a29a54f7755debfa189db830c4b8de51826f;p=wall-notify%2Fwall-notify.git drop privileges when running as group utmp --- diff --git a/configure.ac b/configure.ac index 528f714..9f1efc3 100644 --- a/configure.ac +++ b/configure.ac @@ -37,12 +37,16 @@ fi AC_CHECK_HEADERS([utempter.h utmpx.h]) if test "x$ac_cv_header_utempter_h" = xyes; then + AC_CHECK_FUNCS([setresuid setresgid],[], + [AC_MSG_ERROR([setresuid() and setresgid() required for utmpx])]) + AC_MSG_NOTICE([using utempter]) AC_CHECK_LIB([utempter], [utempter_add_record], [], [AC_MSG_ERROR([utempter_add_record() required])]) AC_CHECK_LIB([utempter], [utempter_remove_record], [], [AC_MSG_ERROR([utempter_remove_record() required])]) AC_DEFINE([USE_UTEMPTER], 1, [Define to 1 to use utempter.]) + elif test "x$ac_cv_header_utmpx_h" = xyes; then AC_MSG_NOTICE([using utmp]) AC_DEFINE([USE_UTMPX], 1, [Define to 1 to use utmp.]) diff --git a/src/wall-notify.c b/src/wall-notify.c index 40cdfe5..292b71a 100644 --- a/src/wall-notify.c +++ b/src/wall-notify.c @@ -203,6 +203,44 @@ static int wait_for_write(int fd, int timeout) { return 1; } +#ifdef USE_UTMPX +static void drop_privileges(void) { + uid_t uid, ruid, euid, suid; + gid_t gid, rgid, egid, sgid; + + uid = getuid(); + gid = getgid(); + + /* Drop all privileges. */ + if (setresuid(uid, uid, uid) != 0) { + perror("setresuid"); + exit(EXIT_FAILURE); + } + if (setresgid(gid, gid, gid) != 0) { + perror("setresgid"); + exit(EXIT_FAILURE); + } + + /* Verify all privileges were dropped. */ + if (getresuid(&ruid, &euid, &suid) != 0) { + perror("getresuid"); + exit(EXIT_FAILURE); + } + if (getresgid(&rgid, &egid, &sgid) != 0) { + perror("getresgid"); + exit(EXIT_FAILURE); + } + if (uid == ruid && uid == euid && uid == suid + && gid == rgid && gid == egid && gid == sgid) { + /* Everything fine. */ + return; + } + + fprintf(stderr, "failed to drop privileges, aborting\n"); + exit(EXIT_FAILURE); +} +#endif + static void pass_buffer_to_program(const char *buffer, size_t length, char **argv) { int fds[2]; FILE *fh; @@ -229,6 +267,10 @@ static void pass_buffer_to_program(const char *buffer, size_t length, char **arg } else if (pid == 0) { /* child */ +#ifdef USE_UTMPX + drop_privileges(); +#endif + close(fds[1]); /* write side */ /* Pass read side as stdin to the program. */