main.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #include <assert.h>
  2. #include <security/pam_appl.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <unistd.h> // getpass
  7. // apt install libpam0g-dev
  8. // compile with flag -lpam
  9. char *pam_get_str(const pam_handle_t *pamh, int item_type) {
  10. char *str;
  11. assert(pam_get_item(pamh, item_type, (const void **)&str) == PAM_SUCCESS);
  12. return str;
  13. }
  14. int conv(int num_msg, const struct pam_message **msg,
  15. struct pam_response **resp, void *appdata_ptr) {
  16. // [...] *resp is a struct pam_response array [...]
  17. *resp = calloc(num_msg, sizeof(struct pam_response));
  18. assert(*resp != NULL);
  19. for (int i = 0; i < num_msg; i++) {
  20. // getpass returns a statically allocated string
  21. (*resp)[i].resp = strdup(getpass(msg[i]->msg));
  22. }
  23. return PAM_SUCCESS;
  24. }
  25. int main(int argc, char **argv) {
  26. const char *user = NULL;
  27. const char *service_name;
  28. if (argc > 1) {
  29. service_name = argv[1];
  30. } else {
  31. service_name = "test";
  32. }
  33. const struct pam_conv pam_conversation = {conv, NULL};
  34. pam_handle_t *pamh; // blind structure, see security/_pam_types.h
  35. int status = pam_start(service_name, NULL, &pam_conversation, &pamh);
  36. if (status != PAM_SUCCESS) {
  37. fprintf(stderr, "pam_start: %s\n", pam_strerror(pamh, PAM_SYSTEM_ERR));
  38. return 1;
  39. } else {
  40. printf("PAM service name \"%s\"\n", pam_get_str(pamh, PAM_SERVICE));
  41. int status = pam_authenticate(pamh, 0);
  42. if (status != PAM_SUCCESS) {
  43. fprintf(stderr, "pam_authenticate: %s\n", pam_strerror(pamh, status));
  44. } else {
  45. char *user = pam_get_str(pamh, PAM_USER);
  46. fprintf(stderr, "Successfully authenticated user \"%s\".\n", user);
  47. fprintf(stdout, "%s\n", user);
  48. }
  49. assert(pam_end(pamh, status) == PAM_SUCCESS);
  50. return status == PAM_SUCCESS ? 0 : 2;
  51. }
  52. }