* ftpd.c: Add support for restricted users, as requested in
authorGeoffrey King <gjking@mit.edu>
Thu, 8 Oct 1998 05:21:56 +0000 (05:21 +0000)
committerGeoffrey King <gjking@mit.edu>
Thu, 8 Oct 1998 05:21:56 +0000 (05:21 +0000)
[krb5-appl/481].  Users that appear in /etc/ftpusers, followed
by the keyword "restrict" will be granted access, but a chroot()
will be done to their home directory.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@10970 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/gssftp/ftpd/ChangeLog
src/appl/gssftp/ftpd/ftpd.c

index 1984531d1bbe1938554d59e2c1a65008c4fe1d5d..37967da9547347b8cab27b08bc3442e017897c07 100644 (file)
@@ -1,3 +1,10 @@
+1998-10-08  Geoffrey King  <gjking@mit.edu>
+
+       * ftpd.c: Add support for restricted users, as requested in
+       [krb5-appl/481].  Users that appear in /etc/ftpusers, followed
+       by the keyword "restrict" will be granted access, but a chroot()
+       will be done to their home directory.
+
 Tue Sep 29 19:25:09 1998  Theodore Y. Ts'o  <tytso@mit.edu>
 
        * ftpd.c (auth_data): Don't use h_errno, it's not fully portable,
index d31181af7fa9edc4aa09bd5ca8929770b2710cfb..44bf8dfe5b50cd17ca5f13c7797528f12e69f363 100644 (file)
@@ -179,6 +179,7 @@ int maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */
 int    logging;
 int    authenticate;
 int    guest;
+int    restricted;
 int    type;
 int    clevel;                 /* control protection level */
 int    dlevel;                 /* data protection level */
@@ -607,7 +608,10 @@ int askpasswd;                     /* had user command, ask for passwd */
  * If account doesn't exist, ask for passwd anyway.  Otherwise, check user
  * requesting login privileges.  Disallow anyone who does not have a standard
  * shell as returned by getusershell().  Disallow anyone mentioned in the file
- * _PATH_FTPUSERS to allow people such as root and uucp to be avoided.
+ * _PATH_FTPUSERS to allow people such as root and uucp to be avoided, except
+ * for users whose names are followed by whitespace and then the keyword
+ * "restrict."  Restricted users are allowed to login, but a chroot() is
+ * done to their home directory.
  */
 user(name)
        char *name;
@@ -638,7 +642,7 @@ user(name)
 
        guest = 0;
        if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
-               if (checkuser("ftp") || checkuser("anonymous"))
+               if (disallowed_user("ftp") || disallowed_user("anonymous"))
                        reply(530, "User %s access denied.", name);
                else if ((pw = sgetpwnam("ftp")) != NULL) {
                        guest = 1;
@@ -660,7 +664,7 @@ user(name)
 #else
                cp = shell;
 #endif
-               if (cp == NULL || checkuser(name)) {
+               if (cp == NULL || disallowed_user(name)) {
                        reply(530, "User %s access denied.", name);
                        if (logging)
                                syslog(LOG_NOTICE,
@@ -669,6 +673,7 @@ user(name)
                        pw = (struct passwd *) NULL;
                        return;
                }
+               restricted = restricted_user(name);
        }
 #ifdef GSSAPI
        if (auth_type && strcmp(auth_type, "GSSAPI") == 0) {
@@ -736,6 +741,7 @@ user(name)
                reply(331, "Password required for %s.", name);
 
        askpasswd = 1;
+
        /*
         * Delay before reading passwd after first failed
         * attempt to slow down passwd-guessing programs.
@@ -745,7 +751,9 @@ user(name)
 }
 
 /*
- * Check if a user is in the file _PATH_FTPUSERS
+ * Check if a user is in the file _PATH_FTPUSERS.
+ * Return 1 if they are (a disallowed user), -1 if their username
+ * is followed by "restrict." (a restricted user).  Otherwise return 0.
  */
 checkuser(name)
        char *name;
@@ -755,19 +763,47 @@ checkuser(name)
        char line[FTP_BUFSIZ];
 
        if ((fd = fopen(_PATH_FTPUSERS, "r")) != NULL) {
-               while (fgets(line, sizeof(line), fd) != NULL)
-                       if ((p = strchr(line, '\n')) != NULL) {
-                               *p = '\0';
-                               if (line[0] == '#')
-                                       continue;
-                               if (strcmp(line, name) == 0)
-                                       return (1);
+            while (fgets(line, sizeof(line), fd) != NULL) {
+                 if ((p = strchr(line, '\n')) != NULL) {
+                       *p = '\0';
+                       if (line[0] == '#')
+                            continue;
+                       if (strcmp(line, name) == 0)
+                            return (1);
+                       if (strncmp(line, name, strlen(name)) == 0) {
+                            int i = strlen(name) + 1;
+                            
+                            /* Make sure foo doesn't match foobar */
+                            if (line[i] == '\0' || !isspace(line[i]))
+                                 continue;
+                            /* Ignore whitespace */
+                            while (isspace(line[++i]));
+
+                            if (strcmp(&line[i], "restrict") == 0)
+                                 return (-1);
+                            else
+                                 return (1);
                        }
-               (void) fclose(fd);
+                 }
+            }
        }
+       (void) fclose(fd);
+
        return (0);
 }
 
+disallowed_user(name)
+        char *name;
+{
+        return(checkuser(name) == 1);
+}
+
+restricted_user(name)
+        char *name;
+{
+        return(checkuser(name) == -1);
+}
+
 /*
  * Terminate login as previous user, if any, resetting state;
  * used when USER command is given or login fails.
@@ -902,9 +938,9 @@ login(passwd)
        ftp_logwtmp(ttyline, pw->pw_name, remotehost);
        logged_in = 1;
 
-       if (guest) {
-               if (chroot(pw->pw_dir) < 0) {
-                       reply(550, "Can't set guest privileges.");
+       if (guest || restricted) {
+               if (chroot(pw->pw_dir) < 0) {
+                       reply(550, "Can't set privileges.");
                        goto bad;
                }
        }
@@ -923,7 +959,7 @@ login(passwd)
                        goto bad;
                }
        } else {
-               if (chdir(pw->pw_dir) < 0) {
+               if (chdir(restricted ? "/" : pw->pw_dir) < 0) {
                        if (chdir("/") < 0) {
                                reply(530, "User %s: can't change directory to %s.",
                                      pw->pw_name, pw->pw_dir);