Skip to content

Commit

Permalink
rc.c, openrc-pam.c: move lockfile code into pam module
Browse files Browse the repository at this point in the history
since we now assure that XDG_RUNTIME_DIR is set in the pam environment,
we can handle the lock file in there instead, which makes way more sense
for me at least.

Signed-off-by: Anna (navi) Figueiredo Gomes <[email protected]>
  • Loading branch information
navi-desu committed Jun 20, 2023
1 parent b0bb596 commit d2ce671
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 87 deletions.
63 changes: 59 additions & 4 deletions src/openrc-pam/openrc-pam.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
84 changes: 1 addition & 83 deletions src/openrc/rc.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
#include "helpers.h"

const char *extraopts = NULL;
const char getoptstring[] = "a:no:s:Slu" getoptstring_COMMON
const char getoptstring[] = "a:no:s:S" getoptstring_COMMON
#ifdef RC_USER_SERVICES
getoptstring_USER_SERVICES
#endif
Expand All @@ -61,8 +61,6 @@ const struct option longopts[] = {
{ "override", 1, NULL, 'o' },
{ "service", 1, NULL, 's' },
{ "sys", 0, NULL, 'S' },
{ "lock", 0, NULL, 'l' },
{ "unlock", 0, NULL, 'u' },
#ifdef RC_USER_SERVICES
longopts_USER_SERVICES
#endif
Expand Down Expand Up @@ -786,60 +784,6 @@ 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_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;
Expand All @@ -859,11 +803,6 @@ int main(int argc, char **argv)
int regen = 0;
bool nostop = false;
char *svcdir = NULL;
#ifdef RC_USER_SERVICES
int locknum = 0;
int lockval = 0;
bool lock = false;
#endif
#ifdef __linux__
char *proc;
char *p;
Expand Down Expand Up @@ -934,14 +873,6 @@ int main(int argc, char **argv)
printf("%s\n", systype);
exit(EXIT_SUCCESS);
/* NOTREACHED */
case 'l':
lock = true;
lockval = 1;
break;
case 'u':
lock = true;
lockval = -1;
break;
#ifdef RC_USER_SERVICES
case_RC_USER_SERVICES
#endif
Expand Down Expand Up @@ -975,19 +906,6 @@ int main(int argc, char **argv)
setenv("RC_PID", pidstr, 1);
free(pidstr);

#ifdef RC_USER_SERVICES
if (rc_is_user() && lock) {
/* if we are locking, reduce the count by 1,
* because we don't want to count ourselves */
locknum = inc_dec_lockfile(lockval) - lockval > 0 ? 1 : 0;

if (locknum > 0) {
einfov("Lock set, skipping");
return EXIT_SUCCESS;
}
}
#endif

svcdir = rc_svcdir();
xasprintf(&rc_stopping, "%s/%s", svcdir, RC_STOPPING_FOLDER);
xasprintf(&rc_starting, "%s/%s", svcdir, RC_STARTING_FOLDER);
Expand Down

0 comments on commit d2ce671

Please sign in to comment.