diff options
-rw-r--r-- | src/pam-freerdp.c | 58 |
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; |