From b8613baa85965cbdf5fbe262b9464d5c0d98614f Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Sat, 27 May 2023 08:10:13 -0300 Subject: openrc: create lockfile for --user. the pam module sets a variable that when in user mode, openrc should pick up and either create/increment, or decrement. this is done so that multiple session_open and session_close from pam doesn't randomly change the user runlevel for the current user. only the first session open starts the default runlevel, and only the last session close switches to the none runlevel. Signed-off-by: Anna (navi) Figueiredo Gomes --- src/openrc/rc.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/openrc/rc.c b/src/openrc/rc.c index dca94a7f..366ceca2 100644 --- a/src/openrc/rc.c +++ b/src/openrc/rc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -819,6 +820,60 @@ handle_bad_signal(int sig) } #endif +#ifdef RC_USER_SERVICES + +static int +inc_dec_lockfile(int val) +{ + char *svcdir = NULL; + char *lockfile_path = NULL; + FILE *lockfile = NULL; + + int locknum = 0; + + einfov("locking lockfile"); + + svcdir = rc_user_svcdir(); + + if (mkdir(svcdir, 0700) != 0 && errno != EEXIST) + eerrorx("mkdir: %s, %s", svcdir, strerror(errno)); + + xasprintf(&lockfile_path, "%s/%s", svcdir, "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); + free(svcdir); + + fprintf(lockfile, "%d", locknum); + + if (flock(fileno(lockfile), LOCK_UN)) { + eerrorx("flock: %s", strerror(errno)); + } + fclose(lockfile); + + einfov("unlocking lockfile"); + + return locknum; +} + +#endif + int main(int argc, char **argv) { const char *bootlevel = NULL; @@ -839,7 +894,7 @@ int main(int argc, char **argv) bool nostop = false; #ifdef RC_USER_SERVICES char *user_svcdir = NULL; - char *user_sysconfdir = NULL; + int locknum = 0; #endif #ifdef __linux__ char *proc; @@ -946,6 +1001,18 @@ int main(int argc, char **argv) #ifdef RC_USER_SERVICES if (rc_is_user()) { + if (rc_yesno(getenv("RC_PAM_STARTING"))) { + /* the lockfile count -1 because we don't want to count ourselves */ + locknum = inc_dec_lockfile(1) - 1; + } else if (rc_yesno(getenv("RC_PAM_STOPPING"))) { + locknum = inc_dec_lockfile(-1); + } + + if (locknum > 0) { + einfov("lock set, skipping"); + return EXIT_SUCCESS; + } + user_svcdir = rc_user_svcdir(); xasprintf(&rc_stopping, "%s/%s", user_svcdir, RC_STOPPING_FOLDER); xasprintf(&rc_starting, "%s/%s", user_svcdir, RC_STARTING_FOLDER); -- cgit v1.2.3