Fix copying conditions.
[shishi.git] / extra / pam_shishi / pam_shishi.c
blobe4cda2f4667f362b915567249587d34e70fafda0
1 /* pam_shishi.c PAM module using Shishi.
2 * Copyright (C) 2002, 2003 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #if HAVE_CONFIG_H
23 #include "config.h"
24 #endif
26 #ifdef STDC_HEADERS
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <ctype.h>
31 #endif
33 #include <vasprintf.h>
34 #include <shishi.h>
36 /* Libtool defines PIC for shared objects */
37 #ifndef PIC
38 #define PAM_STATIC
39 #endif
41 /* These #defines must be present according to PAM documentation. */
42 #define PAM_SM_AUTH
43 #define PAM_SM_ACCOUNT
44 #define PAM_SM_SESSION
45 #define PAM_SM_PASSWORD
47 #ifdef HAVE_SECURITY_PAM_APPL_H
48 #include <security/pam_appl.h>
49 #endif
50 #ifdef HAVE_SECURITY_PAM_MODULES_H
51 #include <security/pam_modules.h>
52 #endif
54 #if defined(DEBUG_PAM) && defined(HAVE_SECURITY__PAM_MACROS_H)
55 #define DEBUG
56 #include <security/_pam_macros.h>
57 #else
58 #define D(x) /* nothing */
59 #endif
61 #ifndef PAM_EXTERN
62 #ifdef PAM_STATIC
63 #define PAM_EXTERN static
64 #else
65 #define PAM_EXTERN extern
66 #endif
67 #endif
69 PAM_EXTERN int
70 pam_sm_authenticate (pam_handle_t * pamh,
71 int flags, int argc, const char **argv)
73 Shishi *h = NULL;
74 Shishi_key *key = NULL;
75 Shishi_tkt *tkt = NULL;
76 int retval, rc;
77 const char *user = NULL;
78 const char *password = NULL;
79 int i;
80 struct pam_conv *conv;
81 struct pam_message *pmsg[1], msg[1];
82 struct pam_response *resp;
83 int nargs = 1;
85 D (("called."));
86 D (("flags %d argc %d", flags, argc));
87 for (i = 0; i < argc; i++)
88 D (("argv[%d]=%s", i, argv[i]));
90 rc = shishi_init (&h);
91 if (rc != SHISHI_OK)
93 h = NULL;
94 D (("shishi_init() failed: %s", shishi_strerror (retval)));
95 retval = PAM_AUTHINFO_UNAVAIL;
96 goto done;
99 retval = pam_get_user (pamh, &user, NULL);
100 if (retval != PAM_SUCCESS)
102 D (("get user returned error: %s", pam_strerror (pamh, retval)));
103 goto done;
105 D (("get user returned: %s", user));
107 shishi_principal_default_set (h, user);
109 retval = pam_get_item (pamh, PAM_AUTHTOK, (const void **) &password);
110 if (retval != PAM_SUCCESS)
112 D (("get password returned error: %s", pam_strerror (pamh, retval)));
113 goto done;
115 D (("get password returned: %s", password));
117 if (password == NULL)
119 retval = pam_get_item (pamh, PAM_CONV, (const void **) &conv);
120 if (retval != PAM_SUCCESS)
122 D (("get conv returned error: %s", pam_strerror (pamh, retval)));
123 goto done;
126 pmsg[0] = &msg[0];
127 asprintf ((char **) &msg[0].msg, "Password for `%s@%s': ",
128 shishi_principal_default (h), shishi_realm_default (h));
129 msg[0].msg_style = PAM_PROMPT_ECHO_ON;
130 resp = NULL;
132 retval = conv->conv (nargs, (const struct pam_message **) pmsg,
133 &resp, conv->appdata_ptr);
135 free ((char *) msg[0].msg);
137 if (retval != PAM_SUCCESS)
139 D (("conv returned error: %s", pam_strerror (pamh, retval)));
140 goto done;
143 D (("conv returned: %s", resp->resp));
145 password = resp->resp;
148 tkt = shishi_tkts_get_for_localservicepasswd (shishi_tkts_default (h),
149 "host", password);
150 if (tkt == NULL)
152 D (("TGS exchange failed: %s\n", shishi_error (h)));
153 retval = PAM_AUTHINFO_UNAVAIL;
154 goto done;
157 key = shishi_hostkeys_for_localservice (h, "host");
158 if (key == NULL)
160 D (("Key not found: %s\n", shishi_error (h)));
161 retval = PAM_AUTHINFO_UNAVAIL;
162 goto done;
165 rc = shishi_tkt_decrypt (tkt, key);
166 if (rc != SHISHI_OK)
168 D (("Could not decrypt ticket: %s\n", shishi_strerror (rc)));
169 retval = PAM_AUTHINFO_UNAVAIL;
170 goto done;
173 retval = PAM_SUCCESS;
175 done:
176 if (h)
177 shishi_done (h);
178 pam_set_data (pamh, "shishi_setcred_return", (void *) retval, NULL);
179 D (("done. [%s]", pam_strerror (pamh, retval)));
181 return retval;
184 PAM_EXTERN int
185 pam_sm_setcred (pam_handle_t * pamh, int flags, int argc, const char **argv)
187 int retval;
188 int auth_retval;
190 D (("called."));
192 retval = pam_get_data (pamh, "shishi_setcred_return",
193 (const void **) &auth_retval);
194 if (retval != PAM_SUCCESS)
195 return PAM_CRED_UNAVAIL;
197 /* XXX save ticket in user's file here
198 XXX support CRED_EXPIRED */
200 switch (auth_retval)
202 case PAM_SUCCESS:
203 retval = PAM_SUCCESS;
204 break;
206 case PAM_USER_UNKNOWN:
207 retval = PAM_USER_UNKNOWN;
208 break;
210 case PAM_AUTH_ERR:
211 default:
212 retval = PAM_CRED_ERR;
213 break;
216 D (("done. [%s]", pam_strerror (pamh, retval)));
218 return retval;
221 PAM_EXTERN int
222 pam_sm_acct_mgmt (pam_handle_t * pamh, int flags, int argc, const char **argv)
224 int retval;
226 D (("called."));
228 /* TODO: check if password expired? */
229 retval = PAM_SUCCESS;
231 D (("done. [%s]", pam_strerror (pamh, retval)));
233 return retval;
236 PAM_EXTERN int
237 pam_sm_open_session (pam_handle_t * pamh,
238 int flags, int argc, const char **argv)
240 int retval;
242 D (("called."));
244 /* TODO: afslog()? */
245 retval = PAM_SUCCESS;
247 D (("done. [%s]", pam_strerror (pamh, retval)));
249 return retval;
252 PAM_EXTERN int
253 pam_sm_close_session (pam_handle_t * pamh,
254 int flags, int argc, const char **argv)
256 int retval;
258 D (("called."));
260 /* TODO: destroy tickets? destroy AFS tokens? */
261 retval = PAM_SUCCESS;
263 D (("done. [%s]", pam_strerror (pamh, retval)));
265 return retval;
268 PAM_EXTERN int
269 pam_sm_chauthtok (pam_handle_t * pamh, int flags, int argc, const char **argv)
271 int retval;
273 D (("called."));
275 /* TODO: Change password */
276 retval = PAM_SUCCESS;
278 D (("done. [%s]", pam_strerror (pamh, retval)));
280 return retval;
283 #ifdef PAM_STATIC
285 struct pam_module _pam_shishi_modstruct = {
286 "pam_shishi",
287 pam_sm_authenticate,
288 pam_sm_setcred,
289 pam_sm_acct_mgmt,
290 pam_sm_open_session,
291 pam_sm_close_session,
292 pam_sm_chauthtok
295 #endif