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.test.
5   Linux only.
6 
7   Compile as
8 
9      gcc pam_mariadb_mtr.c -shared -lpam -fPIC -o pam_mariadb_mtr.so
10 
11   Install as appropriate (for example, in /lib/security/).
12   Create /etc/pam.d/mariadb_mtr with
13 =========================================================
14 auth            required        pam_mariadb_mtr.so pam_test
15 account         required        pam_permit.so
16 =========================================================
17 */
18 
19 #include <stdlib.h>
20 #include <string.h>
21 #include <security/pam_modules.h>
22 #include <security/pam_appl.h>
23 
24 #define N 3
25 
pam_sm_authenticate(pam_handle_t * pamh,int flags,int argc,const char * argv[])26 int pam_sm_authenticate(pam_handle_t *pamh, int flags,
27                         int argc, const char *argv[])
28 {
29   struct pam_conv *conv;
30   struct pam_response *resp = 0;
31   int pam_err, retval = PAM_SYSTEM_ERR;
32   struct pam_message msg[N] = {
33     { PAM_TEXT_INFO, "Challenge input first." },
34     { PAM_PROMPT_ECHO_ON, "Enter:" },
35     { PAM_ERROR_MSG, "Now, the magic number!" }
36   };
37   const struct pam_message *msgp[N] = { msg, msg+1, msg+2 };
38   char *r1 = 0, *r2 = 0;
39 
40   pam_err = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
41   if (pam_err != PAM_SUCCESS)
42     goto ret;
43 
44   pam_err = (*conv->conv)(N, msgp, &resp, conv->appdata_ptr);
45 
46   if (pam_err != PAM_SUCCESS || !resp || !((r1= resp[1].resp)))
47     goto ret;
48 
49   free(resp);
50 
51   msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
52   msg[0].msg = "PIN:";
53   pam_err = (*conv->conv)(1, msgp, &resp, conv->appdata_ptr);
54 
55   if (pam_err != PAM_SUCCESS || !resp || !((r2= resp[0].resp)))
56     goto ret;
57 
58   if (strlen(r1) == atoi(r2) % 100)
59     retval = PAM_SUCCESS;
60   else
61     retval = PAM_AUTH_ERR;
62 
63   if (argc > 0 && argv[0])
64     pam_set_item(pamh, PAM_USER, argv[0]);
65 
66 ret:
67   free(resp);
68   free(r1);
69   free(r2);
70   return retval;
71 }
72 
pam_sm_setcred(pam_handle_t * pamh,int flags,int argc,const char * argv[])73 int pam_sm_setcred(pam_handle_t *pamh, int flags,
74                    int argc, const char *argv[])
75 {
76 
77     return PAM_SUCCESS;
78 }
79 
80