-/* $OpenBSD: auth.c,v 1.76 2007/08/23 02:49:43 djm Exp $ */
+/* $OpenBSD: auth.c,v 1.83 2010/01/13 23:47:26 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
#include <netinet/in.h>
#include <errno.h>
+#include <fcntl.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <unistd.h>
#include "xmalloc.h"
#include "match.h"
{
struct stat st;
const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
- char *shell;
+ char *shell, *tmp, *chroot_path;
u_int i;
#ifdef USE_SHADOW
struct spwd *spw = NULL;
#endif /* USE_SHADOW */
/* grab passwd field for locked account check */
+ passwd = pw->pw_passwd;
#ifdef USE_SHADOW
if (spw != NULL)
#ifdef USE_LIBIAF
#else
passwd = spw->sp_pwdp;
#endif /* USE_LIBIAF */
-#else
- passwd = pw->pw_passwd;
#endif
/* check for locked account */
* Get the shell from the password data. An empty shell field is
* legal, and means /bin/sh.
*/
- shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
+ shell = xstrdup((pw->pw_shell[0] == '\0') ?
+ _PATH_BSHELL : pw->pw_shell);
+
+ /*
+ * Amend shell if chroot is requested.
+ */
+ if (options.chroot_directory != NULL &&
+ strcasecmp(options.chroot_directory, "none") != 0) {
+ tmp = tilde_expand_filename(options.chroot_directory,
+ pw->pw_uid);
+ chroot_path = percent_expand(tmp, "h", pw->pw_dir,
+ "u", pw->pw_name, (char *)NULL);
+ xfree(tmp);
+ xasprintf(&tmp, "%s/%s", chroot_path, shell);
+ xfree(shell);
+ shell = tmp;
+ free(chroot_path);
+ }
/* deny if shell does not exists or is not executable */
if (stat(shell, &st) != 0) {
logit("User %.100s not allowed because shell %.100s does not exist",
pw->pw_name, shell);
+ xfree(shell);
return 0;
}
if (S_ISREG(st.st_mode) == 0 ||
(st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
logit("User %.100s not allowed because shell %.100s is not executable",
pw->pw_name, shell);
+ xfree(shell);
return 0;
}
+ xfree(shell);
if (options.num_deny_users > 0 || options.num_allow_users > 0 ||
options.num_deny_groups > 0 || options.num_allow_groups > 0) {
*
* Returns 0 on success and -1 on failure
*/
-int
+static int
secure_filename(FILE *f, const char *file, struct passwd *pw,
char *err, size_t errlen)
{
return -1;
}
- /* If are passed the homedir then we can stop */
+ /* If are past the homedir then we can stop */
if (comparehome && strcmp(homedir, buf) == 0) {
debug3("secure_filename: terminating check at '%s'",
buf);
return 0;
}
+FILE *
+auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
+{
+ char line[1024];
+ struct stat st;
+ int fd;
+ FILE *f;
+
+ /*
+ * Open the file containing the authorized keys
+ * Fail quietly if file does not exist
+ */
+ if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) {
+ if (errno != ENOENT)
+ debug("Could not open keyfile '%s': %s", file,
+ strerror(errno));
+ return NULL;
+ }
+
+ if (fstat(fd, &st) < 0) {
+ close(fd);
+ return NULL;
+ }
+ if (!S_ISREG(st.st_mode)) {
+ logit("User %s authorized keys %s is not a regular file",
+ pw->pw_name, file);
+ close(fd);
+ return NULL;
+ }
+ unset_nonblock(fd);
+ if ((f = fdopen(fd, "r")) == NULL) {
+ close(fd);
+ return NULL;
+ }
+ if (options.strict_modes &&
+ secure_filename(f, file, pw, line, sizeof(line)) != 0) {
+ fclose(f);
+ logit("Authentication refused: %s", line);
+ return NULL;
+ }
+
+ return f;
+}
+
struct passwd *
getpwnamallow(const char *user)
{