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