version 1.10, 1999/11/24 00:26:00 |
version 1.11, 1999/11/24 19:53:43 |
|
|
#include "uidswap.h" |
#include "uidswap.h" |
#include "servconf.h" |
#include "servconf.h" |
|
|
/* This function processes an rhosts-style file (.rhosts, .shosts, or |
/* |
/etc/hosts.equiv). This returns true if authentication can be granted |
* This function processes an rhosts-style file (.rhosts, .shosts, or |
based on the file, and returns zero otherwise. */ |
* /etc/hosts.equiv). This returns true if authentication can be granted |
|
* based on the file, and returns zero otherwise. |
|
*/ |
|
|
int |
int |
check_rhosts_file(const char *filename, const char *hostname, |
check_rhosts_file(const char *filename, const char *hostname, |
|
|
if (!f) |
if (!f) |
return 0; |
return 0; |
|
|
/* Go through the file, checking every entry. */ |
|
while (fgets(buf, sizeof(buf), f)) { |
while (fgets(buf, sizeof(buf), f)) { |
/* All three must be at least as big as buf to avoid overflows. */ |
/* All three must be at least as big as buf to avoid overflows. */ |
char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp; |
char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp; |
|
|
if (*cp == '#' || *cp == '\n' || !*cp) |
if (*cp == '#' || *cp == '\n' || !*cp) |
continue; |
continue; |
|
|
/* NO_PLUS is supported at least on OSF/1. We skip it (we |
/* |
don't ever support the plus syntax). */ |
* 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) |
if (strncmp(cp, "NO_PLUS", 7) == 0) |
continue; |
continue; |
|
|
/* This should be safe because each buffer is as big as |
/* |
the whole string, and thus cannot be overwritten. */ |
* 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)) { |
switch (sscanf(buf, "%s %s %s", hostbuf, userbuf, dummy)) { |
case 0: |
case 0: |
packet_send_debug("Found empty line in %.100s.", filename); |
packet_send_debug("Found empty line in %.100s.", filename); |
|
|
return 0; |
return 0; |
} |
} |
|
|
/* Tries to authenticate the user using the .shosts or .rhosts file. |
/* |
Returns true if authentication succeeds. If ignore_rhosts is |
* Tries to authenticate the user using the .shosts or .rhosts file. Returns |
true, only /etc/hosts.equiv will be considered (.rhosts and .shosts |
* true if authentication succeeds. If ignore_rhosts is true, only |
are ignored). */ |
* /etc/hosts.equiv will be considered (.rhosts and .shosts are ignored). |
|
*/ |
|
|
int |
int |
auth_rhosts(struct passwd *pw, const char *client_user) |
auth_rhosts(struct passwd *pw, const char *client_user) |
|
|
static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; |
static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; |
unsigned int rhosts_file_index; |
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. */ |
/* Switch to the user's uid. */ |
temporarily_use_uid(pw->pw_uid); |
temporarily_use_uid(pw->pw_uid); |
|
/* |
|
* Quick check: if the user has no .shosts or .rhosts files, return |
|
* failure immediately without doing costly lookups from name |
|
* servers. |
|
*/ |
for (rhosts_file_index = 0; rhosts_files[rhosts_file_index]; |
for (rhosts_file_index = 0; rhosts_files[rhosts_file_index]; |
rhosts_file_index++) { |
rhosts_file_index++) { |
/* Check users .rhosts or .shosts. */ |
/* Check users .rhosts or .shosts. */ |
|
|
stat(SSH_HOSTS_EQUIV, &st) < 0) |
stat(SSH_HOSTS_EQUIV, &st) < 0) |
return 0; |
return 0; |
|
|
/* Get the name, address, and port of the remote host. */ |
|
hostname = get_canonical_hostname(); |
hostname = get_canonical_hostname(); |
ipaddr = get_remote_ipaddr(); |
ipaddr = get_remote_ipaddr(); |
|
|
|
|
return 1; |
return 1; |
} |
} |
} |
} |
/* Check that the home directory is owned by root or the user, and |
/* |
is not group or world writable. */ |
* 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) { |
if (stat(pw->pw_dir, &st) < 0) { |
log("Rhosts authentication refused for %.100s: no home directory %.200s", |
log("Rhosts authentication refused for %.100s: no home directory %.200s", |
pw->pw_name, pw->pw_dir); |
pw->pw_name, pw->pw_dir); |
|
|
if (stat(buf, &st) < 0) |
if (stat(buf, &st) < 0) |
continue; |
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 |
* Make sure that the file is either owned by the user or by |
the owner. This is to help avoid novices accidentally |
* root, and make sure it is not writable by anyone but the |
allowing access to their account by anyone. */ |
* owner. This is to help avoid novices accidentally |
|
* allowing access to their account by anyone. |
|
*/ |
if (options.strict_modes && |
if (options.strict_modes && |
((st.st_uid != 0 && st.st_uid != pw->pw_uid) || |
((st.st_uid != 0 && st.st_uid != pw->pw_uid) || |
(st.st_mode & 022) != 0)) { |
(st.st_mode & 022) != 0)) { |