X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=src%2Fwall-notify.c;h=806204e09c975c27c6885b3785724c6e0662162e;hb=1bc8ac76b48b4353161780a49509579367fb1bd8;hp=40cdfe587870bc46f6ae5cbfc6b8c0308a74d70e;hpb=1eb18876bb0eb8f55567dd8a92ab10091d045df7;p=wall-notify%2Fwall-notify.git diff --git a/src/wall-notify.c b/src/wall-notify.c index 40cdfe5..806204e 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. */ @@ -317,12 +359,20 @@ static void *x11_event_loop_thread(void *unused) { #endif static void usage(const char *argv0) { - fprintf(stderr, "usage: %s \n", argv0); + fprintf(stderr, "usage: %s [-X] \n", argv0); + fprintf(stderr, "Pass wall messages to .\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "-X quit when the current X session terminates\n"); +#ifdef DONT_USE_X11 + fprintf(stderr, "\n"); + fprintf(stderr, "compiled without X11 support, -X disabled\n"); +#endif exit(EXIT_FAILURE); } int main(int argc, char **argv) { + int enable_x11; int ptm, pts; char *name; const char *argv0; @@ -331,6 +381,20 @@ int main(int argc, char **argv) { /* Don't pass our argv[0] to the notification program. */ argv++; + enable_x11 = 0; + if (argc > 1 && argv[0][0] == '-') { + if (!strcmp("-X", argv[0])) { + enable_x11 = 1; + } else { + if (strcmp("-h", argv[0])) { + fprintf(stderr, "%s: unknown option '%s'!\n\n", argv0, argv[0]); + } + usage(argv0); + } + argc--; /* for usage */ + argv++; + } + if (argc < 2) { usage(argv0); } @@ -358,18 +422,21 @@ int main(int argc, char **argv) { exit(EXIT_FAILURE); } -#ifndef DONT_USE_X11 /* Start a thread which connects to X11. This way we die if the user logs * out of its X11 session. */ - { + if (enable_x11) { +#ifdef DONT_USE_X11 + fprintf(stderr, "%s: option -X is disabled!\n\n", argv0); + usage(argv0); +#else pthread_t tid; if (pthread_create(&tid, NULL, x11_event_loop_thread, NULL) != 0) { perror("pthread_create"); exit(EXIT_FAILURE); } - } #endif + } /* Cleanup on signals. Necessary before login(). */ setup_signals();