6 * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
10 #define PLEASE_ENTER_PASSWORD "Password required for %s."
11 #define GUEST_LOGIN_PROMPT "Guest login ok, " \
12 "send your complete e-mail address as password."
14 /* the following is a password that "can't be correct" */
15 #define BLOCK_PASSWORD "\177BAD PASSWPRD\177"
27 * here, we make a definition for the externally accessible function
28 * in this file (this definition is required for static a module
29 * but strongly encouraged generally) it is used to instruct the
30 * modules include file to define the function prototypes.
35 #include <security/pam_modules.h>
36 #include <security/_pam_macros.h>
37 #include <security/pam_ext.h>
39 /* argument parsing */
41 #define PAM_DEBUG_ARG 01
42 #define PAM_IGNORE_EMAIL 02
43 #define PAM_NO_ANON 04
46 _pam_parse(pam_handle_t *pamh, int argc, const char **argv, const char **users)
50 /* step through arguments */
51 for (ctrl=0; argc-- > 0; ++argv) {
55 if (!strcmp(*argv,"debug"))
56 ctrl |= PAM_DEBUG_ARG;
57 else if (!strncmp(*argv,"users=",6)) {
59 } else if (!strcmp(*argv,"ignore")) {
60 ctrl |= PAM_IGNORE_EMAIL;
62 pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
70 * check if name is in list or default list. place users name in *_user
71 * return 1 if listed 0 if not.
74 static int lookup(const char *name, const char *list, const char **_user)
78 *_user = name; /* this is the default */
84 list_copy = x_strdup(list);
86 while (list_copy && (l = strtok_r(x, ",", &sptr))) {
88 if (!strcmp(name, l)) {
93 _pam_overwrite(list_copy);
97 static const char *l[MAX_L] = { "ftp", "anonymous" };
100 for (i=0; i<MAX_L; ++i) {
101 if (!strcmp(l[i], name)) {
112 /* --- authentication management functions (only) --- */
115 pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
116 int argc, const char **argv)
118 int retval, anon=0, ctrl;
120 const char *users = NULL;
123 * this module checks if the user name is ftp or annonymous. If
124 * this is the case, it can set the PAM_RUSER to the entered email
125 * address and SUCCEEDS, otherwise it FAILS.
128 ctrl = _pam_parse(pamh, argc, argv, &users);
130 retval = pam_get_user(pamh, &user, NULL);
131 if (retval != PAM_SUCCESS || user == NULL) {
132 pam_syslog(pamh, LOG_ERR, "no user specified");
133 return PAM_USER_UNKNOWN;
136 if (!(ctrl & PAM_NO_ANON)) {
137 anon = lookup(user, users, &user);
141 retval = pam_set_item(pamh, PAM_USER, (const void *)user);
142 if (retval != PAM_SUCCESS || user == NULL) {
143 pam_syslog(pamh, LOG_ERR, "user resetting failed");
144 return PAM_USER_UNKNOWN;
149 * OK. we require an email address for user or the user's password.
150 * - build conversation and get their input.
158 retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp,
159 PLEASE_ENTER_PASSWORD, user);
161 retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp,
164 if (retval != PAM_SUCCESS) {
165 _pam_overwrite (resp);
167 return ((retval == PAM_CONV_AGAIN)
168 ? PAM_INCOMPLETE:PAM_AUTHINFO_UNAVAIL);
172 /* XXX: Some effort should be made to verify this email address! */
174 if (!(ctrl & PAM_IGNORE_EMAIL)) {
176 token = strtok_r(resp, "@", &sptr);
177 retval = pam_set_item(pamh, PAM_RUSER, token);
179 if ((token) && (retval == PAM_SUCCESS)) {
180 token = strtok_r(NULL, "@", &sptr);
181 retval = pam_set_item(pamh, PAM_RHOST, token);
185 /* we are happy to grant annonymous access to the user */
186 retval = PAM_SUCCESS;
190 * we have a password so set AUTHTOK
193 pam_set_item(pamh, PAM_AUTHTOK, resp);
196 * this module failed, but the next one might succeed with
200 retval = PAM_AUTH_ERR;
204 _pam_overwrite(resp);
207 /* success or failure */
214 pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
215 int argc UNUSED, const char **argv UNUSED)
223 /* static module data */
225 struct pam_module _pam_ftp_modstruct = {
237 /* end of module definition */