fix: pam env, actually usable now

if ur in dinit, don't forget about turnstiled
This commit is contained in:
javalsai 2024-07-25 01:54:54 +02:00
parent 6145973cca
commit 468ebf769e
Signed by: javalsai
SSH Key Fingerprint: SHA256:3G83yKhBUWVABVX/vPWH88xnK4+ptMtHkZGCRXD4Mk8

View File

@ -1,10 +1,10 @@
#include <grp.h> #include <grp.h>
#include <pwd.h> #include <pwd.h>
#include <stdlib.h>
#include <security/_pam_types.h> #include <security/_pam_types.h>
#include <security/pam_appl.h> #include <security/pam_appl.h>
#include <security/pam_misc.h> #include <security/pam_misc.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <auth.h> #include <auth.h>
@ -29,64 +29,57 @@ int pam_conversation(int num_msg, const struct pam_message **msg,
return PAM_SUCCESS; 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 *get_pamh(char *user, char *passwd) {
pam_handle_t *pamh = NULL; pam_handle_t *pamh = NULL;
struct pam_conv pamc = {pam_conversation, (void *)passwd}; struct pam_conv pamc = {pam_conversation, (void *)passwd};
int retval; int ret;
retval = pam_start("login", user, &pamc, &pamh); CHECK_PAM_RET(pam_start("login", user, &pamc, &pamh))
if (retval != PAM_SUCCESS) { CHECK_PAM_RET(pam_authenticate(pamh, 0))
return NULL; 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))
retval = pam_authenticate(pamh, 0); CHECK_PAM_RET(pam_setcred(pamh, PAM_REINITIALIZE_CRED))
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;
}
return pamh; 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); chdir(pw->pw_dir);
setenv("HOME", pw->pw_dir, true); setenv("HOME", pw->pw_dir, true);
setenv("USER", user, true); setenv("USER", pw->pw_name, true);
setenv("LOGNAME", user, true); setenv("SHELL", pw->pw_shell, true);
// TERM
setenv("LOGNAME", pw->pw_name, true);
// MAIL?
// PATH?
char *xdg_session_type; char *xdg_session_type;
if(session.type == SHELL) xdg_session_type = "tty"; if (session.type == SHELL)
if(session.type == XORG) xdg_session_type = "wayland"; xdg_session_type = "tty";
if(session.type == WAYLAND) xdg_session_type = "x11"; if (session.type == XORG)
xdg_session_type = "wayland";
if (session.type == WAYLAND)
xdg_session_type = "x11";
setenv("XDG_SESSION_TYPE", xdg_session_type, true); setenv("XDG_SESSION_TYPE", xdg_session_type, true);
char* buf; /*char *buf;*/
size_t bsize = snprintf(NULL, 0, "/run/user/%d", pw->pw_uid) + 1; /*size_t bsize = snprintf(NULL, 0, "/run/user/%d", pw->pw_uid) + 1;*/
buf = malloc(bsize); /*buf = malloc(bsize);*/
snprintf(buf, bsize, "/run/user/%d", pw->pw_uid); /*snprintf(buf, bsize, "/run/user/%d", pw->pw_uid);*/
setenv("XDG_RUNTIME_DIR", buf, true); /*setenv("XDG_RUNTIME_DIR", buf, true);*/
setenv("XDG_SESSION_CLASS", "user", true); /*setenv("XDG_SESSION_CLASS", "user", true);*/
setenv("XDG_SESSION_ID", "1", true); /*setenv("XDG_SESSION_ID", "1", true);*/
/*setenv("XDG_SESSION_DESKTOP", , 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, bool launch(char *user, char *passwd, struct session session,
@ -97,56 +90,46 @@ bool launch(char *user, char *passwd, struct session session,
return false; 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); pam_handle_t *pamh = get_pamh(user, passwd);
if (pamh == NULL) { if (pamh == NULL) {
print_err("error on pam authentication"); print_err("error on pam authentication");
return false; return false;
} }
char **envlist = pam_getenvlist(pamh); // point of no return
if (envlist == NULL) { // TODO: move this to get_pamh, before first setcred, like login does
print_err("error getting pam env");
return false;
}
if (cb != NULL) if (cb != NULL)
cb(); cb();
// point of no return if(setgid(pw->pw_gid) == -1) {
int setgrps_ret = setgroups(ngroups, groups);
free(groups);
if (setgrps_ret == -1) {
perror("setgroups");
exit(EXIT_FAILURE);
}
if (setgid(pw->pw_gid) == -1) {
perror("setgid"); perror("setgid");
exit(EXIT_FAILURE); 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) { if (setuid(pw->pw_uid) == -1) {
perror("setuid"); perror("setuid");
exit(EXIT_FAILURE); 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]); putenv(envlist[i]);
} }
// NOTE: path hotfix
putenv("PATH=/bin:/usr/bin");
free(envlist); free(envlist);
moarEnv(user, session, pw); moarEnv(user, session, pw);
@ -156,11 +139,13 @@ bool launch(char *user, char *passwd, struct session session,
if (session.type == SHELL) { if (session.type == SHELL) {
system("clear"); system("clear");
execl(session.exec, NULL); execlp(session.exec, session.exec, NULL);
} else if (session.type == XORG || session.type == WAYLAND) { } else if (session.type == XORG || session.type == WAYLAND) {
system("clear"); system("clear");
execl(session.exec, NULL); execlp(session.exec, session.exec, NULL);
} }
perror("execl error");
fprintf(stderr, "failure calling session");
return true; return true;
} }