Skip to content

Instantly share code, notes, and snippets.

@rmohr
Last active April 22, 2024 08:03
Show Gist options
  • Save rmohr/a131ae3b095095aff134 to your computer and use it in GitHub Desktop.
Save rmohr/a131ae3b095095aff134 to your computer and use it in GitHub Desktop.
Absolutely minimalistic pam authentication example
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <unistd.h> /* getpass */
#include <security/pam_appl.h> /* pam_start, pam_conv, pam_end, ... */
#define TRY(x) ret = (x); printf("PAM: %s\n", pam_strerror(handle, ret)); if (ret != PAM_SUCCESS) goto finally
int test_conv(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr){
const struct pam_message* msg_ptr = *msg;
struct pam_response * resp_ptr = NULL;
int x = 0;
*resp = calloc(sizeof(struct pam_response), num_msg);
for (x = 0; x < num_msg; x++, msg_ptr++){
char* resp_str;
switch (msg_ptr->msg_style){
case PAM_PROMPT_ECHO_OFF:
case PAM_PROMPT_ECHO_ON:
resp_str = getpass(msg_ptr->msg);
resp[x]->resp= strdup(resp_str);
break;
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
printf("PAM: %s\n", msg_ptr->msg);
break;
default:
assert(0);
}
}
return PAM_SUCCESS;
}
int main(int argc, char** argv){
int len = 1000;
const char service[] = "passwd";
char user[len];
const char *changed_username = NULL;
struct pam_conv conv;
char resp_str[len];
conv.conv=test_conv;
pam_handle_t* handle;
int ret;
printf("Username: ");
fgets(user,len, stdin);
strtok(user, "\n");
TRY( pam_start(service, user, &conv, &handle ));
TRY( pam_authenticate(handle, 0));
TRY( pam_acct_mgmt(handle, 0));
TRY( pam_get_item(handle, PAM_USER,(const void**) &changed_username ));
if (changed_username != NULL) {
printf("PAM: %s\n", changed_username);
}
finally:
pam_end(handle, ret);
return ret;
}
@dimaweber
Copy link

dimaweber commented Apr 22, 2024

should't it be

(*resp)[idx].resp=strdup(...)

?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment