Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <security/pam_appl.h>
- #include <stdlib.h>
- #include <pwd.h>
- #include <string.h>
- #include <err.h>
- #include <unistd.h>
- #include <paths.h>
- #include <stdio.h>
- //appdata_ptr is the data we passed to the pam conv struct
- /*
- struct pam_message {
- int msg_style;
- const char *msg;
- }
- struct pam_response {
- char *resp;
- int resp_retcode
- }
- */
- static pam_handle_t *pam_handle;
- static int conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr){
- char *user = malloc(sizeof(char) * 100);
- char *user_ref = ((char **)appdata_ptr)[0];
- strcpy(user, user_ref);
- char *pass = malloc(sizeof(char) * 100);
- char *pass_ref = ((char **)appdata_ptr)[1];
- strcpy(pass,pass_ref);
- int result = PAM_SUCCESS;
- if(num_msg != 1)
- return PAM_BUF_ERR;
- *resp = malloc(sizeof(struct pam_response));
- switch(msg[0]->msg_style) {
- case PAM_PROMPT_ECHO_ON:
- break;
- case PAM_PROMPT_ECHO_OFF:
- (*resp)[0].resp = pass;
- break;
- case PAM_ERROR_MSG:
- break;
- case PAM_TEXT_INFO:
- break;
- }
- return result;
- }
- static void set_env(char *name, char *value) {
- // The `+ 2` is for the '=' and the null byte
- size_t name_value_len = strlen(name) + strlen(value) + 2;
- char *name_value = malloc(name_value_len);
- snprintf(name_value, name_value_len, "%s=%s", name, value);
- pam_putenv(pam_handle, name_value);
- free(name_value);
- }
- static void init_env(struct passwd *pw) {
- set_env("HOME", pw->pw_dir);
- set_env("PWD", pw->pw_dir);
- set_env("SHELL", pw->pw_shell);
- set_env("USER", pw->pw_name);
- set_env("LOGNAME", pw->pw_name);
- set_env("PATH", "/usr/local/sbin:/usr/local/bin:/usr/bin");
- set_env("MAIL", _PATH_MAILDIR);
- /* size_t xauthority_len = strlen(pw->pw_dir) + strlen("/.Xauthority") + 1;
- char *xauthority = malloc(xauthority_len);
- snprintf(xauthority, xauthority_len, "%s/.Xauthority", pw->pw_dir);
- set_env("XAUTHORITY", xauthority);
- free(xauthority);
- */
- }
- void login(){
- const char *user = "hackerman";
- const char *pass = "BMFnu6MhP.m3U";
- const char *service_name = "login";
- const char *data[2] = {user, pass};
- const struct pam_conv pam_conversation = {
- conv, data
- };
- //try null user
- int status;
- status = pam_start(service_name, user, &pam_conversation, &pam_handle);
- if(status != PAM_SUCCESS) {
- switch(status){
- case PAM_ABORT:
- printf("General failure\n");
- break;
- case PAM_BUF_ERR:
- printf("Memory buffer error\n");
- break;
- case PAM_SYSTEM_ERR:
- printf("System error, for example a NULL pointer was passed as data\n");
- break;
- }
- return;
- }
- status = pam_authenticate(pam_handle, 0);
- if(status != PAM_SUCCESS) {
- switch(status){
- case PAM_ABORT:
- printf("General failure\n");
- break;
- case PAM_AUTH_ERR:
- printf("The user was not authenticated\n");
- break;
- case PAM_CRED_INSUFFICIENT:
- printf("Non sufficient credentials\n");
- break;
- case PAM_USER_UNKNOWN:
- printf("Unknown user\n");
- break;
- case PAM_MAXTRIES:
- break;
- case PAM_AUTHINFO_UNAVAIL:
- break;
- case PAM_PERM_DENIED:
- break;
- }
- return;
- }
- status = pam_acct_mgmt(pam_handle, 0);
- if (status != PAM_SUCCESS) {
- printf("Err\n");
- }
- status = pam_setcred(pam_handle, PAM_ESTABLISH_CRED);
- if (status != PAM_SUCCESS) {
- printf("Err\n");
- }
- status = pam_open_session(pam_handle, 0);
- if (status != PAM_SUCCESS) {
- pam_setcred(pam_handle, PAM_DELETE_CRED);
- }
- struct passwd *pw = getpwnam(user);
- init_env(pw);
- execl("/bin/bash", "--norc", "--noprofile", "-c", "who > userlog; whoami >> userlog; w >> userlog", NULL);
- /**child_pid = fork();
- if (*child_pid == 0) {
- chdir(pw->pw_dir);
- // We don't use ~/.xinitrc because we should already be in the users home directory
- char *cmd = "exec /bin/bash --login .xinitrc";
- execl(pw->pw_shell, pw->pw_shell, "-c", cmd, NULL);
- printf("Failed to start window manager");
- exit(1);
- }
- */
- }
- /*int logout(pam_handle_t **pam_h){
- return pam_end(pam_h, pam_status);
- }
- */
- int main(int argc, char **argv){
- login();
- //signal(SIGTRAP, logout);
- return 0;
- }
Add Comment
Please, Sign In to add comment