diff options
-rw-r--r-- | src/pam-freerdp.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/src/pam-freerdp.c b/src/pam-freerdp.c index f234ca9..4714165 100644 --- a/src/pam-freerdp.c +++ b/src/pam-freerdp.c @@ -23,6 +23,7 @@ #include <sys/wait.h> #include <sys/types.h> #include <sys/socket.h> +#include <sys/stat.h> #include <sys/mman.h> #include <sys/un.h> #include <pwd.h> @@ -284,7 +285,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char ** argv memset(&socket_addr, 0, sizeof(struct sockaddr_un)); socket_addr.sun_family = AF_UNIX; strncpy(socket_addr.sun_path, pwdent->pw_dir, sizeof(socket_addr.sun_path) - 1); - strncpy(socket_addr.sun_path + strlen(pwdent->pw_dir), "/.freerdp-socket", sizeof(socket_addr.sun_path) - 1); + strncpy(socket_addr.sun_path + strlen(pwdent->pw_dir), "/.freerdp-socket", (sizeof(socket_addr.sun_path) - strlen(pwdent->pw_dir)) - 1); /* We bind the socket before forking so that we ensure that there isn't a race condition to get to it. Things will block @@ -295,6 +296,15 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char ** argv goto done; } + /* Set the socket file permissions to be 600 and the user and group + to be the guest user. NOTE: This won't protect on BSD */ + if (chmod(socket_addr.sun_path, S_IRUSR | S_IWUSR) != 0 || + chown(socket_addr.sun_path, pwdent->pw_uid, pwdent->pw_gid) != 0) { + close(socketfd); + retval = PAM_SYSTEM_ERR; + goto done; + } + /* Build this up as a buffer so we can just write it and see that very, very clearly */ int buffer_len = 0; @@ -304,10 +314,15 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char ** argv buffer_len += strlen(password) + 1; /* Add one for the NULL */ char * buffer = malloc(buffer_len); + /* Lock the buffer before writing */ + mlock(buffer, buffer_len); snprintf(buffer, buffer_len, "%s %s %s %s", ruser, password, rdomain, rhost); pid_t pid = fork(); if (pid == 0) { + /* Locks to carry over */ + mlock(buffer, buffer_len); + if (setgid(pwdent->pw_gid) < 0 || setuid(pwdent->pw_uid) < 0 || setegid(pwdent->pw_gid) < 0 || seteuid(pwdent->pw_uid) < 0) { _exit(EXIT_FAILURE); @@ -342,11 +357,14 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char ** argv } else if (pid < 0) { retval = PAM_SYSTEM_ERR; close(socketfd); - free(buffer); } else { session_pid = pid; } + memset(buffer, 0, buffer_len); + munlock(buffer, buffer_len); + free(buffer); + done: return retval; } @@ -364,12 +382,20 @@ pam_sm_close_session (pam_handle_t *pamh, int flags, int argc, const char **argv return PAM_IGNORE; } +/* LightDM likes to have this function around, but we don't need it as we + don't have a token hanging around. */ +PAM_EXTERN int +pam_sm_setcred (pam_handle_t *pamh, int flags, int argc, const char ** argv) +{ + return PAM_SUCCESS; +} + #ifdef PAM_STATIC struct pam_module _pam_freerdp_modstruct = { - "pam-freerdp", + "pam_freerdp", pam_sm_authenticate, - NULL, + pam_sm_setcred, NULL, pam_sm_open_session, pam_sm_close_session, |