e3004a52e4e1922383e3835f89fbab88f315f37d
[openafs.git] / src / pam / test_pam.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <roken.h>
14
15 #include <security/pam_appl.h>
16
17 static int my_conv(int num_msg, PAM_CONST struct pam_message **msg,
18                    struct pam_response **response, void *appdata_ptr);
19
20
21 static struct pam_conv pam_conv = { &my_conv, NULL };
22
23
24 static pam_handle_t *pamh;
25
26
27 static const char *service = "afstest";
28 static const char *new_envstring = "GOTHEREVIATESTPAM=1";
29 static const char *new_homestring = "HOME=/tmp";
30
31 #if defined(AFS_LINUX20_ENV) || defined(AFS_FBSD_ENV) || defined(AFS_DFBSD_ENV) || defined(AFS_NBSD_ENV) || defined(AFS_DARWIN_ENV)
32 #define getpassphrase getpass
33 #endif
34
35
36 int
37 main(int argc, char *argv[])
38 {
39     int authenticated = 0;
40     int retcode;
41     char *username;
42     int setcred = 1;
43
44     if (argc < 2 || argc > 3) {
45         fprintf(stderr, "Usage: %s [-u] <user>\n", argv[0]);
46         exit(1);
47     }
48     if (argc == 3) {
49         if (strcmp(argv[1], "-u") != 0) {
50             fprintf(stderr, "Usage: %s [-u] <user>\n", argv[0]);
51             exit(1);
52         }
53         /* service = "unixtest"; */
54         setcred = 0;
55         username = argv[2];
56     } else {
57         username = argv[1];
58     }
59
60     if ((retcode =
61          pam_start(service, username, &pam_conv, &pamh)) != PAM_SUCCESS) {
62         fprintf(stderr, "PAM error %d\n", retcode);
63         exit(1);
64     }
65
66     authenticated = ((retcode = pam_authenticate(pamh, 0)) == PAM_SUCCESS);
67
68     if (!authenticated) {
69         fprintf(stderr, "PAM couldn't authenticate you.\n");
70         pam_end(pamh, PAM_ABORT);
71         exit(1);
72     }
73
74     if ((retcode = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS) {
75         fprintf(stderr, "pam_acct_mgmt returned %d.\n", retcode);
76         pam_end(pamh, PAM_ABORT);
77         exit(1);
78     }
79
80     /* pam_open_session */
81
82     if (setcred)
83         if ((retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) {
84             fprintf(stderr, "pam_setcred returned %d.\n", retcode);
85             pam_end(pamh, PAM_ABORT);
86             exit(1);
87         }
88
89     if ((retcode = pam_open_session(pamh, PAM_SILENT)) != PAM_SUCCESS) {
90         fprintf(stderr, "pam_open_session returned %d.\n", retcode);
91         pam_end(pamh, PAM_ABORT);
92         exit(1);
93     }
94     pam_end(pamh, PAM_SUCCESS);
95
96     putenv((char *)new_envstring);
97     putenv((char *)new_homestring);
98     chdir("/tmp");
99     printf("Type exit to back out.\n");
100     return execl("/bin/csh", "/bin/csh", NULL);
101 }
102
103
104 static int
105 my_conv(int num_msg, PAM_CONST struct pam_message **msg, struct pam_response **response,
106         void *appdata_ptr)
107 {
108     PAM_CONST struct pam_message *m;
109     struct pam_response *r;
110     char *p;
111
112     m = *msg;
113     if (response) {
114         *response = calloc(num_msg, sizeof(struct pam_response));
115         if (*response == NULL)
116             return PAM_BUF_ERR;
117         r = *response;
118     } else {
119         r = NULL;
120     }
121
122     while (num_msg--) {
123         switch (m->msg_style) {
124         case PAM_PROMPT_ECHO_OFF:
125 #ifdef __hpux
126             /* ON HP's we still read 8 chars */
127             if (r)
128                 r->resp = strdup(getpass(m->msg));
129 #else
130             if (r)
131                 r->resp = strdup(getpassphrase(m->msg));
132 #endif
133             break;
134         case PAM_PROMPT_ECHO_ON:
135             fputs(m->msg, stdout);
136             if (r) {
137                 r->resp = malloc(PAM_MAX_RESP_SIZE);
138                 fgets(r->resp, PAM_MAX_RESP_SIZE, stdin);
139                 r->resp[PAM_MAX_RESP_SIZE - 1] = '\0';
140                 p = &r->resp[strlen(r->resp) - 1];
141                 while (*p == '\n' && p >= r->resp)
142                     *(p--) = '\0';
143             }
144             break;
145         case PAM_ERROR_MSG:
146             fputs(m->msg, stderr);
147             break;
148         case PAM_TEXT_INFO:
149             fputs(m->msg, stdout);
150             break;
151         default:
152             break;
153         }
154         m++;
155         if (r)
156             r++;
157     }
158     return PAM_SUCCESS;
159 }