#include <ctype.h>
#include <errno.h>
+#include <grp.h>
#include <pwd.h>
#include <stdarg.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#if HAVE_BSD_AUTH
-#include <login_cap.h>
-#include <bsd_auth.h>
-#endif
-
#include "arg.h"
#include "util.h"
}
#endif
-#ifndef HAVE_BSD_AUTH
-/* only run as root */
static const char *
getpw(void)
{
const char *rval;
struct passwd *pw;
+ /* Check if the current user has a password entry */
errno = 0;
if (!(pw = getpwuid(getuid()))) {
if (errno)
- die("getpwuid: %s\n", strerror(errno));
+ die("slock: getpwuid: %s\n", strerror(errno));
else
- die("cannot retrieve password entry\n");
+ die("slock: cannot retrieve password entry\n");
}
rval = pw->pw_passwd;
if (rval[0] == 'x' && rval[1] == '\0') {
struct spwd *sp;
if (!(sp = getspnam(getenv("USER"))))
- die("cannot retrieve shadow entry (make sure to suid or sgid slock)\n");
+ die("slock: getspnam: cannot retrieve shadow entry (make sure to suid or sgid slock)\n");
rval = sp->sp_pwdp;
}
-#endif
+#else
+ if (rval[0] == '*' && rval[1] == '\0') {
+#ifdef __OpenBSD__
+ if (!(pw = getpwnam_shadow(getenv("USER"))))
+ die("slock: getpwnam_shadow: cannot retrieve shadow entry (make sure to suid or sgid slock)\n");
+ rval = pw->pw_passwd;
+#else
+ die("slock: getpwuid: cannot retrieve shadow entry (make sure to suid or sgid slock)\n");
+#endif /* __OpenBSD__ */
+ }
+#endif /* HAVE_SHADOW_H */
- /* drop privileges */
- if (geteuid() == 0 &&
- ((getegid() != pw->pw_gid && setgid(pw->pw_gid) < 0) || setuid(pw->pw_uid) < 0))
- die("cannot drop privileges\n");
return rval;
}
-#endif
static void
-#ifdef HAVE_BSD_AUTH
-readpw(Display *dpy)
-#else
readpw(Display *dpy, const char *pws)
-#endif
{
char buf[32], passwd[256], *encrypted;
int num, screen, running, failure;
switch (ksym) {
case XK_Return:
passwd[len] = 0;
-#ifdef HAVE_BSD_AUTH
- running = !auth_userokay(getlogin(), NULL, "auth-slock", passwd);
-#else
errno = 0;
if (!(encrypted = crypt(passwd, pws)))
fprintf(stderr, "slock: crypt: %s\n", strerror(errno));
else
running = !!strcmp(encrypted, pws);
-#endif
if (running) {
XBell(dpy, 100);
failure = True;
XDefineCursor(dpy, lock->win, invisible);
/* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */
- for (i = 6, ptgrab = kbgrab = -1; i; --i) {
+ for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) {
if (ptgrab != GrabSuccess) {
ptgrab = XGrabPointer(dpy, lock->root, False,
ButtonPressMask | ButtonReleaseMask |
int
main(int argc, char **argv) {
-#ifndef HAVE_BSD_AUTH
+ struct passwd *pwd;
+ struct group *grp;
+ uid_t duid;
+ gid_t dgid;
const char *pws;
-#endif
Display *dpy;
int s, nlocks;
usage();
} ARGEND
+ /* validate drop-user and -group */
+ errno = 0;
+ if (!(pwd = getpwnam(user)))
+ die("slock: getpwnam %s: %s\n", user, errno ?
+ strerror(errno) : "user entry not found");
+ duid = pwd->pw_uid;
+ errno = 0;
+ if (!(grp = getgrnam(group)))
+ die("slock: getgrnam %s: %s\n", group, errno ?
+ strerror(errno) : "group entry not found");
+ dgid = grp->gr_gid;
+
#ifdef __linux__
dontkillme();
#endif
- /* Check if the current user has a password entry */
- errno = 0;
- if (!getpwuid(getuid())) {
- if (errno == 0)
- die("slock: no password entry for current user\n");
- else
- die("slock: getpwuid: %s\n", strerror(errno));
- }
-
-#ifndef HAVE_BSD_AUTH
pws = getpw();
if (strlen(pws) < 2)
die("slock: failed to get user password hash.\n");
-#endif
if (!(dpy = XOpenDisplay(NULL)))
die("slock: cannot open display\n");
+ /* drop privileges */
+ if (setgroups(0, NULL) < 0)
+ die("slock: setgroups: %s\n", strerror(errno));
+ if (setgid(dgid) < 0)
+ die("slock: setgid: %s\n", strerror(errno));
+ if (setuid(duid) < 0)
+ die("slock: setuid: %s\n", strerror(errno));
+
/* check for Xrandr support */
rr = XRRQueryExtension(dpy, &rrevbase, &rrerrbase);
}
/* everything is now blank. Wait for the correct password */
-#ifdef HAVE_BSD_AUTH
- readpw(dpy);
-#else
readpw(dpy, pws);
-#endif
/* password ok, unlock everything and quit */
cleanup(dpy);