diff --git a/src/auth.c b/src/auth.c index 228680e..7f324c6 100644 --- a/src/auth.c +++ b/src/auth.c @@ -1,10 +1,10 @@ #include #include -#include #include #include #include #include +#include #include #include @@ -29,64 +29,57 @@ int pam_conversation(int num_msg, const struct pam_message **msg, return PAM_SUCCESS; } +#define CHECK_PAM_RET(call) \ + ret = (call); \ + if (ret != PAM_SUCCESS) { \ + pam_end(pamh, ret); \ + return NULL; \ + } pam_handle_t *get_pamh(char *user, char *passwd) { pam_handle_t *pamh = NULL; struct pam_conv pamc = {pam_conversation, (void *)passwd}; - int retval; + int ret; - retval = pam_start("login", user, &pamc, &pamh); - if (retval != PAM_SUCCESS) { - return NULL; - } - - retval = pam_authenticate(pamh, 0); - if (retval != PAM_SUCCESS) { - pam_end(pamh, retval); - return NULL; - } - - retval = pam_acct_mgmt(pamh, 0); - if (retval != PAM_SUCCESS) { - pam_end(pamh, retval); - return NULL; - } - - retval = pam_setcred(pamh, PAM_ESTABLISH_CRED); - if (retval != PAM_SUCCESS) { - pam_end(pamh, retval); - return NULL; - } - - retval = pam_open_session(pamh, 0); - if (retval != PAM_SUCCESS) { - pam_end(pamh, retval); - return NULL; - } + CHECK_PAM_RET(pam_start("login", user, &pamc, &pamh)) + CHECK_PAM_RET(pam_authenticate(pamh, 0)) + CHECK_PAM_RET(pam_acct_mgmt(pamh, 0)) + CHECK_PAM_RET(pam_setcred(pamh, PAM_ESTABLISH_CRED)) + CHECK_PAM_RET(pam_open_session(pamh, 0)) + CHECK_PAM_RET(pam_setcred(pamh, PAM_REINITIALIZE_CRED)) return pamh; } +#undef CHECK_PAM_RET -void moarEnv(char* user, struct session session, struct passwd *pw) { +void moarEnv(char *user, struct session session, struct passwd *pw) { chdir(pw->pw_dir); setenv("HOME", pw->pw_dir, true); - setenv("USER", user, true); - setenv("LOGNAME", user, true); + setenv("USER", pw->pw_name, true); + setenv("SHELL", pw->pw_shell, true); + // TERM + setenv("LOGNAME", pw->pw_name, true); + // MAIL? + + // PATH? char *xdg_session_type; - if(session.type == SHELL) xdg_session_type = "tty"; - if(session.type == XORG) xdg_session_type = "wayland"; - if(session.type == WAYLAND) xdg_session_type = "x11"; + if (session.type == SHELL) + xdg_session_type = "tty"; + if (session.type == XORG) + xdg_session_type = "wayland"; + if (session.type == WAYLAND) + xdg_session_type = "x11"; setenv("XDG_SESSION_TYPE", xdg_session_type, true); - char* buf; - size_t bsize = snprintf(NULL, 0, "/run/user/%d", pw->pw_uid) + 1; - buf = malloc(bsize); - snprintf(buf, bsize, "/run/user/%d", pw->pw_uid); - setenv("XDG_RUNTIME_DIR", buf, true); - setenv("XDG_SESSION_CLASS", "user", true); - setenv("XDG_SESSION_ID", "1", true); + /*char *buf;*/ + /*size_t bsize = snprintf(NULL, 0, "/run/user/%d", pw->pw_uid) + 1;*/ + /*buf = malloc(bsize);*/ + /*snprintf(buf, bsize, "/run/user/%d", pw->pw_uid);*/ + /*setenv("XDG_RUNTIME_DIR", buf, true);*/ + /*setenv("XDG_SESSION_CLASS", "user", true);*/ + /*setenv("XDG_SESSION_ID", "1", true);*/ /*setenv("XDG_SESSION_DESKTOP", , true);*/ - setenv("XDG_SEAT", "seat0", true); + /*setenv("XDG_SEAT", "seat0", true);*/ } bool launch(char *user, char *passwd, struct session session, @@ -97,56 +90,46 @@ bool launch(char *user, char *passwd, struct session session, return false; } - gid_t *groups; - int ngroups = 0; - getgrouplist(user, pw->pw_gid, NULL, &ngroups); - groups = malloc(ngroups * sizeof(gid_t)); - if (groups == NULL) { - print_err("malloc error"); - return false; - } - if (getgrouplist(user, pw->pw_gid, groups, &ngroups) == -1) { - free(groups); - print_err("error fetching groups"); - return false; - } - pam_handle_t *pamh = get_pamh(user, passwd); if (pamh == NULL) { print_err("error on pam authentication"); return false; } - char **envlist = pam_getenvlist(pamh); - if (envlist == NULL) { - print_err("error getting pam env"); - return false; - } - + // point of no return + // TODO: move this to get_pamh, before first setcred, like login does if (cb != NULL) cb(); - // point of no return - int setgrps_ret = setgroups(ngroups, groups); - free(groups); - if (setgrps_ret == -1) { - perror("setgroups"); - exit(EXIT_FAILURE); - } - - if (setgid(pw->pw_gid) == -1) { + if(setgid(pw->pw_gid) == -1) { perror("setgid"); exit(EXIT_FAILURE); } + if(initgroups(user, pw->pw_gid) == -1) { + perror("init groups"); + exit(EXIT_FAILURE); + } + + char **envlist = pam_getenvlist(pamh); + if (envlist == NULL) { + perror("pam_getenvlist"); + exit(EXIT_FAILURE); + } + + // TODO: chown stdin to user if (setuid(pw->pw_uid) == -1) { perror("setuid"); exit(EXIT_FAILURE); } - for(uint i = 0; envlist[i] != NULL; i++) { + system("clear"); + printf("\x1b[0m\x1b[H"); + for (uint i = 0; envlist[i] != NULL; i++) { putenv(envlist[i]); } + // NOTE: path hotfix + putenv("PATH=/bin:/usr/bin"); free(envlist); moarEnv(user, session, pw); @@ -156,11 +139,13 @@ bool launch(char *user, char *passwd, struct session session, if (session.type == SHELL) { system("clear"); - execl(session.exec, NULL); + execlp(session.exec, session.exec, NULL); } else if (session.type == XORG || session.type == WAYLAND) { system("clear"); - execl(session.exec, NULL); + execlp(session.exec, session.exec, NULL); } + perror("execl error"); + fprintf(stderr, "failure calling session"); return true; }