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