1 /*
2   This code is in the public domain and has no copyright.
3 
4   Pam module to test pam authentication plugin. Used in pam tests.
5   Linux only.
6 
7   Install as appropriate (for example, in /lib/security/).
8   see also mariadb_mtr.conf
9 */
10 
11 #include <stdlib.h>
12 #include <string.h>
13 #include <security/pam_modules.h>
14 #include <security/pam_appl.h>
15 
16 #define N 3
17 
pam_sm_authenticate(pam_handle_t * pamh,int flags,int argc,const char * argv[])18 int pam_sm_authenticate(pam_handle_t *pamh, int flags __attribute__((unused)),
19                         int argc, const char *argv[])
20 {
21   struct pam_conv *conv;
22   struct pam_response *resp = 0;
23   int pam_err, retval = PAM_SYSTEM_ERR;
24   struct pam_message msg[N] = {
25     { PAM_TEXT_INFO, (char*)"Challenge input first." },
26     { PAM_PROMPT_ECHO_OFF, (char*)"Enter:" },
27     { PAM_ERROR_MSG, (char*)"Now, the magic number!" }
28   };
29   const struct pam_message *msgp[N] = { msg, msg+1, msg+2 };
30   char *r1 = 0, *r2 = 0;
31 
32   pam_err = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
33   if (pam_err != PAM_SUCCESS)
34     goto ret;
35 
36   pam_err = (*conv->conv)(N, msgp, &resp, conv->appdata_ptr);
37 
38   if (pam_err != PAM_SUCCESS || !resp || !((r1= resp[1].resp)))
39     goto ret;
40 
41   if (strcmp(r1, "cleartext good") == 0)
42     retval = PAM_SUCCESS;
43   else if (strcmp(r1, "cleartext bad") == 0)
44     retval = PAM_AUTH_ERR;
45   else
46   {
47     free(resp);
48     msg[0].msg_style = PAM_PROMPT_ECHO_ON;
49     msg[0].msg = (char*)"PIN:";
50     pam_err = (*conv->conv)(1, msgp, &resp, conv->appdata_ptr);
51 
52     if (pam_err != PAM_SUCCESS || !resp || !((r2= resp[0].resp)))
53       goto ret;
54 
55     /* Produce the crash for testing purposes. */
56     if (strcmp(r1, "crash pam module") == 0 && atoi(r2) == 616)
57       abort();
58 
59     if (strlen(r1) == (size_t)atoi(r2) % 100)
60       retval = PAM_SUCCESS;
61     else
62       retval = PAM_AUTH_ERR;
63   }
64 
65   if (argc > 0 && argv[0])
66     pam_set_item(pamh, PAM_USER, argv[0]);
67 
68 ret:
69   free(resp);
70   free(r1);
71   free(r2);
72   return retval;
73 }
74 
pam_sm_setcred(pam_handle_t * pamh,int flags,int argc,const char * argv[])75 int pam_sm_setcred(pam_handle_t *pamh __attribute__((unused)),
76                    int flags __attribute__((unused)),
77                    int argc __attribute__((unused)),
78                    const char *argv[] __attribute__((unused)))
79 {
80 
81     return PAM_SUCCESS;
82 }
83 
84