+/* $OpenBSD: auth.c,v 1.72 2006/07/22 20:48:22 stevesk Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
*/
#include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.57 2005/01/22 08:17:59 dtucker Exp $");
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif
+#include <pwd.h>
#ifdef HAVE_LOGIN_H
#include <login.h>
#endif
#ifdef USE_SHADOW
#include <shadow.h>
#endif
-
#ifdef HAVE_LIBGEN_H
#include <libgen.h>
#endif
+#include <stdarg.h>
+#include <string.h>
#include "xmalloc.h"
#include "match.h"
#include "bufaux.h"
#include "packet.h"
#include "loginrec.h"
+#include "monitor_wrap.h"
/* import */
extern ServerOptions options;
+extern int use_privsep;
extern Buffer loginmsg;
/* Debugging messages */
struct stat st;
const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
char *shell;
- int i;
+ u_int i;
#ifdef USE_SHADOW
struct spwd *spw = NULL;
#endif
/* grab passwd field for locked account check */
#ifdef USE_SHADOW
if (spw != NULL)
+#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF)
+ passwd = get_iaf_password(pw);
+#else
passwd = spw->sp_pwdp;
+#endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */
#else
passwd = pw->pw_passwd;
#endif
if (strstr(passwd, LOCKED_PASSWD_SUBSTR))
locked = 1;
#endif
+#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF)
+ free(passwd);
+#endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */
if (locked) {
logit("User %.100s not allowed because account is locked",
pw->pw_name);
return 0;
}
- if (options.num_deny_users > 0 || options.num_allow_users > 0) {
+ if (options.num_deny_users > 0 || options.num_allow_users > 0 ||
+ options.num_deny_groups > 0 || options.num_allow_groups > 0) {
hostname = get_canonical_hostname(options.use_dns);
ipaddr = get_remote_ipaddr();
}
}
#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
- if (!sys_auth_allowed_user(pw))
+ if (!sys_auth_allowed_user(pw, &loginmsg))
return 0;
#endif
void (*authlog) (const char *fmt,...) = verbose;
char *authmsg;
+ if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
+ return;
+
/* Raise logging level */
if (authenticated == 1 ||
!authctxt->valid ||
info);
#ifdef CUSTOM_FAILED_LOGIN
- if (authenticated == 0 && strcmp(method, "password") == 0)
+ if (authenticated == 0 && !authctxt->postponed &&
+ (strcmp(method, "password") == 0 ||
+ strncmp(method, "keyboard-interactive", 20) == 0 ||
+ strcmp(method, "challenge-response") == 0))
record_failed_login(authctxt->user,
get_canonical_hostname(options.use_dns), "ssh");
#endif
+#ifdef SSH_AUDIT_EVENTS
+ if (authenticated == 0 && !authctxt->postponed)
+ audit_event(audit_classify_auth(method));
+#endif
}
/*
switch (options.permit_root_login) {
case PERMIT_YES:
return 1;
- break;
case PERMIT_NO_PASSWD:
if (strcmp(method, "password") != 0)
return 1;
*
* This returns a buffer allocated by xmalloc.
*/
-char *
-expand_filename(const char *filename, struct passwd *pw)
+static char *
+expand_authorized_keys(const char *filename, struct passwd *pw)
{
- Buffer buffer;
- char *file;
- const char *cp;
+ char *file, ret[MAXPATHLEN];
+ int i;
- /*
- * Build the filename string in the buffer by making the appropriate
- * substitutions to the given file name.
- */
- buffer_init(&buffer);
- for (cp = filename; *cp; cp++) {
- if (cp[0] == '%' && cp[1] == '%') {
- buffer_append(&buffer, "%", 1);
- cp++;
- continue;
- }
- if (cp[0] == '%' && cp[1] == 'h') {
- buffer_append(&buffer, pw->pw_dir, strlen(pw->pw_dir));
- cp++;
- continue;
- }
- if (cp[0] == '%' && cp[1] == 'u') {
- buffer_append(&buffer, pw->pw_name,
- strlen(pw->pw_name));
- cp++;
- continue;
- }
- buffer_append(&buffer, cp, 1);
- }
- buffer_append(&buffer, "\0", 1);
+ file = percent_expand(filename, "h", pw->pw_dir,
+ "u", pw->pw_name, (char *)NULL);
/*
* Ensure that filename starts anchored. If not, be backward
* compatible and prepend the '%h/'
*/
- file = xmalloc(MAXPATHLEN);
- cp = buffer_ptr(&buffer);
- if (*cp != '/')
- snprintf(file, MAXPATHLEN, "%s/%s", pw->pw_dir, cp);
- else
- strlcpy(file, cp, MAXPATHLEN);
-
- buffer_free(&buffer);
- return file;
+ if (*file == '/')
+ return (file);
+
+ i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file);
+ if (i < 0 || (size_t)i >= sizeof(ret))
+ fatal("expand_authorized_keys: path too long");
+ xfree(file);
+ return (xstrdup(ret));
}
char *
authorized_keys_file(struct passwd *pw)
{
- return expand_filename(options.authorized_keys_file, pw);
+ return expand_authorized_keys(options.authorized_keys_file, pw);
}
char *
authorized_keys_file2(struct passwd *pw)
{
- return expand_filename(options.authorized_keys_file2, pw);
+ return expand_authorized_keys(options.authorized_keys_file2, pw);
}
/* return ok if key exists in sysfile or userfile */
#endif
struct passwd *pw;
+ parse_server_match_config(&options, user,
+ get_canonical_hostname(options.use_dns), get_remote_ipaddr());
+
pw = getpwnam(user);
if (pw == NULL) {
logit("Invalid user %.100s from %.100s",
record_failed_login(user,
get_canonical_hostname(options.use_dns), "ssh");
#endif
+#ifdef SSH_AUDIT_EVENTS
+ audit_event(SSH_INVALID_USER);
+#endif /* SSH_AUDIT_EVENTS */
return (NULL);
}
if (!allowed_user(pw))