File allow_cmd_before_and_after.patch of Package physlock
From 185a63267380d87728031674a68b8b80247ae3a9 Mon Sep 17 00:00:00 2001
From: Christoph Ruegge <mail@cxcs.de>
Date: Fri, 25 Oct 2019 08:22:57 +0200
Subject: [PATCH 02/11] Call pam_setcred after successful authentication
---
main.c | 1 +
1 file changed, 1 insertion(+)
--- main.c
+++ main.c
@@ -197,6 +197,7 @@ int main(int argc, char **argv) {
u->pam_status = pam_authenticate(u->pamh, 0);
switch (u->pam_status) {
case PAM_SUCCESS:
+ pam_setcred(u->pamh, PAM_REFRESH_CRED);
locked = 0;
break;
case PAM_AUTH_ERR:
From 2eb17b1111d2839ba24a0ac764a50c29a03c8355 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bert=20M=C3=BCnnich?= <ber.t@posteo.de>
Date: Mon, 16 Dec 2019 09:36:36 +0100
Subject: [PATCH 03/11] Fix for systemd mechanism never used
---
Makefile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- Makefile
+++ Makefile
@@ -10,7 +10,8 @@ MANPREFIX = $(PREFIX)/share/man
HAVE_SYSTEMD = 1
cflags = -Wall -pedantic $(CFLAGS)
-cppflags = -I. $(CPPFLAGS) -D_XOPEN_SOURCE=500
+cppflags = -I. $(CPPFLAGS) -D_XOPEN_SOURCE=500 \
+ -DHAVE_SYSTEMD=$(HAVE_SYSTEMD)
lib_systemd_0 =
lib_systemd_1 = -lsystemd
From 3d5c3b599a2fe3f50032c1066ee46d0e047c002c Mon Sep 17 00:00:00 2001
From: travankor <travankor@tuta.io>
Date: Fri, 13 Dec 2019 13:54:19 -0700
Subject: [PATCH 04/11] Rename systemd function to logind.
---
main.c | 2 +-
physlock.h | 2 +-
session.c | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
--- main.c
+++ main.c
@@ -134,7 +134,7 @@ int main(int argc, char **argv) {
return 0;
}
- if (get_user_systemd(&user, oldvt) == -1 && get_user_utmp(&user, oldvt) == -1)
+ if (get_user_logind(&user, oldvt) == -1 && get_user_utmp(&user, oldvt) == -1)
get_user_by_id(&user, owner);
get_user_by_id(&root, 0);
if (strcmp(user.name, root.name) != 0)
--- physlock.h
+++ physlock.h
@@ -64,7 +64,7 @@ void parse_options(int, char**);
/* session.c */
-int get_user_systemd(userinfo_t*, int);
+int get_user_logind(userinfo_t*, int);
int get_user_utmp(userinfo_t*, int);
--- session.c
+++ session.c
@@ -11,7 +11,7 @@
#if HAVE_SYSTEMD
#include <systemd/sd-login.h>
-int get_user_systemd(userinfo_t *uinfo, int vt) {
+int get_user_logind(userinfo_t *uinfo, int vt) {
int ret = -1, i, n;
char **sessions = NULL;
unsigned int sess_vt;
@@ -40,7 +40,7 @@ int get_user_systemd(userinfo_t *uinfo, int vt) {
#else
-int get_user_systemd(userinfo_t *uinfo, int vt) {
+int get_user_logind(userinfo_t *uinfo, int vt) {
(void)uinfo;
(void)vt;
return -1;
From 454122212049f48edfc3c6d80d4c0436ea33160b Mon Sep 17 00:00:00 2001
From: travankor <travankor@tuta.io>
Date: Fri, 13 Dec 2019 14:23:48 -0700
Subject: [PATCH 05/11] Add option to use elogind.
Fixes issue #85.
---
Makefile | 10 +++++++---
README.md | 3 ++-
session.c | 5 +++++
3 files changed, 14 insertions(+), 4 deletions(-)
--- Makefile
+++ Makefile
@@ -6,16 +6,20 @@ VPATH = $(srcdir)
PREFIX = /usr/local
MANPREFIX = $(PREFIX)/share/man
-# enable user detection using libsystemd
+# enable user detection using libsystemd or libelogind
HAVE_SYSTEMD = 1
+HAVE_ELOGIND = 0
cflags = -Wall -pedantic $(CFLAGS)
cppflags = -I. $(CPPFLAGS) -D_XOPEN_SOURCE=500 \
- -DHAVE_SYSTEMD=$(HAVE_SYSTEMD)
+ -DHAVE_SYSTEMD=$(HAVE_SYSTEMD) -DHAVE_ELOGIND=$(HAVE_ELOGIND)
lib_systemd_0 =
lib_systemd_1 = -lsystemd
-ldlibs = $(LDLIBS) -lpam -lpam_misc $(lib_systemd_$(HAVE_SYSTEMD))
+lib_elogind_0 =
+lib_elogind_1 = -lelogind
+ldlibs = $(LDLIBS) -lpam -lpam_misc \
+ $(lib_systemd_$(HAVE_SYSTEMD)) $(lib_elogind_$(HAVE_ELOGIND))
objs = main.o options.o session.o util.o vt.o
--- README.md
+++ README.md
@@ -7,7 +7,8 @@ PAM for authentication.
physlock uses 3 mechanisms to detect the user of the active session:
-1. Querying systemd-logind(1) if not compiled with `HAVE_SYSTEMD=0`
+1. Querying systemd-logind(1) or elogind(8) if compiled with either
+ `HAVE_SYSTEMD=1` or `HAVE_ELOGIND=1`
2. Searching the utmp file for an entry whose `ut_line` field is the base name
of the active tty device file
3. Using the owner of the active tty device file typically set by login(1)
--- session.c
+++ session.c
@@ -10,6 +10,11 @@
#if HAVE_SYSTEMD
#include <systemd/sd-login.h>
+#elif HAVE_ELOGIND
+#include <elogind/sd-login.h>
+#endif
+
+#if HAVE_SYSTEMD || HAVE_ELOGIND
int get_user_logind(userinfo_t *uinfo, int vt) {
int ret = -1, i, n;
From 2d8113990c1e8153e8e8ee4612ecd534b555a0f5 Mon Sep 17 00:00:00 2001
From: dexterlb <dexterlb@qtrp.org>
Date: Sun, 2 Jun 2019 18:27:03 +0300
Subject: [PATCH 07/11] implement -a, -b and -n
---
main.c | 31 +++++++++++++++++++++++++++----
options.c | 14 ++++++++++++--
physlock.h | 3 +++
3 files changed, 42 insertions(+), 6 deletions(-)
--- main.c
+++ main.c
@@ -26,6 +26,7 @@
#include <errno.h>
#include <pwd.h>
#include <signal.h>
+#include <sys/wait.h>
#include <security/pam_misc.h>
static int oldvt;
@@ -33,6 +34,7 @@ static vt_t vt;
static int oldsysrq;
static int oldprintk;
static pid_t chpid;
+static int cmdpid;
static int locked;
static userinfo_t root, user;
@@ -67,8 +69,8 @@ CLEANUP void free_user(userinfo_t *uinfo) {
}
void cleanup() {
- if (options->detach && chpid > 0)
- /* No cleanup in parent after successful fork */
+ if ((options->detach && chpid > 0) || cmdpid == 0)
+ /* No cleanup in parent after successful fork or in failed forked command */
return;
free_user(&user);
free_user(&root);
@@ -98,17 +100,30 @@ void setup_signal(int signum, void (*handler)(int)) {
sigact.sa_flags = 0;
sigact.sa_handler = handler;
sigemptyset(&sigact.sa_mask);
-
+
if (sigaction(signum, &sigact, NULL) < 0)
error(0, errno, "signal %d", signum);
}
+void run_command(const char* cmd) {
+ cmdpid = fork();
+ if (cmdpid < 0) {
+ error(EXIT_FAILURE, errno, "fork");
+ } else if (cmdpid > 0) {
+ wait(NULL);
+ } else {
+ execlp("sh", "sh", "-c", cmd, NULL);
+ error(EXIT_FAILURE, errno, "exec");
+ }
+}
+
int main(int argc, char **argv) {
int try = 0, root_user = 1;
uid_t owner;
userinfo_t *u = &user;
oldvt = oldsysrq = oldprintk = vt.nr = vt.fd = -1;
+ cmdpid = -1;
vt.ios = NULL;
error_init(2);
@@ -180,11 +195,15 @@ int main(int argc, char **argv) {
dup2(vt.fd, 1);
dup2(vt.fd, 2);
+ if (options->command_before != NULL && options->command_before[0] != '\0') {
+ run_command(options->command_before);
+ }
+
if (options->prompt != NULL && options->prompt[0] != '\0') {
fprintf(vt.ios, "%s\n\n", options->prompt);
}
- locked = 1;
+ locked = !options->no_auth;
while (locked) {
if (!root_user && try >= (u == &root ? 1 : 3)) {
@@ -218,6 +237,10 @@ int main(int argc, char **argv) {
}
}
+ if (options->command_after != NULL && options->command_after[0] != '\0') {
+ run_command(options->command_after);
+ }
+
return 0;
}
--- options.c
+++ options.c
@@ -37,7 +37,7 @@ void print_version() {
void parse_options(int argc, char **argv) {
int opt;
-
+
progname = strrchr(argv[0], '/');
progname = progname != NULL ? progname + 1 : argv[0];
@@ -45,8 +45,9 @@ void parse_options(int argc, char **argv) {
_options.disable_sysrq = 0;
_options.lock_switch = -1;
_options.mute_kernel_messages = 0;
+ _options.no_auth = 0;
- while ((opt = getopt(argc, argv, "dhLlmp:sv")) != -1) {
+ while ((opt = getopt(argc, argv, "dhLlmnp:svb:a:")) != -1) {
switch (opt) {
case '?':
print_usage();
@@ -66,9 +67,18 @@ void parse_options(int argc, char **argv) {
case 'm':
_options.mute_kernel_messages = 1;
break;
+ case 'n':
+ _options.no_auth = 1;
+ break;
case 'p':
_options.prompt = optarg;
break;
+ case 'b':
+ _options.command_before = optarg;
+ break;
+ case 'a':
+ _options.command_after = optarg;
+ break;
case 's':
_options.disable_sysrq = 1;
break;
--- physlock.h
+++ physlock.h
@@ -54,7 +54,10 @@ typedef struct options_s {
int disable_sysrq;
int lock_switch;
int mute_kernel_messages;
+ int no_auth;
const char *prompt;
+ const char *command_before;
+ const char *command_after;
} options_t;
extern const options_t *options;
From 46ad54bf65fa00c3fb1fb89c64972c0ea0fca3b7 Mon Sep 17 00:00:00 2001
From: dexterlb <dexterlb@qtrp.org>
Date: Sun, 2 Jun 2019 18:37:24 +0300
Subject: [PATCH 08/11] document extra options
---
README.md | 3 +++
physlock.1 | 15 ++++++++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
--- README.md
+++ README.md
@@ -58,6 +58,9 @@ The following command-line arguments are supported:
-l only lock console switching
-L only enable console switching
-m mute kernel messages on console while physlock is running
+ -b CMD execute CMD before the password prompt
+ -a CMD execute CMD after successfully authenticating
+ -n don't actually authenticate: just execute commands
-p MSG Display MSG before the password prompt
-s disable sysrq key while physlock is running
-v print version information and exit
--- physlock.1
+++ physlock.1
@@ -3,9 +3,13 @@
physlock \- lock all consoles / virtual terminals
.SH SYNOPSIS
.B physlock
-.RB [ \-dhLlmsv ]
+.RB [ \-dhLlmnsv ]
.RB [ \-p
.IR MSG ]
+.RB [ \-b
+.IR CMD ]
+.RB [ \-a
+.IR CMD ]
.SH DESCRIPTION
physlock is an alternative to vlock, it is equivalent to `vlock \-an'. It is
written because vlock blocks some linux kernel mechanisms like hibernate and
@@ -39,6 +43,15 @@ locked.
.B \-m
Mute kernel messages on console while physlock is running.
.TP
+.B "\-b " CMD
+Execute CMD before asking for password
+.TP
+.B "\-a " CMD
+Execute CMD after asking for password
+.TP
+.B \-n
+Don't ask for authentication: just execute commands
+.TP
.BI "\-p " MSG
Display
.I MSG
From a9f968d9e331127a2ae0d548c3020874a1358689 Mon Sep 17 00:00:00 2001
From: dexterlb <dexterlb@qtrp.org>
Date: Mon, 17 Jun 2019 17:36:23 +0300
Subject: [PATCH 09/11] add extra options to print_usage()
---
options.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- options.c
+++ options.c
@@ -28,7 +28,7 @@ static options_t _options;
const options_t *options = (const options_t*) &_options;
void print_usage() {
- printf("usage: physlock [-dhLlmsv] [-p MSG]\n");
+ printf("usage: physlock [-dhLlmsbanv] [-p MSG]\n");
}
void print_version() {
From 7200a418b58b9608141c421875919798382cd504 Mon Sep 17 00:00:00 2001
From: dexterlb <dexterlb@qtrp.org>
Date: Tue, 1 Oct 2019 11:55:11 +0300
Subject: [PATCH 10/11] use hardcoded /bin/sh as a shell instead of relying on
PATH
---
main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- main.c
+++ main.c
@@ -112,7 +112,7 @@ void run_command(const char* cmd) {
} else if (cmdpid > 0) {
wait(NULL);
} else {
- execlp("sh", "sh", "-c", cmd, NULL);
+ execl("/bin/sh", "sh", "-c", cmd, NULL);
error(EXIT_FAILURE, errno, "exec");
}
}
From fc47a51029ea32bd575962248e11cca5fd9b550d Mon Sep 17 00:00:00 2001
From: dexterlb <dexterlb@qtrp.org>
Date: Tue, 1 Oct 2019 12:14:04 +0300
Subject: [PATCH 11/11] don't run external commands as root
---
main.c | 40 ++++++++++++++++++++++++++++------------
1 file changed, 28 insertions(+), 12 deletions(-)
--- main.c
+++ main.c
@@ -105,16 +105,32 @@ void setup_signal(int signum, void (*handler)(int)) {
error(0, errno, "signal %d", signum);
}
-void run_command(const char* cmd) {
- cmdpid = fork();
- if (cmdpid < 0) {
- error(EXIT_FAILURE, errno, "fork");
- } else if (cmdpid > 0) {
- wait(NULL);
- } else {
- execl("/bin/sh", "sh", "-c", cmd, NULL);
- error(EXIT_FAILURE, errno, "exec");
- }
+void drop_privileges(userinfo_t* user) {
+ struct passwd *p = getpwnam(user->name);
+ if (p == NULL) {
+ error(EXIT_FAILURE, errno, "get user passwd data");
+ }
+
+ if (setgid(p->pw_gid) != 0) {
+ error(EXIT_FAILURE, errno, "setgid");
+ }
+
+ if (setuid(p->pw_uid) != 0) {
+ error(EXIT_FAILURE, errno, "setuid");
+ }
+}
+
+void run_command(const char* cmd, userinfo_t* user) {
+ cmdpid = fork();
+ if (cmdpid < 0) {
+ error(EXIT_FAILURE, errno, "fork");
+ } else if (cmdpid > 0) {
+ wait(NULL);
+ } else {
+ drop_privileges(user);
+ execl("/bin/sh", "sh", "-c", cmd, NULL);
+ error(EXIT_FAILURE, errno, "exec");
+ }
}
int main(int argc, char **argv) {
@@ -196,7 +212,7 @@ int main(int argc, char **argv) {
dup2(vt.fd, 2);
if (options->command_before != NULL && options->command_before[0] != '\0') {
- run_command(options->command_before);
+ run_command(options->command_before, &user);
}
if (options->prompt != NULL && options->prompt[0] != '\0') {
@@ -238,7 +254,7 @@ int main(int argc, char **argv) {
}
if (options->command_after != NULL && options->command_after[0] != '\0') {
- run_command(options->command_after);
+ run_command(options->command_after, &user);
}
return 0;