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