X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/d231781a31a77d4a3100241b72f3dd517cf5190c..HEAD:/auth.c diff --git a/auth.c b/auth.c index 3bca8dc2..da87807a 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.71 2006/07/12 11:34:58 dtucker Exp $ */ +/* $OpenBSD: auth.c,v 1.83 2010/01/13 23:47:26 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -27,8 +27,12 @@ #include #include +#include + +#include #include +#include #ifdef HAVE_PATHS_H # include #endif @@ -43,28 +47,35 @@ #include #endif #include +#include +#include +#include #include "xmalloc.h" #include "match.h" #include "groupaccess.h" #include "log.h" +#include "buffer.h" #include "servconf.h" +#include "key.h" +#include "hostfile.h" #include "auth.h" #include "auth-options.h" #include "canohost.h" -#include "buffer.h" -#include "bufaux.h" #include "uidswap.h" #include "misc.h" -#include "bufaux.h" #include "packet.h" #include "loginrec.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif #include "monitor_wrap.h" /* import */ extern ServerOptions options; extern int use_privsep; extern Buffer loginmsg; +extern struct passwd *privsep_pw; /* Debugging messages */ Buffer auth_debug; @@ -84,7 +95,7 @@ allowed_user(struct passwd * pw) { 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; @@ -104,15 +115,14 @@ allowed_user(struct passwd * pw) #endif /* USE_SHADOW */ /* grab passwd field for locked account check */ + passwd = pw->pw_passwd; #ifdef USE_SHADOW if (spw != NULL) -#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF) +#ifdef USE_LIBIAF passwd = get_iaf_password(pw); #else passwd = spw->sp_pwdp; -#endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */ -#else - passwd = pw->pw_passwd; +#endif /* USE_LIBIAF */ #endif /* check for locked account */ @@ -132,9 +142,9 @@ allowed_user(struct passwd * pw) if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) locked = 1; #endif -#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF) +#ifdef USE_LIBIAF free(passwd); -#endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */ +#endif /* USE_LIBIAF */ if (locked) { logit("User %.100s not allowed because account is locked", pw->pw_name); @@ -146,20 +156,40 @@ allowed_user(struct passwd * pw) * 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) { @@ -271,6 +301,11 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) strcmp(method, "challenge-response") == 0)) record_failed_login(authctxt->user, get_canonical_hostname(options.use_dns), "ssh"); +# ifdef WITH_AIXAUTHENTICATE + if (authenticated) + sys_auth_record_login(authctxt->user, + get_canonical_hostname(options.use_dns), "ssh", &loginmsg); +# endif #endif #ifdef SSH_AUDIT_EVENTS if (authenticated == 0 && !authctxt->postponed) @@ -396,7 +431,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, * * 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) { @@ -440,7 +475,7 @@ secure_filename(FILE *f, const char *file, struct passwd *pw, 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); @@ -456,6 +491,50 @@ secure_filename(FILE *f, const char *file, struct passwd *pw, 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) { @@ -555,8 +634,8 @@ fakepw(void) fake.pw_passwd = "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; fake.pw_gecos = "NOUSER"; - fake.pw_uid = (uid_t)-1; - fake.pw_gid = (gid_t)-1; + fake.pw_uid = privsep_pw == NULL ? (uid_t)-1 : privsep_pw->pw_uid; + fake.pw_gid = privsep_pw == NULL ? (gid_t)-1 : privsep_pw->pw_gid; #ifdef HAVE_PW_CLASS_IN_PASSWD fake.pw_class = ""; #endif