Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
libpam-privtmp (0.1-2) unstable; urgency=low

* Autocreate user's tmp directory if doesn't exist.

-- Eugeny Sokolov <esokolov@netangels.ru> Sun, 2 May 2017 19:44:24 +0600

libpam-privtmp (0.1-1) unstable; urgency=low

* Initial release.
Expand Down
44 changes: 28 additions & 16 deletions pam_privtmp.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <errno.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
Expand Down Expand Up @@ -30,7 +32,6 @@ void to_log(int prio, const char *format, ...)
closelog();
}


int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
const char *PAM_user = NULL;
Expand All @@ -56,27 +57,38 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **ar

snprintf(usertmp, 200, "%s/tmp", pw->pw_dir);
ret = stat(usertmp, &statbuf);
if (ret == 0 && S_ISDIR(statbuf.st_mode)) {
// Try to unshare
ret = unshare(CLONE_NEWNS);
if (ret) {
to_log(LOG_ERR, "failed to unshare mounts namespace for user %s\n", pw->pw_name);
return PAM_SESSION_ERR;
}
// Mark / as slave
ret = mount("", "/", "none", MS_REC|MS_SLAVE, NULL);
if (ret != 0 || ! S_ISDIR(statbuf.st_mode)) {
to_log(LOG_INFO, "user's temp dir not found: '%s'. Trying to create it.\n", usertmp);
ret = mkdir(usertmp, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
if (ret) {
to_log(LOG_ERR, "failed to mark root tree as rslave for user %s\n", pw->pw_name);
to_log(LOG_ERR, "Can't create user's temp dir '%s'. %s\n", usertmp, strerror(errno));
return PAM_SESSION_ERR;
}
// Mount user's tmp
ret = mount(usertmp, "/tmp", "none", MS_BIND, NULL);
ret = chown(usertmp, pw->pw_uid, pw->pw_gid);
if (ret) {
to_log(LOG_ERR, "failed to bind mount temp dir for user %s\n", pw->pw_name);
to_log(LOG_ERR, "can't chown user's temp directory '%s' for user '%s'\n", usertmp, pw->pw_name);
return PAM_SESSION_ERR;
}
} else
to_log(LOG_INFO, "user's temp dir not found: %s\n", usertmp);
}

// Try to unshare
ret = unshare(CLONE_NEWNS);
if (ret) {
to_log(LOG_ERR, "failed to unshare mounts namespace for user %s\n", pw->pw_name);
return PAM_SESSION_ERR;
}
// Mark / as slave
ret = mount("", "/", "none", MS_REC|MS_SLAVE, NULL);
if (ret) {
to_log(LOG_ERR, "failed to mark root tree as rslave for user %s\n", pw->pw_name);
return PAM_SESSION_ERR;
}
// Mount user's tmp
ret = mount(usertmp, "/tmp", "none", MS_BIND, NULL);
if (ret) {
to_log(LOG_ERR, "failed to bind mount temp dir for user %s\n", pw->pw_name);
return PAM_SESSION_ERR;
}

return PAM_SUCCESS;
}
Expand Down