+1998-08-28 Geoffrey King <gjking@mit.edu>
+
+ * ftpd.c (login): New function. Essentially, the old pass
+ function has been split into its two logical components, pass and
+ login.
+ (pass): If auth_ok is true, reply with code 202 to tell the
+ user that a PASS command is not necessary. Also, don't reply
+ 230 "User logged in" if the user didn't send a PASS command;
+ this causes the client to get a bit confused.
+ (auth_ok): New function that returns true if either gss_ok or
+ kerb_ok is true (all the #ifdefs were beginning to clutter things,
+ and it's a good abstraction in case other auth types are ever
+ added in the future).
+ (user): If GSSAPI or Kerberos v4 authentication succeeds, call
+ login immediately, instead of waiting for the client to send "PASS
+ dummy." Also, use #ifdef PARANOID instead of "some paranoid sites
+ may wish to uncomment this"
+
Wed Aug 19 06:47:46 1998 Geoffrey King <gjking@mit.edu>
* ftpd.c: Add a new command line option, -c, which tells the
char *getusershell();
#endif
- /* Some paranoid sites may want the client to authenticate
- * before accepting the USER command. If so, uncomment this:
-
+#ifdef PARANOID
+ /*
+ * Some paranoid sites may want the client to authenticate
+ * before accepting the USER command.
+ */
if (!auth_type) {
reply(530,
"Must perform authentication before identifying USER.");
return;
- */
+#endif
if (logged_in) {
if (guest) {
reply(530, "Can't change user from guest login.");
/* 232 is per draft-8, but why 331 not 53z? */
reply(gss_ok ? 232 : 331, "%s", buf);
syslog(gss_ok ? LOG_INFO : LOG_ERR, "%s", buf);
+ if (gss_ok) {
+ login((char *) NULL);
+ return;
+ }
} else
#endif /* GSSAPI */
#ifdef KRB5_KRB4_COMPAT
name, kerb_ok ? "" : "; Password required.");
reply(kerb_ok ? 232 : 331, "%s", buf);
syslog(kerb_ok ? LOG_INFO : LOG_ERR, "%s", buf);
+ if (kerb_ok) {
+ login((char *) NULL);
+ return;
+ }
} else
#endif /* KRB5_KRB4_COMPAT */
/* Other auth types go here ... */
return;
} else
reply(331, "Password required for %s.", name);
+
askpasswd = 1;
/*
* Delay before reading passwd after first failed
{
char *xpasswd, *salt;
- if (logged_in || askpasswd == 0) {
- reply(503, "Login with USER first.");
+ if (auth_ok()) {
+ reply(202, "PASS command superfluous.");
return;
}
- askpasswd = 0;
- if (
-#ifdef KRB5_KRB4_COMPAT
- !kerb_ok &&
-#endif /* KRB5_KRB4_COMPAT */
-#ifdef GSSAPI
- !gss_ok &&
-#endif /* GSSAPI */
- !guest) { /* "ftp" is only account allowed no password */
+
+ if (logged_in || askpasswd == 0) {
+ reply(503, "Login with USER first.");
+ return;
+ }
+
+ if (!auth_ok() && !guest) {
+ /* "ftp" is only account allowed no password */
if (pw == NULL)
salt = "xx";
else
if (pw == NULL ||
(*pw->pw_passwd && strcmp(xpasswd, pw->pw_passwd) &&
!kpass(pw->pw_name, passwd)) ||
- (!*pw->pw_passwd && !kpass(pw->pw_name, passwd))) {
+ (!*pw->pw_passwd && !kpass(pw->pw_name, passwd)))
#else
/* The strcmp does not catch null passwords! */
if (pw == NULL || *pw->pw_passwd == '\0' ||
- strcmp(xpasswd, pw->pw_passwd)) {
+ strcmp(xpasswd, pw->pw_passwd))
#endif /* KRB5_KRB4_COMPAT */
+ {
reply(530, "Login incorrect.");
pw = NULL;
if (login_attempts++ >= 5) {
exit(0);
}
return;
- }
+ }
}
login_attempts = 0; /* this time successful */
+
+ login(passwd);
+ return;
+}
+
+login(passwd)
+ char *passwd;
+{
(void) krb5_setegid((gid_t)pw->pw_gid);
(void) initgroups(pw->pw_name, pw->pw_gid);
/* open wtmp before chroot */
- (void)sprintf(ttyline, "ftp%d", getpid());
+ (void) sprintf(ttyline, "ftp%d", getpid());
ftp_logwtmp(ttyline, pw->pw_name, remotehost);
logged_in = 1;
if (guest) {
if (chroot(pw->pw_dir) < 0) {
- reply(550, "Can't set guest priveleges.");
+ reply(550, "Can't set guest privileges.");
goto bad;
}
}
syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s",
remotehost, passwd);
} else {
- reply(230, "User %s logged in.", pw->pw_name);
+ if (askpasswd) {
+ askpasswd = 0;
+ reply(230, "User %s logged in.", pw->pw_name);
+ }
#ifdef SETPROCTITLE
sprintf(proctitle, "%s: %s", remotehost, pw->pw_name);
setproctitle(proctitle);
pdata = -1;
}
+int auth_ok(void)
+{
+ return(0
+#ifdef KRB5_KRB4_COMPAT
+ || kerb_ok
+#endif /* KRB5_KRB4_COMPAT */
+#ifdef GSSAPI
+ || gss_ok
+#endif /* GSSAPI */
+ );
+}
+
#ifdef SETPROCTITLE
/*
* clobber argv so ps will show what we're doing.
return retval;
}
#endif /* GSSAPI */
+