auth-rhosts.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Rhosts authentication. This file contains code to check whether to admit
* the login based on rhosts authentication. This file also processes
* /etc/hosts.equiv.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
#include "includes.h"
RCSID("$OpenBSD: auth-rhosts.c,v 1.28 2002/05/13 21:26:49 markus Exp $");
#pragma ident "%Z%%M% %I% %E% SMI"
#include "packet.h"
#include "uidswap.h"
#include "pathnames.h"
#include "log.h"
#include "servconf.h"
#include "canohost.h"
#include "auth.h"
/* import */
extern ServerOptions options;
extern int use_privsep;
/*
* This function processes an rhosts-style file (.rhosts, .shosts, or
* /etc/hosts.equiv). This returns true if authentication can be granted
* based on the file, and returns zero otherwise.
*/
static int
const char *ipaddr, const char *client_user,
const char *server_user)
{
FILE *f;
/* Open the .rhosts file, deny if unreadable */
if (!f)
return 0;
/* All three must be at least as big as buf to avoid overflows. */
int negated;
;
continue;
/*
* NO_PLUS is supported at least on OSF/1. We skip it (we
* don't ever support the plus syntax).
*/
continue;
/*
* This should be safe because each buffer is as big as the
* whole string, and thus cannot be overwritten.
*/
case 0:
continue;
case 1:
/* Host name only. */
break;
case 2:
/* Got both host and user name. */
break;
case 3:
continue;
default:
/* Weird... */
continue;
}
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++;
/* We come here if either was '+' or '-'. */
auth_debug_add("Ignoring wild host/user names in %.100s.",
filename);
continue;
}
/* Verify that host name matches. */
if (host[0] == '@') {
continue;
continue; /* Different hostname. */
/* Verify that user name matches. */
if (user[0] == '@') {
continue;
continue; /* Different username. */
/* Found the user and host. */
fclose(f);
/* If the entry was negated, deny access. */
if (negated) {
auth_debug_add("Matched negative entry in %.100s.",
filename);
return 0;
}
/* Accept authentication. */
return 1;
}
/* Authentication using this file denied. */
fclose(f);
return 0;
}
/*
* 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
{
ipaddr = get_remote_ipaddr();
}
static int
const char *ipaddr)
{
char buf[1024];
debug2("auth_rhosts2: clientuser %s hostname %s ipaddr %s",
/* no user given */
return 0;
/* Switch to the user's uid. */
/*
* Quick check: if the user has no .shosts or .rhosts files, return
* failure immediately without doing costly lookups from name
* servers.
*/
rhosts_file_index++) {
/* Check users .rhosts or .shosts. */
break;
}
/* 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] &&
return 0;
/* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */
auth_debug_add("Accepted for %.100s [%.100s] by /etc/hosts.equiv.",
return 1;
}
auth_debug_add("Accepted for %.100s [%.100s] by %.100s.",
return 1;
}
}
/*
* Check that the home directory is owned by root or the user, and is
* not group or world writable.
*/
log("Rhosts authentication refused for %.100s: "
auth_debug_add("Rhosts authentication refused for %.100s: "
return 0;
}
if (options.strict_modes &&
log("Rhosts authentication refused for %.100s: "
auth_debug_add("Rhosts authentication refused for %.100s: "
return 0;
}
/* Temporarily use the user's uid. */
/* Check all .rhosts files (currently .shosts and .rhosts). */
rhosts_file_index++) {
/* Check users .rhosts or .shosts. */
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 &&
log("Rhosts authentication refused for %.100s: bad modes for %.200s",
continue;
}
/* Check if we have been configured to ignore .rhosts and .shosts files. */
if (options.ignore_rhosts) {
auth_debug_add("Server has been configured to ignore %.100s.",
continue;
}
/* Check if authentication is permitted by the file. */
auth_debug_add("Accepted by %.100s.",
/* Restore the privileged uid. */
restore_uid();
auth_debug_add("Accepted host %s ip %s client_user %s server_user %s",
return 1;
}
}
/* Restore the privileged uid. */
restore_uid();
return 0;
}
int
const char *ipaddr)
{
int ret;
if (!use_privsep)
return ret;
}