X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=slock.c;h=467937cee0c0474ea98b5bfb1bf7c2c9b2a9cbd4;hb=ba3acfc0dcf1d0603bd9d6bdee1e319339b1a509;hp=12b8d4dd49fe31ba1678e0680873b457cbbf39af;hpb=c1507cd225a34ef69045cfc20519b16212dba8dd;p=slock.git diff --git a/slock.c b/slock.c index 12b8d4d..467937c 100644 --- a/slock.c +++ b/slock.c @@ -1,3 +1,4 @@ + /* See LICENSE file for license details. */ #define _XOPEN_SOURCE 500 #if HAVE_SHADOW_H @@ -43,6 +44,21 @@ die(const char *errstr, ...) { exit(EXIT_FAILURE); } +#ifdef __linux__ +#include + +static void +dontkillme(void) { + int fd; + + fd = open("/proc/self/oom_score_adj", O_WRONLY); + if (fd < 0 && errno == ENOENT) + return; + if (fd < 0 || write(fd, "-1000\n", 6) != 6 || close(fd) != 0) + die("cannot disable the out-of-memory killer for this process\n"); +} +#endif + #ifndef HAVE_BSD_AUTH static const char * getpw(void) { /* only run as root */ @@ -51,12 +67,12 @@ getpw(void) { /* only run as root */ pw = getpwuid(getuid()); if(!pw) - die("slock: cannot retrieve password entry (make sure to suid or sgid slock)"); + die("slock: cannot retrieve password entry (make sure to suid or sgid slock)\n"); endpwent(); rval = pw->pw_passwd; #if HAVE_SHADOW_H - { + if (strlen(rval) >= 1) { /* kludge, assumes pw placeholder entry has len >= 1 */ struct spwd *sp; sp = getspnam(getenv("USER")); if(!sp) @@ -67,8 +83,9 @@ getpw(void) { /* only run as root */ #endif /* drop privileges */ - if(setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0) - die("slock: cannot drop privileges"); + if (geteuid() == 0 + && ((getegid() != pw->pw_gid && setgid(pw->pw_gid) < 0) || setuid(pw->pw_uid) < 0)) + die("slock: cannot drop privileges\n"); return rval; } #endif @@ -113,9 +130,9 @@ readpw(Display *dpy, const char *pws) #ifdef HAVE_BSD_AUTH running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd); #else - running = strcmp(crypt(passwd, pws), pws); + running = !!strcmp(crypt(passwd, pws), pws); #endif - if(running != False) + if(running) XBell(dpy, 100); len = 0; break; @@ -211,9 +228,9 @@ lockscreen(Display *dpy, int screen) { break; usleep(1000); } - running = (len > 0); } + running &= (len > 0); if(!running) { unlockscreen(dpy, lock); lock = NULL; @@ -243,24 +260,38 @@ main(int argc, char **argv) { else if(argc != 1) usage(); +#ifdef __linux__ + dontkillme(); +#endif + if(!getpwuid(getuid())) - die("slock: no passwd entry for you"); + die("slock: no passwd entry for you\n"); #ifndef HAVE_BSD_AUTH pws = getpw(); #endif if(!(dpy = XOpenDisplay(0))) - die("slock: cannot open display"); + die("slock: cannot open display\n"); /* Get the number of screens in display "dpy" and blank them all. */ nscreens = ScreenCount(dpy); locks = malloc(sizeof(Lock *) * nscreens); if(locks == NULL) - die("slock: malloc: %s", strerror(errno)); - for(screen = 0; screen < nscreens; screen++) - locks[screen] = lockscreen(dpy, screen); + die("slock: malloc: %s\n", strerror(errno)); + int nlocks = 0; + for(screen = 0; screen < nscreens; screen++) { + if ( (locks[screen] = lockscreen(dpy, screen)) != NULL) + nlocks++; + } XSync(dpy, False); + /* Did we actually manage to lock something? */ + if (nlocks == 0) { // nothing to protect + free(locks); + XCloseDisplay(dpy); + return 1; + } + /* Everything is now blank. Now wait for the correct password. */ #ifdef HAVE_BSD_AUTH readpw(dpy);