aboutsummaryrefslogtreecommitdiff
path: root/src/openrc-pam/openrc-pam.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openrc-pam/openrc-pam.c')
-rw-r--r--src/openrc-pam/openrc-pam.c63
1 files changed, 59 insertions, 4 deletions
diff --git a/src/openrc-pam/openrc-pam.c b/src/openrc-pam/openrc-pam.c
index 40b9a6dc..0a2cde11 100644
--- a/src/openrc-pam/openrc-pam.c
+++ b/src/openrc-pam/openrc-pam.c
@@ -6,12 +6,56 @@
#include <stdbool.h>
#include <stdio.h>
#include <syslog.h>
+#include <sys/file.h>
#include <unistd.h>
#include <string.h>
#include "einfo.h"
#include "queue.h"
+static int
+inc_dec_lockfile(pam_handle_t *pamh, int val)
+{
+ char *lockfile_path = NULL;
+ FILE *lockfile = NULL;
+
+ int locknum = 0;
+
+ pam_syslog(pamh, LOG_INFO, "locking lockfile");
+
+ xasprintf(&lockfile_path, "%s/openrc/%s", pam_getenv(pamh, "XDG_RUNTIME_DIR"), "lock");
+ lockfile = fopen(lockfile_path, "r+");
+ if (!lockfile) {
+ lockfile = fopen(lockfile_path, "w+");
+ if (!lockfile)
+ eerrorx("fopen: failed to open file %s, %s", lockfile_path, strerror(errno));
+ if (flock(fileno(lockfile), LOCK_EX) != 0) {
+ eerrorx("flock: %s", strerror(errno));
+ }
+ locknum = 1;
+ } else {
+ if (flock(fileno(lockfile), LOCK_EX) != 0) {
+ eerrorx("flock: %s", strerror(errno));
+ }
+ fscanf(lockfile, "%d", &locknum);
+ locknum += val;
+ rewind(lockfile);
+ }
+
+ free(lockfile_path);
+
+ fprintf(lockfile, "%d", locknum);
+
+ if (flock(fileno(lockfile), LOCK_UN)) {
+ eerrorx("flock: %s", strerror(errno));
+ }
+ fclose(lockfile);
+
+ pam_syslog(pamh, LOG_INFO, "unlocking lockfile");
+
+ return locknum;
+}
+
static void load_envs_from_file(const char *path, RC_STRINGLIST *out) {
FILE *fp = NULL;
char *line = NULL;
@@ -151,6 +195,7 @@ static char *create_xdg_runtime_dir(struct passwd *pw) {
}
static bool exec_openrc(pam_handle_t *pamh, const char *runlevel, bool lock) {
+ int lockval;
char *cmd = NULL;
const char *username;
struct passwd *pw = NULL;
@@ -182,11 +227,21 @@ static bool exec_openrc(pam_handle_t *pamh, const char *runlevel, bool lock) {
envlist = pam_getenvlist(pamh);
- xasprintf(&cmd, "openrc --user %s %s", lock ? "--lock" : "--unlock", runlevel);
- pam_syslog(pamh, LOG_INFO, "Executing %s for user %s", cmd, username);
- exec_user_cmd(pw, cmd, envlist);
+ xasprintf(&cmd, "openrc --user %s", runlevel);
+
+ /* if we are locking, reduce the count by 1,
+ * because we don't want to count ourselves */
+ lockval = inc_dec_lockfile(pamh, lock ? 1 : -1) - lock == true ? 1 : 0;
- set_user_env(pamh);
+ if (lockval == 0) {
+ pam_syslog(pamh, LOG_INFO, "Executing %s for user %s", cmd, username);
+ exec_user_cmd(pw, cmd, envlist);
+ }
+
+ if (lock) {
+ pam_syslog(pamh, LOG_INFO, "Setting the user's environment");
+ set_user_env(pamh);
+ }
for (env = envlist; *env; env++)
free(*env);