]> andersk Git - openssh.git/blobdiff - auth-rhosts.c
- Merged very large OpenBSD source code reformat
[openssh.git] / auth-rhosts.c
index 8149be6bb1a46b9cd0b8fd9bf1ad9d7ab88b2687..e60712087ca20a18e68e68dfd6e41aa3328d901a 100644 (file)
@@ -1,19 +1,19 @@
 /*
-
-auth-rhosts.c
-
-Author: Tatu Ylonen <ylo@cs.hut.fi>
-
-Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
-                   All rights reserved
-
-Created: Fri Mar 17 05:12:18 1995 ylo
-
-Rhosts authentication.  This file contains code to check whether to admit
-the login based on rhosts authentication.  This file also processes
-/etc/hosts.equiv.
-
-*/
+ * 
+ * auth-rhosts.c
+ * 
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * 
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
*                    All rights reserved
+ * 
+ * Created: Fri Mar 17 05:12:18 1995 ylo
+ * 
+ * Rhosts authentication.  This file contains code to check whether to admit
+ * the login based on rhosts authentication.  This file also processes
+ * /etc/hosts.equiv.
+ * 
+ */
 
 #include "includes.h"
 RCSID("$Id$");
@@ -28,256 +28,228 @@ RCSID("$Id$");
    /etc/hosts.equiv).  This returns true if authentication can be granted
    based on the file, and returns zero otherwise. */
 
-int check_rhosts_file(const char *filename, const char *hostname,
-                     const char *ipaddr, const char *client_user,
-                     const char *server_user)
+int 
+check_rhosts_file(const char *filename, const char *hostname,
+                 const char *ipaddr, const char *client_user,
+                 const char *server_user)
 {
-  FILE *f;
-  char buf[1024]; /* Must not be larger than host, user, dummy below. */
-  
-  /* Open the .rhosts file. */
-  f = fopen(filename, "r");
-  if (!f)
-    return 0; /* Cannot read the .rhosts - deny access. */
-
-  /* Go through the file, checking every entry. */
-  while (fgets(buf, sizeof(buf), f))
-    {
-      /* All three must be at least as big as buf to avoid overflows. */
-      char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp;
-      int negated;
-      
-      for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
-       ;
-      if (*cp == '#' || *cp == '\n' || !*cp)
-       continue;
-
-      /* NO_PLUS is supported at least on OSF/1.  We skip it (we don't ever
-        support the plus syntax). */
-      if (strncmp(cp, "NO_PLUS", 7) == 0)
-       continue;
-
-      /* This should be safe because each buffer is as big as the whole
-        string, and thus cannot be overwritten. */
-      switch (sscanf(buf, "%s %s %s", hostbuf, userbuf, dummy))
-       {
-       case 0:
-         packet_send_debug("Found empty line in %.100s.", filename);
-         continue; /* Empty line? */
-       case 1:
-         /* Host name only. */
-         strlcpy(userbuf, server_user, sizeof(userbuf));
-         break;
-       case 2:
-         /* Got both host and user name. */
-         break;
-       case 3:
-         packet_send_debug("Found garbage in %.100s.", filename);
-         continue; /* Extra garbage */
-       default:
-         continue; /* Weird... */
-       }
-
-      host = hostbuf;
-      user = userbuf;
-      negated = 0;
-
-      /* Process negated host names, or positive netgroups. */
-      if (host[0] == '-')
-       {
-         negated = 1;
-         host++;
-       }
-      else
-       if (host[0] == '+')
-         host++;
-
-      if (user[0] == '-')
-       {
-         negated = 1;
-         user++;
-       }
-      else
-       if (user[0] == '+')
-         user++;
-
-      /* Check for empty host/user names (particularly '+'). */
-      if (!host[0] || !user[0])
-       { 
-         /* We come here if either was '+' or '-'. */
-         packet_send_debug("Ignoring wild host/user names in %.100s.",
-                           filename);
-         continue;
-       }
-         
-      /* Verify that host name matches. */
-      if (host[0] == '@')
-       {
-         if (!innetgr(host + 1, hostname, NULL, NULL) &&
-             !innetgr(host + 1, ipaddr, NULL, NULL))
-           continue;
-       }
-      else
-       if (strcasecmp(host, hostname) && strcmp(host, ipaddr) != 0)
-         continue; /* Different hostname. */
-
-      /* Verify that user name matches. */
-      if (user[0] == '@')
-       {
-         if (!innetgr(user + 1, NULL, client_user, NULL))
-           continue;
+       FILE *f;
+       char buf[1024]; /* Must not be larger than host, user, dummy below. */
+
+       /* Open the .rhosts file, deny if unreadable */
+       f = fopen(filename, "r");
+       if (!f)
+               return 0;
+
+       /* Go through the file, checking every entry. */
+       while (fgets(buf, sizeof(buf), f)) {
+               /* All three must be at least as big as buf to avoid overflows. */
+               char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp;
+               int negated;
+
+               for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
+                       ;
+               if (*cp == '#' || *cp == '\n' || !*cp)
+                       continue;
+
+               /* NO_PLUS is supported at least on OSF/1.  We skip it (we
+                  don't ever support the plus syntax). */
+               if (strncmp(cp, "NO_PLUS", 7) == 0)
+                       continue;
+
+               /* This should be safe because each buffer is as big as
+                  the whole string, and thus cannot be overwritten. */
+               switch (sscanf(buf, "%s %s %s", hostbuf, userbuf, dummy)) {
+               case 0:
+                       packet_send_debug("Found empty line in %.100s.", filename);
+                       continue;
+               case 1:
+                       /* Host name only. */
+                       strlcpy(userbuf, server_user, sizeof(userbuf));
+                       break;
+               case 2:
+                       /* Got both host and user name. */
+                       break;
+               case 3:
+                       packet_send_debug("Found garbage in %.100s.", filename);
+                       continue;
+               default:
+                       /* Weird... */
+                       continue;
+               }
+
+               host = hostbuf;
+               user = userbuf;
+               negated = 0;
+
+               /* Process negated host names, or positive netgroups. */
+               if (host[0] == '-') {
+                       negated = 1;
+                       host++;
+               } else if (host[0] == '+')
+                       host++;
+
+               if (user[0] == '-') {
+                       negated = 1;
+                       user++;
+               } else if (user[0] == '+')
+                       user++;
+
+               /* Check for empty host/user names (particularly '+'). */
+               if (!host[0] || !user[0]) {
+                       /* We come here if either was '+' or '-'. */
+                       packet_send_debug("Ignoring wild host/user names in %.100s.",
+                                         filename);
+                       continue;
+               }
+               /* Verify that host name matches. */
+               if (host[0] == '@') {
+                       if (!innetgr(host + 1, hostname, NULL, NULL) &&
+                           !innetgr(host + 1, ipaddr, NULL, NULL))
+                               continue;
+               } else if (strcasecmp(host, hostname) && strcmp(host, ipaddr) != 0)
+                       continue;       /* Different hostname. */
+
+               /* Verify that user name matches. */
+               if (user[0] == '@') {
+                       if (!innetgr(user + 1, NULL, client_user, NULL))
+                               continue;
+               } else if (strcmp(user, client_user) != 0)
+                       continue;       /* Different username. */
+
+               /* Found the user and host. */
+               fclose(f);
+
+               /* If the entry was negated, deny access. */
+               if (negated) {
+                       packet_send_debug("Matched negative entry in %.100s.",
+                                         filename);
+                       return 0;
+               }
+               /* Accept authentication. */
+               return 1;
        }
-      else
-       if (strcmp(user, client_user) != 0)
-         continue; /* Different username. */
 
-      /* Found the user and host. */
-      fclose(f);
-
-      /* If the entry was negated, deny access. */
-      if (negated)
-       {
-         packet_send_debug("Matched negative entry in %.100s.",
-                           filename);
-         return 0;
-       }
-
-      /* Accept authentication. */
-      return 1;
-    }
-     
-  /* Authentication using this file denied. */
-  fclose(f);
-  return 0;
+       /* Authentication using this file denied. */
+       fclose(f);
+       return 0;
 }
 
-/* Tries to authenticate the user using the .shosts or .rhosts file.  
+/* Tries to authenticate the user using the .shosts or .rhosts file.
    Returns true if authentication succeeds.  If ignore_rhosts is
    true, only /etc/hosts.equiv will be considered (.rhosts and .shosts
    are ignored). */
 
-int auth_rhosts(struct passwd *pw, const char *client_user)
+int 
+auth_rhosts(struct passwd *pw, const char *client_user)
 {
-  extern ServerOptions options;
-  char buf[1024];
-  const char *hostname, *ipaddr;
-  struct stat st;
-  static const char *rhosts_files[] = { ".shosts", ".rhosts", NULL };
-  unsigned int rhosts_file_index;
-
-  /* Quick check: if the user has no .shosts or .rhosts files, return failure
-     immediately without doing costly lookups from name servers. */
-  /* Switch to the user's uid. */
-  temporarily_use_uid(pw->pw_uid);
-  for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
-       rhosts_file_index++)
-    {
-      /* Check users .rhosts or .shosts. */
-      snprintf(buf, sizeof buf, "%.500s/%.100s", 
-             pw->pw_dir, rhosts_files[rhosts_file_index]);
-      if (stat(buf, &st) >= 0)
-       break;
-    }
-  /* Switch back to privileged uid. */
-  restore_uid();
-
-  if (!rhosts_files[rhosts_file_index] && stat("/etc/hosts.equiv", &st) < 0 &&
-      stat(SSH_HOSTS_EQUIV, &st) < 0)
-    return 0; /* The user has no .shosts or .rhosts file and there are no
-                system-wide files. */
-
-  /* Get the name, address, and port of the remote host.  */
-  hostname = get_canonical_hostname();
-  ipaddr = get_remote_ipaddr();
-
-  /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */
-  if (pw->pw_uid != 0)
-    {
-      if (check_rhosts_file("/etc/hosts.equiv", hostname, ipaddr, client_user,
-                           pw->pw_name))
-       {
-         packet_send_debug("Accepted for %.100s [%.100s] by /etc/hosts.equiv.",
-                           hostname, ipaddr);
-         return 1;
+       extern ServerOptions options;
+       char buf[1024];
+       const char *hostname, *ipaddr;
+       struct stat st;
+       static const char *rhosts_files[] = {".shosts", ".rhosts", NULL};
+       unsigned int rhosts_file_index;
+
+       /* Quick check: if the user has no .shosts or .rhosts files,
+          return failure immediately without doing costly lookups from
+          name servers. */
+       /* Switch to the user's uid. */
+       temporarily_use_uid(pw->pw_uid);
+       for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
+            rhosts_file_index++) {
+               /* Check users .rhosts or .shosts. */
+               snprintf(buf, sizeof buf, "%.500s/%.100s",
+                        pw->pw_dir, rhosts_files[rhosts_file_index]);
+               if (stat(buf, &st) >= 0)
+                       break;
        }
-      if (check_rhosts_file(SSH_HOSTS_EQUIV, hostname, ipaddr, client_user,
-                           pw->pw_name))
-       {
-         packet_send_debug("Accepted for %.100s [%.100s] by %.100s.", 
-                           hostname, ipaddr, SSH_HOSTS_EQUIV);
-         return 1;
+       /* Switch back to privileged uid. */
+       restore_uid();
+
+       /* Deny if The user has no .shosts or .rhosts file and there are no system-wide files. */
+       if (!rhosts_files[rhosts_file_index] &&
+           stat("/etc/hosts.equiv", &st) < 0 &&
+           stat(SSH_HOSTS_EQUIV, &st) < 0)
+               return 0;
+
+       /* Get the name, address, and port of the remote host.  */
+       hostname = get_canonical_hostname();
+       ipaddr = get_remote_ipaddr();
+
+       /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */
+       if (pw->pw_uid != 0) {
+               if (check_rhosts_file("/etc/hosts.equiv", hostname, ipaddr, client_user,
+                                     pw->pw_name)) {
+                       packet_send_debug("Accepted for %.100s [%.100s] by /etc/hosts.equiv.",
+                                         hostname, ipaddr);
+                       return 1;
+               }
+               if (check_rhosts_file(SSH_HOSTS_EQUIV, hostname, ipaddr, client_user,
+                                     pw->pw_name)) {
+                       packet_send_debug("Accepted for %.100s [%.100s] by %.100s.",
+                                     hostname, ipaddr, SSH_HOSTS_EQUIV);
+                       return 1;
+               }
        }
-    }
-
-  /* Check that the home directory is owned by root or the user, and is not 
-     group or world writable. */
-  if (stat(pw->pw_dir, &st) < 0)
-    {
-      log("Rhosts authentication refused for %.100s: no home directory %.200s",
-         pw->pw_name, pw->pw_dir);
-      packet_send_debug("Rhosts authentication refused for %.100: no home directory %.200s",
-                       pw->pw_name, pw->pw_dir);
-      return 0;
-    }
-  if (options.strict_modes && 
-      ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
-       (st.st_mode & 022) != 0))
-    {
-      log("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.",
-         pw->pw_name);
-      packet_send_debug("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.",
-                       pw->pw_name);
-      return 0;
-    }
-  
-  /* Check all .rhosts files (currently .shosts and .rhosts). */
-  /* Temporarily use the user's uid. */
-  temporarily_use_uid(pw->pw_uid);
-  for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
-       rhosts_file_index++)
-    {
-      /* Check users .rhosts or .shosts. */
-      snprintf(buf, sizeof buf, "%.500s/%.100s", 
-             pw->pw_dir, rhosts_files[rhosts_file_index]);
-      if (stat(buf, &st) < 0)
-       continue; /* No such file. */
-
-      /* Make sure that the file is either owned by the user or by root,
-        and make sure it is not writable by anyone but the owner.  This is
-        to help avoid novices accidentally allowing access to their account
-        by anyone. */
-      if (options.strict_modes &&
-         ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
-          (st.st_mode & 022) != 0))
-       {
-         log("Rhosts authentication refused for %.100s: bad modes for %.200s",
-             pw->pw_name, buf);
-         packet_send_debug("Bad file modes for %.200s", buf);
-         continue;
+       /* Check that the home directory is owned by root or the user, and
+          is not group or world writable. */
+       if (stat(pw->pw_dir, &st) < 0) {
+               log("Rhosts authentication refused for %.100s: no home directory %.200s",
+                   pw->pw_name, pw->pw_dir);
+               packet_send_debug("Rhosts authentication refused for %.100: no home directory %.200s",
+                                 pw->pw_name, pw->pw_dir);
+               return 0;
        }
-
-      /* Check if we have been configured to ignore .rhosts and .shosts 
-        files. */
-      if (options.ignore_rhosts)
-       {
-         packet_send_debug("Server has been configured to ignore %.100s.",
-                           rhosts_files[rhosts_file_index]);
-         continue;
+       if (options.strict_modes &&
+           ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
+            (st.st_mode & 022) != 0)) {
+               log("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.",
+                   pw->pw_name);
+               packet_send_debug("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.",
+                                 pw->pw_name);
+               return 0;
        }
-
-      /* Check if authentication is permitted by the file. */
-      if (check_rhosts_file(buf, hostname, ipaddr, client_user, pw->pw_name))
-       {
-         packet_send_debug("Accepted by %.100s.",
-                           rhosts_files[rhosts_file_index]);
-         /* Restore the privileged uid. */
-         restore_uid();
-         return 1;
+       /* Temporarily use the user's uid. */
+       temporarily_use_uid(pw->pw_uid);
+
+       /* Check all .rhosts files (currently .shosts and .rhosts). */
+       for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
+            rhosts_file_index++) {
+               /* Check users .rhosts or .shosts. */
+               snprintf(buf, sizeof buf, "%.500s/%.100s",
+                        pw->pw_dir, rhosts_files[rhosts_file_index]);
+               if (stat(buf, &st) < 0)
+                       continue;
+
+               /* Make sure that the file is either owned by the user or
+                  by root, and make sure it is not writable by anyone but
+                  the owner.  This is to help avoid novices accidentally
+                  allowing access to their account by anyone. */
+               if (options.strict_modes &&
+                   ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
+                    (st.st_mode & 022) != 0)) {
+                       log("Rhosts authentication refused for %.100s: bad modes for %.200s",
+                           pw->pw_name, buf);
+                       packet_send_debug("Bad file modes for %.200s", buf);
+                       continue;
+               }
+               /* Check if we have been configured to ignore .rhosts and .shosts files. */
+               if (options.ignore_rhosts) {
+                       packet_send_debug("Server has been configured to ignore %.100s.",
+                                         rhosts_files[rhosts_file_index]);
+                       continue;
+               }
+               /* Check if authentication is permitted by the file. */
+               if (check_rhosts_file(buf, hostname, ipaddr, client_user, pw->pw_name)) {
+                       packet_send_debug("Accepted by %.100s.",
+                                         rhosts_files[rhosts_file_index]);
+                       /* Restore the privileged uid. */
+                       restore_uid();
+                       return 1;
+               }
        }
-    }
 
-  /* Rhosts authentication denied. */
-  /* Restore the privileged uid. */
-  restore_uid();
-  return 0;
+       /* Restore the privileged uid. */
+       restore_uid();
+       return 0;
 }
This page took 0.051571 seconds and 4 git commands to generate.