aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pam-freerdp.c58
1 files changed, 42 insertions, 16 deletions
diff --git a/src/pam-freerdp.c b/src/pam-freerdp.c
index bf533c4..189c82f 100644
--- a/src/pam-freerdp.c
+++ b/src/pam-freerdp.c
@@ -1,7 +1,10 @@
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
+#include <sys/types.h>
+#include <pwd.h>
#include <security/pam_modules.h>
#include <security/pam_modutil.h>
@@ -95,30 +98,40 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, const char **argv)
GET_ITEM(rdomain, PAM_TYPE_DOMAIN);
GET_ITEM(password, PAM_AUTHTOK);
+ int stdinpipe[2];
+ if (pipe(stdinpipe) != 0) {
+ retval = PAM_SYSTEM_ERR;
+ goto done;
+ }
+
/* At this point we should have the values, let's check the auth */
pid_t pid;
switch (pid = fork()) {
case 0: { /* child */
- char * args[13];
+ dup2(stdinpipe[0], 0);
+
+ char * args[7];
+
args[0] = XFREERDP;
args[1] = "--plugin";
args[2] = "rdpsnd.so";
args[3] = "--no-nla";
args[4] = "-f";
- args[5] = "--ignore-certificate"; /* TODO: Change when we set the home directory properly */
-
- /* TODO: Use stdin */
- args[6] = "-u";
- args[7] = ruser;
- args[8] = "-p";
- args[9] = password;
- args[10] = "-d";
- args[11] = rdomain;
-
- args[12] = NULL;
-
- /* TODO: Drop privs */
- /* TODO: Home directory environment to user's home */
+ args[5] = "--from-stdin";
+ args[6] = NULL;
+
+ struct passwd * pwdent = getpwnam(username);
+ if (pwdent == NULL) {
+ _exit(EXIT_FAILURE);
+ }
+
+ if (setgid(pwdent->pw_gid) < 0 || setuid(pwdent->pw_uid) < 0 ||
+ setegid(pwdent->pw_gid) < 0 || seteuid(pwdent->pw_uid) < 0) {
+ _exit(EXIT_FAILURE);
+ }
+
+ setenv("HOME", pwdent->pw_dir, 1);
+
execvp(args[0], args);
_exit(EXIT_FAILURE);
break;
@@ -129,7 +142,20 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, const char **argv)
}
default: {
int forkret = 0;
- if (waitpid(pid, &forkret, 0) < 0) {
+ int bytesout = 0;
+
+ bytesout += write(stdinpipe[1], ruser, strlen(ruser));
+ bytesout += write(stdinpipe[1], " ", 1);
+ bytesout += write(stdinpipe[1], password, strlen(password));
+ bytesout += write(stdinpipe[1], " ", 1);
+ bytesout += write(stdinpipe[1], rdomain, strlen(rdomain));
+ bytesout += write(stdinpipe[1], " ", 1);
+ bytesout += write(stdinpipe[1], rhost, strlen(rhost));
+ bytesout += write(stdinpipe[1], " ", 1);
+
+ close(stdinpipe[1]);
+
+ if (waitpid(pid, &forkret, 0) < 0 || bytesout == 0) {
retval = PAM_SYSTEM_ERR;
} else if (forkret == 0) {
retval = PAM_SUCCESS;