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