aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pam-freerdp.c34
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,