]> andersk Git - gssapi-openssh.git/blobdiff - openssh/auth.c
The man2html from jbasney on pkilab2 works whereas the standard one doesn't.
[gssapi-openssh.git] / openssh / auth.c
index 2dc5c2be62939c0e9a283c78a073752c38603d6f..19253fe52afe42a893e1bca3d4c429a47e40d0d4 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: auth.c,v 1.80 2008/11/04 07:58:09 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.60 2005/06/17 02:44:32 djm Exp $");
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+
+#include <netinet/in.h>
+
+#include <errno.h>
+#include <fcntl.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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
 
 #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"
 
+#include "version.h"
+#include "ssh-globus-usage.h"
+
 /* import */
 extern ServerOptions options;
+extern int use_privsep;
 extern Buffer loginmsg;
+extern struct passwd *privsep_pw;
 
 /* Debugging messages */
 Buffer auth_debug;
@@ -95,15 +118,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 */
@@ -123,9 +145,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);
@@ -231,6 +253,9 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
        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 ||
@@ -247,7 +272,8 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
            authmsg,
            method,
            authctxt->valid ? "" : "invalid user ",
-           authctxt->user,
+           (authctxt->user && authctxt->user[0]) ?
+               authctxt->user : "unknown",
            get_remote_ipaddr(),
            get_remote_port(),
            info);
@@ -259,45 +285,31 @@ 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) {
-               ssh_audit_event_t event;
-
-               debug3("audit failed auth attempt, method %s euid %d",
-                   method, (int)geteuid());
-               /*
-                * Because the auth loop is used in both monitor and slave,
-                * we must be careful to send each event only once and with
-                * enough privs to write the event.
-                */
-               event = audit_classify_auth(method);
-               switch(event) {
-               case SSH_AUTH_FAIL_NONE:
-               case SSH_AUTH_FAIL_PASSWD:
-               case SSH_AUTH_FAIL_KBDINT:
-                       if (geteuid() == 0)
-                               audit_event(event);
-                       break;
-               case SSH_AUTH_FAIL_PUBKEY:
-               case SSH_AUTH_FAIL_HOSTBASED:
-               case SSH_AUTH_FAIL_GSSAPI:
-                       /*
-                        * This is required to handle the case where privsep
-                        * is enabled but it's root logging in, since
-                        * use_privsep won't be cleared until after a
-                        * successful login.
-                        */
-                       if (geteuid() == 0)
-                               audit_event(event);
-                       else
-                               PRIVSEP(audit_event(event));
-                       break;
-               default:
-                       error("unknown authentication audit event %d", event);
-               }
-       }
+       if (authenticated == 0 && !authctxt->postponed)
+               audit_event(audit_classify_auth(method));
 #endif
+       if (authenticated) {
+               char *userdn = NULL;
+               char *mech_name = NULL;
+               ssh_gssapi_get_client_info(&userdn, &mech_name);
+               debug("REPORTING (%s) (%s) (%s) (%s) (%s) (%s) (%s)",
+                        SSH_RELEASE, SSLeay_version(SSLEAY_VERSION),
+                        method, mech_name?mech_name:"NULL", get_remote_ipaddr(),
+                        (authctxt->user && authctxt->user[0])?
+                               authctxt->user : "unknown",
+                       userdn?userdn:"NULL");
+               ssh_globus_send_usage_metrics(SSH_RELEASE,
+                                       SSLeay_version(SSLEAY_VERSION),
+                                       method, mech_name, get_remote_ipaddr(),
+                                       authctxt->user, userdn);
+       }
 }
 
 /*
@@ -309,7 +321,6 @@ auth_root_allowed(char *method)
        switch (options.permit_root_login) {
        case PERMIT_YES:
                return 1;
-               break;
        case PERMIT_NO_PASSWD:
                if (strcmp(method, "password") != 0)
                        return 1;
@@ -333,10 +344,11 @@ auth_root_allowed(char *method)
  *
  * This returns a buffer allocated by xmalloc.
  */
-static char *
+char *
 expand_authorized_keys(const char *filename, struct passwd *pw)
 {
-       char *file, *ret;
+       char *file, ret[MAXPATHLEN];
+       int i;
 
        file = percent_expand(filename, "h", pw->pw_dir,
            "u", pw->pw_name, (char *)NULL);
@@ -348,14 +360,11 @@ expand_authorized_keys(const char *filename, struct passwd *pw)
        if (*file == '/')
                return (file);
 
-       ret = xmalloc(MAXPATHLEN);
-       if (strlcpy(ret, pw->pw_dir, MAXPATHLEN) >= MAXPATHLEN ||
-           strlcat(ret, "/", MAXPATHLEN) >= MAXPATHLEN ||
-           strlcat(ret, file, MAXPATHLEN) >= MAXPATHLEN)
+       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 (ret);
+       return (xstrdup(ret));
 }
 
 char *
@@ -421,7 +430,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)
 {
@@ -481,6 +490,46 @@ 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)
+               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)
 {
@@ -492,10 +541,18 @@ getpwnamallow(const char *user)
 #endif
        struct passwd *pw;
 
+       parse_server_match_config(&options, user,
+           get_canonical_hostname(options.use_dns), get_remote_ipaddr());
+
        pw = getpwnam(user);
+#ifdef USE_PAM
+       if (options.use_pam && options.permit_pam_user_change && pw == NULL)
+               pw = sshpam_getpw(user);
+#endif
        if (pw == NULL) {
                logit("Invalid user %.100s from %.100s",
-                   user, get_remote_ipaddr());
+                     (user && user[0]) ? user : "unknown",
+                     get_remote_ipaddr());
 #ifdef CUSTOM_FAILED_LOGIN
                record_failed_login(user,
                    get_canonical_hostname(options.use_dns), "ssh");
@@ -577,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
This page took 0.063283 seconds and 4 git commands to generate.