summaryrefslogtreecommitdiff
path: root/auth-pam.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth-pam.c')
-rw-r--r--auth-pam.c113
1 files changed, 70 insertions, 43 deletions
diff --git a/auth-pam.c b/auth-pam.c
index e3f4c4252..174d289f3 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -13,12 +13,16 @@
13#include "xmalloc.h" 13#include "xmalloc.h"
14#include "servconf.h" 14#include "servconf.h"
15 15
16RCSID("$Id: auth-pam.c,v 1.4 2000/04/29 14:47:29 damien Exp $"); 16RCSID("$Id: auth-pam.c,v 1.5 2000/05/31 01:20:12 damien Exp $");
17
18#define NEW_AUTHTOK_MSG \
19 "Warning: You password has expired, please change it now"
17 20
18/* Callbacks */ 21/* Callbacks */
19static int pamconv(int num_msg, const struct pam_message **msg, 22static int pamconv(int num_msg, const struct pam_message **msg,
20 struct pam_response **resp, void *appdata_ptr); 23 struct pam_response **resp, void *appdata_ptr);
21void pam_cleanup_proc(void *context); 24void pam_cleanup_proc(void *context);
25void pam_msg_cat(const char *msg);
22 26
23/* module-local variables */ 27/* module-local variables */
24static struct pam_conv conv = { 28static struct pam_conv conv = {
@@ -27,7 +31,7 @@ static struct pam_conv conv = {
27}; 31};
28static struct pam_handle_t *pamh = NULL; 32static struct pam_handle_t *pamh = NULL;
29static const char *pampasswd = NULL; 33static const char *pampasswd = NULL;
30static char *pamconv_msg = NULL; 34static char *pam_msg = NULL;
31 35
32/* PAM conversation function. This is really a kludge to get the password */ 36/* PAM conversation function. This is really a kludge to get the password */
33/* into PAM and to pick up any messages generated by PAM into pamconv_msg */ 37/* into PAM and to pick up any messages generated by PAM into pamconv_msg */
@@ -36,8 +40,6 @@ static int pamconv(int num_msg, const struct pam_message **msg,
36{ 40{
37 struct pam_response *reply; 41 struct pam_response *reply;
38 int count; 42 int count;
39 size_t msg_len;
40 char *p;
41 43
42 /* PAM will free this later */ 44 /* PAM will free this later */
43 reply = malloc(num_msg * sizeof(*reply)); 45 reply = malloc(num_msg * sizeof(*reply));
@@ -54,31 +56,14 @@ static int pamconv(int num_msg, const struct pam_message **msg,
54 reply[count].resp_retcode = PAM_SUCCESS; 56 reply[count].resp_retcode = PAM_SUCCESS;
55 reply[count].resp = xstrdup(pampasswd); 57 reply[count].resp = xstrdup(pampasswd);
56 break; 58 break;
57
58 case PAM_TEXT_INFO: 59 case PAM_TEXT_INFO:
59 reply[count].resp_retcode = PAM_SUCCESS; 60 reply[count].resp_retcode = PAM_SUCCESS;
60 reply[count].resp = xstrdup(""); 61 reply[count].resp = xstrdup("");
61 62
62 if (msg[count]->msg == NULL) 63 if (msg[count]->msg != NULL)
63 break; 64 pam_msg_cat(msg[count]->msg);
64 65
65 debug("Adding PAM message: %s", msg[count]->msg);
66
67 msg_len = strlen(msg[count]->msg);
68 if (pamconv_msg) {
69 size_t n = strlen(pamconv_msg);
70 pamconv_msg = xrealloc(pamconv_msg, n + msg_len + 2);
71 p = pamconv_msg + n;
72 } else {
73 pamconv_msg = p = xmalloc(msg_len + 2);
74 }
75 memcpy(p, msg[count]->msg, msg_len);
76 p[msg_len] = '\n';
77 p[msg_len + 1] = '\0';
78 break; 66 break;
79
80 case PAM_PROMPT_ECHO_ON:
81 case PAM_ERROR_MSG:
82 default: 67 default:
83 free(reply); 68 free(reply);
84 return PAM_CONV_ERR; 69 return PAM_CONV_ERR;
@@ -100,19 +85,19 @@ void pam_cleanup_proc(void *context)
100 pam_retval = pam_close_session((pam_handle_t *)pamh, 0); 85 pam_retval = pam_close_session((pam_handle_t *)pamh, 0);
101 if (pam_retval != PAM_SUCCESS) { 86 if (pam_retval != PAM_SUCCESS) {
102 log("Cannot close PAM session: %.200s", 87 log("Cannot close PAM session: %.200s",
103 PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); 88 PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
104 } 89 }
105 90
106 pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_DELETE_CRED); 91 pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_DELETE_CRED);
107 if (pam_retval != PAM_SUCCESS) { 92 if (pam_retval != PAM_SUCCESS) {
108 log("Cannot delete credentials: %.200s", 93 log("Cannot delete credentials: %.200s",
109 PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); 94 PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
110 } 95 }
111 96
112 pam_retval = pam_end((pam_handle_t *)pamh, pam_retval); 97 pam_retval = pam_end((pam_handle_t *)pamh, pam_retval);
113 if (pam_retval != PAM_SUCCESS) { 98 if (pam_retval != PAM_SUCCESS) {
114 log("Cannot release PAM authentication: %.200s", 99 log("Cannot release PAM authentication: %.200s",
115 PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); 100 PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
116 } 101 }
117 } 102 }
118} 103}
@@ -135,7 +120,8 @@ int auth_pam_password(struct passwd *pw, const char *password)
135 120
136 pam_retval = pam_authenticate((pam_handle_t *)pamh, 0); 121 pam_retval = pam_authenticate((pam_handle_t *)pamh, 0);
137 if (pam_retval == PAM_SUCCESS) { 122 if (pam_retval == PAM_SUCCESS) {
138 debug("PAM Password authentication accepted for user \"%.100s\"", pw->pw_name); 123 debug("PAM Password authentication accepted for user \"%.100s\"",
124 pw->pw_name);
139 return 1; 125 return 1;
140 } else { 126 } else {
141 debug("PAM Password authentication for \"%.100s\" failed: %s", 127 debug("PAM Password authentication for \"%.100s\" failed: %s",
@@ -148,26 +134,36 @@ int auth_pam_password(struct passwd *pw, const char *password)
148int do_pam_account(char *username, char *remote_user) 134int do_pam_account(char *username, char *remote_user)
149{ 135{
150 int pam_retval; 136 int pam_retval;
151 137
152 debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname()); 138 debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname());
153 pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST, 139 pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST,
154 get_canonical_hostname()); 140 get_canonical_hostname());
155 if (pam_retval != PAM_SUCCESS) { 141 if (pam_retval != PAM_SUCCESS) {
156 fatal("PAM set rhost failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); 142 fatal("PAM set rhost failed: %.200s",
143 PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
157 } 144 }
158 145
159 if (remote_user != NULL) { 146 if (remote_user != NULL) {
160 debug("PAM setting ruser to \"%.200s\"", remote_user); 147 debug("PAM setting ruser to \"%.200s\"", remote_user);
161 pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user); 148 pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user);
162 if (pam_retval != PAM_SUCCESS) { 149 if (pam_retval != PAM_SUCCESS) {
163 fatal("PAM set ruser failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); 150 fatal("PAM set ruser failed: %.200s",
151 PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
164 } 152 }
165 } 153 }
166 154
167 pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0); 155 pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0);
168 if (pam_retval != PAM_SUCCESS) { 156 switch (pam_retval) {
169 log("PAM rejected by account configuration: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); 157 case PAM_SUCCESS:
170 return(0); 158 /* This is what we want */
159 break;
160 case PAM_NEW_AUTHTOK_REQD:
161 pam_msg_cat(NEW_AUTHTOK_MSG);
162 break;
163 default:
164 log("PAM rejected by account configuration: %.200s",
165 PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
166 return(0);
171 } 167 }
172 168
173 return(1); 169 return(1);
@@ -181,13 +177,17 @@ void do_pam_session(char *username, const char *ttyname)
181 if (ttyname != NULL) { 177 if (ttyname != NULL) {
182 debug("PAM setting tty to \"%.200s\"", ttyname); 178 debug("PAM setting tty to \"%.200s\"", ttyname);
183 pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname); 179 pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname);
184 if (pam_retval != PAM_SUCCESS) 180 if (pam_retval != PAM_SUCCESS) {
185 fatal("PAM set tty failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); 181 fatal("PAM set tty failed: %.200s",
182 PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
183 }
186 } 184 }
187 185
188 pam_retval = pam_open_session((pam_handle_t *)pamh, 0); 186 pam_retval = pam_open_session((pam_handle_t *)pamh, 0);
189 if (pam_retval != PAM_SUCCESS) 187 if (pam_retval != PAM_SUCCESS) {
190 fatal("PAM session setup failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); 188 fatal("PAM session setup failed: %.200s",
189 PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
190 }
191} 191}
192 192
193/* Set PAM credentials */ 193/* Set PAM credentials */
@@ -197,8 +197,10 @@ void do_pam_setcred()
197 197
198 debug("PAM establishing creds"); 198 debug("PAM establishing creds");
199 pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_ESTABLISH_CRED); 199 pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_ESTABLISH_CRED);
200 if (pam_retval != PAM_SUCCESS) 200 if (pam_retval != PAM_SUCCESS) {
201 fatal("PAM setcred failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); 201 fatal("PAM setcred failed: %.200s",
202 PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
203 }
202} 204}
203 205
204/* Cleanly shutdown PAM */ 206/* Cleanly shutdown PAM */
@@ -217,9 +219,12 @@ void start_pam(struct passwd *pw)
217 219
218 pam_retval = pam_start(SSHD_PAM_SERVICE, pw->pw_name, &conv, 220 pam_retval = pam_start(SSHD_PAM_SERVICE, pw->pw_name, &conv,
219 (pam_handle_t**)&pamh); 221 (pam_handle_t**)&pamh);
220 if (pam_retval != PAM_SUCCESS)
221 fatal("PAM initialisation failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
222 222
223 if (pam_retval != PAM_SUCCESS) {
224 fatal("PAM initialisation failed: %.200s",
225 PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
226 }
227
223 fatal_add_cleanup(&pam_cleanup_proc, NULL); 228 fatal_add_cleanup(&pam_cleanup_proc, NULL);
224} 229}
225 230
@@ -237,8 +242,30 @@ char **fetch_pam_environment(void)
237/* or account checking to stderr */ 242/* or account checking to stderr */
238void print_pam_messages(void) 243void print_pam_messages(void)
239{ 244{
240 if (pamconv_msg != NULL) 245 if (pam_msg != NULL)
241 fprintf(stderr, pamconv_msg); 246 fprintf(stderr, pam_msg);
247}
248
249/* Append a message to the PAM message buffer */
250void pam_msg_cat(const char *msg)
251{
252 char *p;
253 size_t new_msg_len;
254 size_t pam_msg_len;
255
256 new_msg_len = strlen(msg);
257
258 if (pam_msg) {
259 pam_msg_len = strlen(pam_msg);
260 pam_msg = xrealloc(pam_msg, new_msg_len + pam_msg_len + 2);
261 p = pam_msg + pam_msg_len;
262 } else {
263 pam_msg = p = xmalloc(new_msg_len + 2);
264 }
265
266 memcpy(p, msg, new_msg_len);
267 p[new_msg_len] = '\n';
268 p[new_msg_len + 1] = '\0';
242} 269}
243 270
244#endif /* USE_PAM */ 271#endif /* USE_PAM */