Skip to content

Commit

Permalink
pam_openrc
Browse files Browse the repository at this point in the history
  • Loading branch information
navi-desu committed Oct 27, 2024
1 parent 033af2f commit 7279dba
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/pam_openrc/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
if get_option('pam') and pam_dep.found()
shared_module('pam_openrc',
['pam_openrc.c', misc_c, version_h],
c_args : [cc_branding_flags],
dependencies : [pam_dep],
name_prefix : '',
link_with : [libeinfo, librc],
include_directories : [incdir, einfo_incdir, rc_incdir],
install : true,
install_dir : libdir / 'security')
endif
76 changes: 76 additions & 0 deletions src/pam_openrc/pam_openrc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include <fcntl.h>
#include <pwd.h>
#include <security/pam_modules.h>
#include <sys/file.h>
#include <syslog.h>
#include <unistd.h>

#include <einfo.h>
#include <rc.h>
#include "helpers.h"

static int lock_user(struct passwd *pw) {
char *file;
int fd;

xasprintf(&file, "%s/users/%s", rc_svcdir(), pw->pw_name);
elog(LOG_INFO, "Opening %s.", file);
fd = open(file, O_RDWR | O_CREAT | O_CLOEXEC, 0664);
free(file);

if (fd == -1 || flock(fd, LOCK_EX | LOCK_NB) == -1) {
elog(LOG_ERR, "Failed to lock lockfile.");
return -1;
}

return fd;
}

static int exec_openrc(pam_handle_t *pamh, bool start) {
const char *user, *session;
struct passwd *pw;
char *elog_name;
int lockfile;

if (pam_get_item(pamh, PAM_SERVICE, (const void **)&session) != PAM_SUCCESS)
return PAM_SESSION_ERR;
/* noop if the current stack was started by openrc-user, to avoid looping */
if (strcmp(session, "openrc-user") == 0)
return PAM_SUCCESS;

if (pam_get_user(pamh, &user, "") != PAM_SUCCESS || !(pw = getpwnam(user)))
return PAM_SESSION_ERR;

if (pw->pw_uid == 0)
return PAM_SUCCESS;

xasprintf(&elog_name, "pam_openrc.%s", pw->pw_name);
setenv("EINFO_LOG", elog_name, true);
free(elog_name);

if ((lockfile = lock_user(pw)) == -1) {
unsetenv("EINFO_LOG");
return PAM_SESSION_ERR;
}

if (fork() == 0) {
execl(RC_LIBEXECDIR "/bin/openrc-user", "openrc-user", pw->pw_name, start ? "start" : "stop", NULL);
elog(LOG_ERR, "Failed to exec openrc-user");
close(lockfile);
exit(1);
}

close(lockfile);
unsetenv("EINFO_LOG");
return PAM_SUCCESS;
}

PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) {
(void) flags; (void) argc; (void) argv;
return exec_openrc(pamh, true);
}

PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) {
(void) flags; (void) argc; (void) argv;
return exec_openrc(pamh, false);
}

0 comments on commit 7279dba

Please sign in to comment.