]> ruderich.org/simon Gitweb - wall-notify/wall-notify.git/commitdiff
drop privileges when running as group utmp
authorSimon Ruderich <simon@ruderich.org>
Thu, 15 May 2014 16:48:20 +0000 (18:48 +0200)
committerSimon Ruderich <simon@ruderich.org>
Thu, 15 May 2014 16:48:20 +0000 (18:48 +0200)
configure.ac
src/wall-notify.c

index 528f7146ba45d116615fb97d6b4601a8f409a490..9f1efc3a1e4ba30cbe52b7797054c5fddd787b48 100644 (file)
@@ -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.])
index 40cdfe587870bc46f6ae5cbfc6b8c0308a74d70e..292b71a1d9d026208db979be56cc5c03bdffb4d0 100644 (file)
@@ -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. */